kernel: bump 4.9 to 4.9.96
[openwrt/staging/wigyori.git] / target / linux / layerscape / patches-4.9 / 701-sdk_dpaa-support-layerscape.patch
1 From 2f887ade916e7e1de2f8a84d3902aaa30af4b163 Mon Sep 17 00:00:00 2001
2 From: Yangbo Lu <yangbo.lu@nxp.com>
3 Date: Wed, 17 Jan 2018 14:59:15 +0800
4 Subject: [PATCH 07/30] sdk_dpaa: support layerscape
5
6 This is an integrated patch for layerscape dpaa1-sdk support.
7
8 Signed-off-by: Camelia Groza <camelia.groza@nxp.com>
9 Signed-off-by: Zhao Qiang <qiang.zhao@nxp.com>
10 Signed-off-by: Zhang Ying-22455 <ying.zhang22455@nxp.com>
11 Signed-off-by: Madalin Bucur <madalin.bucur@nxp.com>
12 Signed-off-by: Mathew McBride <matt@traverse.com.au>
13 Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
14 ---
15 drivers/net/ethernet/freescale/sdk_dpaa/Kconfig | 196 +
16 drivers/net/ethernet/freescale/sdk_dpaa/Makefile | 46 +
17 .../net/ethernet/freescale/sdk_dpaa/dpaa_1588.c | 580 ++
18 .../net/ethernet/freescale/sdk_dpaa/dpaa_1588.h | 138 +
19 .../net/ethernet/freescale/sdk_dpaa/dpaa_debugfs.c | 180 +
20 .../net/ethernet/freescale/sdk_dpaa/dpaa_debugfs.h | 43 +
21 drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth.c | 1224 ++++
22 drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth.h | 687 ++
23 .../ethernet/freescale/sdk_dpaa/dpaa_eth_base.c | 205 +
24 .../ethernet/freescale/sdk_dpaa/dpaa_eth_base.h | 49 +
25 .../ethernet/freescale/sdk_dpaa/dpaa_eth_ceetm.c | 2013 ++++++
26 .../ethernet/freescale/sdk_dpaa/dpaa_eth_ceetm.h | 238 +
27 .../ethernet/freescale/sdk_dpaa/dpaa_eth_common.c | 1802 +++++
28 .../ethernet/freescale/sdk_dpaa/dpaa_eth_common.h | 225 +
29 .../ethernet/freescale/sdk_dpaa/dpaa_eth_proxy.c | 381 +
30 .../net/ethernet/freescale/sdk_dpaa/dpaa_eth_sg.c | 1168 +++
31 .../ethernet/freescale/sdk_dpaa/dpaa_eth_sysfs.c | 278 +
32 .../ethernet/freescale/sdk_dpaa/dpaa_eth_trace.h | 144 +
33 .../net/ethernet/freescale/sdk_dpaa/dpaa_ethtool.c | 544 ++
34 drivers/net/ethernet/freescale/sdk_dpaa/dpaa_ptp.c | 291 +
35 drivers/net/ethernet/freescale/sdk_dpaa/mac-api.c | 907 +++
36 drivers/net/ethernet/freescale/sdk_dpaa/mac.c | 489 ++
37 drivers/net/ethernet/freescale/sdk_dpaa/mac.h | 135 +
38 .../net/ethernet/freescale/sdk_dpaa/offline_port.c | 848 +++
39 .../net/ethernet/freescale/sdk_dpaa/offline_port.h | 59 +
40 drivers/net/ethernet/freescale/sdk_fman/Kconfig | 153 +
41 drivers/net/ethernet/freescale/sdk_fman/Makefile | 11 +
42 .../freescale/sdk_fman/Peripherals/FM/HC/Makefile | 15 +
43 .../freescale/sdk_fman/Peripherals/FM/HC/hc.c | 1232 ++++
44 .../freescale/sdk_fman/Peripherals/FM/MAC/Makefile | 28 +
45 .../freescale/sdk_fman/Peripherals/FM/MAC/dtsec.c | 1465 ++++
46 .../freescale/sdk_fman/Peripherals/FM/MAC/dtsec.h | 228 +
47 .../sdk_fman/Peripherals/FM/MAC/dtsec_mii_acc.c | 97 +
48 .../sdk_fman/Peripherals/FM/MAC/dtsec_mii_acc.h | 42 +
49 .../freescale/sdk_fman/Peripherals/FM/MAC/fm_mac.c | 674 ++
50 .../freescale/sdk_fman/Peripherals/FM/MAC/fm_mac.h | 226 +
51 .../sdk_fman/Peripherals/FM/MAC/fman_crc32.c | 119 +
52 .../sdk_fman/Peripherals/FM/MAC/fman_crc32.h | 43 +
53 .../sdk_fman/Peripherals/FM/MAC/fman_dtsec.c | 845 +++
54 .../Peripherals/FM/MAC/fman_dtsec_mii_acc.c | 163 +
55 .../sdk_fman/Peripherals/FM/MAC/fman_memac.c | 532 ++
56 .../Peripherals/FM/MAC/fman_memac_mii_acc.c | 213 +
57 .../sdk_fman/Peripherals/FM/MAC/fman_tgec.c | 367 +
58 .../freescale/sdk_fman/Peripherals/FM/MAC/memac.c | 1153 +++
59 .../freescale/sdk_fman/Peripherals/FM/MAC/memac.h | 110 +
60 .../sdk_fman/Peripherals/FM/MAC/memac_mii_acc.c | 78 +
61 .../sdk_fman/Peripherals/FM/MAC/memac_mii_acc.h | 73 +
62 .../freescale/sdk_fman/Peripherals/FM/MAC/tgec.c | 1017 +++
63 .../freescale/sdk_fman/Peripherals/FM/MAC/tgec.h | 151 +
64 .../sdk_fman/Peripherals/FM/MAC/tgec_mii_acc.c | 139 +
65 .../sdk_fman/Peripherals/FM/MAC/tgec_mii_acc.h | 80 +
66 .../sdk_fman/Peripherals/FM/MACSEC/Makefile | 15 +
67 .../sdk_fman/Peripherals/FM/MACSEC/fm_macsec.c | 237 +
68 .../sdk_fman/Peripherals/FM/MACSEC/fm_macsec.h | 203 +
69 .../Peripherals/FM/MACSEC/fm_macsec_guest.c | 59 +
70 .../Peripherals/FM/MACSEC/fm_macsec_master.c | 1031 +++
71 .../Peripherals/FM/MACSEC/fm_macsec_master.h | 479 ++
72 .../Peripherals/FM/MACSEC/fm_macsec_secy.c | 883 +++
73 .../Peripherals/FM/MACSEC/fm_macsec_secy.h | 144 +
74 .../freescale/sdk_fman/Peripherals/FM/Makefile | 23 +
75 .../freescale/sdk_fman/Peripherals/FM/Pcd/Makefile | 26 +
76 .../freescale/sdk_fman/Peripherals/FM/Pcd/crc64.h | 360 +
77 .../freescale/sdk_fman/Peripherals/FM/Pcd/fm_cc.c | 7582 ++++++++++++++++++++
78 .../freescale/sdk_fman/Peripherals/FM/Pcd/fm_cc.h | 399 +
79 .../freescale/sdk_fman/Peripherals/FM/Pcd/fm_kg.c | 3242 +++++++++
80 .../freescale/sdk_fman/Peripherals/FM/Pcd/fm_kg.h | 206 +
81 .../sdk_fman/Peripherals/FM/Pcd/fm_manip.c | 5571 ++++++++++++++
82 .../sdk_fman/Peripherals/FM/Pcd/fm_manip.h | 555 ++
83 .../freescale/sdk_fman/Peripherals/FM/Pcd/fm_pcd.c | 2095 ++++++
84 .../freescale/sdk_fman/Peripherals/FM/Pcd/fm_pcd.h | 543 ++
85 .../sdk_fman/Peripherals/FM/Pcd/fm_pcd_ipc.h | 280 +
86 .../sdk_fman/Peripherals/FM/Pcd/fm_plcr.c | 1847 +++++
87 .../sdk_fman/Peripherals/FM/Pcd/fm_plcr.h | 165 +
88 .../freescale/sdk_fman/Peripherals/FM/Pcd/fm_prs.c | 423 ++
89 .../freescale/sdk_fman/Peripherals/FM/Pcd/fm_prs.h | 316 +
90 .../sdk_fman/Peripherals/FM/Pcd/fm_replic.c | 984 +++
91 .../sdk_fman/Peripherals/FM/Pcd/fm_replic.h | 101 +
92 .../sdk_fman/Peripherals/FM/Pcd/fman_kg.c | 888 +++
93 .../sdk_fman/Peripherals/FM/Pcd/fman_prs.c | 129 +
94 .../sdk_fman/Peripherals/FM/Port/Makefile | 15 +
95 .../sdk_fman/Peripherals/FM/Port/fm_port.c | 6436 +++++++++++++++++
96 .../sdk_fman/Peripherals/FM/Port/fm_port.h | 999 +++
97 .../sdk_fman/Peripherals/FM/Port/fm_port_dsar.h | 494 ++
98 .../sdk_fman/Peripherals/FM/Port/fm_port_im.c | 753 ++
99 .../sdk_fman/Peripherals/FM/Port/fman_port.c | 1568 ++++
100 .../freescale/sdk_fman/Peripherals/FM/Rtc/Makefile | 15 +
101 .../freescale/sdk_fman/Peripherals/FM/Rtc/fm_rtc.c | 692 ++
102 .../freescale/sdk_fman/Peripherals/FM/Rtc/fm_rtc.h | 96 +
103 .../sdk_fman/Peripherals/FM/Rtc/fman_rtc.c | 334 +
104 .../freescale/sdk_fman/Peripherals/FM/SP/Makefile | 15 +
105 .../freescale/sdk_fman/Peripherals/FM/SP/fm_sp.c | 757 ++
106 .../freescale/sdk_fman/Peripherals/FM/SP/fm_sp.h | 85 +
107 .../freescale/sdk_fman/Peripherals/FM/SP/fman_sp.c | 197 +
108 .../freescale/sdk_fman/Peripherals/FM/fm.c | 5216 ++++++++++++++
109 .../freescale/sdk_fman/Peripherals/FM/fm.h | 648 ++
110 .../freescale/sdk_fman/Peripherals/FM/fm_ipc.h | 465 ++
111 .../freescale/sdk_fman/Peripherals/FM/fm_muram.c | 174 +
112 .../freescale/sdk_fman/Peripherals/FM/fman.c | 1398 ++++
113 .../sdk_fman/Peripherals/FM/inc/fm_common.h | 1214 ++++
114 .../freescale/sdk_fman/Peripherals/FM/inc/fm_hc.h | 93 +
115 .../sdk_fman/Peripherals/FM/inc/fm_sp_common.h | 117 +
116 .../net/ethernet/freescale/sdk_fman/etc/Makefile | 12 +
117 .../net/ethernet/freescale/sdk_fman/etc/error.c | 95 +
118 drivers/net/ethernet/freescale/sdk_fman/etc/list.c | 71 +
119 .../net/ethernet/freescale/sdk_fman/etc/memcpy.c | 620 ++
120 drivers/net/ethernet/freescale/sdk_fman/etc/mm.c | 1155 +++
121 drivers/net/ethernet/freescale/sdk_fman/etc/mm.h | 105 +
122 .../net/ethernet/freescale/sdk_fman/etc/sprint.c | 81 +
123 .../ethernet/freescale/sdk_fman/fmanv3h_dflags.h | 57 +
124 .../ethernet/freescale/sdk_fman/fmanv3l_dflags.h | 56 +
125 .../sdk_fman/inc/Peripherals/crc_mac_addr_ext.h | 364 +
126 .../freescale/sdk_fman/inc/Peripherals/dpaa_ext.h | 210 +
127 .../freescale/sdk_fman/inc/Peripherals/fm_ext.h | 1731 +++++
128 .../sdk_fman/inc/Peripherals/fm_mac_ext.h | 887 +++
129 .../sdk_fman/inc/Peripherals/fm_macsec_ext.h | 1271 ++++
130 .../sdk_fman/inc/Peripherals/fm_muram_ext.h | 170 +
131 .../sdk_fman/inc/Peripherals/fm_pcd_ext.h | 3974 ++++++++++
132 .../sdk_fman/inc/Peripherals/fm_port_ext.h | 2608 +++++++
133 .../sdk_fman/inc/Peripherals/fm_rtc_ext.h | 619 ++
134 .../sdk_fman/inc/Peripherals/fm_vsp_ext.h | 411 ++
135 .../sdk_fman/inc/Peripherals/mii_acc_ext.h | 76 +
136 .../net/ethernet/freescale/sdk_fman/inc/core_ext.h | 90 +
137 .../freescale/sdk_fman/inc/cores/arm_ext.h | 55 +
138 .../freescale/sdk_fman/inc/cores/e500v2_ext.h | 476 ++
139 .../freescale/sdk_fman/inc/cores/ppc_ext.h | 141 +
140 .../ethernet/freescale/sdk_fman/inc/ddr_std_ext.h | 77 +
141 .../ethernet/freescale/sdk_fman/inc/debug_ext.h | 233 +
142 .../ethernet/freescale/sdk_fman/inc/endian_ext.h | 447 ++
143 .../net/ethernet/freescale/sdk_fman/inc/enet_ext.h | 205 +
144 .../ethernet/freescale/sdk_fman/inc/error_ext.h | 529 ++
145 .../ethernet/freescale/sdk_fman/inc/etc/list_ext.h | 358 +
146 .../ethernet/freescale/sdk_fman/inc/etc/mem_ext.h | 318 +
147 .../freescale/sdk_fman/inc/etc/memcpy_ext.h | 208 +
148 .../ethernet/freescale/sdk_fman/inc/etc/mm_ext.h | 310 +
149 .../freescale/sdk_fman/inc/etc/sprint_ext.h | 118 +
150 .../sdk_fman/inc/flib/common/arch/ppc_access.h | 37 +
151 .../freescale/sdk_fman/inc/flib/common/general.h | 52 +
152 .../freescale/sdk_fman/inc/flib/fman_common.h | 78 +
153 .../freescale/sdk_fman/inc/flib/fsl_enet.h | 273 +
154 .../freescale/sdk_fman/inc/flib/fsl_fman.h | 825 +++
155 .../freescale/sdk_fman/inc/flib/fsl_fman_dtsec.h | 1096 +++
156 .../sdk_fman/inc/flib/fsl_fman_dtsec_mii_acc.h | 107 +
157 .../freescale/sdk_fman/inc/flib/fsl_fman_kg.h | 514 ++
158 .../freescale/sdk_fman/inc/flib/fsl_fman_memac.h | 434 ++
159 .../sdk_fman/inc/flib/fsl_fman_memac_mii_acc.h | 78 +
160 .../freescale/sdk_fman/inc/flib/fsl_fman_port.h | 593 ++
161 .../freescale/sdk_fman/inc/flib/fsl_fman_prs.h | 102 +
162 .../freescale/sdk_fman/inc/flib/fsl_fman_rtc.h | 449 ++
163 .../freescale/sdk_fman/inc/flib/fsl_fman_sp.h | 138 +
164 .../freescale/sdk_fman/inc/flib/fsl_fman_tgec.h | 479 ++
165 .../integrations/FMANV3H/dpaa_integration_ext.h | 291 +
166 .../sdk_fman/inc/integrations/FMANV3H/part_ext.h | 71 +
167 .../integrations/FMANV3H/part_integration_ext.h | 304 +
168 .../integrations/FMANV3L/dpaa_integration_ext.h | 293 +
169 .../sdk_fman/inc/integrations/FMANV3L/part_ext.h | 59 +
170 .../integrations/FMANV3L/part_integration_ext.h | 304 +
171 .../inc/integrations/LS1043/dpaa_integration_ext.h | 291 +
172 .../sdk_fman/inc/integrations/LS1043/part_ext.h | 64 +
173 .../inc/integrations/LS1043/part_integration_ext.h | 185 +
174 .../inc/integrations/P1023/dpaa_integration_ext.h | 213 +
175 .../sdk_fman/inc/integrations/P1023/part_ext.h | 82 +
176 .../inc/integrations/P1023/part_integration_ext.h | 635 ++
177 .../P3040_P4080_P5020/dpaa_integration_ext.h | 276 +
178 .../inc/integrations/P3040_P4080_P5020/part_ext.h | 83 +
179 .../P3040_P4080_P5020/part_integration_ext.h | 336 +
180 .../net/ethernet/freescale/sdk_fman/inc/math_ext.h | 100 +
181 .../net/ethernet/freescale/sdk_fman/inc/ncsw_ext.h | 435 ++
182 .../net/ethernet/freescale/sdk_fman/inc/net_ext.h | 430 ++
183 .../net/ethernet/freescale/sdk_fman/inc/std_ext.h | 48 +
184 .../ethernet/freescale/sdk_fman/inc/stdarg_ext.h | 49 +
185 .../ethernet/freescale/sdk_fman/inc/stdlib_ext.h | 162 +
186 .../ethernet/freescale/sdk_fman/inc/string_ext.h | 56 +
187 .../ethernet/freescale/sdk_fman/inc/types_ext.h | 62 +
188 .../ethernet/freescale/sdk_fman/inc/xx_common.h | 56 +
189 .../net/ethernet/freescale/sdk_fman/inc/xx_ext.h | 791 ++
190 .../ethernet/freescale/sdk_fman/ls1043_dflags.h | 56 +
191 .../net/ethernet/freescale/sdk_fman/ncsw_config.mk | 53 +
192 .../net/ethernet/freescale/sdk_fman/p1023_dflags.h | 65 +
193 .../freescale/sdk_fman/p3040_4080_5020_dflags.h | 62 +
194 .../net/ethernet/freescale/sdk_fman/src/Makefile | 11 +
195 .../freescale/sdk_fman/src/inc/system/sys_ext.h | 118 +
196 .../freescale/sdk_fman/src/inc/system/sys_io_ext.h | 46 +
197 .../freescale/sdk_fman/src/inc/types_linux.h | 208 +
198 .../sdk_fman/src/inc/wrapper/fsl_fman_test.h | 84 +
199 .../sdk_fman/src/inc/wrapper/lnxwrp_exp_sym.h | 130 +
200 .../sdk_fman/src/inc/wrapper/lnxwrp_fm_ext.h | 163 +
201 .../sdk_fman/src/inc/wrapper/lnxwrp_fsl_fman.h | 921 +++
202 .../ethernet/freescale/sdk_fman/src/inc/xx/xx.h | 50 +
203 .../freescale/sdk_fman/src/system/Makefile | 10 +
204 .../freescale/sdk_fman/src/system/sys_io.c | 171 +
205 .../freescale/sdk_fman/src/wrapper/Makefile | 19 +
206 .../freescale/sdk_fman/src/wrapper/fman_test.c | 1665 +++++
207 .../freescale/sdk_fman/src/wrapper/lnxwrp_fm.c | 2908 ++++++++
208 .../freescale/sdk_fman/src/wrapper/lnxwrp_fm.h | 294 +
209 .../sdk_fman/src/wrapper/lnxwrp_fm_port.c | 1480 ++++
210 .../sdk_fman/src/wrapper/lnxwrp_ioctls_fm.c | 4854 +++++++++++++
211 .../sdk_fman/src/wrapper/lnxwrp_ioctls_fm_compat.c | 1297 ++++
212 .../sdk_fman/src/wrapper/lnxwrp_ioctls_fm_compat.h | 755 ++
213 .../sdk_fman/src/wrapper/lnxwrp_resources.h | 121 +
214 .../sdk_fman/src/wrapper/lnxwrp_resources_ut.c | 191 +
215 .../sdk_fman/src/wrapper/lnxwrp_resources_ut.h | 144 +
216 .../sdk_fman/src/wrapper/lnxwrp_resources_ut.make | 28 +
217 .../freescale/sdk_fman/src/wrapper/lnxwrp_sysfs.c | 60 +
218 .../freescale/sdk_fman/src/wrapper/lnxwrp_sysfs.h | 60 +
219 .../sdk_fman/src/wrapper/lnxwrp_sysfs_fm.c | 1855 +++++
220 .../sdk_fman/src/wrapper/lnxwrp_sysfs_fm.h | 136 +
221 .../sdk_fman/src/wrapper/lnxwrp_sysfs_fm_port.c | 1268 ++++
222 .../sdk_fman/src/wrapper/lnxwrp_sysfs_fm_port.h | 56 +
223 .../ethernet/freescale/sdk_fman/src/xx/Makefile | 18 +
224 .../freescale/sdk_fman/src/xx/module_strings.c | 46 +
225 .../freescale/sdk_fman/src/xx/xx_arm_linux.c | 905 +++
226 .../ethernet/freescale/sdk_fman/src/xx/xx_linux.c | 918 +++
227 drivers/staging/fsl_qbman/Kconfig | 228 +
228 drivers/staging/fsl_qbman/Makefile | 28 +
229 drivers/staging/fsl_qbman/bman_config.c | 720 ++
230 drivers/staging/fsl_qbman/bman_debugfs.c | 119 +
231 drivers/staging/fsl_qbman/bman_driver.c | 575 ++
232 drivers/staging/fsl_qbman/bman_high.c | 1145 +++
233 drivers/staging/fsl_qbman/bman_low.h | 565 ++
234 drivers/staging/fsl_qbman/bman_private.h | 166 +
235 drivers/staging/fsl_qbman/bman_test.c | 56 +
236 drivers/staging/fsl_qbman/bman_test.h | 44 +
237 drivers/staging/fsl_qbman/bman_test_high.c | 183 +
238 drivers/staging/fsl_qbman/bman_test_thresh.c | 196 +
239 drivers/staging/fsl_qbman/dpa_alloc.c | 706 ++
240 drivers/staging/fsl_qbman/dpa_sys.h | 259 +
241 drivers/staging/fsl_qbman/dpa_sys_arm.h | 95 +
242 drivers/staging/fsl_qbman/dpa_sys_arm64.h | 102 +
243 drivers/staging/fsl_qbman/dpa_sys_ppc32.h | 70 +
244 drivers/staging/fsl_qbman/dpa_sys_ppc64.h | 79 +
245 drivers/staging/fsl_qbman/fsl_usdpaa.c | 2007 ++++++
246 drivers/staging/fsl_qbman/fsl_usdpaa_irq.c | 289 +
247 drivers/staging/fsl_qbman/qbman_driver.c | 88 +
248 drivers/staging/fsl_qbman/qman_config.c | 1224 ++++
249 drivers/staging/fsl_qbman/qman_debugfs.c | 1594 ++++
250 drivers/staging/fsl_qbman/qman_driver.c | 977 +++
251 drivers/staging/fsl_qbman/qman_high.c | 5669 +++++++++++++++
252 drivers/staging/fsl_qbman/qman_low.h | 1442 ++++
253 drivers/staging/fsl_qbman/qman_private.h | 398 +
254 drivers/staging/fsl_qbman/qman_test.c | 57 +
255 drivers/staging/fsl_qbman/qman_test.h | 45 +
256 drivers/staging/fsl_qbman/qman_test_high.c | 216 +
257 drivers/staging/fsl_qbman/qman_test_hotpotato.c | 502 ++
258 drivers/staging/fsl_qbman/qman_utility.c | 129 +
259 include/linux/fsl_bman.h | 532 ++
260 include/linux/fsl_qman.h | 3888 ++++++++++
261 include/linux/fsl_usdpaa.h | 372 +
262 include/uapi/linux/fmd/Kbuild | 5 +
263 include/uapi/linux/fmd/Peripherals/Kbuild | 4 +
264 include/uapi/linux/fmd/Peripherals/fm_ioctls.h | 628 ++
265 include/uapi/linux/fmd/Peripherals/fm_pcd_ioctls.h | 3084 ++++++++
266 .../uapi/linux/fmd/Peripherals/fm_port_ioctls.h | 973 +++
267 .../uapi/linux/fmd/Peripherals/fm_test_ioctls.h | 208 +
268 include/uapi/linux/fmd/integrations/Kbuild | 1 +
269 .../linux/fmd/integrations/integration_ioctls.h | 56 +
270 include/uapi/linux/fmd/ioctls.h | 96 +
271 include/uapi/linux/fmd/net_ioctls.h | 430 ++
272 257 files changed, 153236 insertions(+)
273 create mode 100644 drivers/net/ethernet/freescale/sdk_dpaa/Kconfig
274 create mode 100644 drivers/net/ethernet/freescale/sdk_dpaa/Makefile
275 create mode 100644 drivers/net/ethernet/freescale/sdk_dpaa/dpaa_1588.c
276 create mode 100644 drivers/net/ethernet/freescale/sdk_dpaa/dpaa_1588.h
277 create mode 100644 drivers/net/ethernet/freescale/sdk_dpaa/dpaa_debugfs.c
278 create mode 100644 drivers/net/ethernet/freescale/sdk_dpaa/dpaa_debugfs.h
279 create mode 100644 drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth.c
280 create mode 100644 drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth.h
281 create mode 100644 drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_base.c
282 create mode 100644 drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_base.h
283 create mode 100644 drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_ceetm.c
284 create mode 100644 drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_ceetm.h
285 create mode 100644 drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_common.c
286 create mode 100644 drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_common.h
287 create mode 100644 drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_proxy.c
288 create mode 100644 drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_sg.c
289 create mode 100644 drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_sysfs.c
290 create mode 100644 drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_trace.h
291 create mode 100644 drivers/net/ethernet/freescale/sdk_dpaa/dpaa_ethtool.c
292 create mode 100644 drivers/net/ethernet/freescale/sdk_dpaa/dpaa_ptp.c
293 create mode 100644 drivers/net/ethernet/freescale/sdk_dpaa/mac-api.c
294 create mode 100644 drivers/net/ethernet/freescale/sdk_dpaa/mac.c
295 create mode 100644 drivers/net/ethernet/freescale/sdk_dpaa/mac.h
296 create mode 100644 drivers/net/ethernet/freescale/sdk_dpaa/offline_port.c
297 create mode 100644 drivers/net/ethernet/freescale/sdk_dpaa/offline_port.h
298 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Kconfig
299 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Makefile
300 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/HC/Makefile
301 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/HC/hc.c
302 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/Makefile
303 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/dtsec.c
304 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/dtsec.h
305 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/dtsec_mii_acc.c
306 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/dtsec_mii_acc.h
307 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/fm_mac.c
308 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/fm_mac.h
309 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/fman_crc32.c
310 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/fman_crc32.h
311 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/fman_dtsec.c
312 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/fman_dtsec_mii_acc.c
313 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/fman_memac.c
314 create mode 100755 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/fman_memac_mii_acc.c
315 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/fman_tgec.c
316 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/memac.c
317 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/memac.h
318 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/memac_mii_acc.c
319 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/memac_mii_acc.h
320 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/tgec.c
321 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/tgec.h
322 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/tgec_mii_acc.c
323 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/tgec_mii_acc.h
324 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MACSEC/Makefile
325 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MACSEC/fm_macsec.c
326 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MACSEC/fm_macsec.h
327 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MACSEC/fm_macsec_guest.c
328 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MACSEC/fm_macsec_master.c
329 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MACSEC/fm_macsec_master.h
330 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MACSEC/fm_macsec_secy.c
331 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MACSEC/fm_macsec_secy.h
332 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Makefile
333 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/Makefile
334 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/crc64.h
335 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/fm_cc.c
336 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/fm_cc.h
337 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/fm_kg.c
338 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/fm_kg.h
339 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/fm_manip.c
340 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/fm_manip.h
341 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/fm_pcd.c
342 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/fm_pcd.h
343 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/fm_pcd_ipc.h
344 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/fm_plcr.c
345 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/fm_plcr.h
346 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/fm_prs.c
347 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/fm_prs.h
348 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/fm_replic.c
349 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/fm_replic.h
350 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/fman_kg.c
351 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/fman_prs.c
352 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Port/Makefile
353 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Port/fm_port.c
354 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Port/fm_port.h
355 create mode 100755 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Port/fm_port_dsar.h
356 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Port/fm_port_im.c
357 create mode 100755 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Port/fman_port.c
358 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Rtc/Makefile
359 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Rtc/fm_rtc.c
360 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Rtc/fm_rtc.h
361 create mode 100755 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Rtc/fman_rtc.c
362 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/SP/Makefile
363 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/SP/fm_sp.c
364 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/SP/fm_sp.h
365 create mode 100755 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/SP/fman_sp.c
366 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/fm.c
367 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/fm.h
368 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/fm_ipc.h
369 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/fm_muram.c
370 create mode 100755 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/fman.c
371 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/inc/fm_common.h
372 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/inc/fm_hc.h
373 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/inc/fm_sp_common.h
374 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/etc/Makefile
375 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/etc/error.c
376 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/etc/list.c
377 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/etc/memcpy.c
378 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/etc/mm.c
379 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/etc/mm.h
380 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/etc/sprint.c
381 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/fmanv3h_dflags.h
382 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/fmanv3l_dflags.h
383 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/Peripherals/crc_mac_addr_ext.h
384 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/Peripherals/dpaa_ext.h
385 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/Peripherals/fm_ext.h
386 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/Peripherals/fm_mac_ext.h
387 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/Peripherals/fm_macsec_ext.h
388 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/Peripherals/fm_muram_ext.h
389 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/Peripherals/fm_pcd_ext.h
390 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/Peripherals/fm_port_ext.h
391 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/Peripherals/fm_rtc_ext.h
392 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/Peripherals/fm_vsp_ext.h
393 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/Peripherals/mii_acc_ext.h
394 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/core_ext.h
395 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/cores/arm_ext.h
396 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/cores/e500v2_ext.h
397 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/cores/ppc_ext.h
398 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/ddr_std_ext.h
399 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/debug_ext.h
400 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/endian_ext.h
401 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/enet_ext.h
402 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/error_ext.h
403 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/etc/list_ext.h
404 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/etc/mem_ext.h
405 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/etc/memcpy_ext.h
406 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/etc/mm_ext.h
407 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/etc/sprint_ext.h
408 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/flib/common/arch/ppc_access.h
409 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/flib/common/general.h
410 create mode 100755 drivers/net/ethernet/freescale/sdk_fman/inc/flib/fman_common.h
411 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/flib/fsl_enet.h
412 create mode 100755 drivers/net/ethernet/freescale/sdk_fman/inc/flib/fsl_fman.h
413 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/flib/fsl_fman_dtsec.h
414 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/flib/fsl_fman_dtsec_mii_acc.h
415 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/flib/fsl_fman_kg.h
416 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/flib/fsl_fman_memac.h
417 create mode 100755 drivers/net/ethernet/freescale/sdk_fman/inc/flib/fsl_fman_memac_mii_acc.h
418 create mode 100755 drivers/net/ethernet/freescale/sdk_fman/inc/flib/fsl_fman_port.h
419 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/flib/fsl_fman_prs.h
420 create mode 100755 drivers/net/ethernet/freescale/sdk_fman/inc/flib/fsl_fman_rtc.h
421 create mode 100755 drivers/net/ethernet/freescale/sdk_fman/inc/flib/fsl_fman_sp.h
422 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/flib/fsl_fman_tgec.h
423 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/integrations/FMANV3H/dpaa_integration_ext.h
424 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/integrations/FMANV3H/part_ext.h
425 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/integrations/FMANV3H/part_integration_ext.h
426 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/integrations/FMANV3L/dpaa_integration_ext.h
427 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/integrations/FMANV3L/part_ext.h
428 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/integrations/FMANV3L/part_integration_ext.h
429 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/integrations/LS1043/dpaa_integration_ext.h
430 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/integrations/LS1043/part_ext.h
431 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/integrations/LS1043/part_integration_ext.h
432 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/integrations/P1023/dpaa_integration_ext.h
433 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/integrations/P1023/part_ext.h
434 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/integrations/P1023/part_integration_ext.h
435 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/integrations/P3040_P4080_P5020/dpaa_integration_ext.h
436 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/integrations/P3040_P4080_P5020/part_ext.h
437 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/integrations/P3040_P4080_P5020/part_integration_ext.h
438 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/math_ext.h
439 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/ncsw_ext.h
440 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/net_ext.h
441 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/std_ext.h
442 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/stdarg_ext.h
443 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/stdlib_ext.h
444 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/string_ext.h
445 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/types_ext.h
446 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/xx_common.h
447 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/xx_ext.h
448 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/ls1043_dflags.h
449 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/ncsw_config.mk
450 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/p1023_dflags.h
451 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/p3040_4080_5020_dflags.h
452 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/src/Makefile
453 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/src/inc/system/sys_ext.h
454 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/src/inc/system/sys_io_ext.h
455 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/src/inc/types_linux.h
456 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/src/inc/wrapper/fsl_fman_test.h
457 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/src/inc/wrapper/lnxwrp_exp_sym.h
458 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/src/inc/wrapper/lnxwrp_fm_ext.h
459 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/src/inc/wrapper/lnxwrp_fsl_fman.h
460 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/src/inc/xx/xx.h
461 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/src/system/Makefile
462 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/src/system/sys_io.c
463 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/src/wrapper/Makefile
464 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/src/wrapper/fman_test.c
465 create mode 100755 drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_fm.c
466 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_fm.h
467 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_fm_port.c
468 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_ioctls_fm.c
469 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_ioctls_fm_compat.c
470 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_ioctls_fm_compat.h
471 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_resources.h
472 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_resources_ut.c
473 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_resources_ut.h
474 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_resources_ut.make
475 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_sysfs.c
476 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_sysfs.h
477 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_sysfs_fm.c
478 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_sysfs_fm.h
479 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_sysfs_fm_port.c
480 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_sysfs_fm_port.h
481 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/src/xx/Makefile
482 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/src/xx/module_strings.c
483 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/src/xx/xx_arm_linux.c
484 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/src/xx/xx_linux.c
485 create mode 100644 drivers/staging/fsl_qbman/Kconfig
486 create mode 100644 drivers/staging/fsl_qbman/Makefile
487 create mode 100644 drivers/staging/fsl_qbman/bman_config.c
488 create mode 100644 drivers/staging/fsl_qbman/bman_debugfs.c
489 create mode 100644 drivers/staging/fsl_qbman/bman_driver.c
490 create mode 100644 drivers/staging/fsl_qbman/bman_high.c
491 create mode 100644 drivers/staging/fsl_qbman/bman_low.h
492 create mode 100644 drivers/staging/fsl_qbman/bman_private.h
493 create mode 100644 drivers/staging/fsl_qbman/bman_test.c
494 create mode 100644 drivers/staging/fsl_qbman/bman_test.h
495 create mode 100644 drivers/staging/fsl_qbman/bman_test_high.c
496 create mode 100644 drivers/staging/fsl_qbman/bman_test_thresh.c
497 create mode 100644 drivers/staging/fsl_qbman/dpa_alloc.c
498 create mode 100644 drivers/staging/fsl_qbman/dpa_sys.h
499 create mode 100644 drivers/staging/fsl_qbman/dpa_sys_arm.h
500 create mode 100644 drivers/staging/fsl_qbman/dpa_sys_arm64.h
501 create mode 100644 drivers/staging/fsl_qbman/dpa_sys_ppc32.h
502 create mode 100644 drivers/staging/fsl_qbman/dpa_sys_ppc64.h
503 create mode 100644 drivers/staging/fsl_qbman/fsl_usdpaa.c
504 create mode 100644 drivers/staging/fsl_qbman/fsl_usdpaa_irq.c
505 create mode 100644 drivers/staging/fsl_qbman/qbman_driver.c
506 create mode 100644 drivers/staging/fsl_qbman/qman_config.c
507 create mode 100644 drivers/staging/fsl_qbman/qman_debugfs.c
508 create mode 100644 drivers/staging/fsl_qbman/qman_driver.c
509 create mode 100644 drivers/staging/fsl_qbman/qman_high.c
510 create mode 100644 drivers/staging/fsl_qbman/qman_low.h
511 create mode 100644 drivers/staging/fsl_qbman/qman_private.h
512 create mode 100644 drivers/staging/fsl_qbman/qman_test.c
513 create mode 100644 drivers/staging/fsl_qbman/qman_test.h
514 create mode 100644 drivers/staging/fsl_qbman/qman_test_high.c
515 create mode 100644 drivers/staging/fsl_qbman/qman_test_hotpotato.c
516 create mode 100644 drivers/staging/fsl_qbman/qman_utility.c
517 create mode 100644 include/linux/fsl_bman.h
518 create mode 100644 include/linux/fsl_qman.h
519 create mode 100644 include/linux/fsl_usdpaa.h
520 create mode 100644 include/uapi/linux/fmd/Kbuild
521 create mode 100644 include/uapi/linux/fmd/Peripherals/Kbuild
522 create mode 100644 include/uapi/linux/fmd/Peripherals/fm_ioctls.h
523 create mode 100644 include/uapi/linux/fmd/Peripherals/fm_pcd_ioctls.h
524 create mode 100644 include/uapi/linux/fmd/Peripherals/fm_port_ioctls.h
525 create mode 100644 include/uapi/linux/fmd/Peripherals/fm_test_ioctls.h
526 create mode 100644 include/uapi/linux/fmd/integrations/Kbuild
527 create mode 100644 include/uapi/linux/fmd/integrations/integration_ioctls.h
528 create mode 100644 include/uapi/linux/fmd/ioctls.h
529 create mode 100644 include/uapi/linux/fmd/net_ioctls.h
530
531 --- /dev/null
532 +++ b/drivers/net/ethernet/freescale/sdk_dpaa/Kconfig
533 @@ -0,0 +1,196 @@
534 +menuconfig FSL_SDK_DPAA_ETH
535 + tristate "DPAA Ethernet"
536 + depends on (FSL_SOC || ARM64 || ARM) && FSL_SDK_BMAN && FSL_SDK_QMAN && FSL_SDK_FMAN && !FSL_DPAA_ETH
537 + select PHYLIB
538 + help
539 + Data Path Acceleration Architecture Ethernet driver,
540 + supporting the Freescale QorIQ chips.
541 + Depends on Freescale Buffer Manager and Queue Manager
542 + driver and Frame Manager Driver.
543 +
544 +if FSL_SDK_DPAA_ETH
545 +
546 +config FSL_DPAA_HOOKS
547 + bool "DPAA Ethernet driver hooks"
548 +
549 +config FSL_DPAA_CEETM
550 + bool "DPAA CEETM QoS"
551 + depends on NET_SCHED
552 + default n
553 + help
554 + Enable QoS offloading support through the CEETM hardware block.
555 +
556 +config FSL_DPAA_CEETM_CCS_THRESHOLD_1G
557 + hex "CEETM egress congestion threshold on 1G ports"
558 + depends on FSL_DPAA_CEETM
559 + range 0x1000 0x10000000
560 + default "0x000a0000"
561 + help
562 + The size in bytes of the CEETM egress Class Congestion State threshold on 1G ports.
563 + The threshold needs to be configured keeping in mind the following factors:
564 + - A threshold too large will buffer frames for a long time in the TX queues,
565 + when a small shaping rate is configured. This will cause buffer pool depletion
566 + or out of memory errors. This in turn will cause frame loss on RX;
567 + - A threshold too small will cause unnecessary frame loss by entering
568 + congestion too often.
569 +
570 +config FSL_DPAA_CEETM_CCS_THRESHOLD_10G
571 + hex "CEETM egress congestion threshold on 10G ports"
572 + depends on FSL_DPAA_CEETM
573 + range 0x1000 0x20000000
574 + default "0x00640000"
575 + help
576 + The size in bytes of the CEETM egress Class Congestion State threshold on 10G ports.
577 + See FSL_DPAA_CEETM_CCS_THRESHOLD_1G for details.
578 +
579 +config FSL_DPAA_OFFLINE_PORTS
580 + bool "Offline Ports support"
581 + depends on FSL_SDK_DPAA_ETH
582 + default y
583 + help
584 + The Offline Parsing / Host Command ports (short: OH ports, of Offline ports) provide
585 + most of the functionality of the regular, online ports, except they receive their
586 + frames from a core or an accelerator on the SoC, via QMan frame queues,
587 + rather than directly from the network.
588 + Offline ports are configured via PCD (Parse-Classify-Distribute) schemes, just like
589 + any online FMan port. They deliver the processed frames to frame queues, according
590 + to the applied PCD configurations.
591 +
592 + Choosing this feature will not impact the functionality and/or performance of the system,
593 + so it is safe to have it.
594 +
595 +config FSL_DPAA_ADVANCED_DRIVERS
596 + bool "Advanced DPAA Ethernet drivers"
597 + depends on FSL_SDK_DPAA_ETH
598 + default y
599 + help
600 + Besides the standard DPAA Ethernet driver the DPAA Proxy initialization driver
601 + is needed to support advanced scenarios. Select this to also build the advanced
602 + drivers.
603 +
604 +config FSL_DPAA_ETH_JUMBO_FRAME
605 + bool "Optimize for jumbo frames"
606 + default n
607 + help
608 + Optimize the DPAA Ethernet driver throughput for large frames
609 + termination traffic (e.g. 4K and above).
610 + NOTE: This option can only be used if FSL_FM_MAX_FRAME_SIZE
611 + is set to 9600 bytes.
612 + Using this option in combination with small frames increases
613 + significantly the driver's memory footprint and may even deplete
614 + the system memory. Also, the skb truesize is altered and messages
615 + from the stack that warn against this are bypassed.
616 + This option is not available on LS1043.
617 +
618 +config FSL_DPAA_TS
619 + bool "Linux compliant timestamping"
620 + depends on FSL_SDK_DPAA_ETH
621 + default n
622 + help
623 + Enable Linux API compliant timestamping support.
624 +
625 +config FSL_DPAA_1588
626 + bool "IEEE 1588-compliant timestamping"
627 + depends on FSL_SDK_DPAA_ETH
628 + select FSL_DPAA_TS
629 + default n
630 + help
631 + Enable IEEE1588 support code.
632 +
633 +config FSL_DPAA_ETH_USE_NDO_SELECT_QUEUE
634 + bool "Use driver's Tx queue selection mechanism"
635 + default y
636 + depends on FSL_SDK_DPAA_ETH
637 + help
638 + The DPAA-Ethernet driver defines a ndo_select_queue() callback for optimal selection
639 + of the egress FQ. That will override the XPS support for this netdevice.
640 + If for whatever reason you want to be in control of the egress FQ-to-CPU selection and mapping,
641 + or simply don't want to use the driver's ndo_select_queue() callback, then unselect this
642 + and use the standard XPS support instead.
643 +
644 +config FSL_DPAA_ETH_MAX_BUF_COUNT
645 + int "Maximum nuber of buffers in private bpool"
646 + depends on FSL_SDK_DPAA_ETH
647 + range 64 2048
648 + default "128"
649 + help
650 + The maximum number of buffers to be by default allocated in the DPAA-Ethernet private port's
651 + buffer pool. One needn't normally modify this, as it has probably been tuned for performance
652 + already. This cannot be lower than DPAA_ETH_REFILL_THRESHOLD.
653 +
654 +config FSL_DPAA_ETH_REFILL_THRESHOLD
655 + int "Private bpool refill threshold"
656 + depends on FSL_SDK_DPAA_ETH
657 + range 32 FSL_DPAA_ETH_MAX_BUF_COUNT
658 + default "80"
659 + help
660 + The DPAA-Ethernet driver will start replenishing buffer pools whose count
661 + falls below this threshold. This must be related to DPAA_ETH_MAX_BUF_COUNT. One needn't normally
662 + modify this value unless one has very specific performance reasons.
663 +
664 +config FSL_DPAA_CS_THRESHOLD_1G
665 + hex "Egress congestion threshold on 1G ports"
666 + depends on FSL_SDK_DPAA_ETH
667 + range 0x1000 0x10000000
668 + default "0x06000000"
669 + help
670 + The size in bytes of the egress Congestion State notification threshold on 1G ports.
671 + The 1G dTSECs can quite easily be flooded by cores doing Tx in a tight loop
672 + (e.g. by sending UDP datagrams at "while(1) speed"),
673 + and the larger the frame size, the more acute the problem.
674 + So we have to find a balance between these factors:
675 + - avoiding the device staying congested for a prolonged time (risking
676 + the netdev watchdog to fire - see also the tx_timeout module param);
677 + - affecting performance of protocols such as TCP, which otherwise
678 + behave well under the congestion notification mechanism;
679 + - preventing the Tx cores from tightly-looping (as if the congestion
680 + threshold was too low to be effective);
681 + - running out of memory if the CS threshold is set too high.
682 +
683 +config FSL_DPAA_CS_THRESHOLD_10G
684 + hex "Egress congestion threshold on 10G ports"
685 + depends on FSL_SDK_DPAA_ETH
686 + range 0x1000 0x20000000
687 + default "0x10000000"
688 + help
689 + The size in bytes of the egress Congestion State notification threshold on 10G ports.
690 +
691 +config FSL_DPAA_INGRESS_CS_THRESHOLD
692 + hex "Ingress congestion threshold on FMan ports"
693 + depends on FSL_SDK_DPAA_ETH
694 + default "0x10000000"
695 + help
696 + The size in bytes of the ingress tail-drop threshold on FMan ports.
697 + Traffic piling up above this value will be rejected by QMan and discarded by FMan.
698 +
699 +config FSL_DPAA_ETH_DEBUGFS
700 + bool "DPAA Ethernet debugfs interface"
701 + depends on DEBUG_FS && FSL_SDK_DPAA_ETH
702 + default y
703 + help
704 + This option compiles debugfs code for the DPAA Ethernet driver.
705 +
706 +config FSL_DPAA_ETH_DEBUG
707 + bool "DPAA Ethernet Debug Support"
708 + depends on FSL_SDK_DPAA_ETH
709 + default n
710 + help
711 + This option compiles debug code for the DPAA Ethernet driver.
712 +
713 +config FSL_DPAA_DBG_LOOP
714 + bool "DPAA Ethernet Debug loopback"
715 + depends on FSL_DPAA_ETH_DEBUGFS && FSL_DPAA_ETH_USE_NDO_SELECT_QUEUE
716 + default n
717 + help
718 + This option allows to divert all received traffic on a certain interface A towards a
719 + selected interface B. This option is used to benchmark the HW + Ethernet driver in
720 + isolation from the Linux networking stack. The loops are controlled by debugfs entries,
721 + one for each interface. By default all loops are disabled (target value is -1). I.e. to
722 + change the loop setting for interface 4 and divert all received traffic to interface 5
723 + write Tx interface number in the receive interface debugfs file:
724 + # cat /sys/kernel/debug/powerpc/fsl_dpa/eth4_loop
725 + 4->-1
726 + # echo 5 > /sys/kernel/debug/powerpc/fsl_dpa/eth4_loop
727 + # cat /sys/kernel/debug/powerpc/fsl_dpa/eth4_loop
728 + 4->5
729 +endif # FSL_SDK_DPAA_ETH
730 --- /dev/null
731 +++ b/drivers/net/ethernet/freescale/sdk_dpaa/Makefile
732 @@ -0,0 +1,46 @@
733 +#
734 +# Makefile for the Freescale Ethernet controllers
735 +#
736 +ccflags-y += -DVERSION=\"\"
737 +#
738 +# Include netcomm SW specific definitions
739 +include $(srctree)/drivers/net/ethernet/freescale/sdk_fman/ncsw_config.mk
740 +
741 +ccflags-y += -I$(NET_DPA)
742 +
743 +obj-$(CONFIG_FSL_SDK_DPAA_ETH) += fsl_mac.o fsl_dpa.o
744 +obj-$(CONFIG_PTP_1588_CLOCK_DPAA) += dpaa_ptp.o
745 +
746 +fsl_dpa-objs += dpaa_ethtool.o dpaa_eth_sysfs.o dpaa_eth.o dpaa_eth_sg.o dpaa_eth_common.o
747 +ifeq ($(CONFIG_FSL_DPAA_DBG_LOOP),y)
748 +fsl_dpa-objs += dpaa_debugfs.o
749 +endif
750 +ifeq ($(CONFIG_FSL_DPAA_1588),y)
751 +fsl_dpa-objs += dpaa_1588.o
752 +endif
753 +ifeq ($(CONFIG_FSL_DPAA_CEETM),y)
754 +ccflags-y += -Idrivers/net/ethernet/freescale/sdk_fman/src/wrapper
755 +fsl_dpa-objs += dpaa_eth_ceetm.o
756 +endif
757 +
758 +fsl_mac-objs += mac.o mac-api.o
759 +
760 +# Advanced drivers
761 +ifeq ($(CONFIG_FSL_DPAA_ADVANCED_DRIVERS),y)
762 +obj-$(CONFIG_FSL_SDK_DPAA_ETH) += fsl_advanced.o
763 +obj-$(CONFIG_FSL_SDK_DPAA_ETH) += fsl_proxy.o
764 +
765 +fsl_advanced-objs += dpaa_eth_base.o
766 +# suport for multiple drivers per kernel module comes in kernel 3.14
767 +# so we are forced to generate several modules for the advanced drivers
768 +fsl_proxy-objs += dpaa_eth_proxy.o
769 +
770 +ifeq ($(CONFIG_FSL_DPAA_OFFLINE_PORTS),y)
771 +obj-$(CONFIG_FSL_SDK_DPAA_ETH) += fsl_oh.o
772 +
773 +fsl_oh-objs += offline_port.o
774 +endif
775 +endif
776 +
777 +# Needed by the tracing framework
778 +CFLAGS_dpaa_eth.o := -I$(src)
779 --- /dev/null
780 +++ b/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_1588.c
781 @@ -0,0 +1,580 @@
782 +/* Copyright (C) 2011 Freescale Semiconductor, Inc.
783 + * Copyright (C) 2009 IXXAT Automation, GmbH
784 + *
785 + * DPAA Ethernet Driver -- IEEE 1588 interface functionality
786 + *
787 + * This program is free software; you can redistribute it and/or modify
788 + * it under the terms of the GNU General Public License as published by
789 + * the Free Software Foundation; either version 2 of the License, or
790 + * (at your option) any later version.
791 + *
792 + * This program is distributed in the hope that it will be useful,
793 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
794 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
795 + * GNU General Public License for more details.
796 + *
797 + * You should have received a copy of the GNU General Public License along
798 + * with this program; if not, write to the Free Software Foundation, Inc.,
799 + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
800 + *
801 + */
802 +#include <linux/io.h>
803 +#include <linux/device.h>
804 +#include <linux/fs.h>
805 +#include <linux/vmalloc.h>
806 +#include <linux/spinlock.h>
807 +#include <linux/ip.h>
808 +#include <linux/ipv6.h>
809 +#include <linux/udp.h>
810 +#include <asm/div64.h>
811 +#include "dpaa_eth.h"
812 +#include "dpaa_eth_common.h"
813 +#include "dpaa_1588.h"
814 +#include "mac.h"
815 +
816 +static int dpa_ptp_init_circ(struct dpa_ptp_circ_buf *ptp_buf, u32 size)
817 +{
818 + struct circ_buf *circ_buf = &ptp_buf->circ_buf;
819 +
820 + circ_buf->buf = vmalloc(sizeof(struct dpa_ptp_data) * size);
821 + if (!circ_buf->buf)
822 + return 1;
823 +
824 + circ_buf->head = 0;
825 + circ_buf->tail = 0;
826 + ptp_buf->size = size;
827 + spin_lock_init(&ptp_buf->ptp_lock);
828 +
829 + return 0;
830 +}
831 +
832 +static void dpa_ptp_reset_circ(struct dpa_ptp_circ_buf *ptp_buf, u32 size)
833 +{
834 + struct circ_buf *circ_buf = &ptp_buf->circ_buf;
835 +
836 + circ_buf->head = 0;
837 + circ_buf->tail = 0;
838 + ptp_buf->size = size;
839 +}
840 +
841 +static int dpa_ptp_insert(struct dpa_ptp_circ_buf *ptp_buf,
842 + struct dpa_ptp_data *data)
843 +{
844 + struct circ_buf *circ_buf = &ptp_buf->circ_buf;
845 + int size = ptp_buf->size;
846 + struct dpa_ptp_data *tmp;
847 + unsigned long flags;
848 + int head, tail;
849 +
850 + spin_lock_irqsave(&ptp_buf->ptp_lock, flags);
851 +
852 + head = circ_buf->head;
853 + tail = circ_buf->tail;
854 +
855 + if (CIRC_SPACE(head, tail, size) <= 0)
856 + circ_buf->tail = (tail + 1) & (size - 1);
857 +
858 + tmp = (struct dpa_ptp_data *)(circ_buf->buf) + head;
859 + memcpy(tmp, data, sizeof(struct dpa_ptp_data));
860 +
861 + circ_buf->head = (head + 1) & (size - 1);
862 +
863 + spin_unlock_irqrestore(&ptp_buf->ptp_lock, flags);
864 +
865 + return 0;
866 +}
867 +
868 +static int dpa_ptp_is_ident_match(struct dpa_ptp_ident *dst,
869 + struct dpa_ptp_ident *src)
870 +{
871 + int ret;
872 +
873 + if ((dst->version != src->version) || (dst->msg_type != src->msg_type))
874 + return 0;
875 +
876 + if ((dst->netw_prot == src->netw_prot)
877 + || src->netw_prot == DPA_PTP_PROT_DONTCARE) {
878 + if (dst->seq_id != src->seq_id)
879 + return 0;
880 +
881 + ret = memcmp(dst->snd_port_id, src->snd_port_id,
882 + DPA_PTP_SOURCE_PORT_LENGTH);
883 + if (ret)
884 + return 0;
885 + else
886 + return 1;
887 + }
888 +
889 + return 0;
890 +}
891 +
892 +static int dpa_ptp_find_and_remove(struct dpa_ptp_circ_buf *ptp_buf,
893 + struct dpa_ptp_ident *ident,
894 + struct dpa_ptp_time *ts)
895 +{
896 + struct circ_buf *circ_buf = &ptp_buf->circ_buf;
897 + int size = ptp_buf->size;
898 + int head, tail, idx;
899 + unsigned long flags;
900 + struct dpa_ptp_data *tmp, *tmp2;
901 + struct dpa_ptp_ident *tmp_ident;
902 +
903 + spin_lock_irqsave(&ptp_buf->ptp_lock, flags);
904 +
905 + head = circ_buf->head;
906 + tail = idx = circ_buf->tail;
907 +
908 + if (CIRC_CNT(head, tail, size) == 0) {
909 + spin_unlock_irqrestore(&ptp_buf->ptp_lock, flags);
910 + return 1;
911 + }
912 +
913 + while (idx != head) {
914 + tmp = (struct dpa_ptp_data *)(circ_buf->buf) + idx;
915 + tmp_ident = &tmp->ident;
916 + if (dpa_ptp_is_ident_match(tmp_ident, ident))
917 + break;
918 + idx = (idx + 1) & (size - 1);
919 + }
920 +
921 + if (idx == head) {
922 + spin_unlock_irqrestore(&ptp_buf->ptp_lock, flags);
923 + return 1;
924 + }
925 +
926 + ts->sec = tmp->ts.sec;
927 + ts->nsec = tmp->ts.nsec;
928 +
929 + if (idx != tail) {
930 + if (CIRC_CNT(idx, tail, size) > TS_ACCUMULATION_THRESHOLD) {
931 + tail = circ_buf->tail =
932 + (idx - TS_ACCUMULATION_THRESHOLD) & (size - 1);
933 + }
934 +
935 + while (CIRC_CNT(idx, tail, size) > 0) {
936 + tmp = (struct dpa_ptp_data *)(circ_buf->buf) + idx;
937 + idx = (idx - 1) & (size - 1);
938 + tmp2 = (struct dpa_ptp_data *)(circ_buf->buf) + idx;
939 + *tmp = *tmp2;
940 + }
941 + }
942 + circ_buf->tail = (tail + 1) & (size - 1);
943 +
944 + spin_unlock_irqrestore(&ptp_buf->ptp_lock, flags);
945 +
946 + return 0;
947 +}
948 +
949 +/* Parse the PTP packets
950 + *
951 + * The PTP header can be found in an IPv4 packet, IPv6 patcket or in
952 + * an IEEE802.3 ethernet frame. This function returns the position of
953 + * the PTP packet or NULL if no PTP found
954 + */
955 +static u8 *dpa_ptp_parse_packet(struct sk_buff *skb, u16 *eth_type)
956 +{
957 + u8 *pos = skb->data + ETH_ALEN + ETH_ALEN;
958 + u8 *ptp_loc = NULL;
959 + u8 msg_type;
960 + u32 access_len = ETH_ALEN + ETH_ALEN + DPA_ETYPE_LEN;
961 + struct iphdr *iph;
962 + struct udphdr *udph;
963 + struct ipv6hdr *ipv6h;
964 +
965 + /* when we can receive S/G frames we need to check the data we want to
966 + * access is in the linear skb buffer
967 + */
968 + if (!pskb_may_pull(skb, access_len))
969 + return NULL;
970 +
971 + *eth_type = *((u16 *)pos);
972 +
973 + /* Check if inner tag is here */
974 + if (*eth_type == ETH_P_8021Q) {
975 + access_len += DPA_VLAN_TAG_LEN;
976 +
977 + if (!pskb_may_pull(skb, access_len))
978 + return NULL;
979 +
980 + pos += DPA_VLAN_TAG_LEN;
981 + *eth_type = *((u16 *)pos);
982 + }
983 +
984 + pos += DPA_ETYPE_LEN;
985 +
986 + switch (*eth_type) {
987 + /* Transport of PTP over Ethernet */
988 + case ETH_P_1588:
989 + ptp_loc = pos;
990 +
991 + if (!pskb_may_pull(skb, access_len + PTP_OFFS_MSG_TYPE + 1))
992 + return NULL;
993 +
994 + msg_type = *((u8 *)(ptp_loc + PTP_OFFS_MSG_TYPE)) & 0xf;
995 + if ((msg_type == PTP_MSGTYPE_SYNC)
996 + || (msg_type == PTP_MSGTYPE_DELREQ)
997 + || (msg_type == PTP_MSGTYPE_PDELREQ)
998 + || (msg_type == PTP_MSGTYPE_PDELRESP))
999 + return ptp_loc;
1000 + break;
1001 + /* Transport of PTP over IPv4 */
1002 + case ETH_P_IP:
1003 + iph = (struct iphdr *)pos;
1004 + access_len += sizeof(struct iphdr);
1005 +
1006 + if (!pskb_may_pull(skb, access_len))
1007 + return NULL;
1008 +
1009 + if (ntohs(iph->protocol) != IPPROTO_UDP)
1010 + return NULL;
1011 +
1012 + access_len += iph->ihl * 4 - sizeof(struct iphdr) +
1013 + sizeof(struct udphdr);
1014 +
1015 + if (!pskb_may_pull(skb, access_len))
1016 + return NULL;
1017 +
1018 + pos += iph->ihl * 4;
1019 + udph = (struct udphdr *)pos;
1020 + if (ntohs(udph->dest) != 319)
1021 + return NULL;
1022 + ptp_loc = pos + sizeof(struct udphdr);
1023 + break;
1024 + /* Transport of PTP over IPv6 */
1025 + case ETH_P_IPV6:
1026 + ipv6h = (struct ipv6hdr *)pos;
1027 +
1028 + access_len += sizeof(struct ipv6hdr) + sizeof(struct udphdr);
1029 +
1030 + if (ntohs(ipv6h->nexthdr) != IPPROTO_UDP)
1031 + return NULL;
1032 +
1033 + pos += sizeof(struct ipv6hdr);
1034 + udph = (struct udphdr *)pos;
1035 + if (ntohs(udph->dest) != 319)
1036 + return NULL;
1037 + ptp_loc = pos + sizeof(struct udphdr);
1038 + break;
1039 + default:
1040 + break;
1041 + }
1042 +
1043 + return ptp_loc;
1044 +}
1045 +
1046 +static int dpa_ptp_store_stamp(const struct dpa_priv_s *priv,
1047 + struct sk_buff *skb, void *data, enum port_type rx_tx,
1048 + struct dpa_ptp_data *ptp_data)
1049 +{
1050 + u64 nsec;
1051 + u32 mod;
1052 + u8 *ptp_loc;
1053 + u16 eth_type;
1054 +
1055 + ptp_loc = dpa_ptp_parse_packet(skb, &eth_type);
1056 + if (!ptp_loc)
1057 + return -EINVAL;
1058 +
1059 + switch (eth_type) {
1060 + case ETH_P_IP:
1061 + ptp_data->ident.netw_prot = DPA_PTP_PROT_IPV4;
1062 + break;
1063 + case ETH_P_IPV6:
1064 + ptp_data->ident.netw_prot = DPA_PTP_PROT_IPV6;
1065 + break;
1066 + case ETH_P_1588:
1067 + ptp_data->ident.netw_prot = DPA_PTP_PROT_802_3;
1068 + break;
1069 + default:
1070 + return -EINVAL;
1071 + }
1072 +
1073 + if (!pskb_may_pull(skb, ptp_loc - skb->data + PTP_OFFS_SEQ_ID + 2))
1074 + return -EINVAL;
1075 +
1076 + ptp_data->ident.version = *(ptp_loc + PTP_OFFS_VER_PTP) & 0xf;
1077 + ptp_data->ident.msg_type = *(ptp_loc + PTP_OFFS_MSG_TYPE) & 0xf;
1078 + ptp_data->ident.seq_id = *((u16 *)(ptp_loc + PTP_OFFS_SEQ_ID));
1079 + memcpy(ptp_data->ident.snd_port_id, ptp_loc + PTP_OFFS_SRCPRTID,
1080 + DPA_PTP_SOURCE_PORT_LENGTH);
1081 +
1082 + nsec = dpa_get_timestamp_ns(priv, rx_tx, data);
1083 + mod = do_div(nsec, NANOSEC_PER_SECOND);
1084 + ptp_data->ts.sec = nsec;
1085 + ptp_data->ts.nsec = mod;
1086 +
1087 + return 0;
1088 +}
1089 +
1090 +void dpa_ptp_store_txstamp(const struct dpa_priv_s *priv,
1091 + struct sk_buff *skb, void *data)
1092 +{
1093 + struct dpa_ptp_tsu *tsu = priv->tsu;
1094 + struct dpa_ptp_data ptp_tx_data;
1095 +
1096 + if (dpa_ptp_store_stamp(priv, skb, data, TX, &ptp_tx_data))
1097 + return;
1098 +
1099 + dpa_ptp_insert(&tsu->tx_timestamps, &ptp_tx_data);
1100 +}
1101 +
1102 +void dpa_ptp_store_rxstamp(const struct dpa_priv_s *priv,
1103 + struct sk_buff *skb, void *data)
1104 +{
1105 + struct dpa_ptp_tsu *tsu = priv->tsu;
1106 + struct dpa_ptp_data ptp_rx_data;
1107 +
1108 + if (dpa_ptp_store_stamp(priv, skb, data, RX, &ptp_rx_data))
1109 + return;
1110 +
1111 + dpa_ptp_insert(&tsu->rx_timestamps, &ptp_rx_data);
1112 +}
1113 +
1114 +static uint8_t dpa_get_tx_timestamp(struct dpa_ptp_tsu *ptp_tsu,
1115 + struct dpa_ptp_ident *ident,
1116 + struct dpa_ptp_time *ts)
1117 +{
1118 + struct dpa_ptp_tsu *tsu = ptp_tsu;
1119 + struct dpa_ptp_time tmp;
1120 + int flag;
1121 +
1122 + flag = dpa_ptp_find_and_remove(&tsu->tx_timestamps, ident, &tmp);
1123 + if (!flag) {
1124 + ts->sec = tmp.sec;
1125 + ts->nsec = tmp.nsec;
1126 + return 0;
1127 + }
1128 +
1129 + return -1;
1130 +}
1131 +
1132 +static uint8_t dpa_get_rx_timestamp(struct dpa_ptp_tsu *ptp_tsu,
1133 + struct dpa_ptp_ident *ident,
1134 + struct dpa_ptp_time *ts)
1135 +{
1136 + struct dpa_ptp_tsu *tsu = ptp_tsu;
1137 + struct dpa_ptp_time tmp;
1138 + int flag;
1139 +
1140 + flag = dpa_ptp_find_and_remove(&tsu->rx_timestamps, ident, &tmp);
1141 + if (!flag) {
1142 + ts->sec = tmp.sec;
1143 + ts->nsec = tmp.nsec;
1144 + return 0;
1145 + }
1146 +
1147 + return -1;
1148 +}
1149 +
1150 +static void dpa_set_fiper_alarm(struct dpa_ptp_tsu *tsu,
1151 + struct dpa_ptp_time *cnt_time)
1152 +{
1153 + struct mac_device *mac_dev = tsu->dpa_priv->mac_dev;
1154 + u64 tmp, fiper;
1155 +
1156 + if (mac_dev->fm_rtc_disable)
1157 + mac_dev->fm_rtc_disable(get_fm_handle(tsu->dpa_priv->net_dev));
1158 +
1159 + /* TMR_FIPER1 will pulse every second after ALARM1 expired */
1160 + tmp = (u64)cnt_time->sec * NANOSEC_PER_SECOND + (u64)cnt_time->nsec;
1161 + fiper = NANOSEC_PER_SECOND - DPA_PTP_NOMINAL_FREQ_PERIOD_NS;
1162 + if (mac_dev->fm_rtc_set_alarm)
1163 + mac_dev->fm_rtc_set_alarm(get_fm_handle(tsu->dpa_priv->net_dev),
1164 + 0, tmp);
1165 + if (mac_dev->fm_rtc_set_fiper)
1166 + mac_dev->fm_rtc_set_fiper(get_fm_handle(tsu->dpa_priv->net_dev),
1167 + 0, fiper);
1168 +
1169 + if (mac_dev->fm_rtc_enable)
1170 + mac_dev->fm_rtc_enable(get_fm_handle(tsu->dpa_priv->net_dev));
1171 +}
1172 +
1173 +static void dpa_get_curr_cnt(struct dpa_ptp_tsu *tsu,
1174 + struct dpa_ptp_time *curr_time)
1175 +{
1176 + struct mac_device *mac_dev = tsu->dpa_priv->mac_dev;
1177 + u64 tmp;
1178 + u32 mod;
1179 +
1180 + if (mac_dev->fm_rtc_get_cnt)
1181 + mac_dev->fm_rtc_get_cnt(get_fm_handle(tsu->dpa_priv->net_dev),
1182 + &tmp);
1183 +
1184 + mod = do_div(tmp, NANOSEC_PER_SECOND);
1185 + curr_time->sec = (u32)tmp;
1186 + curr_time->nsec = mod;
1187 +}
1188 +
1189 +static void dpa_set_1588cnt(struct dpa_ptp_tsu *tsu,
1190 + struct dpa_ptp_time *cnt_time)
1191 +{
1192 + struct mac_device *mac_dev = tsu->dpa_priv->mac_dev;
1193 + u64 tmp;
1194 +
1195 + tmp = (u64)cnt_time->sec * NANOSEC_PER_SECOND + (u64)cnt_time->nsec;
1196 +
1197 + if (mac_dev->fm_rtc_set_cnt)
1198 + mac_dev->fm_rtc_set_cnt(get_fm_handle(tsu->dpa_priv->net_dev),
1199 + tmp);
1200 +
1201 + /* Restart fiper two seconds later */
1202 + cnt_time->sec += 2;
1203 + cnt_time->nsec = 0;
1204 + dpa_set_fiper_alarm(tsu, cnt_time);
1205 +}
1206 +
1207 +static void dpa_get_drift(struct dpa_ptp_tsu *tsu, u32 *addend)
1208 +{
1209 + struct mac_device *mac_dev = tsu->dpa_priv->mac_dev;
1210 + u32 drift;
1211 +
1212 + if (mac_dev->fm_rtc_get_drift)
1213 + mac_dev->fm_rtc_get_drift(get_fm_handle(tsu->dpa_priv->net_dev),
1214 + &drift);
1215 +
1216 + *addend = drift;
1217 +}
1218 +
1219 +static void dpa_set_drift(struct dpa_ptp_tsu *tsu, u32 addend)
1220 +{
1221 + struct mac_device *mac_dev = tsu->dpa_priv->mac_dev;
1222 +
1223 + if (mac_dev->fm_rtc_set_drift)
1224 + mac_dev->fm_rtc_set_drift(get_fm_handle(tsu->dpa_priv->net_dev),
1225 + addend);
1226 +}
1227 +
1228 +static void dpa_flush_timestamp(struct dpa_ptp_tsu *tsu)
1229 +{
1230 + dpa_ptp_reset_circ(&tsu->rx_timestamps, DEFAULT_PTP_RX_BUF_SZ);
1231 + dpa_ptp_reset_circ(&tsu->tx_timestamps, DEFAULT_PTP_TX_BUF_SZ);
1232 +}
1233 +
1234 +int dpa_ioctl_1588(struct net_device *dev, struct ifreq *ifr, int cmd)
1235 +{
1236 + struct dpa_priv_s *priv = netdev_priv(dev);
1237 + struct dpa_ptp_tsu *tsu = priv->tsu;
1238 + struct mac_device *mac_dev = priv->mac_dev;
1239 + struct dpa_ptp_data ptp_data;
1240 + struct dpa_ptp_data *ptp_data_user;
1241 + struct dpa_ptp_time act_time;
1242 + u32 addend;
1243 + int retval = 0;
1244 +
1245 + if (!tsu || !tsu->valid)
1246 + return -ENODEV;
1247 +
1248 + switch (cmd) {
1249 + case PTP_ENBL_TXTS_IOCTL:
1250 + tsu->hwts_tx_en_ioctl = 1;
1251 + if (mac_dev->fm_rtc_enable)
1252 + mac_dev->fm_rtc_enable(get_fm_handle(dev));
1253 + if (mac_dev->ptp_enable)
1254 + mac_dev->ptp_enable(mac_dev->get_mac_handle(mac_dev));
1255 + break;
1256 + case PTP_DSBL_TXTS_IOCTL:
1257 + tsu->hwts_tx_en_ioctl = 0;
1258 + if (mac_dev->fm_rtc_disable)
1259 + mac_dev->fm_rtc_disable(get_fm_handle(dev));
1260 + if (mac_dev->ptp_disable)
1261 + mac_dev->ptp_disable(mac_dev->get_mac_handle(mac_dev));
1262 + break;
1263 + case PTP_ENBL_RXTS_IOCTL:
1264 + tsu->hwts_rx_en_ioctl = 1;
1265 + break;
1266 + case PTP_DSBL_RXTS_IOCTL:
1267 + tsu->hwts_rx_en_ioctl = 0;
1268 + break;
1269 + case PTP_GET_RX_TIMESTAMP:
1270 + ptp_data_user = (struct dpa_ptp_data *)ifr->ifr_data;
1271 + if (copy_from_user(&ptp_data.ident,
1272 + &ptp_data_user->ident, sizeof(ptp_data.ident)))
1273 + return -EINVAL;
1274 +
1275 + if (dpa_get_rx_timestamp(tsu, &ptp_data.ident, &ptp_data.ts))
1276 + return -EAGAIN;
1277 +
1278 + if (copy_to_user((void __user *)&ptp_data_user->ts,
1279 + &ptp_data.ts, sizeof(ptp_data.ts)))
1280 + return -EFAULT;
1281 + break;
1282 + case PTP_GET_TX_TIMESTAMP:
1283 + ptp_data_user = (struct dpa_ptp_data *)ifr->ifr_data;
1284 + if (copy_from_user(&ptp_data.ident,
1285 + &ptp_data_user->ident, sizeof(ptp_data.ident)))
1286 + return -EINVAL;
1287 +
1288 + if (dpa_get_tx_timestamp(tsu, &ptp_data.ident, &ptp_data.ts))
1289 + return -EAGAIN;
1290 +
1291 + if (copy_to_user((void __user *)&ptp_data_user->ts,
1292 + &ptp_data.ts, sizeof(ptp_data.ts)))
1293 + return -EFAULT;
1294 + break;
1295 + case PTP_GET_TIME:
1296 + dpa_get_curr_cnt(tsu, &act_time);
1297 + if (copy_to_user(ifr->ifr_data, &act_time, sizeof(act_time)))
1298 + return -EFAULT;
1299 + break;
1300 + case PTP_SET_TIME:
1301 + if (copy_from_user(&act_time, ifr->ifr_data, sizeof(act_time)))
1302 + return -EINVAL;
1303 + dpa_set_1588cnt(tsu, &act_time);
1304 + break;
1305 + case PTP_GET_ADJ:
1306 + dpa_get_drift(tsu, &addend);
1307 + if (copy_to_user(ifr->ifr_data, &addend, sizeof(addend)))
1308 + return -EFAULT;
1309 + break;
1310 + case PTP_SET_ADJ:
1311 + if (copy_from_user(&addend, ifr->ifr_data, sizeof(addend)))
1312 + return -EINVAL;
1313 + dpa_set_drift(tsu, addend);
1314 + break;
1315 + case PTP_SET_FIPER_ALARM:
1316 + if (copy_from_user(&act_time, ifr->ifr_data, sizeof(act_time)))
1317 + return -EINVAL;
1318 + dpa_set_fiper_alarm(tsu, &act_time);
1319 + break;
1320 + case PTP_CLEANUP_TS:
1321 + dpa_flush_timestamp(tsu);
1322 + break;
1323 + default:
1324 + return -EINVAL;
1325 + }
1326 +
1327 + return retval;
1328 +}
1329 +
1330 +int dpa_ptp_init(struct dpa_priv_s *priv)
1331 +{
1332 + struct dpa_ptp_tsu *tsu;
1333 +
1334 + /* Allocate memory for PTP structure */
1335 + tsu = kzalloc(sizeof(struct dpa_ptp_tsu), GFP_KERNEL);
1336 + if (!tsu)
1337 + return -ENOMEM;
1338 +
1339 + tsu->valid = TRUE;
1340 + tsu->dpa_priv = priv;
1341 +
1342 + dpa_ptp_init_circ(&tsu->rx_timestamps, DEFAULT_PTP_RX_BUF_SZ);
1343 + dpa_ptp_init_circ(&tsu->tx_timestamps, DEFAULT_PTP_TX_BUF_SZ);
1344 +
1345 + priv->tsu = tsu;
1346 +
1347 + return 0;
1348 +}
1349 +EXPORT_SYMBOL(dpa_ptp_init);
1350 +
1351 +void dpa_ptp_cleanup(struct dpa_priv_s *priv)
1352 +{
1353 + struct dpa_ptp_tsu *tsu = priv->tsu;
1354 +
1355 + tsu->valid = FALSE;
1356 + vfree(tsu->rx_timestamps.circ_buf.buf);
1357 + vfree(tsu->tx_timestamps.circ_buf.buf);
1358 +
1359 + kfree(tsu);
1360 +}
1361 +EXPORT_SYMBOL(dpa_ptp_cleanup);
1362 --- /dev/null
1363 +++ b/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_1588.h
1364 @@ -0,0 +1,138 @@
1365 +/* Copyright (C) 2011 Freescale Semiconductor, Inc.
1366 + *
1367 + * This program is free software; you can redistribute it and/or modify
1368 + * it under the terms of the GNU General Public License as published by
1369 + * the Free Software Foundation; either version 2 of the License, or
1370 + * (at your option) any later version.
1371 + *
1372 + * This program is distributed in the hope that it will be useful,
1373 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
1374 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1375 + * GNU General Public License for more details.
1376 + *
1377 + * You should have received a copy of the GNU General Public License along
1378 + * with this program; if not, write to the Free Software Foundation, Inc.,
1379 + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
1380 + *
1381 + */
1382 +#ifndef __DPAA_1588_H__
1383 +#define __DPAA_1588_H__
1384 +
1385 +#include <linux/netdevice.h>
1386 +#include <linux/etherdevice.h>
1387 +#include <linux/circ_buf.h>
1388 +#include <linux/fsl_qman.h>
1389 +
1390 +#define DEFAULT_PTP_RX_BUF_SZ 256
1391 +#define DEFAULT_PTP_TX_BUF_SZ 256
1392 +
1393 +/* 1588 private ioctl calls */
1394 +#define PTP_ENBL_TXTS_IOCTL SIOCDEVPRIVATE
1395 +#define PTP_DSBL_TXTS_IOCTL (SIOCDEVPRIVATE + 1)
1396 +#define PTP_ENBL_RXTS_IOCTL (SIOCDEVPRIVATE + 2)
1397 +#define PTP_DSBL_RXTS_IOCTL (SIOCDEVPRIVATE + 3)
1398 +#define PTP_GET_TX_TIMESTAMP (SIOCDEVPRIVATE + 4)
1399 +#define PTP_GET_RX_TIMESTAMP (SIOCDEVPRIVATE + 5)
1400 +#define PTP_SET_TIME (SIOCDEVPRIVATE + 6)
1401 +#define PTP_GET_TIME (SIOCDEVPRIVATE + 7)
1402 +#define PTP_SET_FIPER_ALARM (SIOCDEVPRIVATE + 8)
1403 +#define PTP_SET_ADJ (SIOCDEVPRIVATE + 9)
1404 +#define PTP_GET_ADJ (SIOCDEVPRIVATE + 10)
1405 +#define PTP_CLEANUP_TS (SIOCDEVPRIVATE + 11)
1406 +
1407 +/* PTP V2 message type */
1408 +enum {
1409 + PTP_MSGTYPE_SYNC = 0x0,
1410 + PTP_MSGTYPE_DELREQ = 0x1,
1411 + PTP_MSGTYPE_PDELREQ = 0x2,
1412 + PTP_MSGTYPE_PDELRESP = 0x3,
1413 + PTP_MSGTYPE_FLWUP = 0x8,
1414 + PTP_MSGTYPE_DELRESP = 0x9,
1415 + PTP_MSGTYPE_PDELRES_FLWUP = 0xA,
1416 + PTP_MSGTYPE_ANNOUNCE = 0xB,
1417 + PTP_MSGTYPE_SGNLNG = 0xC,
1418 + PTP_MSGTYPE_MNGMNT = 0xD,
1419 +};
1420 +
1421 +/* Byte offset of data in the PTP V2 headers */
1422 +#define PTP_OFFS_MSG_TYPE 0
1423 +#define PTP_OFFS_VER_PTP 1
1424 +#define PTP_OFFS_MSG_LEN 2
1425 +#define PTP_OFFS_DOM_NMB 4
1426 +#define PTP_OFFS_FLAGS 6
1427 +#define PTP_OFFS_CORFIELD 8
1428 +#define PTP_OFFS_SRCPRTID 20
1429 +#define PTP_OFFS_SEQ_ID 30
1430 +#define PTP_OFFS_CTRL 32
1431 +#define PTP_OFFS_LOGMEAN 33
1432 +
1433 +#define PTP_IP_OFFS 14
1434 +#define PTP_UDP_OFFS 34
1435 +#define PTP_HEADER_OFFS 42
1436 +#define PTP_MSG_TYPE_OFFS (PTP_HEADER_OFFS + PTP_OFFS_MSG_TYPE)
1437 +#define PTP_SPORT_ID_OFFS (PTP_HEADER_OFFS + PTP_OFFS_SRCPRTID)
1438 +#define PTP_SEQ_ID_OFFS (PTP_HEADER_OFFS + PTP_OFFS_SEQ_ID)
1439 +#define PTP_CTRL_OFFS (PTP_HEADER_OFFS + PTP_OFFS_CTRL)
1440 +
1441 +/* 1588-2008 network protocol enumeration values */
1442 +#define DPA_PTP_PROT_IPV4 1
1443 +#define DPA_PTP_PROT_IPV6 2
1444 +#define DPA_PTP_PROT_802_3 3
1445 +#define DPA_PTP_PROT_DONTCARE 0xFFFF
1446 +
1447 +#define DPA_PTP_SOURCE_PORT_LENGTH 10
1448 +#define DPA_PTP_HEADER_SZE 34
1449 +#define DPA_ETYPE_LEN 2
1450 +#define DPA_VLAN_TAG_LEN 4
1451 +#define NANOSEC_PER_SECOND 1000000000
1452 +
1453 +/* The threshold between the current found one and the oldest one */
1454 +#define TS_ACCUMULATION_THRESHOLD 50
1455 +
1456 +/* Struct needed to identify a timestamp */
1457 +struct dpa_ptp_ident {
1458 + u8 version;
1459 + u8 msg_type;
1460 + u16 netw_prot;
1461 + u16 seq_id;
1462 + u8 snd_port_id[DPA_PTP_SOURCE_PORT_LENGTH];
1463 +};
1464 +
1465 +/* Timestamp format in 1588-2008 */
1466 +struct dpa_ptp_time {
1467 + u64 sec; /* just 48 bit used */
1468 + u32 nsec;
1469 +};
1470 +
1471 +/* needed for timestamp data over ioctl */
1472 +struct dpa_ptp_data {
1473 + struct dpa_ptp_ident ident;
1474 + struct dpa_ptp_time ts;
1475 +};
1476 +
1477 +struct dpa_ptp_circ_buf {
1478 + struct circ_buf circ_buf;
1479 + u32 size;
1480 + spinlock_t ptp_lock;
1481 +};
1482 +
1483 +/* PTP TSU control structure */
1484 +struct dpa_ptp_tsu {
1485 + struct dpa_priv_s *dpa_priv;
1486 + bool valid;
1487 + struct dpa_ptp_circ_buf rx_timestamps;
1488 + struct dpa_ptp_circ_buf tx_timestamps;
1489 +
1490 + /* HW timestamping over ioctl enabled flag */
1491 + int hwts_tx_en_ioctl;
1492 + int hwts_rx_en_ioctl;
1493 +};
1494 +
1495 +extern int dpa_ptp_init(struct dpa_priv_s *priv);
1496 +extern void dpa_ptp_cleanup(struct dpa_priv_s *priv);
1497 +extern void dpa_ptp_store_txstamp(const struct dpa_priv_s *priv,
1498 + struct sk_buff *skb, void *data);
1499 +extern void dpa_ptp_store_rxstamp(const struct dpa_priv_s *priv,
1500 + struct sk_buff *skb, void *data);
1501 +extern int dpa_ioctl_1588(struct net_device *dev, struct ifreq *ifr, int cmd);
1502 +#endif
1503 --- /dev/null
1504 +++ b/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_debugfs.c
1505 @@ -0,0 +1,180 @@
1506 +/* Copyright 2008-2013 Freescale Semiconductor Inc.
1507 + *
1508 + * Redistribution and use in source and binary forms, with or without
1509 + * modification, are permitted provided that the following conditions are met:
1510 + * * Redistributions of source code must retain the above copyright
1511 + * notice, this list of conditions and the following disclaimer.
1512 + * * Redistributions in binary form must reproduce the above copyright
1513 + * notice, this list of conditions and the following disclaimer in the
1514 + * documentation and/or other materials provided with the distribution.
1515 + * * Neither the name of Freescale Semiconductor nor the
1516 + * names of its contributors may be used to endorse or promote products
1517 + * derived from this software without specific prior written permission.
1518 + *
1519 + *
1520 + * ALTERNATIVELY, this software may be distributed under the terms of the
1521 + * GNU General Public License ("GPL") as published by the Free Software
1522 + * Foundation, either version 2 of that License or (at your option) any
1523 + * later version.
1524 + *
1525 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
1526 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
1527 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
1528 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
1529 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
1530 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
1531 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
1532 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
1533 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
1534 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
1535 + */
1536 +
1537 +#include <linux/module.h>
1538 +#include <linux/fsl_qman.h> /* struct qm_mcr_querycgr */
1539 +#include <linux/debugfs.h>
1540 +#include "dpaa_debugfs.h"
1541 +#include "dpaa_eth.h" /* struct dpa_priv_s, dpa_percpu_priv_s, dpa_bp */
1542 +
1543 +#define DPA_DEBUGFS_DESCRIPTION "FSL DPAA Ethernet debugfs entries"
1544 +#define DPA_ETH_DEBUGFS_ROOT "fsl_dpa"
1545 +
1546 +static struct dentry *dpa_debugfs_root;
1547 +
1548 +static int __cold dpa_debugfs_loop_open(struct inode *inode, struct file *file);
1549 +static ssize_t dpa_loop_write(struct file *f,
1550 + const char __user *buf, size_t count, loff_t *off);
1551 +
1552 +static const struct file_operations dpa_debugfs_lp_fops = {
1553 + .open = dpa_debugfs_loop_open,
1554 + .write = dpa_loop_write,
1555 + .read = seq_read,
1556 + .llseek = seq_lseek,
1557 + .release = single_release,
1558 +};
1559 +
1560 +static int dpa_debugfs_loop_show(struct seq_file *file, void *offset)
1561 +{
1562 + struct dpa_priv_s *priv;
1563 +
1564 + BUG_ON(offset == NULL);
1565 +
1566 + priv = netdev_priv((struct net_device *)file->private);
1567 + seq_printf(file, "%d->%d\n", priv->loop_id, priv->loop_to);
1568 +
1569 + return 0;
1570 +}
1571 +
1572 +static int user_input_convert(const char __user *user_buf, size_t count,
1573 + long *val)
1574 +{
1575 + char buf[12];
1576 +
1577 + if (count > sizeof(buf) - 1)
1578 + return -EINVAL;
1579 + if (copy_from_user(buf, user_buf, count))
1580 + return -EFAULT;
1581 + buf[count] = '\0';
1582 + if (kstrtol(buf, 0, val))
1583 + return -EINVAL;
1584 + return 0;
1585 +}
1586 +
1587 +static ssize_t dpa_loop_write(struct file *f,
1588 + const char __user *buf, size_t count, loff_t *off)
1589 +{
1590 + struct dpa_priv_s *priv;
1591 + struct net_device *netdev;
1592 + struct seq_file *sf;
1593 + int ret;
1594 + long val;
1595 +
1596 + ret = user_input_convert(buf, count, &val);
1597 + if (ret)
1598 + return ret;
1599 +
1600 + sf = (struct seq_file *)f->private_data;
1601 + netdev = (struct net_device *)sf->private;
1602 + priv = netdev_priv(netdev);
1603 +
1604 + priv->loop_to = ((val < 0) || (val > 20)) ? -1 : val;
1605 +
1606 + return count;
1607 +}
1608 +
1609 +static int __cold dpa_debugfs_loop_open(struct inode *inode, struct file *file)
1610 +{
1611 + int _errno;
1612 + const struct net_device *net_dev;
1613 +
1614 + _errno = single_open(file, dpa_debugfs_loop_show, inode->i_private);
1615 + if (unlikely(_errno < 0)) {
1616 + net_dev = (struct net_device *)inode->i_private;
1617 +
1618 + if (netif_msg_drv((struct dpa_priv_s *)netdev_priv(net_dev)))
1619 + netdev_err(net_dev, "single_open() = %d\n",
1620 + _errno);
1621 + }
1622 +
1623 + return _errno;
1624 +}
1625 +
1626 +
1627 +int dpa_netdev_debugfs_create(struct net_device *net_dev)
1628 +{
1629 + struct dpa_priv_s *priv = netdev_priv(net_dev);
1630 + static int cnt;
1631 + char loop_file_name[100];
1632 +
1633 + if (unlikely(dpa_debugfs_root == NULL)) {
1634 + pr_err(KBUILD_MODNAME ": %s:%hu:%s(): \t%s\n",
1635 + KBUILD_BASENAME".c", __LINE__, __func__,
1636 + "root debugfs missing, possible module ordering issue");
1637 + return -ENOMEM;
1638 + }
1639 +
1640 + sprintf(loop_file_name, "eth%d_loop", ++cnt);
1641 + priv->debugfs_loop_file = debugfs_create_file(loop_file_name,
1642 + S_IRUGO,
1643 + dpa_debugfs_root,
1644 + net_dev,
1645 + &dpa_debugfs_lp_fops);
1646 + if (unlikely(priv->debugfs_loop_file == NULL)) {
1647 + netdev_err(net_dev, "debugfs_create_file(%s/%s)",
1648 + dpa_debugfs_root->d_iname,
1649 + loop_file_name);
1650 +
1651 + return -ENOMEM;
1652 + }
1653 + return 0;
1654 +}
1655 +
1656 +void dpa_netdev_debugfs_remove(struct net_device *net_dev)
1657 +{
1658 + struct dpa_priv_s *priv = netdev_priv(net_dev);
1659 +
1660 + debugfs_remove(priv->debugfs_loop_file);
1661 +}
1662 +
1663 +int __init dpa_debugfs_module_init(void)
1664 +{
1665 + int _errno = 0;
1666 +
1667 + pr_info(KBUILD_MODNAME ": " DPA_DEBUGFS_DESCRIPTION "\n");
1668 +
1669 + dpa_debugfs_root = debugfs_create_dir(DPA_ETH_DEBUGFS_ROOT, NULL);
1670 +
1671 + if (unlikely(dpa_debugfs_root == NULL)) {
1672 + _errno = -ENOMEM;
1673 + pr_err(KBUILD_MODNAME ": %s:%hu:%s():\n",
1674 + KBUILD_BASENAME".c", __LINE__, __func__);
1675 + pr_err("\tdebugfs_create_dir(%s/"KBUILD_MODNAME") = %d\n",
1676 + DPA_ETH_DEBUGFS_ROOT, _errno);
1677 + }
1678 +
1679 + return _errno;
1680 +}
1681 +
1682 +void __exit dpa_debugfs_module_exit(void)
1683 +{
1684 + debugfs_remove(dpa_debugfs_root);
1685 +}
1686 --- /dev/null
1687 +++ b/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_debugfs.h
1688 @@ -0,0 +1,43 @@
1689 +/* Copyright 2008-2013 Freescale Semiconductor Inc.
1690 + *
1691 + * Redistribution and use in source and binary forms, with or without
1692 + * modification, are permitted provided that the following conditions are met:
1693 + * * Redistributions of source code must retain the above copyright
1694 + * notice, this list of conditions and the following disclaimer.
1695 + * * Redistributions in binary form must reproduce the above copyright
1696 + * notice, this list of conditions and the following disclaimer in the
1697 + * documentation and/or other materials provided with the distribution.
1698 + * * Neither the name of Freescale Semiconductor nor the
1699 + * names of its contributors may be used to endorse or promote products
1700 + * derived from this software without specific prior written permission.
1701 + *
1702 + *
1703 + * ALTERNATIVELY, this software may be distributed under the terms of the
1704 + * GNU General Public License ("GPL") as published by the Free Software
1705 + * Foundation, either version 2 of that License or (at your option) any
1706 + * later version.
1707 + *
1708 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
1709 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
1710 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
1711 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
1712 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
1713 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
1714 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
1715 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
1716 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
1717 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
1718 + */
1719 +
1720 +#ifndef DPAA_DEBUGFS_H_
1721 +#define DPAA_DEBUGFS_H_
1722 +
1723 +#include <linux/netdevice.h>
1724 +#include <linux/dcache.h> /* struct dentry needed in dpaa_eth.h */
1725 +
1726 +int dpa_netdev_debugfs_create(struct net_device *net_dev);
1727 +void dpa_netdev_debugfs_remove(struct net_device *net_dev);
1728 +int __init dpa_debugfs_module_init(void);
1729 +void __exit dpa_debugfs_module_exit(void);
1730 +
1731 +#endif /* DPAA_DEBUGFS_H_ */
1732 --- /dev/null
1733 +++ b/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth.c
1734 @@ -0,0 +1,1224 @@
1735 +/* Copyright 2008-2013 Freescale Semiconductor Inc.
1736 + *
1737 + * Redistribution and use in source and binary forms, with or without
1738 + * modification, are permitted provided that the following conditions are met:
1739 + * * Redistributions of source code must retain the above copyright
1740 + * notice, this list of conditions and the following disclaimer.
1741 + * * Redistributions in binary form must reproduce the above copyright
1742 + * notice, this list of conditions and the following disclaimer in the
1743 + * documentation and/or other materials provided with the distribution.
1744 + * * Neither the name of Freescale Semiconductor nor the
1745 + * names of its contributors may be used to endorse or promote products
1746 + * derived from this software without specific prior written permission.
1747 + *
1748 + *
1749 + * ALTERNATIVELY, this software may be distributed under the terms of the
1750 + * GNU General Public License ("GPL") as published by the Free Software
1751 + * Foundation, either version 2 of that License or (at your option) any
1752 + * later version.
1753 + *
1754 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
1755 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
1756 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
1757 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
1758 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
1759 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
1760 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
1761 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
1762 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
1763 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
1764 + */
1765 +
1766 +#ifdef CONFIG_FSL_DPAA_ETH_DEBUG
1767 +#define pr_fmt(fmt) \
1768 + KBUILD_MODNAME ": %s:%hu:%s() " fmt, \
1769 + KBUILD_BASENAME".c", __LINE__, __func__
1770 +#else
1771 +#define pr_fmt(fmt) \
1772 + KBUILD_MODNAME ": " fmt
1773 +#endif
1774 +
1775 +#include <linux/init.h>
1776 +#include <linux/module.h>
1777 +#include <linux/of_mdio.h>
1778 +#include <linux/of_net.h>
1779 +#include <linux/kthread.h>
1780 +#include <linux/io.h>
1781 +#include <linux/if_arp.h> /* arp_hdr_len() */
1782 +#include <linux/if_vlan.h> /* VLAN_HLEN */
1783 +#include <linux/icmp.h> /* struct icmphdr */
1784 +#include <linux/ip.h> /* struct iphdr */
1785 +#include <linux/ipv6.h> /* struct ipv6hdr */
1786 +#include <linux/udp.h> /* struct udphdr */
1787 +#include <linux/tcp.h> /* struct tcphdr */
1788 +#include <linux/net.h> /* net_ratelimit() */
1789 +#include <linux/if_ether.h> /* ETH_P_IP and ETH_P_IPV6 */
1790 +#include <linux/highmem.h>
1791 +#include <linux/percpu.h>
1792 +#include <linux/dma-mapping.h>
1793 +#include <linux/fsl_bman.h>
1794 +#ifdef CONFIG_SOC_BUS
1795 +#include <linux/sys_soc.h> /* soc_device_match */
1796 +#endif
1797 +
1798 +#include "fsl_fman.h"
1799 +#include "fm_ext.h"
1800 +#include "fm_port_ext.h"
1801 +
1802 +#include "mac.h"
1803 +#include "dpaa_eth.h"
1804 +#include "dpaa_eth_common.h"
1805 +#ifdef CONFIG_FSL_DPAA_DBG_LOOP
1806 +#include "dpaa_debugfs.h"
1807 +#endif /* CONFIG_FSL_DPAA_DBG_LOOP */
1808 +
1809 +/* CREATE_TRACE_POINTS only needs to be defined once. Other dpa files
1810 + * using trace events only need to #include <trace/events/sched.h>
1811 + */
1812 +#define CREATE_TRACE_POINTS
1813 +#include "dpaa_eth_trace.h"
1814 +
1815 +#define DPA_NAPI_WEIGHT 64
1816 +
1817 +/* Valid checksum indication */
1818 +#define DPA_CSUM_VALID 0xFFFF
1819 +
1820 +#define DPA_DESCRIPTION "FSL DPAA Ethernet driver"
1821 +
1822 +MODULE_LICENSE("Dual BSD/GPL");
1823 +
1824 +MODULE_AUTHOR("Andy Fleming <afleming@freescale.com>");
1825 +
1826 +MODULE_DESCRIPTION(DPA_DESCRIPTION);
1827 +
1828 +static uint8_t debug = -1;
1829 +module_param(debug, byte, S_IRUGO);
1830 +MODULE_PARM_DESC(debug, "Module/Driver verbosity level");
1831 +
1832 +/* This has to work in tandem with the DPA_CS_THRESHOLD_xxx values. */
1833 +static uint16_t tx_timeout = 1000;
1834 +module_param(tx_timeout, ushort, S_IRUGO);
1835 +MODULE_PARM_DESC(tx_timeout, "The Tx timeout in ms");
1836 +
1837 +static const char rtx[][3] = {
1838 + [RX] = "RX",
1839 + [TX] = "TX"
1840 +};
1841 +
1842 +#ifndef CONFIG_PPC
1843 +bool dpaa_errata_a010022;
1844 +EXPORT_SYMBOL(dpaa_errata_a010022);
1845 +#endif
1846 +
1847 +/* BM */
1848 +
1849 +#define DPAA_ETH_MAX_PAD (L1_CACHE_BYTES * 8)
1850 +
1851 +static uint8_t dpa_priv_common_bpid;
1852 +
1853 +#ifdef CONFIG_FSL_DPAA_DBG_LOOP
1854 +struct net_device *dpa_loop_netdevs[20];
1855 +#endif
1856 +
1857 +#ifdef CONFIG_PM
1858 +
1859 +static int dpaa_suspend(struct device *dev)
1860 +{
1861 + struct net_device *net_dev;
1862 + struct dpa_priv_s *priv;
1863 + struct mac_device *mac_dev;
1864 + int err = 0;
1865 +
1866 + net_dev = dev_get_drvdata(dev);
1867 +
1868 + if (net_dev->flags & IFF_UP) {
1869 + priv = netdev_priv(net_dev);
1870 + mac_dev = priv->mac_dev;
1871 +
1872 + if (priv->wol & DPAA_WOL_MAGIC) {
1873 + err = priv->mac_dev->set_wol(mac_dev->port_dev[RX],
1874 + priv->mac_dev->get_mac_handle(mac_dev), true);
1875 + if (err) {
1876 + netdev_err(net_dev, "set_wol() = %d\n", err);
1877 + goto set_wol_failed;
1878 + }
1879 + }
1880 +
1881 + err = fm_port_suspend(mac_dev->port_dev[RX]);
1882 + if (err) {
1883 + netdev_err(net_dev, "fm_port_suspend(RX) = %d\n", err);
1884 + goto rx_port_suspend_failed;
1885 + }
1886 +
1887 + err = fm_port_suspend(mac_dev->port_dev[TX]);
1888 + if (err) {
1889 + netdev_err(net_dev, "fm_port_suspend(TX) = %d\n", err);
1890 + goto tx_port_suspend_failed;
1891 + }
1892 + }
1893 +
1894 + return 0;
1895 +
1896 +tx_port_suspend_failed:
1897 + fm_port_resume(mac_dev->port_dev[RX]);
1898 +rx_port_suspend_failed:
1899 + if (priv->wol & DPAA_WOL_MAGIC) {
1900 + priv->mac_dev->set_wol(mac_dev->port_dev[RX],
1901 + priv->mac_dev->get_mac_handle(mac_dev), false);
1902 + }
1903 +set_wol_failed:
1904 + return err;
1905 +}
1906 +
1907 +static int dpaa_resume(struct device *dev)
1908 +{
1909 + struct net_device *net_dev;
1910 + struct dpa_priv_s *priv;
1911 + struct mac_device *mac_dev;
1912 + int err = 0;
1913 +
1914 + net_dev = dev_get_drvdata(dev);
1915 +
1916 + if (net_dev->flags & IFF_UP) {
1917 + priv = netdev_priv(net_dev);
1918 + mac_dev = priv->mac_dev;
1919 +
1920 + err = fm_mac_resume(mac_dev->get_mac_handle(mac_dev));
1921 + if (err) {
1922 + netdev_err(net_dev, "fm_mac_resume = %d\n", err);
1923 + goto resume_failed;
1924 + }
1925 +
1926 + err = fm_port_resume(mac_dev->port_dev[TX]);
1927 + if (err) {
1928 + netdev_err(net_dev, "fm_port_resume(TX) = %d\n", err);
1929 + goto resume_failed;
1930 + }
1931 +
1932 + err = fm_port_resume(mac_dev->port_dev[RX]);
1933 + if (err) {
1934 + netdev_err(net_dev, "fm_port_resume(RX) = %d\n", err);
1935 + goto resume_failed;
1936 + }
1937 +
1938 + if (priv->wol & DPAA_WOL_MAGIC) {
1939 + err = priv->mac_dev->set_wol(mac_dev->port_dev[RX],
1940 + priv->mac_dev->get_mac_handle(mac_dev), false);
1941 + if (err) {
1942 + netdev_err(net_dev, "set_wol() = %d\n", err);
1943 + goto resume_failed;
1944 + }
1945 + }
1946 + }
1947 +
1948 + return 0;
1949 +
1950 +resume_failed:
1951 + return err;
1952 +}
1953 +
1954 +static const struct dev_pm_ops dpaa_pm_ops = {
1955 + .suspend = dpaa_suspend,
1956 + .resume = dpaa_resume,
1957 +};
1958 +
1959 +#define DPAA_PM_OPS (&dpaa_pm_ops)
1960 +
1961 +#else /* CONFIG_PM */
1962 +
1963 +#define DPAA_PM_OPS NULL
1964 +
1965 +#endif /* CONFIG_PM */
1966 +
1967 +/* Checks whether the checksum field in Parse Results array is valid
1968 + * (equals 0xFFFF) and increments the .cse counter otherwise
1969 + */
1970 +static inline void
1971 +dpa_csum_validation(const struct dpa_priv_s *priv,
1972 + struct dpa_percpu_priv_s *percpu_priv,
1973 + const struct qm_fd *fd)
1974 +{
1975 + dma_addr_t addr = qm_fd_addr(fd);
1976 + struct dpa_bp *dpa_bp = priv->dpa_bp;
1977 + void *frm = phys_to_virt(addr);
1978 + fm_prs_result_t *parse_result;
1979 +
1980 + if (unlikely(!frm))
1981 + return;
1982 +
1983 + dma_sync_single_for_cpu(dpa_bp->dev, addr, DPA_RX_PRIV_DATA_SIZE +
1984 + DPA_PARSE_RESULTS_SIZE, DMA_BIDIRECTIONAL);
1985 +
1986 + parse_result = (fm_prs_result_t *)(frm + DPA_RX_PRIV_DATA_SIZE);
1987 +
1988 + if (parse_result->cksum != DPA_CSUM_VALID)
1989 + percpu_priv->rx_errors.cse++;
1990 +}
1991 +
1992 +static void _dpa_rx_error(struct net_device *net_dev,
1993 + const struct dpa_priv_s *priv,
1994 + struct dpa_percpu_priv_s *percpu_priv,
1995 + const struct qm_fd *fd,
1996 + u32 fqid)
1997 +{
1998 + /* limit common, possibly innocuous Rx FIFO Overflow errors'
1999 + * interference with zero-loss convergence benchmark results.
2000 + */
2001 + if (likely(fd->status & FM_FD_STAT_ERR_PHYSICAL))
2002 + pr_warn_once("fsl-dpa: non-zero error counters in fman statistics (sysfs)\n");
2003 + else
2004 + if (netif_msg_hw(priv) && net_ratelimit())
2005 + netdev_dbg(net_dev, "Err FD status = 0x%08x\n",
2006 + fd->status & FM_FD_STAT_RX_ERRORS);
2007 +#ifdef CONFIG_FSL_DPAA_HOOKS
2008 + if (dpaa_eth_hooks.rx_error &&
2009 + dpaa_eth_hooks.rx_error(net_dev, fd, fqid) == DPAA_ETH_STOLEN)
2010 + /* it's up to the hook to perform resource cleanup */
2011 + return;
2012 +#endif
2013 + percpu_priv->stats.rx_errors++;
2014 +
2015 + if (fd->status & FM_PORT_FRM_ERR_DMA)
2016 + percpu_priv->rx_errors.dme++;
2017 + if (fd->status & FM_PORT_FRM_ERR_PHYSICAL)
2018 + percpu_priv->rx_errors.fpe++;
2019 + if (fd->status & FM_PORT_FRM_ERR_SIZE)
2020 + percpu_priv->rx_errors.fse++;
2021 + if (fd->status & FM_PORT_FRM_ERR_PRS_HDR_ERR)
2022 + percpu_priv->rx_errors.phe++;
2023 + if (fd->status & FM_FD_STAT_L4CV)
2024 + dpa_csum_validation(priv, percpu_priv, fd);
2025 +
2026 + dpa_fd_release(net_dev, fd);
2027 +}
2028 +
2029 +static void _dpa_tx_error(struct net_device *net_dev,
2030 + const struct dpa_priv_s *priv,
2031 + struct dpa_percpu_priv_s *percpu_priv,
2032 + const struct qm_fd *fd,
2033 + u32 fqid)
2034 +{
2035 + struct sk_buff *skb;
2036 +
2037 + if (netif_msg_hw(priv) && net_ratelimit())
2038 + netdev_warn(net_dev, "FD status = 0x%08x\n",
2039 + fd->status & FM_FD_STAT_TX_ERRORS);
2040 +#ifdef CONFIG_FSL_DPAA_HOOKS
2041 + if (dpaa_eth_hooks.tx_error &&
2042 + dpaa_eth_hooks.tx_error(net_dev, fd, fqid) == DPAA_ETH_STOLEN)
2043 + /* now the hook must ensure proper cleanup */
2044 + return;
2045 +#endif
2046 + percpu_priv->stats.tx_errors++;
2047 +
2048 + /* If we intended the buffers from this frame to go into the bpools
2049 + * when the FMan transmit was done, we need to put it in manually.
2050 + */
2051 + if (fd->bpid != 0xff) {
2052 + dpa_fd_release(net_dev, fd);
2053 + return;
2054 + }
2055 +
2056 + skb = _dpa_cleanup_tx_fd(priv, fd);
2057 + dev_kfree_skb(skb);
2058 +}
2059 +
2060 +/* Helper function to factor out frame validation logic on all Rx paths. Its
2061 + * purpose is to extract from the Parse Results structure information about
2062 + * the integrity of the frame, its checksum, the length of the parsed headers
2063 + * and whether the frame is suitable for GRO.
2064 + *
2065 + * Assumes no parser errors, since any error frame is dropped before this
2066 + * function is called.
2067 + *
2068 + * @skb will have its ip_summed field overwritten;
2069 + * @use_gro will only be written with 0, if the frame is definitely not
2070 + * GRO-able; otherwise, it will be left unchanged;
2071 + * @hdr_size will be written with a safe value, at least the size of the
2072 + * headers' length.
2073 + */
2074 +void __hot _dpa_process_parse_results(const fm_prs_result_t *parse_results,
2075 + const struct qm_fd *fd,
2076 + struct sk_buff *skb, int *use_gro)
2077 +{
2078 + if (fd->status & FM_FD_STAT_L4CV) {
2079 + /* The parser has run and performed L4 checksum validation.
2080 + * We know there were no parser errors (and implicitly no
2081 + * L4 csum error), otherwise we wouldn't be here.
2082 + */
2083 + skb->ip_summed = CHECKSUM_UNNECESSARY;
2084 +
2085 + /* Don't go through GRO for certain types of traffic that
2086 + * we know are not GRO-able, such as dgram-based protocols.
2087 + * In the worst-case scenarios, such as small-pkt terminating
2088 + * UDP, the extra GRO processing would be overkill.
2089 + *
2090 + * The only protocol the Parser supports that is also GRO-able
2091 + * is currently TCP.
2092 + */
2093 + if (!fm_l4_frame_is_tcp(parse_results))
2094 + *use_gro = 0;
2095 +
2096 + return;
2097 + }
2098 +
2099 + /* We're here because either the parser didn't run or the L4 checksum
2100 + * was not verified. This may include the case of a UDP frame with
2101 + * checksum zero or an L4 proto other than TCP/UDP
2102 + */
2103 + skb->ip_summed = CHECKSUM_NONE;
2104 +
2105 + /* Bypass GRO for unknown traffic or if no PCDs are applied */
2106 + *use_gro = 0;
2107 +}
2108 +
2109 +int dpaa_eth_poll(struct napi_struct *napi, int budget)
2110 +{
2111 + struct dpa_napi_portal *np =
2112 + container_of(napi, struct dpa_napi_portal, napi);
2113 +
2114 + int cleaned = qman_p_poll_dqrr(np->p, budget);
2115 +
2116 + if (cleaned < budget) {
2117 + int tmp;
2118 + napi_complete(napi);
2119 + tmp = qman_p_irqsource_add(np->p, QM_PIRQ_DQRI);
2120 + DPA_BUG_ON(tmp);
2121 + }
2122 +
2123 + return cleaned;
2124 +}
2125 +EXPORT_SYMBOL(dpaa_eth_poll);
2126 +
2127 +static void __hot _dpa_tx_conf(struct net_device *net_dev,
2128 + const struct dpa_priv_s *priv,
2129 + struct dpa_percpu_priv_s *percpu_priv,
2130 + const struct qm_fd *fd,
2131 + u32 fqid)
2132 +{
2133 + struct sk_buff *skb;
2134 +
2135 + /* do we need the timestamp for the error frames? */
2136 +
2137 + if (unlikely(fd->status & FM_FD_STAT_TX_ERRORS) != 0) {
2138 + if (netif_msg_hw(priv) && net_ratelimit())
2139 + netdev_warn(net_dev, "FD status = 0x%08x\n",
2140 + fd->status & FM_FD_STAT_TX_ERRORS);
2141 +
2142 + percpu_priv->stats.tx_errors++;
2143 + }
2144 +
2145 + /* hopefully we need not get the timestamp before the hook */
2146 +#ifdef CONFIG_FSL_DPAA_HOOKS
2147 + if (dpaa_eth_hooks.tx_confirm && dpaa_eth_hooks.tx_confirm(net_dev,
2148 + fd, fqid) == DPAA_ETH_STOLEN)
2149 + /* it's the hook that must now perform cleanup */
2150 + return;
2151 +#endif
2152 + /* This might not perfectly reflect the reality, if the core dequeuing
2153 + * the Tx confirmation is different from the one that did the enqueue,
2154 + * but at least it'll show up in the total count.
2155 + */
2156 + percpu_priv->tx_confirm++;
2157 +
2158 + skb = _dpa_cleanup_tx_fd(priv, fd);
2159 +
2160 + dev_kfree_skb(skb);
2161 +}
2162 +
2163 +enum qman_cb_dqrr_result
2164 +priv_rx_error_dqrr(struct qman_portal *portal,
2165 + struct qman_fq *fq,
2166 + const struct qm_dqrr_entry *dq)
2167 +{
2168 + struct net_device *net_dev;
2169 + struct dpa_priv_s *priv;
2170 + struct dpa_percpu_priv_s *percpu_priv;
2171 + int *count_ptr;
2172 +
2173 + net_dev = ((struct dpa_fq *)fq)->net_dev;
2174 + priv = netdev_priv(net_dev);
2175 +
2176 + percpu_priv = raw_cpu_ptr(priv->percpu_priv);
2177 + count_ptr = raw_cpu_ptr(priv->dpa_bp->percpu_count);
2178 +
2179 + if (dpaa_eth_napi_schedule(percpu_priv, portal))
2180 + return qman_cb_dqrr_stop;
2181 +
2182 + if (unlikely(dpaa_eth_refill_bpools(priv->dpa_bp, count_ptr)))
2183 + /* Unable to refill the buffer pool due to insufficient
2184 + * system memory. Just release the frame back into the pool,
2185 + * otherwise we'll soon end up with an empty buffer pool.
2186 + */
2187 + dpa_fd_release(net_dev, &dq->fd);
2188 + else
2189 + _dpa_rx_error(net_dev, priv, percpu_priv, &dq->fd, fq->fqid);
2190 +
2191 + return qman_cb_dqrr_consume;
2192 +}
2193 +
2194 +
2195 +enum qman_cb_dqrr_result __hot
2196 +priv_rx_default_dqrr(struct qman_portal *portal,
2197 + struct qman_fq *fq,
2198 + const struct qm_dqrr_entry *dq)
2199 +{
2200 + struct net_device *net_dev;
2201 + struct dpa_priv_s *priv;
2202 + struct dpa_percpu_priv_s *percpu_priv;
2203 + int *count_ptr;
2204 + struct dpa_bp *dpa_bp;
2205 +
2206 + net_dev = ((struct dpa_fq *)fq)->net_dev;
2207 + priv = netdev_priv(net_dev);
2208 + dpa_bp = priv->dpa_bp;
2209 +
2210 + /* Trace the Rx fd */
2211 + trace_dpa_rx_fd(net_dev, fq, &dq->fd);
2212 +
2213 + /* IRQ handler, non-migratable; safe to use raw_cpu_ptr here */
2214 + percpu_priv = raw_cpu_ptr(priv->percpu_priv);
2215 + count_ptr = raw_cpu_ptr(dpa_bp->percpu_count);
2216 +
2217 + if (unlikely(dpaa_eth_napi_schedule(percpu_priv, portal)))
2218 + return qman_cb_dqrr_stop;
2219 +
2220 + /* Vale of plenty: make sure we didn't run out of buffers */
2221 +
2222 + if (unlikely(dpaa_eth_refill_bpools(dpa_bp, count_ptr)))
2223 + /* Unable to refill the buffer pool due to insufficient
2224 + * system memory. Just release the frame back into the pool,
2225 + * otherwise we'll soon end up with an empty buffer pool.
2226 + */
2227 + dpa_fd_release(net_dev, &dq->fd);
2228 + else
2229 + _dpa_rx(net_dev, portal, priv, percpu_priv, &dq->fd, fq->fqid,
2230 + count_ptr);
2231 +
2232 + return qman_cb_dqrr_consume;
2233 +}
2234 +
2235 +enum qman_cb_dqrr_result
2236 +priv_tx_conf_error_dqrr(struct qman_portal *portal,
2237 + struct qman_fq *fq,
2238 + const struct qm_dqrr_entry *dq)
2239 +{
2240 + struct net_device *net_dev;
2241 + struct dpa_priv_s *priv;
2242 + struct dpa_percpu_priv_s *percpu_priv;
2243 +
2244 + net_dev = ((struct dpa_fq *)fq)->net_dev;
2245 + priv = netdev_priv(net_dev);
2246 +
2247 + percpu_priv = raw_cpu_ptr(priv->percpu_priv);
2248 +
2249 + if (dpaa_eth_napi_schedule(percpu_priv, portal))
2250 + return qman_cb_dqrr_stop;
2251 +
2252 + _dpa_tx_error(net_dev, priv, percpu_priv, &dq->fd, fq->fqid);
2253 +
2254 + return qman_cb_dqrr_consume;
2255 +}
2256 +
2257 +enum qman_cb_dqrr_result __hot
2258 +priv_tx_conf_default_dqrr(struct qman_portal *portal,
2259 + struct qman_fq *fq,
2260 + const struct qm_dqrr_entry *dq)
2261 +{
2262 + struct net_device *net_dev;
2263 + struct dpa_priv_s *priv;
2264 + struct dpa_percpu_priv_s *percpu_priv;
2265 +
2266 + net_dev = ((struct dpa_fq *)fq)->net_dev;
2267 + priv = netdev_priv(net_dev);
2268 +
2269 + /* Trace the fd */
2270 + trace_dpa_tx_conf_fd(net_dev, fq, &dq->fd);
2271 +
2272 + /* Non-migratable context, safe to use raw_cpu_ptr */
2273 + percpu_priv = raw_cpu_ptr(priv->percpu_priv);
2274 +
2275 + if (dpaa_eth_napi_schedule(percpu_priv, portal))
2276 + return qman_cb_dqrr_stop;
2277 +
2278 + _dpa_tx_conf(net_dev, priv, percpu_priv, &dq->fd, fq->fqid);
2279 +
2280 + return qman_cb_dqrr_consume;
2281 +}
2282 +
2283 +void priv_ern(struct qman_portal *portal,
2284 + struct qman_fq *fq,
2285 + const struct qm_mr_entry *msg)
2286 +{
2287 + struct net_device *net_dev;
2288 + const struct dpa_priv_s *priv;
2289 + struct sk_buff *skb;
2290 + struct dpa_percpu_priv_s *percpu_priv;
2291 + struct qm_fd fd = msg->ern.fd;
2292 +
2293 + net_dev = ((struct dpa_fq *)fq)->net_dev;
2294 + priv = netdev_priv(net_dev);
2295 + /* Non-migratable context, safe to use raw_cpu_ptr */
2296 + percpu_priv = raw_cpu_ptr(priv->percpu_priv);
2297 +
2298 + percpu_priv->stats.tx_dropped++;
2299 + percpu_priv->stats.tx_fifo_errors++;
2300 + count_ern(percpu_priv, msg);
2301 +
2302 + /* If we intended this buffer to go into the pool
2303 + * when the FM was done, we need to put it in
2304 + * manually.
2305 + */
2306 + if (msg->ern.fd.bpid != 0xff) {
2307 + dpa_fd_release(net_dev, &fd);
2308 + return;
2309 + }
2310 +
2311 + skb = _dpa_cleanup_tx_fd(priv, &fd);
2312 + dev_kfree_skb_any(skb);
2313 +}
2314 +
2315 +const struct dpa_fq_cbs_t private_fq_cbs = {
2316 + .rx_defq = { .cb = { .dqrr = priv_rx_default_dqrr } },
2317 + .tx_defq = { .cb = { .dqrr = priv_tx_conf_default_dqrr } },
2318 + .rx_errq = { .cb = { .dqrr = priv_rx_error_dqrr } },
2319 + .tx_errq = { .cb = { .dqrr = priv_tx_conf_error_dqrr } },
2320 + .egress_ern = { .cb = { .ern = priv_ern } }
2321 +};
2322 +EXPORT_SYMBOL(private_fq_cbs);
2323 +
2324 +static void dpaa_eth_napi_enable(struct dpa_priv_s *priv)
2325 +{
2326 + struct dpa_percpu_priv_s *percpu_priv;
2327 + int i, j;
2328 +
2329 + for_each_possible_cpu(i) {
2330 + percpu_priv = per_cpu_ptr(priv->percpu_priv, i);
2331 +
2332 + for (j = 0; j < qman_portal_max; j++)
2333 + napi_enable(&percpu_priv->np[j].napi);
2334 + }
2335 +}
2336 +
2337 +static void dpaa_eth_napi_disable(struct dpa_priv_s *priv)
2338 +{
2339 + struct dpa_percpu_priv_s *percpu_priv;
2340 + int i, j;
2341 +
2342 + for_each_possible_cpu(i) {
2343 + percpu_priv = per_cpu_ptr(priv->percpu_priv, i);
2344 +
2345 + for (j = 0; j < qman_portal_max; j++)
2346 + napi_disable(&percpu_priv->np[j].napi);
2347 + }
2348 +}
2349 +
2350 +static int __cold dpa_eth_priv_start(struct net_device *net_dev)
2351 +{
2352 + int err;
2353 + struct dpa_priv_s *priv;
2354 +
2355 + priv = netdev_priv(net_dev);
2356 +
2357 + dpaa_eth_napi_enable(priv);
2358 +
2359 + err = dpa_start(net_dev);
2360 + if (err < 0)
2361 + dpaa_eth_napi_disable(priv);
2362 +
2363 + return err;
2364 +}
2365 +
2366 +
2367 +
2368 +static int __cold dpa_eth_priv_stop(struct net_device *net_dev)
2369 +{
2370 + int _errno;
2371 + struct dpa_priv_s *priv;
2372 +
2373 + _errno = dpa_stop(net_dev);
2374 + /* Allow NAPI to consume any frame still in the Rx/TxConfirm
2375 + * ingress queues. This is to avoid a race between the current
2376 + * context and ksoftirqd which could leave NAPI disabled while
2377 + * in fact there's still Rx traffic to be processed.
2378 + */
2379 + usleep_range(5000, 10000);
2380 +
2381 + priv = netdev_priv(net_dev);
2382 + dpaa_eth_napi_disable(priv);
2383 +
2384 + return _errno;
2385 +}
2386 +
2387 +#ifdef CONFIG_NET_POLL_CONTROLLER
2388 +static void dpaa_eth_poll_controller(struct net_device *net_dev)
2389 +{
2390 + struct dpa_priv_s *priv = netdev_priv(net_dev);
2391 + struct dpa_percpu_priv_s *percpu_priv =
2392 + raw_cpu_ptr(priv->percpu_priv);
2393 + struct qman_portal *p;
2394 + const struct qman_portal_config *pc;
2395 + struct dpa_napi_portal *np;
2396 +
2397 + p = (struct qman_portal *)qman_get_affine_portal(smp_processor_id());
2398 + pc = qman_p_get_portal_config(p);
2399 + np = &percpu_priv->np[pc->index];
2400 +
2401 + qman_p_irqsource_remove(np->p, QM_PIRQ_DQRI);
2402 + qman_p_poll_dqrr(np->p, np->napi.weight);
2403 + qman_p_irqsource_add(np->p, QM_PIRQ_DQRI);
2404 +}
2405 +#endif
2406 +
2407 +static const struct net_device_ops dpa_private_ops = {
2408 + .ndo_open = dpa_eth_priv_start,
2409 + .ndo_start_xmit = dpa_tx,
2410 + .ndo_stop = dpa_eth_priv_stop,
2411 + .ndo_tx_timeout = dpa_timeout,
2412 + .ndo_get_stats64 = dpa_get_stats64,
2413 + .ndo_set_mac_address = dpa_set_mac_address,
2414 + .ndo_validate_addr = eth_validate_addr,
2415 +#ifdef CONFIG_FSL_DPAA_ETH_USE_NDO_SELECT_QUEUE
2416 + .ndo_select_queue = dpa_select_queue,
2417 +#endif
2418 + .ndo_change_mtu = dpa_change_mtu,
2419 + .ndo_set_rx_mode = dpa_set_rx_mode,
2420 + .ndo_init = dpa_ndo_init,
2421 + .ndo_set_features = dpa_set_features,
2422 + .ndo_fix_features = dpa_fix_features,
2423 + .ndo_do_ioctl = dpa_ioctl,
2424 +#ifdef CONFIG_NET_POLL_CONTROLLER
2425 + .ndo_poll_controller = dpaa_eth_poll_controller,
2426 +#endif
2427 +};
2428 +
2429 +static int dpa_private_napi_add(struct net_device *net_dev)
2430 +{
2431 + struct dpa_priv_s *priv = netdev_priv(net_dev);
2432 + struct dpa_percpu_priv_s *percpu_priv;
2433 + int i, cpu;
2434 +
2435 + for_each_possible_cpu(cpu) {
2436 + percpu_priv = per_cpu_ptr(priv->percpu_priv, cpu);
2437 +
2438 + percpu_priv->np = devm_kzalloc(net_dev->dev.parent,
2439 + qman_portal_max * sizeof(struct dpa_napi_portal),
2440 + GFP_KERNEL);
2441 +
2442 + if (unlikely(percpu_priv->np == NULL)) {
2443 + dev_err(net_dev->dev.parent, "devm_kzalloc() failed\n");
2444 + return -ENOMEM;
2445 + }
2446 +
2447 + for (i = 0; i < qman_portal_max; i++)
2448 + netif_napi_add(net_dev, &percpu_priv->np[i].napi,
2449 + dpaa_eth_poll, DPA_NAPI_WEIGHT);
2450 + }
2451 +
2452 + return 0;
2453 +}
2454 +
2455 +void dpa_private_napi_del(struct net_device *net_dev)
2456 +{
2457 + struct dpa_priv_s *priv = netdev_priv(net_dev);
2458 + struct dpa_percpu_priv_s *percpu_priv;
2459 + int i, cpu;
2460 +
2461 + for_each_possible_cpu(cpu) {
2462 + percpu_priv = per_cpu_ptr(priv->percpu_priv, cpu);
2463 +
2464 + if (percpu_priv->np) {
2465 + for (i = 0; i < qman_portal_max; i++)
2466 + netif_napi_del(&percpu_priv->np[i].napi);
2467 +
2468 + devm_kfree(net_dev->dev.parent, percpu_priv->np);
2469 + }
2470 + }
2471 +}
2472 +EXPORT_SYMBOL(dpa_private_napi_del);
2473 +
2474 +static int dpa_private_netdev_init(struct net_device *net_dev)
2475 +{
2476 + int i;
2477 + struct dpa_priv_s *priv = netdev_priv(net_dev);
2478 + struct dpa_percpu_priv_s *percpu_priv;
2479 + const uint8_t *mac_addr;
2480 +
2481 + /* Although we access another CPU's private data here
2482 + * we do it at initialization so it is safe
2483 + */
2484 + for_each_possible_cpu(i) {
2485 + percpu_priv = per_cpu_ptr(priv->percpu_priv, i);
2486 + percpu_priv->net_dev = net_dev;
2487 + }
2488 +
2489 + net_dev->netdev_ops = &dpa_private_ops;
2490 + mac_addr = priv->mac_dev->addr;
2491 +
2492 + net_dev->mem_start = priv->mac_dev->res->start;
2493 + net_dev->mem_end = priv->mac_dev->res->end;
2494 +
2495 + net_dev->hw_features |= (NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM |
2496 + NETIF_F_LLTX);
2497 +
2498 + /* Advertise S/G and HIGHDMA support for private interfaces */
2499 + net_dev->hw_features |= NETIF_F_SG | NETIF_F_HIGHDMA;
2500 + /* Recent kernels enable GSO automatically, if
2501 + * we declare NETIF_F_SG. For conformity, we'll
2502 + * still declare GSO explicitly.
2503 + */
2504 + net_dev->features |= NETIF_F_GSO;
2505 +
2506 + /* Advertise GRO support */
2507 + net_dev->features |= NETIF_F_GRO;
2508 +
2509 + /* Advertise NETIF_F_HW_ACCEL_MQ to avoid Tx timeout warnings */
2510 + net_dev->features |= NETIF_F_HW_ACCEL_MQ;
2511 +
2512 +#ifndef CONFIG_PPC
2513 + /* Due to the A010022 FMan errata, we can not use contig frames larger
2514 + * than 4K, nor S/G frames. We need to stop advertising S/G and GSO
2515 + * support.
2516 + */
2517 + if (unlikely(dpaa_errata_a010022)) {
2518 + net_dev->hw_features &= ~NETIF_F_SG;
2519 + net_dev->features &= ~NETIF_F_GSO;
2520 + }
2521 +#endif
2522 +
2523 + return dpa_netdev_init(net_dev, mac_addr, tx_timeout);
2524 +}
2525 +
2526 +static struct dpa_bp * __cold
2527 +dpa_priv_bp_probe(struct device *dev)
2528 +{
2529 + struct dpa_bp *dpa_bp;
2530 +
2531 + dpa_bp = devm_kzalloc(dev, sizeof(*dpa_bp), GFP_KERNEL);
2532 + if (unlikely(dpa_bp == NULL)) {
2533 + dev_err(dev, "devm_kzalloc() failed\n");
2534 + return ERR_PTR(-ENOMEM);
2535 + }
2536 +
2537 + dpa_bp->percpu_count = devm_alloc_percpu(dev, *dpa_bp->percpu_count);
2538 + dpa_bp->target_count = CONFIG_FSL_DPAA_ETH_MAX_BUF_COUNT;
2539 +
2540 + dpa_bp->seed_cb = dpa_bp_priv_seed;
2541 + dpa_bp->free_buf_cb = _dpa_bp_free_pf;
2542 +
2543 + return dpa_bp;
2544 +}
2545 +
2546 +/* Place all ingress FQs (Rx Default, Rx Error, PCD FQs) in a dedicated CGR.
2547 + * We won't be sending congestion notifications to FMan; for now, we just use
2548 + * this CGR to generate enqueue rejections to FMan in order to drop the frames
2549 + * before they reach our ingress queues and eat up memory.
2550 + */
2551 +static int dpaa_eth_priv_ingress_cgr_init(struct dpa_priv_s *priv)
2552 +{
2553 + struct qm_mcc_initcgr initcgr;
2554 + u32 cs_th;
2555 + int err;
2556 +
2557 + err = qman_alloc_cgrid(&priv->ingress_cgr.cgrid);
2558 + if (err < 0) {
2559 + pr_err("Error %d allocating CGR ID\n", err);
2560 + goto out_error;
2561 + }
2562 +
2563 + /* Enable CS TD, but disable Congestion State Change Notifications. */
2564 + initcgr.we_mask = QM_CGR_WE_CS_THRES;
2565 + initcgr.cgr.cscn_en = QM_CGR_EN;
2566 + cs_th = CONFIG_FSL_DPAA_INGRESS_CS_THRESHOLD;
2567 + qm_cgr_cs_thres_set64(&initcgr.cgr.cs_thres, cs_th, 1);
2568 +
2569 + initcgr.we_mask |= QM_CGR_WE_CSTD_EN;
2570 + initcgr.cgr.cstd_en = QM_CGR_EN;
2571 +
2572 + /* This is actually a hack, because this CGR will be associated with
2573 + * our affine SWP. However, we'll place our ingress FQs in it.
2574 + */
2575 + err = qman_create_cgr(&priv->ingress_cgr, QMAN_CGR_FLAG_USE_INIT,
2576 + &initcgr);
2577 + if (err < 0) {
2578 + pr_err("Error %d creating ingress CGR with ID %d\n", err,
2579 + priv->ingress_cgr.cgrid);
2580 + qman_release_cgrid(priv->ingress_cgr.cgrid);
2581 + goto out_error;
2582 + }
2583 + pr_debug("Created ingress CGR %d for netdev with hwaddr %pM\n",
2584 + priv->ingress_cgr.cgrid, priv->mac_dev->addr);
2585 +
2586 + /* struct qman_cgr allows special cgrid values (i.e. outside the 0..255
2587 + * range), but we have no common initialization path between the
2588 + * different variants of the DPAA Eth driver, so we do it here rather
2589 + * than modifying every other variant than "private Eth".
2590 + */
2591 + priv->use_ingress_cgr = true;
2592 +
2593 +out_error:
2594 + return err;
2595 +}
2596 +
2597 +static int dpa_priv_bp_create(struct net_device *net_dev, struct dpa_bp *dpa_bp,
2598 + size_t count)
2599 +{
2600 + struct dpa_priv_s *priv = netdev_priv(net_dev);
2601 + int i;
2602 +
2603 + if (netif_msg_probe(priv))
2604 + dev_dbg(net_dev->dev.parent,
2605 + "Using private BM buffer pools\n");
2606 +
2607 + priv->bp_count = count;
2608 +
2609 + for (i = 0; i < count; i++) {
2610 + int err;
2611 + err = dpa_bp_alloc(&dpa_bp[i], net_dev->dev.parent);
2612 + if (err < 0) {
2613 + dpa_bp_free(priv);
2614 + priv->dpa_bp = NULL;
2615 + return err;
2616 + }
2617 +
2618 + priv->dpa_bp = &dpa_bp[i];
2619 + }
2620 +
2621 + dpa_priv_common_bpid = priv->dpa_bp->bpid;
2622 + return 0;
2623 +}
2624 +
2625 +static const struct of_device_id dpa_match[];
2626 +
2627 +#ifdef CONFIG_FSL_DPAA_DBG_LOOP
2628 +static int dpa_new_loop_id(void)
2629 +{
2630 + static int if_id;
2631 +
2632 + return if_id++;
2633 +}
2634 +#endif
2635 +
2636 +static int
2637 +dpaa_eth_priv_probe(struct platform_device *_of_dev)
2638 +{
2639 + int err = 0, i, channel;
2640 + struct device *dev;
2641 + struct device_node *dpa_node;
2642 + struct dpa_bp *dpa_bp;
2643 + size_t count = 1;
2644 + struct net_device *net_dev = NULL;
2645 + struct dpa_priv_s *priv = NULL;
2646 + struct dpa_percpu_priv_s *percpu_priv;
2647 + struct fm_port_fqs port_fqs;
2648 + struct dpa_buffer_layout_s *buf_layout = NULL;
2649 + struct mac_device *mac_dev;
2650 +
2651 + dev = &_of_dev->dev;
2652 +
2653 + dpa_node = dev->of_node;
2654 +
2655 + if (!of_device_is_available(dpa_node))
2656 + return -ENODEV;
2657 +
2658 + /* Get the buffer pools assigned to this interface;
2659 + * run only once the default pool probing code
2660 + */
2661 + dpa_bp = (dpa_bpid2pool(dpa_priv_common_bpid)) ? :
2662 + dpa_priv_bp_probe(dev);
2663 + if (IS_ERR(dpa_bp))
2664 + return PTR_ERR(dpa_bp);
2665 +
2666 + /* Allocate this early, so we can store relevant information in
2667 + * the private area (needed by 1588 code in dpa_mac_probe)
2668 + */
2669 + net_dev = alloc_etherdev_mq(sizeof(*priv), DPAA_ETH_TX_QUEUES);
2670 + if (!net_dev) {
2671 + dev_err(dev, "alloc_etherdev_mq() failed\n");
2672 + goto alloc_etherdev_mq_failed;
2673 + }
2674 +
2675 + /* Do this here, so we can be verbose early */
2676 + SET_NETDEV_DEV(net_dev, dev);
2677 + dev_set_drvdata(dev, net_dev);
2678 +
2679 + priv = netdev_priv(net_dev);
2680 + priv->net_dev = net_dev;
2681 + strcpy(priv->if_type, "private");
2682 +
2683 + priv->msg_enable = netif_msg_init(debug, -1);
2684 +
2685 +#ifdef CONFIG_FSL_DPAA_DBG_LOOP
2686 + priv->loop_id = dpa_new_loop_id();
2687 + priv->loop_to = -1; /* disabled by default */
2688 + dpa_loop_netdevs[priv->loop_id] = net_dev;
2689 +#endif
2690 +
2691 + mac_dev = dpa_mac_probe(_of_dev);
2692 + if (IS_ERR(mac_dev) || !mac_dev) {
2693 + err = PTR_ERR(mac_dev);
2694 + goto mac_probe_failed;
2695 + }
2696 +
2697 + /* We have physical ports, so we need to establish
2698 + * the buffer layout.
2699 + */
2700 + buf_layout = devm_kzalloc(dev, 2 * sizeof(*buf_layout),
2701 + GFP_KERNEL);
2702 + if (!buf_layout) {
2703 + dev_err(dev, "devm_kzalloc() failed\n");
2704 + goto alloc_failed;
2705 + }
2706 + dpa_set_buffers_layout(mac_dev, buf_layout);
2707 +
2708 + /* For private ports, need to compute the size of the default
2709 + * buffer pool, based on FMan port buffer layout;also update
2710 + * the maximum buffer size for private ports if necessary
2711 + */
2712 + dpa_bp->size = dpa_bp_size(&buf_layout[RX]);
2713 +
2714 +#ifdef CONFIG_FSL_DPAA_ETH_JUMBO_FRAME
2715 + /* We only want to use jumbo frame optimization if we actually have
2716 + * L2 MAX FRM set for jumbo frames as well.
2717 + */
2718 +#ifndef CONFIG_PPC
2719 + if (likely(!dpaa_errata_a010022))
2720 +#endif
2721 + if(fm_get_max_frm() < 9600)
2722 + dev_warn(dev,
2723 + "Invalid configuration: if jumbo frames support is on, FSL_FM_MAX_FRAME_SIZE should be set to 9600\n");
2724 +#endif
2725 +
2726 + INIT_LIST_HEAD(&priv->dpa_fq_list);
2727 +
2728 + memset(&port_fqs, 0, sizeof(port_fqs));
2729 +
2730 + err = dpa_fq_probe_mac(dev, &priv->dpa_fq_list, &port_fqs, true, RX);
2731 + if (!err)
2732 + err = dpa_fq_probe_mac(dev, &priv->dpa_fq_list,
2733 + &port_fqs, true, TX);
2734 +
2735 + if (err < 0)
2736 + goto fq_probe_failed;
2737 +
2738 + /* bp init */
2739 +
2740 + err = dpa_priv_bp_create(net_dev, dpa_bp, count);
2741 +
2742 + if (err < 0)
2743 + goto bp_create_failed;
2744 +
2745 + priv->mac_dev = mac_dev;
2746 +
2747 + channel = dpa_get_channel();
2748 +
2749 + if (channel < 0) {
2750 + err = channel;
2751 + goto get_channel_failed;
2752 + }
2753 +
2754 + priv->channel = (uint16_t)channel;
2755 + dpaa_eth_add_channel(priv->channel);
2756 +
2757 + dpa_fq_setup(priv, &private_fq_cbs, priv->mac_dev->port_dev[TX]);
2758 +
2759 + /* Create a congestion group for this netdev, with
2760 + * dynamically-allocated CGR ID.
2761 + * Must be executed after probing the MAC, but before
2762 + * assigning the egress FQs to the CGRs.
2763 + */
2764 + err = dpaa_eth_cgr_init(priv);
2765 + if (err < 0) {
2766 + dev_err(dev, "Error initializing CGR\n");
2767 + goto tx_cgr_init_failed;
2768 + }
2769 + err = dpaa_eth_priv_ingress_cgr_init(priv);
2770 + if (err < 0) {
2771 + dev_err(dev, "Error initializing ingress CGR\n");
2772 + goto rx_cgr_init_failed;
2773 + }
2774 +
2775 + /* Add the FQs to the interface, and make them active */
2776 + err = dpa_fqs_init(dev, &priv->dpa_fq_list, false);
2777 + if (err < 0)
2778 + goto fq_alloc_failed;
2779 +
2780 + priv->buf_layout = buf_layout;
2781 + priv->tx_headroom = dpa_get_headroom(&priv->buf_layout[TX]);
2782 + priv->rx_headroom = dpa_get_headroom(&priv->buf_layout[RX]);
2783 +
2784 + /* All real interfaces need their ports initialized */
2785 + dpaa_eth_init_ports(mac_dev, dpa_bp, count, &port_fqs,
2786 + buf_layout, dev);
2787 +
2788 +#ifdef CONFIG_FMAN_PFC
2789 + for (i = 0; i < CONFIG_FMAN_PFC_COS_COUNT; i++) {
2790 + err = fm_port_set_pfc_priorities_mapping_to_qman_wq(
2791 + mac_dev->port_dev[TX], i, i);
2792 + if (unlikely(err != 0)) {
2793 + dev_err(dev, "Error maping PFC %u to WQ %u\n", i, i);
2794 + goto pfc_mapping_failed;
2795 + }
2796 + }
2797 +#endif
2798 +
2799 + priv->percpu_priv = devm_alloc_percpu(dev, *priv->percpu_priv);
2800 +
2801 + if (priv->percpu_priv == NULL) {
2802 + dev_err(dev, "devm_alloc_percpu() failed\n");
2803 + err = -ENOMEM;
2804 + goto alloc_percpu_failed;
2805 + }
2806 + for_each_possible_cpu(i) {
2807 + percpu_priv = per_cpu_ptr(priv->percpu_priv, i);
2808 + memset(percpu_priv, 0, sizeof(*percpu_priv));
2809 + }
2810 +
2811 + /* Initialize NAPI */
2812 + err = dpa_private_napi_add(net_dev);
2813 +
2814 + if (err < 0)
2815 + goto napi_add_failed;
2816 +
2817 + err = dpa_private_netdev_init(net_dev);
2818 +
2819 + if (err < 0)
2820 + goto netdev_init_failed;
2821 +
2822 + dpaa_eth_sysfs_init(&net_dev->dev);
2823 +
2824 +#ifdef CONFIG_PM
2825 + device_set_wakeup_capable(dev, true);
2826 +#endif
2827 +
2828 + pr_info("fsl_dpa: Probed interface %s\n", net_dev->name);
2829 +
2830 + return 0;
2831 +
2832 +netdev_init_failed:
2833 +napi_add_failed:
2834 + dpa_private_napi_del(net_dev);
2835 +alloc_percpu_failed:
2836 +#ifdef CONFIG_FMAN_PFC
2837 +pfc_mapping_failed:
2838 +#endif
2839 + dpa_fq_free(dev, &priv->dpa_fq_list);
2840 +fq_alloc_failed:
2841 + qman_delete_cgr_safe(&priv->ingress_cgr);
2842 + qman_release_cgrid(priv->ingress_cgr.cgrid);
2843 +rx_cgr_init_failed:
2844 + qman_delete_cgr_safe(&priv->cgr_data.cgr);
2845 + qman_release_cgrid(priv->cgr_data.cgr.cgrid);
2846 +tx_cgr_init_failed:
2847 +get_channel_failed:
2848 + dpa_bp_free(priv);
2849 +bp_create_failed:
2850 +fq_probe_failed:
2851 +alloc_failed:
2852 +mac_probe_failed:
2853 + dev_set_drvdata(dev, NULL);
2854 + free_netdev(net_dev);
2855 +alloc_etherdev_mq_failed:
2856 + if (atomic_read(&dpa_bp->refs) == 0)
2857 + devm_kfree(dev, dpa_bp);
2858 +
2859 + return err;
2860 +}
2861 +
2862 +static const struct of_device_id dpa_match[] = {
2863 + {
2864 + .compatible = "fsl,dpa-ethernet"
2865 + },
2866 + {}
2867 +};
2868 +MODULE_DEVICE_TABLE(of, dpa_match);
2869 +
2870 +static struct platform_driver dpa_driver = {
2871 + .driver = {
2872 + .name = KBUILD_MODNAME,
2873 + .of_match_table = dpa_match,
2874 + .owner = THIS_MODULE,
2875 + .pm = DPAA_PM_OPS,
2876 + },
2877 + .probe = dpaa_eth_priv_probe,
2878 + .remove = dpa_remove
2879 +};
2880 +
2881 +#ifndef CONFIG_PPC
2882 +static bool __init __cold soc_has_errata_a010022(void)
2883 +{
2884 +#ifdef CONFIG_SOC_BUS
2885 + const struct soc_device_attribute soc_msi_matches[] = {
2886 + { .family = "QorIQ LS1043A",
2887 + .data = NULL },
2888 + { },
2889 + };
2890 +
2891 + if (soc_device_match(soc_msi_matches))
2892 + return true;
2893 +
2894 + return false;
2895 +#else
2896 + return true; /* cannot identify SoC */
2897 +#endif
2898 +}
2899 +#endif
2900 +
2901 +static int __init __cold dpa_load(void)
2902 +{
2903 + int _errno;
2904 +
2905 + pr_info(DPA_DESCRIPTION "\n");
2906 +
2907 +#ifdef CONFIG_FSL_DPAA_DBG_LOOP
2908 + dpa_debugfs_module_init();
2909 +#endif /* CONFIG_FSL_DPAA_DBG_LOOP */
2910 +
2911 + /* initialise dpaa_eth mirror values */
2912 + dpa_rx_extra_headroom = fm_get_rx_extra_headroom();
2913 + dpa_max_frm = fm_get_max_frm();
2914 + dpa_num_cpus = num_possible_cpus();
2915 +
2916 +#ifndef CONFIG_PPC
2917 + /* Detect if the current SoC requires the 4K alignment workaround */
2918 + dpaa_errata_a010022 = soc_has_errata_a010022();
2919 +#endif
2920 +
2921 +#ifdef CONFIG_FSL_DPAA_DBG_LOOP
2922 + memset(dpa_loop_netdevs, 0, sizeof(dpa_loop_netdevs));
2923 +#endif
2924 +
2925 + _errno = platform_driver_register(&dpa_driver);
2926 + if (unlikely(_errno < 0)) {
2927 + pr_err(KBUILD_MODNAME
2928 + ": %s:%hu:%s(): platform_driver_register() = %d\n",
2929 + KBUILD_BASENAME".c", __LINE__, __func__, _errno);
2930 + }
2931 +
2932 + pr_debug(KBUILD_MODNAME ": %s:%s() ->\n",
2933 + KBUILD_BASENAME".c", __func__);
2934 +
2935 + return _errno;
2936 +}
2937 +module_init(dpa_load);
2938 +
2939 +static void __exit __cold dpa_unload(void)
2940 +{
2941 + pr_debug(KBUILD_MODNAME ": -> %s:%s()\n",
2942 + KBUILD_BASENAME".c", __func__);
2943 +
2944 + platform_driver_unregister(&dpa_driver);
2945 +
2946 +#ifdef CONFIG_FSL_DPAA_DBG_LOOP
2947 + dpa_debugfs_module_exit();
2948 +#endif /* CONFIG_FSL_DPAA_DBG_LOOP */
2949 +
2950 + /* Only one channel is used and needs to be relased after all
2951 + * interfaces are removed
2952 + */
2953 + dpa_release_channel();
2954 +
2955 + pr_debug(KBUILD_MODNAME ": %s:%s() ->\n",
2956 + KBUILD_BASENAME".c", __func__);
2957 +}
2958 +module_exit(dpa_unload);
2959 --- /dev/null
2960 +++ b/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth.h
2961 @@ -0,0 +1,687 @@
2962 +/* Copyright 2008-2012 Freescale Semiconductor Inc.
2963 + *
2964 + * Redistribution and use in source and binary forms, with or without
2965 + * modification, are permitted provided that the following conditions are met:
2966 + * * Redistributions of source code must retain the above copyright
2967 + * notice, this list of conditions and the following disclaimer.
2968 + * * Redistributions in binary form must reproduce the above copyright
2969 + * notice, this list of conditions and the following disclaimer in the
2970 + * documentation and/or other materials provided with the distribution.
2971 + * * Neither the name of Freescale Semiconductor nor the
2972 + * names of its contributors may be used to endorse or promote products
2973 + * derived from this software without specific prior written permission.
2974 + *
2975 + *
2976 + * ALTERNATIVELY, this software may be distributed under the terms of the
2977 + * GNU General Public License ("GPL") as published by the Free Software
2978 + * Foundation, either version 2 of that License or (at your option) any
2979 + * later version.
2980 + *
2981 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
2982 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
2983 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
2984 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
2985 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
2986 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
2987 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
2988 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
2989 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
2990 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2991 + */
2992 +
2993 +#ifndef __DPA_H
2994 +#define __DPA_H
2995 +
2996 +#include <linux/netdevice.h>
2997 +#include <linux/fsl_qman.h> /* struct qman_fq */
2998 +
2999 +#include "fm_ext.h"
3000 +#include "dpaa_eth_trace.h"
3001 +
3002 +extern int dpa_rx_extra_headroom;
3003 +extern int dpa_max_frm;
3004 +extern int dpa_num_cpus;
3005 +
3006 +#define dpa_get_rx_extra_headroom() dpa_rx_extra_headroom
3007 +#define dpa_get_max_frm() dpa_max_frm
3008 +
3009 +#define dpa_get_max_mtu() \
3010 + (dpa_get_max_frm() - (VLAN_ETH_HLEN + ETH_FCS_LEN))
3011 +
3012 +#define __hot
3013 +
3014 +/* Simple enum of FQ types - used for array indexing */
3015 +enum port_type {RX, TX};
3016 +
3017 +/* TODO: This structure should be renamed & moved to the FMD wrapper */
3018 +struct dpa_buffer_layout_s {
3019 + uint16_t priv_data_size;
3020 + bool parse_results;
3021 + bool time_stamp;
3022 + bool hash_results;
3023 + uint8_t manip_extra_space;
3024 + uint16_t data_align;
3025 +};
3026 +
3027 +#ifdef CONFIG_FSL_DPAA_ETH_DEBUG
3028 +#define DPA_BUG_ON(cond) BUG_ON(cond)
3029 +#else
3030 +#define DPA_BUG_ON(cond)
3031 +#endif
3032 +
3033 +#define DPA_TX_PRIV_DATA_SIZE 16
3034 +#define DPA_PARSE_RESULTS_SIZE sizeof(fm_prs_result_t)
3035 +#define DPA_TIME_STAMP_SIZE 8
3036 +#define DPA_HASH_RESULTS_SIZE 8
3037 +#define DPA_RX_PRIV_DATA_SIZE (DPA_TX_PRIV_DATA_SIZE + \
3038 + dpa_get_rx_extra_headroom())
3039 +
3040 +#define FM_FD_STAT_RX_ERRORS \
3041 + (FM_PORT_FRM_ERR_DMA | FM_PORT_FRM_ERR_PHYSICAL | \
3042 + FM_PORT_FRM_ERR_SIZE | FM_PORT_FRM_ERR_CLS_DISCARD | \
3043 + FM_PORT_FRM_ERR_EXTRACTION | FM_PORT_FRM_ERR_NO_SCHEME | \
3044 + FM_PORT_FRM_ERR_ILL_PLCR | FM_PORT_FRM_ERR_PRS_TIMEOUT | \
3045 + FM_PORT_FRM_ERR_PRS_ILL_INSTRUCT | FM_PORT_FRM_ERR_PRS_HDR_ERR)
3046 +
3047 +#define FM_FD_STAT_TX_ERRORS \
3048 + (FM_PORT_FRM_ERR_UNSUPPORTED_FORMAT | \
3049 + FM_PORT_FRM_ERR_LENGTH | FM_PORT_FRM_ERR_DMA)
3050 +
3051 +#ifndef CONFIG_FSL_DPAA_ETH_JUMBO_FRAME
3052 +/* The raw buffer size must be cacheline aligned.
3053 + * Normally we use 2K buffers.
3054 + */
3055 +#define DPA_BP_RAW_SIZE 2048
3056 +#else
3057 +/* For jumbo frame optimizations, use buffers large enough to accommodate
3058 + * 9.6K frames, FD maximum offset, skb sh_info overhead and some extra
3059 + * space to account for further alignments.
3060 + */
3061 +#define DPA_MAX_FRM_SIZE 9600
3062 +#ifdef CONFIG_PPC
3063 +#define DPA_BP_RAW_SIZE \
3064 + ((DPA_MAX_FRM_SIZE + DPA_MAX_FD_OFFSET + \
3065 + sizeof(struct skb_shared_info) + 128) & ~(SMP_CACHE_BYTES - 1))
3066 +#else /* CONFIG_PPC */
3067 +#define DPA_BP_RAW_SIZE ((unlikely(dpaa_errata_a010022)) ? 2048 : \
3068 + ((DPA_MAX_FRM_SIZE + DPA_MAX_FD_OFFSET + \
3069 + sizeof(struct skb_shared_info) + 128) & ~(SMP_CACHE_BYTES - 1)))
3070 +#endif /* CONFIG_PPC */
3071 +#endif /* CONFIG_FSL_DPAA_ETH_JUMBO_FRAME */
3072 +
3073 +/* This is what FMan is ever allowed to use.
3074 + * FMan-DMA requires 16-byte alignment for Rx buffers, but SKB_DATA_ALIGN is
3075 + * even stronger (SMP_CACHE_BYTES-aligned), so we just get away with that,
3076 + * via SKB_WITH_OVERHEAD(). We can't rely on netdev_alloc_frag() giving us
3077 + * half-page-aligned buffers (can we?), so we reserve some more space
3078 + * for start-of-buffer alignment.
3079 + */
3080 +#define dpa_bp_size(buffer_layout) (SKB_WITH_OVERHEAD(DPA_BP_RAW_SIZE) - \
3081 + SMP_CACHE_BYTES)
3082 +/* We must ensure that skb_shinfo is always cacheline-aligned. */
3083 +#define DPA_SKB_SIZE(size) ((size) & ~(SMP_CACHE_BYTES - 1))
3084 +
3085 +/* Maximum size of a buffer for which recycling is allowed.
3086 + * We need an upper limit such that forwarded skbs that get reallocated on Tx
3087 + * aren't allowed to grow unboundedly. On the other hand, we need to make sure
3088 + * that skbs allocated by us will not fail to be recycled due to their size.
3089 + *
3090 + * For a requested size, the kernel allocator provides the next power of two
3091 + * sized block, which the stack will use as is, regardless of the actual size
3092 + * it required; since we must accommodate at most 9.6K buffers (L2 maximum
3093 + * supported frame size), set the recycling upper limit to 16K.
3094 + */
3095 +#define DPA_RECYCLE_MAX_SIZE 16384
3096 +
3097 +#if defined(CONFIG_FSL_SDK_FMAN_TEST)
3098 +/*TODO: temporary for fman pcd testing */
3099 +#define FMAN_PCD_TESTS_MAX_NUM_RANGES 20
3100 +#endif
3101 +
3102 +#define DPAA_ETH_FQ_DELTA 0x10000
3103 +
3104 +#define DPAA_ETH_PCD_FQ_BASE(device_addr) \
3105 + (((device_addr) & 0x1fffff) >> 6)
3106 +
3107 +#define DPAA_ETH_PCD_FQ_HI_PRIO_BASE(device_addr) \
3108 + (DPAA_ETH_FQ_DELTA + DPAA_ETH_PCD_FQ_BASE(device_addr))
3109 +
3110 +/* Largest value that the FQD's OAL field can hold.
3111 + * This is DPAA-1.x specific.
3112 + * TODO: This rather belongs in fsl_qman.h
3113 + */
3114 +#define FSL_QMAN_MAX_OAL 127
3115 +
3116 +/* Maximum offset value for a contig or sg FD (represented on 9 bits) */
3117 +#define DPA_MAX_FD_OFFSET ((1 << 9) - 1)
3118 +
3119 +/* Default alignment for start of data in an Rx FD */
3120 +#define DPA_FD_DATA_ALIGNMENT 16
3121 +
3122 +/* Values for the L3R field of the FM Parse Results
3123 + */
3124 +/* L3 Type field: First IP Present IPv4 */
3125 +#define FM_L3_PARSE_RESULT_IPV4 0x8000
3126 +/* L3 Type field: First IP Present IPv6 */
3127 +#define FM_L3_PARSE_RESULT_IPV6 0x4000
3128 +
3129 +/* Values for the L4R field of the FM Parse Results
3130 + * See $8.8.4.7.20 - L4 HXS - L4 Results from DPAA-Rev2 Reference Manual.
3131 + */
3132 +/* L4 Type field: UDP */
3133 +#define FM_L4_PARSE_RESULT_UDP 0x40
3134 +/* L4 Type field: TCP */
3135 +#define FM_L4_PARSE_RESULT_TCP 0x20
3136 +/* FD status field indicating whether the FM Parser has attempted to validate
3137 + * the L4 csum of the frame.
3138 + * Note that having this bit set doesn't necessarily imply that the checksum
3139 + * is valid. One would have to check the parse results to find that out.
3140 + */
3141 +#define FM_FD_STAT_L4CV 0x00000004
3142 +
3143 +
3144 +#define FM_FD_STAT_ERR_PHYSICAL FM_PORT_FRM_ERR_PHYSICAL
3145 +
3146 +/* Check if the parsed frame was found to be a TCP segment.
3147 + *
3148 + * @parse_result_ptr must be of type (fm_prs_result_t *).
3149 + */
3150 +#define fm_l4_frame_is_tcp(parse_result_ptr) \
3151 + ((parse_result_ptr)->l4r & FM_L4_PARSE_RESULT_TCP)
3152 +
3153 +/* number of Tx queues to FMan */
3154 +#ifdef CONFIG_FMAN_PFC
3155 +#define DPAA_ETH_TX_QUEUES (NR_CPUS * CONFIG_FMAN_PFC_COS_COUNT)
3156 +#else
3157 +#define DPAA_ETH_TX_QUEUES NR_CPUS
3158 +#endif
3159 +
3160 +#define DPAA_ETH_RX_QUEUES 128
3161 +
3162 +/* Convenience macros for storing/retrieving the skb back-pointers. They must
3163 + * accommodate both recycling and confirmation paths - i.e. cases when the buf
3164 + * was allocated by ourselves, respectively by the stack. In the former case,
3165 + * we could store the skb at negative offset; in the latter case, we can't,
3166 + * so we'll use 0 as offset.
3167 + *
3168 + * NB: @off is an offset from a (struct sk_buff **) pointer!
3169 + */
3170 +#define DPA_WRITE_SKB_PTR(skb, skbh, addr, off) \
3171 +{ \
3172 + skbh = (struct sk_buff **)addr; \
3173 + *(skbh + (off)) = skb; \
3174 +}
3175 +#define DPA_READ_SKB_PTR(skb, skbh, addr, off) \
3176 +{ \
3177 + skbh = (struct sk_buff **)addr; \
3178 + skb = *(skbh + (off)); \
3179 +}
3180 +
3181 +#ifdef CONFIG_PM
3182 +/* Magic Packet wakeup */
3183 +#define DPAA_WOL_MAGIC 0x00000001
3184 +#endif
3185 +
3186 +#if defined(CONFIG_FSL_SDK_FMAN_TEST)
3187 +struct pcd_range {
3188 + uint32_t base;
3189 + uint32_t count;
3190 +};
3191 +#endif
3192 +
3193 +/* More detailed FQ types - used for fine-grained WQ assignments */
3194 +enum dpa_fq_type {
3195 + FQ_TYPE_RX_DEFAULT = 1, /* Rx Default FQs */
3196 + FQ_TYPE_RX_ERROR, /* Rx Error FQs */
3197 + FQ_TYPE_RX_PCD, /* User-defined PCDs */
3198 + FQ_TYPE_TX, /* "Real" Tx FQs */
3199 + FQ_TYPE_TX_CONFIRM, /* Tx default Conf FQ (actually an Rx FQ) */
3200 + FQ_TYPE_TX_CONF_MQ, /* Tx conf FQs (one for each Tx FQ) */
3201 + FQ_TYPE_TX_ERROR, /* Tx Error FQs (these are actually Rx FQs) */
3202 + FQ_TYPE_RX_PCD_HI_PRIO, /* User-defined high-priority PCDs */
3203 +};
3204 +
3205 +struct dpa_fq {
3206 + struct qman_fq fq_base;
3207 + struct list_head list;
3208 + struct net_device *net_dev;
3209 + bool init;
3210 + uint32_t fqid;
3211 + uint32_t flags;
3212 + uint16_t channel;
3213 + uint8_t wq;
3214 + enum dpa_fq_type fq_type;
3215 +};
3216 +
3217 +struct dpa_fq_cbs_t {
3218 + struct qman_fq rx_defq;
3219 + struct qman_fq tx_defq;
3220 + struct qman_fq rx_errq;
3221 + struct qman_fq tx_errq;
3222 + struct qman_fq egress_ern;
3223 +};
3224 +
3225 +struct fqid_cell {
3226 + uint32_t start;
3227 + uint32_t count;
3228 +};
3229 +
3230 +struct dpa_bp {
3231 + struct bman_pool *pool;
3232 + uint8_t bpid;
3233 + struct device *dev;
3234 + union {
3235 + /* The buffer pools used for the private ports are initialized
3236 + * with target_count buffers for each CPU; at runtime the
3237 + * number of buffers per CPU is constantly brought back to this
3238 + * level
3239 + */
3240 + int target_count;
3241 + /* The configured value for the number of buffers in the pool,
3242 + * used for shared port buffer pools
3243 + */
3244 + int config_count;
3245 + };
3246 + size_t size;
3247 + bool seed_pool;
3248 + /* physical address of the contiguous memory used by the pool to store
3249 + * the buffers
3250 + */
3251 + dma_addr_t paddr;
3252 + /* virtual address of the contiguous memory used by the pool to store
3253 + * the buffers
3254 + */
3255 + void __iomem *vaddr;
3256 + /* current number of buffers in the bpool alloted to this CPU */
3257 + int __percpu *percpu_count;
3258 + atomic_t refs;
3259 + /* some bpools need to be seeded before use by this cb */
3260 + int (*seed_cb)(struct dpa_bp *);
3261 + /* some bpools need to be emptied before freeing; this cb is used
3262 + * for freeing of individual buffers taken from the pool
3263 + */
3264 + void (*free_buf_cb)(void *addr);
3265 +};
3266 +
3267 +struct dpa_rx_errors {
3268 + u64 dme; /* DMA Error */
3269 + u64 fpe; /* Frame Physical Error */
3270 + u64 fse; /* Frame Size Error */
3271 + u64 phe; /* Header Error */
3272 + u64 cse; /* Checksum Validation Error */
3273 +};
3274 +
3275 +/* Counters for QMan ERN frames - one counter per rejection code */
3276 +struct dpa_ern_cnt {
3277 + u64 cg_tdrop; /* Congestion group taildrop */
3278 + u64 wred; /* WRED congestion */
3279 + u64 err_cond; /* Error condition */
3280 + u64 early_window; /* Order restoration, frame too early */
3281 + u64 late_window; /* Order restoration, frame too late */
3282 + u64 fq_tdrop; /* FQ taildrop */
3283 + u64 fq_retired; /* FQ is retired */
3284 + u64 orp_zero; /* ORP disabled */
3285 +};
3286 +
3287 +struct dpa_napi_portal {
3288 + struct napi_struct napi;
3289 + struct qman_portal *p;
3290 +};
3291 +
3292 +struct dpa_percpu_priv_s {
3293 + struct net_device *net_dev;
3294 + struct dpa_napi_portal *np;
3295 + u64 in_interrupt;
3296 + u64 tx_returned;
3297 + u64 tx_confirm;
3298 + /* fragmented (non-linear) skbuffs received from the stack */
3299 + u64 tx_frag_skbuffs;
3300 + /* number of S/G frames received */
3301 + u64 rx_sg;
3302 +
3303 + struct rtnl_link_stats64 stats;
3304 + struct dpa_rx_errors rx_errors;
3305 + struct dpa_ern_cnt ern_cnt;
3306 +};
3307 +
3308 +struct dpa_priv_s {
3309 + struct dpa_percpu_priv_s __percpu *percpu_priv;
3310 + struct dpa_bp *dpa_bp;
3311 + /* Store here the needed Tx headroom for convenience and speed
3312 + * (even though it can be computed based on the fields of buf_layout)
3313 + */
3314 + uint16_t tx_headroom;
3315 + struct net_device *net_dev;
3316 + struct mac_device *mac_dev;
3317 + struct qman_fq *egress_fqs[DPAA_ETH_TX_QUEUES];
3318 + struct qman_fq *conf_fqs[DPAA_ETH_TX_QUEUES];
3319 +
3320 + size_t bp_count;
3321 +
3322 + uint16_t channel; /* "fsl,qman-channel-id" */
3323 + struct list_head dpa_fq_list;
3324 +
3325 +#ifdef CONFIG_FSL_DPAA_DBG_LOOP
3326 + struct dentry *debugfs_loop_file;
3327 +#endif
3328 +
3329 + uint32_t msg_enable; /* net_device message level */
3330 +#ifdef CONFIG_FSL_DPAA_1588
3331 + struct dpa_ptp_tsu *tsu;
3332 +#endif
3333 +
3334 +#if defined(CONFIG_FSL_SDK_FMAN_TEST)
3335 +/* TODO: this is temporary until pcd support is implemented in dpaa */
3336 + int priv_pcd_num_ranges;
3337 + struct pcd_range priv_pcd_ranges[FMAN_PCD_TESTS_MAX_NUM_RANGES];
3338 +#endif
3339 +
3340 + struct {
3341 + /**
3342 + * All egress queues to a given net device belong to one
3343 + * (and the same) congestion group.
3344 + */
3345 + struct qman_cgr cgr;
3346 + /* If congested, when it began. Used for performance stats. */
3347 + u32 congestion_start_jiffies;
3348 + /* Number of jiffies the Tx port was congested. */
3349 + u32 congested_jiffies;
3350 + /**
3351 + * Counter for the number of times the CGR
3352 + * entered congestion state
3353 + */
3354 + u32 cgr_congested_count;
3355 + } cgr_data;
3356 + /* Use a per-port CGR for ingress traffic. */
3357 + bool use_ingress_cgr;
3358 + struct qman_cgr ingress_cgr;
3359 +
3360 +#ifdef CONFIG_FSL_DPAA_TS
3361 + bool ts_tx_en; /* Tx timestamping enabled */
3362 + bool ts_rx_en; /* Rx timestamping enabled */
3363 +#endif /* CONFIG_FSL_DPAA_TS */
3364 +
3365 + struct dpa_buffer_layout_s *buf_layout;
3366 + uint16_t rx_headroom;
3367 + char if_type[30];
3368 +
3369 + void *peer;
3370 +#ifdef CONFIG_PM
3371 + u32 wol;
3372 +#endif
3373 +#ifdef CONFIG_FSL_DPAA_DBG_LOOP
3374 + int loop_id;
3375 + int loop_to;
3376 +#endif
3377 +#ifdef CONFIG_FSL_DPAA_CEETM
3378 + bool ceetm_en; /* CEETM QoS enabled */
3379 +#endif
3380 +};
3381 +
3382 +struct fm_port_fqs {
3383 + struct dpa_fq *tx_defq;
3384 + struct dpa_fq *tx_errq;
3385 + struct dpa_fq *rx_defq;
3386 + struct dpa_fq *rx_errq;
3387 +};
3388 +
3389 +
3390 +#ifdef CONFIG_FSL_DPAA_DBG_LOOP
3391 +extern struct net_device *dpa_loop_netdevs[20];
3392 +#endif
3393 +
3394 +/* functions with different implementation for SG and non-SG: */
3395 +int dpa_bp_priv_seed(struct dpa_bp *dpa_bp);
3396 +int dpaa_eth_refill_bpools(struct dpa_bp *dpa_bp, int *count_ptr);
3397 +void __hot _dpa_rx(struct net_device *net_dev,
3398 + struct qman_portal *portal,
3399 + const struct dpa_priv_s *priv,
3400 + struct dpa_percpu_priv_s *percpu_priv,
3401 + const struct qm_fd *fd,
3402 + u32 fqid,
3403 + int *count_ptr);
3404 +int __hot dpa_tx(struct sk_buff *skb, struct net_device *net_dev);
3405 +int __hot dpa_tx_extended(struct sk_buff *skb, struct net_device *net_dev,
3406 + struct qman_fq *egress_fq, struct qman_fq *conf_fq);
3407 +struct sk_buff *_dpa_cleanup_tx_fd(const struct dpa_priv_s *priv,
3408 + const struct qm_fd *fd);
3409 +void __hot _dpa_process_parse_results(const fm_prs_result_t *parse_results,
3410 + const struct qm_fd *fd,
3411 + struct sk_buff *skb,
3412 + int *use_gro);
3413 +#ifndef CONFIG_FSL_DPAA_TS
3414 +bool dpa_skb_is_recyclable(struct sk_buff *skb);
3415 +bool dpa_buf_is_recyclable(struct sk_buff *skb,
3416 + uint32_t min_size,
3417 + uint16_t min_offset,
3418 + unsigned char **new_buf_start);
3419 +#endif
3420 +int __hot skb_to_contig_fd(struct dpa_priv_s *priv,
3421 + struct sk_buff *skb, struct qm_fd *fd,
3422 + int *count_ptr, int *offset);
3423 +int __hot skb_to_sg_fd(struct dpa_priv_s *priv,
3424 + struct sk_buff *skb, struct qm_fd *fd);
3425 +int __cold __attribute__((nonnull))
3426 + _dpa_fq_free(struct device *dev, struct qman_fq *fq);
3427 +
3428 +/* Turn on HW checksum computation for this outgoing frame.
3429 + * If the current protocol is not something we support in this regard
3430 + * (or if the stack has already computed the SW checksum), we do nothing.
3431 + *
3432 + * Returns 0 if all goes well (or HW csum doesn't apply), and a negative value
3433 + * otherwise.
3434 + *
3435 + * Note that this function may modify the fd->cmd field and the skb data buffer
3436 + * (the Parse Results area).
3437 + */
3438 +int dpa_enable_tx_csum(struct dpa_priv_s *priv,
3439 + struct sk_buff *skb, struct qm_fd *fd, char *parse_results);
3440 +
3441 +static inline int dpaa_eth_napi_schedule(struct dpa_percpu_priv_s *percpu_priv,
3442 + struct qman_portal *portal)
3443 +{
3444 + /* In case of threaded ISR for RT enable kernel,
3445 + * in_irq() does not return appropriate value, so use
3446 + * in_serving_softirq to distinguish softirq or irq context.
3447 + */
3448 + if (unlikely(in_irq() || !in_serving_softirq())) {
3449 + /* Disable QMan IRQ and invoke NAPI */
3450 + int ret = qman_p_irqsource_remove(portal, QM_PIRQ_DQRI);
3451 + if (likely(!ret)) {
3452 + const struct qman_portal_config *pc =
3453 + qman_p_get_portal_config(portal);
3454 + struct dpa_napi_portal *np =
3455 + &percpu_priv->np[pc->index];
3456 +
3457 + np->p = portal;
3458 + napi_schedule(&np->napi);
3459 + percpu_priv->in_interrupt++;
3460 + return 1;
3461 + }
3462 + }
3463 + return 0;
3464 +}
3465 +
3466 +static inline ssize_t __const __must_check __attribute__((nonnull))
3467 +dpa_fd_length(const struct qm_fd *fd)
3468 +{
3469 + return fd->length20;
3470 +}
3471 +
3472 +static inline ssize_t __const __must_check __attribute__((nonnull))
3473 +dpa_fd_offset(const struct qm_fd *fd)
3474 +{
3475 + return fd->offset;
3476 +}
3477 +
3478 +static inline uint16_t dpa_get_headroom(struct dpa_buffer_layout_s *bl)
3479 +{
3480 + uint16_t headroom;
3481 + /* The frame headroom must accommodate:
3482 + * - the driver private data area
3483 + * - parse results, hash results, timestamp if selected
3484 + * - manip extra space
3485 + * If either hash results or time stamp are selected, both will
3486 + * be copied to/from the frame headroom, as TS is located between PR and
3487 + * HR in the IC and IC copy size has a granularity of 16bytes
3488 + * (see description of FMBM_RICP and FMBM_TICP registers in DPAARM)
3489 + *
3490 + * Also make sure the headroom is a multiple of data_align bytes
3491 + */
3492 + headroom = (uint16_t)(bl->priv_data_size +
3493 + (bl->parse_results ? DPA_PARSE_RESULTS_SIZE : 0) +
3494 + (bl->hash_results || bl->time_stamp ?
3495 + DPA_TIME_STAMP_SIZE + DPA_HASH_RESULTS_SIZE : 0) +
3496 + bl->manip_extra_space);
3497 +
3498 + return bl->data_align ? ALIGN(headroom, bl->data_align) : headroom;
3499 +}
3500 +
3501 +int fm_mac_dump_regs(struct mac_device *h_dev, char *buf, int n);
3502 +int fm_mac_dump_rx_stats(struct mac_device *h_dev, char *buf, int n);
3503 +int fm_mac_dump_tx_stats(struct mac_device *h_dev, char *buf, int n);
3504 +
3505 +void dpaa_eth_sysfs_remove(struct device *dev);
3506 +void dpaa_eth_sysfs_init(struct device *dev);
3507 +int dpaa_eth_poll(struct napi_struct *napi, int budget);
3508 +
3509 +void dpa_private_napi_del(struct net_device *net_dev);
3510 +
3511 +/* Equivalent to a memset(0), but works faster */
3512 +static inline void clear_fd(struct qm_fd *fd)
3513 +{
3514 + fd->opaque_addr = 0;
3515 + fd->opaque = 0;
3516 + fd->cmd = 0;
3517 +}
3518 +
3519 +static inline int _dpa_tx_fq_to_id(const struct dpa_priv_s *priv,
3520 + struct qman_fq *tx_fq)
3521 +{
3522 + int i;
3523 +
3524 + for (i = 0; i < DPAA_ETH_TX_QUEUES; i++)
3525 + if (priv->egress_fqs[i] == tx_fq)
3526 + return i;
3527 +
3528 + return -EINVAL;
3529 +}
3530 +
3531 +static inline int __hot dpa_xmit(struct dpa_priv_s *priv,
3532 + struct rtnl_link_stats64 *percpu_stats,
3533 + struct qm_fd *fd, struct qman_fq *egress_fq,
3534 + struct qman_fq *conf_fq)
3535 +{
3536 + int err, i;
3537 +
3538 + if (fd->bpid == 0xff)
3539 + fd->cmd |= qman_fq_fqid(conf_fq);
3540 +
3541 + /* Trace this Tx fd */
3542 + trace_dpa_tx_fd(priv->net_dev, egress_fq, fd);
3543 +
3544 + for (i = 0; i < 100000; i++) {
3545 + err = qman_enqueue(egress_fq, fd, 0);
3546 + if (err != -EBUSY)
3547 + break;
3548 + }
3549 +
3550 + if (unlikely(err < 0)) {
3551 + /* TODO differentiate b/w -EBUSY (EQCR full) and other codes? */
3552 + percpu_stats->tx_errors++;
3553 + percpu_stats->tx_fifo_errors++;
3554 + return err;
3555 + }
3556 +
3557 + percpu_stats->tx_packets++;
3558 + percpu_stats->tx_bytes += dpa_fd_length(fd);
3559 +
3560 + return 0;
3561 +}
3562 +
3563 +/* Use multiple WQs for FQ assignment:
3564 + * - Tx Confirmation queues go to WQ1.
3565 + * - Rx Default, Tx and PCD queues go to WQ3 (no differentiation between
3566 + * Rx and Tx traffic, or between Rx Default and Rx PCD frames).
3567 + * - Rx Error and Tx Error queues go to WQ2 (giving them a better chance
3568 + * to be scheduled, in case there are many more FQs in WQ3).
3569 + * This ensures that Tx-confirmed buffers are timely released. In particular,
3570 + * it avoids congestion on the Tx Confirm FQs, which can pile up PFDRs if they
3571 + * are greatly outnumbered by other FQs in the system (usually PCDs), while
3572 + * dequeue scheduling is round-robin.
3573 + */
3574 +static inline void _dpa_assign_wq(struct dpa_fq *fq)
3575 +{
3576 + switch (fq->fq_type) {
3577 + case FQ_TYPE_TX_CONFIRM:
3578 + case FQ_TYPE_TX_CONF_MQ:
3579 + fq->wq = 1;
3580 + break;
3581 + case FQ_TYPE_RX_DEFAULT:
3582 + case FQ_TYPE_TX:
3583 + fq->wq = 3;
3584 + break;
3585 + case FQ_TYPE_RX_ERROR:
3586 + case FQ_TYPE_TX_ERROR:
3587 + case FQ_TYPE_RX_PCD_HI_PRIO:
3588 + fq->wq = 2;
3589 + break;
3590 + case FQ_TYPE_RX_PCD:
3591 + fq->wq = 5;
3592 + break;
3593 + default:
3594 + WARN(1, "Invalid FQ type %d for FQID %d!\n",
3595 + fq->fq_type, fq->fqid);
3596 + }
3597 +}
3598 +
3599 +#ifdef CONFIG_FSL_DPAA_ETH_USE_NDO_SELECT_QUEUE
3600 +/* Use in lieu of skb_get_queue_mapping() */
3601 +#ifdef CONFIG_FMAN_PFC
3602 +#define dpa_get_queue_mapping(skb) \
3603 + (((skb)->priority < CONFIG_FMAN_PFC_COS_COUNT) ? \
3604 + ((skb)->priority * dpa_num_cpus + smp_processor_id()) : \
3605 + ((CONFIG_FMAN_PFC_COS_COUNT - 1) * \
3606 + dpa_num_cpus + smp_processor_id()));
3607 +
3608 +#else
3609 +#define dpa_get_queue_mapping(skb) \
3610 + raw_smp_processor_id()
3611 +#endif
3612 +#else
3613 +/* Use the queue selected by XPS */
3614 +#define dpa_get_queue_mapping(skb) \
3615 + skb_get_queue_mapping(skb)
3616 +#endif
3617 +
3618 +#ifdef CONFIG_PTP_1588_CLOCK_DPAA
3619 +struct ptp_priv_s {
3620 + struct device_node *node;
3621 + struct platform_device *of_dev;
3622 + struct ptp_clock *clock;
3623 + struct mac_device *mac_dev;
3624 +};
3625 +extern struct ptp_priv_s ptp_priv;
3626 +#endif
3627 +
3628 +static inline void _dpa_bp_free_pf(void *addr)
3629 +{
3630 + put_page(virt_to_head_page(addr));
3631 +}
3632 +
3633 +/* LS1043A SoC has a HW issue regarding FMan DMA transactions; The issue
3634 + * manifests itself at high traffic rates when frames cross 4K memory
3635 + * boundaries or when they are not aligned to 16 bytes; For the moment, we
3636 + * use a SW workaround to avoid frames larger than 4K or that exceed 4K
3637 + * alignments and to realign the frames to 16 bytes.
3638 + */
3639 +
3640 +#ifndef CONFIG_PPC
3641 +extern bool dpaa_errata_a010022; /* SoC affected by A010022 errata */
3642 +#define NONREC_MARK 0x01
3643 +#define HAS_DMA_ISSUE(start, size) \
3644 + (((uintptr_t)(start) + (size)) > \
3645 + (((uintptr_t)(start) + 0x1000) & ~0xFFF))
3646 +#endif /* !CONFIG_PPC */
3647 +
3648 +#endif /* __DPA_H */
3649 --- /dev/null
3650 +++ b/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_base.c
3651 @@ -0,0 +1,205 @@
3652 +/* Copyright 2008-2013 Freescale Semiconductor, Inc.
3653 + *
3654 + * Redistribution and use in source and binary forms, with or without
3655 + * modification, are permitted provided that the following conditions are met:
3656 + * * Redistributions of source code must retain the above copyright
3657 + * notice, this list of conditions and the following disclaimer.
3658 + * * Redistributions in binary form must reproduce the above copyright
3659 + * notice, this list of conditions and the following disclaimer in the
3660 + * documentation and/or other materials provided with the distribution.
3661 + * * Neither the name of Freescale Semiconductor nor the
3662 + * names of its contributors may be used to endorse or promote products
3663 + * derived from this software without specific prior written permission.
3664 + *
3665 + *
3666 + * ALTERNATIVELY, this software may be distributed under the terms of the
3667 + * GNU General Public License ("GPL") as published by the Free Software
3668 + * Foundation, either version 2 of that License or (at your option) any
3669 + * later version.
3670 + *
3671 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
3672 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
3673 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
3674 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
3675 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
3676 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
3677 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
3678 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
3679 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
3680 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
3681 + */
3682 +
3683 +#ifdef CONFIG_FSL_DPAA_ETH_DEBUG
3684 +#define pr_fmt(fmt) \
3685 + KBUILD_MODNAME ": %s:%hu:%s() " fmt, \
3686 + KBUILD_BASENAME".c", __LINE__, __func__
3687 +#else
3688 +#define pr_fmt(fmt) \
3689 + KBUILD_MODNAME ": " fmt
3690 +#endif
3691 +
3692 +#include <linux/init.h>
3693 +#include <linux/module.h>
3694 +#include <linux/io.h>
3695 +#include <linux/of_platform.h>
3696 +#include <linux/of_net.h>
3697 +#include <linux/etherdevice.h>
3698 +#include <linux/kthread.h>
3699 +#include <linux/percpu.h>
3700 +#include <linux/highmem.h>
3701 +#include <linux/sort.h>
3702 +#include <linux/fsl_qman.h>
3703 +#include "dpaa_eth.h"
3704 +#include "dpaa_eth_common.h"
3705 +#include "dpaa_eth_base.h"
3706 +
3707 +#define DPA_DESCRIPTION "FSL DPAA Advanced drivers:"
3708 +
3709 +MODULE_LICENSE("Dual BSD/GPL");
3710 +
3711 +uint8_t advanced_debug = -1;
3712 +module_param(advanced_debug, byte, S_IRUGO);
3713 +MODULE_PARM_DESC(advanced_debug, "Module/Driver verbosity level");
3714 +EXPORT_SYMBOL(advanced_debug);
3715 +
3716 +static int dpa_bp_cmp(const void *dpa_bp0, const void *dpa_bp1)
3717 +{
3718 + return ((struct dpa_bp *)dpa_bp0)->size -
3719 + ((struct dpa_bp *)dpa_bp1)->size;
3720 +}
3721 +
3722 +struct dpa_bp * __cold __must_check /* __attribute__((nonnull)) */
3723 +dpa_bp_probe(struct platform_device *_of_dev, size_t *count)
3724 +{
3725 + int i, lenp, na, ns, err;
3726 + struct device *dev;
3727 + struct device_node *dev_node;
3728 + const __be32 *bpool_cfg;
3729 + struct dpa_bp *dpa_bp;
3730 + u32 bpid;
3731 +
3732 + dev = &_of_dev->dev;
3733 +
3734 + *count = of_count_phandle_with_args(dev->of_node,
3735 + "fsl,bman-buffer-pools", NULL);
3736 + if (*count < 1) {
3737 + dev_err(dev, "missing fsl,bman-buffer-pools device tree entry\n");
3738 + return ERR_PTR(-EINVAL);
3739 + }
3740 +
3741 + dpa_bp = devm_kzalloc(dev, *count * sizeof(*dpa_bp), GFP_KERNEL);
3742 + if (dpa_bp == NULL) {
3743 + dev_err(dev, "devm_kzalloc() failed\n");
3744 + return ERR_PTR(-ENOMEM);
3745 + }
3746 +
3747 + dev_node = of_find_node_by_path("/");
3748 + if (unlikely(dev_node == NULL)) {
3749 + dev_err(dev, "of_find_node_by_path(/) failed\n");
3750 + return ERR_PTR(-EINVAL);
3751 + }
3752 +
3753 + na = of_n_addr_cells(dev_node);
3754 + ns = of_n_size_cells(dev_node);
3755 +
3756 + for (i = 0; i < *count; i++) {
3757 + of_node_put(dev_node);
3758 +
3759 + dev_node = of_parse_phandle(dev->of_node,
3760 + "fsl,bman-buffer-pools", i);
3761 + if (dev_node == NULL) {
3762 + dev_err(dev, "of_find_node_by_phandle() failed\n");
3763 + return ERR_PTR(-EFAULT);
3764 + }
3765 +
3766 + if (unlikely(!of_device_is_compatible(dev_node, "fsl,bpool"))) {
3767 + dev_err(dev,
3768 + "!of_device_is_compatible(%s, fsl,bpool)\n",
3769 + dev_node->full_name);
3770 + dpa_bp = ERR_PTR(-EINVAL);
3771 + goto _return_of_node_put;
3772 + }
3773 +
3774 + err = of_property_read_u32(dev_node, "fsl,bpid", &bpid);
3775 + if (err) {
3776 + dev_err(dev, "Cannot find buffer pool ID in the device tree\n");
3777 + dpa_bp = ERR_PTR(-EINVAL);
3778 + goto _return_of_node_put;
3779 + }
3780 + dpa_bp[i].bpid = (uint8_t)bpid;
3781 +
3782 + bpool_cfg = of_get_property(dev_node, "fsl,bpool-ethernet-cfg",
3783 + &lenp);
3784 + if (bpool_cfg && (lenp == (2 * ns + na) * sizeof(*bpool_cfg))) {
3785 + const uint32_t *seed_pool;
3786 +
3787 + dpa_bp[i].config_count =
3788 + (int)of_read_number(bpool_cfg, ns);
3789 + dpa_bp[i].size =
3790 + (size_t)of_read_number(bpool_cfg + ns, ns);
3791 + dpa_bp[i].paddr =
3792 + of_read_number(bpool_cfg + 2 * ns, na);
3793 +
3794 + seed_pool = of_get_property(dev_node,
3795 + "fsl,bpool-ethernet-seeds", &lenp);
3796 + dpa_bp[i].seed_pool = !!seed_pool;
3797 +
3798 + } else {
3799 + dev_err(dev,
3800 + "Missing/invalid fsl,bpool-ethernet-cfg device tree entry for node %s\n",
3801 + dev_node->full_name);
3802 + dpa_bp = ERR_PTR(-EINVAL);
3803 + goto _return_of_node_put;
3804 + }
3805 + }
3806 +
3807 + sort(dpa_bp, *count, sizeof(*dpa_bp), dpa_bp_cmp, NULL);
3808 +
3809 + return dpa_bp;
3810 +
3811 +_return_of_node_put:
3812 + if (dev_node)
3813 + of_node_put(dev_node);
3814 +
3815 + return dpa_bp;
3816 +}
3817 +EXPORT_SYMBOL(dpa_bp_probe);
3818 +
3819 +int dpa_bp_create(struct net_device *net_dev, struct dpa_bp *dpa_bp,
3820 + size_t count)
3821 +{
3822 + struct dpa_priv_s *priv = netdev_priv(net_dev);
3823 + int i;
3824 +
3825 + priv->dpa_bp = dpa_bp;
3826 + priv->bp_count = count;
3827 +
3828 + for (i = 0; i < count; i++) {
3829 + int err;
3830 + err = dpa_bp_alloc(&dpa_bp[i], net_dev->dev.parent);
3831 + if (err < 0) {
3832 + dpa_bp_free(priv);
3833 + priv->dpa_bp = NULL;
3834 + return err;
3835 + }
3836 + }
3837 +
3838 + return 0;
3839 +}
3840 +EXPORT_SYMBOL(dpa_bp_create);
3841 +
3842 +static int __init __cold dpa_advanced_load(void)
3843 +{
3844 + pr_info(DPA_DESCRIPTION "\n");
3845 +
3846 + return 0;
3847 +}
3848 +module_init(dpa_advanced_load);
3849 +
3850 +static void __exit __cold dpa_advanced_unload(void)
3851 +{
3852 + pr_debug(KBUILD_MODNAME ": -> %s:%s()\n",
3853 + KBUILD_BASENAME".c", __func__);
3854 +
3855 +}
3856 +module_exit(dpa_advanced_unload);
3857 --- /dev/null
3858 +++ b/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_base.h
3859 @@ -0,0 +1,49 @@
3860 +/* Copyright 2008-2013 Freescale Semiconductor, Inc.
3861 + *
3862 + * Redistribution and use in source and binary forms, with or without
3863 + * modification, are permitted provided that the following conditions are met:
3864 + * * Redistributions of source code must retain the above copyright
3865 + * notice, this list of conditions and the following disclaimer.
3866 + * * Redistributions in binary form must reproduce the above copyright
3867 + * notice, this list of conditions and the following disclaimer in the
3868 + * documentation and/or other materials provided with the distribution.
3869 + * * Neither the name of Freescale Semiconductor nor the
3870 + * names of its contributors may be used to endorse or promote products
3871 + * derived from this software without specific prior written permission.
3872 + *
3873 + *
3874 + * ALTERNATIVELY, this software may be distributed under the terms of the
3875 + * GNU General Public License ("GPL") as published by the Free Software
3876 + * Foundation, either version 2 of that License or (at your option) any
3877 + * later version.
3878 + *
3879 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
3880 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
3881 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
3882 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
3883 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
3884 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
3885 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
3886 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
3887 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
3888 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
3889 + */
3890 +
3891 +#ifndef __DPAA_ETH_BASE_H
3892 +#define __DPAA_ETH_BASE_H
3893 +
3894 +#include <linux/etherdevice.h> /* struct net_device */
3895 +#include <linux/fsl_bman.h> /* struct bm_buffer */
3896 +#include <linux/of_platform.h> /* struct platform_device */
3897 +#include <linux/net_tstamp.h> /* struct hwtstamp_config */
3898 +
3899 +extern uint8_t advanced_debug;
3900 +extern const struct dpa_fq_cbs_t shared_fq_cbs;
3901 +extern int __hot dpa_shared_tx(struct sk_buff *skb, struct net_device *net_dev);
3902 +
3903 +struct dpa_bp * __cold __must_check /* __attribute__((nonnull)) */
3904 +dpa_bp_probe(struct platform_device *_of_dev, size_t *count);
3905 +int dpa_bp_create(struct net_device *net_dev, struct dpa_bp *dpa_bp,
3906 + size_t count);
3907 +
3908 +#endif /* __DPAA_ETH_BASE_H */
3909 --- /dev/null
3910 +++ b/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_ceetm.c
3911 @@ -0,0 +1,2013 @@
3912 +/* Copyright 2008-2016 Freescale Semiconductor Inc.
3913 + *
3914 + * Redistribution and use in source and binary forms, with or without
3915 + * modification, are permitted provided that the following conditions are met:
3916 + * * Redistributions of source code must retain the above copyright
3917 + * notice, this list of conditions and the following disclaimer.
3918 + * * Redistributions in binary form must reproduce the above copyright
3919 + * notice, this list of conditions and the following disclaimer in the
3920 + * documentation and/or other materials provided with the distribution.
3921 + * * Neither the name of Freescale Semiconductor nor the
3922 + * names of its contributors may be used to endorse or promote products
3923 + * derived from this software without specific prior written permission.
3924 + *
3925 + *
3926 + * ALTERNATIVELY, this software may be distributed under the terms of the
3927 + * GNU General Public License ("GPL") as published by the Free Software
3928 + * Foundation, either version 2 of that License or (at your option) any
3929 + * later version.
3930 + *
3931 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
3932 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
3933 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
3934 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
3935 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
3936 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
3937 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
3938 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
3939 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
3940 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
3941 + */
3942 +
3943 +#include <linux/init.h>
3944 +#include "dpaa_eth_ceetm.h"
3945 +
3946 +#define DPA_CEETM_DESCRIPTION "FSL DPAA CEETM qdisc"
3947 +
3948 +const struct nla_policy ceetm_policy[TCA_CEETM_MAX + 1] = {
3949 + [TCA_CEETM_COPT] = { .len = sizeof(struct tc_ceetm_copt) },
3950 + [TCA_CEETM_QOPS] = { .len = sizeof(struct tc_ceetm_qopt) },
3951 +};
3952 +
3953 +struct Qdisc_ops ceetm_qdisc_ops;
3954 +
3955 +/* Obtain the DCP and the SP ids from the FMan port */
3956 +static void get_dcp_and_sp(struct net_device *dev, enum qm_dc_portal *dcp_id,
3957 + unsigned int *sp_id)
3958 +{
3959 + uint32_t channel;
3960 + t_LnxWrpFmPortDev *port_dev;
3961 + struct dpa_priv_s *dpa_priv = netdev_priv(dev);
3962 + struct mac_device *mac_dev = dpa_priv->mac_dev;
3963 +
3964 + port_dev = (t_LnxWrpFmPortDev *)mac_dev->port_dev[TX];
3965 + channel = port_dev->txCh;
3966 +
3967 + *sp_id = channel & CHANNEL_SP_MASK;
3968 + pr_debug(KBUILD_BASENAME " : FM sub-portal ID %d\n", *sp_id);
3969 +
3970 + if (channel < DCP0_MAX_CHANNEL) {
3971 + *dcp_id = qm_dc_portal_fman0;
3972 + pr_debug(KBUILD_BASENAME " : DCP ID 0\n");
3973 + } else {
3974 + *dcp_id = qm_dc_portal_fman1;
3975 + pr_debug(KBUILD_BASENAME " : DCP ID 1\n");
3976 + }
3977 +}
3978 +
3979 +/* Enqueue Rejection Notification callback */
3980 +static void ceetm_ern(struct qman_portal *portal, struct qman_fq *fq,
3981 + const struct qm_mr_entry *msg)
3982 +{
3983 + struct dpa_percpu_priv_s *dpa_percpu_priv;
3984 + struct ceetm_class_stats *cstats = NULL;
3985 + const struct dpa_priv_s *dpa_priv;
3986 + struct qm_fd fd = msg->ern.fd;
3987 + struct net_device *net_dev;
3988 + struct ceetm_fq *ceetm_fq;
3989 + struct ceetm_class *cls;
3990 + struct sk_buff *skb;
3991 +
3992 + ceetm_fq = container_of(fq, struct ceetm_fq, fq);
3993 + net_dev = ceetm_fq->net_dev;
3994 + dpa_priv = netdev_priv(net_dev);
3995 + dpa_percpu_priv = raw_cpu_ptr(dpa_priv->percpu_priv);
3996 +
3997 + /* Increment DPA counters */
3998 + dpa_percpu_priv->stats.tx_dropped++;
3999 + dpa_percpu_priv->stats.tx_fifo_errors++;
4000 + count_ern(dpa_percpu_priv, msg);
4001 +
4002 + /* Increment CEETM counters */
4003 + cls = ceetm_fq->ceetm_cls;
4004 + switch (cls->type) {
4005 + case CEETM_PRIO:
4006 + cstats = this_cpu_ptr(cls->prio.cstats);
4007 + break;
4008 + case CEETM_WBFS:
4009 + cstats = this_cpu_ptr(cls->wbfs.cstats);
4010 + break;
4011 + }
4012 +
4013 + if (cstats)
4014 + cstats->ern_drop_count++;
4015 +
4016 + /* Release the buffers that were supposed to be recycled. */
4017 + if (fd.bpid != 0xff) {
4018 + dpa_fd_release(net_dev, &fd);
4019 + return;
4020 + }
4021 +
4022 + /* Release the frames that were supposed to return on the
4023 + * confirmation path.
4024 + */
4025 + skb = _dpa_cleanup_tx_fd(dpa_priv, &fd);
4026 + dev_kfree_skb_any(skb);
4027 +}
4028 +
4029 +/* Congestion State Change Notification callback */
4030 +static void ceetm_cscn(struct qm_ceetm_ccg *ccg, void *cb_ctx, int congested)
4031 +{
4032 + struct ceetm_fq *ceetm_fq = (struct ceetm_fq *)cb_ctx;
4033 + struct dpa_priv_s *dpa_priv = netdev_priv(ceetm_fq->net_dev);
4034 + struct ceetm_class *cls = ceetm_fq->ceetm_cls;
4035 + struct ceetm_class_stats *cstats = NULL;
4036 +
4037 + switch (cls->type) {
4038 + case CEETM_PRIO:
4039 + cstats = this_cpu_ptr(cls->prio.cstats);
4040 + break;
4041 + case CEETM_WBFS:
4042 + cstats = this_cpu_ptr(cls->wbfs.cstats);
4043 + break;
4044 + }
4045 +
4046 + ceetm_fq->congested = congested;
4047 +
4048 + if (congested) {
4049 + dpa_priv->cgr_data.congestion_start_jiffies = jiffies;
4050 + dpa_priv->cgr_data.cgr_congested_count++;
4051 + if (cstats)
4052 + cstats->congested_count++;
4053 + } else {
4054 + dpa_priv->cgr_data.congested_jiffies +=
4055 + (jiffies - dpa_priv->cgr_data.congestion_start_jiffies);
4056 + }
4057 +}
4058 +
4059 +/* Allocate a ceetm fq */
4060 +static int ceetm_alloc_fq(struct ceetm_fq **fq, struct net_device *dev,
4061 + struct ceetm_class *cls)
4062 +{
4063 + *fq = kzalloc(sizeof(**fq), GFP_KERNEL);
4064 + if (!*fq)
4065 + return -ENOMEM;
4066 +
4067 + (*fq)->net_dev = dev;
4068 + (*fq)->ceetm_cls = cls;
4069 + (*fq)->congested = 0;
4070 + return 0;
4071 +}
4072 +
4073 +/* Configure a ceetm Class Congestion Group */
4074 +static int ceetm_config_ccg(struct qm_ceetm_ccg **ccg,
4075 + struct qm_ceetm_channel *channel, unsigned int id,
4076 + struct ceetm_fq *fq, struct dpa_priv_s *dpa_priv)
4077 +{
4078 + int err;
4079 + u32 cs_th;
4080 + u16 ccg_mask;
4081 + struct qm_ceetm_ccg_params ccg_params;
4082 +
4083 + err = qman_ceetm_ccg_claim(ccg, channel, id, ceetm_cscn, fq);
4084 + if (err)
4085 + return err;
4086 +
4087 + /* Configure the count mode (frames/bytes), enable congestion state
4088 + * notifications, configure the congestion entry and exit thresholds,
4089 + * enable tail-drop, configure the tail-drop mode, and set the
4090 + * overhead accounting limit
4091 + */
4092 + ccg_mask = QM_CCGR_WE_MODE |
4093 + QM_CCGR_WE_CSCN_EN |
4094 + QM_CCGR_WE_CS_THRES_IN | QM_CCGR_WE_CS_THRES_OUT |
4095 + QM_CCGR_WE_TD_EN | QM_CCGR_WE_TD_MODE |
4096 + QM_CCGR_WE_OAL;
4097 +
4098 + ccg_params.mode = 0; /* count bytes */
4099 + ccg_params.cscn_en = 1; /* generate notifications */
4100 + ccg_params.td_en = 1; /* enable tail-drop */
4101 + ccg_params.td_mode = 0; /* tail-drop on congestion state */
4102 + ccg_params.oal = (signed char)(min(sizeof(struct sk_buff) +
4103 + dpa_priv->tx_headroom, (size_t)FSL_QMAN_MAX_OAL));
4104 +
4105 + /* Set the congestion state thresholds according to the link speed */
4106 + if (dpa_priv->mac_dev->if_support & SUPPORTED_10000baseT_Full)
4107 + cs_th = CONFIG_FSL_DPAA_CEETM_CCS_THRESHOLD_10G;
4108 + else
4109 + cs_th = CONFIG_FSL_DPAA_CEETM_CCS_THRESHOLD_1G;
4110 +
4111 + qm_cgr_cs_thres_set64(&ccg_params.cs_thres_in, cs_th, 1);
4112 + qm_cgr_cs_thres_set64(&ccg_params.cs_thres_out,
4113 + cs_th * CEETM_CCGR_RATIO, 1);
4114 +
4115 + err = qman_ceetm_ccg_set(*ccg, ccg_mask, &ccg_params);
4116 + if (err)
4117 + return err;
4118 +
4119 + return 0;
4120 +}
4121 +
4122 +/* Configure a ceetm Logical Frame Queue */
4123 +static int ceetm_config_lfq(struct qm_ceetm_cq *cq, struct ceetm_fq *fq,
4124 + struct qm_ceetm_lfq **lfq)
4125 +{
4126 + int err;
4127 + u64 context_a;
4128 + u32 context_b;
4129 +
4130 + err = qman_ceetm_lfq_claim(lfq, cq);
4131 + if (err)
4132 + return err;
4133 +
4134 + /* Get the former contexts in order to preserve context B */
4135 + err = qman_ceetm_lfq_get_context(*lfq, &context_a, &context_b);
4136 + if (err)
4137 + return err;
4138 +
4139 + context_a = CEETM_CONTEXT_A;
4140 + err = qman_ceetm_lfq_set_context(*lfq, context_a, context_b);
4141 + if (err)
4142 + return err;
4143 +
4144 + (*lfq)->ern = ceetm_ern;
4145 +
4146 + err = qman_ceetm_create_fq(*lfq, &fq->fq);
4147 + if (err)
4148 + return err;
4149 +
4150 + return 0;
4151 +}
4152 +
4153 +/* Configure a prio ceetm class */
4154 +static int ceetm_config_prio_cls(struct ceetm_class *cls,
4155 + struct net_device *dev,
4156 + struct qm_ceetm_channel *channel,
4157 + unsigned int id)
4158 +{
4159 + int err;
4160 + struct dpa_priv_s *dpa_priv = netdev_priv(dev);
4161 +
4162 + err = ceetm_alloc_fq(&cls->prio.fq, dev, cls);
4163 + if (err)
4164 + return err;
4165 +
4166 + /* Claim and configure the CCG */
4167 + err = ceetm_config_ccg(&cls->prio.ccg, channel, id, cls->prio.fq,
4168 + dpa_priv);
4169 + if (err)
4170 + return err;
4171 +
4172 + /* Claim and configure the CQ */
4173 + err = qman_ceetm_cq_claim(&cls->prio.cq, channel, id, cls->prio.ccg);
4174 + if (err)
4175 + return err;
4176 +
4177 + if (cls->shaped) {
4178 + err = qman_ceetm_channel_set_cq_cr_eligibility(channel, id, 1);
4179 + if (err)
4180 + return err;
4181 +
4182 + err = qman_ceetm_channel_set_cq_er_eligibility(channel, id, 1);
4183 + if (err)
4184 + return err;
4185 + }
4186 +
4187 + /* Claim and configure a LFQ */
4188 + err = ceetm_config_lfq(cls->prio.cq, cls->prio.fq, &cls->prio.lfq);
4189 + if (err)
4190 + return err;
4191 +
4192 + return 0;
4193 +}
4194 +
4195 +/* Configure a wbfs ceetm class */
4196 +static int ceetm_config_wbfs_cls(struct ceetm_class *cls,
4197 + struct net_device *dev,
4198 + struct qm_ceetm_channel *channel,
4199 + unsigned int id, int type)
4200 +{
4201 + int err;
4202 + struct dpa_priv_s *dpa_priv = netdev_priv(dev);
4203 +
4204 + err = ceetm_alloc_fq(&cls->wbfs.fq, dev, cls);
4205 + if (err)
4206 + return err;
4207 +
4208 + /* Claim and configure the CCG */
4209 + err = ceetm_config_ccg(&cls->wbfs.ccg, channel, id, cls->wbfs.fq,
4210 + dpa_priv);
4211 + if (err)
4212 + return err;
4213 +
4214 + /* Claim and configure the CQ */
4215 + if (type == WBFS_GRP_B)
4216 + err = qman_ceetm_cq_claim_B(&cls->wbfs.cq, channel, id,
4217 + cls->wbfs.ccg);
4218 + else
4219 + err = qman_ceetm_cq_claim_A(&cls->wbfs.cq, channel, id,
4220 + cls->wbfs.ccg);
4221 + if (err)
4222 + return err;
4223 +
4224 + /* Configure the CQ weight: real number multiplied by 100 to get rid
4225 + * of the fraction
4226 + */
4227 + err = qman_ceetm_set_queue_weight_in_ratio(cls->wbfs.cq,
4228 + cls->wbfs.weight * 100);
4229 + if (err)
4230 + return err;
4231 +
4232 + /* Claim and configure a LFQ */
4233 + err = ceetm_config_lfq(cls->wbfs.cq, cls->wbfs.fq, &cls->wbfs.lfq);
4234 + if (err)
4235 + return err;
4236 +
4237 + return 0;
4238 +}
4239 +
4240 +/* Find class in qdisc hash table using given handle */
4241 +static inline struct ceetm_class *ceetm_find(u32 handle, struct Qdisc *sch)
4242 +{
4243 + struct ceetm_qdisc *priv = qdisc_priv(sch);
4244 + struct Qdisc_class_common *clc;
4245 +
4246 + pr_debug(KBUILD_BASENAME " : %s : find class %X in qdisc %X\n",
4247 + __func__, handle, sch->handle);
4248 +
4249 + clc = qdisc_class_find(&priv->clhash, handle);
4250 + return clc ? container_of(clc, struct ceetm_class, common) : NULL;
4251 +}
4252 +
4253 +/* Insert a class in the qdisc's class hash */
4254 +static void ceetm_link_class(struct Qdisc *sch,
4255 + struct Qdisc_class_hash *clhash,
4256 + struct Qdisc_class_common *common)
4257 +{
4258 + sch_tree_lock(sch);
4259 + qdisc_class_hash_insert(clhash, common);
4260 + sch_tree_unlock(sch);
4261 + qdisc_class_hash_grow(sch, clhash);
4262 +}
4263 +
4264 +/* Destroy a ceetm class */
4265 +static void ceetm_cls_destroy(struct Qdisc *sch, struct ceetm_class *cl)
4266 +{
4267 + if (!cl)
4268 + return;
4269 +
4270 + pr_debug(KBUILD_BASENAME " : %s : destroy class %X from under %X\n",
4271 + __func__, cl->common.classid, sch->handle);
4272 +
4273 + switch (cl->type) {
4274 + case CEETM_ROOT:
4275 + if (cl->root.child) {
4276 + qdisc_destroy(cl->root.child);
4277 + cl->root.child = NULL;
4278 + }
4279 +
4280 + if (cl->root.ch && qman_ceetm_channel_release(cl->root.ch))
4281 + pr_err(KBUILD_BASENAME
4282 + " : %s : error releasing the channel %d\n",
4283 + __func__, cl->root.ch->idx);
4284 +
4285 + break;
4286 +
4287 + case CEETM_PRIO:
4288 + if (cl->prio.child) {
4289 + qdisc_destroy(cl->prio.child);
4290 + cl->prio.child = NULL;
4291 + }
4292 +
4293 + if (cl->prio.lfq && qman_ceetm_lfq_release(cl->prio.lfq))
4294 + pr_err(KBUILD_BASENAME
4295 + " : %s : error releasing the LFQ %d\n",
4296 + __func__, cl->prio.lfq->idx);
4297 +
4298 + if (cl->prio.cq && qman_ceetm_cq_release(cl->prio.cq))
4299 + pr_err(KBUILD_BASENAME
4300 + " : %s : error releasing the CQ %d\n",
4301 + __func__, cl->prio.cq->idx);
4302 +
4303 + if (cl->prio.ccg && qman_ceetm_ccg_release(cl->prio.ccg))
4304 + pr_err(KBUILD_BASENAME
4305 + " : %s : error releasing the CCG %d\n",
4306 + __func__, cl->prio.ccg->idx);
4307 +
4308 + kfree(cl->prio.fq);
4309 +
4310 + if (cl->prio.cstats)
4311 + free_percpu(cl->prio.cstats);
4312 +
4313 + break;
4314 +
4315 + case CEETM_WBFS:
4316 + if (cl->wbfs.lfq && qman_ceetm_lfq_release(cl->wbfs.lfq))
4317 + pr_err(KBUILD_BASENAME
4318 + " : %s : error releasing the LFQ %d\n",
4319 + __func__, cl->wbfs.lfq->idx);
4320 +
4321 + if (cl->wbfs.cq && qman_ceetm_cq_release(cl->wbfs.cq))
4322 + pr_err(KBUILD_BASENAME
4323 + " : %s : error releasing the CQ %d\n",
4324 + __func__, cl->wbfs.cq->idx);
4325 +
4326 + if (cl->wbfs.ccg && qman_ceetm_ccg_release(cl->wbfs.ccg))
4327 + pr_err(KBUILD_BASENAME
4328 + " : %s : error releasing the CCG %d\n",
4329 + __func__, cl->wbfs.ccg->idx);
4330 +
4331 + kfree(cl->wbfs.fq);
4332 +
4333 + if (cl->wbfs.cstats)
4334 + free_percpu(cl->wbfs.cstats);
4335 + }
4336 +
4337 + tcf_destroy_chain(&cl->filter_list);
4338 + kfree(cl);
4339 +}
4340 +
4341 +/* Destroy a ceetm qdisc */
4342 +static void ceetm_destroy(struct Qdisc *sch)
4343 +{
4344 + unsigned int ntx, i;
4345 + struct hlist_node *next;
4346 + struct ceetm_class *cl;
4347 + struct ceetm_qdisc *priv = qdisc_priv(sch);
4348 + struct net_device *dev = qdisc_dev(sch);
4349 +
4350 + pr_debug(KBUILD_BASENAME " : %s : destroy qdisc %X\n",
4351 + __func__, sch->handle);
4352 +
4353 + /* All filters need to be removed before destroying the classes */
4354 + tcf_destroy_chain(&priv->filter_list);
4355 +
4356 + for (i = 0; i < priv->clhash.hashsize; i++) {
4357 + hlist_for_each_entry(cl, &priv->clhash.hash[i], common.hnode)
4358 + tcf_destroy_chain(&cl->filter_list);
4359 + }
4360 +
4361 + for (i = 0; i < priv->clhash.hashsize; i++) {
4362 + hlist_for_each_entry_safe(cl, next, &priv->clhash.hash[i],
4363 + common.hnode)
4364 + ceetm_cls_destroy(sch, cl);
4365 + }
4366 +
4367 + qdisc_class_hash_destroy(&priv->clhash);
4368 +
4369 + switch (priv->type) {
4370 + case CEETM_ROOT:
4371 + dpa_disable_ceetm(dev);
4372 +
4373 + if (priv->root.lni && qman_ceetm_lni_release(priv->root.lni))
4374 + pr_err(KBUILD_BASENAME
4375 + " : %s : error releasing the LNI %d\n",
4376 + __func__, priv->root.lni->idx);
4377 +
4378 + if (priv->root.sp && qman_ceetm_sp_release(priv->root.sp))
4379 + pr_err(KBUILD_BASENAME
4380 + " : %s : error releasing the SP %d\n",
4381 + __func__, priv->root.sp->idx);
4382 +
4383 + if (priv->root.qstats)
4384 + free_percpu(priv->root.qstats);
4385 +
4386 + if (!priv->root.qdiscs)
4387 + break;
4388 +
4389 + /* Remove the pfifo qdiscs */
4390 + for (ntx = 0; ntx < dev->num_tx_queues; ntx++)
4391 + if (priv->root.qdiscs[ntx])
4392 + qdisc_destroy(priv->root.qdiscs[ntx]);
4393 +
4394 + kfree(priv->root.qdiscs);
4395 + break;
4396 +
4397 + case CEETM_PRIO:
4398 + if (priv->prio.parent)
4399 + priv->prio.parent->root.child = NULL;
4400 + break;
4401 +
4402 + case CEETM_WBFS:
4403 + if (priv->wbfs.parent)
4404 + priv->wbfs.parent->prio.child = NULL;
4405 + break;
4406 + }
4407 +}
4408 +
4409 +static int ceetm_dump(struct Qdisc *sch, struct sk_buff *skb)
4410 +{
4411 + struct Qdisc *qdisc;
4412 + unsigned int ntx, i;
4413 + struct nlattr *nest;
4414 + struct tc_ceetm_qopt qopt;
4415 + struct ceetm_qdisc_stats *qstats;
4416 + struct net_device *dev = qdisc_dev(sch);
4417 + struct ceetm_qdisc *priv = qdisc_priv(sch);
4418 +
4419 + pr_debug(KBUILD_BASENAME " : %s : qdisc %X\n", __func__, sch->handle);
4420 +
4421 + sch_tree_lock(sch);
4422 + memset(&qopt, 0, sizeof(qopt));
4423 + qopt.type = priv->type;
4424 + qopt.shaped = priv->shaped;
4425 +
4426 + switch (priv->type) {
4427 + case CEETM_ROOT:
4428 + /* Gather statistics from the underlying pfifo qdiscs */
4429 + sch->q.qlen = 0;
4430 + memset(&sch->bstats, 0, sizeof(sch->bstats));
4431 + memset(&sch->qstats, 0, sizeof(sch->qstats));
4432 +
4433 + for (ntx = 0; ntx < dev->num_tx_queues; ntx++) {
4434 + qdisc = netdev_get_tx_queue(dev, ntx)->qdisc_sleeping;
4435 + sch->q.qlen += qdisc->q.qlen;
4436 + sch->bstats.bytes += qdisc->bstats.bytes;
4437 + sch->bstats.packets += qdisc->bstats.packets;
4438 + sch->qstats.qlen += qdisc->qstats.qlen;
4439 + sch->qstats.backlog += qdisc->qstats.backlog;
4440 + sch->qstats.drops += qdisc->qstats.drops;
4441 + sch->qstats.requeues += qdisc->qstats.requeues;
4442 + sch->qstats.overlimits += qdisc->qstats.overlimits;
4443 + }
4444 +
4445 + for_each_online_cpu(i) {
4446 + qstats = per_cpu_ptr(priv->root.qstats, i);
4447 + sch->qstats.drops += qstats->drops;
4448 + }
4449 +
4450 + qopt.rate = priv->root.rate;
4451 + qopt.ceil = priv->root.ceil;
4452 + qopt.overhead = priv->root.overhead;
4453 + break;
4454 +
4455 + case CEETM_PRIO:
4456 + qopt.qcount = priv->prio.qcount;
4457 + break;
4458 +
4459 + case CEETM_WBFS:
4460 + qopt.qcount = priv->wbfs.qcount;
4461 + qopt.cr = priv->wbfs.cr;
4462 + qopt.er = priv->wbfs.er;
4463 + break;
4464 +
4465 + default:
4466 + pr_err(KBUILD_BASENAME " : %s : invalid qdisc\n", __func__);
4467 + sch_tree_unlock(sch);
4468 + return -EINVAL;
4469 + }
4470 +
4471 + nest = nla_nest_start(skb, TCA_OPTIONS);
4472 + if (!nest)
4473 + goto nla_put_failure;
4474 + if (nla_put(skb, TCA_CEETM_QOPS, sizeof(qopt), &qopt))
4475 + goto nla_put_failure;
4476 + nla_nest_end(skb, nest);
4477 +
4478 + sch_tree_unlock(sch);
4479 + return skb->len;
4480 +
4481 +nla_put_failure:
4482 + sch_tree_unlock(sch);
4483 + nla_nest_cancel(skb, nest);
4484 + return -EMSGSIZE;
4485 +}
4486 +
4487 +/* Configure a root ceetm qdisc */
4488 +static int ceetm_init_root(struct Qdisc *sch, struct ceetm_qdisc *priv,
4489 + struct tc_ceetm_qopt *qopt)
4490 +{
4491 + struct netdev_queue *dev_queue;
4492 + struct Qdisc *qdisc;
4493 + enum qm_dc_portal dcp_id;
4494 + unsigned int i, sp_id, parent_id;
4495 + int err;
4496 + u64 bps;
4497 + struct qm_ceetm_sp *sp;
4498 + struct qm_ceetm_lni *lni;
4499 + struct net_device *dev = qdisc_dev(sch);
4500 + struct dpa_priv_s *dpa_priv = netdev_priv(dev);
4501 + struct mac_device *mac_dev = dpa_priv->mac_dev;
4502 +
4503 + pr_debug(KBUILD_BASENAME " : %s : qdisc %X\n", __func__, sch->handle);
4504 +
4505 + /* Validate inputs */
4506 + if (sch->parent != TC_H_ROOT) {
4507 + pr_err("CEETM: a root ceetm qdisc can not be attached to a class\n");
4508 + tcf_destroy_chain(&priv->filter_list);
4509 + qdisc_class_hash_destroy(&priv->clhash);
4510 + return -EINVAL;
4511 + }
4512 +
4513 + if (!mac_dev) {
4514 + pr_err("CEETM: the interface is lacking a mac\n");
4515 + err = -EINVAL;
4516 + goto err_init_root;
4517 + }
4518 +
4519 + /* pre-allocate underlying pfifo qdiscs */
4520 + priv->root.qdiscs = kcalloc(dev->num_tx_queues,
4521 + sizeof(priv->root.qdiscs[0]),
4522 + GFP_KERNEL);
4523 + if (!priv->root.qdiscs) {
4524 + err = -ENOMEM;
4525 + goto err_init_root;
4526 + }
4527 +
4528 + for (i = 0; i < dev->num_tx_queues; i++) {
4529 + dev_queue = netdev_get_tx_queue(dev, i);
4530 + parent_id = TC_H_MAKE(TC_H_MAJ(sch->handle),
4531 + TC_H_MIN(i + PFIFO_MIN_OFFSET));
4532 +
4533 + qdisc = qdisc_create_dflt(dev_queue, &pfifo_qdisc_ops,
4534 + parent_id);
4535 + if (!qdisc) {
4536 + err = -ENOMEM;
4537 + goto err_init_root;
4538 + }
4539 +
4540 + priv->root.qdiscs[i] = qdisc;
4541 + qdisc->flags |= TCQ_F_ONETXQUEUE;
4542 + }
4543 +
4544 + sch->flags |= TCQ_F_MQROOT;
4545 +
4546 + priv->root.qstats = alloc_percpu(struct ceetm_qdisc_stats);
4547 + if (!priv->root.qstats) {
4548 + pr_err(KBUILD_BASENAME " : %s : alloc_percpu() failed\n",
4549 + __func__);
4550 + err = -ENOMEM;
4551 + goto err_init_root;
4552 + }
4553 +
4554 + priv->shaped = qopt->shaped;
4555 + priv->root.rate = qopt->rate;
4556 + priv->root.ceil = qopt->ceil;
4557 + priv->root.overhead = qopt->overhead;
4558 +
4559 + /* Claim the SP */
4560 + get_dcp_and_sp(dev, &dcp_id, &sp_id);
4561 + err = qman_ceetm_sp_claim(&sp, dcp_id, sp_id);
4562 + if (err) {
4563 + pr_err(KBUILD_BASENAME " : %s : failed to claim the SP\n",
4564 + __func__);
4565 + goto err_init_root;
4566 + }
4567 +
4568 + priv->root.sp = sp;
4569 +
4570 + /* Claim the LNI - will use the same id as the SP id since SPs 0-7
4571 + * are connected to the TX FMan ports
4572 + */
4573 + err = qman_ceetm_lni_claim(&lni, dcp_id, sp_id);
4574 + if (err) {
4575 + pr_err(KBUILD_BASENAME " : %s : failed to claim the LNI\n",
4576 + __func__);
4577 + goto err_init_root;
4578 + }
4579 +
4580 + priv->root.lni = lni;
4581 +
4582 + err = qman_ceetm_sp_set_lni(sp, lni);
4583 + if (err) {
4584 + pr_err(KBUILD_BASENAME " : %s : failed to link the SP and LNI\n",
4585 + __func__);
4586 + goto err_init_root;
4587 + }
4588 +
4589 + lni->sp = sp;
4590 +
4591 + /* Configure the LNI shaper */
4592 + if (priv->shaped) {
4593 + err = qman_ceetm_lni_enable_shaper(lni, 1, priv->root.overhead);
4594 + if (err) {
4595 + pr_err(KBUILD_BASENAME " : %s : failed to configure the LNI shaper\n",
4596 + __func__);
4597 + goto err_init_root;
4598 + }
4599 +
4600 + bps = priv->root.rate << 3; /* Bps -> bps */
4601 + err = qman_ceetm_lni_set_commit_rate_bps(lni, bps, dev->mtu);
4602 + if (err) {
4603 + pr_err(KBUILD_BASENAME " : %s : failed to configure the LNI shaper\n",
4604 + __func__);
4605 + goto err_init_root;
4606 + }
4607 +
4608 + bps = priv->root.ceil << 3; /* Bps -> bps */
4609 + err = qman_ceetm_lni_set_excess_rate_bps(lni, bps, dev->mtu);
4610 + if (err) {
4611 + pr_err(KBUILD_BASENAME " : %s : failed to configure the LNI shaper\n",
4612 + __func__);
4613 + goto err_init_root;
4614 + }
4615 + }
4616 +
4617 + /* TODO default configuration */
4618 +
4619 + dpa_enable_ceetm(dev);
4620 + return 0;
4621 +
4622 +err_init_root:
4623 + ceetm_destroy(sch);
4624 + return err;
4625 +}
4626 +
4627 +/* Configure a prio ceetm qdisc */
4628 +static int ceetm_init_prio(struct Qdisc *sch, struct ceetm_qdisc *priv,
4629 + struct tc_ceetm_qopt *qopt)
4630 +{
4631 + int err;
4632 + unsigned int i;
4633 + struct ceetm_class *parent_cl, *child_cl;
4634 + struct Qdisc *parent_qdisc;
4635 + struct net_device *dev = qdisc_dev(sch);
4636 +
4637 + pr_debug(KBUILD_BASENAME " : %s : qdisc %X\n", __func__, sch->handle);
4638 +
4639 + if (sch->parent == TC_H_ROOT) {
4640 + pr_err("CEETM: a prio ceetm qdisc can not be root\n");
4641 + err = -EINVAL;
4642 + goto err_init_prio;
4643 + }
4644 +
4645 + parent_qdisc = qdisc_lookup(dev, TC_H_MAJ(sch->parent));
4646 + if (strcmp(parent_qdisc->ops->id, ceetm_qdisc_ops.id)) {
4647 + pr_err("CEETM: a ceetm qdisc can not be attached to other qdisc/class types\n");
4648 + err = -EINVAL;
4649 + goto err_init_prio;
4650 + }
4651 +
4652 + /* Obtain the parent root ceetm_class */
4653 + parent_cl = ceetm_find(sch->parent, parent_qdisc);
4654 +
4655 + if (!parent_cl || parent_cl->type != CEETM_ROOT) {
4656 + pr_err("CEETM: a prio ceetm qdiscs can be added only under a root ceetm class\n");
4657 + err = -EINVAL;
4658 + goto err_init_prio;
4659 + }
4660 +
4661 + priv->prio.parent = parent_cl;
4662 + parent_cl->root.child = sch;
4663 +
4664 + priv->shaped = parent_cl->shaped;
4665 + priv->prio.qcount = qopt->qcount;
4666 +
4667 + /* Create and configure qcount child classes */
4668 + for (i = 0; i < priv->prio.qcount; i++) {
4669 + child_cl = kzalloc(sizeof(*child_cl), GFP_KERNEL);
4670 + if (!child_cl) {
4671 + pr_err(KBUILD_BASENAME " : %s : kzalloc() failed\n",
4672 + __func__);
4673 + err = -ENOMEM;
4674 + goto err_init_prio;
4675 + }
4676 +
4677 + child_cl->prio.cstats = alloc_percpu(struct ceetm_class_stats);
4678 + if (!child_cl->prio.cstats) {
4679 + pr_err(KBUILD_BASENAME " : %s : alloc_percpu() failed\n",
4680 + __func__);
4681 + err = -ENOMEM;
4682 + goto err_init_prio_cls;
4683 + }
4684 +
4685 + child_cl->common.classid = TC_H_MAKE(sch->handle, (i + 1));
4686 + child_cl->refcnt = 1;
4687 + child_cl->parent = sch;
4688 + child_cl->type = CEETM_PRIO;
4689 + child_cl->shaped = priv->shaped;
4690 + child_cl->prio.child = NULL;
4691 +
4692 + /* All shaped CQs have CR and ER enabled by default */
4693 + child_cl->prio.cr = child_cl->shaped;
4694 + child_cl->prio.er = child_cl->shaped;
4695 + child_cl->prio.fq = NULL;
4696 + child_cl->prio.cq = NULL;
4697 +
4698 + /* Configure the corresponding hardware CQ */
4699 + err = ceetm_config_prio_cls(child_cl, dev,
4700 + parent_cl->root.ch, i);
4701 + if (err) {
4702 + pr_err(KBUILD_BASENAME " : %s : failed to configure the ceetm prio class %X\n",
4703 + __func__, child_cl->common.classid);
4704 + goto err_init_prio_cls;
4705 + }
4706 +
4707 + /* Add class handle in Qdisc */
4708 + ceetm_link_class(sch, &priv->clhash, &child_cl->common);
4709 + pr_debug(KBUILD_BASENAME " : %s : added ceetm prio class %X associated with CQ %d and CCG %d\n",
4710 + __func__, child_cl->common.classid,
4711 + child_cl->prio.cq->idx, child_cl->prio.ccg->idx);
4712 + }
4713 +
4714 + return 0;
4715 +
4716 +err_init_prio_cls:
4717 + ceetm_cls_destroy(sch, child_cl);
4718 +err_init_prio:
4719 + ceetm_destroy(sch);
4720 + return err;
4721 +}
4722 +
4723 +/* Configure a wbfs ceetm qdisc */
4724 +static int ceetm_init_wbfs(struct Qdisc *sch, struct ceetm_qdisc *priv,
4725 + struct tc_ceetm_qopt *qopt)
4726 +{
4727 + int err, group_b, small_group;
4728 + unsigned int i, id, prio_a, prio_b;
4729 + struct ceetm_class *parent_cl, *child_cl, *root_cl;
4730 + struct Qdisc *parent_qdisc;
4731 + struct ceetm_qdisc *parent_priv;
4732 + struct qm_ceetm_channel *channel;
4733 + struct net_device *dev = qdisc_dev(sch);
4734 +
4735 + pr_debug(KBUILD_BASENAME " : %s : qdisc %X\n", __func__, sch->handle);
4736 +
4737 + /* Validate inputs */
4738 + if (sch->parent == TC_H_ROOT) {
4739 + pr_err("CEETM: a wbfs ceetm qdiscs can not be root\n");
4740 + err = -EINVAL;
4741 + goto err_init_wbfs;
4742 + }
4743 +
4744 + /* Obtain the parent prio ceetm qdisc */
4745 + parent_qdisc = qdisc_lookup(dev, TC_H_MAJ(sch->parent));
4746 + if (strcmp(parent_qdisc->ops->id, ceetm_qdisc_ops.id)) {
4747 + pr_err("CEETM: a ceetm qdisc can not be attached to other qdisc/class types\n");
4748 + err = -EINVAL;
4749 + goto err_init_wbfs;
4750 + }
4751 +
4752 + /* Obtain the parent prio ceetm class */
4753 + parent_cl = ceetm_find(sch->parent, parent_qdisc);
4754 + parent_priv = qdisc_priv(parent_qdisc);
4755 +
4756 + if (!parent_cl || parent_cl->type != CEETM_PRIO) {
4757 + pr_err("CEETM: a wbfs ceetm qdiscs can be added only under a prio ceetm class\n");
4758 + err = -EINVAL;
4759 + goto err_init_wbfs;
4760 + }
4761 +
4762 + if (!qopt->qcount || !qopt->qweight[0]) {
4763 + pr_err("CEETM: qcount and qweight are mandatory for a wbfs ceetm qdisc\n");
4764 + err = -EINVAL;
4765 + goto err_init_wbfs;
4766 + }
4767 +
4768 + priv->shaped = parent_cl->shaped;
4769 +
4770 + if (!priv->shaped && (qopt->cr || qopt->er)) {
4771 + pr_err("CEETM: CR/ER can be enabled only for shaped wbfs ceetm qdiscs\n");
4772 + err = -EINVAL;
4773 + goto err_init_wbfs;
4774 + }
4775 +
4776 + if (priv->shaped && !(qopt->cr || qopt->er)) {
4777 + pr_err("CEETM: either CR or ER must be enabled for shaped wbfs ceetm qdiscs\n");
4778 + err = -EINVAL;
4779 + goto err_init_wbfs;
4780 + }
4781 +
4782 + /* Obtain the parent root ceetm class */
4783 + root_cl = parent_priv->prio.parent;
4784 + if ((root_cl->root.wbfs_grp_a && root_cl->root.wbfs_grp_b) ||
4785 + root_cl->root.wbfs_grp_large) {
4786 + pr_err("CEETM: no more wbfs classes are available\n");
4787 + err = -EINVAL;
4788 + goto err_init_wbfs;
4789 + }
4790 +
4791 + if ((root_cl->root.wbfs_grp_a || root_cl->root.wbfs_grp_b) &&
4792 + qopt->qcount == CEETM_MAX_WBFS_QCOUNT) {
4793 + pr_err("CEETM: only %d wbfs classes are available\n",
4794 + CEETM_MIN_WBFS_QCOUNT);
4795 + err = -EINVAL;
4796 + goto err_init_wbfs;
4797 + }
4798 +
4799 + priv->wbfs.parent = parent_cl;
4800 + parent_cl->prio.child = sch;
4801 +
4802 + priv->wbfs.qcount = qopt->qcount;
4803 + priv->wbfs.cr = qopt->cr;
4804 + priv->wbfs.er = qopt->er;
4805 +
4806 + channel = root_cl->root.ch;
4807 +
4808 + /* Configure the hardware wbfs channel groups */
4809 + if (priv->wbfs.qcount == CEETM_MAX_WBFS_QCOUNT) {
4810 + /* Configure the large group A */
4811 + priv->wbfs.group_type = WBFS_GRP_LARGE;
4812 + small_group = false;
4813 + group_b = false;
4814 + prio_a = TC_H_MIN(parent_cl->common.classid) - 1;
4815 + prio_b = prio_a;
4816 +
4817 + } else if (root_cl->root.wbfs_grp_a) {
4818 + /* Configure the group B */
4819 + priv->wbfs.group_type = WBFS_GRP_B;
4820 +
4821 + err = qman_ceetm_channel_get_group(channel, &small_group,
4822 + &prio_a, &prio_b);
4823 + if (err) {
4824 + pr_err(KBUILD_BASENAME " : %s : failed to get group details\n",
4825 + __func__);
4826 + goto err_init_wbfs;
4827 + }
4828 +
4829 + small_group = true;
4830 + group_b = true;
4831 + prio_b = TC_H_MIN(parent_cl->common.classid) - 1;
4832 + /* If group A isn't configured, configure it as group B */
4833 + prio_a = prio_a ? : prio_b;
4834 +
4835 + } else {
4836 + /* Configure the small group A */
4837 + priv->wbfs.group_type = WBFS_GRP_A;
4838 +
4839 + err = qman_ceetm_channel_get_group(channel, &small_group,
4840 + &prio_a, &prio_b);
4841 + if (err) {
4842 + pr_err(KBUILD_BASENAME " : %s : failed to get group details\n",
4843 + __func__);
4844 + goto err_init_wbfs;
4845 + }
4846 +
4847 + small_group = true;
4848 + group_b = false;
4849 + prio_a = TC_H_MIN(parent_cl->common.classid) - 1;
4850 + /* If group B isn't configured, configure it as group A */
4851 + prio_b = prio_b ? : prio_a;
4852 + }
4853 +
4854 + err = qman_ceetm_channel_set_group(channel, small_group, prio_a,
4855 + prio_b);
4856 + if (err)
4857 + goto err_init_wbfs;
4858 +
4859 + if (priv->shaped) {
4860 + err = qman_ceetm_channel_set_group_cr_eligibility(channel,
4861 + group_b,
4862 + priv->wbfs.cr);
4863 + if (err) {
4864 + pr_err(KBUILD_BASENAME " : %s : failed to set group CR eligibility\n",
4865 + __func__);
4866 + goto err_init_wbfs;
4867 + }
4868 +
4869 + err = qman_ceetm_channel_set_group_er_eligibility(channel,
4870 + group_b,
4871 + priv->wbfs.er);
4872 + if (err) {
4873 + pr_err(KBUILD_BASENAME " : %s : failed to set group ER eligibility\n",
4874 + __func__);
4875 + goto err_init_wbfs;
4876 + }
4877 + }
4878 +
4879 + /* Create qcount child classes */
4880 + for (i = 0; i < priv->wbfs.qcount; i++) {
4881 + child_cl = kzalloc(sizeof(*child_cl), GFP_KERNEL);
4882 + if (!child_cl) {
4883 + pr_err(KBUILD_BASENAME " : %s : kzalloc() failed\n",
4884 + __func__);
4885 + err = -ENOMEM;
4886 + goto err_init_wbfs;
4887 + }
4888 +
4889 + child_cl->wbfs.cstats = alloc_percpu(struct ceetm_class_stats);
4890 + if (!child_cl->wbfs.cstats) {
4891 + pr_err(KBUILD_BASENAME " : %s : alloc_percpu() failed\n",
4892 + __func__);
4893 + err = -ENOMEM;
4894 + goto err_init_wbfs_cls;
4895 + }
4896 +
4897 + child_cl->common.classid = TC_H_MAKE(sch->handle, (i + 1));
4898 + child_cl->refcnt = 1;
4899 + child_cl->parent = sch;
4900 + child_cl->type = CEETM_WBFS;
4901 + child_cl->shaped = priv->shaped;
4902 + child_cl->wbfs.fq = NULL;
4903 + child_cl->wbfs.cq = NULL;
4904 + child_cl->wbfs.weight = qopt->qweight[i];
4905 +
4906 + if (priv->wbfs.group_type == WBFS_GRP_B)
4907 + id = WBFS_GRP_B_OFFSET + i;
4908 + else
4909 + id = WBFS_GRP_A_OFFSET + i;
4910 +
4911 + err = ceetm_config_wbfs_cls(child_cl, dev, channel, id,
4912 + priv->wbfs.group_type);
4913 + if (err) {
4914 + pr_err(KBUILD_BASENAME " : %s : failed to configure the ceetm wbfs class %X\n",
4915 + __func__, child_cl->common.classid);
4916 + goto err_init_wbfs_cls;
4917 + }
4918 +
4919 + /* Add class handle in Qdisc */
4920 + ceetm_link_class(sch, &priv->clhash, &child_cl->common);
4921 + pr_debug(KBUILD_BASENAME " : %s : added ceetm wbfs class %X associated with CQ %d and CCG %d\n",
4922 + __func__, child_cl->common.classid,
4923 + child_cl->wbfs.cq->idx, child_cl->wbfs.ccg->idx);
4924 + }
4925 +
4926 + /* Signal the root class that a group has been configured */
4927 + switch (priv->wbfs.group_type) {
4928 + case WBFS_GRP_LARGE:
4929 + root_cl->root.wbfs_grp_large = true;
4930 + break;
4931 + case WBFS_GRP_A:
4932 + root_cl->root.wbfs_grp_a = true;
4933 + break;
4934 + case WBFS_GRP_B:
4935 + root_cl->root.wbfs_grp_b = true;
4936 + break;
4937 + }
4938 +
4939 + return 0;
4940 +
4941 +err_init_wbfs_cls:
4942 + ceetm_cls_destroy(sch, child_cl);
4943 +err_init_wbfs:
4944 + ceetm_destroy(sch);
4945 + return err;
4946 +}
4947 +
4948 +/* Configure a generic ceetm qdisc */
4949 +static int ceetm_init(struct Qdisc *sch, struct nlattr *opt)
4950 +{
4951 + struct tc_ceetm_qopt *qopt;
4952 + struct nlattr *tb[TCA_CEETM_QOPS + 1];
4953 + int ret;
4954 + struct ceetm_qdisc *priv = qdisc_priv(sch);
4955 + struct net_device *dev = qdisc_dev(sch);
4956 +
4957 + pr_debug(KBUILD_BASENAME " : %s : qdisc %X\n", __func__, sch->handle);
4958 +
4959 + if (!netif_is_multiqueue(dev))
4960 + return -EOPNOTSUPP;
4961 +
4962 + if (!opt) {
4963 + pr_err(KBUILD_BASENAME " : %s : tc error\n", __func__);
4964 + return -EINVAL;
4965 + }
4966 +
4967 + ret = nla_parse_nested(tb, TCA_CEETM_QOPS, opt, ceetm_policy);
4968 + if (ret < 0) {
4969 + pr_err(KBUILD_BASENAME " : %s : tc error\n", __func__);
4970 + return ret;
4971 + }
4972 +
4973 + if (!tb[TCA_CEETM_QOPS]) {
4974 + pr_err(KBUILD_BASENAME " : %s : tc error\n", __func__);
4975 + return -EINVAL;
4976 + }
4977 +
4978 + if (TC_H_MIN(sch->handle)) {
4979 + pr_err("CEETM: a qdisc should not have a minor\n");
4980 + return -EINVAL;
4981 + }
4982 +
4983 + qopt = nla_data(tb[TCA_CEETM_QOPS]);
4984 +
4985 + /* Initialize the class hash list. Each qdisc has its own class hash */
4986 + ret = qdisc_class_hash_init(&priv->clhash);
4987 + if (ret < 0) {
4988 + pr_err(KBUILD_BASENAME " : %s : qdisc_class_hash_init failed\n",
4989 + __func__);
4990 + return ret;
4991 + }
4992 +
4993 + priv->type = qopt->type;
4994 +
4995 + switch (priv->type) {
4996 + case CEETM_ROOT:
4997 + ret = ceetm_init_root(sch, priv, qopt);
4998 + break;
4999 + case CEETM_PRIO:
5000 + ret = ceetm_init_prio(sch, priv, qopt);
5001 + break;
5002 + case CEETM_WBFS:
5003 + ret = ceetm_init_wbfs(sch, priv, qopt);
5004 + break;
5005 + default:
5006 + pr_err(KBUILD_BASENAME " : %s : invalid qdisc\n", __func__);
5007 + ceetm_destroy(sch);
5008 + ret = -EINVAL;
5009 + }
5010 +
5011 + return ret;
5012 +}
5013 +
5014 +/* Edit a root ceetm qdisc */
5015 +static int ceetm_change_root(struct Qdisc *sch, struct ceetm_qdisc *priv,
5016 + struct net_device *dev,
5017 + struct tc_ceetm_qopt *qopt)
5018 +{
5019 + int err = 0;
5020 + u64 bps;
5021 +
5022 + if (priv->shaped != (bool)qopt->shaped) {
5023 + pr_err("CEETM: qdisc %X is %s\n", sch->handle,
5024 + priv->shaped ? "shaped" : "unshaped");
5025 + return -EINVAL;
5026 + }
5027 +
5028 + /* Nothing to modify for unshaped qdiscs */
5029 + if (!priv->shaped)
5030 + return 0;
5031 +
5032 + /* Configure the LNI shaper */
5033 + if (priv->root.overhead != qopt->overhead) {
5034 + err = qman_ceetm_lni_enable_shaper(priv->root.lni, 1,
5035 + qopt->overhead);
5036 + if (err)
5037 + goto change_err;
5038 + priv->root.overhead = qopt->overhead;
5039 + }
5040 +
5041 + if (priv->root.rate != qopt->rate) {
5042 + bps = qopt->rate << 3; /* Bps -> bps */
5043 + err = qman_ceetm_lni_set_commit_rate_bps(priv->root.lni, bps,
5044 + dev->mtu);
5045 + if (err)
5046 + goto change_err;
5047 + priv->root.rate = qopt->rate;
5048 + }
5049 +
5050 + if (priv->root.ceil != qopt->ceil) {
5051 + bps = qopt->ceil << 3; /* Bps -> bps */
5052 + err = qman_ceetm_lni_set_excess_rate_bps(priv->root.lni, bps,
5053 + dev->mtu);
5054 + if (err)
5055 + goto change_err;
5056 + priv->root.ceil = qopt->ceil;
5057 + }
5058 +
5059 + return 0;
5060 +
5061 +change_err:
5062 + pr_err(KBUILD_BASENAME " : %s : failed to configure the root ceetm qdisc %X\n",
5063 + __func__, sch->handle);
5064 + return err;
5065 +}
5066 +
5067 +/* Edit a wbfs ceetm qdisc */
5068 +static int ceetm_change_wbfs(struct Qdisc *sch, struct ceetm_qdisc *priv,
5069 + struct tc_ceetm_qopt *qopt)
5070 +{
5071 + int err;
5072 + bool group_b;
5073 + struct qm_ceetm_channel *channel;
5074 + struct ceetm_class *prio_class, *root_class;
5075 + struct ceetm_qdisc *prio_qdisc;
5076 +
5077 + if (qopt->qcount) {
5078 + pr_err("CEETM: the qcount can not be modified\n");
5079 + return -EINVAL;
5080 + }
5081 +
5082 + if (qopt->qweight[0]) {
5083 + pr_err("CEETM: the qweight can be modified through the wbfs classes\n");
5084 + return -EINVAL;
5085 + }
5086 +
5087 + if (!priv->shaped && (qopt->cr || qopt->er)) {
5088 + pr_err("CEETM: CR/ER can be enabled only for shaped wbfs ceetm qdiscs\n");
5089 + return -EINVAL;
5090 + }
5091 +
5092 + if (priv->shaped && !(qopt->cr || qopt->er)) {
5093 + pr_err("CEETM: either CR or ER must be enabled for shaped wbfs ceetm qdiscs\n");
5094 + return -EINVAL;
5095 + }
5096 +
5097 + /* Nothing to modify for unshaped qdiscs */
5098 + if (!priv->shaped)
5099 + return 0;
5100 +
5101 + prio_class = priv->wbfs.parent;
5102 + prio_qdisc = qdisc_priv(prio_class->parent);
5103 + root_class = prio_qdisc->prio.parent;
5104 + channel = root_class->root.ch;
5105 + group_b = priv->wbfs.group_type == WBFS_GRP_B;
5106 +
5107 + if (qopt->cr != priv->wbfs.cr) {
5108 + err = qman_ceetm_channel_set_group_cr_eligibility(channel,
5109 + group_b,
5110 + qopt->cr);
5111 + if (err)
5112 + goto change_err;
5113 + priv->wbfs.cr = qopt->cr;
5114 + }
5115 +
5116 + if (qopt->er != priv->wbfs.er) {
5117 + err = qman_ceetm_channel_set_group_er_eligibility(channel,
5118 + group_b,
5119 + qopt->er);
5120 + if (err)
5121 + goto change_err;
5122 + priv->wbfs.er = qopt->er;
5123 + }
5124 +
5125 + return 0;
5126 +
5127 +change_err:
5128 + pr_err(KBUILD_BASENAME " : %s : failed to configure the wbfs ceetm qdisc %X\n",
5129 + __func__, sch->handle);
5130 + return err;
5131 +}
5132 +
5133 +/* Edit a ceetm qdisc */
5134 +static int ceetm_change(struct Qdisc *sch, struct nlattr *opt)
5135 +{
5136 + struct tc_ceetm_qopt *qopt;
5137 + struct nlattr *tb[TCA_CEETM_QOPS + 1];
5138 + int ret;
5139 + struct ceetm_qdisc *priv = qdisc_priv(sch);
5140 + struct net_device *dev = qdisc_dev(sch);
5141 +
5142 + pr_debug(KBUILD_BASENAME " : %s : qdisc %X\n", __func__, sch->handle);
5143 +
5144 + ret = nla_parse_nested(tb, TCA_CEETM_QOPS, opt, ceetm_policy);
5145 + if (ret < 0) {
5146 + pr_err(KBUILD_BASENAME " : %s : tc error\n", __func__);
5147 + return ret;
5148 + }
5149 +
5150 + if (!tb[TCA_CEETM_QOPS]) {
5151 + pr_err(KBUILD_BASENAME " : %s : tc error\n", __func__);
5152 + return -EINVAL;
5153 + }
5154 +
5155 + if (TC_H_MIN(sch->handle)) {
5156 + pr_err("CEETM: a qdisc should not have a minor\n");
5157 + return -EINVAL;
5158 + }
5159 +
5160 + qopt = nla_data(tb[TCA_CEETM_QOPS]);
5161 +
5162 + if (priv->type != qopt->type) {
5163 + pr_err("CEETM: qdisc %X is not of the provided type\n",
5164 + sch->handle);
5165 + return -EINVAL;
5166 + }
5167 +
5168 + switch (priv->type) {
5169 + case CEETM_ROOT:
5170 + ret = ceetm_change_root(sch, priv, dev, qopt);
5171 + break;
5172 + case CEETM_PRIO:
5173 + pr_err("CEETM: prio qdiscs can not be modified\n");
5174 + ret = -EINVAL;
5175 + break;
5176 + case CEETM_WBFS:
5177 + ret = ceetm_change_wbfs(sch, priv, qopt);
5178 + break;
5179 + default:
5180 + pr_err(KBUILD_BASENAME " : %s : invalid qdisc\n", __func__);
5181 + ret = -EINVAL;
5182 + }
5183 +
5184 + return ret;
5185 +}
5186 +
5187 +/* Attach the underlying pfifo qdiscs */
5188 +static void ceetm_attach(struct Qdisc *sch)
5189 +{
5190 + struct net_device *dev = qdisc_dev(sch);
5191 + struct ceetm_qdisc *priv = qdisc_priv(sch);
5192 + struct Qdisc *qdisc, *old_qdisc;
5193 + unsigned int i;
5194 +
5195 + pr_debug(KBUILD_BASENAME " : %s : qdisc %X\n", __func__, sch->handle);
5196 +
5197 + for (i = 0; i < dev->num_tx_queues; i++) {
5198 + qdisc = priv->root.qdiscs[i];
5199 + old_qdisc = dev_graft_qdisc(qdisc->dev_queue, qdisc);
5200 + if (old_qdisc)
5201 + qdisc_destroy(old_qdisc);
5202 + }
5203 +}
5204 +
5205 +static unsigned long ceetm_cls_get(struct Qdisc *sch, u32 classid)
5206 +{
5207 + struct ceetm_class *cl;
5208 +
5209 + pr_debug(KBUILD_BASENAME " : %s : classid %X from qdisc %X\n",
5210 + __func__, classid, sch->handle);
5211 + cl = ceetm_find(classid, sch);
5212 +
5213 + if (cl)
5214 + cl->refcnt++; /* Will decrement in put() */
5215 + return (unsigned long)cl;
5216 +}
5217 +
5218 +static void ceetm_cls_put(struct Qdisc *sch, unsigned long arg)
5219 +{
5220 + struct ceetm_class *cl = (struct ceetm_class *)arg;
5221 +
5222 + pr_debug(KBUILD_BASENAME " : %s : classid %X from qdisc %X\n",
5223 + __func__, cl->common.classid, sch->handle);
5224 + cl->refcnt--;
5225 +
5226 + if (cl->refcnt == 0)
5227 + ceetm_cls_destroy(sch, cl);
5228 +}
5229 +
5230 +static int ceetm_cls_change_root(struct ceetm_class *cl,
5231 + struct tc_ceetm_copt *copt,
5232 + struct net_device *dev)
5233 +{
5234 + int err;
5235 + u64 bps;
5236 +
5237 + if ((bool)copt->shaped != cl->shaped) {
5238 + pr_err("CEETM: class %X is %s\n", cl->common.classid,
5239 + cl->shaped ? "shaped" : "unshaped");
5240 + return -EINVAL;
5241 + }
5242 +
5243 + if (cl->shaped && cl->root.rate != copt->rate) {
5244 + bps = copt->rate << 3; /* Bps -> bps */
5245 + err = qman_ceetm_channel_set_commit_rate_bps(cl->root.ch, bps,
5246 + dev->mtu);
5247 + if (err)
5248 + goto change_cls_err;
5249 + cl->root.rate = copt->rate;
5250 + }
5251 +
5252 + if (cl->shaped && cl->root.ceil != copt->ceil) {
5253 + bps = copt->ceil << 3; /* Bps -> bps */
5254 + err = qman_ceetm_channel_set_excess_rate_bps(cl->root.ch, bps,
5255 + dev->mtu);
5256 + if (err)
5257 + goto change_cls_err;
5258 + cl->root.ceil = copt->ceil;
5259 + }
5260 +
5261 + if (!cl->shaped && cl->root.tbl != copt->tbl) {
5262 + err = qman_ceetm_channel_set_weight(cl->root.ch, copt->tbl);
5263 + if (err)
5264 + goto change_cls_err;
5265 + cl->root.tbl = copt->tbl;
5266 + }
5267 +
5268 + return 0;
5269 +
5270 +change_cls_err:
5271 + pr_err(KBUILD_BASENAME " : %s : failed to configure the ceetm root class %X\n",
5272 + __func__, cl->common.classid);
5273 + return err;
5274 +}
5275 +
5276 +static int ceetm_cls_change_prio(struct ceetm_class *cl,
5277 + struct tc_ceetm_copt *copt)
5278 +{
5279 + int err;
5280 +
5281 + if (!cl->shaped && (copt->cr || copt->er)) {
5282 + pr_err("CEETM: only shaped classes can have CR and ER enabled\n");
5283 + return -EINVAL;
5284 + }
5285 +
5286 + if (cl->prio.cr != (bool)copt->cr) {
5287 + err = qman_ceetm_channel_set_cq_cr_eligibility(
5288 + cl->prio.cq->parent,
5289 + cl->prio.cq->idx,
5290 + copt->cr);
5291 + if (err)
5292 + goto change_cls_err;
5293 + cl->prio.cr = copt->cr;
5294 + }
5295 +
5296 + if (cl->prio.er != (bool)copt->er) {
5297 + err = qman_ceetm_channel_set_cq_er_eligibility(
5298 + cl->prio.cq->parent,
5299 + cl->prio.cq->idx,
5300 + copt->er);
5301 + if (err)
5302 + goto change_cls_err;
5303 + cl->prio.er = copt->er;
5304 + }
5305 +
5306 + return 0;
5307 +
5308 +change_cls_err:
5309 + pr_err(KBUILD_BASENAME " : %s : failed to configure the ceetm prio class %X\n",
5310 + __func__, cl->common.classid);
5311 + return err;
5312 +}
5313 +
5314 +static int ceetm_cls_change_wbfs(struct ceetm_class *cl,
5315 + struct tc_ceetm_copt *copt)
5316 +{
5317 + int err;
5318 +
5319 + if (copt->weight != cl->wbfs.weight) {
5320 + /* Configure the CQ weight: real number multiplied by 100 to
5321 + * get rid of the fraction
5322 + */
5323 + err = qman_ceetm_set_queue_weight_in_ratio(cl->wbfs.cq,
5324 + copt->weight * 100);
5325 +
5326 + if (err) {
5327 + pr_err(KBUILD_BASENAME " : %s : failed to configure the ceetm wbfs class %X\n",
5328 + __func__, cl->common.classid);
5329 + return err;
5330 + }
5331 +
5332 + cl->wbfs.weight = copt->weight;
5333 + }
5334 +
5335 + return 0;
5336 +}
5337 +
5338 +/* Add a ceetm root class or configure a ceetm root/prio/wbfs class */
5339 +static int ceetm_cls_change(struct Qdisc *sch, u32 classid, u32 parentid,
5340 + struct nlattr **tca, unsigned long *arg)
5341 +{
5342 + int err;
5343 + u64 bps;
5344 + struct ceetm_qdisc *priv;
5345 + struct ceetm_class *cl = (struct ceetm_class *)*arg;
5346 + struct nlattr *opt = tca[TCA_OPTIONS];
5347 + struct nlattr *tb[__TCA_CEETM_MAX];
5348 + struct tc_ceetm_copt *copt;
5349 + struct qm_ceetm_channel *channel;
5350 + struct net_device *dev = qdisc_dev(sch);
5351 +
5352 + pr_debug(KBUILD_BASENAME " : %s : classid %X under qdisc %X\n",
5353 + __func__, classid, sch->handle);
5354 +
5355 + if (strcmp(sch->ops->id, ceetm_qdisc_ops.id)) {
5356 + pr_err("CEETM: a ceetm class can not be attached to other qdisc/class types\n");
5357 + return -EINVAL;
5358 + }
5359 +
5360 + priv = qdisc_priv(sch);
5361 +
5362 + if (!opt) {
5363 + pr_err(KBUILD_BASENAME " : %s : tc error\n", __func__);
5364 + return -EINVAL;
5365 + }
5366 +
5367 + if (!cl && sch->handle != parentid) {
5368 + pr_err("CEETM: classes can be attached to the root ceetm qdisc only\n");
5369 + return -EINVAL;
5370 + }
5371 +
5372 + if (!cl && priv->type != CEETM_ROOT) {
5373 + pr_err("CEETM: only root ceetm classes can be attached to the root ceetm qdisc\n");
5374 + return -EINVAL;
5375 + }
5376 +
5377 + err = nla_parse_nested(tb, TCA_CEETM_COPT, opt, ceetm_policy);
5378 + if (err < 0) {
5379 + pr_err(KBUILD_BASENAME " : %s : tc error\n", __func__);
5380 + return -EINVAL;
5381 + }
5382 +
5383 + if (!tb[TCA_CEETM_COPT]) {
5384 + pr_err(KBUILD_BASENAME " : %s : tc error\n", __func__);
5385 + return -EINVAL;
5386 + }
5387 +
5388 + if (TC_H_MIN(classid) >= PFIFO_MIN_OFFSET) {
5389 + pr_err("CEETM: only minors 0x01 to 0x20 can be used for ceetm root classes\n");
5390 + return -EINVAL;
5391 + }
5392 +
5393 + copt = nla_data(tb[TCA_CEETM_COPT]);
5394 +
5395 + /* Configure an existing ceetm class */
5396 + if (cl) {
5397 + if (copt->type != cl->type) {
5398 + pr_err("CEETM: class %X is not of the provided type\n",
5399 + cl->common.classid);
5400 + return -EINVAL;
5401 + }
5402 +
5403 + switch (copt->type) {
5404 + case CEETM_ROOT:
5405 + return ceetm_cls_change_root(cl, copt, dev);
5406 +
5407 + case CEETM_PRIO:
5408 + return ceetm_cls_change_prio(cl, copt);
5409 +
5410 + case CEETM_WBFS:
5411 + return ceetm_cls_change_wbfs(cl, copt);
5412 +
5413 + default:
5414 + pr_err(KBUILD_BASENAME " : %s : invalid class\n",
5415 + __func__);
5416 + return -EINVAL;
5417 + }
5418 + }
5419 +
5420 + /* Add a new root ceetm class */
5421 + if (copt->type != CEETM_ROOT) {
5422 + pr_err("CEETM: only root ceetm classes can be attached to the root ceetm qdisc\n");
5423 + return -EINVAL;
5424 + }
5425 +
5426 + if (copt->shaped && !priv->shaped) {
5427 + pr_err("CEETM: can not add a shaped ceetm root class under an unshaped ceetm root qdisc\n");
5428 + return -EINVAL;
5429 + }
5430 +
5431 + cl = kzalloc(sizeof(*cl), GFP_KERNEL);
5432 + if (!cl)
5433 + return -ENOMEM;
5434 +
5435 + cl->type = copt->type;
5436 + cl->shaped = copt->shaped;
5437 + cl->root.rate = copt->rate;
5438 + cl->root.ceil = copt->ceil;
5439 + cl->root.tbl = copt->tbl;
5440 +
5441 + cl->common.classid = classid;
5442 + cl->refcnt = 1;
5443 + cl->parent = sch;
5444 + cl->root.child = NULL;
5445 + cl->root.wbfs_grp_a = false;
5446 + cl->root.wbfs_grp_b = false;
5447 + cl->root.wbfs_grp_large = false;
5448 +
5449 + /* Claim a CEETM channel */
5450 + err = qman_ceetm_channel_claim(&channel, priv->root.lni);
5451 + if (err) {
5452 + pr_err(KBUILD_BASENAME " : %s : failed to claim a channel\n",
5453 + __func__);
5454 + goto claim_err;
5455 + }
5456 +
5457 + cl->root.ch = channel;
5458 +
5459 + if (cl->shaped) {
5460 + /* Configure the channel shaper */
5461 + err = qman_ceetm_channel_enable_shaper(channel, 1);
5462 + if (err)
5463 + goto channel_err;
5464 +
5465 + bps = cl->root.rate << 3; /* Bps -> bps */
5466 + err = qman_ceetm_channel_set_commit_rate_bps(channel, bps,
5467 + dev->mtu);
5468 + if (err)
5469 + goto channel_err;
5470 +
5471 + bps = cl->root.ceil << 3; /* Bps -> bps */
5472 + err = qman_ceetm_channel_set_excess_rate_bps(channel, bps,
5473 + dev->mtu);
5474 + if (err)
5475 + goto channel_err;
5476 +
5477 + } else {
5478 + /* Configure the uFQ algorithm */
5479 + err = qman_ceetm_channel_set_weight(channel, cl->root.tbl);
5480 + if (err)
5481 + goto channel_err;
5482 + }
5483 +
5484 + /* Add class handle in Qdisc */
5485 + ceetm_link_class(sch, &priv->clhash, &cl->common);
5486 +
5487 + pr_debug(KBUILD_BASENAME " : %s : configured class %X associated with channel %d\n",
5488 + __func__, classid, channel->idx);
5489 + *arg = (unsigned long)cl;
5490 + return 0;
5491 +
5492 +channel_err:
5493 + pr_err(KBUILD_BASENAME " : %s : failed to configure the channel %d\n",
5494 + __func__, channel->idx);
5495 + if (qman_ceetm_channel_release(channel))
5496 + pr_err(KBUILD_BASENAME " : %s : failed to release the channel %d\n",
5497 + __func__, channel->idx);
5498 +claim_err:
5499 + kfree(cl);
5500 + return err;
5501 +}
5502 +
5503 +static void ceetm_cls_walk(struct Qdisc *sch, struct qdisc_walker *arg)
5504 +{
5505 + struct ceetm_qdisc *priv = qdisc_priv(sch);
5506 + struct ceetm_class *cl;
5507 + unsigned int i;
5508 +
5509 + pr_debug(KBUILD_BASENAME " : %s : qdisc %X\n", __func__, sch->handle);
5510 +
5511 + if (arg->stop)
5512 + return;
5513 +
5514 + for (i = 0; i < priv->clhash.hashsize; i++) {
5515 + hlist_for_each_entry(cl, &priv->clhash.hash[i], common.hnode) {
5516 + if (arg->count < arg->skip) {
5517 + arg->count++;
5518 + continue;
5519 + }
5520 + if (arg->fn(sch, (unsigned long)cl, arg) < 0) {
5521 + arg->stop = 1;
5522 + return;
5523 + }
5524 + arg->count++;
5525 + }
5526 + }
5527 +}
5528 +
5529 +static int ceetm_cls_dump(struct Qdisc *sch, unsigned long arg,
5530 + struct sk_buff *skb, struct tcmsg *tcm)
5531 +{
5532 + struct ceetm_class *cl = (struct ceetm_class *)arg;
5533 + struct nlattr *nest;
5534 + struct tc_ceetm_copt copt;
5535 +
5536 + pr_debug(KBUILD_BASENAME " : %s : class %X under qdisc %X\n",
5537 + __func__, cl->common.classid, sch->handle);
5538 +
5539 + sch_tree_lock(sch);
5540 +
5541 + tcm->tcm_parent = ((struct Qdisc *)cl->parent)->handle;
5542 + tcm->tcm_handle = cl->common.classid;
5543 +
5544 + memset(&copt, 0, sizeof(copt));
5545 +
5546 + copt.shaped = cl->shaped;
5547 + copt.type = cl->type;
5548 +
5549 + switch (cl->type) {
5550 + case CEETM_ROOT:
5551 + if (cl->root.child)
5552 + tcm->tcm_info = cl->root.child->handle;
5553 +
5554 + copt.rate = cl->root.rate;
5555 + copt.ceil = cl->root.ceil;
5556 + copt.tbl = cl->root.tbl;
5557 + break;
5558 +
5559 + case CEETM_PRIO:
5560 + if (cl->prio.child)
5561 + tcm->tcm_info = cl->prio.child->handle;
5562 +
5563 + copt.cr = cl->prio.cr;
5564 + copt.er = cl->prio.er;
5565 + break;
5566 +
5567 + case CEETM_WBFS:
5568 + copt.weight = cl->wbfs.weight;
5569 + break;
5570 + }
5571 +
5572 + nest = nla_nest_start(skb, TCA_OPTIONS);
5573 + if (!nest)
5574 + goto nla_put_failure;
5575 + if (nla_put(skb, TCA_CEETM_COPT, sizeof(copt), &copt))
5576 + goto nla_put_failure;
5577 + nla_nest_end(skb, nest);
5578 + sch_tree_unlock(sch);
5579 + return skb->len;
5580 +
5581 +nla_put_failure:
5582 + sch_tree_unlock(sch);
5583 + nla_nest_cancel(skb, nest);
5584 + return -EMSGSIZE;
5585 +}
5586 +
5587 +static int ceetm_cls_delete(struct Qdisc *sch, unsigned long arg)
5588 +{
5589 + struct ceetm_qdisc *priv = qdisc_priv(sch);
5590 + struct ceetm_class *cl = (struct ceetm_class *)arg;
5591 +
5592 + pr_debug(KBUILD_BASENAME " : %s : class %X under qdisc %X\n",
5593 + __func__, cl->common.classid, sch->handle);
5594 +
5595 + sch_tree_lock(sch);
5596 + qdisc_class_hash_remove(&priv->clhash, &cl->common);
5597 + cl->refcnt--;
5598 +
5599 + /* The refcnt should be at least 1 since we have incremented it in
5600 + * get(). Will decrement again in put() where we will call destroy()
5601 + * to actually free the memory if it reaches 0.
5602 + */
5603 + WARN_ON(cl->refcnt == 0);
5604 +
5605 + sch_tree_unlock(sch);
5606 + return 0;
5607 +}
5608 +
5609 +/* Get the class' child qdisc, if any */
5610 +static struct Qdisc *ceetm_cls_leaf(struct Qdisc *sch, unsigned long arg)
5611 +{
5612 + struct ceetm_class *cl = (struct ceetm_class *)arg;
5613 +
5614 + pr_debug(KBUILD_BASENAME " : %s : class %X under qdisc %X\n",
5615 + __func__, cl->common.classid, sch->handle);
5616 +
5617 + switch (cl->type) {
5618 + case CEETM_ROOT:
5619 + return cl->root.child;
5620 +
5621 + case CEETM_PRIO:
5622 + return cl->prio.child;
5623 + }
5624 +
5625 + return NULL;
5626 +}
5627 +
5628 +static int ceetm_cls_graft(struct Qdisc *sch, unsigned long arg,
5629 + struct Qdisc *new, struct Qdisc **old)
5630 +{
5631 + if (new && strcmp(new->ops->id, ceetm_qdisc_ops.id)) {
5632 + pr_err("CEETM: only ceetm qdiscs can be attached to ceetm classes\n");
5633 + return -EOPNOTSUPP;
5634 + }
5635 +
5636 + return 0;
5637 +}
5638 +
5639 +static int ceetm_cls_dump_stats(struct Qdisc *sch, unsigned long arg,
5640 + struct gnet_dump *d)
5641 +{
5642 + unsigned int i;
5643 + struct ceetm_class *cl = (struct ceetm_class *)arg;
5644 + struct gnet_stats_basic_packed tmp_bstats;
5645 + struct ceetm_class_stats *cstats = NULL;
5646 + struct qm_ceetm_cq *cq = NULL;
5647 + struct tc_ceetm_xstats xstats;
5648 +
5649 + memset(&xstats, 0, sizeof(xstats));
5650 + memset(&tmp_bstats, 0, sizeof(tmp_bstats));
5651 +
5652 + switch (cl->type) {
5653 + case CEETM_ROOT:
5654 + return 0;
5655 + case CEETM_PRIO:
5656 + cq = cl->prio.cq;
5657 + break;
5658 + case CEETM_WBFS:
5659 + cq = cl->wbfs.cq;
5660 + break;
5661 + }
5662 +
5663 + for_each_online_cpu(i) {
5664 + switch (cl->type) {
5665 + case CEETM_PRIO:
5666 + cstats = per_cpu_ptr(cl->prio.cstats, i);
5667 + break;
5668 + case CEETM_WBFS:
5669 + cstats = per_cpu_ptr(cl->wbfs.cstats, i);
5670 + break;
5671 + }
5672 +
5673 + if (cstats) {
5674 + xstats.ern_drop_count += cstats->ern_drop_count;
5675 + xstats.congested_count += cstats->congested_count;
5676 + tmp_bstats.bytes += cstats->bstats.bytes;
5677 + tmp_bstats.packets += cstats->bstats.packets;
5678 + }
5679 + }
5680 +
5681 + if (gnet_stats_copy_basic(qdisc_root_sleeping_running(sch),
5682 + d, NULL, &tmp_bstats) < 0)
5683 + return -1;
5684 +
5685 + if (cq && qman_ceetm_cq_get_dequeue_statistics(cq, 0,
5686 + &xstats.frame_count,
5687 + &xstats.byte_count))
5688 + return -1;
5689 +
5690 + return gnet_stats_copy_app(d, &xstats, sizeof(xstats));
5691 +}
5692 +
5693 +static struct tcf_proto **ceetm_tcf_chain(struct Qdisc *sch, unsigned long arg)
5694 +{
5695 + struct ceetm_qdisc *priv = qdisc_priv(sch);
5696 + struct ceetm_class *cl = (struct ceetm_class *)arg;
5697 + struct tcf_proto **fl = cl ? &cl->filter_list : &priv->filter_list;
5698 +
5699 + pr_debug(KBUILD_BASENAME " : %s : class %X under qdisc %X\n", __func__,
5700 + cl ? cl->common.classid : 0, sch->handle);
5701 + return fl;
5702 +}
5703 +
5704 +static unsigned long ceetm_tcf_bind(struct Qdisc *sch, unsigned long parent,
5705 + u32 classid)
5706 +{
5707 + struct ceetm_class *cl = ceetm_find(classid, sch);
5708 +
5709 + pr_debug(KBUILD_BASENAME " : %s : class %X under qdisc %X\n", __func__,
5710 + cl ? cl->common.classid : 0, sch->handle);
5711 + return (unsigned long)cl;
5712 +}
5713 +
5714 +static void ceetm_tcf_unbind(struct Qdisc *sch, unsigned long arg)
5715 +{
5716 + struct ceetm_class *cl = (struct ceetm_class *)arg;
5717 +
5718 + pr_debug(KBUILD_BASENAME " : %s : class %X under qdisc %X\n", __func__,
5719 + cl ? cl->common.classid : 0, sch->handle);
5720 +}
5721 +
5722 +const struct Qdisc_class_ops ceetm_cls_ops = {
5723 + .graft = ceetm_cls_graft,
5724 + .leaf = ceetm_cls_leaf,
5725 + .get = ceetm_cls_get,
5726 + .put = ceetm_cls_put,
5727 + .change = ceetm_cls_change,
5728 + .delete = ceetm_cls_delete,
5729 + .walk = ceetm_cls_walk,
5730 + .tcf_chain = ceetm_tcf_chain,
5731 + .bind_tcf = ceetm_tcf_bind,
5732 + .unbind_tcf = ceetm_tcf_unbind,
5733 + .dump = ceetm_cls_dump,
5734 + .dump_stats = ceetm_cls_dump_stats,
5735 +};
5736 +
5737 +struct Qdisc_ops ceetm_qdisc_ops __read_mostly = {
5738 + .id = "ceetm",
5739 + .priv_size = sizeof(struct ceetm_qdisc),
5740 + .cl_ops = &ceetm_cls_ops,
5741 + .init = ceetm_init,
5742 + .destroy = ceetm_destroy,
5743 + .change = ceetm_change,
5744 + .dump = ceetm_dump,
5745 + .attach = ceetm_attach,
5746 + .owner = THIS_MODULE,
5747 +};
5748 +
5749 +/* Run the filters and classifiers attached to the qdisc on the provided skb */
5750 +static struct ceetm_class *ceetm_classify(struct sk_buff *skb,
5751 + struct Qdisc *sch, int *qerr,
5752 + bool *act_drop)
5753 +{
5754 + struct ceetm_qdisc *priv = qdisc_priv(sch);
5755 + struct ceetm_class *cl = NULL, *wbfs_cl;
5756 + struct tcf_result res;
5757 + struct tcf_proto *tcf;
5758 + int result;
5759 +
5760 + *qerr = NET_XMIT_SUCCESS | __NET_XMIT_BYPASS;
5761 + tcf = priv->filter_list;
5762 + while (tcf && (result = tc_classify(skb, tcf, &res, false)) >= 0) {
5763 +#ifdef CONFIG_NET_CLS_ACT
5764 + switch (result) {
5765 + case TC_ACT_QUEUED:
5766 + case TC_ACT_STOLEN:
5767 + *qerr = NET_XMIT_SUCCESS | __NET_XMIT_STOLEN;
5768 + case TC_ACT_SHOT:
5769 + /* No valid class found due to action */
5770 + *act_drop = true;
5771 + return NULL;
5772 + }
5773 +#endif
5774 + cl = (void *)res.class;
5775 + if (!cl) {
5776 + if (res.classid == sch->handle) {
5777 + /* The filter leads to the qdisc */
5778 + /* TODO default qdisc */
5779 + return NULL;
5780 + }
5781 +
5782 + cl = ceetm_find(res.classid, sch);
5783 + if (!cl)
5784 + /* The filter leads to an invalid class */
5785 + break;
5786 + }
5787 +
5788 + /* The class might have its own filters attached */
5789 + tcf = cl->filter_list;
5790 + }
5791 +
5792 + if (!cl) {
5793 + /* No valid class found */
5794 + /* TODO default qdisc */
5795 + return NULL;
5796 + }
5797 +
5798 + switch (cl->type) {
5799 + case CEETM_ROOT:
5800 + if (cl->root.child) {
5801 + /* Run the prio qdisc classifiers */
5802 + return ceetm_classify(skb, cl->root.child, qerr,
5803 + act_drop);
5804 + } else {
5805 + /* The root class does not have a child prio qdisc */
5806 + /* TODO default qdisc */
5807 + return NULL;
5808 + }
5809 + case CEETM_PRIO:
5810 + if (cl->prio.child) {
5811 + /* If filters lead to a wbfs class, return it.
5812 + * Otherwise, return the prio class
5813 + */
5814 + wbfs_cl = ceetm_classify(skb, cl->prio.child, qerr,
5815 + act_drop);
5816 + /* A NULL result might indicate either an erroneous
5817 + * filter, or no filters at all. We will assume the
5818 + * latter
5819 + */
5820 + return wbfs_cl ? : cl;
5821 + }
5822 + }
5823 +
5824 + /* For wbfs and childless prio classes, return the class directly */
5825 + return cl;
5826 +}
5827 +
5828 +int __hot ceetm_tx(struct sk_buff *skb, struct net_device *net_dev)
5829 +{
5830 + const int queue_mapping = dpa_get_queue_mapping(skb);
5831 + struct Qdisc *sch = net_dev->qdisc;
5832 + struct ceetm_class_stats *cstats;
5833 + struct ceetm_qdisc_stats *qstats;
5834 + struct dpa_priv_s *priv_dpa;
5835 + struct ceetm_fq *ceetm_fq;
5836 + struct ceetm_qdisc *priv;
5837 + struct qman_fq *conf_fq;
5838 + struct ceetm_class *cl;
5839 + spinlock_t *root_lock;
5840 + bool act_drop = false;
5841 + int ret;
5842 +
5843 + root_lock = qdisc_lock(sch);
5844 + priv = qdisc_priv(sch);
5845 + qstats = this_cpu_ptr(priv->root.qstats);
5846 +
5847 + spin_lock(root_lock);
5848 + cl = ceetm_classify(skb, sch, &ret, &act_drop);
5849 + spin_unlock(root_lock);
5850 +
5851 +#ifdef CONFIG_NET_CLS_ACT
5852 + if (act_drop) {
5853 + if (ret & __NET_XMIT_BYPASS)
5854 + qstats->drops++;
5855 + goto drop;
5856 + }
5857 +#endif
5858 + /* TODO default class */
5859 + if (unlikely(!cl)) {
5860 + qstats->drops++;
5861 + goto drop;
5862 + }
5863 +
5864 + priv_dpa = netdev_priv(net_dev);
5865 + conf_fq = priv_dpa->conf_fqs[queue_mapping];
5866 +
5867 + /* Choose the proper tx fq and update the basic stats (bytes and
5868 + * packets sent by the class)
5869 + */
5870 + switch (cl->type) {
5871 + case CEETM_PRIO:
5872 + ceetm_fq = cl->prio.fq;
5873 + cstats = this_cpu_ptr(cl->prio.cstats);
5874 + break;
5875 + case CEETM_WBFS:
5876 + ceetm_fq = cl->wbfs.fq;
5877 + cstats = this_cpu_ptr(cl->wbfs.cstats);
5878 + break;
5879 + default:
5880 + qstats->drops++;
5881 + goto drop;
5882 + }
5883 +
5884 + /* If the FQ is congested, avoid enqueuing the frame and dropping it
5885 + * when it returns on the ERN path. Drop it here directly instead.
5886 + */
5887 + if (unlikely(ceetm_fq->congested)) {
5888 + qstats->drops++;
5889 + goto drop;
5890 + }
5891 +
5892 + bstats_update(&cstats->bstats, skb);
5893 + return dpa_tx_extended(skb, net_dev, &ceetm_fq->fq, conf_fq);
5894 +
5895 +drop:
5896 + dev_kfree_skb_any(skb);
5897 + return NET_XMIT_SUCCESS;
5898 +}
5899 +
5900 +static int __init ceetm_register(void)
5901 +{
5902 + int _errno = 0;
5903 +
5904 + pr_info(KBUILD_MODNAME ": " DPA_CEETM_DESCRIPTION "\n");
5905 +
5906 + _errno = register_qdisc(&ceetm_qdisc_ops);
5907 + if (unlikely(_errno))
5908 + pr_err(KBUILD_MODNAME
5909 + ": %s:%hu:%s(): register_qdisc() = %d\n",
5910 + KBUILD_BASENAME ".c", __LINE__, __func__, _errno);
5911 +
5912 + return _errno;
5913 +}
5914 +
5915 +static void __exit ceetm_unregister(void)
5916 +{
5917 + pr_debug(KBUILD_MODNAME ": %s:%s() ->\n",
5918 + KBUILD_BASENAME ".c", __func__);
5919 +
5920 + unregister_qdisc(&ceetm_qdisc_ops);
5921 +}
5922 +
5923 +module_init(ceetm_register);
5924 +module_exit(ceetm_unregister);
5925 --- /dev/null
5926 +++ b/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_ceetm.h
5927 @@ -0,0 +1,238 @@
5928 +/* Copyright 2008-2016 Freescale Semiconductor Inc.
5929 + *
5930 + * Redistribution and use in source and binary forms, with or without
5931 + * modification, are permitted provided that the following conditions are met:
5932 + * * Redistributions of source code must retain the above copyright
5933 + * notice, this list of conditions and the following disclaimer.
5934 + * * Redistributions in binary form must reproduce the above copyright
5935 + * notice, this list of conditions and the following disclaimer in the
5936 + * documentation and/or other materials provided with the distribution.
5937 + * * Neither the name of Freescale Semiconductor nor the
5938 + * names of its contributors may be used to endorse or promote products
5939 + * derived from this software without specific prior written permission.
5940 + *
5941 + *
5942 + * ALTERNATIVELY, this software may be distributed under the terms of the
5943 + * GNU General Public License ("GPL") as published by the Free Software
5944 + * Foundation, either version 2 of that License or (at your option) any
5945 + * later version.
5946 + *
5947 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
5948 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
5949 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
5950 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
5951 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
5952 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
5953 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
5954 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
5955 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
5956 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
5957 + */
5958 +
5959 +#ifndef __DPAA_ETH_CEETM_H
5960 +#define __DPAA_ETH_CEETM_H
5961 +
5962 +#include <net/pkt_sched.h>
5963 +#include <net/pkt_cls.h>
5964 +#include <net/netlink.h>
5965 +#include <lnxwrp_fm.h>
5966 +
5967 +#include "mac.h"
5968 +#include "dpaa_eth_common.h"
5969 +
5970 +/* Mask to determine the sub-portal id from a channel number */
5971 +#define CHANNEL_SP_MASK 0x1f
5972 +/* The number of the last channel that services DCP0, connected to FMan 0.
5973 + * Value validated for B4 and T series platforms.
5974 + */
5975 +#define DCP0_MAX_CHANNEL 0x80f
5976 +/* A2V=1 - field A2 is valid
5977 + * A0V=1 - field A0 is valid - enables frame confirmation
5978 + * OVOM=1 - override operation mode bits with values from A2
5979 + * EBD=1 - external buffers are deallocated at the end of the FMan flow
5980 + * NL=0 - the BMI releases all the internal buffers
5981 + */
5982 +#define CEETM_CONTEXT_A 0x1a00000080000000
5983 +/* The ratio between the superior and inferior congestion state thresholds. The
5984 + * lower threshold is set to 7/8 of the superior one (as the default for WQ
5985 + * scheduling).
5986 + */
5987 +#define CEETM_CCGR_RATIO 0.875
5988 +/* For functional purposes, there are num_tx_queues pfifo qdiscs through which
5989 + * frames reach the driver. Their handles start from 1:21. Handles 1:1 to 1:20
5990 + * are reserved for the maximum 32 CEETM channels (majors and minors are in
5991 + * hex).
5992 + */
5993 +#define PFIFO_MIN_OFFSET 0x21
5994 +
5995 +/* A maximum of 8 CQs can be linked to a CQ channel or to a WBFS scheduler. */
5996 +#define CEETM_MAX_PRIO_QCOUNT 8
5997 +#define CEETM_MAX_WBFS_QCOUNT 8
5998 +#define CEETM_MIN_WBFS_QCOUNT 4
5999 +
6000 +/* The id offsets of the CQs belonging to WBFS groups (ids 8-11/15 for group A
6001 + * and/or 12-15 for group B).
6002 + */
6003 +#define WBFS_GRP_A_OFFSET 8
6004 +#define WBFS_GRP_B_OFFSET 12
6005 +
6006 +#define WBFS_GRP_A 1
6007 +#define WBFS_GRP_B 2
6008 +#define WBFS_GRP_LARGE 3
6009 +
6010 +enum {
6011 + TCA_CEETM_UNSPEC,
6012 + TCA_CEETM_COPT,
6013 + TCA_CEETM_QOPS,
6014 + __TCA_CEETM_MAX,
6015 +};
6016 +
6017 +/* CEETM configuration types */
6018 +enum {
6019 + CEETM_ROOT = 1,
6020 + CEETM_PRIO,
6021 + CEETM_WBFS
6022 +};
6023 +
6024 +#define TCA_CEETM_MAX (__TCA_CEETM_MAX - 1)
6025 +extern const struct nla_policy ceetm_policy[TCA_CEETM_MAX + 1];
6026 +
6027 +struct ceetm_class;
6028 +struct ceetm_qdisc_stats;
6029 +struct ceetm_class_stats;
6030 +
6031 +struct ceetm_fq {
6032 + struct qman_fq fq;
6033 + struct net_device *net_dev;
6034 + struct ceetm_class *ceetm_cls;
6035 + int congested; /* Congestion status */
6036 +};
6037 +
6038 +struct root_q {
6039 + struct Qdisc **qdiscs;
6040 + __u16 overhead;
6041 + __u32 rate;
6042 + __u32 ceil;
6043 + struct qm_ceetm_sp *sp;
6044 + struct qm_ceetm_lni *lni;
6045 + struct ceetm_qdisc_stats __percpu *qstats;
6046 +};
6047 +
6048 +struct prio_q {
6049 + __u16 qcount;
6050 + struct ceetm_class *parent;
6051 +};
6052 +
6053 +struct wbfs_q {
6054 + __u16 qcount;
6055 + int group_type;
6056 + struct ceetm_class *parent;
6057 + __u16 cr;
6058 + __u16 er;
6059 +};
6060 +
6061 +struct ceetm_qdisc {
6062 + int type; /* LNI/CHNL/WBFS */
6063 + bool shaped;
6064 + union {
6065 + struct root_q root;
6066 + struct prio_q prio;
6067 + struct wbfs_q wbfs;
6068 + };
6069 + struct Qdisc_class_hash clhash;
6070 + struct tcf_proto *filter_list; /* qdisc attached filters */
6071 +};
6072 +
6073 +/* CEETM Qdisc configuration parameters */
6074 +struct tc_ceetm_qopt {
6075 + __u32 type;
6076 + __u16 shaped;
6077 + __u16 qcount;
6078 + __u16 overhead;
6079 + __u32 rate;
6080 + __u32 ceil;
6081 + __u16 cr;
6082 + __u16 er;
6083 + __u8 qweight[CEETM_MAX_WBFS_QCOUNT];
6084 +};
6085 +
6086 +struct root_c {
6087 + unsigned int rate;
6088 + unsigned int ceil;
6089 + unsigned int tbl;
6090 + bool wbfs_grp_a;
6091 + bool wbfs_grp_b;
6092 + bool wbfs_grp_large;
6093 + struct Qdisc *child;
6094 + struct qm_ceetm_channel *ch;
6095 +};
6096 +
6097 +struct prio_c {
6098 + bool cr;
6099 + bool er;
6100 + struct ceetm_fq *fq; /* Hardware FQ instance Handle */
6101 + struct qm_ceetm_lfq *lfq;
6102 + struct qm_ceetm_cq *cq; /* Hardware Class Queue instance Handle */
6103 + struct qm_ceetm_ccg *ccg;
6104 + /* only one wbfs can be linked to one priority CQ */
6105 + struct Qdisc *child;
6106 + struct ceetm_class_stats __percpu *cstats;
6107 +};
6108 +
6109 +struct wbfs_c {
6110 + __u8 weight; /* The weight of the class between 1 and 248 */
6111 + struct ceetm_fq *fq; /* Hardware FQ instance Handle */
6112 + struct qm_ceetm_lfq *lfq;
6113 + struct qm_ceetm_cq *cq; /* Hardware Class Queue instance Handle */
6114 + struct qm_ceetm_ccg *ccg;
6115 + struct ceetm_class_stats __percpu *cstats;
6116 +};
6117 +
6118 +struct ceetm_class {
6119 + struct Qdisc_class_common common;
6120 + int refcnt; /* usage count of this class */
6121 + struct tcf_proto *filter_list; /* class attached filters */
6122 + struct Qdisc *parent;
6123 + bool shaped;
6124 + int type; /* ROOT/PRIO/WBFS */
6125 + union {
6126 + struct root_c root;
6127 + struct prio_c prio;
6128 + struct wbfs_c wbfs;
6129 + };
6130 +};
6131 +
6132 +/* CEETM Class configuration parameters */
6133 +struct tc_ceetm_copt {
6134 + __u32 type;
6135 + __u16 shaped;
6136 + __u32 rate;
6137 + __u32 ceil;
6138 + __u16 tbl;
6139 + __u16 cr;
6140 + __u16 er;
6141 + __u8 weight;
6142 +};
6143 +
6144 +/* CEETM stats */
6145 +struct ceetm_qdisc_stats {
6146 + __u32 drops;
6147 +};
6148 +
6149 +struct ceetm_class_stats {
6150 + /* Software counters */
6151 + struct gnet_stats_basic_packed bstats;
6152 + __u32 ern_drop_count;
6153 + __u32 congested_count;
6154 +};
6155 +
6156 +struct tc_ceetm_xstats {
6157 + __u32 ern_drop_count;
6158 + __u32 congested_count;
6159 + /* Hardware counters */
6160 + __u64 frame_count;
6161 + __u64 byte_count;
6162 +};
6163 +
6164 +int __hot ceetm_tx(struct sk_buff *skb, struct net_device *net_dev);
6165 +#endif
6166 --- /dev/null
6167 +++ b/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_common.c
6168 @@ -0,0 +1,1802 @@
6169 +/* Copyright 2008-2013 Freescale Semiconductor, Inc.
6170 + *
6171 + * Redistribution and use in source and binary forms, with or without
6172 + * modification, are permitted provided that the following conditions are met:
6173 + * * Redistributions of source code must retain the above copyright
6174 + * notice, this list of conditions and the following disclaimer.
6175 + * * Redistributions in binary form must reproduce the above copyright
6176 + * notice, this list of conditions and the following disclaimer in the
6177 + * documentation and/or other materials provided with the distribution.
6178 + * * Neither the name of Freescale Semiconductor nor the
6179 + * names of its contributors may be used to endorse or promote products
6180 + * derived from this software without specific prior written permission.
6181 + *
6182 + *
6183 + * ALTERNATIVELY, this software may be distributed under the terms of the
6184 + * GNU General Public License ("GPL") as published by the Free Software
6185 + * Foundation, either version 2 of that License or (at your option) any
6186 + * later version.
6187 + *
6188 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
6189 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
6190 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
6191 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
6192 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
6193 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
6194 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
6195 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
6196 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
6197 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
6198 + */
6199 +
6200 +#include <linux/init.h>
6201 +#include <linux/module.h>
6202 +#include <linux/of_platform.h>
6203 +#include <linux/of_net.h>
6204 +#include <linux/etherdevice.h>
6205 +#include <linux/kthread.h>
6206 +#include <linux/percpu.h>
6207 +#include <linux/highmem.h>
6208 +#include <linux/sort.h>
6209 +#include <linux/fsl_qman.h>
6210 +#include <linux/ip.h>
6211 +#include <linux/ipv6.h>
6212 +#include <linux/if_vlan.h> /* vlan_eth_hdr */
6213 +#include "dpaa_eth.h"
6214 +#include "dpaa_eth_common.h"
6215 +#ifdef CONFIG_FSL_DPAA_1588
6216 +#include "dpaa_1588.h"
6217 +#endif
6218 +#ifdef CONFIG_FSL_DPAA_DBG_LOOP
6219 +#include "dpaa_debugfs.h"
6220 +#endif /* CONFIG_FSL_DPAA_DBG_LOOP */
6221 +#include "mac.h"
6222 +
6223 +/* Size in bytes of the FQ taildrop threshold */
6224 +#define DPA_FQ_TD 0x200000
6225 +
6226 +#ifdef CONFIG_PTP_1588_CLOCK_DPAA
6227 +struct ptp_priv_s ptp_priv;
6228 +#endif
6229 +
6230 +static struct dpa_bp *dpa_bp_array[64];
6231 +
6232 +int dpa_max_frm;
6233 +EXPORT_SYMBOL(dpa_max_frm);
6234 +
6235 +int dpa_rx_extra_headroom;
6236 +EXPORT_SYMBOL(dpa_rx_extra_headroom);
6237 +
6238 +int dpa_num_cpus = NR_CPUS;
6239 +
6240 +static const struct fqid_cell tx_confirm_fqids[] = {
6241 + {0, DPAA_ETH_TX_QUEUES}
6242 +};
6243 +
6244 +static struct fqid_cell default_fqids[][3] = {
6245 + [RX] = { {0, 1}, {0, 1}, {0, DPAA_ETH_RX_QUEUES} },
6246 + [TX] = { {0, 1}, {0, 1}, {0, DPAA_ETH_TX_QUEUES} }
6247 +};
6248 +
6249 +static const char fsl_qman_frame_queues[][25] = {
6250 + [RX] = "fsl,qman-frame-queues-rx",
6251 + [TX] = "fsl,qman-frame-queues-tx"
6252 +};
6253 +#ifdef CONFIG_FSL_DPAA_HOOKS
6254 +/* A set of callbacks for hooking into the fastpath at different points. */
6255 +struct dpaa_eth_hooks_s dpaa_eth_hooks;
6256 +EXPORT_SYMBOL(dpaa_eth_hooks);
6257 +/* This function should only be called on the probe paths, since it makes no
6258 + * effort to guarantee consistency of the destination hooks structure.
6259 + */
6260 +void fsl_dpaa_eth_set_hooks(struct dpaa_eth_hooks_s *hooks)
6261 +{
6262 + if (hooks)
6263 + dpaa_eth_hooks = *hooks;
6264 + else
6265 + pr_err("NULL pointer to hooks!\n");
6266 +}
6267 +EXPORT_SYMBOL(fsl_dpaa_eth_set_hooks);
6268 +#endif
6269 +
6270 +int dpa_netdev_init(struct net_device *net_dev,
6271 + const uint8_t *mac_addr,
6272 + uint16_t tx_timeout)
6273 +{
6274 + int err;
6275 + struct dpa_priv_s *priv = netdev_priv(net_dev);
6276 + struct device *dev = net_dev->dev.parent;
6277 +
6278 + net_dev->priv_flags |= IFF_LIVE_ADDR_CHANGE;
6279 +
6280 + net_dev->features |= net_dev->hw_features;
6281 + net_dev->vlan_features = net_dev->features;
6282 +
6283 + memcpy(net_dev->perm_addr, mac_addr, net_dev->addr_len);
6284 + memcpy(net_dev->dev_addr, mac_addr, net_dev->addr_len);
6285 +
6286 + net_dev->ethtool_ops = &dpa_ethtool_ops;
6287 +
6288 + net_dev->needed_headroom = priv->tx_headroom;
6289 + net_dev->watchdog_timeo = msecs_to_jiffies(tx_timeout);
6290 +
6291 + err = register_netdev(net_dev);
6292 + if (err < 0) {
6293 + dev_err(dev, "register_netdev() = %d\n", err);
6294 + return err;
6295 + }
6296 +
6297 +#ifdef CONFIG_FSL_DPAA_DBG_LOOP
6298 + /* create debugfs entry for this net_device */
6299 + err = dpa_netdev_debugfs_create(net_dev);
6300 + if (err) {
6301 + unregister_netdev(net_dev);
6302 + return err;
6303 + }
6304 +#endif /* CONFIG_FSL_DPAA_DBG_LOOP */
6305 +
6306 + return 0;
6307 +}
6308 +EXPORT_SYMBOL(dpa_netdev_init);
6309 +
6310 +int __cold dpa_start(struct net_device *net_dev)
6311 +{
6312 + int err, i;
6313 + struct dpa_priv_s *priv;
6314 + struct mac_device *mac_dev;
6315 +
6316 + priv = netdev_priv(net_dev);
6317 + mac_dev = priv->mac_dev;
6318 +
6319 + err = mac_dev->init_phy(net_dev, priv->mac_dev);
6320 + if (err < 0) {
6321 + if (netif_msg_ifup(priv))
6322 + netdev_err(net_dev, "init_phy() = %d\n", err);
6323 + return err;
6324 + }
6325 +
6326 + for_each_port_device(i, mac_dev->port_dev) {
6327 + err = fm_port_enable(mac_dev->port_dev[i]);
6328 + if (err)
6329 + goto mac_start_failed;
6330 + }
6331 +
6332 + err = priv->mac_dev->start(mac_dev);
6333 + if (err < 0) {
6334 + if (netif_msg_ifup(priv))
6335 + netdev_err(net_dev, "mac_dev->start() = %d\n", err);
6336 + goto mac_start_failed;
6337 + }
6338 +
6339 + netif_tx_start_all_queues(net_dev);
6340 +
6341 + return 0;
6342 +
6343 +mac_start_failed:
6344 + for_each_port_device(i, mac_dev->port_dev)
6345 + fm_port_disable(mac_dev->port_dev[i]);
6346 +
6347 + return err;
6348 +}
6349 +EXPORT_SYMBOL(dpa_start);
6350 +
6351 +int __cold dpa_stop(struct net_device *net_dev)
6352 +{
6353 + int _errno, i, err;
6354 + struct dpa_priv_s *priv;
6355 + struct mac_device *mac_dev;
6356 +
6357 + priv = netdev_priv(net_dev);
6358 + mac_dev = priv->mac_dev;
6359 +
6360 + netif_tx_stop_all_queues(net_dev);
6361 + /* Allow the Fman (Tx) port to process in-flight frames before we
6362 + * try switching it off.
6363 + */
6364 + usleep_range(5000, 10000);
6365 +
6366 + _errno = mac_dev->stop(mac_dev);
6367 + if (unlikely(_errno < 0))
6368 + if (netif_msg_ifdown(priv))
6369 + netdev_err(net_dev, "mac_dev->stop() = %d\n",
6370 + _errno);
6371 +
6372 + for_each_port_device(i, mac_dev->port_dev) {
6373 + err = fm_port_disable(mac_dev->port_dev[i]);
6374 + _errno = err ? err : _errno;
6375 + }
6376 +
6377 + if (mac_dev->phy_dev)
6378 + phy_disconnect(mac_dev->phy_dev);
6379 + mac_dev->phy_dev = NULL;
6380 +
6381 + return _errno;
6382 +}
6383 +EXPORT_SYMBOL(dpa_stop);
6384 +
6385 +void __cold dpa_timeout(struct net_device *net_dev)
6386 +{
6387 + const struct dpa_priv_s *priv;
6388 + struct dpa_percpu_priv_s *percpu_priv;
6389 +
6390 + priv = netdev_priv(net_dev);
6391 + percpu_priv = raw_cpu_ptr(priv->percpu_priv);
6392 +
6393 + if (netif_msg_timer(priv))
6394 + netdev_crit(net_dev, "Transmit timeout!\n");
6395 +
6396 + percpu_priv->stats.tx_errors++;
6397 +}
6398 +EXPORT_SYMBOL(dpa_timeout);
6399 +
6400 +/* net_device */
6401 +
6402 +/**
6403 + * @param net_dev the device for which statistics are calculated
6404 + * @param stats the function fills this structure with the device's statistics
6405 + * @return the address of the structure containing the statistics
6406 + *
6407 + * Calculates the statistics for the given device by adding the statistics
6408 + * collected by each CPU.
6409 + */
6410 +struct rtnl_link_stats64 __cold
6411 +*dpa_get_stats64(struct net_device *net_dev,
6412 + struct rtnl_link_stats64 *stats)
6413 +{
6414 + struct dpa_priv_s *priv = netdev_priv(net_dev);
6415 + u64 *cpustats;
6416 + u64 *netstats = (u64 *)stats;
6417 + int i, j;
6418 + struct dpa_percpu_priv_s *percpu_priv;
6419 + int numstats = sizeof(struct rtnl_link_stats64) / sizeof(u64);
6420 +
6421 + for_each_possible_cpu(i) {
6422 + percpu_priv = per_cpu_ptr(priv->percpu_priv, i);
6423 +
6424 + cpustats = (u64 *)&percpu_priv->stats;
6425 +
6426 + for (j = 0; j < numstats; j++)
6427 + netstats[j] += cpustats[j];
6428 + }
6429 + return stats;
6430 +}
6431 +EXPORT_SYMBOL(dpa_get_stats64);
6432 +
6433 +int dpa_change_mtu(struct net_device *net_dev, int new_mtu)
6434 +{
6435 + int max_mtu = dpa_get_max_mtu();
6436 +
6437 +#ifndef CONFIG_PPC
6438 + /* Due to the A010022 FMan errata, we can not use contig frames larger
6439 + * than 4K, nor S/G frames. We need to prevent the user from setting a
6440 + * large MTU.
6441 + */
6442 + if (unlikely(dpaa_errata_a010022))
6443 + max_mtu = DPA_BP_RAW_SIZE;
6444 +#endif
6445 +
6446 + /* Make sure we don't exceed the Ethernet controller's MAXFRM */
6447 + if (new_mtu < 68 || new_mtu > max_mtu) {
6448 + netdev_err(net_dev, "Invalid L3 mtu %d (must be between %d and %d).\n",
6449 + new_mtu, 68, max_mtu);
6450 + return -EINVAL;
6451 + }
6452 + net_dev->mtu = new_mtu;
6453 +
6454 + return 0;
6455 +}
6456 +EXPORT_SYMBOL(dpa_change_mtu);
6457 +
6458 +/* .ndo_init callback */
6459 +int dpa_ndo_init(struct net_device *net_dev)
6460 +{
6461 + /* If fsl_fm_max_frm is set to a higher value than the all-common 1500,
6462 + * we choose conservatively and let the user explicitly set a higher
6463 + * MTU via ifconfig. Otherwise, the user may end up with different MTUs
6464 + * in the same LAN.
6465 + * If on the other hand fsl_fm_max_frm has been chosen below 1500,
6466 + * start with the maximum allowed.
6467 + */
6468 + int init_mtu = min(dpa_get_max_mtu(), ETH_DATA_LEN);
6469 +
6470 + pr_debug("Setting initial MTU on net device: %d\n", init_mtu);
6471 + net_dev->mtu = init_mtu;
6472 +
6473 + return 0;
6474 +}
6475 +EXPORT_SYMBOL(dpa_ndo_init);
6476 +
6477 +int dpa_set_features(struct net_device *dev, netdev_features_t features)
6478 +{
6479 + /* Not much to do here for now */
6480 + dev->features = features;
6481 + return 0;
6482 +}
6483 +EXPORT_SYMBOL(dpa_set_features);
6484 +
6485 +netdev_features_t dpa_fix_features(struct net_device *dev,
6486 + netdev_features_t features)
6487 +{
6488 + netdev_features_t unsupported_features = 0;
6489 +
6490 + /* In theory we should never be requested to enable features that
6491 + * we didn't set in netdev->features and netdev->hw_features at probe
6492 + * time, but double check just to be on the safe side.
6493 + * We don't support enabling Rx csum through ethtool yet
6494 + */
6495 + unsupported_features |= NETIF_F_RXCSUM;
6496 +
6497 + features &= ~unsupported_features;
6498 +
6499 + return features;
6500 +}
6501 +EXPORT_SYMBOL(dpa_fix_features);
6502 +
6503 +#ifdef CONFIG_FSL_DPAA_TS
6504 +u64 dpa_get_timestamp_ns(const struct dpa_priv_s *priv, enum port_type rx_tx,
6505 + const void *data)
6506 +{
6507 + u64 *ts, ns;
6508 +
6509 + ts = fm_port_get_buffer_time_stamp(priv->mac_dev->port_dev[rx_tx],
6510 + data);
6511 +
6512 + if (!ts || *ts == 0)
6513 + return 0;
6514 +
6515 + be64_to_cpus(ts);
6516 +
6517 + /* multiple DPA_PTP_NOMINAL_FREQ_PERIOD_NS for case of non power of 2 */
6518 + ns = *ts << DPA_PTP_NOMINAL_FREQ_PERIOD_SHIFT;
6519 +
6520 + return ns;
6521 +}
6522 +
6523 +int dpa_get_ts(const struct dpa_priv_s *priv, enum port_type rx_tx,
6524 + struct skb_shared_hwtstamps *shhwtstamps, const void *data)
6525 +{
6526 + u64 ns;
6527 +
6528 + ns = dpa_get_timestamp_ns(priv, rx_tx, data);
6529 +
6530 + if (ns == 0)
6531 + return -EINVAL;
6532 +
6533 + memset(shhwtstamps, 0, sizeof(*shhwtstamps));
6534 + shhwtstamps->hwtstamp = ns_to_ktime(ns);
6535 +
6536 + return 0;
6537 +}
6538 +
6539 +static void dpa_ts_tx_enable(struct net_device *dev)
6540 +{
6541 + struct dpa_priv_s *priv = netdev_priv(dev);
6542 + struct mac_device *mac_dev = priv->mac_dev;
6543 +
6544 + if (mac_dev->fm_rtc_enable)
6545 + mac_dev->fm_rtc_enable(get_fm_handle(dev));
6546 + if (mac_dev->ptp_enable)
6547 + mac_dev->ptp_enable(mac_dev->get_mac_handle(mac_dev));
6548 +
6549 + priv->ts_tx_en = true;
6550 +}
6551 +
6552 +static void dpa_ts_tx_disable(struct net_device *dev)
6553 +{
6554 + struct dpa_priv_s *priv = netdev_priv(dev);
6555 +
6556 +#if 0
6557 +/* the RTC might be needed by the Rx Ts, cannot disable here
6558 + * no separate ptp_disable API for Rx/Tx, cannot disable here
6559 + */
6560 + struct mac_device *mac_dev = priv->mac_dev;
6561 +
6562 + if (mac_dev->fm_rtc_disable)
6563 + mac_dev->fm_rtc_disable(get_fm_handle(dev));
6564 +
6565 + if (mac_dev->ptp_disable)
6566 + mac_dev->ptp_disable(mac_dev->get_mac_handle(mac_dev));
6567 +#endif
6568 +
6569 + priv->ts_tx_en = false;
6570 +}
6571 +
6572 +static void dpa_ts_rx_enable(struct net_device *dev)
6573 +{
6574 + struct dpa_priv_s *priv = netdev_priv(dev);
6575 + struct mac_device *mac_dev = priv->mac_dev;
6576 +
6577 + if (mac_dev->fm_rtc_enable)
6578 + mac_dev->fm_rtc_enable(get_fm_handle(dev));
6579 + if (mac_dev->ptp_enable)
6580 + mac_dev->ptp_enable(mac_dev->get_mac_handle(mac_dev));
6581 +
6582 + priv->ts_rx_en = true;
6583 +}
6584 +
6585 +static void dpa_ts_rx_disable(struct net_device *dev)
6586 +{
6587 + struct dpa_priv_s *priv = netdev_priv(dev);
6588 +
6589 +#if 0
6590 +/* the RTC might be needed by the Tx Ts, cannot disable here
6591 + * no separate ptp_disable API for Rx/Tx, cannot disable here
6592 + */
6593 + struct mac_device *mac_dev = priv->mac_dev;
6594 +
6595 + if (mac_dev->fm_rtc_disable)
6596 + mac_dev->fm_rtc_disable(get_fm_handle(dev));
6597 +
6598 + if (mac_dev->ptp_disable)
6599 + mac_dev->ptp_disable(mac_dev->get_mac_handle(mac_dev));
6600 +#endif
6601 +
6602 + priv->ts_rx_en = false;
6603 +}
6604 +
6605 +static int dpa_ts_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
6606 +{
6607 + struct hwtstamp_config config;
6608 +
6609 + if (copy_from_user(&config, rq->ifr_data, sizeof(config)))
6610 + return -EFAULT;
6611 +
6612 + switch (config.tx_type) {
6613 + case HWTSTAMP_TX_OFF:
6614 + dpa_ts_tx_disable(dev);
6615 + break;
6616 + case HWTSTAMP_TX_ON:
6617 + dpa_ts_tx_enable(dev);
6618 + break;
6619 + default:
6620 + return -ERANGE;
6621 + }
6622 +
6623 + if (config.rx_filter == HWTSTAMP_FILTER_NONE)
6624 + dpa_ts_rx_disable(dev);
6625 + else {
6626 + dpa_ts_rx_enable(dev);
6627 + /* TS is set for all frame types, not only those requested */
6628 + config.rx_filter = HWTSTAMP_FILTER_ALL;
6629 + }
6630 +
6631 + return copy_to_user(rq->ifr_data, &config, sizeof(config)) ?
6632 + -EFAULT : 0;
6633 +}
6634 +#endif /* CONFIG_FSL_DPAA_TS */
6635 +
6636 +int dpa_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
6637 +{
6638 +#ifdef CONFIG_FSL_DPAA_1588
6639 + struct dpa_priv_s *priv = netdev_priv(dev);
6640 +#endif
6641 + int ret = -EINVAL;
6642 +
6643 + if (!netif_running(dev))
6644 + return -EINVAL;
6645 +
6646 + if (cmd == SIOCGMIIREG) {
6647 + if (!dev->phydev)
6648 + ret = -EINVAL;
6649 + else
6650 + ret = phy_mii_ioctl(dev->phydev, rq, cmd);
6651 + }
6652 +
6653 +#ifdef CONFIG_FSL_DPAA_TS
6654 + if (cmd == SIOCSHWTSTAMP)
6655 + return dpa_ts_ioctl(dev, rq, cmd);
6656 +#endif /* CONFIG_FSL_DPAA_TS */
6657 +
6658 +#ifdef CONFIG_FSL_DPAA_1588
6659 + if ((cmd >= PTP_ENBL_TXTS_IOCTL) && (cmd <= PTP_CLEANUP_TS)) {
6660 + if (priv->tsu && priv->tsu->valid)
6661 + ret = dpa_ioctl_1588(dev, rq, cmd);
6662 + else
6663 + ret = -ENODEV;
6664 + }
6665 +#endif
6666 +
6667 + return ret;
6668 +}
6669 +EXPORT_SYMBOL(dpa_ioctl);
6670 +
6671 +int __cold dpa_remove(struct platform_device *of_dev)
6672 +{
6673 + int err;
6674 + struct device *dev;
6675 + struct net_device *net_dev;
6676 + struct dpa_priv_s *priv;
6677 +
6678 + dev = &of_dev->dev;
6679 + net_dev = dev_get_drvdata(dev);
6680 +
6681 + priv = netdev_priv(net_dev);
6682 +
6683 + dpaa_eth_sysfs_remove(dev);
6684 +
6685 + dev_set_drvdata(dev, NULL);
6686 + unregister_netdev(net_dev);
6687 +
6688 + err = dpa_fq_free(dev, &priv->dpa_fq_list);
6689 +
6690 + qman_delete_cgr_safe(&priv->ingress_cgr);
6691 + qman_release_cgrid(priv->ingress_cgr.cgrid);
6692 + qman_delete_cgr_safe(&priv->cgr_data.cgr);
6693 + qman_release_cgrid(priv->cgr_data.cgr.cgrid);
6694 +
6695 + dpa_private_napi_del(net_dev);
6696 +
6697 + dpa_bp_free(priv);
6698 +
6699 + if (priv->buf_layout)
6700 + devm_kfree(dev, priv->buf_layout);
6701 +
6702 +#ifdef CONFIG_FSL_DPAA_DBG_LOOP
6703 + /* remove debugfs entry for this net_device */
6704 + dpa_netdev_debugfs_remove(net_dev);
6705 +#endif /* CONFIG_FSL_DPAA_DBG_LOOP */
6706 +
6707 +#ifdef CONFIG_FSL_DPAA_1588
6708 + if (priv->tsu && priv->tsu->valid)
6709 + dpa_ptp_cleanup(priv);
6710 +#endif
6711 +
6712 + free_netdev(net_dev);
6713 +
6714 + return err;
6715 +}
6716 +EXPORT_SYMBOL(dpa_remove);
6717 +
6718 +struct mac_device * __cold __must_check
6719 +__attribute__((nonnull))
6720 +dpa_mac_probe(struct platform_device *_of_dev)
6721 +{
6722 + struct device *dpa_dev, *dev;
6723 + struct device_node *mac_node;
6724 + struct platform_device *of_dev;
6725 + struct mac_device *mac_dev;
6726 +#ifdef CONFIG_FSL_DPAA_1588
6727 + int lenp;
6728 + const phandle *phandle_prop;
6729 + struct net_device *net_dev = NULL;
6730 + struct dpa_priv_s *priv = NULL;
6731 + struct device_node *timer_node;
6732 +#endif
6733 + dpa_dev = &_of_dev->dev;
6734 +
6735 + mac_node = of_parse_phandle(_of_dev->dev.of_node, "fsl,fman-mac", 0);
6736 + if (unlikely(mac_node == NULL)) {
6737 + dev_err(dpa_dev, "Cannot find MAC device device tree node\n");
6738 + return ERR_PTR(-EFAULT);
6739 + }
6740 +
6741 + of_dev = of_find_device_by_node(mac_node);
6742 + if (unlikely(of_dev == NULL)) {
6743 + dev_err(dpa_dev, "of_find_device_by_node(%s) failed\n",
6744 + mac_node->full_name);
6745 + of_node_put(mac_node);
6746 + return ERR_PTR(-EINVAL);
6747 + }
6748 + of_node_put(mac_node);
6749 +
6750 + dev = &of_dev->dev;
6751 +
6752 + mac_dev = dev_get_drvdata(dev);
6753 + if (unlikely(mac_dev == NULL)) {
6754 + dev_err(dpa_dev, "dev_get_drvdata(%s) failed\n",
6755 + dev_name(dev));
6756 + return ERR_PTR(-EINVAL);
6757 + }
6758 +
6759 +#ifdef CONFIG_FSL_DPAA_1588
6760 + phandle_prop = of_get_property(mac_node, "ptp-timer", &lenp);
6761 + if (phandle_prop && ((mac_dev->phy_if != PHY_INTERFACE_MODE_SGMII) ||
6762 + ((mac_dev->phy_if == PHY_INTERFACE_MODE_SGMII) &&
6763 + (mac_dev->speed == SPEED_1000)))) {
6764 + timer_node = of_find_node_by_phandle(*phandle_prop);
6765 + if (timer_node)
6766 + net_dev = dev_get_drvdata(dpa_dev);
6767 + if (timer_node && net_dev) {
6768 + priv = netdev_priv(net_dev);
6769 + if (!dpa_ptp_init(priv))
6770 + dev_info(dev, "%s: ptp 1588 is initialized.\n",
6771 + mac_node->full_name);
6772 + }
6773 + }
6774 +#endif
6775 +
6776 +#ifdef CONFIG_PTP_1588_CLOCK_DPAA
6777 + if ((mac_dev->phy_if != PHY_INTERFACE_MODE_SGMII) ||
6778 + ((mac_dev->phy_if == PHY_INTERFACE_MODE_SGMII) &&
6779 + (mac_dev->speed == SPEED_1000))) {
6780 + ptp_priv.node = of_parse_phandle(mac_node, "ptp-timer", 0);
6781 + if (ptp_priv.node) {
6782 + ptp_priv.of_dev = of_find_device_by_node(ptp_priv.node);
6783 + if (unlikely(ptp_priv.of_dev == NULL)) {
6784 + dev_err(dpa_dev,
6785 + "Cannot find device represented by timer_node\n");
6786 + of_node_put(ptp_priv.node);
6787 + return ERR_PTR(-EINVAL);
6788 + }
6789 + ptp_priv.mac_dev = mac_dev;
6790 + }
6791 + }
6792 +#endif
6793 + return mac_dev;
6794 +}
6795 +EXPORT_SYMBOL(dpa_mac_probe);
6796 +
6797 +int dpa_set_mac_address(struct net_device *net_dev, void *addr)
6798 +{
6799 + const struct dpa_priv_s *priv;
6800 + int _errno;
6801 + struct mac_device *mac_dev;
6802 +
6803 + priv = netdev_priv(net_dev);
6804 +
6805 + _errno = eth_mac_addr(net_dev, addr);
6806 + if (_errno < 0) {
6807 + if (netif_msg_drv(priv))
6808 + netdev_err(net_dev,
6809 + "eth_mac_addr() = %d\n",
6810 + _errno);
6811 + return _errno;
6812 + }
6813 +
6814 + mac_dev = priv->mac_dev;
6815 +
6816 + _errno = mac_dev->change_addr(mac_dev->get_mac_handle(mac_dev),
6817 + net_dev->dev_addr);
6818 + if (_errno < 0) {
6819 + if (netif_msg_drv(priv))
6820 + netdev_err(net_dev,
6821 + "mac_dev->change_addr() = %d\n",
6822 + _errno);
6823 + return _errno;
6824 + }
6825 +
6826 + return 0;
6827 +}
6828 +EXPORT_SYMBOL(dpa_set_mac_address);
6829 +
6830 +void dpa_set_rx_mode(struct net_device *net_dev)
6831 +{
6832 + int _errno;
6833 + const struct dpa_priv_s *priv;
6834 +
6835 + priv = netdev_priv(net_dev);
6836 +
6837 + if (!!(net_dev->flags & IFF_PROMISC) != priv->mac_dev->promisc) {
6838 + priv->mac_dev->promisc = !priv->mac_dev->promisc;
6839 + _errno = priv->mac_dev->set_promisc(
6840 + priv->mac_dev->get_mac_handle(priv->mac_dev),
6841 + priv->mac_dev->promisc);
6842 + if (unlikely(_errno < 0) && netif_msg_drv(priv))
6843 + netdev_err(net_dev,
6844 + "mac_dev->set_promisc() = %d\n",
6845 + _errno);
6846 + }
6847 +
6848 + _errno = priv->mac_dev->set_multi(net_dev, priv->mac_dev);
6849 + if (unlikely(_errno < 0) && netif_msg_drv(priv))
6850 + netdev_err(net_dev, "mac_dev->set_multi() = %d\n", _errno);
6851 +}
6852 +EXPORT_SYMBOL(dpa_set_rx_mode);
6853 +
6854 +void dpa_set_buffers_layout(struct mac_device *mac_dev,
6855 + struct dpa_buffer_layout_s *layout)
6856 +{
6857 + struct fm_port_params params;
6858 +
6859 + /* Rx */
6860 + layout[RX].priv_data_size = (uint16_t)DPA_RX_PRIV_DATA_SIZE;
6861 + layout[RX].parse_results = true;
6862 + layout[RX].hash_results = true;
6863 +#ifdef CONFIG_FSL_DPAA_TS
6864 + layout[RX].time_stamp = true;
6865 +#endif
6866 + fm_port_get_buff_layout_ext_params(mac_dev->port_dev[RX], &params);
6867 + layout[RX].manip_extra_space = params.manip_extra_space;
6868 + /* a value of zero for data alignment means "don't care", so align to
6869 + * a non-zero value to prevent FMD from using its own default
6870 + */
6871 + layout[RX].data_align = params.data_align ? : DPA_FD_DATA_ALIGNMENT;
6872 +
6873 + /* Tx */
6874 + layout[TX].priv_data_size = DPA_TX_PRIV_DATA_SIZE;
6875 + layout[TX].parse_results = true;
6876 + layout[TX].hash_results = true;
6877 +#ifdef CONFIG_FSL_DPAA_TS
6878 + layout[TX].time_stamp = true;
6879 +#endif
6880 + fm_port_get_buff_layout_ext_params(mac_dev->port_dev[TX], &params);
6881 + layout[TX].manip_extra_space = params.manip_extra_space;
6882 + layout[TX].data_align = params.data_align ? : DPA_FD_DATA_ALIGNMENT;
6883 +}
6884 +EXPORT_SYMBOL(dpa_set_buffers_layout);
6885 +
6886 +int __attribute__((nonnull))
6887 +dpa_bp_alloc(struct dpa_bp *dpa_bp, struct device *dev)
6888 +{
6889 + int err;
6890 + struct bman_pool_params bp_params;
6891 +
6892 + if (dpa_bp->size == 0 || dpa_bp->config_count == 0) {
6893 + pr_err("Buffer pool is not properly initialized! Missing size or initial number of buffers");
6894 + return -EINVAL;
6895 + }
6896 +
6897 + memset(&bp_params, 0, sizeof(struct bman_pool_params));
6898 +#ifdef CONFIG_FMAN_PFC
6899 + bp_params.flags = BMAN_POOL_FLAG_THRESH;
6900 + bp_params.thresholds[0] = bp_params.thresholds[2] =
6901 + CONFIG_FSL_DPAA_ETH_REFILL_THRESHOLD;
6902 + bp_params.thresholds[1] = bp_params.thresholds[3] =
6903 + CONFIG_FSL_DPAA_ETH_MAX_BUF_COUNT;
6904 +#endif
6905 +
6906 + /* If the pool is already specified, we only create one per bpid */
6907 + if (dpa_bpid2pool_use(dpa_bp->bpid))
6908 + return 0;
6909 +
6910 + if (dpa_bp->bpid == 0)
6911 + bp_params.flags |= BMAN_POOL_FLAG_DYNAMIC_BPID;
6912 + else
6913 + bp_params.bpid = dpa_bp->bpid;
6914 +
6915 + dpa_bp->pool = bman_new_pool(&bp_params);
6916 + if (unlikely(dpa_bp->pool == NULL)) {
6917 + pr_err("bman_new_pool() failed\n");
6918 + return -ENODEV;
6919 + }
6920 +
6921 + dpa_bp->bpid = (uint8_t)bman_get_params(dpa_bp->pool)->bpid;
6922 +
6923 + err = dma_coerce_mask_and_coherent(dev, DMA_BIT_MASK(40));
6924 + if (err) {
6925 + pr_err("dma_coerce_mask_and_coherent() failed\n");
6926 + goto bman_free_pool;
6927 + }
6928 +
6929 + dpa_bp->dev = dev;
6930 +
6931 + if (dpa_bp->seed_cb) {
6932 + err = dpa_bp->seed_cb(dpa_bp);
6933 + if (err)
6934 + goto bman_free_pool;
6935 + }
6936 +
6937 + dpa_bpid2pool_map(dpa_bp->bpid, dpa_bp);
6938 +
6939 + return 0;
6940 +
6941 +bman_free_pool:
6942 + bman_free_pool(dpa_bp->pool);
6943 +
6944 + return err;
6945 +}
6946 +EXPORT_SYMBOL(dpa_bp_alloc);
6947 +
6948 +void dpa_bp_drain(struct dpa_bp *bp)
6949 +{
6950 + int ret, num = 8;
6951 +
6952 + do {
6953 + struct bm_buffer bmb[8];
6954 + int i;
6955 +
6956 + ret = bman_acquire(bp->pool, bmb, num, 0);
6957 + if (ret < 0) {
6958 + if (num == 8) {
6959 + /* we have less than 8 buffers left;
6960 + * drain them one by one
6961 + */
6962 + num = 1;
6963 + ret = 1;
6964 + continue;
6965 + } else {
6966 + /* Pool is fully drained */
6967 + break;
6968 + }
6969 + }
6970 +
6971 + for (i = 0; i < num; i++) {
6972 + dma_addr_t addr = bm_buf_addr(&bmb[i]);
6973 +
6974 + dma_unmap_single(bp->dev, addr, bp->size,
6975 + DMA_BIDIRECTIONAL);
6976 +
6977 + bp->free_buf_cb(phys_to_virt(addr));
6978 + }
6979 + } while (ret > 0);
6980 +}
6981 +EXPORT_SYMBOL(dpa_bp_drain);
6982 +
6983 +static void __cold __attribute__((nonnull))
6984 +_dpa_bp_free(struct dpa_bp *dpa_bp)
6985 +{
6986 + struct dpa_bp *bp = dpa_bpid2pool(dpa_bp->bpid);
6987 +
6988 + /* the mapping between bpid and dpa_bp is done very late in the
6989 + * allocation procedure; if something failed before the mapping, the bp
6990 + * was not configured, therefore we don't need the below instructions
6991 + */
6992 + if (!bp)
6993 + return;
6994 +
6995 + if (!atomic_dec_and_test(&bp->refs))
6996 + return;
6997 +
6998 + if (bp->free_buf_cb)
6999 + dpa_bp_drain(bp);
7000 +
7001 + dpa_bp_array[bp->bpid] = NULL;
7002 + bman_free_pool(bp->pool);
7003 +}
7004 +
7005 +void __cold __attribute__((nonnull))
7006 +dpa_bp_free(struct dpa_priv_s *priv)
7007 +{
7008 + int i;
7009 +
7010 + if (priv->dpa_bp)
7011 + for (i = 0; i < priv->bp_count; i++)
7012 + _dpa_bp_free(&priv->dpa_bp[i]);
7013 +}
7014 +EXPORT_SYMBOL(dpa_bp_free);
7015 +
7016 +struct dpa_bp *dpa_bpid2pool(int bpid)
7017 +{
7018 + return dpa_bp_array[bpid];
7019 +}
7020 +EXPORT_SYMBOL(dpa_bpid2pool);
7021 +
7022 +void dpa_bpid2pool_map(int bpid, struct dpa_bp *dpa_bp)
7023 +{
7024 + dpa_bp_array[bpid] = dpa_bp;
7025 + atomic_set(&dpa_bp->refs, 1);
7026 +}
7027 +
7028 +bool dpa_bpid2pool_use(int bpid)
7029 +{
7030 + if (dpa_bpid2pool(bpid)) {
7031 + atomic_inc(&dpa_bp_array[bpid]->refs);
7032 + return true;
7033 + }
7034 +
7035 + return false;
7036 +}
7037 +
7038 +#ifdef CONFIG_FSL_DPAA_ETH_USE_NDO_SELECT_QUEUE
7039 +u16 dpa_select_queue(struct net_device *net_dev, struct sk_buff *skb,
7040 + void *accel_priv, select_queue_fallback_t fallback)
7041 +{
7042 + return dpa_get_queue_mapping(skb);
7043 +}
7044 +EXPORT_SYMBOL(dpa_select_queue);
7045 +#endif
7046 +
7047 +struct dpa_fq *dpa_fq_alloc(struct device *dev,
7048 + u32 fq_start,
7049 + u32 fq_count,
7050 + struct list_head *list,
7051 + enum dpa_fq_type fq_type)
7052 +{
7053 + int i;
7054 + struct dpa_fq *dpa_fq;
7055 +
7056 + dpa_fq = devm_kzalloc(dev, sizeof(*dpa_fq) * fq_count, GFP_KERNEL);
7057 + if (dpa_fq == NULL)
7058 + return NULL;
7059 +
7060 + for (i = 0; i < fq_count; i++) {
7061 + dpa_fq[i].fq_type = fq_type;
7062 + if (fq_type == FQ_TYPE_RX_PCD_HI_PRIO)
7063 + dpa_fq[i].fqid = fq_start ?
7064 + DPAA_ETH_FQ_DELTA + fq_start + i : 0;
7065 + else
7066 + dpa_fq[i].fqid = fq_start ? fq_start + i : 0;
7067 +
7068 + list_add_tail(&dpa_fq[i].list, list);
7069 + }
7070 +
7071 +#ifdef CONFIG_FMAN_PFC
7072 + if (fq_type == FQ_TYPE_TX)
7073 + for (i = 0; i < fq_count; i++)
7074 + dpa_fq[i].wq = i / dpa_num_cpus;
7075 + else
7076 +#endif
7077 + for (i = 0; i < fq_count; i++)
7078 + _dpa_assign_wq(dpa_fq + i);
7079 +
7080 + return dpa_fq;
7081 +}
7082 +EXPORT_SYMBOL(dpa_fq_alloc);
7083 +
7084 +/* Probing of FQs for MACful ports */
7085 +int dpa_fq_probe_mac(struct device *dev, struct list_head *list,
7086 + struct fm_port_fqs *port_fqs,
7087 + bool alloc_tx_conf_fqs,
7088 + enum port_type ptype)
7089 +{
7090 + struct fqid_cell *fqids = NULL;
7091 + const void *fqids_off = NULL;
7092 + struct dpa_fq *dpa_fq = NULL;
7093 + struct device_node *np = dev->of_node;
7094 + int num_ranges;
7095 + int i, lenp;
7096 +
7097 + if (ptype == TX && alloc_tx_conf_fqs) {
7098 + if (!dpa_fq_alloc(dev, tx_confirm_fqids->start,
7099 + tx_confirm_fqids->count, list,
7100 + FQ_TYPE_TX_CONF_MQ))
7101 + goto fq_alloc_failed;
7102 + }
7103 +
7104 + fqids_off = of_get_property(np, fsl_qman_frame_queues[ptype], &lenp);
7105 + if (fqids_off == NULL) {
7106 + /* No dts definition, so use the defaults. */
7107 + fqids = default_fqids[ptype];
7108 + num_ranges = 3;
7109 + } else {
7110 + num_ranges = lenp / sizeof(*fqids);
7111 +
7112 + fqids = devm_kzalloc(dev, sizeof(*fqids) * num_ranges,
7113 + GFP_KERNEL);
7114 + if (fqids == NULL)
7115 + goto fqids_alloc_failed;
7116 +
7117 + /* convert to CPU endianess */
7118 + for (i = 0; i < num_ranges; i++) {
7119 + fqids[i].start = be32_to_cpup(fqids_off +
7120 + i * sizeof(*fqids));
7121 + fqids[i].count = be32_to_cpup(fqids_off +
7122 + i * sizeof(*fqids) + sizeof(__be32));
7123 + }
7124 + }
7125 +
7126 + for (i = 0; i < num_ranges; i++) {
7127 + switch (i) {
7128 + case 0:
7129 + /* The first queue is the error queue */
7130 + if (fqids[i].count != 1)
7131 + goto invalid_error_queue;
7132 +
7133 + dpa_fq = dpa_fq_alloc(dev, fqids[i].start,
7134 + fqids[i].count, list,
7135 + ptype == RX ?
7136 + FQ_TYPE_RX_ERROR :
7137 + FQ_TYPE_TX_ERROR);
7138 + if (dpa_fq == NULL)
7139 + goto fq_alloc_failed;
7140 +
7141 + if (ptype == RX)
7142 + port_fqs->rx_errq = &dpa_fq[0];
7143 + else
7144 + port_fqs->tx_errq = &dpa_fq[0];
7145 + break;
7146 + case 1:
7147 + /* the second queue is the default queue */
7148 + if (fqids[i].count != 1)
7149 + goto invalid_default_queue;
7150 +
7151 + dpa_fq = dpa_fq_alloc(dev, fqids[i].start,
7152 + fqids[i].count, list,
7153 + ptype == RX ?
7154 + FQ_TYPE_RX_DEFAULT :
7155 + FQ_TYPE_TX_CONFIRM);
7156 + if (dpa_fq == NULL)
7157 + goto fq_alloc_failed;
7158 +
7159 + if (ptype == RX)
7160 + port_fqs->rx_defq = &dpa_fq[0];
7161 + else
7162 + port_fqs->tx_defq = &dpa_fq[0];
7163 + break;
7164 + default:
7165 + /* all subsequent queues are either RX* PCD or Tx */
7166 + if (ptype == RX) {
7167 + if (!dpa_fq_alloc(dev, fqids[i].start,
7168 + fqids[i].count, list,
7169 + FQ_TYPE_RX_PCD) ||
7170 + !dpa_fq_alloc(dev, fqids[i].start,
7171 + fqids[i].count, list,
7172 + FQ_TYPE_RX_PCD_HI_PRIO))
7173 + goto fq_alloc_failed;
7174 + } else {
7175 + if (!dpa_fq_alloc(dev, fqids[i].start,
7176 + fqids[i].count, list,
7177 + FQ_TYPE_TX))
7178 + goto fq_alloc_failed;
7179 + }
7180 + break;
7181 + }
7182 + }
7183 +
7184 + return 0;
7185 +
7186 +fq_alloc_failed:
7187 +fqids_alloc_failed:
7188 + dev_err(dev, "Cannot allocate memory for frame queues\n");
7189 + return -ENOMEM;
7190 +
7191 +invalid_default_queue:
7192 +invalid_error_queue:
7193 + dev_err(dev, "Too many default or error queues\n");
7194 + return -EINVAL;
7195 +}
7196 +EXPORT_SYMBOL(dpa_fq_probe_mac);
7197 +
7198 +static u32 rx_pool_channel;
7199 +static DEFINE_SPINLOCK(rx_pool_channel_init);
7200 +
7201 +int dpa_get_channel(void)
7202 +{
7203 + spin_lock(&rx_pool_channel_init);
7204 + if (!rx_pool_channel) {
7205 + u32 pool;
7206 + int ret = qman_alloc_pool(&pool);
7207 + if (!ret)
7208 + rx_pool_channel = pool;
7209 + }
7210 + spin_unlock(&rx_pool_channel_init);
7211 + if (!rx_pool_channel)
7212 + return -ENOMEM;
7213 + return rx_pool_channel;
7214 +}
7215 +EXPORT_SYMBOL(dpa_get_channel);
7216 +
7217 +void dpa_release_channel(void)
7218 +{
7219 + qman_release_pool(rx_pool_channel);
7220 +}
7221 +EXPORT_SYMBOL(dpa_release_channel);
7222 +
7223 +void dpaa_eth_add_channel(u16 channel)
7224 +{
7225 + const cpumask_t *cpus = qman_affine_cpus();
7226 + u32 pool = QM_SDQCR_CHANNELS_POOL_CONV(channel);
7227 + int cpu;
7228 + struct qman_portal *portal;
7229 +
7230 + for_each_cpu(cpu, cpus) {
7231 + portal = (struct qman_portal *)qman_get_affine_portal(cpu);
7232 + qman_p_static_dequeue_add(portal, pool);
7233 + }
7234 +}
7235 +EXPORT_SYMBOL(dpaa_eth_add_channel);
7236 +
7237 +/**
7238 + * Congestion group state change notification callback.
7239 + * Stops the device's egress queues while they are congested and
7240 + * wakes them upon exiting congested state.
7241 + * Also updates some CGR-related stats.
7242 + */
7243 +static void dpaa_eth_cgscn(struct qman_portal *qm, struct qman_cgr *cgr,
7244 +
7245 + int congested)
7246 +{
7247 + struct dpa_priv_s *priv = (struct dpa_priv_s *)container_of(cgr,
7248 + struct dpa_priv_s, cgr_data.cgr);
7249 +
7250 + if (congested) {
7251 + priv->cgr_data.congestion_start_jiffies = jiffies;
7252 + netif_tx_stop_all_queues(priv->net_dev);
7253 + priv->cgr_data.cgr_congested_count++;
7254 + } else {
7255 + priv->cgr_data.congested_jiffies +=
7256 + (jiffies - priv->cgr_data.congestion_start_jiffies);
7257 + netif_tx_wake_all_queues(priv->net_dev);
7258 + }
7259 +}
7260 +
7261 +int dpaa_eth_cgr_init(struct dpa_priv_s *priv)
7262 +{
7263 + struct qm_mcc_initcgr initcgr;
7264 + u32 cs_th;
7265 + int err;
7266 +
7267 + err = qman_alloc_cgrid(&priv->cgr_data.cgr.cgrid);
7268 + if (err < 0) {
7269 + pr_err("Error %d allocating CGR ID\n", err);
7270 + goto out_error;
7271 + }
7272 + priv->cgr_data.cgr.cb = dpaa_eth_cgscn;
7273 +
7274 + /* Enable Congestion State Change Notifications and CS taildrop */
7275 + initcgr.we_mask = QM_CGR_WE_CSCN_EN | QM_CGR_WE_CS_THRES;
7276 + initcgr.cgr.cscn_en = QM_CGR_EN;
7277 +
7278 + /* Set different thresholds based on the MAC speed.
7279 + * TODO: this may turn suboptimal if the MAC is reconfigured at a speed
7280 + * lower than its max, e.g. if a dTSEC later negotiates a 100Mbps link.
7281 + * In such cases, we ought to reconfigure the threshold, too.
7282 + */
7283 + if (priv->mac_dev->if_support & SUPPORTED_10000baseT_Full)
7284 + cs_th = CONFIG_FSL_DPAA_CS_THRESHOLD_10G;
7285 + else
7286 + cs_th = CONFIG_FSL_DPAA_CS_THRESHOLD_1G;
7287 + qm_cgr_cs_thres_set64(&initcgr.cgr.cs_thres, cs_th, 1);
7288 +
7289 + initcgr.we_mask |= QM_CGR_WE_CSTD_EN;
7290 + initcgr.cgr.cstd_en = QM_CGR_EN;
7291 +
7292 + err = qman_create_cgr(&priv->cgr_data.cgr, QMAN_CGR_FLAG_USE_INIT,
7293 + &initcgr);
7294 + if (err < 0) {
7295 + pr_err("Error %d creating CGR with ID %d\n", err,
7296 + priv->cgr_data.cgr.cgrid);
7297 + qman_release_cgrid(priv->cgr_data.cgr.cgrid);
7298 + goto out_error;
7299 + }
7300 + pr_debug("Created CGR %d for netdev with hwaddr %pM on QMan channel %d\n",
7301 + priv->cgr_data.cgr.cgrid, priv->mac_dev->addr,
7302 + priv->cgr_data.cgr.chan);
7303 +
7304 +out_error:
7305 + return err;
7306 +}
7307 +EXPORT_SYMBOL(dpaa_eth_cgr_init);
7308 +
7309 +static inline void dpa_setup_ingress(const struct dpa_priv_s *priv,
7310 + struct dpa_fq *fq,
7311 + const struct qman_fq *template)
7312 +{
7313 + fq->fq_base = *template;
7314 + fq->net_dev = priv->net_dev;
7315 +
7316 + fq->flags = QMAN_FQ_FLAG_NO_ENQUEUE;
7317 + fq->channel = priv->channel;
7318 +}
7319 +
7320 +static inline void dpa_setup_egress(const struct dpa_priv_s *priv,
7321 + struct dpa_fq *fq,
7322 + struct fm_port *port,
7323 + const struct qman_fq *template)
7324 +{
7325 + fq->fq_base = *template;
7326 + fq->net_dev = priv->net_dev;
7327 +
7328 + if (port) {
7329 + fq->flags = QMAN_FQ_FLAG_TO_DCPORTAL;
7330 + fq->channel = (uint16_t)fm_get_tx_port_channel(port);
7331 + } else {
7332 + fq->flags = QMAN_FQ_FLAG_NO_MODIFY;
7333 + }
7334 +}
7335 +
7336 +void dpa_fq_setup(struct dpa_priv_s *priv, const struct dpa_fq_cbs_t *fq_cbs,
7337 + struct fm_port *tx_port)
7338 +{
7339 + struct dpa_fq *fq;
7340 + uint16_t portals[NR_CPUS];
7341 + int cpu, portal_cnt = 0, num_portals = 0;
7342 + uint32_t pcd_fqid, pcd_fqid_hi_prio;
7343 + const cpumask_t *affine_cpus = qman_affine_cpus();
7344 + int egress_cnt = 0, conf_cnt = 0;
7345 +
7346 + /* Prepare for PCD FQs init */
7347 + for_each_cpu(cpu, affine_cpus)
7348 + portals[num_portals++] = qman_affine_channel(cpu);
7349 + if (num_portals == 0)
7350 + dev_err(priv->net_dev->dev.parent,
7351 + "No Qman software (affine) channels found");
7352 +
7353 + pcd_fqid = (priv->mac_dev) ?
7354 + DPAA_ETH_PCD_FQ_BASE(priv->mac_dev->res->start) : 0;
7355 + pcd_fqid_hi_prio = (priv->mac_dev) ?
7356 + DPAA_ETH_PCD_FQ_HI_PRIO_BASE(priv->mac_dev->res->start) : 0;
7357 +
7358 + /* Initialize each FQ in the list */
7359 + list_for_each_entry(fq, &priv->dpa_fq_list, list) {
7360 + switch (fq->fq_type) {
7361 + case FQ_TYPE_RX_DEFAULT:
7362 + BUG_ON(!priv->mac_dev);
7363 + dpa_setup_ingress(priv, fq, &fq_cbs->rx_defq);
7364 + break;
7365 + case FQ_TYPE_RX_ERROR:
7366 + BUG_ON(!priv->mac_dev);
7367 + dpa_setup_ingress(priv, fq, &fq_cbs->rx_errq);
7368 + break;
7369 + case FQ_TYPE_RX_PCD:
7370 + /* For MACless we can't have dynamic Rx queues */
7371 + BUG_ON(!priv->mac_dev && !fq->fqid);
7372 + dpa_setup_ingress(priv, fq, &fq_cbs->rx_defq);
7373 + if (!fq->fqid)
7374 + fq->fqid = pcd_fqid++;
7375 + fq->channel = portals[portal_cnt];
7376 + portal_cnt = (portal_cnt + 1) % num_portals;
7377 + break;
7378 + case FQ_TYPE_RX_PCD_HI_PRIO:
7379 + /* For MACless we can't have dynamic Hi Pri Rx queues */
7380 + BUG_ON(!priv->mac_dev && !fq->fqid);
7381 + dpa_setup_ingress(priv, fq, &fq_cbs->rx_defq);
7382 + if (!fq->fqid)
7383 + fq->fqid = pcd_fqid_hi_prio++;
7384 + fq->channel = portals[portal_cnt];
7385 + portal_cnt = (portal_cnt + 1) % num_portals;
7386 + break;
7387 + case FQ_TYPE_TX:
7388 + dpa_setup_egress(priv, fq, tx_port,
7389 + &fq_cbs->egress_ern);
7390 + /* If we have more Tx queues than the number of cores,
7391 + * just ignore the extra ones.
7392 + */
7393 + if (egress_cnt < DPAA_ETH_TX_QUEUES)
7394 + priv->egress_fqs[egress_cnt++] = &fq->fq_base;
7395 + break;
7396 + case FQ_TYPE_TX_CONFIRM:
7397 + BUG_ON(!priv->mac_dev);
7398 + dpa_setup_ingress(priv, fq, &fq_cbs->tx_defq);
7399 + break;
7400 + case FQ_TYPE_TX_CONF_MQ:
7401 + BUG_ON(!priv->mac_dev);
7402 + dpa_setup_ingress(priv, fq, &fq_cbs->tx_defq);
7403 + priv->conf_fqs[conf_cnt++] = &fq->fq_base;
7404 + break;
7405 + case FQ_TYPE_TX_ERROR:
7406 + BUG_ON(!priv->mac_dev);
7407 + dpa_setup_ingress(priv, fq, &fq_cbs->tx_errq);
7408 + break;
7409 + default:
7410 + dev_warn(priv->net_dev->dev.parent,
7411 + "Unknown FQ type detected!\n");
7412 + break;
7413 + }
7414 + }
7415 +
7416 + /* The number of Tx queues may be smaller than the number of cores, if
7417 + * the Tx queue range is specified in the device tree instead of being
7418 + * dynamically allocated.
7419 + * Make sure all CPUs receive a corresponding Tx queue.
7420 + */
7421 + while (egress_cnt < DPAA_ETH_TX_QUEUES) {
7422 + list_for_each_entry(fq, &priv->dpa_fq_list, list) {
7423 + if (fq->fq_type != FQ_TYPE_TX)
7424 + continue;
7425 + priv->egress_fqs[egress_cnt++] = &fq->fq_base;
7426 + if (egress_cnt == DPAA_ETH_TX_QUEUES)
7427 + break;
7428 + }
7429 + }
7430 +}
7431 +EXPORT_SYMBOL(dpa_fq_setup);
7432 +
7433 +int dpa_fq_init(struct dpa_fq *dpa_fq, bool td_enable)
7434 +{
7435 + int _errno;
7436 + const struct dpa_priv_s *priv;
7437 + struct device *dev;
7438 + struct qman_fq *fq;
7439 + struct qm_mcc_initfq initfq;
7440 + struct qman_fq *confq;
7441 + int queue_id;
7442 +
7443 + priv = netdev_priv(dpa_fq->net_dev);
7444 + dev = dpa_fq->net_dev->dev.parent;
7445 +
7446 + if (dpa_fq->fqid == 0)
7447 + dpa_fq->flags |= QMAN_FQ_FLAG_DYNAMIC_FQID;
7448 +
7449 + dpa_fq->init = !(dpa_fq->flags & QMAN_FQ_FLAG_NO_MODIFY);
7450 +
7451 + _errno = qman_create_fq(dpa_fq->fqid, dpa_fq->flags, &dpa_fq->fq_base);
7452 + if (_errno) {
7453 + dev_err(dev, "qman_create_fq() failed\n");
7454 + return _errno;
7455 + }
7456 + fq = &dpa_fq->fq_base;
7457 +
7458 + if (dpa_fq->init) {
7459 + memset(&initfq, 0, sizeof(initfq));
7460 +
7461 + initfq.we_mask = QM_INITFQ_WE_FQCTRL;
7462 + /* FIXME: why would we want to keep an empty FQ in cache? */
7463 + initfq.fqd.fq_ctrl = QM_FQCTRL_PREFERINCACHE;
7464 +
7465 + /* Try to reduce the number of portal interrupts for
7466 + * Tx Confirmation FQs.
7467 + */
7468 + if (dpa_fq->fq_type == FQ_TYPE_TX_CONFIRM)
7469 + initfq.fqd.fq_ctrl |= QM_FQCTRL_HOLDACTIVE;
7470 +
7471 + /* FQ placement */
7472 + initfq.we_mask |= QM_INITFQ_WE_DESTWQ;
7473 +
7474 + initfq.fqd.dest.channel = dpa_fq->channel;
7475 + initfq.fqd.dest.wq = dpa_fq->wq;
7476 +
7477 + /* Put all egress queues in a congestion group of their own.
7478 + * Sensu stricto, the Tx confirmation queues are Rx FQs,
7479 + * rather than Tx - but they nonetheless account for the
7480 + * memory footprint on behalf of egress traffic. We therefore
7481 + * place them in the netdev's CGR, along with the Tx FQs.
7482 + */
7483 + if (dpa_fq->fq_type == FQ_TYPE_TX ||
7484 + dpa_fq->fq_type == FQ_TYPE_TX_CONFIRM ||
7485 + dpa_fq->fq_type == FQ_TYPE_TX_CONF_MQ) {
7486 + initfq.we_mask |= QM_INITFQ_WE_CGID;
7487 + initfq.fqd.fq_ctrl |= QM_FQCTRL_CGE;
7488 + initfq.fqd.cgid = (uint8_t)priv->cgr_data.cgr.cgrid;
7489 + /* Set a fixed overhead accounting, in an attempt to
7490 + * reduce the impact of fixed-size skb shells and the
7491 + * driver's needed headroom on system memory. This is
7492 + * especially the case when the egress traffic is
7493 + * composed of small datagrams.
7494 + * Unfortunately, QMan's OAL value is capped to an
7495 + * insufficient value, but even that is better than
7496 + * no overhead accounting at all.
7497 + */
7498 + initfq.we_mask |= QM_INITFQ_WE_OAC;
7499 + initfq.fqd.oac_init.oac = QM_OAC_CG;
7500 + initfq.fqd.oac_init.oal =
7501 + (signed char)(min(sizeof(struct sk_buff) +
7502 + priv->tx_headroom, (size_t)FSL_QMAN_MAX_OAL));
7503 + }
7504 +
7505 + if (td_enable) {
7506 + initfq.we_mask |= QM_INITFQ_WE_TDTHRESH;
7507 + qm_fqd_taildrop_set(&initfq.fqd.td,
7508 + DPA_FQ_TD, 1);
7509 + initfq.fqd.fq_ctrl = QM_FQCTRL_TDE;
7510 + }
7511 +
7512 + /* Configure the Tx confirmation queue, now that we know
7513 + * which Tx queue it pairs with.
7514 + */
7515 + if (dpa_fq->fq_type == FQ_TYPE_TX) {
7516 + queue_id = _dpa_tx_fq_to_id(priv, &dpa_fq->fq_base);
7517 + if (queue_id >= 0) {
7518 + confq = priv->conf_fqs[queue_id];
7519 + if (confq) {
7520 + initfq.we_mask |= QM_INITFQ_WE_CONTEXTA;
7521 + /* ContextA: OVOM=1 (use contextA2 bits instead of ICAD)
7522 + * A2V=1 (contextA A2 field is valid)
7523 + * A0V=1 (contextA A0 field is valid)
7524 + * B0V=1 (contextB field is valid)
7525 + * ContextA A2: EBD=1 (deallocate buffers inside FMan)
7526 + * ContextB B0(ASPID): 0 (absolute Virtual Storage ID)
7527 + */
7528 + initfq.fqd.context_a.hi = 0x1e000000;
7529 + initfq.fqd.context_a.lo = 0x80000000;
7530 + }
7531 + }
7532 + }
7533 +
7534 + /* Put all *private* ingress queues in our "ingress CGR". */
7535 + if (priv->use_ingress_cgr &&
7536 + (dpa_fq->fq_type == FQ_TYPE_RX_DEFAULT ||
7537 + dpa_fq->fq_type == FQ_TYPE_RX_ERROR ||
7538 + dpa_fq->fq_type == FQ_TYPE_RX_PCD ||
7539 + dpa_fq->fq_type == FQ_TYPE_RX_PCD_HI_PRIO)) {
7540 + initfq.we_mask |= QM_INITFQ_WE_CGID;
7541 + initfq.fqd.fq_ctrl |= QM_FQCTRL_CGE;
7542 + initfq.fqd.cgid = (uint8_t)priv->ingress_cgr.cgrid;
7543 + /* Set a fixed overhead accounting, just like for the
7544 + * egress CGR.
7545 + */
7546 + initfq.we_mask |= QM_INITFQ_WE_OAC;
7547 + initfq.fqd.oac_init.oac = QM_OAC_CG;
7548 + initfq.fqd.oac_init.oal =
7549 + (signed char)(min(sizeof(struct sk_buff) +
7550 + priv->tx_headroom, (size_t)FSL_QMAN_MAX_OAL));
7551 + }
7552 +
7553 + /* Initialization common to all ingress queues */
7554 + if (dpa_fq->flags & QMAN_FQ_FLAG_NO_ENQUEUE) {
7555 + initfq.we_mask |= QM_INITFQ_WE_CONTEXTA;
7556 + initfq.fqd.fq_ctrl |=
7557 + QM_FQCTRL_CTXASTASHING | QM_FQCTRL_AVOIDBLOCK;
7558 + initfq.fqd.context_a.stashing.exclusive =
7559 + QM_STASHING_EXCL_DATA | QM_STASHING_EXCL_CTX |
7560 + QM_STASHING_EXCL_ANNOTATION;
7561 + initfq.fqd.context_a.stashing.data_cl = 2;
7562 + initfq.fqd.context_a.stashing.annotation_cl = 1;
7563 + initfq.fqd.context_a.stashing.context_cl =
7564 + DIV_ROUND_UP(sizeof(struct qman_fq), 64);
7565 + }
7566 +
7567 + _errno = qman_init_fq(fq, QMAN_INITFQ_FLAG_SCHED, &initfq);
7568 + if (_errno < 0) {
7569 + if (DPA_RX_PCD_HI_PRIO_FQ_INIT_FAIL(dpa_fq, _errno)) {
7570 + dpa_fq->init = 0;
7571 + } else {
7572 + dev_err(dev, "qman_init_fq(%u) = %d\n",
7573 + qman_fq_fqid(fq), _errno);
7574 + qman_destroy_fq(fq, 0);
7575 + }
7576 + return _errno;
7577 + }
7578 + }
7579 +
7580 + dpa_fq->fqid = qman_fq_fqid(fq);
7581 +
7582 + return 0;
7583 +}
7584 +EXPORT_SYMBOL(dpa_fq_init);
7585 +
7586 +int __cold __attribute__((nonnull))
7587 +_dpa_fq_free(struct device *dev, struct qman_fq *fq)
7588 +{
7589 + int _errno, __errno;
7590 + struct dpa_fq *dpa_fq;
7591 + const struct dpa_priv_s *priv;
7592 +
7593 + _errno = 0;
7594 +
7595 + dpa_fq = container_of(fq, struct dpa_fq, fq_base);
7596 + priv = netdev_priv(dpa_fq->net_dev);
7597 +
7598 + if (dpa_fq->init) {
7599 + _errno = qman_retire_fq(fq, NULL);
7600 + if (unlikely(_errno < 0) && netif_msg_drv(priv))
7601 + dev_err(dev, "qman_retire_fq(%u) = %d\n",
7602 + qman_fq_fqid(fq), _errno);
7603 +
7604 + __errno = qman_oos_fq(fq);
7605 + if (unlikely(__errno < 0) && netif_msg_drv(priv)) {
7606 + dev_err(dev, "qman_oos_fq(%u) = %d\n",
7607 + qman_fq_fqid(fq), __errno);
7608 + if (_errno >= 0)
7609 + _errno = __errno;
7610 + }
7611 + }
7612 +
7613 + qman_destroy_fq(fq, 0);
7614 + list_del(&dpa_fq->list);
7615 +
7616 + return _errno;
7617 +}
7618 +EXPORT_SYMBOL(_dpa_fq_free);
7619 +
7620 +int __cold __attribute__((nonnull))
7621 +dpa_fq_free(struct device *dev, struct list_head *list)
7622 +{
7623 + int _errno, __errno;
7624 + struct dpa_fq *dpa_fq, *tmp;
7625 +
7626 + _errno = 0;
7627 + list_for_each_entry_safe(dpa_fq, tmp, list, list) {
7628 + __errno = _dpa_fq_free(dev, (struct qman_fq *)dpa_fq);
7629 + if (unlikely(__errno < 0) && _errno >= 0)
7630 + _errno = __errno;
7631 + }
7632 +
7633 + return _errno;
7634 +}
7635 +EXPORT_SYMBOL(dpa_fq_free);
7636 +
7637 +int dpa_fqs_init(struct device *dev, struct list_head *list, bool td_enable)
7638 +{
7639 + int _errno, __errno;
7640 + struct dpa_fq *dpa_fq, *tmp;
7641 + static bool print_msg __read_mostly;
7642 +
7643 + _errno = 0;
7644 + print_msg = true;
7645 + list_for_each_entry_safe(dpa_fq, tmp, list, list) {
7646 + __errno = dpa_fq_init(dpa_fq, td_enable);
7647 + if (unlikely(__errno < 0) && _errno >= 0) {
7648 + if (DPA_RX_PCD_HI_PRIO_FQ_INIT_FAIL(dpa_fq, __errno)) {
7649 + if (print_msg) {
7650 + dev_warn(dev,
7651 + "Skip RX PCD High Priority FQs initialization\n");
7652 + print_msg = false;
7653 + }
7654 + if (_dpa_fq_free(dev, (struct qman_fq *)dpa_fq))
7655 + dev_warn(dev,
7656 + "Error freeing frame queues\n");
7657 + } else {
7658 + _errno = __errno;
7659 + break;
7660 + }
7661 + }
7662 + }
7663 +
7664 + return _errno;
7665 +}
7666 +EXPORT_SYMBOL(dpa_fqs_init);
7667 +static void
7668 +dpaa_eth_init_tx_port(struct fm_port *port, struct dpa_fq *errq,
7669 + struct dpa_fq *defq, struct dpa_buffer_layout_s *buf_layout)
7670 +{
7671 + struct fm_port_params tx_port_param;
7672 + bool frag_enabled = false;
7673 +
7674 + memset(&tx_port_param, 0, sizeof(tx_port_param));
7675 + dpaa_eth_init_port(tx, port, tx_port_param, errq->fqid, defq->fqid,
7676 + buf_layout, frag_enabled);
7677 +}
7678 +
7679 +static void
7680 +dpaa_eth_init_rx_port(struct fm_port *port, struct dpa_bp *bp, size_t count,
7681 + struct dpa_fq *errq, struct dpa_fq *defq,
7682 + struct dpa_buffer_layout_s *buf_layout)
7683 +{
7684 + struct fm_port_params rx_port_param;
7685 + int i;
7686 + bool frag_enabled = false;
7687 +
7688 + memset(&rx_port_param, 0, sizeof(rx_port_param));
7689 + count = min(ARRAY_SIZE(rx_port_param.pool_param), count);
7690 + rx_port_param.num_pools = (uint8_t)count;
7691 + for (i = 0; i < count; i++) {
7692 + if (i >= rx_port_param.num_pools)
7693 + break;
7694 + rx_port_param.pool_param[i].id = bp[i].bpid;
7695 + rx_port_param.pool_param[i].size = (uint16_t)bp[i].size;
7696 + }
7697 +
7698 + dpaa_eth_init_port(rx, port, rx_port_param, errq->fqid, defq->fqid,
7699 + buf_layout, frag_enabled);
7700 +}
7701 +
7702 +#if defined(CONFIG_FSL_SDK_FMAN_TEST)
7703 +/* Defined as weak, to be implemented by fman pcd tester. */
7704 +int dpa_alloc_pcd_fqids(struct device *, uint32_t, uint8_t, uint32_t *)
7705 +__attribute__((weak));
7706 +
7707 +int dpa_free_pcd_fqids(struct device *, uint32_t) __attribute__((weak));
7708 +#else
7709 +int dpa_alloc_pcd_fqids(struct device *, uint32_t, uint8_t, uint32_t *);
7710 +
7711 +int dpa_free_pcd_fqids(struct device *, uint32_t);
7712 +
7713 +#endif /* CONFIG_FSL_SDK_FMAN_TEST */
7714 +
7715 +
7716 +int dpa_alloc_pcd_fqids(struct device *dev, uint32_t num,
7717 + uint8_t alignment, uint32_t *base_fqid)
7718 +{
7719 + dev_crit(dev, "callback not implemented!\n");
7720 +
7721 + return 0;
7722 +}
7723 +
7724 +int dpa_free_pcd_fqids(struct device *dev, uint32_t base_fqid)
7725 +{
7726 +
7727 + dev_crit(dev, "callback not implemented!\n");
7728 +
7729 + return 0;
7730 +}
7731 +
7732 +void dpaa_eth_init_ports(struct mac_device *mac_dev,
7733 + struct dpa_bp *bp, size_t count,
7734 + struct fm_port_fqs *port_fqs,
7735 + struct dpa_buffer_layout_s *buf_layout,
7736 + struct device *dev)
7737 +{
7738 + struct fm_port_pcd_param rx_port_pcd_param;
7739 + struct fm_port *rxport = mac_dev->port_dev[RX];
7740 + struct fm_port *txport = mac_dev->port_dev[TX];
7741 +
7742 + dpaa_eth_init_tx_port(txport, port_fqs->tx_errq,
7743 + port_fqs->tx_defq, &buf_layout[TX]);
7744 + dpaa_eth_init_rx_port(rxport, bp, count, port_fqs->rx_errq,
7745 + port_fqs->rx_defq, &buf_layout[RX]);
7746 +
7747 + rx_port_pcd_param.cba = dpa_alloc_pcd_fqids;
7748 + rx_port_pcd_param.cbf = dpa_free_pcd_fqids;
7749 + rx_port_pcd_param.dev = dev;
7750 + fm_port_pcd_bind(rxport, &rx_port_pcd_param);
7751 +}
7752 +EXPORT_SYMBOL(dpaa_eth_init_ports);
7753 +
7754 +void dpa_release_sgt(struct qm_sg_entry *sgt)
7755 +{
7756 + struct dpa_bp *dpa_bp;
7757 + struct bm_buffer bmb[DPA_BUFF_RELEASE_MAX];
7758 + uint8_t i = 0, j;
7759 +
7760 + memset(bmb, 0, DPA_BUFF_RELEASE_MAX * sizeof(struct bm_buffer));
7761 +
7762 + do {
7763 + dpa_bp = dpa_bpid2pool(qm_sg_entry_get_bpid(&sgt[i]));
7764 + DPA_BUG_ON(!dpa_bp);
7765 +
7766 + j = 0;
7767 + do {
7768 + DPA_BUG_ON(qm_sg_entry_get_ext(&sgt[i]));
7769 + bm_buffer_set64(&bmb[j], qm_sg_addr(&sgt[i]));
7770 +
7771 + j++; i++;
7772 + } while (j < ARRAY_SIZE(bmb) &&
7773 + !qm_sg_entry_get_final(&sgt[i-1]) &&
7774 + qm_sg_entry_get_bpid(&sgt[i-1]) ==
7775 + qm_sg_entry_get_bpid(&sgt[i]));
7776 +
7777 + while (bman_release(dpa_bp->pool, bmb, j, 0))
7778 + cpu_relax();
7779 + } while (!qm_sg_entry_get_final(&sgt[i-1]));
7780 +}
7781 +EXPORT_SYMBOL(dpa_release_sgt);
7782 +
7783 +void __attribute__((nonnull))
7784 +dpa_fd_release(const struct net_device *net_dev, const struct qm_fd *fd)
7785 +{
7786 + struct qm_sg_entry *sgt;
7787 + struct dpa_bp *dpa_bp;
7788 + struct bm_buffer bmb;
7789 + dma_addr_t addr;
7790 + void *vaddr;
7791 +
7792 + bmb.opaque = 0;
7793 + bm_buffer_set64(&bmb, qm_fd_addr(fd));
7794 +
7795 + dpa_bp = dpa_bpid2pool(fd->bpid);
7796 + DPA_BUG_ON(!dpa_bp);
7797 +
7798 + if (fd->format == qm_fd_sg) {
7799 + vaddr = phys_to_virt(qm_fd_addr(fd));
7800 + sgt = vaddr + dpa_fd_offset(fd);
7801 +
7802 + dma_unmap_single(dpa_bp->dev, qm_fd_addr(fd), dpa_bp->size,
7803 + DMA_BIDIRECTIONAL);
7804 +
7805 + dpa_release_sgt(sgt);
7806 + addr = dma_map_single(dpa_bp->dev, vaddr, dpa_bp->size,
7807 + DMA_BIDIRECTIONAL);
7808 + if (unlikely(dma_mapping_error(dpa_bp->dev, addr))) {
7809 + dev_err(dpa_bp->dev, "DMA mapping failed");
7810 + return;
7811 + }
7812 + bm_buffer_set64(&bmb, addr);
7813 + }
7814 +
7815 + while (bman_release(dpa_bp->pool, &bmb, 1, 0))
7816 + cpu_relax();
7817 +}
7818 +EXPORT_SYMBOL(dpa_fd_release);
7819 +
7820 +void count_ern(struct dpa_percpu_priv_s *percpu_priv,
7821 + const struct qm_mr_entry *msg)
7822 +{
7823 + switch (msg->ern.rc & QM_MR_RC_MASK) {
7824 + case QM_MR_RC_CGR_TAILDROP:
7825 + percpu_priv->ern_cnt.cg_tdrop++;
7826 + break;
7827 + case QM_MR_RC_WRED:
7828 + percpu_priv->ern_cnt.wred++;
7829 + break;
7830 + case QM_MR_RC_ERROR:
7831 + percpu_priv->ern_cnt.err_cond++;
7832 + break;
7833 + case QM_MR_RC_ORPWINDOW_EARLY:
7834 + percpu_priv->ern_cnt.early_window++;
7835 + break;
7836 + case QM_MR_RC_ORPWINDOW_LATE:
7837 + percpu_priv->ern_cnt.late_window++;
7838 + break;
7839 + case QM_MR_RC_FQ_TAILDROP:
7840 + percpu_priv->ern_cnt.fq_tdrop++;
7841 + break;
7842 + case QM_MR_RC_ORPWINDOW_RETIRED:
7843 + percpu_priv->ern_cnt.fq_retired++;
7844 + break;
7845 + case QM_MR_RC_ORP_ZERO:
7846 + percpu_priv->ern_cnt.orp_zero++;
7847 + break;
7848 + }
7849 +}
7850 +EXPORT_SYMBOL(count_ern);
7851 +
7852 +/**
7853 + * Turn on HW checksum computation for this outgoing frame.
7854 + * If the current protocol is not something we support in this regard
7855 + * (or if the stack has already computed the SW checksum), we do nothing.
7856 + *
7857 + * Returns 0 if all goes well (or HW csum doesn't apply), and a negative value
7858 + * otherwise.
7859 + *
7860 + * Note that this function may modify the fd->cmd field and the skb data buffer
7861 + * (the Parse Results area).
7862 + */
7863 +int dpa_enable_tx_csum(struct dpa_priv_s *priv,
7864 + struct sk_buff *skb, struct qm_fd *fd, char *parse_results)
7865 +{
7866 + fm_prs_result_t *parse_result;
7867 + struct iphdr *iph;
7868 + struct ipv6hdr *ipv6h = NULL;
7869 + u8 l4_proto;
7870 + u16 ethertype = ntohs(skb->protocol);
7871 + int retval = 0;
7872 +
7873 + if (skb->ip_summed != CHECKSUM_PARTIAL)
7874 + return 0;
7875 +
7876 + /* Note: L3 csum seems to be already computed in sw, but we can't choose
7877 + * L4 alone from the FM configuration anyway.
7878 + */
7879 +
7880 + /* Fill in some fields of the Parse Results array, so the FMan
7881 + * can find them as if they came from the FMan Parser.
7882 + */
7883 + parse_result = (fm_prs_result_t *)parse_results;
7884 +
7885 + /* If we're dealing with VLAN, get the real Ethernet type */
7886 + if (ethertype == ETH_P_8021Q) {
7887 + /* We can't always assume the MAC header is set correctly
7888 + * by the stack, so reset to beginning of skb->data
7889 + */
7890 + skb_reset_mac_header(skb);
7891 + ethertype = ntohs(vlan_eth_hdr(skb)->h_vlan_encapsulated_proto);
7892 + }
7893 +
7894 + /* Fill in the relevant L3 parse result fields
7895 + * and read the L4 protocol type
7896 + */
7897 + switch (ethertype) {
7898 + case ETH_P_IP:
7899 + parse_result->l3r = cpu_to_be16(FM_L3_PARSE_RESULT_IPV4);
7900 + iph = ip_hdr(skb);
7901 + DPA_BUG_ON(iph == NULL);
7902 + l4_proto = iph->protocol;
7903 + break;
7904 + case ETH_P_IPV6:
7905 + parse_result->l3r = cpu_to_be16(FM_L3_PARSE_RESULT_IPV6);
7906 + ipv6h = ipv6_hdr(skb);
7907 + DPA_BUG_ON(ipv6h == NULL);
7908 + l4_proto = ipv6h->nexthdr;
7909 + break;
7910 + default:
7911 + /* We shouldn't even be here */
7912 + if (netif_msg_tx_err(priv) && net_ratelimit())
7913 + netdev_alert(priv->net_dev,
7914 + "Can't compute HW csum for L3 proto 0x%x\n",
7915 + ntohs(skb->protocol));
7916 + retval = -EIO;
7917 + goto return_error;
7918 + }
7919 +
7920 + /* Fill in the relevant L4 parse result fields */
7921 + switch (l4_proto) {
7922 + case IPPROTO_UDP:
7923 + parse_result->l4r = FM_L4_PARSE_RESULT_UDP;
7924 + break;
7925 + case IPPROTO_TCP:
7926 + parse_result->l4r = FM_L4_PARSE_RESULT_TCP;
7927 + break;
7928 + default:
7929 + /* This can as well be a BUG() */
7930 + if (netif_msg_tx_err(priv) && net_ratelimit())
7931 + netdev_alert(priv->net_dev,
7932 + "Can't compute HW csum for L4 proto 0x%x\n",
7933 + l4_proto);
7934 + retval = -EIO;
7935 + goto return_error;
7936 + }
7937 +
7938 + /* At index 0 is IPOffset_1 as defined in the Parse Results */
7939 + parse_result->ip_off[0] = (uint8_t)skb_network_offset(skb);
7940 + parse_result->l4_off = (uint8_t)skb_transport_offset(skb);
7941 +
7942 + /* Enable L3 (and L4, if TCP or UDP) HW checksum. */
7943 + fd->cmd |= FM_FD_CMD_RPD | FM_FD_CMD_DTC;
7944 +
7945 + /* On P1023 and similar platforms fd->cmd interpretation could
7946 + * be disabled by setting CONTEXT_A bit ICMD; currently this bit
7947 + * is not set so we do not need to check; in the future, if/when
7948 + * using context_a we need to check this bit
7949 + */
7950 +
7951 +return_error:
7952 + return retval;
7953 +}
7954 +EXPORT_SYMBOL(dpa_enable_tx_csum);
7955 +
7956 +#ifdef CONFIG_FSL_DPAA_CEETM
7957 +void dpa_enable_ceetm(struct net_device *dev)
7958 +{
7959 + struct dpa_priv_s *priv = netdev_priv(dev);
7960 + priv->ceetm_en = true;
7961 +}
7962 +EXPORT_SYMBOL(dpa_enable_ceetm);
7963 +
7964 +void dpa_disable_ceetm(struct net_device *dev)
7965 +{
7966 + struct dpa_priv_s *priv = netdev_priv(dev);
7967 + priv->ceetm_en = false;
7968 +}
7969 +EXPORT_SYMBOL(dpa_disable_ceetm);
7970 +#endif
7971 --- /dev/null
7972 +++ b/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_common.h
7973 @@ -0,0 +1,225 @@
7974 +/* Copyright 2008-2013 Freescale Semiconductor, Inc.
7975 + *
7976 + * Redistribution and use in source and binary forms, with or without
7977 + * modification, are permitted provided that the following conditions are met:
7978 + * * Redistributions of source code must retain the above copyright
7979 + * notice, this list of conditions and the following disclaimer.
7980 + * * Redistributions in binary form must reproduce the above copyright
7981 + * notice, this list of conditions and the following disclaimer in the
7982 + * documentation and/or other materials provided with the distribution.
7983 + * * Neither the name of Freescale Semiconductor nor the
7984 + * names of its contributors may be used to endorse or promote products
7985 + * derived from this software without specific prior written permission.
7986 + *
7987 + *
7988 + * ALTERNATIVELY, this software may be distributed under the terms of the
7989 + * GNU General Public License ("GPL") as published by the Free Software
7990 + * Foundation, either version 2 of that License or (at your option) any
7991 + * later version.
7992 + *
7993 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
7994 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
7995 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
7996 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
7997 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
7998 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
7999 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
8000 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
8001 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
8002 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
8003 + */
8004 +
8005 +#ifndef __DPAA_ETH_COMMON_H
8006 +#define __DPAA_ETH_COMMON_H
8007 +
8008 +#include <linux/etherdevice.h> /* struct net_device */
8009 +#include <linux/fsl_bman.h> /* struct bm_buffer */
8010 +#include <linux/of_platform.h> /* struct platform_device */
8011 +#include <linux/net_tstamp.h> /* struct hwtstamp_config */
8012 +
8013 +#include "dpaa_eth.h"
8014 +#include "lnxwrp_fsl_fman.h"
8015 +
8016 +#define dpaa_eth_init_port(type, port, param, errq_id, defq_id, buf_layout,\
8017 + frag_enabled) \
8018 +{ \
8019 + param.errq = errq_id; \
8020 + param.defq = defq_id; \
8021 + param.priv_data_size = buf_layout->priv_data_size; \
8022 + param.parse_results = buf_layout->parse_results; \
8023 + param.hash_results = buf_layout->hash_results; \
8024 + param.frag_enable = frag_enabled; \
8025 + param.time_stamp = buf_layout->time_stamp; \
8026 + param.manip_extra_space = buf_layout->manip_extra_space; \
8027 + param.data_align = buf_layout->data_align; \
8028 + fm_set_##type##_port_params(port, &param); \
8029 +}
8030 +
8031 +#define DPA_SGT_MAX_ENTRIES 16 /* maximum number of entries in SG Table */
8032 +
8033 +#define DPA_SGT_ENTRIES_THRESHOLD DPA_SGT_MAX_ENTRIES
8034 +
8035 +#define DPA_BUFF_RELEASE_MAX 8 /* maximum number of buffers released at once */
8036 +
8037 +#define DPA_RX_PCD_HI_PRIO_FQ_INIT_FAIL(dpa_fq, _errno) \
8038 + (((dpa_fq)->fq_type == FQ_TYPE_RX_PCD_HI_PRIO) && \
8039 + (_errno == -EIO))
8040 +/* return codes for the dpaa-eth hooks */
8041 +enum dpaa_eth_hook_result {
8042 + /* fd/skb was retained by the hook.
8043 + *
8044 + * On the Rx path, this means the Ethernet driver will _not_
8045 + * deliver the skb to the stack. Instead, the hook implementation
8046 + * is expected to properly dispose of the skb.
8047 + *
8048 + * On the Tx path, the Ethernet driver's dpa_tx() function will
8049 + * immediately return NETDEV_TX_OK. The hook implementation is expected
8050 + * to free the skb. *DO*NOT* release it to BMan, or enqueue it to FMan,
8051 + * unless you know exactly what you're doing!
8052 + *
8053 + * On the confirmation/error paths, the Ethernet driver will _not_
8054 + * perform any fd cleanup, nor update the interface statistics.
8055 + */
8056 + DPAA_ETH_STOLEN,
8057 + /* fd/skb was returned to the Ethernet driver for regular processing.
8058 + * The hook is not allowed to, for instance, reallocate the skb (as if
8059 + * by linearizing, copying, cloning or reallocating the headroom).
8060 + */
8061 + DPAA_ETH_CONTINUE
8062 +};
8063 +
8064 +typedef enum dpaa_eth_hook_result (*dpaa_eth_ingress_hook_t)(
8065 + struct sk_buff *skb, struct net_device *net_dev, u32 fqid);
8066 +typedef enum dpaa_eth_hook_result (*dpaa_eth_egress_hook_t)(
8067 + struct sk_buff *skb, struct net_device *net_dev);
8068 +typedef enum dpaa_eth_hook_result (*dpaa_eth_confirm_hook_t)(
8069 + struct net_device *net_dev, const struct qm_fd *fd, u32 fqid);
8070 +
8071 +/* used in napi related functions */
8072 +extern u16 qman_portal_max;
8073 +
8074 +/* from dpa_ethtool.c */
8075 +extern const struct ethtool_ops dpa_ethtool_ops;
8076 +
8077 +#ifdef CONFIG_FSL_DPAA_HOOKS
8078 +/* Various hooks used for unit-testing and/or fastpath optimizations.
8079 + * Currently only one set of such hooks is supported.
8080 + */
8081 +struct dpaa_eth_hooks_s {
8082 + /* Invoked on the Tx private path, immediately after receiving the skb
8083 + * from the stack.
8084 + */
8085 + dpaa_eth_egress_hook_t tx;
8086 +
8087 + /* Invoked on the Rx private path, right before passing the skb
8088 + * up the stack. At that point, the packet's protocol id has already
8089 + * been set. The skb's data pointer is now at the L3 header, and
8090 + * skb->mac_header points to the L2 header. skb->len has been adjusted
8091 + * to be the length of L3+payload (i.e., the length of the
8092 + * original frame minus the L2 header len).
8093 + * For more details on what the skb looks like, see eth_type_trans().
8094 + */
8095 + dpaa_eth_ingress_hook_t rx_default;
8096 +
8097 + /* Driver hook for the Rx error private path. */
8098 + dpaa_eth_confirm_hook_t rx_error;
8099 + /* Driver hook for the Tx confirmation private path. */
8100 + dpaa_eth_confirm_hook_t tx_confirm;
8101 + /* Driver hook for the Tx error private path. */
8102 + dpaa_eth_confirm_hook_t tx_error;
8103 +};
8104 +
8105 +void fsl_dpaa_eth_set_hooks(struct dpaa_eth_hooks_s *hooks);
8106 +
8107 +extern struct dpaa_eth_hooks_s dpaa_eth_hooks;
8108 +#endif
8109 +
8110 +int dpa_netdev_init(struct net_device *net_dev,
8111 + const uint8_t *mac_addr,
8112 + uint16_t tx_timeout);
8113 +int __cold dpa_start(struct net_device *net_dev);
8114 +int __cold dpa_stop(struct net_device *net_dev);
8115 +void __cold dpa_timeout(struct net_device *net_dev);
8116 +struct rtnl_link_stats64 __cold
8117 +*dpa_get_stats64(struct net_device *net_dev,
8118 + struct rtnl_link_stats64 *stats);
8119 +int dpa_change_mtu(struct net_device *net_dev, int new_mtu);
8120 +int dpa_ndo_init(struct net_device *net_dev);
8121 +int dpa_set_features(struct net_device *dev, netdev_features_t features);
8122 +netdev_features_t dpa_fix_features(struct net_device *dev,
8123 + netdev_features_t features);
8124 +#ifdef CONFIG_FSL_DPAA_TS
8125 +u64 dpa_get_timestamp_ns(const struct dpa_priv_s *priv,
8126 + enum port_type rx_tx, const void *data);
8127 +/* Updates the skb shared hw timestamp from the hardware timestamp */
8128 +int dpa_get_ts(const struct dpa_priv_s *priv, enum port_type rx_tx,
8129 + struct skb_shared_hwtstamps *shhwtstamps, const void *data);
8130 +#endif /* CONFIG_FSL_DPAA_TS */
8131 +int dpa_ioctl(struct net_device *dev, struct ifreq *rq, int cmd);
8132 +int __cold dpa_remove(struct platform_device *of_dev);
8133 +struct mac_device * __cold __must_check
8134 +__attribute__((nonnull)) dpa_mac_probe(struct platform_device *_of_dev);
8135 +int dpa_set_mac_address(struct net_device *net_dev, void *addr);
8136 +void dpa_set_rx_mode(struct net_device *net_dev);
8137 +void dpa_set_buffers_layout(struct mac_device *mac_dev,
8138 + struct dpa_buffer_layout_s *layout);
8139 +int __attribute__((nonnull))
8140 +dpa_bp_alloc(struct dpa_bp *dpa_bp, struct device *dev);
8141 +void __cold __attribute__((nonnull))
8142 +dpa_bp_free(struct dpa_priv_s *priv);
8143 +struct dpa_bp *dpa_bpid2pool(int bpid);
8144 +void dpa_bpid2pool_map(int bpid, struct dpa_bp *dpa_bp);
8145 +bool dpa_bpid2pool_use(int bpid);
8146 +void dpa_bp_drain(struct dpa_bp *bp);
8147 +#ifdef CONFIG_FSL_DPAA_ETH_USE_NDO_SELECT_QUEUE
8148 +u16 dpa_select_queue(struct net_device *net_dev, struct sk_buff *skb,
8149 + void *accel_priv, select_queue_fallback_t fallback);
8150 +#endif
8151 +struct dpa_fq *dpa_fq_alloc(struct device *dev,
8152 + u32 fq_start,
8153 + u32 fq_count,
8154 + struct list_head *list,
8155 + enum dpa_fq_type fq_type);
8156 +int dpa_fq_probe_mac(struct device *dev, struct list_head *list,
8157 + struct fm_port_fqs *port_fqs,
8158 + bool tx_conf_fqs_per_core,
8159 + enum port_type ptype);
8160 +int dpa_get_channel(void);
8161 +void dpa_release_channel(void);
8162 +void dpaa_eth_add_channel(u16 channel);
8163 +int dpaa_eth_cgr_init(struct dpa_priv_s *priv);
8164 +void dpa_fq_setup(struct dpa_priv_s *priv, const struct dpa_fq_cbs_t *fq_cbs,
8165 + struct fm_port *tx_port);
8166 +int dpa_fq_init(struct dpa_fq *dpa_fq, bool td_enable);
8167 +int dpa_fqs_init(struct device *dev, struct list_head *list, bool td_enable);
8168 +int __cold __attribute__((nonnull))
8169 +dpa_fq_free(struct device *dev, struct list_head *list);
8170 +void dpaa_eth_init_ports(struct mac_device *mac_dev,
8171 + struct dpa_bp *bp, size_t count,
8172 + struct fm_port_fqs *port_fqs,
8173 + struct dpa_buffer_layout_s *buf_layout,
8174 + struct device *dev);
8175 +void dpa_release_sgt(struct qm_sg_entry *sgt);
8176 +void __attribute__((nonnull))
8177 +dpa_fd_release(const struct net_device *net_dev, const struct qm_fd *fd);
8178 +void count_ern(struct dpa_percpu_priv_s *percpu_priv,
8179 + const struct qm_mr_entry *msg);
8180 +int dpa_enable_tx_csum(struct dpa_priv_s *priv,
8181 + struct sk_buff *skb, struct qm_fd *fd, char *parse_results);
8182 +#ifdef CONFIG_FSL_DPAA_CEETM
8183 +void dpa_enable_ceetm(struct net_device *dev);
8184 +void dpa_disable_ceetm(struct net_device *dev);
8185 +#endif
8186 +struct proxy_device {
8187 + struct mac_device *mac_dev;
8188 +};
8189 +
8190 +/* mac device control functions exposed by proxy interface*/
8191 +int dpa_proxy_start(struct net_device *net_dev);
8192 +int dpa_proxy_stop(struct proxy_device *proxy_dev, struct net_device *net_dev);
8193 +int dpa_proxy_set_mac_address(struct proxy_device *proxy_dev,
8194 + struct net_device *net_dev);
8195 +int dpa_proxy_set_rx_mode(struct proxy_device *proxy_dev,
8196 + struct net_device *net_dev);
8197 +
8198 +#endif /* __DPAA_ETH_COMMON_H */
8199 --- /dev/null
8200 +++ b/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_proxy.c
8201 @@ -0,0 +1,381 @@
8202 +/* Copyright 2008-2013 Freescale Semiconductor Inc.
8203 + *
8204 + * Redistribution and use in source and binary forms, with or without
8205 + * modification, are permitted provided that the following conditions are met:
8206 + * * Redistributions of source code must retain the above copyright
8207 + * notice, this list of conditions and the following disclaimer.
8208 + * * Redistributions in binary form must reproduce the above copyright
8209 + * notice, this list of conditions and the following disclaimer in the
8210 + * documentation and/or other materials provided with the distribution.
8211 + * * Neither the name of Freescale Semiconductor nor the
8212 + * names of its contributors may be used to endorse or promote products
8213 + * derived from this software without specific prior written permission.
8214 + *
8215 + *
8216 + * ALTERNATIVELY, this software may be distributed under the terms of the
8217 + * GNU General Public License ("GPL") as published by the Free Software
8218 + * Foundation, either version 2 of that License or (at your option) any
8219 + * later version.
8220 + *
8221 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
8222 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
8223 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
8224 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
8225 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
8226 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
8227 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
8228 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
8229 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
8230 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
8231 + */
8232 +
8233 +#ifdef CONFIG_FSL_DPAA_ETH_DEBUG
8234 +#define pr_fmt(fmt) \
8235 + KBUILD_MODNAME ": %s:%hu:%s() " fmt, \
8236 + KBUILD_BASENAME".c", __LINE__, __func__
8237 +#else
8238 +#define pr_fmt(fmt) \
8239 + KBUILD_MODNAME ": " fmt
8240 +#endif
8241 +
8242 +#include <linux/init.h>
8243 +#include <linux/module.h>
8244 +#include <linux/of_platform.h>
8245 +#include "dpaa_eth.h"
8246 +#include "dpaa_eth_common.h"
8247 +#include "dpaa_eth_base.h"
8248 +#include "lnxwrp_fsl_fman.h" /* fm_get_rx_extra_headroom(), fm_get_max_frm() */
8249 +#include "mac.h"
8250 +
8251 +#define DPA_DESCRIPTION "FSL DPAA Proxy initialization driver"
8252 +
8253 +MODULE_LICENSE("Dual BSD/GPL");
8254 +
8255 +MODULE_DESCRIPTION(DPA_DESCRIPTION);
8256 +
8257 +static int __cold dpa_eth_proxy_remove(struct platform_device *of_dev);
8258 +#ifdef CONFIG_PM
8259 +
8260 +static int proxy_suspend(struct device *dev)
8261 +{
8262 + struct proxy_device *proxy_dev = dev_get_drvdata(dev);
8263 + struct mac_device *mac_dev = proxy_dev->mac_dev;
8264 + int err = 0;
8265 +
8266 + err = fm_port_suspend(mac_dev->port_dev[RX]);
8267 + if (err)
8268 + goto port_suspend_failed;
8269 +
8270 + err = fm_port_suspend(mac_dev->port_dev[TX]);
8271 + if (err)
8272 + err = fm_port_resume(mac_dev->port_dev[RX]);
8273 +
8274 +port_suspend_failed:
8275 + return err;
8276 +}
8277 +
8278 +static int proxy_resume(struct device *dev)
8279 +{
8280 + struct proxy_device *proxy_dev = dev_get_drvdata(dev);
8281 + struct mac_device *mac_dev = proxy_dev->mac_dev;
8282 + int err = 0;
8283 +
8284 + err = fm_port_resume(mac_dev->port_dev[TX]);
8285 + if (err)
8286 + goto port_resume_failed;
8287 +
8288 + err = fm_port_resume(mac_dev->port_dev[RX]);
8289 + if (err)
8290 + err = fm_port_suspend(mac_dev->port_dev[TX]);
8291 +
8292 +port_resume_failed:
8293 + return err;
8294 +}
8295 +
8296 +static const struct dev_pm_ops proxy_pm_ops = {
8297 + .suspend = proxy_suspend,
8298 + .resume = proxy_resume,
8299 +};
8300 +
8301 +#define PROXY_PM_OPS (&proxy_pm_ops)
8302 +
8303 +#else /* CONFIG_PM */
8304 +
8305 +#define PROXY_PM_OPS NULL
8306 +
8307 +#endif /* CONFIG_PM */
8308 +
8309 +static int dpaa_eth_proxy_probe(struct platform_device *_of_dev)
8310 +{
8311 + int err = 0, i;
8312 + struct device *dev;
8313 + struct device_node *dpa_node;
8314 + struct dpa_bp *dpa_bp;
8315 + struct list_head proxy_fq_list;
8316 + size_t count;
8317 + struct fm_port_fqs port_fqs;
8318 + struct dpa_buffer_layout_s *buf_layout = NULL;
8319 + struct mac_device *mac_dev;
8320 + struct proxy_device *proxy_dev;
8321 +
8322 + dev = &_of_dev->dev;
8323 +
8324 + dpa_node = dev->of_node;
8325 +
8326 + if (!of_device_is_available(dpa_node))
8327 + return -ENODEV;
8328 +
8329 + /* Get the buffer pools assigned to this interface */
8330 + dpa_bp = dpa_bp_probe(_of_dev, &count);
8331 + if (IS_ERR(dpa_bp))
8332 + return PTR_ERR(dpa_bp);
8333 +
8334 + mac_dev = dpa_mac_probe(_of_dev);
8335 + if (IS_ERR(mac_dev))
8336 + return PTR_ERR(mac_dev);
8337 +
8338 + proxy_dev = devm_kzalloc(dev, sizeof(*proxy_dev), GFP_KERNEL);
8339 + if (!proxy_dev) {
8340 + dev_err(dev, "devm_kzalloc() failed\n");
8341 + return -ENOMEM;
8342 + }
8343 +
8344 + proxy_dev->mac_dev = mac_dev;
8345 + dev_set_drvdata(dev, proxy_dev);
8346 +
8347 + /* We have physical ports, so we need to establish
8348 + * the buffer layout.
8349 + */
8350 + buf_layout = devm_kzalloc(dev, 2 * sizeof(*buf_layout),
8351 + GFP_KERNEL);
8352 + if (!buf_layout) {
8353 + dev_err(dev, "devm_kzalloc() failed\n");
8354 + return -ENOMEM;
8355 + }
8356 + dpa_set_buffers_layout(mac_dev, buf_layout);
8357 +
8358 + INIT_LIST_HEAD(&proxy_fq_list);
8359 +
8360 + memset(&port_fqs, 0, sizeof(port_fqs));
8361 +
8362 + err = dpa_fq_probe_mac(dev, &proxy_fq_list, &port_fqs, true, RX);
8363 + if (!err)
8364 + err = dpa_fq_probe_mac(dev, &proxy_fq_list, &port_fqs, true,
8365 + TX);
8366 + if (err < 0) {
8367 + devm_kfree(dev, buf_layout);
8368 + return err;
8369 + }
8370 +
8371 + /* Proxy initializer - Just configures the MAC on behalf of
8372 + * another partition.
8373 + */
8374 + dpaa_eth_init_ports(mac_dev, dpa_bp, count, &port_fqs,
8375 + buf_layout, dev);
8376 +
8377 + /* Proxy interfaces need to be started, and the allocated
8378 + * memory freed
8379 + */
8380 + devm_kfree(dev, buf_layout);
8381 + devm_kfree(dev, dpa_bp);
8382 +
8383 + /* Free FQ structures */
8384 + devm_kfree(dev, port_fqs.rx_defq);
8385 + devm_kfree(dev, port_fqs.rx_errq);
8386 + devm_kfree(dev, port_fqs.tx_defq);
8387 + devm_kfree(dev, port_fqs.tx_errq);
8388 +
8389 + for_each_port_device(i, mac_dev->port_dev) {
8390 + err = fm_port_enable(mac_dev->port_dev[i]);
8391 + if (err)
8392 + goto port_enable_fail;
8393 + }
8394 +
8395 + dev_info(dev, "probed MAC device with MAC address: %02hx:%02hx:%02hx:%02hx:%02hx:%02hx\n",
8396 + mac_dev->addr[0], mac_dev->addr[1], mac_dev->addr[2],
8397 + mac_dev->addr[3], mac_dev->addr[4], mac_dev->addr[5]);
8398 +
8399 + return 0; /* Proxy interface initialization ended */
8400 +
8401 +port_enable_fail:
8402 + for_each_port_device(i, mac_dev->port_dev)
8403 + fm_port_disable(mac_dev->port_dev[i]);
8404 + dpa_eth_proxy_remove(_of_dev);
8405 +
8406 + return err;
8407 +}
8408 +
8409 +int dpa_proxy_set_mac_address(struct proxy_device *proxy_dev,
8410 + struct net_device *net_dev)
8411 +{
8412 + struct mac_device *mac_dev;
8413 + int _errno;
8414 +
8415 + mac_dev = proxy_dev->mac_dev;
8416 +
8417 + _errno = mac_dev->change_addr(mac_dev->get_mac_handle(mac_dev),
8418 + net_dev->dev_addr);
8419 + if (_errno < 0)
8420 + return _errno;
8421 +
8422 + return 0;
8423 +}
8424 +EXPORT_SYMBOL(dpa_proxy_set_mac_address);
8425 +
8426 +int dpa_proxy_set_rx_mode(struct proxy_device *proxy_dev,
8427 + struct net_device *net_dev)
8428 +{
8429 + struct mac_device *mac_dev = proxy_dev->mac_dev;
8430 + int _errno;
8431 +
8432 + if (!!(net_dev->flags & IFF_PROMISC) != mac_dev->promisc) {
8433 + mac_dev->promisc = !mac_dev->promisc;
8434 + _errno = mac_dev->set_promisc(mac_dev->get_mac_handle(mac_dev),
8435 + mac_dev->promisc);
8436 + if (unlikely(_errno < 0))
8437 + netdev_err(net_dev, "mac_dev->set_promisc() = %d\n",
8438 + _errno);
8439 + }
8440 +
8441 + _errno = mac_dev->set_multi(net_dev, mac_dev);
8442 + if (unlikely(_errno < 0))
8443 + return _errno;
8444 +
8445 + return 0;
8446 +}
8447 +EXPORT_SYMBOL(dpa_proxy_set_rx_mode);
8448 +
8449 +int dpa_proxy_start(struct net_device *net_dev)
8450 +{
8451 + struct mac_device *mac_dev;
8452 + const struct dpa_priv_s *priv;
8453 + struct proxy_device *proxy_dev;
8454 + int _errno;
8455 + int i;
8456 +
8457 + priv = netdev_priv(net_dev);
8458 + proxy_dev = (struct proxy_device *)priv->peer;
8459 + mac_dev = proxy_dev->mac_dev;
8460 +
8461 + _errno = mac_dev->init_phy(net_dev, mac_dev);
8462 + if (_errno < 0) {
8463 + if (netif_msg_drv(priv))
8464 + netdev_err(net_dev, "init_phy() = %d\n",
8465 + _errno);
8466 + return _errno;
8467 + }
8468 +
8469 + for_each_port_device(i, mac_dev->port_dev) {
8470 + _errno = fm_port_enable(mac_dev->port_dev[i]);
8471 + if (_errno)
8472 + goto port_enable_fail;
8473 + }
8474 +
8475 + _errno = mac_dev->start(mac_dev);
8476 + if (_errno < 0) {
8477 + if (netif_msg_drv(priv))
8478 + netdev_err(net_dev, "mac_dev->start() = %d\n",
8479 + _errno);
8480 + goto port_enable_fail;
8481 + }
8482 +
8483 + return _errno;
8484 +
8485 +port_enable_fail:
8486 + for_each_port_device(i, mac_dev->port_dev)
8487 + fm_port_disable(mac_dev->port_dev[i]);
8488 +
8489 + return _errno;
8490 +}
8491 +EXPORT_SYMBOL(dpa_proxy_start);
8492 +
8493 +int dpa_proxy_stop(struct proxy_device *proxy_dev, struct net_device *net_dev)
8494 +{
8495 + struct mac_device *mac_dev = proxy_dev->mac_dev;
8496 + const struct dpa_priv_s *priv = netdev_priv(net_dev);
8497 + int _errno, i, err;
8498 +
8499 + _errno = mac_dev->stop(mac_dev);
8500 + if (_errno < 0) {
8501 + if (netif_msg_drv(priv))
8502 + netdev_err(net_dev, "mac_dev->stop() = %d\n",
8503 + _errno);
8504 + return _errno;
8505 + }
8506 +
8507 + for_each_port_device(i, mac_dev->port_dev) {
8508 + err = fm_port_disable(mac_dev->port_dev[i]);
8509 + _errno = err ? err : _errno;
8510 + }
8511 +
8512 + if (mac_dev->phy_dev)
8513 + phy_disconnect(mac_dev->phy_dev);
8514 + mac_dev->phy_dev = NULL;
8515 +
8516 + return _errno;
8517 +}
8518 +EXPORT_SYMBOL(dpa_proxy_stop);
8519 +
8520 +static int __cold dpa_eth_proxy_remove(struct platform_device *of_dev)
8521 +{
8522 + struct device *dev = &of_dev->dev;
8523 + struct proxy_device *proxy_dev = dev_get_drvdata(dev);
8524 +
8525 + kfree(proxy_dev);
8526 +
8527 + dev_set_drvdata(dev, NULL);
8528 +
8529 + return 0;
8530 +}
8531 +
8532 +static const struct of_device_id dpa_proxy_match[] = {
8533 + {
8534 + .compatible = "fsl,dpa-ethernet-init"
8535 + },
8536 + {}
8537 +};
8538 +MODULE_DEVICE_TABLE(of, dpa_proxy_match);
8539 +
8540 +static struct platform_driver dpa_proxy_driver = {
8541 + .driver = {
8542 + .name = KBUILD_MODNAME "-proxy",
8543 + .of_match_table = dpa_proxy_match,
8544 + .owner = THIS_MODULE,
8545 + .pm = PROXY_PM_OPS,
8546 + },
8547 + .probe = dpaa_eth_proxy_probe,
8548 + .remove = dpa_eth_proxy_remove
8549 +};
8550 +
8551 +static int __init __cold dpa_proxy_load(void)
8552 +{
8553 + int _errno;
8554 +
8555 + pr_info(DPA_DESCRIPTION "\n");
8556 +
8557 + /* Initialize dpaa_eth mirror values */
8558 + dpa_rx_extra_headroom = fm_get_rx_extra_headroom();
8559 + dpa_max_frm = fm_get_max_frm();
8560 +
8561 + _errno = platform_driver_register(&dpa_proxy_driver);
8562 + if (unlikely(_errno < 0)) {
8563 + pr_err(KBUILD_MODNAME
8564 + ": %s:%hu:%s(): platform_driver_register() = %d\n",
8565 + KBUILD_BASENAME".c", __LINE__, __func__, _errno);
8566 + }
8567 +
8568 + pr_debug(KBUILD_MODNAME ": %s:%s() ->\n",
8569 + KBUILD_BASENAME".c", __func__);
8570 +
8571 + return _errno;
8572 +}
8573 +module_init(dpa_proxy_load);
8574 +
8575 +static void __exit __cold dpa_proxy_unload(void)
8576 +{
8577 + platform_driver_unregister(&dpa_proxy_driver);
8578 +
8579 + pr_debug(KBUILD_MODNAME ": %s:%s() ->\n",
8580 + KBUILD_BASENAME".c", __func__);
8581 +}
8582 +module_exit(dpa_proxy_unload);
8583 --- /dev/null
8584 +++ b/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_sg.c
8585 @@ -0,0 +1,1168 @@
8586 +/* Copyright 2012 Freescale Semiconductor Inc.
8587 + *
8588 + * Redistribution and use in source and binary forms, with or without
8589 + * modification, are permitted provided that the following conditions are met:
8590 + * * Redistributions of source code must retain the above copyright
8591 + * notice, this list of conditions and the following disclaimer.
8592 + * * Redistributions in binary form must reproduce the above copyright
8593 + * notice, this list of conditions and the following disclaimer in the
8594 + * documentation and/or other materials provided with the distribution.
8595 + * * Neither the name of Freescale Semiconductor nor the
8596 + * names of its contributors may be used to endorse or promote products
8597 + * derived from this software without specific prior written permission.
8598 + *
8599 + *
8600 + * ALTERNATIVELY, this software may be distributed under the terms of the
8601 + * GNU General Public License ("GPL") as published by the Free Software
8602 + * Foundation, either version 2 of that License or (at your option) any
8603 + * later version.
8604 + *
8605 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
8606 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
8607 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
8608 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
8609 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
8610 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
8611 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
8612 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
8613 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
8614 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
8615 + */
8616 +
8617 +#ifdef CONFIG_FSL_DPAA_ETH_DEBUG
8618 +#define pr_fmt(fmt) \
8619 + KBUILD_MODNAME ": %s:%hu:%s() " fmt, \
8620 + KBUILD_BASENAME".c", __LINE__, __func__
8621 +#else
8622 +#define pr_fmt(fmt) \
8623 + KBUILD_MODNAME ": " fmt
8624 +#endif
8625 +
8626 +#include <linux/init.h>
8627 +#include <linux/skbuff.h>
8628 +#include <linux/highmem.h>
8629 +#include <linux/fsl_bman.h>
8630 +#include <net/sock.h>
8631 +
8632 +#include "dpaa_eth.h"
8633 +#include "dpaa_eth_common.h"
8634 +#ifdef CONFIG_FSL_DPAA_1588
8635 +#include "dpaa_1588.h"
8636 +#endif
8637 +#ifdef CONFIG_FSL_DPAA_CEETM
8638 +#include "dpaa_eth_ceetm.h"
8639 +#endif
8640 +
8641 +/* DMA map and add a page frag back into the bpool.
8642 + * @vaddr fragment must have been allocated with netdev_alloc_frag(),
8643 + * specifically for fitting into @dpa_bp.
8644 + */
8645 +static void dpa_bp_recycle_frag(struct dpa_bp *dpa_bp, unsigned long vaddr,
8646 + int *count_ptr)
8647 +{
8648 + struct bm_buffer bmb;
8649 + dma_addr_t addr;
8650 +
8651 + bmb.opaque = 0;
8652 +
8653 + addr = dma_map_single(dpa_bp->dev, (void *)vaddr, dpa_bp->size,
8654 + DMA_BIDIRECTIONAL);
8655 + if (unlikely(dma_mapping_error(dpa_bp->dev, addr))) {
8656 + dev_err(dpa_bp->dev, "DMA mapping failed");
8657 + return;
8658 + }
8659 +
8660 + bm_buffer_set64(&bmb, addr);
8661 +
8662 + while (bman_release(dpa_bp->pool, &bmb, 1, 0))
8663 + cpu_relax();
8664 +
8665 + (*count_ptr)++;
8666 +}
8667 +
8668 +static int _dpa_bp_add_8_bufs(const struct dpa_bp *dpa_bp)
8669 +{
8670 + struct bm_buffer bmb[8];
8671 + void *new_buf;
8672 + dma_addr_t addr;
8673 + uint8_t i;
8674 + struct device *dev = dpa_bp->dev;
8675 + struct sk_buff *skb, **skbh;
8676 +
8677 + memset(bmb, 0, sizeof(struct bm_buffer) * 8);
8678 +
8679 + for (i = 0; i < 8; i++) {
8680 + /* We'll prepend the skb back-pointer; can't use the DPA
8681 + * priv space, because FMan will overwrite it (from offset 0)
8682 + * if it ends up being the second, third, etc. fragment
8683 + * in a S/G frame.
8684 + *
8685 + * We only need enough space to store a pointer, but allocate
8686 + * an entire cacheline for performance reasons.
8687 + */
8688 +#ifndef CONFIG_PPC
8689 + if (unlikely(dpaa_errata_a010022)) {
8690 + struct page *new_page = alloc_page(GFP_ATOMIC);
8691 + if (unlikely(!new_page))
8692 + goto netdev_alloc_failed;
8693 + new_buf = page_address(new_page);
8694 + }
8695 + else
8696 +#endif
8697 + new_buf = netdev_alloc_frag(SMP_CACHE_BYTES + DPA_BP_RAW_SIZE);
8698 +
8699 + if (unlikely(!new_buf))
8700 + goto netdev_alloc_failed;
8701 + new_buf = PTR_ALIGN(new_buf + SMP_CACHE_BYTES, SMP_CACHE_BYTES);
8702 +
8703 + skb = build_skb(new_buf, DPA_SKB_SIZE(dpa_bp->size) +
8704 + SKB_DATA_ALIGN(sizeof(struct skb_shared_info)));
8705 + if (unlikely(!skb)) {
8706 + put_page(virt_to_head_page(new_buf));
8707 + goto build_skb_failed;
8708 + }
8709 + DPA_WRITE_SKB_PTR(skb, skbh, new_buf, -1);
8710 +
8711 + addr = dma_map_single(dev, new_buf,
8712 + dpa_bp->size, DMA_BIDIRECTIONAL);
8713 + if (unlikely(dma_mapping_error(dev, addr)))
8714 + goto dma_map_failed;
8715 +
8716 + bm_buffer_set64(&bmb[i], addr);
8717 + }
8718 +
8719 +release_bufs:
8720 + /* Release the buffers. In case bman is busy, keep trying
8721 + * until successful. bman_release() is guaranteed to succeed
8722 + * in a reasonable amount of time
8723 + */
8724 + while (unlikely(bman_release(dpa_bp->pool, bmb, i, 0)))
8725 + cpu_relax();
8726 + return i;
8727 +
8728 +dma_map_failed:
8729 + kfree_skb(skb);
8730 +
8731 +build_skb_failed:
8732 +netdev_alloc_failed:
8733 + net_err_ratelimited("dpa_bp_add_8_bufs() failed\n");
8734 + WARN_ONCE(1, "Memory allocation failure on Rx\n");
8735 +
8736 + bm_buffer_set64(&bmb[i], 0);
8737 + /* Avoid releasing a completely null buffer; bman_release() requires
8738 + * at least one buffer.
8739 + */
8740 + if (likely(i))
8741 + goto release_bufs;
8742 +
8743 + return 0;
8744 +}
8745 +
8746 +/* Cold path wrapper over _dpa_bp_add_8_bufs(). */
8747 +static void dpa_bp_add_8_bufs(const struct dpa_bp *dpa_bp, int cpu)
8748 +{
8749 + int *count_ptr = per_cpu_ptr(dpa_bp->percpu_count, cpu);
8750 + *count_ptr += _dpa_bp_add_8_bufs(dpa_bp);
8751 +}
8752 +
8753 +int dpa_bp_priv_seed(struct dpa_bp *dpa_bp)
8754 +{
8755 + int i;
8756 +
8757 + /* Give each CPU an allotment of "config_count" buffers */
8758 + for_each_possible_cpu(i) {
8759 + int j;
8760 +
8761 + /* Although we access another CPU's counters here
8762 + * we do it at boot time so it is safe
8763 + */
8764 + for (j = 0; j < dpa_bp->config_count; j += 8)
8765 + dpa_bp_add_8_bufs(dpa_bp, i);
8766 + }
8767 + return 0;
8768 +}
8769 +EXPORT_SYMBOL(dpa_bp_priv_seed);
8770 +
8771 +/* Add buffers/(pages) for Rx processing whenever bpool count falls below
8772 + * REFILL_THRESHOLD.
8773 + */
8774 +int dpaa_eth_refill_bpools(struct dpa_bp *dpa_bp, int *countptr)
8775 +{
8776 + int count = *countptr;
8777 + int new_bufs;
8778 +
8779 + if (unlikely(count < CONFIG_FSL_DPAA_ETH_REFILL_THRESHOLD)) {
8780 + do {
8781 + new_bufs = _dpa_bp_add_8_bufs(dpa_bp);
8782 + if (unlikely(!new_bufs)) {
8783 + /* Avoid looping forever if we've temporarily
8784 + * run out of memory. We'll try again at the
8785 + * next NAPI cycle.
8786 + */
8787 + break;
8788 + }
8789 + count += new_bufs;
8790 + } while (count < CONFIG_FSL_DPAA_ETH_MAX_BUF_COUNT);
8791 +
8792 + *countptr = count;
8793 + if (unlikely(count < CONFIG_FSL_DPAA_ETH_MAX_BUF_COUNT))
8794 + return -ENOMEM;
8795 + }
8796 +
8797 + return 0;
8798 +}
8799 +EXPORT_SYMBOL(dpaa_eth_refill_bpools);
8800 +
8801 +/* Cleanup function for outgoing frame descriptors that were built on Tx path,
8802 + * either contiguous frames or scatter/gather ones.
8803 + * Skb freeing is not handled here.
8804 + *
8805 + * This function may be called on error paths in the Tx function, so guard
8806 + * against cases when not all fd relevant fields were filled in.
8807 + *
8808 + * Return the skb backpointer, since for S/G frames the buffer containing it
8809 + * gets freed here.
8810 + */
8811 +struct sk_buff *_dpa_cleanup_tx_fd(const struct dpa_priv_s *priv,
8812 + const struct qm_fd *fd)
8813 +{
8814 + const struct qm_sg_entry *sgt;
8815 + int i;
8816 + struct dpa_bp *dpa_bp = priv->dpa_bp;
8817 + dma_addr_t addr = qm_fd_addr(fd);
8818 + dma_addr_t sg_addr;
8819 + struct sk_buff **skbh;
8820 + struct sk_buff *skb = NULL;
8821 + const enum dma_data_direction dma_dir = DMA_TO_DEVICE;
8822 + int nr_frags;
8823 + int sg_len;
8824 +
8825 + /* retrieve skb back pointer */
8826 + DPA_READ_SKB_PTR(skb, skbh, phys_to_virt(addr), 0);
8827 +
8828 + if (unlikely(fd->format == qm_fd_sg)) {
8829 + nr_frags = skb_shinfo(skb)->nr_frags;
8830 + dma_unmap_single(dpa_bp->dev, addr, dpa_fd_offset(fd) +
8831 + sizeof(struct qm_sg_entry) * (1 + nr_frags),
8832 + dma_dir);
8833 +
8834 + /* The sgt buffer has been allocated with netdev_alloc_frag(),
8835 + * it's from lowmem.
8836 + */
8837 + sgt = phys_to_virt(addr + dpa_fd_offset(fd));
8838 +#ifdef CONFIG_FSL_DPAA_1588
8839 + if (priv->tsu && priv->tsu->valid &&
8840 + priv->tsu->hwts_tx_en_ioctl)
8841 + dpa_ptp_store_txstamp(priv, skb, (void *)skbh);
8842 +#endif
8843 +#ifdef CONFIG_FSL_DPAA_TS
8844 + if (unlikely(priv->ts_tx_en &&
8845 + skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP)) {
8846 + struct skb_shared_hwtstamps shhwtstamps;
8847 +
8848 + dpa_get_ts(priv, TX, &shhwtstamps, (void *)skbh);
8849 + skb_tstamp_tx(skb, &shhwtstamps);
8850 + }
8851 +#endif /* CONFIG_FSL_DPAA_TS */
8852 +
8853 + /* sgt[0] is from lowmem, was dma_map_single()-ed */
8854 + sg_addr = qm_sg_addr(&sgt[0]);
8855 + sg_len = qm_sg_entry_get_len(&sgt[0]);
8856 + dma_unmap_single(dpa_bp->dev, sg_addr, sg_len, dma_dir);
8857 +
8858 + /* remaining pages were mapped with dma_map_page() */
8859 + for (i = 1; i <= nr_frags; i++) {
8860 + DPA_BUG_ON(qm_sg_entry_get_ext(&sgt[i]));
8861 + sg_addr = qm_sg_addr(&sgt[i]);
8862 + sg_len = qm_sg_entry_get_len(&sgt[i]);
8863 + dma_unmap_page(dpa_bp->dev, sg_addr, sg_len, dma_dir);
8864 + }
8865 +
8866 + /* Free the page frag that we allocated on Tx */
8867 + put_page(virt_to_head_page(sgt));
8868 + } else {
8869 + dma_unmap_single(dpa_bp->dev, addr,
8870 + skb_tail_pointer(skb) - (u8 *)skbh, dma_dir);
8871 +#ifdef CONFIG_FSL_DPAA_TS
8872 + /* get the timestamp for non-SG frames */
8873 +#ifdef CONFIG_FSL_DPAA_1588
8874 + if (priv->tsu && priv->tsu->valid &&
8875 + priv->tsu->hwts_tx_en_ioctl)
8876 + dpa_ptp_store_txstamp(priv, skb, (void *)skbh);
8877 +#endif
8878 + if (unlikely(priv->ts_tx_en &&
8879 + skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP)) {
8880 + struct skb_shared_hwtstamps shhwtstamps;
8881 +
8882 + dpa_get_ts(priv, TX, &shhwtstamps, (void *)skbh);
8883 + skb_tstamp_tx(skb, &shhwtstamps);
8884 + }
8885 +#endif
8886 + }
8887 +
8888 + return skb;
8889 +}
8890 +EXPORT_SYMBOL(_dpa_cleanup_tx_fd);
8891 +
8892 +#ifndef CONFIG_FSL_DPAA_TS
8893 +bool dpa_skb_is_recyclable(struct sk_buff *skb)
8894 +{
8895 +#ifndef CONFIG_PPC
8896 + /* Do no recycle skbs realigned by the errata workaround */
8897 + if (unlikely(dpaa_errata_a010022) && skb->mark == NONREC_MARK)
8898 + return false;
8899 +#endif
8900 +
8901 + /* No recycling possible if skb buffer is kmalloc'ed */
8902 + if (skb->head_frag == 0)
8903 + return false;
8904 +
8905 + /* or if it's an userspace buffer */
8906 + if (skb_shinfo(skb)->tx_flags & SKBTX_DEV_ZEROCOPY)
8907 + return false;
8908 +
8909 + /* or if it's cloned or shared */
8910 + if (skb_shared(skb) || skb_cloned(skb) ||
8911 + skb->fclone != SKB_FCLONE_UNAVAILABLE)
8912 + return false;
8913 +
8914 + return true;
8915 +}
8916 +EXPORT_SYMBOL(dpa_skb_is_recyclable);
8917 +
8918 +bool dpa_buf_is_recyclable(struct sk_buff *skb,
8919 + uint32_t min_size,
8920 + uint16_t min_offset,
8921 + unsigned char **new_buf_start)
8922 +{
8923 + unsigned char *new;
8924 +
8925 + /* In order to recycle a buffer, the following conditions must be met:
8926 + * - buffer size no less than the buffer pool size
8927 + * - buffer size no higher than an upper limit (to avoid moving too much
8928 + * system memory to the buffer pools)
8929 + * - buffer address aligned to cacheline bytes
8930 + * - offset of data from start of buffer no lower than a minimum value
8931 + * - offset of data from start of buffer no higher than a maximum value
8932 + */
8933 + new = min(skb_end_pointer(skb) - min_size, skb->data - min_offset);
8934 +
8935 + /* left align to the nearest cacheline */
8936 + new = (unsigned char *)((unsigned long)new & ~(SMP_CACHE_BYTES - 1));
8937 +
8938 + if (likely(new >= skb->head &&
8939 + new >= (skb->data - DPA_MAX_FD_OFFSET) &&
8940 + skb_end_pointer(skb) - new <= DPA_RECYCLE_MAX_SIZE)) {
8941 + *new_buf_start = new;
8942 + return true;
8943 + }
8944 +
8945 + return false;
8946 +}
8947 +EXPORT_SYMBOL(dpa_buf_is_recyclable);
8948 +#endif
8949 +
8950 +/* Build a linear skb around the received buffer.
8951 + * We are guaranteed there is enough room at the end of the data buffer to
8952 + * accommodate the shared info area of the skb.
8953 + */
8954 +static struct sk_buff *__hot contig_fd_to_skb(const struct dpa_priv_s *priv,
8955 + const struct qm_fd *fd, int *use_gro)
8956 +{
8957 + dma_addr_t addr = qm_fd_addr(fd);
8958 + ssize_t fd_off = dpa_fd_offset(fd);
8959 + void *vaddr;
8960 + const fm_prs_result_t *parse_results;
8961 + struct sk_buff *skb = NULL, **skbh;
8962 +
8963 + vaddr = phys_to_virt(addr);
8964 + DPA_BUG_ON(!IS_ALIGNED((unsigned long)vaddr, SMP_CACHE_BYTES));
8965 +
8966 + /* Retrieve the skb and adjust data and tail pointers, to make sure
8967 + * forwarded skbs will have enough space on Tx if extra headers
8968 + * are added.
8969 + */
8970 + DPA_READ_SKB_PTR(skb, skbh, vaddr, -1);
8971 +
8972 +#ifdef CONFIG_FSL_DPAA_ETH_JUMBO_FRAME
8973 + /* When using jumbo Rx buffers, we risk having frames dropped due to
8974 + * the socket backlog reaching its maximum allowed size.
8975 + * Use the frame length for the skb truesize instead of the buffer
8976 + * size, as this is the size of the data that actually gets copied to
8977 + * userspace.
8978 + * The stack may increase the payload. In this case, it will want to
8979 + * warn us that the frame length is larger than the truesize. We
8980 + * bypass the warning.
8981 + */
8982 +#ifndef CONFIG_PPC
8983 + /* We do not support Jumbo frames on LS1043 and thus we edit
8984 + * the skb truesize only when the 4k errata is not present.
8985 + */
8986 + if (likely(!dpaa_errata_a010022))
8987 +#endif
8988 + skb->truesize = SKB_TRUESIZE(dpa_fd_length(fd));
8989 +#endif
8990 +
8991 + DPA_BUG_ON(fd_off != priv->rx_headroom);
8992 + skb_reserve(skb, fd_off);
8993 + skb_put(skb, dpa_fd_length(fd));
8994 +
8995 + /* Peek at the parse results for csum validation */
8996 + parse_results = (const fm_prs_result_t *)(vaddr +
8997 + DPA_RX_PRIV_DATA_SIZE);
8998 + _dpa_process_parse_results(parse_results, fd, skb, use_gro);
8999 +
9000 +#ifdef CONFIG_FSL_DPAA_1588
9001 + if (priv->tsu && priv->tsu->valid && priv->tsu->hwts_rx_en_ioctl)
9002 + dpa_ptp_store_rxstamp(priv, skb, vaddr);
9003 +#endif
9004 +#ifdef CONFIG_FSL_DPAA_TS
9005 + if (priv->ts_rx_en)
9006 + dpa_get_ts(priv, RX, skb_hwtstamps(skb), vaddr);
9007 +#endif /* CONFIG_FSL_DPAA_TS */
9008 +
9009 + return skb;
9010 +}
9011 +
9012 +
9013 +/* Build an skb with the data of the first S/G entry in the linear portion and
9014 + * the rest of the frame as skb fragments.
9015 + *
9016 + * The page fragment holding the S/G Table is recycled here.
9017 + */
9018 +static struct sk_buff *__hot sg_fd_to_skb(const struct dpa_priv_s *priv,
9019 + const struct qm_fd *fd, int *use_gro,
9020 + int *count_ptr)
9021 +{
9022 + const struct qm_sg_entry *sgt;
9023 + dma_addr_t addr = qm_fd_addr(fd);
9024 + ssize_t fd_off = dpa_fd_offset(fd);
9025 + dma_addr_t sg_addr;
9026 + void *vaddr, *sg_vaddr;
9027 + struct dpa_bp *dpa_bp;
9028 + struct page *page, *head_page;
9029 + int frag_offset, frag_len;
9030 + int page_offset;
9031 + int i;
9032 + const fm_prs_result_t *parse_results;
9033 + struct sk_buff *skb = NULL, *skb_tmp, **skbh;
9034 +
9035 + vaddr = phys_to_virt(addr);
9036 + DPA_BUG_ON(!IS_ALIGNED((unsigned long)vaddr, SMP_CACHE_BYTES));
9037 +
9038 + dpa_bp = priv->dpa_bp;
9039 + /* Iterate through the SGT entries and add data buffers to the skb */
9040 + sgt = vaddr + fd_off;
9041 + for (i = 0; i < DPA_SGT_MAX_ENTRIES; i++) {
9042 + /* Extension bit is not supported */
9043 + DPA_BUG_ON(qm_sg_entry_get_ext(&sgt[i]));
9044 +
9045 + /* We use a single global Rx pool */
9046 + DPA_BUG_ON(dpa_bp !=
9047 + dpa_bpid2pool(qm_sg_entry_get_bpid(&sgt[i])));
9048 +
9049 + sg_addr = qm_sg_addr(&sgt[i]);
9050 + sg_vaddr = phys_to_virt(sg_addr);
9051 + DPA_BUG_ON(!IS_ALIGNED((unsigned long)sg_vaddr,
9052 + SMP_CACHE_BYTES));
9053 +
9054 + dma_unmap_single(dpa_bp->dev, sg_addr, dpa_bp->size,
9055 + DMA_BIDIRECTIONAL);
9056 + if (i == 0) {
9057 + DPA_READ_SKB_PTR(skb, skbh, sg_vaddr, -1);
9058 + DPA_BUG_ON(skb->head != sg_vaddr);
9059 +#ifdef CONFIG_FSL_DPAA_1588
9060 + if (priv->tsu && priv->tsu->valid &&
9061 + priv->tsu->hwts_rx_en_ioctl)
9062 + dpa_ptp_store_rxstamp(priv, skb, vaddr);
9063 +#endif
9064 +#ifdef CONFIG_FSL_DPAA_TS
9065 + if (priv->ts_rx_en)
9066 + dpa_get_ts(priv, RX, skb_hwtstamps(skb), vaddr);
9067 +#endif /* CONFIG_FSL_DPAA_TS */
9068 +
9069 + /* In the case of a SG frame, FMan stores the Internal
9070 + * Context in the buffer containing the sgt.
9071 + * Inspect the parse results before anything else.
9072 + */
9073 + parse_results = (const fm_prs_result_t *)(vaddr +
9074 + DPA_RX_PRIV_DATA_SIZE);
9075 + _dpa_process_parse_results(parse_results, fd, skb,
9076 + use_gro);
9077 +
9078 + /* Make sure forwarded skbs will have enough space
9079 + * on Tx, if extra headers are added.
9080 + */
9081 + DPA_BUG_ON(fd_off != priv->rx_headroom);
9082 + skb_reserve(skb, fd_off);
9083 + skb_put(skb, qm_sg_entry_get_len(&sgt[i]));
9084 + } else {
9085 + /* Not the first S/G entry; all data from buffer will
9086 + * be added in an skb fragment; fragment index is offset
9087 + * by one since first S/G entry was incorporated in the
9088 + * linear part of the skb.
9089 + *
9090 + * Caution: 'page' may be a tail page.
9091 + */
9092 + DPA_READ_SKB_PTR(skb_tmp, skbh, sg_vaddr, -1);
9093 + page = virt_to_page(sg_vaddr);
9094 + head_page = virt_to_head_page(sg_vaddr);
9095 +
9096 + /* Free (only) the skbuff shell because its data buffer
9097 + * is already a frag in the main skb.
9098 + */
9099 + get_page(head_page);
9100 + dev_kfree_skb(skb_tmp);
9101 +
9102 + /* Compute offset in (possibly tail) page */
9103 + page_offset = ((unsigned long)sg_vaddr &
9104 + (PAGE_SIZE - 1)) +
9105 + (page_address(page) - page_address(head_page));
9106 + /* page_offset only refers to the beginning of sgt[i];
9107 + * but the buffer itself may have an internal offset.
9108 + */
9109 + frag_offset = qm_sg_entry_get_offset(&sgt[i]) +
9110 + page_offset;
9111 + frag_len = qm_sg_entry_get_len(&sgt[i]);
9112 + /* skb_add_rx_frag() does no checking on the page; if
9113 + * we pass it a tail page, we'll end up with
9114 + * bad page accounting and eventually with segafults.
9115 + */
9116 + skb_add_rx_frag(skb, i - 1, head_page, frag_offset,
9117 + frag_len, dpa_bp->size);
9118 + }
9119 + /* Update the pool count for the current {cpu x bpool} */
9120 + (*count_ptr)--;
9121 +
9122 + if (qm_sg_entry_get_final(&sgt[i]))
9123 + break;
9124 + }
9125 + WARN_ONCE(i == DPA_SGT_MAX_ENTRIES, "No final bit on SGT\n");
9126 +
9127 + /* recycle the SGT fragment */
9128 + DPA_BUG_ON(dpa_bp != dpa_bpid2pool(fd->bpid));
9129 + dpa_bp_recycle_frag(dpa_bp, (unsigned long)vaddr, count_ptr);
9130 + return skb;
9131 +}
9132 +
9133 +#ifdef CONFIG_FSL_DPAA_DBG_LOOP
9134 +static inline int dpa_skb_loop(const struct dpa_priv_s *priv,
9135 + struct sk_buff *skb)
9136 +{
9137 + if (unlikely(priv->loop_to < 0))
9138 + return 0; /* loop disabled by default */
9139 +
9140 + skb_push(skb, ETH_HLEN); /* compensate for eth_type_trans */
9141 + dpa_tx(skb, dpa_loop_netdevs[priv->loop_to]);
9142 +
9143 + return 1; /* Frame Tx on the selected interface */
9144 +}
9145 +#endif
9146 +
9147 +void __hot _dpa_rx(struct net_device *net_dev,
9148 + struct qman_portal *portal,
9149 + const struct dpa_priv_s *priv,
9150 + struct dpa_percpu_priv_s *percpu_priv,
9151 + const struct qm_fd *fd,
9152 + u32 fqid,
9153 + int *count_ptr)
9154 +{
9155 + struct dpa_bp *dpa_bp;
9156 + struct sk_buff *skb;
9157 + dma_addr_t addr = qm_fd_addr(fd);
9158 + u32 fd_status = fd->status;
9159 + unsigned int skb_len;
9160 + struct rtnl_link_stats64 *percpu_stats = &percpu_priv->stats;
9161 + int use_gro = net_dev->features & NETIF_F_GRO;
9162 +
9163 + if (unlikely(fd_status & FM_FD_STAT_RX_ERRORS) != 0) {
9164 + if (netif_msg_hw(priv) && net_ratelimit())
9165 + netdev_warn(net_dev, "FD status = 0x%08x\n",
9166 + fd_status & FM_FD_STAT_RX_ERRORS);
9167 +
9168 + percpu_stats->rx_errors++;
9169 + goto _release_frame;
9170 + }
9171 +
9172 + dpa_bp = priv->dpa_bp;
9173 + DPA_BUG_ON(dpa_bp != dpa_bpid2pool(fd->bpid));
9174 +
9175 + /* prefetch the first 64 bytes of the frame or the SGT start */
9176 + dma_unmap_single(dpa_bp->dev, addr, dpa_bp->size, DMA_BIDIRECTIONAL);
9177 + prefetch(phys_to_virt(addr) + dpa_fd_offset(fd));
9178 +
9179 + /* The only FD types that we may receive are contig and S/G */
9180 + DPA_BUG_ON((fd->format != qm_fd_contig) && (fd->format != qm_fd_sg));
9181 +
9182 + if (likely(fd->format == qm_fd_contig)) {
9183 +#ifdef CONFIG_FSL_DPAA_HOOKS
9184 + /* Execute the Rx processing hook, if it exists. */
9185 + if (dpaa_eth_hooks.rx_default &&
9186 + dpaa_eth_hooks.rx_default((void *)fd, net_dev,
9187 + fqid) == DPAA_ETH_STOLEN) {
9188 + /* won't count the rx bytes in */
9189 + return;
9190 + }
9191 +#endif
9192 + skb = contig_fd_to_skb(priv, fd, &use_gro);
9193 + } else {
9194 + skb = sg_fd_to_skb(priv, fd, &use_gro, count_ptr);
9195 + percpu_priv->rx_sg++;
9196 + }
9197 +
9198 + /* Account for either the contig buffer or the SGT buffer (depending on
9199 + * which case we were in) having been removed from the pool.
9200 + */
9201 + (*count_ptr)--;
9202 + skb->protocol = eth_type_trans(skb, net_dev);
9203 +
9204 + skb_len = skb->len;
9205 +
9206 +#ifdef CONFIG_FSL_DPAA_DBG_LOOP
9207 + if (dpa_skb_loop(priv, skb)) {
9208 + percpu_stats->rx_packets++;
9209 + percpu_stats->rx_bytes += skb_len;
9210 + return;
9211 + }
9212 +#endif
9213 +
9214 + if (use_gro) {
9215 + gro_result_t gro_result;
9216 + const struct qman_portal_config *pc =
9217 + qman_p_get_portal_config(portal);
9218 + struct dpa_napi_portal *np = &percpu_priv->np[pc->index];
9219 +
9220 + np->p = portal;
9221 + gro_result = napi_gro_receive(&np->napi, skb);
9222 + /* If frame is dropped by the stack, rx_dropped counter is
9223 + * incremented automatically, so no need for us to update it
9224 + */
9225 + if (unlikely(gro_result == GRO_DROP))
9226 + goto packet_dropped;
9227 + } else if (unlikely(netif_receive_skb(skb) == NET_RX_DROP))
9228 + goto packet_dropped;
9229 +
9230 + percpu_stats->rx_packets++;
9231 + percpu_stats->rx_bytes += skb_len;
9232 +
9233 +packet_dropped:
9234 + return;
9235 +
9236 +_release_frame:
9237 + dpa_fd_release(net_dev, fd);
9238 +}
9239 +
9240 +int __hot skb_to_contig_fd(struct dpa_priv_s *priv,
9241 + struct sk_buff *skb, struct qm_fd *fd,
9242 + int *count_ptr, int *offset)
9243 +{
9244 + struct sk_buff **skbh;
9245 + dma_addr_t addr;
9246 + struct dpa_bp *dpa_bp = priv->dpa_bp;
9247 + struct net_device *net_dev = priv->net_dev;
9248 + int err;
9249 + enum dma_data_direction dma_dir;
9250 + unsigned char *buffer_start;
9251 + int dma_map_size;
9252 +
9253 +#ifndef CONFIG_FSL_DPAA_TS
9254 + /* Check recycling conditions; only if timestamp support is not
9255 + * enabled, otherwise we need the fd back on tx confirmation
9256 + */
9257 +
9258 + /* We can recycle the buffer if:
9259 + * - the pool is not full
9260 + * - the buffer meets the skb recycling conditions
9261 + * - the buffer meets our own (size, offset, align) conditions
9262 + */
9263 + if (likely((*count_ptr < dpa_bp->target_count) &&
9264 + dpa_skb_is_recyclable(skb) &&
9265 + dpa_buf_is_recyclable(skb, dpa_bp->size,
9266 + priv->tx_headroom, &buffer_start))) {
9267 + /* Buffer is recyclable; use the new start address
9268 + * and set fd parameters and DMA mapping direction
9269 + */
9270 + fd->bpid = dpa_bp->bpid;
9271 + DPA_BUG_ON(skb->data - buffer_start > DPA_MAX_FD_OFFSET);
9272 + fd->offset = (uint16_t)(skb->data - buffer_start);
9273 + dma_dir = DMA_BIDIRECTIONAL;
9274 + dma_map_size = dpa_bp->size;
9275 +
9276 + DPA_WRITE_SKB_PTR(skb, skbh, buffer_start, -1);
9277 + *offset = skb_headroom(skb) - fd->offset;
9278 + } else
9279 +#endif
9280 + {
9281 + /* Not recyclable.
9282 + * We are guaranteed to have at least tx_headroom bytes
9283 + * available, so just use that for offset.
9284 + */
9285 + fd->bpid = 0xff;
9286 + buffer_start = skb->data - priv->tx_headroom;
9287 + fd->offset = priv->tx_headroom;
9288 + dma_dir = DMA_TO_DEVICE;
9289 + dma_map_size = skb_tail_pointer(skb) - buffer_start;
9290 +
9291 + /* The buffer will be Tx-confirmed, but the TxConf cb must
9292 + * necessarily look at our Tx private data to retrieve the
9293 + * skbuff. (In short: can't use DPA_WRITE_SKB_PTR() here.)
9294 + */
9295 + DPA_WRITE_SKB_PTR(skb, skbh, buffer_start, 0);
9296 + }
9297 +
9298 + /* Enable L3/L4 hardware checksum computation.
9299 + *
9300 + * We must do this before dma_map_single(DMA_TO_DEVICE), because we may
9301 + * need to write into the skb.
9302 + */
9303 + err = dpa_enable_tx_csum(priv, skb, fd,
9304 + ((char *)skbh) + DPA_TX_PRIV_DATA_SIZE);
9305 + if (unlikely(err < 0)) {
9306 + if (netif_msg_tx_err(priv) && net_ratelimit())
9307 + netdev_err(net_dev, "HW csum error: %d\n", err);
9308 + return err;
9309 + }
9310 +
9311 + /* Fill in the rest of the FD fields */
9312 + fd->format = qm_fd_contig;
9313 + fd->length20 = skb->len;
9314 + fd->cmd |= FM_FD_CMD_FCO;
9315 +
9316 + /* Map the entire buffer size that may be seen by FMan, but no more */
9317 + addr = dma_map_single(dpa_bp->dev, skbh, dma_map_size, dma_dir);
9318 + if (unlikely(dma_mapping_error(dpa_bp->dev, addr))) {
9319 + if (netif_msg_tx_err(priv) && net_ratelimit())
9320 + netdev_err(net_dev, "dma_map_single() failed\n");
9321 + return -EINVAL;
9322 + }
9323 + qm_fd_addr_set64(fd, addr);
9324 +
9325 + return 0;
9326 +}
9327 +EXPORT_SYMBOL(skb_to_contig_fd);
9328 +
9329 +#ifndef CONFIG_PPC
9330 +/* Verify the conditions that trigger the A010022 errata: data unaligned to
9331 + * 16 bytes and 4K memory address crossings.
9332 + */
9333 +static bool a010022_check_skb(struct sk_buff *skb, struct dpa_priv_s *priv)
9334 +{
9335 + int nr_frags, i = 0;
9336 + skb_frag_t *frag;
9337 +
9338 + /* Check if the headroom is aligned */
9339 + if (((uintptr_t)skb->data - priv->tx_headroom) %
9340 + priv->buf_layout[TX].data_align != 0)
9341 + return true;
9342 +
9343 + /* Check if the headroom crosses a boundary */
9344 + if (HAS_DMA_ISSUE(skb->head, skb_headroom(skb)))
9345 + return true;
9346 +
9347 + /* Check if the non-paged data crosses a boundary */
9348 + if (HAS_DMA_ISSUE(skb->data, skb_headlen(skb)))
9349 + return true;
9350 +
9351 + /* Check if the entire linear skb crosses a boundary */
9352 + if (HAS_DMA_ISSUE(skb->head, skb_end_offset(skb)))
9353 + return true;
9354 +
9355 + nr_frags = skb_shinfo(skb)->nr_frags;
9356 +
9357 + while (i < nr_frags) {
9358 + frag = &skb_shinfo(skb)->frags[i];
9359 +
9360 + /* Check if a paged fragment crosses a boundary from its
9361 + * offset to its end.
9362 + */
9363 + if (HAS_DMA_ISSUE(frag->page_offset, frag->size))
9364 + return true;
9365 +
9366 + i++;
9367 + }
9368 +
9369 + return false;
9370 +}
9371 +
9372 +/* Realign the skb by copying its contents at the start of a newly allocated
9373 + * page. Build a new skb around the new buffer and release the old one.
9374 + * A performance drop should be expected.
9375 + */
9376 +static struct sk_buff *a010022_realign_skb(struct sk_buff *skb,
9377 + struct dpa_priv_s *priv)
9378 +{
9379 + int trans_offset = skb_transport_offset(skb);
9380 + int net_offset = skb_network_offset(skb);
9381 + struct sk_buff *nskb = NULL;
9382 + int nsize, headroom;
9383 + struct page *npage;
9384 + void *npage_addr;
9385 +
9386 + /* Guarantee the minimum required headroom */
9387 + if (skb_headroom(skb) >= priv->tx_headroom)
9388 + headroom = skb_headroom(skb);
9389 + else
9390 + headroom = priv->tx_headroom;
9391 +
9392 + npage = alloc_page(GFP_ATOMIC);
9393 + if (unlikely(!npage)) {
9394 + WARN_ONCE(1, "Memory allocation failure\n");
9395 + return NULL;
9396 + }
9397 + npage_addr = page_address(npage);
9398 +
9399 + /* For the new skb we only need the old one's data (both non-paged and
9400 + * paged) and a headroom large enough to fit our private info. We can
9401 + * skip the old tailroom.
9402 + *
9403 + * Make sure the new linearized buffer will not exceed a page's size.
9404 + */
9405 + nsize = headroom + skb->len +
9406 + SKB_DATA_ALIGN(sizeof(struct skb_shared_info));
9407 + if (unlikely(nsize > 4096))
9408 + goto err;
9409 +
9410 + nskb = build_skb(npage_addr, nsize);
9411 + if (unlikely(!nskb))
9412 + goto err;
9413 +
9414 + /* Reserve only the needed headroom in order to guarantee the data's
9415 + * alignment.
9416 + * Code borrowed and adapted from skb_copy().
9417 + */
9418 + skb_reserve(nskb, priv->tx_headroom);
9419 + skb_put(nskb, skb->len);
9420 + if (skb_copy_bits(skb, 0, nskb->data, skb->len)) {
9421 + WARN_ONCE(1, "skb parsing failure\n");
9422 + goto err;
9423 + }
9424 + copy_skb_header(nskb, skb);
9425 +
9426 +#ifdef CONFIG_FSL_DPAA_TS
9427 + /* Copy relevant timestamp info from the old skb to the new */
9428 + if (priv->ts_tx_en) {
9429 + skb_shinfo(nskb)->tx_flags = skb_shinfo(skb)->tx_flags;
9430 + skb_shinfo(nskb)->hwtstamps = skb_shinfo(skb)->hwtstamps;
9431 + skb_shinfo(nskb)->tskey = skb_shinfo(skb)->tskey;
9432 + if (skb->sk)
9433 + skb_set_owner_w(nskb, skb->sk);
9434 + }
9435 +#endif
9436 + /* We move the headroom when we align it so we have to reset the
9437 + * network and transport header offsets relative to the new data
9438 + * pointer. The checksum offload relies on these offsets.
9439 + */
9440 + skb_set_network_header(nskb, net_offset);
9441 + skb_set_transport_header(nskb, trans_offset);
9442 +
9443 + /* We don't want the buffer to be recycled so we mark it accordingly */
9444 + nskb->mark = NONREC_MARK;
9445 +
9446 + dev_kfree_skb(skb);
9447 + return nskb;
9448 +
9449 +err:
9450 + if (nskb)
9451 + dev_kfree_skb(nskb);
9452 + put_page(npage);
9453 + return NULL;
9454 +}
9455 +#endif
9456 +
9457 +int __hot skb_to_sg_fd(struct dpa_priv_s *priv,
9458 + struct sk_buff *skb, struct qm_fd *fd)
9459 +{
9460 + struct dpa_bp *dpa_bp = priv->dpa_bp;
9461 + dma_addr_t addr;
9462 + dma_addr_t sg_addr;
9463 + struct sk_buff **skbh;
9464 + struct net_device *net_dev = priv->net_dev;
9465 + int sg_len, sgt_size;
9466 + int err;
9467 +
9468 + struct qm_sg_entry *sgt;
9469 + void *sgt_buf;
9470 + skb_frag_t *frag;
9471 + int i = 0, j = 0;
9472 + int nr_frags;
9473 + const enum dma_data_direction dma_dir = DMA_TO_DEVICE;
9474 +
9475 + nr_frags = skb_shinfo(skb)->nr_frags;
9476 + fd->format = qm_fd_sg;
9477 +
9478 + sgt_size = sizeof(struct qm_sg_entry) * (1 + nr_frags);
9479 +
9480 + /* Get a page frag to store the SGTable, or a full page if the errata
9481 + * is in place and we need to avoid crossing a 4k boundary.
9482 + */
9483 +#ifndef CONFIG_PPC
9484 + if (unlikely(dpaa_errata_a010022))
9485 + sgt_buf = page_address(alloc_page(GFP_ATOMIC));
9486 + else
9487 +#endif
9488 + sgt_buf = netdev_alloc_frag(priv->tx_headroom + sgt_size);
9489 + if (unlikely(!sgt_buf)) {
9490 + dev_err(dpa_bp->dev, "netdev_alloc_frag() failed\n");
9491 + return -ENOMEM;
9492 + }
9493 +
9494 + /* it seems that the memory allocator does not zero the allocated mem */
9495 + memset(sgt_buf, 0, priv->tx_headroom + sgt_size);
9496 +
9497 + /* Enable L3/L4 hardware checksum computation.
9498 + *
9499 + * We must do this before dma_map_single(DMA_TO_DEVICE), because we may
9500 + * need to write into the skb.
9501 + */
9502 + err = dpa_enable_tx_csum(priv, skb, fd,
9503 + sgt_buf + DPA_TX_PRIV_DATA_SIZE);
9504 + if (unlikely(err < 0)) {
9505 + if (netif_msg_tx_err(priv) && net_ratelimit())
9506 + netdev_err(net_dev, "HW csum error: %d\n", err);
9507 + goto csum_failed;
9508 + }
9509 +
9510 + /* Assign the data from skb->data to the first SG list entry */
9511 + sgt = (struct qm_sg_entry *)(sgt_buf + priv->tx_headroom);
9512 + sg_len = skb_headlen(skb);
9513 + qm_sg_entry_set_bpid(&sgt[0], 0xff);
9514 + qm_sg_entry_set_offset(&sgt[0], 0);
9515 + qm_sg_entry_set_len(&sgt[0], sg_len);
9516 + qm_sg_entry_set_ext(&sgt[0], 0);
9517 + qm_sg_entry_set_final(&sgt[0], 0);
9518 +
9519 + addr = dma_map_single(dpa_bp->dev, skb->data, sg_len, dma_dir);
9520 + if (unlikely(dma_mapping_error(dpa_bp->dev, addr))) {
9521 + dev_err(dpa_bp->dev, "DMA mapping failed");
9522 + err = -EINVAL;
9523 + goto sg0_map_failed;
9524 + }
9525 +
9526 + qm_sg_entry_set64(&sgt[0], addr);
9527 +
9528 + /* populate the rest of SGT entries */
9529 + for (i = 1; i <= nr_frags; i++) {
9530 + frag = &skb_shinfo(skb)->frags[i - 1];
9531 + qm_sg_entry_set_bpid(&sgt[i], 0xff);
9532 + qm_sg_entry_set_offset(&sgt[i], 0);
9533 + qm_sg_entry_set_len(&sgt[i], frag->size);
9534 + qm_sg_entry_set_ext(&sgt[i], 0);
9535 +
9536 + if (i == nr_frags)
9537 + qm_sg_entry_set_final(&sgt[i], 1);
9538 + else
9539 + qm_sg_entry_set_final(&sgt[i], 0);
9540 +
9541 + DPA_BUG_ON(!skb_frag_page(frag));
9542 + addr = skb_frag_dma_map(dpa_bp->dev, frag, 0, frag->size,
9543 + dma_dir);
9544 + if (unlikely(dma_mapping_error(dpa_bp->dev, addr))) {
9545 + dev_err(dpa_bp->dev, "DMA mapping failed");
9546 + err = -EINVAL;
9547 + goto sg_map_failed;
9548 + }
9549 +
9550 + /* keep the offset in the address */
9551 + qm_sg_entry_set64(&sgt[i], addr);
9552 + }
9553 +
9554 + fd->length20 = skb->len;
9555 + fd->offset = priv->tx_headroom;
9556 +
9557 + /* DMA map the SGT page */
9558 + DPA_WRITE_SKB_PTR(skb, skbh, sgt_buf, 0);
9559 + addr = dma_map_single(dpa_bp->dev, sgt_buf,
9560 + priv->tx_headroom + sgt_size,
9561 + dma_dir);
9562 +
9563 + if (unlikely(dma_mapping_error(dpa_bp->dev, addr))) {
9564 + dev_err(dpa_bp->dev, "DMA mapping failed");
9565 + err = -EINVAL;
9566 + goto sgt_map_failed;
9567 + }
9568 +
9569 + qm_fd_addr_set64(fd, addr);
9570 + fd->bpid = 0xff;
9571 + fd->cmd |= FM_FD_CMD_FCO;
9572 +
9573 + return 0;
9574 +
9575 +sgt_map_failed:
9576 +sg_map_failed:
9577 + for (j = 0; j < i; j++) {
9578 + sg_addr = qm_sg_addr(&sgt[j]);
9579 + dma_unmap_page(dpa_bp->dev, sg_addr,
9580 + qm_sg_entry_get_len(&sgt[j]), dma_dir);
9581 + }
9582 +sg0_map_failed:
9583 +csum_failed:
9584 + put_page(virt_to_head_page(sgt_buf));
9585 +
9586 + return err;
9587 +}
9588 +EXPORT_SYMBOL(skb_to_sg_fd);
9589 +
9590 +int __hot dpa_tx(struct sk_buff *skb, struct net_device *net_dev)
9591 +{
9592 + struct dpa_priv_s *priv;
9593 + const int queue_mapping = dpa_get_queue_mapping(skb);
9594 + struct qman_fq *egress_fq, *conf_fq;
9595 +
9596 +#ifdef CONFIG_FSL_DPAA_HOOKS
9597 + /* If there is a Tx hook, run it. */
9598 + if (dpaa_eth_hooks.tx &&
9599 + dpaa_eth_hooks.tx(skb, net_dev) == DPAA_ETH_STOLEN)
9600 + /* won't update any Tx stats */
9601 + return NETDEV_TX_OK;
9602 +#endif
9603 +
9604 + priv = netdev_priv(net_dev);
9605 +
9606 +#ifdef CONFIG_FSL_DPAA_CEETM
9607 + if (priv->ceetm_en)
9608 + return ceetm_tx(skb, net_dev);
9609 +#endif
9610 +
9611 + egress_fq = priv->egress_fqs[queue_mapping];
9612 + conf_fq = priv->conf_fqs[queue_mapping];
9613 +
9614 + return dpa_tx_extended(skb, net_dev, egress_fq, conf_fq);
9615 +}
9616 +
9617 +int __hot dpa_tx_extended(struct sk_buff *skb, struct net_device *net_dev,
9618 + struct qman_fq *egress_fq, struct qman_fq *conf_fq)
9619 +{
9620 + struct dpa_priv_s *priv;
9621 + struct qm_fd fd;
9622 + struct dpa_percpu_priv_s *percpu_priv;
9623 + struct rtnl_link_stats64 *percpu_stats;
9624 + int err = 0;
9625 + bool nonlinear;
9626 + int *countptr, offset = 0;
9627 +
9628 + priv = netdev_priv(net_dev);
9629 + /* Non-migratable context, safe to use raw_cpu_ptr */
9630 + percpu_priv = raw_cpu_ptr(priv->percpu_priv);
9631 + percpu_stats = &percpu_priv->stats;
9632 + countptr = raw_cpu_ptr(priv->dpa_bp->percpu_count);
9633 +
9634 + clear_fd(&fd);
9635 +
9636 +#ifndef CONFIG_PPC
9637 + if (unlikely(dpaa_errata_a010022) && a010022_check_skb(skb, priv)) {
9638 + skb = a010022_realign_skb(skb, priv);
9639 + if (!skb)
9640 + goto skb_to_fd_failed;
9641 + }
9642 +#endif
9643 +
9644 + nonlinear = skb_is_nonlinear(skb);
9645 +
9646 +#ifdef CONFIG_FSL_DPAA_1588
9647 + if (priv->tsu && priv->tsu->valid && priv->tsu->hwts_tx_en_ioctl)
9648 + fd.cmd |= FM_FD_CMD_UPD;
9649 +#endif
9650 +#ifdef CONFIG_FSL_DPAA_TS
9651 + if (unlikely(priv->ts_tx_en &&
9652 + skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP))
9653 + fd.cmd |= FM_FD_CMD_UPD;
9654 + skb_shinfo(skb)->tx_flags |= SKBTX_IN_PROGRESS;
9655 +#endif /* CONFIG_FSL_DPAA_TS */
9656 +
9657 + /* MAX_SKB_FRAGS is larger than our DPA_SGT_MAX_ENTRIES; make sure
9658 + * we don't feed FMan with more fragments than it supports.
9659 + * Btw, we're using the first sgt entry to store the linear part of
9660 + * the skb, so we're one extra frag short.
9661 + */
9662 + if (nonlinear &&
9663 + likely(skb_shinfo(skb)->nr_frags < DPA_SGT_MAX_ENTRIES)) {
9664 + /* Just create a S/G fd based on the skb */
9665 + err = skb_to_sg_fd(priv, skb, &fd);
9666 + percpu_priv->tx_frag_skbuffs++;
9667 + } else {
9668 + /* Make sure we have enough headroom to accommodate private
9669 + * data, parse results, etc. Normally this shouldn't happen if
9670 + * we're here via the standard kernel stack.
9671 + */
9672 + if (unlikely(skb_headroom(skb) < priv->tx_headroom)) {
9673 + struct sk_buff *skb_new;
9674 +
9675 + skb_new = skb_realloc_headroom(skb, priv->tx_headroom);
9676 + if (unlikely(!skb_new)) {
9677 + dev_kfree_skb(skb);
9678 + percpu_stats->tx_errors++;
9679 + return NETDEV_TX_OK;
9680 + }
9681 + dev_kfree_skb(skb);
9682 + skb = skb_new;
9683 + }
9684 +
9685 + /* We're going to store the skb backpointer at the beginning
9686 + * of the data buffer, so we need a privately owned skb
9687 + */
9688 +
9689 + /* Code borrowed from skb_unshare(). */
9690 + if (skb_cloned(skb)) {
9691 + struct sk_buff *nskb = skb_copy(skb, GFP_ATOMIC);
9692 + kfree_skb(skb);
9693 + skb = nskb;
9694 +#ifndef CONFIG_PPC
9695 + if (unlikely(dpaa_errata_a010022) &&
9696 + a010022_check_skb(skb, priv)) {
9697 + skb = a010022_realign_skb(skb, priv);
9698 + if (!skb)
9699 + goto skb_to_fd_failed;
9700 + }
9701 +#endif
9702 + /* skb_copy() has now linearized the skbuff. */
9703 + } else if (unlikely(nonlinear)) {
9704 + /* We are here because the egress skb contains
9705 + * more fragments than we support. In this case,
9706 + * we have no choice but to linearize it ourselves.
9707 + */
9708 + err = __skb_linearize(skb);
9709 + }
9710 + if (unlikely(!skb || err < 0))
9711 + /* Common out-of-memory error path */
9712 + goto enomem;
9713 +
9714 + err = skb_to_contig_fd(priv, skb, &fd, countptr, &offset);
9715 + }
9716 + if (unlikely(err < 0))
9717 + goto skb_to_fd_failed;
9718 +
9719 + if (fd.bpid != 0xff) {
9720 + skb_recycle(skb);
9721 + /* skb_recycle() reserves NET_SKB_PAD as skb headroom,
9722 + * but we need the skb to look as if returned by build_skb().
9723 + * We need to manually adjust the tailptr as well.
9724 + */
9725 + skb->data = skb->head + offset;
9726 + skb_reset_tail_pointer(skb);
9727 +
9728 + (*countptr)++;
9729 + percpu_priv->tx_returned++;
9730 + }
9731 +
9732 + if (unlikely(dpa_xmit(priv, percpu_stats, &fd, egress_fq, conf_fq) < 0))
9733 + goto xmit_failed;
9734 +
9735 + netif_trans_update(net_dev);
9736 + return NETDEV_TX_OK;
9737 +
9738 +xmit_failed:
9739 + if (fd.bpid != 0xff) {
9740 + (*countptr)--;
9741 + percpu_priv->tx_returned--;
9742 + dpa_fd_release(net_dev, &fd);
9743 + percpu_stats->tx_errors++;
9744 + return NETDEV_TX_OK;
9745 + }
9746 + _dpa_cleanup_tx_fd(priv, &fd);
9747 +skb_to_fd_failed:
9748 +enomem:
9749 + percpu_stats->tx_errors++;
9750 + dev_kfree_skb(skb);
9751 + return NETDEV_TX_OK;
9752 +}
9753 +EXPORT_SYMBOL(dpa_tx_extended);
9754 --- /dev/null
9755 +++ b/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_sysfs.c
9756 @@ -0,0 +1,278 @@
9757 +/* Copyright 2008-2012 Freescale Semiconductor Inc.
9758 + *
9759 + * Redistribution and use in source and binary forms, with or without
9760 + * modification, are permitted provided that the following conditions are met:
9761 + * * Redistributions of source code must retain the above copyright
9762 + * notice, this list of conditions and the following disclaimer.
9763 + * * Redistributions in binary form must reproduce the above copyright
9764 + * notice, this list of conditions and the following disclaimer in the
9765 + * documentation and/or other materials provided with the distribution.
9766 + * * Neither the name of Freescale Semiconductor nor the
9767 + * names of its contributors may be used to endorse or promote products
9768 + * derived from this software without specific prior written permission.
9769 + *
9770 + *
9771 + * ALTERNATIVELY, this software may be distributed under the terms of the
9772 + * GNU General Public License ("GPL") as published by the Free Software
9773 + * Foundation, either version 2 of that License or (at your option) any
9774 + * later version.
9775 + *
9776 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
9777 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
9778 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
9779 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
9780 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
9781 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
9782 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
9783 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
9784 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
9785 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
9786 + */
9787 +
9788 +#include <linux/init.h>
9789 +#include <linux/module.h>
9790 +#include <linux/kthread.h>
9791 +#include <linux/io.h>
9792 +#include <linux/of_net.h>
9793 +#include "dpaa_eth.h"
9794 +#include "mac.h" /* struct mac_device */
9795 +#ifdef CONFIG_FSL_DPAA_1588
9796 +#include "dpaa_1588.h"
9797 +#endif
9798 +
9799 +static ssize_t dpaa_eth_show_addr(struct device *dev,
9800 + struct device_attribute *attr, char *buf)
9801 +{
9802 + struct dpa_priv_s *priv = netdev_priv(to_net_dev(dev));
9803 + struct mac_device *mac_dev = priv->mac_dev;
9804 +
9805 + if (mac_dev)
9806 + return sprintf(buf, "%llx",
9807 + (unsigned long long)mac_dev->res->start);
9808 + else
9809 + return sprintf(buf, "none");
9810 +}
9811 +
9812 +static ssize_t dpaa_eth_show_type(struct device *dev,
9813 + struct device_attribute *attr, char *buf)
9814 +{
9815 + struct dpa_priv_s *priv = netdev_priv(to_net_dev(dev));
9816 + ssize_t res = 0;
9817 +
9818 + if (priv)
9819 + res = sprintf(buf, "%s", priv->if_type);
9820 +
9821 + return res;
9822 +}
9823 +
9824 +static ssize_t dpaa_eth_show_fqids(struct device *dev,
9825 + struct device_attribute *attr, char *buf)
9826 +{
9827 + struct dpa_priv_s *priv = netdev_priv(to_net_dev(dev));
9828 + ssize_t bytes = 0;
9829 + int i = 0;
9830 + char *str;
9831 + struct dpa_fq *fq;
9832 + struct dpa_fq *tmp;
9833 + struct dpa_fq *prev = NULL;
9834 + u32 first_fqid = 0;
9835 + u32 last_fqid = 0;
9836 + char *prevstr = NULL;
9837 +
9838 + list_for_each_entry_safe(fq, tmp, &priv->dpa_fq_list, list) {
9839 + switch (fq->fq_type) {
9840 + case FQ_TYPE_RX_DEFAULT:
9841 + str = "Rx default";
9842 + break;
9843 + case FQ_TYPE_RX_ERROR:
9844 + str = "Rx error";
9845 + break;
9846 + case FQ_TYPE_RX_PCD:
9847 + str = "Rx PCD";
9848 + break;
9849 + case FQ_TYPE_TX_CONFIRM:
9850 + str = "Tx default confirmation";
9851 + break;
9852 + case FQ_TYPE_TX_CONF_MQ:
9853 + str = "Tx confirmation (mq)";
9854 + break;
9855 + case FQ_TYPE_TX_ERROR:
9856 + str = "Tx error";
9857 + break;
9858 + case FQ_TYPE_TX:
9859 + str = "Tx";
9860 + break;
9861 + case FQ_TYPE_RX_PCD_HI_PRIO:
9862 + str ="Rx PCD High Priority";
9863 + break;
9864 + default:
9865 + str = "Unknown";
9866 + }
9867 +
9868 + if (prev && (abs(fq->fqid - prev->fqid) != 1 ||
9869 + str != prevstr)) {
9870 + if (last_fqid == first_fqid)
9871 + bytes += sprintf(buf + bytes,
9872 + "%s: %d\n", prevstr, prev->fqid);
9873 + else
9874 + bytes += sprintf(buf + bytes,
9875 + "%s: %d - %d\n", prevstr,
9876 + first_fqid, last_fqid);
9877 + }
9878 +
9879 + if (prev && abs(fq->fqid - prev->fqid) == 1 && str == prevstr)
9880 + last_fqid = fq->fqid;
9881 + else
9882 + first_fqid = last_fqid = fq->fqid;
9883 +
9884 + prev = fq;
9885 + prevstr = str;
9886 + i++;
9887 + }
9888 +
9889 + if (prev) {
9890 + if (last_fqid == first_fqid)
9891 + bytes += sprintf(buf + bytes, "%s: %d\n", prevstr,
9892 + prev->fqid);
9893 + else
9894 + bytes += sprintf(buf + bytes, "%s: %d - %d\n", prevstr,
9895 + first_fqid, last_fqid);
9896 + }
9897 +
9898 + return bytes;
9899 +}
9900 +
9901 +static ssize_t dpaa_eth_show_bpids(struct device *dev,
9902 + struct device_attribute *attr, char *buf)
9903 +{
9904 + ssize_t bytes = 0;
9905 + struct dpa_priv_s *priv = netdev_priv(to_net_dev(dev));
9906 + struct dpa_bp *dpa_bp = priv->dpa_bp;
9907 + int i = 0;
9908 +
9909 + for (i = 0; i < priv->bp_count; i++)
9910 + bytes += snprintf(buf + bytes, PAGE_SIZE, "%u\n",
9911 + dpa_bp[i].bpid);
9912 +
9913 + return bytes;
9914 +}
9915 +
9916 +static ssize_t dpaa_eth_show_mac_regs(struct device *dev,
9917 + struct device_attribute *attr, char *buf)
9918 +{
9919 + struct dpa_priv_s *priv = netdev_priv(to_net_dev(dev));
9920 + struct mac_device *mac_dev = priv->mac_dev;
9921 + int n = 0;
9922 +
9923 + if (mac_dev)
9924 + n = fm_mac_dump_regs(mac_dev, buf, n);
9925 + else
9926 + return sprintf(buf, "no mac registers\n");
9927 +
9928 + return n;
9929 +}
9930 +
9931 +static ssize_t dpaa_eth_show_mac_rx_stats(struct device *dev,
9932 + struct device_attribute *attr, char *buf)
9933 +{
9934 + struct dpa_priv_s *priv = netdev_priv(to_net_dev(dev));
9935 + struct mac_device *mac_dev = priv->mac_dev;
9936 + int n = 0;
9937 +
9938 + if (mac_dev)
9939 + n = fm_mac_dump_rx_stats(mac_dev, buf, n);
9940 + else
9941 + return sprintf(buf, "no mac rx stats\n");
9942 +
9943 + return n;
9944 +}
9945 +
9946 +static ssize_t dpaa_eth_show_mac_tx_stats(struct device *dev,
9947 + struct device_attribute *attr, char *buf)
9948 +{
9949 + struct dpa_priv_s *priv = netdev_priv(to_net_dev(dev));
9950 + struct mac_device *mac_dev = priv->mac_dev;
9951 + int n = 0;
9952 +
9953 + if (mac_dev)
9954 + n = fm_mac_dump_tx_stats(mac_dev, buf, n);
9955 + else
9956 + return sprintf(buf, "no mac tx stats\n");
9957 +
9958 + return n;
9959 +}
9960 +
9961 +#ifdef CONFIG_FSL_DPAA_1588
9962 +static ssize_t dpaa_eth_show_ptp_1588(struct device *dev,
9963 + struct device_attribute *attr, char *buf)
9964 +{
9965 + struct dpa_priv_s *priv = netdev_priv(to_net_dev(dev));
9966 +
9967 + if (priv->tsu && priv->tsu->valid)
9968 + return sprintf(buf, "1\n");
9969 + else
9970 + return sprintf(buf, "0\n");
9971 +}
9972 +
9973 +static ssize_t dpaa_eth_set_ptp_1588(struct device *dev,
9974 + struct device_attribute *attr,
9975 + const char *buf, size_t count)
9976 +{
9977 + struct dpa_priv_s *priv = netdev_priv(to_net_dev(dev));
9978 + unsigned int num;
9979 + unsigned long flags;
9980 +
9981 + if (kstrtouint(buf, 0, &num) < 0)
9982 + return -EINVAL;
9983 +
9984 + local_irq_save(flags);
9985 +
9986 + if (num) {
9987 + if (priv->tsu)
9988 + priv->tsu->valid = TRUE;
9989 + } else {
9990 + if (priv->tsu)
9991 + priv->tsu->valid = FALSE;
9992 + }
9993 +
9994 + local_irq_restore(flags);
9995 +
9996 + return count;
9997 +}
9998 +#endif
9999 +
10000 +static struct device_attribute dpaa_eth_attrs[] = {
10001 + __ATTR(device_addr, S_IRUGO, dpaa_eth_show_addr, NULL),
10002 + __ATTR(device_type, S_IRUGO, dpaa_eth_show_type, NULL),
10003 + __ATTR(fqids, S_IRUGO, dpaa_eth_show_fqids, NULL),
10004 + __ATTR(bpids, S_IRUGO, dpaa_eth_show_bpids, NULL),
10005 + __ATTR(mac_regs, S_IRUGO, dpaa_eth_show_mac_regs, NULL),
10006 + __ATTR(mac_rx_stats, S_IRUGO, dpaa_eth_show_mac_rx_stats, NULL),
10007 + __ATTR(mac_tx_stats, S_IRUGO, dpaa_eth_show_mac_tx_stats, NULL),
10008 +#ifdef CONFIG_FSL_DPAA_1588
10009 + __ATTR(ptp_1588, S_IRUGO | S_IWUSR, dpaa_eth_show_ptp_1588,
10010 + dpaa_eth_set_ptp_1588),
10011 +#endif
10012 +};
10013 +
10014 +void dpaa_eth_sysfs_init(struct device *dev)
10015 +{
10016 + int i;
10017 +
10018 + for (i = 0; i < ARRAY_SIZE(dpaa_eth_attrs); i++)
10019 + if (device_create_file(dev, &dpaa_eth_attrs[i])) {
10020 + dev_err(dev, "Error creating sysfs file\n");
10021 + while (i > 0)
10022 + device_remove_file(dev, &dpaa_eth_attrs[--i]);
10023 + return;
10024 + }
10025 +}
10026 +EXPORT_SYMBOL(dpaa_eth_sysfs_init);
10027 +
10028 +void dpaa_eth_sysfs_remove(struct device *dev)
10029 +{
10030 + int i;
10031 +
10032 + for (i = 0; i < ARRAY_SIZE(dpaa_eth_attrs); i++)
10033 + device_remove_file(dev, &dpaa_eth_attrs[i]);
10034 +}
10035 --- /dev/null
10036 +++ b/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_trace.h
10037 @@ -0,0 +1,144 @@
10038 +/* Copyright 2013 Freescale Semiconductor Inc.
10039 + *
10040 + * Redistribution and use in source and binary forms, with or without
10041 + * modification, are permitted provided that the following conditions are met:
10042 + * * Redistributions of source code must retain the above copyright
10043 + * notice, this list of conditions and the following disclaimer.
10044 + * * Redistributions in binary form must reproduce the above copyright
10045 + * notice, this list of conditions and the following disclaimer in the
10046 + * documentation and/or other materials provided with the distribution.
10047 + * * Neither the name of Freescale Semiconductor nor the
10048 + * names of its contributors may be used to endorse or promote products
10049 + * derived from this software without specific prior written permission.
10050 + *
10051 + *
10052 + * ALTERNATIVELY, this software may be distributed under the terms of the
10053 + * GNU General Public License ("GPL") as published by the Free Software
10054 + * Foundation, either version 2 of that License or (at your option) any
10055 + * later version.
10056 + *
10057 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
10058 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
10059 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
10060 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
10061 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
10062 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
10063 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
10064 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
10065 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
10066 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
10067 + */
10068 +
10069 +#undef TRACE_SYSTEM
10070 +#define TRACE_SYSTEM dpaa_eth
10071 +
10072 +#if !defined(_DPAA_ETH_TRACE_H) || defined(TRACE_HEADER_MULTI_READ)
10073 +#define _DPAA_ETH_TRACE_H
10074 +
10075 +#include <linux/skbuff.h>
10076 +#include <linux/netdevice.h>
10077 +#include "dpaa_eth.h"
10078 +#include <linux/tracepoint.h>
10079 +
10080 +#define fd_format_name(format) { qm_fd_##format, #format }
10081 +#define fd_format_list \
10082 + fd_format_name(contig), \
10083 + fd_format_name(sg)
10084 +#define TR_FMT "[%s] fqid=%d, fd: addr=0x%llx, format=%s, off=%u, len=%u," \
10085 + " status=0x%08x"
10086 +
10087 +/* This is used to declare a class of events.
10088 + * individual events of this type will be defined below.
10089 + */
10090 +
10091 +/* Store details about a frame descriptor and the FQ on which it was
10092 + * transmitted/received.
10093 + */
10094 +DECLARE_EVENT_CLASS(dpaa_eth_fd,
10095 + /* Trace function prototype */
10096 + TP_PROTO(struct net_device *netdev,
10097 + struct qman_fq *fq,
10098 + const struct qm_fd *fd),
10099 +
10100 + /* Repeat argument list here */
10101 + TP_ARGS(netdev, fq, fd),
10102 +
10103 + /* A structure containing the relevant information we want to record.
10104 + * Declare name and type for each normal element, name, type and size
10105 + * for arrays. Use __string for variable length strings.
10106 + */
10107 + TP_STRUCT__entry(
10108 + __field(u32, fqid)
10109 + __field(u64, fd_addr)
10110 + __field(u8, fd_format)
10111 + __field(u16, fd_offset)
10112 + __field(u32, fd_length)
10113 + __field(u32, fd_status)
10114 + __string(name, netdev->name)
10115 + ),
10116 +
10117 + /* The function that assigns values to the above declared fields */
10118 + TP_fast_assign(
10119 + __entry->fqid = fq->fqid;
10120 + __entry->fd_addr = qm_fd_addr_get64(fd);
10121 + __entry->fd_format = fd->format;
10122 + __entry->fd_offset = dpa_fd_offset(fd);
10123 + __entry->fd_length = dpa_fd_length(fd);
10124 + __entry->fd_status = fd->status;
10125 + __assign_str(name, netdev->name);
10126 + ),
10127 +
10128 + /* This is what gets printed when the trace event is triggered */
10129 + /* TODO: print the status using __print_flags() */
10130 + TP_printk(TR_FMT,
10131 + __get_str(name), __entry->fqid, __entry->fd_addr,
10132 + __print_symbolic(__entry->fd_format, fd_format_list),
10133 + __entry->fd_offset, __entry->fd_length, __entry->fd_status)
10134 +);
10135 +
10136 +/* Now declare events of the above type. Format is:
10137 + * DEFINE_EVENT(class, name, proto, args), with proto and args same as for class
10138 + */
10139 +
10140 +/* Tx (egress) fd */
10141 +DEFINE_EVENT(dpaa_eth_fd, dpa_tx_fd,
10142 +
10143 + TP_PROTO(struct net_device *netdev,
10144 + struct qman_fq *fq,
10145 + const struct qm_fd *fd),
10146 +
10147 + TP_ARGS(netdev, fq, fd)
10148 +);
10149 +
10150 +/* Rx fd */
10151 +DEFINE_EVENT(dpaa_eth_fd, dpa_rx_fd,
10152 +
10153 + TP_PROTO(struct net_device *netdev,
10154 + struct qman_fq *fq,
10155 + const struct qm_fd *fd),
10156 +
10157 + TP_ARGS(netdev, fq, fd)
10158 +);
10159 +
10160 +/* Tx confirmation fd */
10161 +DEFINE_EVENT(dpaa_eth_fd, dpa_tx_conf_fd,
10162 +
10163 + TP_PROTO(struct net_device *netdev,
10164 + struct qman_fq *fq,
10165 + const struct qm_fd *fd),
10166 +
10167 + TP_ARGS(netdev, fq, fd)
10168 +);
10169 +
10170 +/* If only one event of a certain type needs to be declared, use TRACE_EVENT().
10171 + * The syntax is the same as for DECLARE_EVENT_CLASS().
10172 + */
10173 +
10174 +#endif /* _DPAA_ETH_TRACE_H */
10175 +
10176 +/* This must be outside ifdef _DPAA_ETH_TRACE_H */
10177 +#undef TRACE_INCLUDE_PATH
10178 +#define TRACE_INCLUDE_PATH .
10179 +#undef TRACE_INCLUDE_FILE
10180 +#define TRACE_INCLUDE_FILE dpaa_eth_trace
10181 +#include <trace/define_trace.h>
10182 --- /dev/null
10183 +++ b/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_ethtool.c
10184 @@ -0,0 +1,544 @@
10185 +/* Copyright 2008-2012 Freescale Semiconductor, Inc.
10186 + *
10187 + * Redistribution and use in source and binary forms, with or without
10188 + * modification, are permitted provided that the following conditions are met:
10189 + * * Redistributions of source code must retain the above copyright
10190 + * notice, this list of conditions and the following disclaimer.
10191 + * * Redistributions in binary form must reproduce the above copyright
10192 + * notice, this list of conditions and the following disclaimer in the
10193 + * documentation and/or other materials provided with the distribution.
10194 + * * Neither the name of Freescale Semiconductor nor the
10195 + * names of its contributors may be used to endorse or promote products
10196 + * derived from this software without specific prior written permission.
10197 + *
10198 + *
10199 + * ALTERNATIVELY, this software may be distributed under the terms of the
10200 + * GNU General Public License ("GPL") as published by the Free Software
10201 + * Foundation, either version 2 of that License or (at your option) any
10202 + * later version.
10203 + *
10204 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
10205 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
10206 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
10207 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
10208 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
10209 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
10210 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
10211 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
10212 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
10213 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
10214 + */
10215 +
10216 +#ifdef CONFIG_FSL_DPAA_ETH_DEBUG
10217 +#define pr_fmt(fmt) \
10218 + KBUILD_MODNAME ": %s:%hu:%s() " fmt, \
10219 + KBUILD_BASENAME".c", __LINE__, __func__
10220 +#else
10221 +#define pr_fmt(fmt) \
10222 + KBUILD_MODNAME ": " fmt
10223 +#endif
10224 +
10225 +#include <linux/string.h>
10226 +
10227 +#include "dpaa_eth.h"
10228 +#include "mac.h" /* struct mac_device */
10229 +#include "dpaa_eth_common.h"
10230 +
10231 +static const char dpa_stats_percpu[][ETH_GSTRING_LEN] = {
10232 + "interrupts",
10233 + "rx packets",
10234 + "tx packets",
10235 + "tx recycled",
10236 + "tx confirm",
10237 + "tx S/G",
10238 + "rx S/G",
10239 + "tx error",
10240 + "rx error",
10241 + "bp count"
10242 +};
10243 +
10244 +static char dpa_stats_global[][ETH_GSTRING_LEN] = {
10245 + /* dpa rx errors */
10246 + "rx dma error",
10247 + "rx frame physical error",
10248 + "rx frame size error",
10249 + "rx header error",
10250 + "rx csum error",
10251 +
10252 + /* demultiplexing errors */
10253 + "qman cg_tdrop",
10254 + "qman wred",
10255 + "qman error cond",
10256 + "qman early window",
10257 + "qman late window",
10258 + "qman fq tdrop",
10259 + "qman fq retired",
10260 + "qman orp disabled",
10261 +
10262 + /* congestion related stats */
10263 + "congestion time (ms)",
10264 + "entered congestion",
10265 + "congested (0/1)"
10266 +};
10267 +
10268 +#define DPA_STATS_PERCPU_LEN ARRAY_SIZE(dpa_stats_percpu)
10269 +#define DPA_STATS_GLOBAL_LEN ARRAY_SIZE(dpa_stats_global)
10270 +
10271 +static int __cold dpa_get_settings(struct net_device *net_dev,
10272 + struct ethtool_cmd *et_cmd)
10273 +{
10274 + int _errno;
10275 + struct dpa_priv_s *priv;
10276 +
10277 + priv = netdev_priv(net_dev);
10278 +
10279 + if (priv->mac_dev == NULL) {
10280 + netdev_info(net_dev, "This is a MAC-less interface\n");
10281 + return -ENODEV;
10282 + }
10283 + if (unlikely(priv->mac_dev->phy_dev == NULL)) {
10284 + netdev_dbg(net_dev, "phy device not initialized\n");
10285 + return 0;
10286 + }
10287 +
10288 + _errno = phy_ethtool_gset(priv->mac_dev->phy_dev, et_cmd);
10289 + if (unlikely(_errno < 0))
10290 + netdev_err(net_dev, "phy_ethtool_gset() = %d\n", _errno);
10291 +
10292 + return _errno;
10293 +}
10294 +
10295 +static int __cold dpa_set_settings(struct net_device *net_dev,
10296 + struct ethtool_cmd *et_cmd)
10297 +{
10298 + int _errno;
10299 + struct dpa_priv_s *priv;
10300 +
10301 + priv = netdev_priv(net_dev);
10302 +
10303 + if (priv->mac_dev == NULL) {
10304 + netdev_info(net_dev, "This is a MAC-less interface\n");
10305 + return -ENODEV;
10306 + }
10307 + if (unlikely(priv->mac_dev->phy_dev == NULL)) {
10308 + netdev_err(net_dev, "phy device not initialized\n");
10309 + return -ENODEV;
10310 + }
10311 +
10312 + _errno = phy_ethtool_sset(priv->mac_dev->phy_dev, et_cmd);
10313 + if (unlikely(_errno < 0))
10314 + netdev_err(net_dev, "phy_ethtool_sset() = %d\n", _errno);
10315 +
10316 + return _errno;
10317 +}
10318 +
10319 +static void __cold dpa_get_drvinfo(struct net_device *net_dev,
10320 + struct ethtool_drvinfo *drvinfo)
10321 +{
10322 + int _errno;
10323 +
10324 + strncpy(drvinfo->driver, KBUILD_MODNAME,
10325 + sizeof(drvinfo->driver) - 1)[sizeof(drvinfo->driver)-1] = 0;
10326 + _errno = snprintf(drvinfo->fw_version, sizeof(drvinfo->fw_version),
10327 + "%X", 0);
10328 +
10329 + if (unlikely(_errno >= sizeof(drvinfo->fw_version))) {
10330 + /* Truncated output */
10331 + netdev_notice(net_dev, "snprintf() = %d\n", _errno);
10332 + } else if (unlikely(_errno < 0)) {
10333 + netdev_warn(net_dev, "snprintf() = %d\n", _errno);
10334 + memset(drvinfo->fw_version, 0, sizeof(drvinfo->fw_version));
10335 + }
10336 + strncpy(drvinfo->bus_info, dev_name(net_dev->dev.parent->parent),
10337 + sizeof(drvinfo->bus_info)-1)[sizeof(drvinfo->bus_info)-1] = 0;
10338 +}
10339 +
10340 +static uint32_t __cold dpa_get_msglevel(struct net_device *net_dev)
10341 +{
10342 + return ((struct dpa_priv_s *)netdev_priv(net_dev))->msg_enable;
10343 +}
10344 +
10345 +static void __cold dpa_set_msglevel(struct net_device *net_dev,
10346 + uint32_t msg_enable)
10347 +{
10348 + ((struct dpa_priv_s *)netdev_priv(net_dev))->msg_enable = msg_enable;
10349 +}
10350 +
10351 +static int __cold dpa_nway_reset(struct net_device *net_dev)
10352 +{
10353 + int _errno;
10354 + struct dpa_priv_s *priv;
10355 +
10356 + priv = netdev_priv(net_dev);
10357 +
10358 + if (priv->mac_dev == NULL) {
10359 + netdev_info(net_dev, "This is a MAC-less interface\n");
10360 + return -ENODEV;
10361 + }
10362 + if (unlikely(priv->mac_dev->phy_dev == NULL)) {
10363 + netdev_err(net_dev, "phy device not initialized\n");
10364 + return -ENODEV;
10365 + }
10366 +
10367 + _errno = 0;
10368 + if (priv->mac_dev->phy_dev->autoneg) {
10369 + _errno = phy_start_aneg(priv->mac_dev->phy_dev);
10370 + if (unlikely(_errno < 0))
10371 + netdev_err(net_dev, "phy_start_aneg() = %d\n",
10372 + _errno);
10373 + }
10374 +
10375 + return _errno;
10376 +}
10377 +
10378 +static void __cold dpa_get_pauseparam(struct net_device *net_dev,
10379 + struct ethtool_pauseparam *epause)
10380 +{
10381 + struct dpa_priv_s *priv;
10382 + struct mac_device *mac_dev;
10383 + struct phy_device *phy_dev;
10384 +
10385 + priv = netdev_priv(net_dev);
10386 + mac_dev = priv->mac_dev;
10387 +
10388 + if (mac_dev == NULL) {
10389 + netdev_info(net_dev, "This is a MAC-less interface\n");
10390 + return;
10391 + }
10392 +
10393 + phy_dev = mac_dev->phy_dev;
10394 + if (unlikely(phy_dev == NULL)) {
10395 + netdev_err(net_dev, "phy device not initialized\n");
10396 + return;
10397 + }
10398 +
10399 + epause->autoneg = mac_dev->autoneg_pause;
10400 + epause->rx_pause = mac_dev->rx_pause_active;
10401 + epause->tx_pause = mac_dev->tx_pause_active;
10402 +}
10403 +
10404 +static int __cold dpa_set_pauseparam(struct net_device *net_dev,
10405 + struct ethtool_pauseparam *epause)
10406 +{
10407 + struct dpa_priv_s *priv;
10408 + struct mac_device *mac_dev;
10409 + struct phy_device *phy_dev;
10410 + int _errno;
10411 + u32 newadv, oldadv;
10412 + bool rx_pause, tx_pause;
10413 +
10414 + priv = netdev_priv(net_dev);
10415 + mac_dev = priv->mac_dev;
10416 +
10417 + if (mac_dev == NULL) {
10418 + netdev_info(net_dev, "This is a MAC-less interface\n");
10419 + return -ENODEV;
10420 + }
10421 +
10422 + phy_dev = mac_dev->phy_dev;
10423 + if (unlikely(phy_dev == NULL)) {
10424 + netdev_err(net_dev, "phy device not initialized\n");
10425 + return -ENODEV;
10426 + }
10427 +
10428 + if (!(phy_dev->supported & SUPPORTED_Pause) ||
10429 + (!(phy_dev->supported & SUPPORTED_Asym_Pause) &&
10430 + (epause->rx_pause != epause->tx_pause)))
10431 + return -EINVAL;
10432 +
10433 + /* The MAC should know how to handle PAUSE frame autonegotiation before
10434 + * adjust_link is triggered by a forced renegotiation of sym/asym PAUSE
10435 + * settings.
10436 + */
10437 + mac_dev->autoneg_pause = !!epause->autoneg;
10438 + mac_dev->rx_pause_req = !!epause->rx_pause;
10439 + mac_dev->tx_pause_req = !!epause->tx_pause;
10440 +
10441 + /* Determine the sym/asym advertised PAUSE capabilities from the desired
10442 + * rx/tx pause settings.
10443 + */
10444 + newadv = 0;
10445 + if (epause->rx_pause)
10446 + newadv = ADVERTISED_Pause | ADVERTISED_Asym_Pause;
10447 + if (epause->tx_pause)
10448 + newadv |= ADVERTISED_Asym_Pause;
10449 +
10450 + oldadv = phy_dev->advertising &
10451 + (ADVERTISED_Pause | ADVERTISED_Asym_Pause);
10452 +
10453 + /* If there are differences between the old and the new advertised
10454 + * values, restart PHY autonegotiation and advertise the new values.
10455 + */
10456 + if (oldadv != newadv) {
10457 + phy_dev->advertising &= ~(ADVERTISED_Pause
10458 + | ADVERTISED_Asym_Pause);
10459 + phy_dev->advertising |= newadv;
10460 + if (phy_dev->autoneg) {
10461 + _errno = phy_start_aneg(phy_dev);
10462 + if (unlikely(_errno < 0))
10463 + netdev_err(net_dev, "phy_start_aneg() = %d\n",
10464 + _errno);
10465 + }
10466 + }
10467 +
10468 + get_pause_cfg(mac_dev, &rx_pause, &tx_pause);
10469 + _errno = set_mac_active_pause(mac_dev, rx_pause, tx_pause);
10470 + if (unlikely(_errno < 0))
10471 + netdev_err(net_dev, "set_mac_active_pause() = %d\n", _errno);
10472 +
10473 + return _errno;
10474 +}
10475 +
10476 +#ifdef CONFIG_PM
10477 +static void dpa_get_wol(struct net_device *net_dev, struct ethtool_wolinfo *wol)
10478 +{
10479 + struct dpa_priv_s *priv = netdev_priv(net_dev);
10480 +
10481 + wol->supported = 0;
10482 + wol->wolopts = 0;
10483 +
10484 + if (!priv->wol || !device_can_wakeup(net_dev->dev.parent))
10485 + return;
10486 +
10487 + if (priv->wol & DPAA_WOL_MAGIC) {
10488 + wol->supported = WAKE_MAGIC;
10489 + wol->wolopts = WAKE_MAGIC;
10490 + }
10491 +}
10492 +
10493 +static int dpa_set_wol(struct net_device *net_dev, struct ethtool_wolinfo *wol)
10494 +{
10495 + struct dpa_priv_s *priv = netdev_priv(net_dev);
10496 +
10497 + if (priv->mac_dev == NULL) {
10498 + netdev_info(net_dev, "This is a MAC-less interface\n");
10499 + return -ENODEV;
10500 + }
10501 +
10502 + if (unlikely(priv->mac_dev->phy_dev == NULL)) {
10503 + netdev_dbg(net_dev, "phy device not initialized\n");
10504 + return -ENODEV;
10505 + }
10506 +
10507 + if (!device_can_wakeup(net_dev->dev.parent) ||
10508 + (wol->wolopts & ~WAKE_MAGIC))
10509 + return -EOPNOTSUPP;
10510 +
10511 + priv->wol = 0;
10512 +
10513 + if (wol->wolopts & WAKE_MAGIC) {
10514 + priv->wol = DPAA_WOL_MAGIC;
10515 + device_set_wakeup_enable(net_dev->dev.parent, 1);
10516 + } else {
10517 + device_set_wakeup_enable(net_dev->dev.parent, 0);
10518 + }
10519 +
10520 + return 0;
10521 +}
10522 +#endif
10523 +
10524 +static int dpa_get_eee(struct net_device *net_dev, struct ethtool_eee *et_eee)
10525 +{
10526 + struct dpa_priv_s *priv;
10527 +
10528 + priv = netdev_priv(net_dev);
10529 + if (priv->mac_dev == NULL) {
10530 + netdev_info(net_dev, "This is a MAC-less interface\n");
10531 + return -ENODEV;
10532 + }
10533 +
10534 + if (unlikely(priv->mac_dev->phy_dev == NULL)) {
10535 + netdev_err(net_dev, "phy device not initialized\n");
10536 + return -ENODEV;
10537 + }
10538 +
10539 + return phy_ethtool_get_eee(priv->mac_dev->phy_dev, et_eee);
10540 +}
10541 +
10542 +static int dpa_set_eee(struct net_device *net_dev, struct ethtool_eee *et_eee)
10543 +{
10544 + struct dpa_priv_s *priv;
10545 +
10546 + priv = netdev_priv(net_dev);
10547 + if (priv->mac_dev == NULL) {
10548 + netdev_info(net_dev, "This is a MAC-less interface\n");
10549 + return -ENODEV;
10550 + }
10551 +
10552 + if (unlikely(priv->mac_dev->phy_dev == NULL)) {
10553 + netdev_err(net_dev, "phy device not initialized\n");
10554 + return -ENODEV;
10555 + }
10556 +
10557 + return phy_ethtool_set_eee(priv->mac_dev->phy_dev, et_eee);
10558 +}
10559 +
10560 +static int dpa_get_sset_count(struct net_device *net_dev, int type)
10561 +{
10562 + unsigned int total_stats, num_stats;
10563 +
10564 + num_stats = num_online_cpus() + 1;
10565 + total_stats = num_stats * DPA_STATS_PERCPU_LEN + DPA_STATS_GLOBAL_LEN;
10566 +
10567 + switch (type) {
10568 + case ETH_SS_STATS:
10569 + return total_stats;
10570 + default:
10571 + return -EOPNOTSUPP;
10572 + }
10573 +}
10574 +
10575 +static void copy_stats(struct dpa_percpu_priv_s *percpu_priv, int num_cpus,
10576 + int crr_cpu, u64 bp_count, u64 *data)
10577 +{
10578 + int num_stat_values = num_cpus + 1;
10579 + int crr_stat = 0;
10580 +
10581 + /* update current CPU's stats and also add them to the total values */
10582 + data[crr_stat * num_stat_values + crr_cpu] = percpu_priv->in_interrupt;
10583 + data[crr_stat++ * num_stat_values + num_cpus] += percpu_priv->in_interrupt;
10584 +
10585 + data[crr_stat * num_stat_values + crr_cpu] = percpu_priv->stats.rx_packets;
10586 + data[crr_stat++ * num_stat_values + num_cpus] += percpu_priv->stats.rx_packets;
10587 +
10588 + data[crr_stat * num_stat_values + crr_cpu] = percpu_priv->stats.tx_packets;
10589 + data[crr_stat++ * num_stat_values + num_cpus] += percpu_priv->stats.tx_packets;
10590 +
10591 + data[crr_stat * num_stat_values + crr_cpu] = percpu_priv->tx_returned;
10592 + data[crr_stat++ * num_stat_values + num_cpus] += percpu_priv->tx_returned;
10593 +
10594 + data[crr_stat * num_stat_values + crr_cpu] = percpu_priv->tx_confirm;
10595 + data[crr_stat++ * num_stat_values + num_cpus] += percpu_priv->tx_confirm;
10596 +
10597 + data[crr_stat * num_stat_values + crr_cpu] = percpu_priv->tx_frag_skbuffs;
10598 + data[crr_stat++ * num_stat_values + num_cpus] += percpu_priv->tx_frag_skbuffs;
10599 +
10600 + data[crr_stat * num_stat_values + crr_cpu] = percpu_priv->rx_sg;
10601 + data[crr_stat++ * num_stat_values + num_cpus] += percpu_priv->rx_sg;
10602 +
10603 + data[crr_stat * num_stat_values + crr_cpu] = percpu_priv->stats.tx_errors;
10604 + data[crr_stat++ * num_stat_values + num_cpus] += percpu_priv->stats.tx_errors;
10605 +
10606 + data[crr_stat * num_stat_values + crr_cpu] = percpu_priv->stats.rx_errors;
10607 + data[crr_stat++ * num_stat_values + num_cpus] += percpu_priv->stats.rx_errors;
10608 +
10609 + data[crr_stat * num_stat_values + crr_cpu] = bp_count;
10610 + data[crr_stat++ * num_stat_values + num_cpus] += bp_count;
10611 +}
10612 +
10613 +static void dpa_get_ethtool_stats(struct net_device *net_dev,
10614 + struct ethtool_stats *stats, u64 *data)
10615 +{
10616 + u64 bp_count, cg_time, cg_num, cg_status;
10617 + struct dpa_percpu_priv_s *percpu_priv;
10618 + struct qm_mcr_querycgr query_cgr;
10619 + struct dpa_rx_errors rx_errors;
10620 + struct dpa_ern_cnt ern_cnt;
10621 + struct dpa_priv_s *priv;
10622 + unsigned int num_cpus, offset;
10623 + struct dpa_bp *dpa_bp;
10624 + int total_stats, i;
10625 +
10626 + total_stats = dpa_get_sset_count(net_dev, ETH_SS_STATS);
10627 + priv = netdev_priv(net_dev);
10628 + dpa_bp = priv->dpa_bp;
10629 + num_cpus = num_online_cpus();
10630 + bp_count = 0;
10631 +
10632 + memset(&rx_errors, 0, sizeof(struct dpa_rx_errors));
10633 + memset(&ern_cnt, 0, sizeof(struct dpa_ern_cnt));
10634 + memset(data, 0, total_stats * sizeof(u64));
10635 +
10636 + for_each_online_cpu(i) {
10637 + percpu_priv = per_cpu_ptr(priv->percpu_priv, i);
10638 +
10639 + if (dpa_bp->percpu_count)
10640 + bp_count = *(per_cpu_ptr(dpa_bp->percpu_count, i));
10641 +
10642 + rx_errors.dme += percpu_priv->rx_errors.dme;
10643 + rx_errors.fpe += percpu_priv->rx_errors.fpe;
10644 + rx_errors.fse += percpu_priv->rx_errors.fse;
10645 + rx_errors.phe += percpu_priv->rx_errors.phe;
10646 + rx_errors.cse += percpu_priv->rx_errors.cse;
10647 +
10648 + ern_cnt.cg_tdrop += percpu_priv->ern_cnt.cg_tdrop;
10649 + ern_cnt.wred += percpu_priv->ern_cnt.wred;
10650 + ern_cnt.err_cond += percpu_priv->ern_cnt.err_cond;
10651 + ern_cnt.early_window += percpu_priv->ern_cnt.early_window;
10652 + ern_cnt.late_window += percpu_priv->ern_cnt.late_window;
10653 + ern_cnt.fq_tdrop += percpu_priv->ern_cnt.fq_tdrop;
10654 + ern_cnt.fq_retired += percpu_priv->ern_cnt.fq_retired;
10655 + ern_cnt.orp_zero += percpu_priv->ern_cnt.orp_zero;
10656 +
10657 + copy_stats(percpu_priv, num_cpus, i, bp_count, data);
10658 + }
10659 +
10660 + offset = (num_cpus + 1) * DPA_STATS_PERCPU_LEN;
10661 + memcpy(data + offset, &rx_errors, sizeof(struct dpa_rx_errors));
10662 +
10663 + offset += sizeof(struct dpa_rx_errors) / sizeof(u64);
10664 + memcpy(data + offset, &ern_cnt, sizeof(struct dpa_ern_cnt));
10665 +
10666 + /* gather congestion related counters */
10667 + cg_num = 0;
10668 + cg_status = 0;
10669 + cg_time = jiffies_to_msecs(priv->cgr_data.congested_jiffies);
10670 + if (qman_query_cgr(&priv->cgr_data.cgr, &query_cgr) == 0) {
10671 + cg_num = priv->cgr_data.cgr_congested_count;
10672 + cg_status = query_cgr.cgr.cs;
10673 +
10674 + /* reset congestion stats (like QMan API does */
10675 + priv->cgr_data.congested_jiffies = 0;
10676 + priv->cgr_data.cgr_congested_count = 0;
10677 + }
10678 +
10679 + offset += sizeof(struct dpa_ern_cnt) / sizeof(u64);
10680 + data[offset++] = cg_time;
10681 + data[offset++] = cg_num;
10682 + data[offset++] = cg_status;
10683 +}
10684 +
10685 +static void dpa_get_strings(struct net_device *net_dev, u32 stringset, u8 *data)
10686 +{
10687 + unsigned int i, j, num_cpus, size;
10688 + char stat_string_cpu[ETH_GSTRING_LEN];
10689 + u8 *strings;
10690 +
10691 + strings = data;
10692 + num_cpus = num_online_cpus();
10693 + size = DPA_STATS_GLOBAL_LEN * ETH_GSTRING_LEN;
10694 +
10695 + for (i = 0; i < DPA_STATS_PERCPU_LEN; i++) {
10696 + for (j = 0; j < num_cpus; j++) {
10697 + snprintf(stat_string_cpu, ETH_GSTRING_LEN, "%s [CPU %d]", dpa_stats_percpu[i], j);
10698 + memcpy(strings, stat_string_cpu, ETH_GSTRING_LEN);
10699 + strings += ETH_GSTRING_LEN;
10700 + }
10701 + snprintf(stat_string_cpu, ETH_GSTRING_LEN, "%s [TOTAL]", dpa_stats_percpu[i]);
10702 + memcpy(strings, stat_string_cpu, ETH_GSTRING_LEN);
10703 + strings += ETH_GSTRING_LEN;
10704 + }
10705 + memcpy(strings, dpa_stats_global, size);
10706 +}
10707 +
10708 +const struct ethtool_ops dpa_ethtool_ops = {
10709 + .get_settings = dpa_get_settings,
10710 + .set_settings = dpa_set_settings,
10711 + .get_drvinfo = dpa_get_drvinfo,
10712 + .get_msglevel = dpa_get_msglevel,
10713 + .set_msglevel = dpa_set_msglevel,
10714 + .nway_reset = dpa_nway_reset,
10715 + .get_pauseparam = dpa_get_pauseparam,
10716 + .set_pauseparam = dpa_set_pauseparam,
10717 + .self_test = NULL, /* TODO invoke the cold-boot unit-test? */
10718 + .get_link = ethtool_op_get_link,
10719 + .get_eee = dpa_get_eee,
10720 + .set_eee = dpa_set_eee,
10721 + .get_sset_count = dpa_get_sset_count,
10722 + .get_ethtool_stats = dpa_get_ethtool_stats,
10723 + .get_strings = dpa_get_strings,
10724 +#ifdef CONFIG_PM
10725 + .get_wol = dpa_get_wol,
10726 + .set_wol = dpa_set_wol,
10727 +#endif
10728 +};
10729 --- /dev/null
10730 +++ b/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_ptp.c
10731 @@ -0,0 +1,291 @@
10732 +/*
10733 + * DPAA Ethernet Driver -- PTP 1588 clock using the dTSEC
10734 + *
10735 + * Author: Yangbo Lu <yangbo.lu@freescale.com>
10736 + *
10737 + * Copyright 2014 Freescale Semiconductor, Inc.
10738 + *
10739 + * This program is free software; you can redistribute it and/or modify it
10740 + * under the terms of the GNU General Public License as published by the
10741 + * Free Software Foundation; either version 2 of the License, or (at your
10742 + * option) any later version.
10743 +*/
10744 +
10745 +#include <linux/device.h>
10746 +#include <linux/hrtimer.h>
10747 +#include <linux/init.h>
10748 +#include <linux/interrupt.h>
10749 +#include <linux/kernel.h>
10750 +#include <linux/module.h>
10751 +#include <linux/of.h>
10752 +#include <linux/of_platform.h>
10753 +#include <linux/timex.h>
10754 +#include <linux/io.h>
10755 +
10756 +#include <linux/ptp_clock_kernel.h>
10757 +
10758 +#include "dpaa_eth.h"
10759 +#include "mac.h"
10760 +
10761 +static struct mac_device *mac_dev;
10762 +static u32 freqCompensation;
10763 +
10764 +/* Bit definitions for the TMR_CTRL register */
10765 +#define ALM1P (1<<31) /* Alarm1 output polarity */
10766 +#define ALM2P (1<<30) /* Alarm2 output polarity */
10767 +#define FS (1<<28) /* FIPER start indication */
10768 +#define PP1L (1<<27) /* Fiper1 pulse loopback mode enabled. */
10769 +#define PP2L (1<<26) /* Fiper2 pulse loopback mode enabled. */
10770 +#define TCLK_PERIOD_SHIFT (16) /* 1588 timer reference clock period. */
10771 +#define TCLK_PERIOD_MASK (0x3ff)
10772 +#define RTPE (1<<15) /* Record Tx Timestamp to PAL Enable. */
10773 +#define FRD (1<<14) /* FIPER Realignment Disable */
10774 +#define ESFDP (1<<11) /* External Tx/Rx SFD Polarity. */
10775 +#define ESFDE (1<<10) /* External Tx/Rx SFD Enable. */
10776 +#define ETEP2 (1<<9) /* External trigger 2 edge polarity */
10777 +#define ETEP1 (1<<8) /* External trigger 1 edge polarity */
10778 +#define COPH (1<<7) /* Generated clock output phase. */
10779 +#define CIPH (1<<6) /* External oscillator input clock phase */
10780 +#define TMSR (1<<5) /* Timer soft reset. */
10781 +#define BYP (1<<3) /* Bypass drift compensated clock */
10782 +#define TE (1<<2) /* 1588 timer enable. */
10783 +#define CKSEL_SHIFT (0) /* 1588 Timer reference clock source */
10784 +#define CKSEL_MASK (0x3)
10785 +
10786 +/* Bit definitions for the TMR_TEVENT register */
10787 +#define ETS2 (1<<25) /* External trigger 2 timestamp sampled */
10788 +#define ETS1 (1<<24) /* External trigger 1 timestamp sampled */
10789 +#define ALM2 (1<<17) /* Current time = alarm time register 2 */
10790 +#define ALM1 (1<<16) /* Current time = alarm time register 1 */
10791 +#define PP1 (1<<7) /* periodic pulse generated on FIPER1 */
10792 +#define PP2 (1<<6) /* periodic pulse generated on FIPER2 */
10793 +#define PP3 (1<<5) /* periodic pulse generated on FIPER3 */
10794 +
10795 +/* Bit definitions for the TMR_TEMASK register */
10796 +#define ETS2EN (1<<25) /* External trigger 2 timestamp enable */
10797 +#define ETS1EN (1<<24) /* External trigger 1 timestamp enable */
10798 +#define ALM2EN (1<<17) /* Timer ALM2 event enable */
10799 +#define ALM1EN (1<<16) /* Timer ALM1 event enable */
10800 +#define PP1EN (1<<7) /* Periodic pulse event 1 enable */
10801 +#define PP2EN (1<<6) /* Periodic pulse event 2 enable */
10802 +
10803 +/* Bit definitions for the TMR_PEVENT register */
10804 +#define TXP2 (1<<9) /* PTP transmitted timestamp im TXTS2 */
10805 +#define TXP1 (1<<8) /* PTP transmitted timestamp in TXTS1 */
10806 +#define RXP (1<<0) /* PTP frame has been received */
10807 +
10808 +/* Bit definitions for the TMR_PEMASK register */
10809 +#define TXP2EN (1<<9) /* Transmit PTP packet event 2 enable */
10810 +#define TXP1EN (1<<8) /* Transmit PTP packet event 1 enable */
10811 +#define RXPEN (1<<0) /* Receive PTP packet event enable */
10812 +
10813 +/* Bit definitions for the TMR_STAT register */
10814 +#define STAT_VEC_SHIFT (0) /* Timer general purpose status vector */
10815 +#define STAT_VEC_MASK (0x3f)
10816 +
10817 +/* Bit definitions for the TMR_PRSC register */
10818 +#define PRSC_OCK_SHIFT (0) /* Output clock division/prescale factor. */
10819 +#define PRSC_OCK_MASK (0xffff)
10820 +
10821 +
10822 +#define N_EXT_TS 2
10823 +
10824 +static void set_alarm(void)
10825 +{
10826 + u64 ns;
10827 +
10828 + if (mac_dev->fm_rtc_get_cnt)
10829 + mac_dev->fm_rtc_get_cnt(mac_dev->fm_dev, &ns);
10830 + ns += 1500000000ULL;
10831 + ns = div_u64(ns, 1000000000UL) * 1000000000ULL;
10832 + ns -= DPA_PTP_NOMINAL_FREQ_PERIOD_NS;
10833 + if (mac_dev->fm_rtc_set_alarm)
10834 + mac_dev->fm_rtc_set_alarm(mac_dev->fm_dev, 0, ns);
10835 +}
10836 +
10837 +static void set_fipers(void)
10838 +{
10839 + u64 fiper;
10840 +
10841 + if (mac_dev->fm_rtc_disable)
10842 + mac_dev->fm_rtc_disable(mac_dev->fm_dev);
10843 +
10844 + set_alarm();
10845 + fiper = 1000000000ULL - DPA_PTP_NOMINAL_FREQ_PERIOD_NS;
10846 + if (mac_dev->fm_rtc_set_fiper)
10847 + mac_dev->fm_rtc_set_fiper(mac_dev->fm_dev, 0, fiper);
10848 +
10849 + if (mac_dev->fm_rtc_enable)
10850 + mac_dev->fm_rtc_enable(mac_dev->fm_dev);
10851 +}
10852 +
10853 +/* PTP clock operations */
10854 +
10855 +static int ptp_dpa_adjfreq(struct ptp_clock_info *ptp, s32 ppb)
10856 +{
10857 + u64 adj;
10858 + u32 diff, tmr_add;
10859 + int neg_adj = 0;
10860 +
10861 + if (ppb < 0) {
10862 + neg_adj = 1;
10863 + ppb = -ppb;
10864 + }
10865 +
10866 + tmr_add = freqCompensation;
10867 + adj = tmr_add;
10868 + adj *= ppb;
10869 + diff = div_u64(adj, 1000000000ULL);
10870 +
10871 + tmr_add = neg_adj ? tmr_add - diff : tmr_add + diff;
10872 +
10873 + if (mac_dev->fm_rtc_set_drift)
10874 + mac_dev->fm_rtc_set_drift(mac_dev->fm_dev, tmr_add);
10875 +
10876 + return 0;
10877 +}
10878 +
10879 +static int ptp_dpa_adjtime(struct ptp_clock_info *ptp, s64 delta)
10880 +{
10881 + s64 now;
10882 +
10883 + if (mac_dev->fm_rtc_get_cnt)
10884 + mac_dev->fm_rtc_get_cnt(mac_dev->fm_dev, &now);
10885 +
10886 + now += delta;
10887 +
10888 + if (mac_dev->fm_rtc_set_cnt)
10889 + mac_dev->fm_rtc_set_cnt(mac_dev->fm_dev, now);
10890 + set_fipers();
10891 +
10892 + return 0;
10893 +}
10894 +
10895 +static int ptp_dpa_gettime(struct ptp_clock_info *ptp, struct timespec64 *ts)
10896 +{
10897 + u64 ns;
10898 + u32 remainder;
10899 +
10900 + if (mac_dev->fm_rtc_get_cnt)
10901 + mac_dev->fm_rtc_get_cnt(mac_dev->fm_dev, &ns);
10902 +
10903 + ts->tv_sec = div_u64_rem(ns, 1000000000, &remainder);
10904 + ts->tv_nsec = remainder;
10905 + return 0;
10906 +}
10907 +
10908 +static int ptp_dpa_settime(struct ptp_clock_info *ptp,
10909 + const struct timespec64 *ts)
10910 +{
10911 + u64 ns;
10912 +
10913 + ns = ts->tv_sec * 1000000000ULL;
10914 + ns += ts->tv_nsec;
10915 +
10916 + if (mac_dev->fm_rtc_set_cnt)
10917 + mac_dev->fm_rtc_set_cnt(mac_dev->fm_dev, ns);
10918 + set_fipers();
10919 + return 0;
10920 +}
10921 +
10922 +static int ptp_dpa_enable(struct ptp_clock_info *ptp,
10923 + struct ptp_clock_request *rq, int on)
10924 +{
10925 + u32 bit;
10926 +
10927 + switch (rq->type) {
10928 + case PTP_CLK_REQ_EXTTS:
10929 + switch (rq->extts.index) {
10930 + case 0:
10931 + bit = ETS1EN;
10932 + break;
10933 + case 1:
10934 + bit = ETS2EN;
10935 + break;
10936 + default:
10937 + return -EINVAL;
10938 + }
10939 + if (on) {
10940 + if (mac_dev->fm_rtc_enable_interrupt)
10941 + mac_dev->fm_rtc_enable_interrupt(
10942 + mac_dev->fm_dev, bit);
10943 + } else {
10944 + if (mac_dev->fm_rtc_disable_interrupt)
10945 + mac_dev->fm_rtc_disable_interrupt(
10946 + mac_dev->fm_dev, bit);
10947 + }
10948 + return 0;
10949 +
10950 + case PTP_CLK_REQ_PPS:
10951 + if (on) {
10952 + if (mac_dev->fm_rtc_enable_interrupt)
10953 + mac_dev->fm_rtc_enable_interrupt(
10954 + mac_dev->fm_dev, PP1EN);
10955 + } else {
10956 + if (mac_dev->fm_rtc_disable_interrupt)
10957 + mac_dev->fm_rtc_disable_interrupt(
10958 + mac_dev->fm_dev, PP1EN);
10959 + }
10960 + return 0;
10961 +
10962 + default:
10963 + break;
10964 + }
10965 +
10966 + return -EOPNOTSUPP;
10967 +}
10968 +
10969 +static struct ptp_clock_info ptp_dpa_caps = {
10970 + .owner = THIS_MODULE,
10971 + .name = "dpaa clock",
10972 + .max_adj = 512000,
10973 + .n_alarm = 0,
10974 + .n_ext_ts = N_EXT_TS,
10975 + .n_per_out = 0,
10976 + .pps = 1,
10977 + .adjfreq = ptp_dpa_adjfreq,
10978 + .adjtime = ptp_dpa_adjtime,
10979 + .gettime64 = ptp_dpa_gettime,
10980 + .settime64 = ptp_dpa_settime,
10981 + .enable = ptp_dpa_enable,
10982 +};
10983 +
10984 +static int __init __cold dpa_ptp_load(void)
10985 +{
10986 + struct device *ptp_dev;
10987 + struct timespec64 now;
10988 + struct ptp_clock *clock = ptp_priv.clock;
10989 + int dpa_phc_index;
10990 + int err;
10991 +
10992 + if (!(ptp_priv.of_dev && ptp_priv.mac_dev))
10993 + return -ENODEV;
10994 +
10995 + ptp_dev = &ptp_priv.of_dev->dev;
10996 + mac_dev = ptp_priv.mac_dev;
10997 +
10998 + if (mac_dev->fm_rtc_get_drift)
10999 + mac_dev->fm_rtc_get_drift(mac_dev->fm_dev, &freqCompensation);
11000 +
11001 + getnstimeofday64(&now);
11002 + ptp_dpa_settime(&ptp_dpa_caps, &now);
11003 +
11004 + clock = ptp_clock_register(&ptp_dpa_caps, ptp_dev);
11005 + if (IS_ERR(clock)) {
11006 + err = PTR_ERR(clock);
11007 + return err;
11008 + }
11009 + dpa_phc_index = ptp_clock_index(clock);
11010 + return 0;
11011 +}
11012 +module_init(dpa_ptp_load);
11013 +
11014 +static void __exit __cold dpa_ptp_unload(void)
11015 +{
11016 + struct ptp_clock *clock = ptp_priv.clock;
11017 +
11018 + if (mac_dev->fm_rtc_disable_interrupt)
11019 + mac_dev->fm_rtc_disable_interrupt(mac_dev->fm_dev, 0xffffffff);
11020 + ptp_clock_unregister(clock);
11021 +}
11022 +module_exit(dpa_ptp_unload);
11023 --- /dev/null
11024 +++ b/drivers/net/ethernet/freescale/sdk_dpaa/mac-api.c
11025 @@ -0,0 +1,907 @@
11026 +/* Copyright 2008-2012 Freescale Semiconductor, Inc.
11027 + *
11028 + * Redistribution and use in source and binary forms, with or without
11029 + * modification, are permitted provided that the following conditions are met:
11030 + * * Redistributions of source code must retain the above copyright
11031 + * notice, this list of conditions and the following disclaimer.
11032 + * * Redistributions in binary form must reproduce the above copyright
11033 + * notice, this list of conditions and the following disclaimer in the
11034 + * documentation and/or other materials provided with the distribution.
11035 + * * Neither the name of Freescale Semiconductor nor the
11036 + * names of its contributors may be used to endorse or promote products
11037 + * derived from this software without specific prior written permission.
11038 + *
11039 + *
11040 + * ALTERNATIVELY, this software may be distributed under the terms of the
11041 + * GNU General Public License ("GPL") as published by the Free Software
11042 + * Foundation, either version 2 of that License or (at your option) any
11043 + * later version.
11044 + *
11045 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
11046 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
11047 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
11048 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
11049 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
11050 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
11051 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
11052 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
11053 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
11054 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
11055 + */
11056 +
11057 +#ifdef CONFIG_FSL_DPAA_ETH_DEBUG
11058 +#define pr_fmt(fmt) \
11059 + KBUILD_MODNAME ": %s:%hu:%s() " fmt, \
11060 + KBUILD_BASENAME".c", __LINE__, __func__
11061 +#else
11062 +#define pr_fmt(fmt) \
11063 + KBUILD_MODNAME ": " fmt
11064 +#endif
11065 +
11066 +#include <linux/init.h>
11067 +#include <linux/module.h>
11068 +#include <linux/io.h>
11069 +#include <linux/of_platform.h>
11070 +#include <linux/of_mdio.h>
11071 +#include <linux/phy.h>
11072 +#include <linux/netdevice.h>
11073 +
11074 +#include "dpaa_eth.h"
11075 +#include "mac.h"
11076 +#include "lnxwrp_fsl_fman.h"
11077 +
11078 +#include "error_ext.h" /* GET_ERROR_TYPE, E_OK */
11079 +
11080 +#include "fsl_fman_dtsec.h"
11081 +#include "fsl_fman_tgec.h"
11082 +#include "fsl_fman_memac.h"
11083 +#include "../sdk_fman/src/wrapper/lnxwrp_sysfs_fm.h"
11084 +
11085 +#define MAC_DESCRIPTION "FSL FMan MAC API based driver"
11086 +
11087 +MODULE_LICENSE("Dual BSD/GPL");
11088 +
11089 +MODULE_AUTHOR("Emil Medve <Emilian.Medve@Freescale.com>");
11090 +
11091 +MODULE_DESCRIPTION(MAC_DESCRIPTION);
11092 +
11093 +struct mac_priv_s {
11094 + struct fm_mac_dev *fm_mac;
11095 +};
11096 +
11097 +const char *mac_driver_description __initconst = MAC_DESCRIPTION;
11098 +const size_t mac_sizeof_priv[] = {
11099 + [DTSEC] = sizeof(struct mac_priv_s),
11100 + [XGMAC] = sizeof(struct mac_priv_s),
11101 + [MEMAC] = sizeof(struct mac_priv_s)
11102 +};
11103 +
11104 +static const enet_mode_t _100[] = {
11105 + [PHY_INTERFACE_MODE_MII] = e_ENET_MODE_MII_100,
11106 + [PHY_INTERFACE_MODE_RMII] = e_ENET_MODE_RMII_100
11107 +};
11108 +
11109 +static const enet_mode_t _1000[] = {
11110 + [PHY_INTERFACE_MODE_GMII] = e_ENET_MODE_GMII_1000,
11111 + [PHY_INTERFACE_MODE_SGMII] = e_ENET_MODE_SGMII_1000,
11112 + [PHY_INTERFACE_MODE_QSGMII] = e_ENET_MODE_QSGMII_1000,
11113 + [PHY_INTERFACE_MODE_TBI] = e_ENET_MODE_TBI_1000,
11114 + [PHY_INTERFACE_MODE_RGMII] = e_ENET_MODE_RGMII_1000,
11115 + [PHY_INTERFACE_MODE_RGMII_ID] = e_ENET_MODE_RGMII_1000,
11116 + [PHY_INTERFACE_MODE_RGMII_RXID] = e_ENET_MODE_RGMII_1000,
11117 + [PHY_INTERFACE_MODE_RGMII_TXID] = e_ENET_MODE_RGMII_1000,
11118 + [PHY_INTERFACE_MODE_RTBI] = e_ENET_MODE_RTBI_1000
11119 +};
11120 +
11121 +static enet_mode_t __cold __attribute__((nonnull))
11122 +macdev2enetinterface(const struct mac_device *mac_dev)
11123 +{
11124 + switch (mac_dev->max_speed) {
11125 + case SPEED_100:
11126 + return _100[mac_dev->phy_if];
11127 + case SPEED_1000:
11128 + return _1000[mac_dev->phy_if];
11129 + case SPEED_2500:
11130 + return e_ENET_MODE_SGMII_2500;
11131 + case SPEED_10000:
11132 + return e_ENET_MODE_XGMII_10000;
11133 + default:
11134 + return e_ENET_MODE_MII_100;
11135 + }
11136 +}
11137 +
11138 +static void mac_exception(handle_t _mac_dev, e_FmMacExceptions exception)
11139 +{
11140 + struct mac_device *mac_dev;
11141 +
11142 + mac_dev = (struct mac_device *)_mac_dev;
11143 +
11144 + if (e_FM_MAC_EX_10G_RX_FIFO_OVFL == exception) {
11145 + /* don't flag RX FIFO after the first */
11146 + fm_mac_set_exception(mac_dev->get_mac_handle(mac_dev),
11147 + e_FM_MAC_EX_10G_RX_FIFO_OVFL, false);
11148 + dev_err(mac_dev->dev, "10G MAC got RX FIFO Error = %x\n",
11149 + exception);
11150 + }
11151 +
11152 + dev_dbg(mac_dev->dev, "%s:%s() -> %d\n", KBUILD_BASENAME".c", __func__,
11153 + exception);
11154 +}
11155 +
11156 +static int __cold init(struct mac_device *mac_dev)
11157 +{
11158 + int _errno;
11159 + struct mac_priv_s *priv;
11160 + t_FmMacParams param;
11161 + uint32_t version;
11162 +
11163 + priv = macdev_priv(mac_dev);
11164 +
11165 + param.baseAddr = (typeof(param.baseAddr))(uintptr_t)devm_ioremap(
11166 + mac_dev->dev, mac_dev->res->start, 0x2000);
11167 + param.enetMode = macdev2enetinterface(mac_dev);
11168 + memcpy(&param.addr, mac_dev->addr, min(sizeof(param.addr),
11169 + sizeof(mac_dev->addr)));
11170 + param.macId = mac_dev->cell_index;
11171 + param.h_Fm = (handle_t)mac_dev->fm;
11172 + param.mdioIrq = NO_IRQ;
11173 + param.f_Exception = mac_exception;
11174 + param.f_Event = mac_exception;
11175 + param.h_App = mac_dev;
11176 +
11177 + priv->fm_mac = fm_mac_config(&param);
11178 + if (unlikely(priv->fm_mac == NULL)) {
11179 + _errno = -EINVAL;
11180 + goto _return;
11181 + }
11182 +
11183 + fm_mac_set_handle(mac_dev->fm_dev, priv->fm_mac,
11184 + (macdev2enetinterface(mac_dev) != e_ENET_MODE_XGMII_10000) ?
11185 + param.macId : param.macId + FM_MAX_NUM_OF_1G_MACS);
11186 +
11187 + _errno = fm_mac_config_max_frame_length(priv->fm_mac,
11188 + fm_get_max_frm());
11189 + if (unlikely(_errno < 0))
11190 + goto _return_fm_mac_free;
11191 +
11192 + if (macdev2enetinterface(mac_dev) != e_ENET_MODE_XGMII_10000) {
11193 + /* 10G always works with pad and CRC */
11194 + _errno = fm_mac_config_pad_and_crc(priv->fm_mac, true);
11195 + if (unlikely(_errno < 0))
11196 + goto _return_fm_mac_free;
11197 +
11198 + _errno = fm_mac_config_half_duplex(priv->fm_mac,
11199 + mac_dev->half_duplex);
11200 + if (unlikely(_errno < 0))
11201 + goto _return_fm_mac_free;
11202 + } else {
11203 + _errno = fm_mac_config_reset_on_init(priv->fm_mac, true);
11204 + if (unlikely(_errno < 0))
11205 + goto _return_fm_mac_free;
11206 + }
11207 +
11208 + _errno = fm_mac_init(priv->fm_mac);
11209 + if (unlikely(_errno < 0))
11210 + goto _return_fm_mac_free;
11211 +
11212 +#ifndef CONFIG_FMAN_MIB_CNT_OVF_IRQ_EN
11213 + /* For 1G MAC, disable by default the MIB counters overflow interrupt */
11214 + if (macdev2enetinterface(mac_dev) != e_ENET_MODE_XGMII_10000) {
11215 + _errno = fm_mac_set_exception(mac_dev->get_mac_handle(mac_dev),
11216 + e_FM_MAC_EX_1G_RX_MIB_CNT_OVFL, FALSE);
11217 + if (unlikely(_errno < 0))
11218 + goto _return_fm_mac_free;
11219 + }
11220 +#endif /* !CONFIG_FMAN_MIB_CNT_OVF_IRQ_EN */
11221 +
11222 + /* For 10G MAC, disable Tx ECC exception */
11223 + if (macdev2enetinterface(mac_dev) == e_ENET_MODE_XGMII_10000) {
11224 + _errno = fm_mac_set_exception(mac_dev->get_mac_handle(mac_dev),
11225 + e_FM_MAC_EX_10G_1TX_ECC_ER, FALSE);
11226 + if (unlikely(_errno < 0))
11227 + goto _return_fm_mac_free;
11228 + }
11229 +
11230 + _errno = fm_mac_get_version(priv->fm_mac, &version);
11231 + if (unlikely(_errno < 0))
11232 + goto _return_fm_mac_free;
11233 +
11234 + dev_info(mac_dev->dev, "FMan %s version: 0x%08x\n",
11235 + ((macdev2enetinterface(mac_dev) != e_ENET_MODE_XGMII_10000) ?
11236 + "dTSEC" : "XGEC"), version);
11237 +
11238 + goto _return;
11239 +
11240 +
11241 +_return_fm_mac_free:
11242 + fm_mac_free(mac_dev->get_mac_handle(mac_dev));
11243 +
11244 +_return:
11245 + return _errno;
11246 +}
11247 +
11248 +static int __cold memac_init(struct mac_device *mac_dev)
11249 +{
11250 + int _errno;
11251 + struct mac_priv_s *priv;
11252 + t_FmMacParams param;
11253 +
11254 + priv = macdev_priv(mac_dev);
11255 +
11256 + param.baseAddr = (typeof(param.baseAddr))(uintptr_t)devm_ioremap(
11257 + mac_dev->dev, mac_dev->res->start, 0x2000);
11258 + param.enetMode = macdev2enetinterface(mac_dev);
11259 + memcpy(&param.addr, mac_dev->addr, sizeof(mac_dev->addr));
11260 + param.macId = mac_dev->cell_index;
11261 + param.h_Fm = (handle_t)mac_dev->fm;
11262 + param.mdioIrq = NO_IRQ;
11263 + param.f_Exception = mac_exception;
11264 + param.f_Event = mac_exception;
11265 + param.h_App = mac_dev;
11266 +
11267 + priv->fm_mac = fm_mac_config(&param);
11268 + if (unlikely(priv->fm_mac == NULL)) {
11269 + _errno = -EINVAL;
11270 + goto _return;
11271 + }
11272 +
11273 + fm_mac_set_handle(mac_dev->fm_dev, priv->fm_mac,
11274 + (macdev2enetinterface(mac_dev) != e_ENET_MODE_XGMII_10000) ?
11275 + param.macId : param.macId + FM_MAX_NUM_OF_1G_MACS);
11276 +
11277 + _errno = fm_mac_config_max_frame_length(priv->fm_mac, fm_get_max_frm());
11278 + if (unlikely(_errno < 0))
11279 + goto _return_fm_mac_free;
11280 +
11281 + _errno = fm_mac_config_reset_on_init(priv->fm_mac, true);
11282 + if (unlikely(_errno < 0))
11283 + goto _return_fm_mac_free;
11284 +
11285 + _errno = fm_mac_init(priv->fm_mac);
11286 + if (unlikely(_errno < 0))
11287 + goto _return_fm_mac_free;
11288 +
11289 + dev_info(mac_dev->dev, "FMan MEMAC\n");
11290 +
11291 + goto _return;
11292 +
11293 +_return_fm_mac_free:
11294 + fm_mac_free(priv->fm_mac);
11295 +
11296 +_return:
11297 + return _errno;
11298 +}
11299 +
11300 +static int __cold start(struct mac_device *mac_dev)
11301 +{
11302 + int _errno;
11303 + struct phy_device *phy_dev = mac_dev->phy_dev;
11304 +
11305 + _errno = fm_mac_enable(mac_dev->get_mac_handle(mac_dev));
11306 +
11307 + if (!_errno && phy_dev)
11308 + phy_start(phy_dev);
11309 +
11310 + return _errno;
11311 +}
11312 +
11313 +static int __cold stop(struct mac_device *mac_dev)
11314 +{
11315 + if (mac_dev->phy_dev)
11316 + phy_stop(mac_dev->phy_dev);
11317 +
11318 + return fm_mac_disable(mac_dev->get_mac_handle(mac_dev));
11319 +}
11320 +
11321 +static int __cold set_multi(struct net_device *net_dev,
11322 + struct mac_device *mac_dev)
11323 +{
11324 + struct mac_priv_s *mac_priv;
11325 + struct mac_address *old_addr, *tmp;
11326 + struct netdev_hw_addr *ha;
11327 + int _errno;
11328 +
11329 + mac_priv = macdev_priv(mac_dev);
11330 +
11331 + /* Clear previous address list */
11332 + list_for_each_entry_safe(old_addr, tmp, &mac_dev->mc_addr_list, list) {
11333 + _errno = fm_mac_remove_hash_mac_addr(mac_priv->fm_mac,
11334 + (t_EnetAddr *)old_addr->addr);
11335 + if (_errno < 0)
11336 + return _errno;
11337 +
11338 + list_del(&old_addr->list);
11339 + kfree(old_addr);
11340 + }
11341 +
11342 + /* Add all the addresses from the new list */
11343 + netdev_for_each_mc_addr(ha, net_dev) {
11344 + _errno = fm_mac_add_hash_mac_addr(mac_priv->fm_mac,
11345 + (t_EnetAddr *)ha->addr);
11346 + if (_errno < 0)
11347 + return _errno;
11348 +
11349 + tmp = kmalloc(sizeof(struct mac_address), GFP_ATOMIC);
11350 + if (!tmp) {
11351 + dev_err(mac_dev->dev, "Out of memory\n");
11352 + return -ENOMEM;
11353 + }
11354 + memcpy(tmp->addr, ha->addr, ETH_ALEN);
11355 + list_add(&tmp->list, &mac_dev->mc_addr_list);
11356 + }
11357 + return 0;
11358 +}
11359 +
11360 +/* Avoid redundant calls to FMD, if the MAC driver already contains the desired
11361 + * active PAUSE settings. Otherwise, the new active settings should be reflected
11362 + * in FMan.
11363 + */
11364 +int set_mac_active_pause(struct mac_device *mac_dev, bool rx, bool tx)
11365 +{
11366 + struct fm_mac_dev *fm_mac_dev = mac_dev->get_mac_handle(mac_dev);
11367 + int _errno = 0;
11368 +
11369 + if (unlikely(rx != mac_dev->rx_pause_active)) {
11370 + _errno = fm_mac_set_rx_pause_frames(fm_mac_dev, rx);
11371 + if (likely(_errno == 0))
11372 + mac_dev->rx_pause_active = rx;
11373 + }
11374 +
11375 + if (unlikely(tx != mac_dev->tx_pause_active)) {
11376 + _errno = fm_mac_set_tx_pause_frames(fm_mac_dev, tx);
11377 + if (likely(_errno == 0))
11378 + mac_dev->tx_pause_active = tx;
11379 + }
11380 +
11381 + return _errno;
11382 +}
11383 +EXPORT_SYMBOL(set_mac_active_pause);
11384 +
11385 +/* Determine the MAC RX/TX PAUSE frames settings based on PHY
11386 + * autonegotiation or values set by eththool.
11387 + */
11388 +void get_pause_cfg(struct mac_device *mac_dev, bool *rx_pause, bool *tx_pause)
11389 +{
11390 + struct phy_device *phy_dev = mac_dev->phy_dev;
11391 + u16 lcl_adv, rmt_adv;
11392 + u8 flowctrl;
11393 +
11394 + *rx_pause = *tx_pause = false;
11395 +
11396 + if (!phy_dev->duplex)
11397 + return;
11398 +
11399 + /* If PAUSE autonegotiation is disabled, the TX/RX PAUSE settings
11400 + * are those set by ethtool.
11401 + */
11402 + if (!mac_dev->autoneg_pause) {
11403 + *rx_pause = mac_dev->rx_pause_req;
11404 + *tx_pause = mac_dev->tx_pause_req;
11405 + return;
11406 + }
11407 +
11408 + /* Else if PAUSE autonegotiation is enabled, the TX/RX PAUSE
11409 + * settings depend on the result of the link negotiation.
11410 + */
11411 +
11412 + /* get local capabilities */
11413 + lcl_adv = 0;
11414 + if (phy_dev->advertising & ADVERTISED_Pause)
11415 + lcl_adv |= ADVERTISE_PAUSE_CAP;
11416 + if (phy_dev->advertising & ADVERTISED_Asym_Pause)
11417 + lcl_adv |= ADVERTISE_PAUSE_ASYM;
11418 +
11419 + /* get link partner capabilities */
11420 + rmt_adv = 0;
11421 + if (phy_dev->pause)
11422 + rmt_adv |= LPA_PAUSE_CAP;
11423 + if (phy_dev->asym_pause)
11424 + rmt_adv |= LPA_PAUSE_ASYM;
11425 +
11426 + /* Calculate TX/RX settings based on local and peer advertised
11427 + * symmetric/asymmetric PAUSE capabilities.
11428 + */
11429 + flowctrl = mii_resolve_flowctrl_fdx(lcl_adv, rmt_adv);
11430 + if (flowctrl & FLOW_CTRL_RX)
11431 + *rx_pause = true;
11432 + if (flowctrl & FLOW_CTRL_TX)
11433 + *tx_pause = true;
11434 +}
11435 +EXPORT_SYMBOL(get_pause_cfg);
11436 +
11437 +static void adjust_link_void(struct net_device *net_dev)
11438 +{
11439 +}
11440 +
11441 +static void adjust_link(struct net_device *net_dev)
11442 +{
11443 + struct dpa_priv_s *priv = netdev_priv(net_dev);
11444 + struct mac_device *mac_dev = priv->mac_dev;
11445 + struct phy_device *phy_dev = mac_dev->phy_dev;
11446 + struct fm_mac_dev *fm_mac_dev;
11447 + bool rx_pause, tx_pause;
11448 + int _errno;
11449 +
11450 + fm_mac_dev = mac_dev->get_mac_handle(mac_dev);
11451 + fm_mac_adjust_link(fm_mac_dev, phy_dev->link, phy_dev->speed,
11452 + phy_dev->duplex);
11453 +
11454 + get_pause_cfg(mac_dev, &rx_pause, &tx_pause);
11455 + _errno = set_mac_active_pause(mac_dev, rx_pause, tx_pause);
11456 + if (unlikely(_errno < 0))
11457 + netdev_err(net_dev, "set_mac_active_pause() = %d\n", _errno);
11458 +}
11459 +
11460 +/* Initializes driver's PHY state, and attaches to the PHY.
11461 + * Returns 0 on success.
11462 + */
11463 +static int dtsec_init_phy(struct net_device *net_dev,
11464 + struct mac_device *mac_dev)
11465 +{
11466 + struct phy_device *phy_dev;
11467 +
11468 + if (of_phy_is_fixed_link(mac_dev->phy_node))
11469 + phy_dev = of_phy_attach(net_dev, mac_dev->phy_node,
11470 + 0, mac_dev->phy_if);
11471 + else
11472 + phy_dev = of_phy_connect(net_dev, mac_dev->phy_node,
11473 + &adjust_link, 0, mac_dev->phy_if);
11474 + if (unlikely(phy_dev == NULL) || IS_ERR(phy_dev)) {
11475 + netdev_err(net_dev, "Could not connect to PHY %s\n",
11476 + mac_dev->phy_node ?
11477 + mac_dev->phy_node->full_name :
11478 + mac_dev->fixed_bus_id);
11479 + return phy_dev == NULL ? -ENODEV : PTR_ERR(phy_dev);
11480 + }
11481 +
11482 + /* Remove any features not supported by the controller */
11483 + phy_dev->supported &= mac_dev->if_support;
11484 + /* Enable the symmetric and asymmetric PAUSE frame advertisements,
11485 + * as most of the PHY drivers do not enable them by default.
11486 + */
11487 + phy_dev->supported |= (SUPPORTED_Pause | SUPPORTED_Asym_Pause);
11488 + phy_dev->advertising = phy_dev->supported;
11489 +
11490 + mac_dev->phy_dev = phy_dev;
11491 +
11492 + return 0;
11493 +}
11494 +
11495 +static int xgmac_init_phy(struct net_device *net_dev,
11496 + struct mac_device *mac_dev)
11497 +{
11498 + struct phy_device *phy_dev;
11499 +
11500 + if (of_phy_is_fixed_link(mac_dev->phy_node))
11501 + phy_dev = of_phy_attach(net_dev, mac_dev->phy_node,
11502 + 0, mac_dev->phy_if);
11503 + else
11504 + phy_dev = of_phy_connect(net_dev, mac_dev->phy_node,
11505 + &adjust_link_void, 0, mac_dev->phy_if);
11506 + if (unlikely(phy_dev == NULL) || IS_ERR(phy_dev)) {
11507 + netdev_err(net_dev, "Could not attach to PHY %s\n",
11508 + mac_dev->phy_node ?
11509 + mac_dev->phy_node->full_name :
11510 + mac_dev->fixed_bus_id);
11511 + return phy_dev == NULL ? -ENODEV : PTR_ERR(phy_dev);
11512 + }
11513 +
11514 + phy_dev->supported &= mac_dev->if_support;
11515 + /* Enable the symmetric and asymmetric PAUSE frame advertisements,
11516 + * as most of the PHY drivers do not enable them by default.
11517 + */
11518 + phy_dev->supported |= (SUPPORTED_Pause | SUPPORTED_Asym_Pause);
11519 + phy_dev->advertising = phy_dev->supported;
11520 +
11521 + mac_dev->phy_dev = phy_dev;
11522 +
11523 + return 0;
11524 +}
11525 +
11526 +static int memac_init_phy(struct net_device *net_dev,
11527 + struct mac_device *mac_dev)
11528 +{
11529 + struct phy_device *phy_dev;
11530 +
11531 + if ((macdev2enetinterface(mac_dev) == e_ENET_MODE_XGMII_10000) ||
11532 + (macdev2enetinterface(mac_dev) == e_ENET_MODE_SGMII_2500) ||
11533 + of_phy_is_fixed_link(mac_dev->phy_node)) {
11534 + phy_dev = of_phy_connect(net_dev, mac_dev->phy_node,
11535 + &adjust_link_void, 0,
11536 + mac_dev->phy_if);
11537 + } else {
11538 + phy_dev = of_phy_connect(net_dev, mac_dev->phy_node,
11539 + &adjust_link, 0, mac_dev->phy_if);
11540 + }
11541 +
11542 + if (unlikely(phy_dev == NULL) || IS_ERR(phy_dev)) {
11543 + netdev_err(net_dev, "Could not connect to PHY %s\n",
11544 + mac_dev->phy_node ?
11545 + mac_dev->phy_node->full_name :
11546 + mac_dev->fixed_bus_id);
11547 + return phy_dev == NULL ? -ENODEV : PTR_ERR(phy_dev);
11548 + }
11549 +
11550 + /* Remove any features not supported by the controller */
11551 + phy_dev->supported &= mac_dev->if_support;
11552 + /* Enable the symmetric and asymmetric PAUSE frame advertisements,
11553 + * as most of the PHY drivers do not enable them by default.
11554 + */
11555 + phy_dev->supported |= (SUPPORTED_Pause | SUPPORTED_Asym_Pause);
11556 + phy_dev->advertising = phy_dev->supported;
11557 +
11558 + mac_dev->phy_dev = phy_dev;
11559 +
11560 + return 0;
11561 +}
11562 +
11563 +static int __cold uninit(struct fm_mac_dev *fm_mac_dev)
11564 +{
11565 + int _errno, __errno;
11566 +
11567 + _errno = fm_mac_disable(fm_mac_dev);
11568 + __errno = fm_mac_free(fm_mac_dev);
11569 +
11570 + if (unlikely(__errno < 0))
11571 + _errno = __errno;
11572 +
11573 + return _errno;
11574 +}
11575 +
11576 +static struct fm_mac_dev *get_mac_handle(struct mac_device *mac_dev)
11577 +{
11578 + const struct mac_priv_s *priv;
11579 + priv = macdev_priv(mac_dev);
11580 + return priv->fm_mac;
11581 +}
11582 +
11583 +static int dtsec_dump_regs(struct mac_device *h_mac, char *buf, int nn)
11584 +{
11585 + struct dtsec_regs *p_mm = (struct dtsec_regs *) h_mac->vaddr;
11586 + int i = 0, n = nn;
11587 +
11588 + FM_DMP_SUBTITLE(buf, n, "\n");
11589 +
11590 + FM_DMP_TITLE(buf, n, p_mm, "FM MAC - DTSEC-%d", h_mac->cell_index);
11591 +
11592 + FM_DMP_V32(buf, n, p_mm, tsec_id);
11593 + FM_DMP_V32(buf, n, p_mm, tsec_id2);
11594 + FM_DMP_V32(buf, n, p_mm, ievent);
11595 + FM_DMP_V32(buf, n, p_mm, imask);
11596 + FM_DMP_V32(buf, n, p_mm, ecntrl);
11597 + FM_DMP_V32(buf, n, p_mm, ptv);
11598 + FM_DMP_V32(buf, n, p_mm, tmr_ctrl);
11599 + FM_DMP_V32(buf, n, p_mm, tmr_pevent);
11600 + FM_DMP_V32(buf, n, p_mm, tmr_pemask);
11601 + FM_DMP_V32(buf, n, p_mm, tctrl);
11602 + FM_DMP_V32(buf, n, p_mm, rctrl);
11603 + FM_DMP_V32(buf, n, p_mm, maccfg1);
11604 + FM_DMP_V32(buf, n, p_mm, maccfg2);
11605 + FM_DMP_V32(buf, n, p_mm, ipgifg);
11606 + FM_DMP_V32(buf, n, p_mm, hafdup);
11607 + FM_DMP_V32(buf, n, p_mm, maxfrm);
11608 +
11609 + FM_DMP_V32(buf, n, p_mm, macstnaddr1);
11610 + FM_DMP_V32(buf, n, p_mm, macstnaddr2);
11611 +
11612 + for (i = 0; i < 7; ++i) {
11613 + FM_DMP_V32(buf, n, p_mm, macaddr[i].exact_match1);
11614 + FM_DMP_V32(buf, n, p_mm, macaddr[i].exact_match2);
11615 + }
11616 +
11617 + FM_DMP_V32(buf, n, p_mm, car1);
11618 + FM_DMP_V32(buf, n, p_mm, car2);
11619 +
11620 + return n;
11621 +}
11622 +
11623 +static int xgmac_dump_regs(struct mac_device *h_mac, char *buf, int nn)
11624 +{
11625 + struct tgec_regs *p_mm = (struct tgec_regs *) h_mac->vaddr;
11626 + int n = nn;
11627 +
11628 + FM_DMP_SUBTITLE(buf, n, "\n");
11629 + FM_DMP_TITLE(buf, n, p_mm, "FM MAC - TGEC -%d", h_mac->cell_index);
11630 +
11631 + FM_DMP_V32(buf, n, p_mm, tgec_id);
11632 + FM_DMP_V32(buf, n, p_mm, command_config);
11633 + FM_DMP_V32(buf, n, p_mm, mac_addr_0);
11634 + FM_DMP_V32(buf, n, p_mm, mac_addr_1);
11635 + FM_DMP_V32(buf, n, p_mm, maxfrm);
11636 + FM_DMP_V32(buf, n, p_mm, pause_quant);
11637 + FM_DMP_V32(buf, n, p_mm, rx_fifo_sections);
11638 + FM_DMP_V32(buf, n, p_mm, tx_fifo_sections);
11639 + FM_DMP_V32(buf, n, p_mm, rx_fifo_almost_f_e);
11640 + FM_DMP_V32(buf, n, p_mm, tx_fifo_almost_f_e);
11641 + FM_DMP_V32(buf, n, p_mm, hashtable_ctrl);
11642 + FM_DMP_V32(buf, n, p_mm, mdio_cfg_status);
11643 + FM_DMP_V32(buf, n, p_mm, mdio_command);
11644 + FM_DMP_V32(buf, n, p_mm, mdio_data);
11645 + FM_DMP_V32(buf, n, p_mm, mdio_regaddr);
11646 + FM_DMP_V32(buf, n, p_mm, status);
11647 + FM_DMP_V32(buf, n, p_mm, tx_ipg_len);
11648 + FM_DMP_V32(buf, n, p_mm, mac_addr_2);
11649 + FM_DMP_V32(buf, n, p_mm, mac_addr_3);
11650 + FM_DMP_V32(buf, n, p_mm, rx_fifo_ptr_rd);
11651 + FM_DMP_V32(buf, n, p_mm, rx_fifo_ptr_wr);
11652 + FM_DMP_V32(buf, n, p_mm, tx_fifo_ptr_rd);
11653 + FM_DMP_V32(buf, n, p_mm, tx_fifo_ptr_wr);
11654 + FM_DMP_V32(buf, n, p_mm, imask);
11655 + FM_DMP_V32(buf, n, p_mm, ievent);
11656 +
11657 + return n;
11658 +}
11659 +
11660 +static int memac_dump_regs(struct mac_device *h_mac, char *buf, int nn)
11661 +{
11662 + struct memac_regs *p_mm = (struct memac_regs *) h_mac->vaddr;
11663 + int i = 0, n = nn;
11664 +
11665 + FM_DMP_SUBTITLE(buf, n, "\n");
11666 + FM_DMP_TITLE(buf, n, p_mm, "FM MAC - MEMAC -%d", h_mac->cell_index);
11667 +
11668 + FM_DMP_V32(buf, n, p_mm, command_config);
11669 + FM_DMP_V32(buf, n, p_mm, mac_addr0.mac_addr_l);
11670 + FM_DMP_V32(buf, n, p_mm, mac_addr0.mac_addr_u);
11671 + FM_DMP_V32(buf, n, p_mm, maxfrm);
11672 + FM_DMP_V32(buf, n, p_mm, hashtable_ctrl);
11673 + FM_DMP_V32(buf, n, p_mm, ievent);
11674 + FM_DMP_V32(buf, n, p_mm, tx_ipg_length);
11675 + FM_DMP_V32(buf, n, p_mm, imask);
11676 +
11677 + for (i = 0; i < 4; ++i)
11678 + FM_DMP_V32(buf, n, p_mm, pause_quanta[i]);
11679 +
11680 + for (i = 0; i < 4; ++i)
11681 + FM_DMP_V32(buf, n, p_mm, pause_thresh[i]);
11682 +
11683 + FM_DMP_V32(buf, n, p_mm, rx_pause_status);
11684 +
11685 + for (i = 0; i < MEMAC_NUM_OF_PADDRS; ++i) {
11686 + FM_DMP_V32(buf, n, p_mm, mac_addr[i].mac_addr_l);
11687 + FM_DMP_V32(buf, n, p_mm, mac_addr[i].mac_addr_u);
11688 + }
11689 +
11690 + FM_DMP_V32(buf, n, p_mm, lpwake_timer);
11691 + FM_DMP_V32(buf, n, p_mm, sleep_timer);
11692 + FM_DMP_V32(buf, n, p_mm, statn_config);
11693 + FM_DMP_V32(buf, n, p_mm, if_mode);
11694 + FM_DMP_V32(buf, n, p_mm, if_status);
11695 + FM_DMP_V32(buf, n, p_mm, hg_config);
11696 + FM_DMP_V32(buf, n, p_mm, hg_pause_quanta);
11697 + FM_DMP_V32(buf, n, p_mm, hg_pause_thresh);
11698 + FM_DMP_V32(buf, n, p_mm, hgrx_pause_status);
11699 + FM_DMP_V32(buf, n, p_mm, hg_fifos_status);
11700 + FM_DMP_V32(buf, n, p_mm, rhm);
11701 + FM_DMP_V32(buf, n, p_mm, thm);
11702 +
11703 + return n;
11704 +}
11705 +
11706 +static int memac_dump_regs_rx(struct mac_device *h_mac, char *buf, int nn)
11707 +{
11708 + struct memac_regs *p_mm = (struct memac_regs *) h_mac->vaddr;
11709 + int n = nn;
11710 +
11711 + FM_DMP_SUBTITLE(buf, n, "\n");
11712 + FM_DMP_TITLE(buf, n, p_mm, "FM MAC - MEMAC -%d Rx stats", h_mac->cell_index);
11713 +
11714 + /* Rx Statistics Counter */
11715 + FM_DMP_V32(buf, n, p_mm, reoct_l);
11716 + FM_DMP_V32(buf, n, p_mm, reoct_u);
11717 + FM_DMP_V32(buf, n, p_mm, roct_l);
11718 + FM_DMP_V32(buf, n, p_mm, roct_u);
11719 + FM_DMP_V32(buf, n, p_mm, raln_l);
11720 + FM_DMP_V32(buf, n, p_mm, raln_u);
11721 + FM_DMP_V32(buf, n, p_mm, rxpf_l);
11722 + FM_DMP_V32(buf, n, p_mm, rxpf_u);
11723 + FM_DMP_V32(buf, n, p_mm, rfrm_l);
11724 + FM_DMP_V32(buf, n, p_mm, rfrm_u);
11725 + FM_DMP_V32(buf, n, p_mm, rfcs_l);
11726 + FM_DMP_V32(buf, n, p_mm, rfcs_u);
11727 + FM_DMP_V32(buf, n, p_mm, rvlan_l);
11728 + FM_DMP_V32(buf, n, p_mm, rvlan_u);
11729 + FM_DMP_V32(buf, n, p_mm, rerr_l);
11730 + FM_DMP_V32(buf, n, p_mm, rerr_u);
11731 + FM_DMP_V32(buf, n, p_mm, ruca_l);
11732 + FM_DMP_V32(buf, n, p_mm, ruca_u);
11733 + FM_DMP_V32(buf, n, p_mm, rmca_l);
11734 + FM_DMP_V32(buf, n, p_mm, rmca_u);
11735 + FM_DMP_V32(buf, n, p_mm, rbca_l);
11736 + FM_DMP_V32(buf, n, p_mm, rbca_u);
11737 + FM_DMP_V32(buf, n, p_mm, rdrp_l);
11738 + FM_DMP_V32(buf, n, p_mm, rdrp_u);
11739 + FM_DMP_V32(buf, n, p_mm, rpkt_l);
11740 + FM_DMP_V32(buf, n, p_mm, rpkt_u);
11741 + FM_DMP_V32(buf, n, p_mm, rund_l);
11742 + FM_DMP_V32(buf, n, p_mm, rund_u);
11743 + FM_DMP_V32(buf, n, p_mm, r64_l);
11744 + FM_DMP_V32(buf, n, p_mm, r64_u);
11745 + FM_DMP_V32(buf, n, p_mm, r127_l);
11746 + FM_DMP_V32(buf, n, p_mm, r127_u);
11747 + FM_DMP_V32(buf, n, p_mm, r255_l);
11748 + FM_DMP_V32(buf, n, p_mm, r255_u);
11749 + FM_DMP_V32(buf, n, p_mm, r511_l);
11750 + FM_DMP_V32(buf, n, p_mm, r511_u);
11751 + FM_DMP_V32(buf, n, p_mm, r1023_l);
11752 + FM_DMP_V32(buf, n, p_mm, r1023_u);
11753 + FM_DMP_V32(buf, n, p_mm, r1518_l);
11754 + FM_DMP_V32(buf, n, p_mm, r1518_u);
11755 + FM_DMP_V32(buf, n, p_mm, r1519x_l);
11756 + FM_DMP_V32(buf, n, p_mm, r1519x_u);
11757 + FM_DMP_V32(buf, n, p_mm, rovr_l);
11758 + FM_DMP_V32(buf, n, p_mm, rovr_u);
11759 + FM_DMP_V32(buf, n, p_mm, rjbr_l);
11760 + FM_DMP_V32(buf, n, p_mm, rjbr_u);
11761 + FM_DMP_V32(buf, n, p_mm, rfrg_l);
11762 + FM_DMP_V32(buf, n, p_mm, rfrg_u);
11763 + FM_DMP_V32(buf, n, p_mm, rcnp_l);
11764 + FM_DMP_V32(buf, n, p_mm, rcnp_u);
11765 + FM_DMP_V32(buf, n, p_mm, rdrntp_l);
11766 + FM_DMP_V32(buf, n, p_mm, rdrntp_u);
11767 +
11768 + return n;
11769 +}
11770 +
11771 +static int memac_dump_regs_tx(struct mac_device *h_mac, char *buf, int nn)
11772 +{
11773 + struct memac_regs *p_mm = (struct memac_regs *) h_mac->vaddr;
11774 + int n = nn;
11775 +
11776 + FM_DMP_SUBTITLE(buf, n, "\n");
11777 + FM_DMP_TITLE(buf, n, p_mm, "FM MAC - MEMAC -%d Tx stats", h_mac->cell_index);
11778 +
11779 +
11780 + /* Tx Statistics Counter */
11781 + FM_DMP_V32(buf, n, p_mm, teoct_l);
11782 + FM_DMP_V32(buf, n, p_mm, teoct_u);
11783 + FM_DMP_V32(buf, n, p_mm, toct_l);
11784 + FM_DMP_V32(buf, n, p_mm, toct_u);
11785 + FM_DMP_V32(buf, n, p_mm, txpf_l);
11786 + FM_DMP_V32(buf, n, p_mm, txpf_u);
11787 + FM_DMP_V32(buf, n, p_mm, tfrm_l);
11788 + FM_DMP_V32(buf, n, p_mm, tfrm_u);
11789 + FM_DMP_V32(buf, n, p_mm, tfcs_l);
11790 + FM_DMP_V32(buf, n, p_mm, tfcs_u);
11791 + FM_DMP_V32(buf, n, p_mm, tvlan_l);
11792 + FM_DMP_V32(buf, n, p_mm, tvlan_u);
11793 + FM_DMP_V32(buf, n, p_mm, terr_l);
11794 + FM_DMP_V32(buf, n, p_mm, terr_u);
11795 + FM_DMP_V32(buf, n, p_mm, tuca_l);
11796 + FM_DMP_V32(buf, n, p_mm, tuca_u);
11797 + FM_DMP_V32(buf, n, p_mm, tmca_l);
11798 + FM_DMP_V32(buf, n, p_mm, tmca_u);
11799 + FM_DMP_V32(buf, n, p_mm, tbca_l);
11800 + FM_DMP_V32(buf, n, p_mm, tbca_u);
11801 + FM_DMP_V32(buf, n, p_mm, tpkt_l);
11802 + FM_DMP_V32(buf, n, p_mm, tpkt_u);
11803 + FM_DMP_V32(buf, n, p_mm, tund_l);
11804 + FM_DMP_V32(buf, n, p_mm, tund_u);
11805 + FM_DMP_V32(buf, n, p_mm, t64_l);
11806 + FM_DMP_V32(buf, n, p_mm, t64_u);
11807 + FM_DMP_V32(buf, n, p_mm, t127_l);
11808 + FM_DMP_V32(buf, n, p_mm, t127_u);
11809 + FM_DMP_V32(buf, n, p_mm, t255_l);
11810 + FM_DMP_V32(buf, n, p_mm, t255_u);
11811 + FM_DMP_V32(buf, n, p_mm, t511_l);
11812 + FM_DMP_V32(buf, n, p_mm, t511_u);
11813 + FM_DMP_V32(buf, n, p_mm, t1023_l);
11814 + FM_DMP_V32(buf, n, p_mm, t1023_u);
11815 + FM_DMP_V32(buf, n, p_mm, t1518_l);
11816 + FM_DMP_V32(buf, n, p_mm, t1518_u);
11817 + FM_DMP_V32(buf, n, p_mm, t1519x_l);
11818 + FM_DMP_V32(buf, n, p_mm, t1519x_u);
11819 + FM_DMP_V32(buf, n, p_mm, tcnp_l);
11820 + FM_DMP_V32(buf, n, p_mm, tcnp_u);
11821 +
11822 + return n;
11823 +}
11824 +
11825 +int fm_mac_dump_regs(struct mac_device *h_mac, char *buf, int nn)
11826 +{
11827 + int n = nn;
11828 +
11829 + n = h_mac->dump_mac_regs(h_mac, buf, n);
11830 +
11831 + return n;
11832 +}
11833 +EXPORT_SYMBOL(fm_mac_dump_regs);
11834 +
11835 +int fm_mac_dump_rx_stats(struct mac_device *h_mac, char *buf, int nn)
11836 +{
11837 + int n = nn;
11838 +
11839 + if(h_mac->dump_mac_rx_stats)
11840 + n = h_mac->dump_mac_rx_stats(h_mac, buf, n);
11841 +
11842 + return n;
11843 +}
11844 +EXPORT_SYMBOL(fm_mac_dump_rx_stats);
11845 +
11846 +int fm_mac_dump_tx_stats(struct mac_device *h_mac, char *buf, int nn)
11847 +{
11848 + int n = nn;
11849 +
11850 + if(h_mac->dump_mac_tx_stats)
11851 + n = h_mac->dump_mac_tx_stats(h_mac, buf, n);
11852 +
11853 + return n;
11854 +}
11855 +EXPORT_SYMBOL(fm_mac_dump_tx_stats);
11856 +
11857 +static void __cold setup_dtsec(struct mac_device *mac_dev)
11858 +{
11859 + mac_dev->init_phy = dtsec_init_phy;
11860 + mac_dev->init = init;
11861 + mac_dev->start = start;
11862 + mac_dev->stop = stop;
11863 + mac_dev->set_promisc = fm_mac_set_promiscuous;
11864 + mac_dev->change_addr = fm_mac_modify_mac_addr;
11865 + mac_dev->set_multi = set_multi;
11866 + mac_dev->uninit = uninit;
11867 + mac_dev->ptp_enable = fm_mac_enable_1588_time_stamp;
11868 + mac_dev->ptp_disable = fm_mac_disable_1588_time_stamp;
11869 + mac_dev->get_mac_handle = get_mac_handle;
11870 + mac_dev->set_tx_pause = fm_mac_set_tx_pause_frames;
11871 + mac_dev->set_rx_pause = fm_mac_set_rx_pause_frames;
11872 + mac_dev->fm_rtc_enable = fm_rtc_enable;
11873 + mac_dev->fm_rtc_disable = fm_rtc_disable;
11874 + mac_dev->fm_rtc_get_cnt = fm_rtc_get_cnt;
11875 + mac_dev->fm_rtc_set_cnt = fm_rtc_set_cnt;
11876 + mac_dev->fm_rtc_get_drift = fm_rtc_get_drift;
11877 + mac_dev->fm_rtc_set_drift = fm_rtc_set_drift;
11878 + mac_dev->fm_rtc_set_alarm = fm_rtc_set_alarm;
11879 + mac_dev->fm_rtc_set_fiper = fm_rtc_set_fiper;
11880 + mac_dev->set_wol = fm_mac_set_wol;
11881 + mac_dev->dump_mac_regs = dtsec_dump_regs;
11882 +}
11883 +
11884 +static void __cold setup_xgmac(struct mac_device *mac_dev)
11885 +{
11886 + mac_dev->init_phy = xgmac_init_phy;
11887 + mac_dev->init = init;
11888 + mac_dev->start = start;
11889 + mac_dev->stop = stop;
11890 + mac_dev->set_promisc = fm_mac_set_promiscuous;
11891 + mac_dev->change_addr = fm_mac_modify_mac_addr;
11892 + mac_dev->set_multi = set_multi;
11893 + mac_dev->uninit = uninit;
11894 + mac_dev->get_mac_handle = get_mac_handle;
11895 + mac_dev->set_tx_pause = fm_mac_set_tx_pause_frames;
11896 + mac_dev->set_rx_pause = fm_mac_set_rx_pause_frames;
11897 + mac_dev->set_wol = fm_mac_set_wol;
11898 + mac_dev->dump_mac_regs = xgmac_dump_regs;
11899 +}
11900 +
11901 +static void __cold setup_memac(struct mac_device *mac_dev)
11902 +{
11903 + mac_dev->init_phy = memac_init_phy;
11904 + mac_dev->init = memac_init;
11905 + mac_dev->start = start;
11906 + mac_dev->stop = stop;
11907 + mac_dev->set_promisc = fm_mac_set_promiscuous;
11908 + mac_dev->change_addr = fm_mac_modify_mac_addr;
11909 + mac_dev->set_multi = set_multi;
11910 + mac_dev->uninit = uninit;
11911 + mac_dev->get_mac_handle = get_mac_handle;
11912 + mac_dev->set_tx_pause = fm_mac_set_tx_pause_frames;
11913 + mac_dev->set_rx_pause = fm_mac_set_rx_pause_frames;
11914 + mac_dev->fm_rtc_enable = fm_rtc_enable;
11915 + mac_dev->fm_rtc_disable = fm_rtc_disable;
11916 + mac_dev->fm_rtc_get_cnt = fm_rtc_get_cnt;
11917 + mac_dev->fm_rtc_set_cnt = fm_rtc_set_cnt;
11918 + mac_dev->fm_rtc_get_drift = fm_rtc_get_drift;
11919 + mac_dev->fm_rtc_set_drift = fm_rtc_set_drift;
11920 + mac_dev->fm_rtc_set_alarm = fm_rtc_set_alarm;
11921 + mac_dev->fm_rtc_set_fiper = fm_rtc_set_fiper;
11922 + mac_dev->set_wol = fm_mac_set_wol;
11923 + mac_dev->dump_mac_regs = memac_dump_regs;
11924 + mac_dev->dump_mac_rx_stats = memac_dump_regs_rx;
11925 + mac_dev->dump_mac_tx_stats = memac_dump_regs_tx;
11926 +}
11927 +
11928 +void (*const mac_setup[])(struct mac_device *mac_dev) = {
11929 + [DTSEC] = setup_dtsec,
11930 + [XGMAC] = setup_xgmac,
11931 + [MEMAC] = setup_memac
11932 +};
11933 --- /dev/null
11934 +++ b/drivers/net/ethernet/freescale/sdk_dpaa/mac.c
11935 @@ -0,0 +1,489 @@
11936 +/* Copyright 2008-2012 Freescale Semiconductor, Inc.
11937 + *
11938 + * Redistribution and use in source and binary forms, with or without
11939 + * modification, are permitted provided that the following conditions are met:
11940 + * * Redistributions of source code must retain the above copyright
11941 + * notice, this list of conditions and the following disclaimer.
11942 + * * Redistributions in binary form must reproduce the above copyright
11943 + * notice, this list of conditions and the following disclaimer in the
11944 + * documentation and/or other materials provided with the distribution.
11945 + * * Neither the name of Freescale Semiconductor nor the
11946 + * names of its contributors may be used to endorse or promote products
11947 + * derived from this software without specific prior written permission.
11948 + *
11949 + *
11950 + * ALTERNATIVELY, this software may be distributed under the terms of the
11951 + * GNU General Public License ("GPL") as published by the Free Software
11952 + * Foundation, either version 2 of that License or (at your option) any
11953 + * later version.
11954 + *
11955 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
11956 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
11957 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
11958 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
11959 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
11960 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
11961 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
11962 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
11963 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
11964 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
11965 + */
11966 +
11967 +#ifdef CONFIG_FSL_DPAA_ETH_DEBUG
11968 +#define pr_fmt(fmt) \
11969 + KBUILD_MODNAME ": %s:%hu:%s() " fmt, \
11970 + KBUILD_BASENAME".c", __LINE__, __func__
11971 +#else
11972 +#define pr_fmt(fmt) \
11973 + KBUILD_MODNAME ": " fmt
11974 +#endif
11975 +
11976 +#include <linux/init.h>
11977 +#include <linux/module.h>
11978 +#include <linux/of_address.h>
11979 +#include <linux/of_platform.h>
11980 +#include <linux/of_net.h>
11981 +#include <linux/of_mdio.h>
11982 +#include <linux/phy_fixed.h>
11983 +#include <linux/device.h>
11984 +#include <linux/phy.h>
11985 +#include <linux/io.h>
11986 +
11987 +#include "lnxwrp_fm_ext.h"
11988 +
11989 +#include "mac.h"
11990 +
11991 +#define DTSEC_SUPPORTED \
11992 + (SUPPORTED_10baseT_Half \
11993 + | SUPPORTED_10baseT_Full \
11994 + | SUPPORTED_100baseT_Half \
11995 + | SUPPORTED_100baseT_Full \
11996 + | SUPPORTED_Autoneg \
11997 + | SUPPORTED_Pause \
11998 + | SUPPORTED_Asym_Pause \
11999 + | SUPPORTED_MII)
12000 +
12001 +static const char phy_str[][11] = {
12002 + [PHY_INTERFACE_MODE_MII] = "mii",
12003 + [PHY_INTERFACE_MODE_GMII] = "gmii",
12004 + [PHY_INTERFACE_MODE_SGMII] = "sgmii",
12005 + [PHY_INTERFACE_MODE_QSGMII] = "qsgmii",
12006 + [PHY_INTERFACE_MODE_TBI] = "tbi",
12007 + [PHY_INTERFACE_MODE_RMII] = "rmii",
12008 + [PHY_INTERFACE_MODE_RGMII] = "rgmii",
12009 + [PHY_INTERFACE_MODE_RGMII_ID] = "rgmii-id",
12010 + [PHY_INTERFACE_MODE_RGMII_RXID] = "rgmii-rxid",
12011 + [PHY_INTERFACE_MODE_RGMII_TXID] = "rgmii-txid",
12012 + [PHY_INTERFACE_MODE_RTBI] = "rtbi",
12013 + [PHY_INTERFACE_MODE_XGMII] = "xgmii",
12014 + [PHY_INTERFACE_MODE_2500SGMII] = "sgmii-2500",
12015 +};
12016 +
12017 +static phy_interface_t __pure __attribute__((nonnull)) str2phy(const char *str)
12018 +{
12019 + int i;
12020 +
12021 + for (i = 0; i < ARRAY_SIZE(phy_str); i++)
12022 + if (strcmp(str, phy_str[i]) == 0)
12023 + return (phy_interface_t)i;
12024 +
12025 + return PHY_INTERFACE_MODE_MII;
12026 +}
12027 +
12028 +static const uint16_t phy2speed[] = {
12029 + [PHY_INTERFACE_MODE_MII] = SPEED_100,
12030 + [PHY_INTERFACE_MODE_GMII] = SPEED_1000,
12031 + [PHY_INTERFACE_MODE_SGMII] = SPEED_1000,
12032 + [PHY_INTERFACE_MODE_QSGMII] = SPEED_1000,
12033 + [PHY_INTERFACE_MODE_TBI] = SPEED_1000,
12034 + [PHY_INTERFACE_MODE_RMII] = SPEED_100,
12035 + [PHY_INTERFACE_MODE_RGMII] = SPEED_1000,
12036 + [PHY_INTERFACE_MODE_RGMII_ID] = SPEED_1000,
12037 + [PHY_INTERFACE_MODE_RGMII_RXID] = SPEED_1000,
12038 + [PHY_INTERFACE_MODE_RGMII_TXID] = SPEED_1000,
12039 + [PHY_INTERFACE_MODE_RTBI] = SPEED_1000,
12040 + [PHY_INTERFACE_MODE_XGMII] = SPEED_10000,
12041 + [PHY_INTERFACE_MODE_2500SGMII] = SPEED_2500,
12042 +};
12043 +
12044 +static struct mac_device * __cold
12045 +alloc_macdev(struct device *dev, size_t sizeof_priv,
12046 + void (*setup)(struct mac_device *mac_dev))
12047 +{
12048 + struct mac_device *mac_dev;
12049 +
12050 + mac_dev = devm_kzalloc(dev, sizeof(*mac_dev) + sizeof_priv, GFP_KERNEL);
12051 + if (unlikely(mac_dev == NULL))
12052 + mac_dev = ERR_PTR(-ENOMEM);
12053 + else {
12054 + mac_dev->dev = dev;
12055 + dev_set_drvdata(dev, mac_dev);
12056 + setup(mac_dev);
12057 + }
12058 +
12059 + return mac_dev;
12060 +}
12061 +
12062 +static int __cold free_macdev(struct mac_device *mac_dev)
12063 +{
12064 + dev_set_drvdata(mac_dev->dev, NULL);
12065 +
12066 + return mac_dev->uninit(mac_dev->get_mac_handle(mac_dev));
12067 +}
12068 +
12069 +static const struct of_device_id mac_match[] = {
12070 + [DTSEC] = {
12071 + .compatible = "fsl,fman-1g-mac"
12072 + },
12073 + [XGMAC] = {
12074 + .compatible = "fsl,fman-10g-mac"
12075 + },
12076 + [MEMAC] = {
12077 + .compatible = "fsl,fman-memac"
12078 + },
12079 + {}
12080 +};
12081 +MODULE_DEVICE_TABLE(of, mac_match);
12082 +
12083 +static int __cold mac_probe(struct platform_device *_of_dev)
12084 +{
12085 + int _errno, i;
12086 + struct device *dev;
12087 + struct device_node *mac_node, *dev_node;
12088 + struct mac_device *mac_dev;
12089 + struct platform_device *of_dev;
12090 + struct resource res;
12091 + const uint8_t *mac_addr;
12092 + const char *char_prop;
12093 + int nph;
12094 + u32 cell_index;
12095 + const struct of_device_id *match;
12096 +
12097 + dev = &_of_dev->dev;
12098 + mac_node = dev->of_node;
12099 +
12100 + match = of_match_device(mac_match, dev);
12101 + if (!match)
12102 + return -EINVAL;
12103 +
12104 + for (i = 0; i < ARRAY_SIZE(mac_match) - 1 && match != mac_match + i;
12105 + i++)
12106 + ;
12107 + BUG_ON(i >= ARRAY_SIZE(mac_match) - 1);
12108 +
12109 + mac_dev = alloc_macdev(dev, mac_sizeof_priv[i], mac_setup[i]);
12110 + if (IS_ERR(mac_dev)) {
12111 + _errno = PTR_ERR(mac_dev);
12112 + dev_err(dev, "alloc_macdev() = %d\n", _errno);
12113 + goto _return;
12114 + }
12115 +
12116 + INIT_LIST_HEAD(&mac_dev->mc_addr_list);
12117 +
12118 + /* Get the FM node */
12119 + dev_node = of_get_parent(mac_node);
12120 + if (unlikely(dev_node == NULL)) {
12121 + dev_err(dev, "of_get_parent(%s) failed\n",
12122 + mac_node->full_name);
12123 + _errno = -EINVAL;
12124 + goto _return_dev_set_drvdata;
12125 + }
12126 +
12127 + of_dev = of_find_device_by_node(dev_node);
12128 + if (unlikely(of_dev == NULL)) {
12129 + dev_err(dev, "of_find_device_by_node(%s) failed\n",
12130 + dev_node->full_name);
12131 + _errno = -EINVAL;
12132 + goto _return_of_node_put;
12133 + }
12134 +
12135 + mac_dev->fm_dev = fm_bind(&of_dev->dev);
12136 + if (unlikely(mac_dev->fm_dev == NULL)) {
12137 + dev_err(dev, "fm_bind(%s) failed\n", dev_node->full_name);
12138 + _errno = -ENODEV;
12139 + goto _return_of_node_put;
12140 + }
12141 +
12142 + mac_dev->fm = (void *)fm_get_handle(mac_dev->fm_dev);
12143 + of_node_put(dev_node);
12144 +
12145 + /* Get the address of the memory mapped registers */
12146 + _errno = of_address_to_resource(mac_node, 0, &res);
12147 + if (unlikely(_errno < 0)) {
12148 + dev_err(dev, "of_address_to_resource(%s) = %d\n",
12149 + mac_node->full_name, _errno);
12150 + goto _return_dev_set_drvdata;
12151 + }
12152 +
12153 + mac_dev->res = __devm_request_region(
12154 + dev,
12155 + fm_get_mem_region(mac_dev->fm_dev),
12156 + res.start, res.end + 1 - res.start, "mac");
12157 + if (unlikely(mac_dev->res == NULL)) {
12158 + dev_err(dev, "__devm_request_mem_region(mac) failed\n");
12159 + _errno = -EBUSY;
12160 + goto _return_dev_set_drvdata;
12161 + }
12162 +
12163 + mac_dev->vaddr = devm_ioremap(dev, mac_dev->res->start,
12164 + mac_dev->res->end + 1
12165 + - mac_dev->res->start);
12166 + if (unlikely(mac_dev->vaddr == NULL)) {
12167 + dev_err(dev, "devm_ioremap() failed\n");
12168 + _errno = -EIO;
12169 + goto _return_dev_set_drvdata;
12170 + }
12171 +
12172 +#define TBIPA_OFFSET 0x1c
12173 +#define TBIPA_DEFAULT_ADDR 5 /* override if used as external PHY addr. */
12174 + mac_dev->tbi_node = of_parse_phandle(mac_node, "tbi-handle", 0);
12175 + if (mac_dev->tbi_node) {
12176 + u32 tbiaddr = TBIPA_DEFAULT_ADDR;
12177 + const __be32 *tbi_reg;
12178 + void __iomem *addr;
12179 +
12180 + tbi_reg = of_get_property(mac_dev->tbi_node, "reg", NULL);
12181 + if (tbi_reg)
12182 + tbiaddr = be32_to_cpup(tbi_reg);
12183 + addr = mac_dev->vaddr + TBIPA_OFFSET;
12184 + /* TODO: out_be32 does not exist on ARM */
12185 + out_be32(addr, tbiaddr);
12186 + }
12187 +
12188 + if (!of_device_is_available(mac_node)) {
12189 + devm_iounmap(dev, mac_dev->vaddr);
12190 + __devm_release_region(dev, fm_get_mem_region(mac_dev->fm_dev),
12191 + res.start, res.end + 1 - res.start);
12192 + fm_unbind(mac_dev->fm_dev);
12193 + devm_kfree(dev, mac_dev);
12194 + dev_set_drvdata(dev, NULL);
12195 + return -ENODEV;
12196 + }
12197 +
12198 + /* Get the cell-index */
12199 + _errno = of_property_read_u32(mac_node, "cell-index", &cell_index);
12200 + if (unlikely(_errno)) {
12201 + dev_err(dev, "Cannot read cell-index of mac node %s from device tree\n",
12202 + mac_node->full_name);
12203 + goto _return_dev_set_drvdata;
12204 + }
12205 + mac_dev->cell_index = (uint8_t)cell_index;
12206 + if (mac_dev->cell_index >= 8)
12207 + mac_dev->cell_index -= 8;
12208 +
12209 + /* Get the MAC address */
12210 + mac_addr = of_get_mac_address(mac_node);
12211 + if (unlikely(mac_addr == NULL)) {
12212 + dev_err(dev, "of_get_mac_address(%s) failed\n",
12213 + mac_node->full_name);
12214 + _errno = -EINVAL;
12215 + goto _return_dev_set_drvdata;
12216 + }
12217 + memcpy(mac_dev->addr, mac_addr, sizeof(mac_dev->addr));
12218 +
12219 + /* Verify the number of port handles */
12220 + nph = of_count_phandle_with_args(mac_node, "fsl,fman-ports", NULL);
12221 + if (unlikely(nph < 0)) {
12222 + dev_err(dev, "Cannot read port handles of mac node %s from device tree\n",
12223 + mac_node->full_name);
12224 + _errno = nph;
12225 + goto _return_dev_set_drvdata;
12226 + }
12227 +
12228 + if (nph != ARRAY_SIZE(mac_dev->port_dev)) {
12229 + dev_err(dev, "Not supported number of port handles of mac node %s from device tree\n",
12230 + mac_node->full_name);
12231 + _errno = -EINVAL;
12232 + goto _return_dev_set_drvdata;
12233 + }
12234 +
12235 + for_each_port_device(i, mac_dev->port_dev) {
12236 + dev_node = of_parse_phandle(mac_node, "fsl,fman-ports", i);
12237 + if (unlikely(dev_node == NULL)) {
12238 + dev_err(dev, "Cannot find port node referenced by mac node %s from device tree\n",
12239 + mac_node->full_name);
12240 + _errno = -EINVAL;
12241 + goto _return_of_node_put;
12242 + }
12243 +
12244 + of_dev = of_find_device_by_node(dev_node);
12245 + if (unlikely(of_dev == NULL)) {
12246 + dev_err(dev, "of_find_device_by_node(%s) failed\n",
12247 + dev_node->full_name);
12248 + _errno = -EINVAL;
12249 + goto _return_of_node_put;
12250 + }
12251 +
12252 + mac_dev->port_dev[i] = fm_port_bind(&of_dev->dev);
12253 + if (unlikely(mac_dev->port_dev[i] == NULL)) {
12254 + dev_err(dev, "dev_get_drvdata(%s) failed\n",
12255 + dev_node->full_name);
12256 + _errno = -EINVAL;
12257 + goto _return_of_node_put;
12258 + }
12259 + of_node_put(dev_node);
12260 + }
12261 +
12262 + /* Get the PHY connection type */
12263 + _errno = of_property_read_string(mac_node, "phy-connection-type",
12264 + &char_prop);
12265 + if (unlikely(_errno)) {
12266 + dev_warn(dev,
12267 + "Cannot read PHY connection type of mac node %s from device tree. Defaulting to MII\n",
12268 + mac_node->full_name);
12269 + mac_dev->phy_if = PHY_INTERFACE_MODE_MII;
12270 + } else
12271 + mac_dev->phy_if = str2phy(char_prop);
12272 +
12273 + mac_dev->link = false;
12274 + mac_dev->half_duplex = false;
12275 + mac_dev->speed = phy2speed[mac_dev->phy_if];
12276 + mac_dev->max_speed = mac_dev->speed;
12277 + mac_dev->if_support = DTSEC_SUPPORTED;
12278 + /* We don't support half-duplex in SGMII mode */
12279 + if (strstr(char_prop, "sgmii") || strstr(char_prop, "qsgmii") ||
12280 + strstr(char_prop, "sgmii-2500"))
12281 + mac_dev->if_support &= ~(SUPPORTED_10baseT_Half |
12282 + SUPPORTED_100baseT_Half);
12283 +
12284 + /* Gigabit support (no half-duplex) */
12285 + if (mac_dev->max_speed == SPEED_1000 ||
12286 + mac_dev->max_speed == SPEED_2500)
12287 + mac_dev->if_support |= SUPPORTED_1000baseT_Full;
12288 +
12289 + /* The 10G interface only supports one mode */
12290 + if (strstr(char_prop, "xgmii"))
12291 + mac_dev->if_support = SUPPORTED_10000baseT_Full;
12292 +
12293 + /* Get the rest of the PHY information */
12294 + mac_dev->phy_node = of_parse_phandle(mac_node, "phy-handle", 0);
12295 + if (!mac_dev->phy_node) {
12296 + struct phy_device *phy;
12297 +
12298 + if (!of_phy_is_fixed_link(mac_node)) {
12299 + dev_err(dev, "Wrong PHY information of mac node %s\n",
12300 + mac_node->full_name);
12301 + goto _return_dev_set_drvdata;
12302 + }
12303 +
12304 + _errno = of_phy_register_fixed_link(mac_node);
12305 + if (_errno)
12306 + goto _return_dev_set_drvdata;
12307 +
12308 + mac_dev->fixed_link = devm_kzalloc(mac_dev->dev,
12309 + sizeof(*mac_dev->fixed_link),
12310 + GFP_KERNEL);
12311 + if (!mac_dev->fixed_link)
12312 + goto _return_dev_set_drvdata;
12313 +
12314 + mac_dev->phy_node = of_node_get(mac_node);
12315 + phy = of_phy_find_device(mac_dev->phy_node);
12316 + if (!phy)
12317 + goto _return_dev_set_drvdata;
12318 +
12319 + mac_dev->fixed_link->link = phy->link;
12320 + mac_dev->fixed_link->speed = phy->speed;
12321 + mac_dev->fixed_link->duplex = phy->duplex;
12322 + mac_dev->fixed_link->pause = phy->pause;
12323 + mac_dev->fixed_link->asym_pause = phy->asym_pause;
12324 + }
12325 +
12326 + _errno = mac_dev->init(mac_dev);
12327 + if (unlikely(_errno < 0)) {
12328 + dev_err(dev, "mac_dev->init() = %d\n", _errno);
12329 + goto _return_dev_set_drvdata;
12330 + }
12331 +
12332 + /* pause frame autonegotiation enabled*/
12333 + mac_dev->autoneg_pause = true;
12334 +
12335 + /* by intializing the values to false, force FMD to enable PAUSE frames
12336 + * on RX and TX
12337 + */
12338 + mac_dev->rx_pause_req = mac_dev->tx_pause_req = true;
12339 + mac_dev->rx_pause_active = mac_dev->tx_pause_active = false;
12340 + _errno = set_mac_active_pause(mac_dev, true, true);
12341 + if (unlikely(_errno < 0))
12342 + dev_err(dev, "set_mac_active_pause() = %d\n", _errno);
12343 +
12344 + dev_info(dev,
12345 + "FMan MAC address: %02hx:%02hx:%02hx:%02hx:%02hx:%02hx\n",
12346 + mac_dev->addr[0], mac_dev->addr[1], mac_dev->addr[2],
12347 + mac_dev->addr[3], mac_dev->addr[4], mac_dev->addr[5]);
12348 +
12349 + goto _return;
12350 +
12351 +_return_of_node_put:
12352 + of_node_put(dev_node);
12353 +_return_dev_set_drvdata:
12354 + dev_set_drvdata(dev, NULL);
12355 +_return:
12356 + return _errno;
12357 +}
12358 +
12359 +static int __cold mac_remove(struct platform_device *of_dev)
12360 +{
12361 + int i, _errno;
12362 + struct device *dev;
12363 + struct mac_device *mac_dev;
12364 +
12365 + dev = &of_dev->dev;
12366 + mac_dev = (struct mac_device *)dev_get_drvdata(dev);
12367 +
12368 + for_each_port_device(i, mac_dev->port_dev)
12369 + fm_port_unbind(mac_dev->port_dev[i]);
12370 +
12371 + fm_unbind(mac_dev->fm_dev);
12372 +
12373 + _errno = free_macdev(mac_dev);
12374 +
12375 + return _errno;
12376 +}
12377 +
12378 +static struct platform_driver mac_driver = {
12379 + .driver = {
12380 + .name = KBUILD_MODNAME,
12381 + .of_match_table = mac_match,
12382 + .owner = THIS_MODULE,
12383 + },
12384 + .probe = mac_probe,
12385 + .remove = mac_remove
12386 +};
12387 +
12388 +static int __init __cold mac_load(void)
12389 +{
12390 + int _errno;
12391 +
12392 + pr_debug(KBUILD_MODNAME ": -> %s:%s()\n",
12393 + KBUILD_BASENAME".c", __func__);
12394 +
12395 + pr_info(KBUILD_MODNAME ": %s\n", mac_driver_description);
12396 +
12397 + _errno = platform_driver_register(&mac_driver);
12398 + if (unlikely(_errno < 0)) {
12399 + pr_err(KBUILD_MODNAME ": %s:%hu:%s(): platform_driver_register() = %d\n",
12400 + KBUILD_BASENAME".c", __LINE__, __func__, _errno);
12401 + goto _return;
12402 + }
12403 +
12404 + goto _return;
12405 +
12406 +_return:
12407 + pr_debug(KBUILD_MODNAME ": %s:%s() ->\n",
12408 + KBUILD_BASENAME".c", __func__);
12409 +
12410 + return _errno;
12411 +}
12412 +module_init(mac_load);
12413 +
12414 +static void __exit __cold mac_unload(void)
12415 +{
12416 + pr_debug(KBUILD_MODNAME ": -> %s:%s()\n",
12417 + KBUILD_BASENAME".c", __func__);
12418 +
12419 + platform_driver_unregister(&mac_driver);
12420 +
12421 + pr_debug(KBUILD_MODNAME ": %s:%s() ->\n",
12422 + KBUILD_BASENAME".c", __func__);
12423 +}
12424 +module_exit(mac_unload);
12425 --- /dev/null
12426 +++ b/drivers/net/ethernet/freescale/sdk_dpaa/mac.h
12427 @@ -0,0 +1,135 @@
12428 +/* Copyright 2008-2011 Freescale Semiconductor, Inc.
12429 + *
12430 + * Redistribution and use in source and binary forms, with or without
12431 + * modification, are permitted provided that the following conditions are met:
12432 + * * Redistributions of source code must retain the above copyright
12433 + * notice, this list of conditions and the following disclaimer.
12434 + * * Redistributions in binary form must reproduce the above copyright
12435 + * notice, this list of conditions and the following disclaimer in the
12436 + * documentation and/or other materials provided with the distribution.
12437 + * * Neither the name of Freescale Semiconductor nor the
12438 + * names of its contributors may be used to endorse or promote products
12439 + * derived from this software without specific prior written permission.
12440 + *
12441 + *
12442 + * ALTERNATIVELY, this software may be distributed under the terms of the
12443 + * GNU General Public License ("GPL") as published by the Free Software
12444 + * Foundation, either version 2 of that License or (at your option) any
12445 + * later version.
12446 + *
12447 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
12448 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
12449 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
12450 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
12451 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
12452 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
12453 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
12454 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
12455 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
12456 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
12457 + */
12458 +
12459 +#ifndef __MAC_H
12460 +#define __MAC_H
12461 +
12462 +#include <linux/device.h> /* struct device, BUS_ID_SIZE */
12463 +#include <linux/if_ether.h> /* ETH_ALEN */
12464 +#include <linux/phy.h> /* phy_interface_t, struct phy_device */
12465 +#include <linux/list.h>
12466 +
12467 +#include "lnxwrp_fsl_fman.h" /* struct port_device */
12468 +
12469 +enum {DTSEC, XGMAC, MEMAC};
12470 +
12471 +struct mac_device {
12472 + struct device *dev;
12473 + void *priv;
12474 + uint8_t cell_index;
12475 + struct resource *res;
12476 + void __iomem *vaddr;
12477 + uint8_t addr[ETH_ALEN];
12478 + bool promisc;
12479 +
12480 + struct fm *fm_dev;
12481 + struct fm_port *port_dev[2];
12482 +
12483 + phy_interface_t phy_if;
12484 + u32 if_support;
12485 + bool link;
12486 + bool half_duplex;
12487 + uint16_t speed;
12488 + uint16_t max_speed;
12489 + struct device_node *phy_node;
12490 + char fixed_bus_id[MII_BUS_ID_SIZE + 3];
12491 + struct device_node *tbi_node;
12492 + struct phy_device *phy_dev;
12493 + void *fm;
12494 + /* List of multicast addresses */
12495 + struct list_head mc_addr_list;
12496 + struct fixed_phy_status *fixed_link;
12497 +
12498 + bool autoneg_pause;
12499 + bool rx_pause_req;
12500 + bool tx_pause_req;
12501 + bool rx_pause_active;
12502 + bool tx_pause_active;
12503 +
12504 + struct fm_mac_dev *(*get_mac_handle)(struct mac_device *mac_dev);
12505 + int (*init_phy)(struct net_device *net_dev, struct mac_device *mac_dev);
12506 + int (*init)(struct mac_device *mac_dev);
12507 + int (*start)(struct mac_device *mac_dev);
12508 + int (*stop)(struct mac_device *mac_dev);
12509 + int (*set_promisc)(struct fm_mac_dev *fm_mac_dev, bool enable);
12510 + int (*change_addr)(struct fm_mac_dev *fm_mac_dev, uint8_t *addr);
12511 + int (*set_multi)(struct net_device *net_dev,
12512 + struct mac_device *mac_dev);
12513 + int (*uninit)(struct fm_mac_dev *fm_mac_dev);
12514 + int (*ptp_enable)(struct fm_mac_dev *fm_mac_dev);
12515 + int (*ptp_disable)(struct fm_mac_dev *fm_mac_dev);
12516 + int (*set_rx_pause)(struct fm_mac_dev *fm_mac_dev, bool en);
12517 + int (*set_tx_pause)(struct fm_mac_dev *fm_mac_dev, bool en);
12518 + int (*fm_rtc_enable)(struct fm *fm_dev);
12519 + int (*fm_rtc_disable)(struct fm *fm_dev);
12520 + int (*fm_rtc_get_cnt)(struct fm *fm_dev, uint64_t *ts);
12521 + int (*fm_rtc_set_cnt)(struct fm *fm_dev, uint64_t ts);
12522 + int (*fm_rtc_get_drift)(struct fm *fm_dev, uint32_t *drift);
12523 + int (*fm_rtc_set_drift)(struct fm *fm_dev, uint32_t drift);
12524 + int (*fm_rtc_set_alarm)(struct fm *fm_dev, uint32_t id, uint64_t time);
12525 + int (*fm_rtc_set_fiper)(struct fm *fm_dev, uint32_t id,
12526 + uint64_t fiper);
12527 +#ifdef CONFIG_PTP_1588_CLOCK_DPAA
12528 + int (*fm_rtc_enable_interrupt)(struct fm *fm_dev, uint32_t events);
12529 + int (*fm_rtc_disable_interrupt)(struct fm *fm_dev, uint32_t events);
12530 +#endif
12531 + int (*set_wol)(struct fm_port *port, struct fm_mac_dev *fm_mac_dev,
12532 + bool en);
12533 + int (*dump_mac_regs)(struct mac_device *h_mac, char *buf, int nn);
12534 + int (*dump_mac_rx_stats)(struct mac_device *h_mac, char *buf, int nn);
12535 + int (*dump_mac_tx_stats)(struct mac_device *h_mac, char *buf, int nn);
12536 +};
12537 +
12538 +struct mac_address {
12539 + uint8_t addr[ETH_ALEN];
12540 + struct list_head list;
12541 +};
12542 +
12543 +#define get_fm_handle(net_dev) \
12544 + (((struct dpa_priv_s *)netdev_priv(net_dev))->mac_dev->fm_dev)
12545 +
12546 +#define for_each_port_device(i, port_dev) \
12547 + for (i = 0; i < ARRAY_SIZE(port_dev); i++)
12548 +
12549 +static inline __attribute((nonnull)) void *macdev_priv(
12550 + const struct mac_device *mac_dev)
12551 +{
12552 + return (void *)mac_dev + sizeof(*mac_dev);
12553 +}
12554 +
12555 +extern const char *mac_driver_description;
12556 +extern const size_t mac_sizeof_priv[];
12557 +extern void (*const mac_setup[])(struct mac_device *mac_dev);
12558 +
12559 +int set_mac_active_pause(struct mac_device *mac_dev, bool rx, bool tx);
12560 +void get_pause_cfg(struct mac_device *mac_dev, bool *rx_pause, bool *tx_pause);
12561 +
12562 +#endif /* __MAC_H */
12563 --- /dev/null
12564 +++ b/drivers/net/ethernet/freescale/sdk_dpaa/offline_port.c
12565 @@ -0,0 +1,848 @@
12566 +/* Copyright 2011-2012 Freescale Semiconductor Inc.
12567 + *
12568 + * Redistribution and use in source and binary forms, with or without
12569 + * modification, are permitted provided that the following conditions are met:
12570 + * * Redistributions of source code must retain the above copyright
12571 + * notice, this list of conditions and the following disclaimer.
12572 + * * Redistributions in binary form must reproduce the above copyright
12573 + * notice, this list of conditions and the following disclaimer in the
12574 + * documentation and/or other materials provided with the distribution.
12575 + * * Neither the name of Freescale Semiconductor nor the
12576 + * names of its contributors may be used to endorse or promote products
12577 + * derived from this software without specific prior written permission.
12578 + *
12579 + *
12580 + * ALTERNATIVELY, this software may be distributed under the terms of the
12581 + * GNU General Public License ("GPL") as published by the Free Software
12582 + * Foundation, either version 2 of that License or (at your option) any
12583 + * later version.
12584 + *
12585 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
12586 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
12587 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
12588 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
12589 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
12590 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
12591 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
12592 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
12593 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
12594 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
12595 + */
12596 +
12597 +/* Offline Parsing / Host Command port driver for FSL QorIQ FMan.
12598 + * Validates device-tree configuration and sets up the offline ports.
12599 + */
12600 +
12601 +#ifdef CONFIG_FSL_DPAA_ETH_DEBUG
12602 +#define pr_fmt(fmt) \
12603 + KBUILD_MODNAME ": %s:%hu:%s() " fmt, \
12604 + KBUILD_BASENAME".c", __LINE__, __func__
12605 +#else
12606 +#define pr_fmt(fmt) \
12607 + KBUILD_MODNAME ": " fmt
12608 +#endif
12609 +
12610 +
12611 +#include <linux/init.h>
12612 +#include <linux/module.h>
12613 +#include <linux/of_platform.h>
12614 +#include <linux/fsl_qman.h>
12615 +
12616 +#include "offline_port.h"
12617 +#include "dpaa_eth.h"
12618 +#include "dpaa_eth_common.h"
12619 +
12620 +#define OH_MOD_DESCRIPTION "FSL FMan Offline Parsing port driver"
12621 +/* Manip extra space and data alignment for fragmentation */
12622 +#define FRAG_MANIP_SPACE 128
12623 +#define FRAG_DATA_ALIGN 64
12624 +
12625 +
12626 +MODULE_LICENSE("Dual BSD/GPL");
12627 +MODULE_AUTHOR("Bogdan Hamciuc <bogdan.hamciuc@freescale.com>");
12628 +MODULE_DESCRIPTION(OH_MOD_DESCRIPTION);
12629 +
12630 +
12631 +static const struct of_device_id oh_port_match_table[] = {
12632 + {
12633 + .compatible = "fsl,dpa-oh"
12634 + },
12635 + {
12636 + .compatible = "fsl,dpa-oh-shared"
12637 + },
12638 + {}
12639 +};
12640 +MODULE_DEVICE_TABLE(of, oh_port_match_table);
12641 +
12642 +#ifdef CONFIG_PM
12643 +
12644 +static int oh_suspend(struct device *dev)
12645 +{
12646 + struct dpa_oh_config_s *oh_config;
12647 +
12648 + oh_config = dev_get_drvdata(dev);
12649 + return fm_port_suspend(oh_config->oh_port);
12650 +}
12651 +
12652 +static int oh_resume(struct device *dev)
12653 +{
12654 + struct dpa_oh_config_s *oh_config;
12655 +
12656 + oh_config = dev_get_drvdata(dev);
12657 + return fm_port_resume(oh_config->oh_port);
12658 +}
12659 +
12660 +static const struct dev_pm_ops oh_pm_ops = {
12661 + .suspend = oh_suspend,
12662 + .resume = oh_resume,
12663 +};
12664 +
12665 +#define OH_PM_OPS (&oh_pm_ops)
12666 +
12667 +#else /* CONFIG_PM */
12668 +
12669 +#define OH_PM_OPS NULL
12670 +
12671 +#endif /* CONFIG_PM */
12672 +
12673 +/* Creates Frame Queues */
12674 +static uint32_t oh_fq_create(struct qman_fq *fq,
12675 + uint32_t fq_id, uint16_t channel,
12676 + uint16_t wq_id)
12677 +{
12678 + struct qm_mcc_initfq fq_opts;
12679 + uint32_t create_flags, init_flags;
12680 + uint32_t ret = 0;
12681 +
12682 + if (fq == NULL)
12683 + return 1;
12684 +
12685 + /* Set flags for FQ create */
12686 + create_flags = QMAN_FQ_FLAG_LOCKED | QMAN_FQ_FLAG_TO_DCPORTAL;
12687 +
12688 + /* Create frame queue */
12689 + ret = qman_create_fq(fq_id, create_flags, fq);
12690 + if (ret != 0)
12691 + return 1;
12692 +
12693 + /* Set flags for FQ init */
12694 + init_flags = QMAN_INITFQ_FLAG_SCHED;
12695 +
12696 + /* Set FQ init options. Specify destination WQ ID and channel */
12697 + fq_opts.we_mask = QM_INITFQ_WE_DESTWQ;
12698 + fq_opts.fqd.dest.wq = wq_id;
12699 + fq_opts.fqd.dest.channel = channel;
12700 +
12701 + /* Initialize frame queue */
12702 + ret = qman_init_fq(fq, init_flags, &fq_opts);
12703 + if (ret != 0) {
12704 + qman_destroy_fq(fq, 0);
12705 + return 1;
12706 + }
12707 +
12708 + return 0;
12709 +}
12710 +
12711 +static void dump_fq(struct device *dev, int fqid, uint16_t channel)
12712 +{
12713 + if (channel) {
12714 + /* display fqs with a valid (!= 0) destination channel */
12715 + dev_info(dev, "FQ ID:%d Channel ID:%d\n", fqid, channel);
12716 + }
12717 +}
12718 +
12719 +static void dump_fq_duple(struct device *dev, struct qman_fq *fqs,
12720 + int fqs_count, uint16_t channel_id)
12721 +{
12722 + int i;
12723 + for (i = 0; i < fqs_count; i++)
12724 + dump_fq(dev, (fqs + i)->fqid, channel_id);
12725 +}
12726 +
12727 +static void dump_oh_config(struct device *dev, struct dpa_oh_config_s *conf)
12728 +{
12729 + struct list_head *fq_list;
12730 + struct fq_duple *fqd;
12731 + int i;
12732 +
12733 + dev_info(dev, "Default egress frame queue: %d\n", conf->default_fqid);
12734 + dev_info(dev, "Default error frame queue: %d\n", conf->error_fqid);
12735 +
12736 + /* TX queues (old initialization) */
12737 + dev_info(dev, "Initialized queues:");
12738 + for (i = 0; i < conf->egress_cnt; i++)
12739 + dump_fq_duple(dev, conf->egress_fqs, conf->egress_cnt,
12740 + conf->channel);
12741 +
12742 + /* initialized ingress queues */
12743 + list_for_each(fq_list, &conf->fqs_ingress_list) {
12744 + fqd = list_entry(fq_list, struct fq_duple, fq_list);
12745 + dump_fq_duple(dev, fqd->fqs, fqd->fqs_count, fqd->channel_id);
12746 + }
12747 +
12748 + /* initialized egress queues */
12749 + list_for_each(fq_list, &conf->fqs_egress_list) {
12750 + fqd = list_entry(fq_list, struct fq_duple, fq_list);
12751 + dump_fq_duple(dev, fqd->fqs, fqd->fqs_count, fqd->channel_id);
12752 + }
12753 +}
12754 +
12755 +/* Destroys Frame Queues */
12756 +static void oh_fq_destroy(struct qman_fq *fq)
12757 +{
12758 + int _errno = 0;
12759 +
12760 + _errno = qman_retire_fq(fq, NULL);
12761 + if (unlikely(_errno < 0))
12762 + pr_err(KBUILD_MODNAME": %s:%hu:%s(): qman_retire_fq(%u)=%d\n",
12763 + KBUILD_BASENAME".c", __LINE__, __func__,
12764 + qman_fq_fqid(fq), _errno);
12765 +
12766 + _errno = qman_oos_fq(fq);
12767 + if (unlikely(_errno < 0)) {
12768 + pr_err(KBUILD_MODNAME": %s:%hu:%s(): qman_oos_fq(%u)=%d\n",
12769 + KBUILD_BASENAME".c", __LINE__, __func__,
12770 + qman_fq_fqid(fq), _errno);
12771 + }
12772 +
12773 + qman_destroy_fq(fq, 0);
12774 +}
12775 +
12776 +/* Allocation code for the OH port's PCD frame queues */
12777 +static int __cold oh_alloc_pcd_fqids(struct device *dev,
12778 + uint32_t num,
12779 + uint8_t alignment,
12780 + uint32_t *base_fqid)
12781 +{
12782 + dev_crit(dev, "callback not implemented!\n");
12783 + BUG();
12784 +
12785 + return 0;
12786 +}
12787 +
12788 +static int __cold oh_free_pcd_fqids(struct device *dev, uint32_t base_fqid)
12789 +{
12790 + dev_crit(dev, "callback not implemented!\n");
12791 + BUG();
12792 +
12793 + return 0;
12794 +}
12795 +
12796 +static void oh_set_buffer_layout(struct fm_port *port,
12797 + struct dpa_buffer_layout_s *layout)
12798 +{
12799 + struct fm_port_params params;
12800 +
12801 + layout->priv_data_size = DPA_TX_PRIV_DATA_SIZE;
12802 + layout->parse_results = true;
12803 + layout->hash_results = true;
12804 + layout->time_stamp = false;
12805 +
12806 + fm_port_get_buff_layout_ext_params(port, &params);
12807 + layout->manip_extra_space = params.manip_extra_space;
12808 + layout->data_align = params.data_align;
12809 +}
12810 +
12811 +static int
12812 +oh_port_probe(struct platform_device *_of_dev)
12813 +{
12814 + struct device *dpa_oh_dev;
12815 + struct device_node *dpa_oh_node;
12816 + int lenp, _errno = 0, fq_idx, duple_idx;
12817 + int n_size, i, j, ret, duples_count;
12818 + struct platform_device *oh_of_dev;
12819 + struct device_node *oh_node, *bpool_node = NULL, *root_node;
12820 + struct device *oh_dev;
12821 + struct dpa_oh_config_s *oh_config = NULL;
12822 + const __be32 *oh_all_queues;
12823 + const __be32 *channel_ids;
12824 + const __be32 *oh_tx_queues;
12825 + uint32_t queues_count;
12826 + uint32_t crt_fqid_base;
12827 + uint32_t crt_fq_count;
12828 + bool frag_enabled = false;
12829 + struct fm_port_params oh_port_tx_params;
12830 + struct fm_port_pcd_param oh_port_pcd_params;
12831 + struct dpa_buffer_layout_s buf_layout;
12832 +
12833 + /* True if the current partition owns the OH port. */
12834 + bool init_oh_port;
12835 +
12836 + const struct of_device_id *match;
12837 + int crt_ext_pools_count;
12838 + u32 ext_pool_size;
12839 + u32 port_id;
12840 + u32 channel_id;
12841 +
12842 + int channel_ids_count;
12843 + int channel_idx;
12844 + struct fq_duple *fqd;
12845 + struct list_head *fq_list, *fq_list_tmp;
12846 +
12847 + const __be32 *bpool_cfg;
12848 + uint32_t bpid;
12849 +
12850 + memset(&oh_port_tx_params, 0, sizeof(oh_port_tx_params));
12851 + dpa_oh_dev = &_of_dev->dev;
12852 + dpa_oh_node = dpa_oh_dev->of_node;
12853 + BUG_ON(dpa_oh_node == NULL);
12854 +
12855 + match = of_match_device(oh_port_match_table, dpa_oh_dev);
12856 + if (!match)
12857 + return -EINVAL;
12858 +
12859 + dev_dbg(dpa_oh_dev, "Probing OH port...\n");
12860 +
12861 + /* Find the referenced OH node */
12862 + oh_node = of_parse_phandle(dpa_oh_node, "fsl,fman-oh-port", 0);
12863 + if (oh_node == NULL) {
12864 + dev_err(dpa_oh_dev,
12865 + "Can't find OH node referenced from node %s\n",
12866 + dpa_oh_node->full_name);
12867 + return -EINVAL;
12868 + }
12869 + dev_info(dpa_oh_dev, "Found OH node handle compatible with %s\n",
12870 + match->compatible);
12871 +
12872 + _errno = of_property_read_u32(oh_node, "cell-index", &port_id);
12873 + if (_errno) {
12874 + dev_err(dpa_oh_dev, "No port id found in node %s\n",
12875 + dpa_oh_node->full_name);
12876 + goto return_kfree;
12877 + }
12878 +
12879 + _errno = of_property_read_u32(oh_node, "fsl,qman-channel-id",
12880 + &channel_id);
12881 + if (_errno) {
12882 + dev_err(dpa_oh_dev, "No channel id found in node %s\n",
12883 + dpa_oh_node->full_name);
12884 + goto return_kfree;
12885 + }
12886 +
12887 + oh_of_dev = of_find_device_by_node(oh_node);
12888 + BUG_ON(oh_of_dev == NULL);
12889 + oh_dev = &oh_of_dev->dev;
12890 +
12891 + /* The OH port must be initialized exactly once.
12892 + * The following scenarios are of interest:
12893 + * - the node is Linux-private (will always initialize it);
12894 + * - the node is shared between two Linux partitions
12895 + * (only one of them will initialize it);
12896 + * - the node is shared between a Linux and a LWE partition
12897 + * (Linux will initialize it) - "fsl,dpa-oh-shared"
12898 + */
12899 +
12900 + /* Check if the current partition owns the OH port
12901 + * and ought to initialize it. It may be the case that we leave this
12902 + * to another (also Linux) partition.
12903 + */
12904 + init_oh_port = strcmp(match->compatible, "fsl,dpa-oh-shared");
12905 +
12906 + /* If we aren't the "owner" of the OH node, we're done here. */
12907 + if (!init_oh_port) {
12908 + dev_dbg(dpa_oh_dev,
12909 + "Not owning the shared OH port %s, will not initialize it.\n",
12910 + oh_node->full_name);
12911 + of_node_put(oh_node);
12912 + return 0;
12913 + }
12914 +
12915 + /* Allocate OH dev private data */
12916 + oh_config = devm_kzalloc(dpa_oh_dev, sizeof(*oh_config), GFP_KERNEL);
12917 + if (oh_config == NULL) {
12918 + dev_err(dpa_oh_dev,
12919 + "Can't allocate private data for OH node %s referenced from node %s!\n",
12920 + oh_node->full_name, dpa_oh_node->full_name);
12921 + _errno = -ENOMEM;
12922 + goto return_kfree;
12923 + }
12924 +
12925 + INIT_LIST_HEAD(&oh_config->fqs_ingress_list);
12926 + INIT_LIST_HEAD(&oh_config->fqs_egress_list);
12927 +
12928 + /* FQs that enter OH port */
12929 + lenp = 0;
12930 + oh_all_queues = of_get_property(dpa_oh_node,
12931 + "fsl,qman-frame-queues-ingress", &lenp);
12932 + if (lenp % (2 * sizeof(*oh_all_queues))) {
12933 + dev_warn(dpa_oh_dev,
12934 + "Wrong ingress queues format for OH node %s referenced from node %s!\n",
12935 + oh_node->full_name, dpa_oh_node->full_name);
12936 + /* just ignore the last unpaired value */
12937 + }
12938 +
12939 + duples_count = lenp / (2 * sizeof(*oh_all_queues));
12940 + dev_err(dpa_oh_dev, "Allocating %d ingress frame queues duples\n",
12941 + duples_count);
12942 + for (duple_idx = 0; duple_idx < duples_count; duple_idx++) {
12943 + crt_fqid_base = be32_to_cpu(oh_all_queues[2 * duple_idx]);
12944 + crt_fq_count = be32_to_cpu(oh_all_queues[2 * duple_idx + 1]);
12945 +
12946 + fqd = devm_kzalloc(dpa_oh_dev,
12947 + sizeof(struct fq_duple), GFP_KERNEL);
12948 + if (!fqd) {
12949 + dev_err(dpa_oh_dev, "Can't allocate structures for ingress frame queues for OH node %s referenced from node %s!\n",
12950 + oh_node->full_name,
12951 + dpa_oh_node->full_name);
12952 + _errno = -ENOMEM;
12953 + goto return_kfree;
12954 + }
12955 +
12956 + fqd->fqs = devm_kzalloc(dpa_oh_dev,
12957 + crt_fq_count * sizeof(struct qman_fq),
12958 + GFP_KERNEL);
12959 + if (!fqd->fqs) {
12960 + dev_err(dpa_oh_dev, "Can't allocate structures for ingress frame queues for OH node %s referenced from node %s!\n",
12961 + oh_node->full_name,
12962 + dpa_oh_node->full_name);
12963 + _errno = -ENOMEM;
12964 + goto return_kfree;
12965 + }
12966 +
12967 + for (j = 0; j < crt_fq_count; j++)
12968 + (fqd->fqs + j)->fqid = crt_fqid_base + j;
12969 + fqd->fqs_count = crt_fq_count;
12970 + fqd->channel_id = (uint16_t)channel_id;
12971 + list_add(&fqd->fq_list, &oh_config->fqs_ingress_list);
12972 + }
12973 +
12974 + /* create the ingress queues */
12975 + list_for_each(fq_list, &oh_config->fqs_ingress_list) {
12976 + fqd = list_entry(fq_list, struct fq_duple, fq_list);
12977 +
12978 + for (j = 0; j < fqd->fqs_count; j++) {
12979 + ret = oh_fq_create(fqd->fqs + j,
12980 + (fqd->fqs + j)->fqid,
12981 + fqd->channel_id, 3);
12982 + if (ret != 0) {
12983 + dev_err(dpa_oh_dev, "Unable to create ingress frame queue %d for OH node %s referenced from node %s!\n",
12984 + (fqd->fqs + j)->fqid,
12985 + oh_node->full_name,
12986 + dpa_oh_node->full_name);
12987 + _errno = -EINVAL;
12988 + goto return_kfree;
12989 + }
12990 + }
12991 + }
12992 +
12993 + /* FQs that exit OH port */
12994 + lenp = 0;
12995 + oh_all_queues = of_get_property(dpa_oh_node,
12996 + "fsl,qman-frame-queues-egress", &lenp);
12997 + if (lenp % (2 * sizeof(*oh_all_queues))) {
12998 + dev_warn(dpa_oh_dev,
12999 + "Wrong egress queues format for OH node %s referenced from node %s!\n",
13000 + oh_node->full_name, dpa_oh_node->full_name);
13001 + /* just ignore the last unpaired value */
13002 + }
13003 +
13004 + duples_count = lenp / (2 * sizeof(*oh_all_queues));
13005 + dev_dbg(dpa_oh_dev, "Allocating %d egress frame queues duples\n",
13006 + duples_count);
13007 + for (duple_idx = 0; duple_idx < duples_count; duple_idx++) {
13008 + crt_fqid_base = be32_to_cpu(oh_all_queues[2 * duple_idx]);
13009 + crt_fq_count = be32_to_cpu(oh_all_queues[2 * duple_idx + 1]);
13010 +
13011 + fqd = devm_kzalloc(dpa_oh_dev,
13012 + sizeof(struct fq_duple), GFP_KERNEL);
13013 + if (!fqd) {
13014 + dev_err(dpa_oh_dev, "Can't allocate structures for egress frame queues for OH node %s referenced from node %s!\n",
13015 + oh_node->full_name,
13016 + dpa_oh_node->full_name);
13017 + _errno = -ENOMEM;
13018 + goto return_kfree;
13019 + }
13020 +
13021 + fqd->fqs = devm_kzalloc(dpa_oh_dev,
13022 + crt_fq_count * sizeof(struct qman_fq),
13023 + GFP_KERNEL);
13024 + if (!fqd->fqs) {
13025 + dev_err(dpa_oh_dev,
13026 + "Can't allocate structures for egress frame queues for OH node %s referenced from node %s!\n",
13027 + oh_node->full_name,
13028 + dpa_oh_node->full_name);
13029 + _errno = -ENOMEM;
13030 + goto return_kfree;
13031 + }
13032 +
13033 + for (j = 0; j < crt_fq_count; j++)
13034 + (fqd->fqs + j)->fqid = crt_fqid_base + j;
13035 + fqd->fqs_count = crt_fq_count;
13036 + /* channel ID is specified in another attribute */
13037 + fqd->channel_id = 0;
13038 + list_add_tail(&fqd->fq_list, &oh_config->fqs_egress_list);
13039 +
13040 + /* allocate the queue */
13041 +
13042 + }
13043 +
13044 + /* channel_ids for FQs that exit OH port */
13045 + lenp = 0;
13046 + channel_ids = of_get_property(dpa_oh_node,
13047 + "fsl,qman-channel-ids-egress", &lenp);
13048 +
13049 + channel_ids_count = lenp / (sizeof(*channel_ids));
13050 + if (channel_ids_count != duples_count) {
13051 + dev_warn(dpa_oh_dev,
13052 + "Not all egress queues have a channel id for OH node %s referenced from node %s!\n",
13053 + oh_node->full_name, dpa_oh_node->full_name);
13054 + /* just ignore the queues that do not have a Channel ID */
13055 + }
13056 +
13057 + channel_idx = 0;
13058 + list_for_each(fq_list, &oh_config->fqs_egress_list) {
13059 + if (channel_idx + 1 > channel_ids_count)
13060 + break;
13061 + fqd = list_entry(fq_list, struct fq_duple, fq_list);
13062 + fqd->channel_id =
13063 + (uint16_t)be32_to_cpu(channel_ids[channel_idx++]);
13064 + }
13065 +
13066 + /* create egress queues */
13067 + list_for_each(fq_list, &oh_config->fqs_egress_list) {
13068 + fqd = list_entry(fq_list, struct fq_duple, fq_list);
13069 +
13070 + if (fqd->channel_id == 0) {
13071 + /* missing channel id in dts */
13072 + continue;
13073 + }
13074 +
13075 + for (j = 0; j < fqd->fqs_count; j++) {
13076 + ret = oh_fq_create(fqd->fqs + j,
13077 + (fqd->fqs + j)->fqid,
13078 + fqd->channel_id, 3);
13079 + if (ret != 0) {
13080 + dev_err(dpa_oh_dev, "Unable to create egress frame queue %d for OH node %s referenced from node %s!\n",
13081 + (fqd->fqs + j)->fqid,
13082 + oh_node->full_name,
13083 + dpa_oh_node->full_name);
13084 + _errno = -EINVAL;
13085 + goto return_kfree;
13086 + }
13087 + }
13088 + }
13089 +
13090 + /* Read FQ ids/nums for the DPA OH node */
13091 + oh_all_queues = of_get_property(dpa_oh_node,
13092 + "fsl,qman-frame-queues-oh", &lenp);
13093 + if (oh_all_queues == NULL) {
13094 + dev_err(dpa_oh_dev,
13095 + "No frame queues have been defined for OH node %s referenced from node %s\n",
13096 + oh_node->full_name, dpa_oh_node->full_name);
13097 + _errno = -EINVAL;
13098 + goto return_kfree;
13099 + }
13100 +
13101 + /* Check that the OH error and default FQs are there */
13102 + BUG_ON(lenp % (2 * sizeof(*oh_all_queues)));
13103 + queues_count = lenp / (2 * sizeof(*oh_all_queues));
13104 + if (queues_count != 2) {
13105 + dev_err(dpa_oh_dev,
13106 + "Error and Default queues must be defined for OH node %s referenced from node %s\n",
13107 + oh_node->full_name, dpa_oh_node->full_name);
13108 + _errno = -EINVAL;
13109 + goto return_kfree;
13110 + }
13111 +
13112 + /* Read the FQIDs defined for this OH port */
13113 + dev_dbg(dpa_oh_dev, "Reading %d queues...\n", queues_count);
13114 + fq_idx = 0;
13115 +
13116 + /* Error FQID - must be present */
13117 + crt_fqid_base = be32_to_cpu(oh_all_queues[fq_idx++]);
13118 + crt_fq_count = be32_to_cpu(oh_all_queues[fq_idx++]);
13119 + if (crt_fq_count != 1) {
13120 + dev_err(dpa_oh_dev,
13121 + "Only 1 Error FQ allowed in OH node %s referenced from node %s (read: %d FQIDs).\n",
13122 + oh_node->full_name, dpa_oh_node->full_name,
13123 + crt_fq_count);
13124 + _errno = -EINVAL;
13125 + goto return_kfree;
13126 + }
13127 + oh_config->error_fqid = crt_fqid_base;
13128 + dev_dbg(dpa_oh_dev, "Read Error FQID 0x%x for OH port %s.\n",
13129 + oh_config->error_fqid, oh_node->full_name);
13130 +
13131 + /* Default FQID - must be present */
13132 + crt_fqid_base = be32_to_cpu(oh_all_queues[fq_idx++]);
13133 + crt_fq_count = be32_to_cpu(oh_all_queues[fq_idx++]);
13134 + if (crt_fq_count != 1) {
13135 + dev_err(dpa_oh_dev,
13136 + "Only 1 Default FQ allowed in OH node %s referenced from %s (read: %d FQIDs).\n",
13137 + oh_node->full_name, dpa_oh_node->full_name,
13138 + crt_fq_count);
13139 + _errno = -EINVAL;
13140 + goto return_kfree;
13141 + }
13142 + oh_config->default_fqid = crt_fqid_base;
13143 + dev_dbg(dpa_oh_dev, "Read Default FQID 0x%x for OH port %s.\n",
13144 + oh_config->default_fqid, oh_node->full_name);
13145 +
13146 + /* TX FQID - presence is optional */
13147 + oh_tx_queues = of_get_property(dpa_oh_node, "fsl,qman-frame-queues-tx",
13148 + &lenp);
13149 + if (oh_tx_queues == NULL) {
13150 + dev_dbg(dpa_oh_dev,
13151 + "No tx queues have been defined for OH node %s referenced from node %s\n",
13152 + oh_node->full_name, dpa_oh_node->full_name);
13153 + goto config_port;
13154 + }
13155 +
13156 + /* Check that queues-tx has only a base and a count defined */
13157 + BUG_ON(lenp % (2 * sizeof(*oh_tx_queues)));
13158 + queues_count = lenp / (2 * sizeof(*oh_tx_queues));
13159 + if (queues_count != 1) {
13160 + dev_err(dpa_oh_dev,
13161 + "TX queues must be defined in only one <base count> tuple for OH node %s referenced from node %s\n",
13162 + oh_node->full_name, dpa_oh_node->full_name);
13163 + _errno = -EINVAL;
13164 + goto return_kfree;
13165 + }
13166 +
13167 + fq_idx = 0;
13168 + crt_fqid_base = be32_to_cpu(oh_tx_queues[fq_idx++]);
13169 + crt_fq_count = be32_to_cpu(oh_tx_queues[fq_idx++]);
13170 + oh_config->egress_cnt = crt_fq_count;
13171 +
13172 + /* Allocate TX queues */
13173 + dev_dbg(dpa_oh_dev, "Allocating %d queues for TX...\n", crt_fq_count);
13174 + oh_config->egress_fqs = devm_kzalloc(dpa_oh_dev,
13175 + crt_fq_count * sizeof(struct qman_fq), GFP_KERNEL);
13176 + if (oh_config->egress_fqs == NULL) {
13177 + dev_err(dpa_oh_dev,
13178 + "Can't allocate private data for TX queues for OH node %s referenced from node %s!\n",
13179 + oh_node->full_name, dpa_oh_node->full_name);
13180 + _errno = -ENOMEM;
13181 + goto return_kfree;
13182 + }
13183 +
13184 + /* Create TX queues */
13185 + for (i = 0; i < crt_fq_count; i++) {
13186 + ret = oh_fq_create(oh_config->egress_fqs + i,
13187 + crt_fqid_base + i, (uint16_t)channel_id, 3);
13188 + if (ret != 0) {
13189 + dev_err(dpa_oh_dev,
13190 + "Unable to create TX frame queue %d for OH node %s referenced from node %s!\n",
13191 + crt_fqid_base + i, oh_node->full_name,
13192 + dpa_oh_node->full_name);
13193 + _errno = -EINVAL;
13194 + goto return_kfree;
13195 + }
13196 + }
13197 +
13198 +config_port:
13199 + /* Get a handle to the fm_port so we can set
13200 + * its configuration params
13201 + */
13202 + oh_config->oh_port = fm_port_bind(oh_dev);
13203 + if (oh_config->oh_port == NULL) {
13204 + dev_err(dpa_oh_dev, "NULL drvdata from fm port dev %s!\n",
13205 + oh_node->full_name);
13206 + _errno = -EINVAL;
13207 + goto return_kfree;
13208 + }
13209 +
13210 + oh_set_buffer_layout(oh_config->oh_port, &buf_layout);
13211 +
13212 + /* read the pool handlers */
13213 + crt_ext_pools_count = of_count_phandle_with_args(dpa_oh_node,
13214 + "fsl,bman-buffer-pools", NULL);
13215 + if (crt_ext_pools_count <= 0) {
13216 + dev_info(dpa_oh_dev,
13217 + "OH port %s has no buffer pool. Fragmentation will not be enabled\n",
13218 + oh_node->full_name);
13219 + goto init_port;
13220 + }
13221 +
13222 + /* used for reading ext_pool_size*/
13223 + root_node = of_find_node_by_path("/");
13224 + if (root_node == NULL) {
13225 + dev_err(dpa_oh_dev, "of_find_node_by_path(/) failed\n");
13226 + _errno = -EINVAL;
13227 + goto return_kfree;
13228 + }
13229 +
13230 + n_size = of_n_size_cells(root_node);
13231 + of_node_put(root_node);
13232 +
13233 + dev_dbg(dpa_oh_dev, "OH port number of pools = %d\n",
13234 + crt_ext_pools_count);
13235 +
13236 + oh_port_tx_params.num_pools = (uint8_t)crt_ext_pools_count;
13237 +
13238 + for (i = 0; i < crt_ext_pools_count; i++) {
13239 + bpool_node = of_parse_phandle(dpa_oh_node,
13240 + "fsl,bman-buffer-pools", i);
13241 + if (bpool_node == NULL) {
13242 + dev_err(dpa_oh_dev, "Invalid Buffer pool node\n");
13243 + _errno = -EINVAL;
13244 + goto return_kfree;
13245 + }
13246 +
13247 + _errno = of_property_read_u32(bpool_node, "fsl,bpid", &bpid);
13248 + if (_errno) {
13249 + dev_err(dpa_oh_dev, "Invalid Buffer Pool ID\n");
13250 + _errno = -EINVAL;
13251 + goto return_kfree;
13252 + }
13253 +
13254 + oh_port_tx_params.pool_param[i].id = (uint8_t)bpid;
13255 + dev_dbg(dpa_oh_dev, "OH port bpool id = %u\n", bpid);
13256 +
13257 + bpool_cfg = of_get_property(bpool_node,
13258 + "fsl,bpool-ethernet-cfg", &lenp);
13259 + if (bpool_cfg == NULL) {
13260 + dev_err(dpa_oh_dev, "Invalid Buffer pool config params\n");
13261 + _errno = -EINVAL;
13262 + goto return_kfree;
13263 + }
13264 +
13265 + ext_pool_size = of_read_number(bpool_cfg + n_size, n_size);
13266 + oh_port_tx_params.pool_param[i].size = (uint16_t)ext_pool_size;
13267 + dev_dbg(dpa_oh_dev, "OH port bpool size = %u\n",
13268 + ext_pool_size);
13269 + of_node_put(bpool_node);
13270 +
13271 + }
13272 +
13273 + if (buf_layout.data_align != FRAG_DATA_ALIGN ||
13274 + buf_layout.manip_extra_space != FRAG_MANIP_SPACE)
13275 + goto init_port;
13276 +
13277 + frag_enabled = true;
13278 + dev_info(dpa_oh_dev, "IP Fragmentation enabled for OH port %d",
13279 + port_id);
13280 +
13281 +init_port:
13282 + of_node_put(oh_node);
13283 + /* Set Tx params */
13284 + dpaa_eth_init_port(tx, oh_config->oh_port, oh_port_tx_params,
13285 + oh_config->error_fqid, oh_config->default_fqid, (&buf_layout),
13286 + frag_enabled);
13287 + /* Set PCD params */
13288 + oh_port_pcd_params.cba = oh_alloc_pcd_fqids;
13289 + oh_port_pcd_params.cbf = oh_free_pcd_fqids;
13290 + oh_port_pcd_params.dev = dpa_oh_dev;
13291 + fm_port_pcd_bind(oh_config->oh_port, &oh_port_pcd_params);
13292 +
13293 + dev_set_drvdata(dpa_oh_dev, oh_config);
13294 +
13295 + /* Enable the OH port */
13296 + _errno = fm_port_enable(oh_config->oh_port);
13297 + if (_errno)
13298 + goto return_kfree;
13299 +
13300 + dev_info(dpa_oh_dev, "OH port %s enabled.\n", oh_node->full_name);
13301 +
13302 + /* print of all referenced & created queues */
13303 + dump_oh_config(dpa_oh_dev, oh_config);
13304 +
13305 + return 0;
13306 +
13307 +return_kfree:
13308 + if (bpool_node)
13309 + of_node_put(bpool_node);
13310 + if (oh_node)
13311 + of_node_put(oh_node);
13312 + if (oh_config && oh_config->egress_fqs)
13313 + devm_kfree(dpa_oh_dev, oh_config->egress_fqs);
13314 +
13315 + list_for_each_safe(fq_list, fq_list_tmp, &oh_config->fqs_ingress_list) {
13316 + fqd = list_entry(fq_list, struct fq_duple, fq_list);
13317 + list_del(fq_list);
13318 + devm_kfree(dpa_oh_dev, fqd->fqs);
13319 + devm_kfree(dpa_oh_dev, fqd);
13320 + }
13321 +
13322 + list_for_each_safe(fq_list, fq_list_tmp, &oh_config->fqs_egress_list) {
13323 + fqd = list_entry(fq_list, struct fq_duple, fq_list);
13324 + list_del(fq_list);
13325 + devm_kfree(dpa_oh_dev, fqd->fqs);
13326 + devm_kfree(dpa_oh_dev, fqd);
13327 + }
13328 +
13329 + devm_kfree(dpa_oh_dev, oh_config);
13330 + return _errno;
13331 +}
13332 +
13333 +static int __cold oh_port_remove(struct platform_device *_of_dev)
13334 +{
13335 + int _errno = 0, i;
13336 + struct dpa_oh_config_s *oh_config;
13337 +
13338 + pr_info("Removing OH port...\n");
13339 +
13340 + oh_config = dev_get_drvdata(&_of_dev->dev);
13341 + if (oh_config == NULL) {
13342 + pr_err(KBUILD_MODNAME
13343 + ": %s:%hu:%s(): No OH config in device private data!\n",
13344 + KBUILD_BASENAME".c", __LINE__, __func__);
13345 + _errno = -ENODEV;
13346 + goto return_error;
13347 + }
13348 +
13349 + if (oh_config->egress_fqs)
13350 + for (i = 0; i < oh_config->egress_cnt; i++)
13351 + oh_fq_destroy(oh_config->egress_fqs + i);
13352 +
13353 + if (oh_config->oh_port == NULL) {
13354 + pr_err(KBUILD_MODNAME
13355 + ": %s:%hu:%s(): No fm port in device private data!\n",
13356 + KBUILD_BASENAME".c", __LINE__, __func__);
13357 + _errno = -EINVAL;
13358 + goto free_egress_fqs;
13359 + }
13360 +
13361 + _errno = fm_port_disable(oh_config->oh_port);
13362 +
13363 +free_egress_fqs:
13364 + if (oh_config->egress_fqs)
13365 + devm_kfree(&_of_dev->dev, oh_config->egress_fqs);
13366 + devm_kfree(&_of_dev->dev, oh_config);
13367 + dev_set_drvdata(&_of_dev->dev, NULL);
13368 +
13369 +return_error:
13370 + return _errno;
13371 +}
13372 +
13373 +static struct platform_driver oh_port_driver = {
13374 + .driver = {
13375 + .name = KBUILD_MODNAME,
13376 + .of_match_table = oh_port_match_table,
13377 + .owner = THIS_MODULE,
13378 + .pm = OH_PM_OPS,
13379 + },
13380 + .probe = oh_port_probe,
13381 + .remove = oh_port_remove
13382 +};
13383 +
13384 +static int __init __cold oh_port_load(void)
13385 +{
13386 + int _errno;
13387 +
13388 + pr_info(OH_MOD_DESCRIPTION "\n");
13389 +
13390 + _errno = platform_driver_register(&oh_port_driver);
13391 + if (_errno < 0) {
13392 + pr_err(KBUILD_MODNAME
13393 + ": %s:%hu:%s(): platform_driver_register() = %d\n",
13394 + KBUILD_BASENAME".c", __LINE__, __func__, _errno);
13395 + }
13396 +
13397 + pr_debug(KBUILD_MODNAME ": %s:%s() ->\n",
13398 + KBUILD_BASENAME".c", __func__);
13399 + return _errno;
13400 +}
13401 +module_init(oh_port_load);
13402 +
13403 +static void __exit __cold oh_port_unload(void)
13404 +{
13405 + pr_debug(KBUILD_MODNAME ": -> %s:%s()\n",
13406 + KBUILD_BASENAME".c", __func__);
13407 +
13408 + platform_driver_unregister(&oh_port_driver);
13409 +
13410 + pr_debug(KBUILD_MODNAME ": %s:%s() ->\n",
13411 + KBUILD_BASENAME".c", __func__);
13412 +}
13413 +module_exit(oh_port_unload);
13414 --- /dev/null
13415 +++ b/drivers/net/ethernet/freescale/sdk_dpaa/offline_port.h
13416 @@ -0,0 +1,59 @@
13417 +/* Copyright 2011 Freescale Semiconductor Inc.
13418 + *
13419 + * Redistribution and use in source and binary forms, with or without
13420 + * modification, are permitted provided that the following conditions are met:
13421 + * * Redistributions of source code must retain the above copyright
13422 + * notice, this list of conditions and the following disclaimer.
13423 + * * Redistributions in binary form must reproduce the above copyright
13424 + * notice, this list of conditions and the following disclaimer in the
13425 + * documentation and/or other materials provided with the distribution.
13426 + * * Neither the name of Freescale Semiconductor nor the
13427 + * names of its contributors may be used to endorse or promote products
13428 + * derived from this software without specific prior written permission.
13429 + *
13430 + *
13431 + * ALTERNATIVELY, this software may be distributed under the terms of the
13432 + * GNU General Public License ("GPL") as published by the Free Software
13433 + * Foundation, either version 2 of that License or (at your option) any
13434 + * later version.
13435 + *
13436 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
13437 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
13438 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
13439 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
13440 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
13441 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
13442 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
13443 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
13444 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
13445 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
13446 + */
13447 +
13448 +#ifndef __OFFLINE_PORT_H
13449 +#define __OFFLINE_PORT_H
13450 +
13451 +struct fm_port;
13452 +struct qman_fq;
13453 +
13454 +/* fqs are defined in duples (base_fq, fq_count) */
13455 +struct fq_duple {
13456 + struct qman_fq *fqs;
13457 + int fqs_count;
13458 + uint16_t channel_id;
13459 + struct list_head fq_list;
13460 +};
13461 +
13462 +/* OH port configuration */
13463 +struct dpa_oh_config_s {
13464 + uint32_t error_fqid;
13465 + uint32_t default_fqid;
13466 + struct fm_port *oh_port;
13467 + uint32_t egress_cnt;
13468 + struct qman_fq *egress_fqs;
13469 + uint16_t channel;
13470 +
13471 + struct list_head fqs_ingress_list;
13472 + struct list_head fqs_egress_list;
13473 +};
13474 +
13475 +#endif /* __OFFLINE_PORT_H */
13476 --- /dev/null
13477 +++ b/drivers/net/ethernet/freescale/sdk_fman/Kconfig
13478 @@ -0,0 +1,153 @@
13479 +menu "Frame Manager support"
13480 +
13481 +menuconfig FSL_SDK_FMAN
13482 + bool "Freescale Frame Manager (datapath) support - SDK driver"
13483 + depends on (FSL_SOC || ARM64 || ARM) && FSL_SDK_BMAN && FSL_SDK_QMAN && !FSL_FMAN
13484 + default y
13485 + ---help---
13486 + If unsure, say Y.
13487 +
13488 +if FSL_SDK_FMAN
13489 +
13490 +config FSL_SDK_FMAN_TEST
13491 + bool "FMan test module"
13492 + default n
13493 + select FSL_DPAA_HOOKS
13494 + ---help---
13495 + This option compiles test code for FMan.
13496 +
13497 +menu "FMAN Processor support"
13498 +choice
13499 + depends on FSL_SDK_FMAN
13500 + prompt "Processor Type"
13501 +
13502 +config FMAN_ARM
13503 + bool "LS1043"
13504 + depends on ARM64 || ARM
13505 + ---help---
13506 + Choose "LS1043" for the ARM platforms:
13507 + LS1043
13508 +
13509 +config FMAN_P3040_P4080_P5020
13510 + bool "P3040 P4080 5020"
13511 +
13512 +config FMAN_P1023
13513 + bool "P1023"
13514 +
13515 +config FMAN_V3H
13516 + bool "FmanV3H"
13517 + ---help---
13518 + Choose "FmanV3H" for Fman rev3H:
13519 + B4860, T4240, T4160, etc
13520 +
13521 +config FMAN_V3L
13522 + bool "FmanV3L"
13523 + ---help---
13524 + Choose "FmanV3L" for Fman rev3L:
13525 + T1040, T1042, T1020, T1022, T1023, T1024, etc
13526 +
13527 +endchoice
13528 +endmenu
13529 +
13530 +config FMAN_MIB_CNT_OVF_IRQ_EN
13531 + bool "Enable the dTSEC MIB counters overflow interrupt"
13532 + default n
13533 + ---help---
13534 + Enable the dTSEC MIB counters overflow interrupt to get
13535 + accurate MIB counters values. Enabled it compensates
13536 + for the counters overflow but reduces performance and
13537 + triggers error messages in HV setups.
13538 +
13539 +config FSL_FM_MAX_FRAME_SIZE
13540 + int "Maximum L2 frame size"
13541 + depends on FSL_SDK_FMAN
13542 + range 64 9600
13543 + default "1522"
13544 + help
13545 + Configure this in relation to the maximum possible MTU of your
13546 + network configuration. In particular, one would need to
13547 + increase this value in order to use jumbo frames.
13548 + FSL_FM_MAX_FRAME_SIZE must accommodate the Ethernet FCS (4 bytes)
13549 + and one ETH+VLAN header (18 bytes), to a total of 22 bytes in
13550 + excess of the desired L3 MTU.
13551 +
13552 + Note that having too large a FSL_FM_MAX_FRAME_SIZE (much larger
13553 + than the actual MTU) may lead to buffer exhaustion, especially
13554 + in the case of badly fragmented datagrams on the Rx path.
13555 + Conversely, having a FSL_FM_MAX_FRAME_SIZE smaller than the actual
13556 + MTU will lead to frames being dropped.
13557 +
13558 + This can be overridden by specifying "fsl_fm_max_frm" in
13559 + the kernel bootargs:
13560 + * in Hypervisor-based scenarios, by adding a "chosen" node
13561 + with the "bootargs" property specifying
13562 + "fsl_fm_max_frm=<YourValue>";
13563 + * in non-Hypervisor-based scenarios, via u-boot's env, by
13564 + modifying the "bootargs" env variable.
13565 +
13566 +config FSL_FM_RX_EXTRA_HEADROOM
13567 + int "Add extra headroom at beginning of data buffers"
13568 + depends on FSL_SDK_FMAN
13569 + range 16 384
13570 + default "64"
13571 + help
13572 + Configure this to tell the Frame Manager to reserve some extra
13573 + space at the beginning of a data buffer on the receive path,
13574 + before Internal Context fields are copied. This is in addition
13575 + to the private data area already reserved for driver internal
13576 + use. The provided value must be a multiple of 16.
13577 +
13578 + This setting can be overridden by specifying
13579 + "fsl_fm_rx_extra_headroom" in the kernel bootargs:
13580 + * in Hypervisor-based scenarios, by adding a "chosen" node
13581 + with the "bootargs" property specifying
13582 + "fsl_fm_rx_extra_headroom=<YourValue>";
13583 + * in non-Hypervisor-based scenarios, via u-boot's env, by
13584 + modifying the "bootargs" env variable.
13585 +
13586 +config FMAN_PFC
13587 + bool "FMan PFC support (EXPERIMENTAL)"
13588 + depends on ( FMAN_V3H || FMAN_V3L || FMAN_ARM) && FSL_SDK_FMAN
13589 + default n
13590 + help
13591 + This option enables PFC support on FMan v3 ports.
13592 + Data Center Bridging defines Classes of Service that are
13593 + flow-controlled using PFC pause frames.
13594 +
13595 +if FMAN_PFC
13596 +config FMAN_PFC_COS_COUNT
13597 + int "Number of PFC Classes of Service"
13598 + depends on FMAN_PFC && FSL_SDK_FMAN
13599 + range 1 4
13600 + default "3"
13601 + help
13602 + The number of Classes of Service controlled by PFC.
13603 +
13604 +config FMAN_PFC_QUANTA_0
13605 + int "The pause quanta for PFC CoS 0"
13606 + depends on FMAN_PFC && FSL_SDK_FMAN
13607 + range 0 65535
13608 + default "65535"
13609 +
13610 +config FMAN_PFC_QUANTA_1
13611 + int "The pause quanta for PFC CoS 1"
13612 + depends on FMAN_PFC && FSL_SDK_FMAN
13613 + range 0 65535
13614 + default "65535"
13615 +
13616 +config FMAN_PFC_QUANTA_2
13617 + int "The pause quanta for PFC CoS 2"
13618 + depends on FMAN_PFC && FSL_SDK_FMAN
13619 + range 0 65535
13620 + default "65535"
13621 +
13622 +config FMAN_PFC_QUANTA_3
13623 + int "The pause quanta for PFC CoS 3"
13624 + depends on FMAN_PFC && FSL_SDK_FMAN
13625 + range 0 65535
13626 + default "65535"
13627 +endif
13628 +
13629 +endif # FSL_SDK_FMAN
13630 +
13631 +endmenu
13632 --- /dev/null
13633 +++ b/drivers/net/ethernet/freescale/sdk_fman/Makefile
13634 @@ -0,0 +1,11 @@
13635 +#
13636 +# Makefile for the Freescale Ethernet controllers
13637 +#
13638 +ccflags-y += -DVERSION=\"\"
13639 +#
13640 +#Include netcomm SW specific definitions
13641 +include $(srctree)/drivers/net/ethernet/freescale/sdk_fman/ncsw_config.mk
13642 +#
13643 +obj-y += etc/
13644 +obj-y += Peripherals/FM/
13645 +obj-y += src/
13646 --- /dev/null
13647 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/HC/Makefile
13648 @@ -0,0 +1,15 @@
13649 +#
13650 +# Makefile for the Freescale Ethernet controllers
13651 +#
13652 +ccflags-y += -DVERSION=\"\"
13653 +#
13654 +#Include netcomm SW specific definitions
13655 +include $(srctree)/drivers/net/ethernet/freescale/sdk_fman/ncsw_config.mk
13656 +
13657 +NCSW_FM_INC = $(srctree)/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/inc
13658 +
13659 +ccflags-y += -I$(NCSW_FM_INC)
13660 +
13661 +obj-y += fsl-ncsw-Hc.o
13662 +
13663 +fsl-ncsw-Hc-objs := hc.o
13664 --- /dev/null
13665 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/HC/hc.c
13666 @@ -0,0 +1,1232 @@
13667 +/*
13668 + * Copyright 2008-2012 Freescale Semiconductor Inc.
13669 + *
13670 + * Redistribution and use in source and binary forms, with or without
13671 + * modification, are permitted provided that the following conditions are met:
13672 + * * Redistributions of source code must retain the above copyright
13673 + * notice, this list of conditions and the following disclaimer.
13674 + * * Redistributions in binary form must reproduce the above copyright
13675 + * notice, this list of conditions and the following disclaimer in the
13676 + * documentation and/or other materials provided with the distribution.
13677 + * * Neither the name of Freescale Semiconductor nor the
13678 + * names of its contributors may be used to endorse or promote products
13679 + * derived from this software without specific prior written permission.
13680 + *
13681 + *
13682 + * ALTERNATIVELY, this software may be distributed under the terms of the
13683 + * GNU General Public License ("GPL") as published by the Free Software
13684 + * Foundation, either version 2 of that License or (at your option) any
13685 + * later version.
13686 + *
13687 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
13688 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
13689 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
13690 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
13691 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
13692 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
13693 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
13694 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
13695 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
13696 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
13697 + */
13698 +
13699 +
13700 +#include "std_ext.h"
13701 +#include "error_ext.h"
13702 +#include "sprint_ext.h"
13703 +#include "string_ext.h"
13704 +
13705 +#include "fm_common.h"
13706 +#include "fm_hc.h"
13707 +
13708 +
13709 +/**************************************************************************//**
13710 + @Description defaults
13711 +*//***************************************************************************/
13712 +#define DEFAULT_dataMemId 0
13713 +
13714 +#define HC_HCOR_OPCODE_PLCR_PRFL 0x0
13715 +#define HC_HCOR_OPCODE_KG_SCM 0x1
13716 +#define HC_HCOR_OPCODE_SYNC 0x2
13717 +#define HC_HCOR_OPCODE_CC 0x3
13718 +#define HC_HCOR_OPCODE_CC_AGE_MASK 0x4
13719 +#define HC_HCOR_OPCODE_CC_CAPWAP_REASSM_TIMEOUT 0x5
13720 +#define HC_HCOR_OPCODE_CC_REASSM_TIMEOUT 0x10
13721 +#define HC_HCOR_OPCODE_CC_IP_FRAG_INITIALIZATION 0x11
13722 +#define HC_HCOR_OPCODE_CC_UPDATE_WITH_AGING 0x13
13723 +#define HC_HCOR_ACTION_REG_REASSM_TIMEOUT_ACTIVE_SHIFT 24
13724 +#define HC_HCOR_EXTRA_REG_REASSM_TIMEOUT_TSBS_SHIFT 24
13725 +#define HC_HCOR_EXTRA_REG_CC_AGING_ADD 0x80000000
13726 +#define HC_HCOR_EXTRA_REG_CC_AGING_REMOVE 0x40000000
13727 +#define HC_HCOR_EXTRA_REG_CC_AGING_CHANGE_MASK 0xC0000000
13728 +#define HC_HCOR_EXTRA_REG_CC_REMOVE_INDX_SHIFT 24
13729 +#define HC_HCOR_EXTRA_REG_CC_REMOVE_INDX_MASK 0x1F000000
13730 +#define HC_HCOR_ACTION_REG_REASSM_TIMEOUT_RES_SHIFT 16
13731 +#define HC_HCOR_ACTION_REG_REASSM_TIMEOUT_RES_MASK 0xF
13732 +#define HC_HCOR_ACTION_REG_IP_FRAG_SCRATCH_POOL_CMD_SHIFT 24
13733 +#define HC_HCOR_ACTION_REG_IP_FRAG_SCRATCH_POOL_BPID 16
13734 +
13735 +#define HC_HCOR_GBL 0x20000000
13736 +
13737 +#define HC_HCOR_KG_SCHEME_COUNTER 0x00000400
13738 +
13739 +#if (DPAA_VERSION == 10)
13740 +#define HC_HCOR_KG_SCHEME_REGS_MASK 0xFFFFF800
13741 +#else
13742 +#define HC_HCOR_KG_SCHEME_REGS_MASK 0xFFFFFE00
13743 +#endif /* (DPAA_VERSION == 10) */
13744 +
13745 +#define SIZE_OF_HC_FRAME_PORT_REGS (sizeof(t_HcFrame)-sizeof(struct fman_kg_scheme_regs)+sizeof(t_FmPcdKgPortRegs))
13746 +#define SIZE_OF_HC_FRAME_SCHEME_REGS sizeof(t_HcFrame)
13747 +#define SIZE_OF_HC_FRAME_PROFILES_REGS (sizeof(t_HcFrame)-sizeof(struct fman_kg_scheme_regs)+sizeof(t_FmPcdPlcrProfileRegs))
13748 +#define SIZE_OF_HC_FRAME_PROFILE_CNT (sizeof(t_HcFrame)-sizeof(t_FmPcdPlcrProfileRegs)+sizeof(uint32_t))
13749 +#define SIZE_OF_HC_FRAME_READ_OR_CC_DYNAMIC 16
13750 +
13751 +#define HC_CMD_POOL_SIZE (INTG_MAX_NUM_OF_CORES)
13752 +
13753 +#define BUILD_FD(len) \
13754 +do { \
13755 + memset(&fmFd, 0, sizeof(t_DpaaFD)); \
13756 + DPAA_FD_SET_ADDR(&fmFd, p_HcFrame); \
13757 + DPAA_FD_SET_OFFSET(&fmFd, 0); \
13758 + DPAA_FD_SET_LENGTH(&fmFd, len); \
13759 +} while (0)
13760 +
13761 +
13762 +#if defined(__MWERKS__) && !defined(__GNUC__)
13763 +#pragma pack(push,1)
13764 +#endif /* defined(__MWERKS__) && ... */
13765 +
13766 +typedef struct t_FmPcdKgPortRegs {
13767 + volatile uint32_t spReg;
13768 + volatile uint32_t cppReg;
13769 +} t_FmPcdKgPortRegs;
13770 +
13771 +typedef struct t_HcFrame {
13772 + volatile uint32_t opcode;
13773 + volatile uint32_t actionReg;
13774 + volatile uint32_t extraReg;
13775 + volatile uint32_t commandSequence;
13776 + union {
13777 + struct fman_kg_scheme_regs schemeRegs;
13778 + struct fman_kg_scheme_regs schemeRegsWithoutCounter;
13779 + t_FmPcdPlcrProfileRegs profileRegs;
13780 + volatile uint32_t singleRegForWrite; /* for writing SP, CPP, profile counter */
13781 + t_FmPcdKgPortRegs portRegsForRead;
13782 + volatile uint32_t clsPlanEntries[CLS_PLAN_NUM_PER_GRP];
13783 + t_FmPcdCcCapwapReassmTimeoutParams ccCapwapReassmTimeout;
13784 + t_FmPcdCcReassmTimeoutParams ccReassmTimeout;
13785 + } hcSpecificData;
13786 +} t_HcFrame;
13787 +
13788 +#if defined(__MWERKS__) && !defined(__GNUC__)
13789 +#pragma pack(pop)
13790 +#endif /* defined(__MWERKS__) && ... */
13791 +
13792 +
13793 +typedef struct t_FmHc {
13794 + t_Handle h_FmPcd;
13795 + t_Handle h_HcPortDev;
13796 + t_FmPcdQmEnqueueCallback *f_QmEnqueue; /**< A callback for enqueuing frames to the QM */
13797 + t_Handle h_QmArg; /**< A handle to the QM module */
13798 + uint8_t dataMemId; /**< Memory partition ID for data buffers */
13799 +
13800 + uint32_t seqNum[HC_CMD_POOL_SIZE]; /* FIFO of seqNum to use when
13801 + taking buffer */
13802 + uint32_t nextSeqNumLocation; /* seqNum location in seqNum[] for next buffer */
13803 + volatile bool enqueued[HC_CMD_POOL_SIZE]; /* HC is active - frame is enqueued
13804 + and not confirmed yet */
13805 + t_HcFrame *p_Frm[HC_CMD_POOL_SIZE];
13806 +} t_FmHc;
13807 +
13808 +
13809 +static t_Error FillBufPool(t_FmHc *p_FmHc)
13810 +{
13811 + uint32_t i;
13812 +
13813 + ASSERT_COND(p_FmHc);
13814 +
13815 + for (i = 0; i < HC_CMD_POOL_SIZE; i++)
13816 + {
13817 +#ifdef FM_LOCKUP_ALIGNMENT_ERRATA_FMAN_SW004
13818 + p_FmHc->p_Frm[i] = (t_HcFrame *)XX_MallocSmart((sizeof(t_HcFrame) + (16 - (sizeof(t_FmHc) % 16))),
13819 + p_FmHc->dataMemId,
13820 + 16);
13821 +#else
13822 + p_FmHc->p_Frm[i] = (t_HcFrame *)XX_MallocSmart(sizeof(t_HcFrame),
13823 + p_FmHc->dataMemId,
13824 + 16);
13825 +#endif /* FM_LOCKUP_ALIGNMENT_ERRATA_FMAN_SW004 */
13826 + if (!p_FmHc->p_Frm[i])
13827 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("FM HC frames!"));
13828 + }
13829 +
13830 + /* Initialize FIFO of seqNum to use during GetBuf */
13831 + for (i = 0; i < HC_CMD_POOL_SIZE; i++)
13832 + {
13833 + p_FmHc->seqNum[i] = i;
13834 + }
13835 + p_FmHc->nextSeqNumLocation = 0;
13836 +
13837 + return E_OK;
13838 +}
13839 +
13840 +static __inline__ t_HcFrame * GetBuf(t_FmHc *p_FmHc, uint32_t *p_SeqNum)
13841 +{
13842 + uint32_t intFlags;
13843 +
13844 + ASSERT_COND(p_FmHc);
13845 +
13846 + intFlags = FmPcdLock(p_FmHc->h_FmPcd);
13847 +
13848 + if (p_FmHc->nextSeqNumLocation == HC_CMD_POOL_SIZE)
13849 + {
13850 + /* No more buffers */
13851 + FmPcdUnlock(p_FmHc->h_FmPcd, intFlags);
13852 + return NULL;
13853 + }
13854 +
13855 + *p_SeqNum = p_FmHc->seqNum[p_FmHc->nextSeqNumLocation];
13856 + p_FmHc->nextSeqNumLocation++;
13857 +
13858 + FmPcdUnlock(p_FmHc->h_FmPcd, intFlags);
13859 + return p_FmHc->p_Frm[*p_SeqNum];
13860 +}
13861 +
13862 +static __inline__ void PutBuf(t_FmHc *p_FmHc, t_HcFrame *p_Buf, uint32_t seqNum)
13863 +{
13864 + uint32_t intFlags;
13865 +
13866 + UNUSED(p_Buf);
13867 +
13868 + intFlags = FmPcdLock(p_FmHc->h_FmPcd);
13869 + ASSERT_COND(p_FmHc->nextSeqNumLocation);
13870 + p_FmHc->nextSeqNumLocation--;
13871 + p_FmHc->seqNum[p_FmHc->nextSeqNumLocation] = seqNum;
13872 + FmPcdUnlock(p_FmHc->h_FmPcd, intFlags);
13873 +}
13874 +
13875 +static __inline__ t_Error EnQFrm(t_FmHc *p_FmHc, t_DpaaFD *p_FmFd, uint32_t seqNum)
13876 +{
13877 + t_Error err = E_OK;
13878 + uint32_t intFlags;
13879 + uint32_t timeout=100;
13880 +
13881 + intFlags = FmPcdLock(p_FmHc->h_FmPcd);
13882 + ASSERT_COND(!p_FmHc->enqueued[seqNum]);
13883 + p_FmHc->enqueued[seqNum] = TRUE;
13884 + FmPcdUnlock(p_FmHc->h_FmPcd, intFlags);
13885 + DBG(TRACE, ("Send Hc, SeqNum %d, buff@0x%x, fd offset 0x%x",
13886 + seqNum,
13887 + DPAA_FD_GET_ADDR(p_FmFd),
13888 + DPAA_FD_GET_OFFSET(p_FmFd)));
13889 + err = p_FmHc->f_QmEnqueue(p_FmHc->h_QmArg, (void *)p_FmFd);
13890 + if (err)
13891 + RETURN_ERROR(MINOR, err, ("HC enqueue failed"));
13892 +
13893 + while (p_FmHc->enqueued[seqNum] && --timeout)
13894 + XX_UDelay(100);
13895 +
13896 + if (!timeout)
13897 + RETURN_ERROR(MINOR, E_TIMEOUT, ("HC Callback, timeout exceeded"));
13898 +
13899 + return err;
13900 +}
13901 +
13902 +
13903 +t_Handle FmHcConfigAndInit(t_FmHcParams *p_FmHcParams)
13904 +{
13905 + t_FmHc *p_FmHc;
13906 + t_FmPortParams fmPortParam;
13907 + t_Error err;
13908 +
13909 + p_FmHc = (t_FmHc *)XX_Malloc(sizeof(t_FmHc));
13910 + if (!p_FmHc)
13911 + {
13912 + REPORT_ERROR(MINOR, E_NO_MEMORY, ("HC obj"));
13913 + return NULL;
13914 + }
13915 + memset(p_FmHc,0,sizeof(t_FmHc));
13916 +
13917 + p_FmHc->h_FmPcd = p_FmHcParams->h_FmPcd;
13918 + p_FmHc->f_QmEnqueue = p_FmHcParams->params.f_QmEnqueue;
13919 + p_FmHc->h_QmArg = p_FmHcParams->params.h_QmArg;
13920 + p_FmHc->dataMemId = DEFAULT_dataMemId;
13921 +
13922 + err = FillBufPool(p_FmHc);
13923 + if (err != E_OK)
13924 + {
13925 + REPORT_ERROR(MAJOR, err, NO_MSG);
13926 + FmHcFree(p_FmHc);
13927 + return NULL;
13928 + }
13929 +
13930 + if (!FmIsMaster(p_FmHcParams->h_Fm))
13931 + return (t_Handle)p_FmHc;
13932 +
13933 + memset(&fmPortParam, 0, sizeof(fmPortParam));
13934 + fmPortParam.baseAddr = p_FmHcParams->params.portBaseAddr;
13935 + fmPortParam.portType = e_FM_PORT_TYPE_OH_HOST_COMMAND;
13936 + fmPortParam.portId = p_FmHcParams->params.portId;
13937 + fmPortParam.liodnBase = p_FmHcParams->params.liodnBase;
13938 + fmPortParam.h_Fm = p_FmHcParams->h_Fm;
13939 +
13940 + fmPortParam.specificParams.nonRxParams.errFqid = p_FmHcParams->params.errFqid;
13941 + fmPortParam.specificParams.nonRxParams.dfltFqid = p_FmHcParams->params.confFqid;
13942 + fmPortParam.specificParams.nonRxParams.qmChannel = p_FmHcParams->params.qmChannel;
13943 +
13944 + p_FmHc->h_HcPortDev = FM_PORT_Config(&fmPortParam);
13945 + if (!p_FmHc->h_HcPortDev)
13946 + {
13947 + REPORT_ERROR(MAJOR, E_INVALID_HANDLE, ("FM HC port!"));
13948 + XX_Free(p_FmHc);
13949 + return NULL;
13950 + }
13951 +
13952 + err = FM_PORT_ConfigMaxFrameLength(p_FmHc->h_HcPortDev,
13953 + (uint16_t)sizeof(t_HcFrame));
13954 +
13955 + if (err != E_OK)
13956 + {
13957 + REPORT_ERROR(MAJOR, err, ("FM HC port init!"));
13958 + FmHcFree(p_FmHc);
13959 + return NULL;
13960 + }
13961 +
13962 + /* final init */
13963 + err = FM_PORT_Init(p_FmHc->h_HcPortDev);
13964 + if (err != E_OK)
13965 + {
13966 + REPORT_ERROR(MAJOR, err, ("FM HC port init!"));
13967 + FmHcFree(p_FmHc);
13968 + return NULL;
13969 + }
13970 +
13971 + err = FM_PORT_Enable(p_FmHc->h_HcPortDev);
13972 + if (err != E_OK)
13973 + {
13974 + REPORT_ERROR(MAJOR, err, ("FM HC port enable!"));
13975 + FmHcFree(p_FmHc);
13976 + return NULL;
13977 + }
13978 +
13979 + return (t_Handle)p_FmHc;
13980 +}
13981 +
13982 +void FmHcFree(t_Handle h_FmHc)
13983 +{
13984 + t_FmHc *p_FmHc = (t_FmHc*)h_FmHc;
13985 + int i;
13986 +
13987 + if (!p_FmHc)
13988 + return;
13989 +
13990 + for (i=0; i<HC_CMD_POOL_SIZE; i++)
13991 + if (p_FmHc->p_Frm[i])
13992 + XX_FreeSmart(p_FmHc->p_Frm[i]);
13993 + else
13994 + break;
13995 +
13996 + if (p_FmHc->h_HcPortDev)
13997 + FM_PORT_Free(p_FmHc->h_HcPortDev);
13998 +
13999 + XX_Free(p_FmHc);
14000 +}
14001 +
14002 +/*****************************************************************************/
14003 +t_Error FmHcSetFramesDataMemory(t_Handle h_FmHc,
14004 + uint8_t memId)
14005 +{
14006 + t_FmHc *p_FmHc = (t_FmHc*)h_FmHc;
14007 + int i;
14008 +
14009 + SANITY_CHECK_RETURN_ERROR(p_FmHc, E_INVALID_HANDLE);
14010 +
14011 + p_FmHc->dataMemId = memId;
14012 +
14013 + for (i=0; i<HC_CMD_POOL_SIZE; i++)
14014 + if (p_FmHc->p_Frm[i])
14015 + XX_FreeSmart(p_FmHc->p_Frm[i]);
14016 +
14017 + return FillBufPool(p_FmHc);
14018 +}
14019 +
14020 +void FmHcTxConf(t_Handle h_FmHc, t_DpaaFD *p_Fd)
14021 +{
14022 + t_FmHc *p_FmHc = (t_FmHc*)h_FmHc;
14023 + t_HcFrame *p_HcFrame;
14024 + uint32_t intFlags;
14025 +
14026 + ASSERT_COND(p_FmHc);
14027 +
14028 + intFlags = FmPcdLock(p_FmHc->h_FmPcd);
14029 + p_HcFrame = (t_HcFrame *)PTR_MOVE(DPAA_FD_GET_ADDR(p_Fd), DPAA_FD_GET_OFFSET(p_Fd));
14030 +
14031 + DBG(TRACE, ("Hc Conf, SeqNum %d, FD@0x%x, fd offset 0x%x",
14032 + p_HcFrame->commandSequence, DPAA_FD_GET_ADDR(p_Fd), DPAA_FD_GET_OFFSET(p_Fd)));
14033 +
14034 + if (!(p_FmHc->enqueued[p_HcFrame->commandSequence]))
14035 + REPORT_ERROR(MINOR, E_INVALID_FRAME, ("Not an Host-Command frame received!"));
14036 + else
14037 + p_FmHc->enqueued[p_HcFrame->commandSequence] = FALSE;
14038 + FmPcdUnlock(p_FmHc->h_FmPcd, intFlags);
14039 +}
14040 +
14041 +t_Error FmHcPcdKgSetScheme(t_Handle h_FmHc,
14042 + t_Handle h_Scheme,
14043 + struct fman_kg_scheme_regs *p_SchemeRegs,
14044 + bool updateCounter)
14045 +{
14046 + t_FmHc *p_FmHc = (t_FmHc*)h_FmHc;
14047 + t_Error err = E_OK;
14048 + t_HcFrame *p_HcFrame;
14049 + t_DpaaFD fmFd;
14050 + uint8_t physicalSchemeId;
14051 + uint32_t seqNum;
14052 +
14053 + p_HcFrame = GetBuf(p_FmHc, &seqNum);
14054 + if (!p_HcFrame)
14055 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("HC Frame object"));
14056 +
14057 + physicalSchemeId = FmPcdKgGetSchemeId(h_Scheme);
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, updateCounter);
14062 + p_HcFrame->extraReg = HC_HCOR_KG_SCHEME_REGS_MASK;
14063 + memcpy(&p_HcFrame->hcSpecificData.schemeRegs, p_SchemeRegs, sizeof(struct fman_kg_scheme_regs));
14064 + if (!updateCounter)
14065 + {
14066 + p_HcFrame->hcSpecificData.schemeRegs.kgse_dv0 = p_SchemeRegs->kgse_dv0;
14067 + p_HcFrame->hcSpecificData.schemeRegs.kgse_dv1 = p_SchemeRegs->kgse_dv1;
14068 + p_HcFrame->hcSpecificData.schemeRegs.kgse_ccbs = p_SchemeRegs->kgse_ccbs;
14069 + p_HcFrame->hcSpecificData.schemeRegs.kgse_mv = p_SchemeRegs->kgse_mv;
14070 + }
14071 + p_HcFrame->commandSequence = seqNum;
14072 +
14073 + BUILD_FD(sizeof(t_HcFrame));
14074 +
14075 + err = EnQFrm(p_FmHc, &fmFd, seqNum);
14076 +
14077 + PutBuf(p_FmHc, p_HcFrame, seqNum);
14078 +
14079 + if (err != E_OK)
14080 + RETURN_ERROR(MINOR, err, NO_MSG);
14081 +
14082 + return E_OK;
14083 +}
14084 +
14085 +t_Error FmHcPcdKgDeleteScheme(t_Handle h_FmHc, t_Handle h_Scheme)
14086 +{
14087 + t_FmHc *p_FmHc = (t_FmHc*)h_FmHc;
14088 + t_Error err = E_OK;
14089 + t_HcFrame *p_HcFrame;
14090 + t_DpaaFD fmFd;
14091 + uint8_t physicalSchemeId = FmPcdKgGetSchemeId(h_Scheme);
14092 + uint32_t seqNum;
14093 +
14094 + p_HcFrame = GetBuf(p_FmHc, &seqNum);
14095 + if (!p_HcFrame)
14096 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("HC Frame object"));
14097 +
14098 + memset(p_HcFrame, 0, sizeof(t_HcFrame));
14099 + p_HcFrame->opcode = (uint32_t)(HC_HCOR_GBL | HC_HCOR_OPCODE_KG_SCM);
14100 + p_HcFrame->actionReg = FmPcdKgBuildWriteSchemeActionReg(physicalSchemeId, TRUE);
14101 + p_HcFrame->extraReg = HC_HCOR_KG_SCHEME_REGS_MASK;
14102 + memset(&p_HcFrame->hcSpecificData.schemeRegs, 0, sizeof(struct fman_kg_scheme_regs));
14103 + p_HcFrame->commandSequence = seqNum;
14104 +
14105 + BUILD_FD(sizeof(t_HcFrame));
14106 +
14107 + err = EnQFrm(p_FmHc, &fmFd, seqNum);
14108 +
14109 + PutBuf(p_FmHc, p_HcFrame, seqNum);
14110 +
14111 + if (err != E_OK)
14112 + RETURN_ERROR(MINOR, err, NO_MSG);
14113 +
14114 + return E_OK;
14115 +}
14116 +
14117 +t_Error FmHcPcdKgCcGetSetParams(t_Handle h_FmHc, t_Handle h_Scheme, uint32_t requiredAction, uint32_t value)
14118 +{
14119 + t_FmHc *p_FmHc = (t_FmHc*)h_FmHc;
14120 + t_Error err = E_OK;
14121 + t_HcFrame *p_HcFrame;
14122 + t_DpaaFD fmFd;
14123 + uint8_t relativeSchemeId;
14124 + uint8_t physicalSchemeId = FmPcdKgGetSchemeId(h_Scheme);
14125 + uint32_t tmpReg32 = 0;
14126 + uint32_t seqNum;
14127 +
14128 + /* Scheme is locked by calling routine */
14129 + /* WARNING - this lock will not be efficient if other HC routine will attempt to change
14130 + * "kgse_mode" or "kgse_om" without locking scheme !
14131 + */
14132 +
14133 + relativeSchemeId = FmPcdKgGetRelativeSchemeId(p_FmHc->h_FmPcd, physicalSchemeId);
14134 + if ( relativeSchemeId == FM_PCD_KG_NUM_OF_SCHEMES)
14135 + RETURN_ERROR(MAJOR, E_NOT_IN_RANGE, NO_MSG);
14136 +
14137 + if (!FmPcdKgGetRequiredActionFlag(p_FmHc->h_FmPcd, relativeSchemeId) ||
14138 + !(FmPcdKgGetRequiredAction(p_FmHc->h_FmPcd, relativeSchemeId) & requiredAction))
14139 + {
14140 + if ((requiredAction & UPDATE_NIA_ENQ_WITHOUT_DMA) &&
14141 + (FmPcdKgGetNextEngine(p_FmHc->h_FmPcd, relativeSchemeId) == e_FM_PCD_PLCR))
14142 + {
14143 + if ((FmPcdKgIsDirectPlcr(p_FmHc->h_FmPcd, relativeSchemeId) == FALSE) ||
14144 + (FmPcdKgIsDistrOnPlcrProfile(p_FmHc->h_FmPcd, relativeSchemeId) == TRUE))
14145 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("In this situation PP can not be with distribution and has to be shared"));
14146 + err = FmPcdPlcrCcGetSetParams(p_FmHc->h_FmPcd, FmPcdKgGetRelativeProfileId(p_FmHc->h_FmPcd, relativeSchemeId), requiredAction);
14147 + if (err)
14148 + RETURN_ERROR(MAJOR, err, NO_MSG);
14149 + }
14150 + else /* From here we deal with KG-Schemes only */
14151 + {
14152 + /* Pre change general code */
14153 + p_HcFrame = GetBuf(p_FmHc, &seqNum);
14154 + if (!p_HcFrame)
14155 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("HC Frame object"));
14156 + memset(p_HcFrame, 0, sizeof(t_HcFrame));
14157 + p_HcFrame->opcode = (uint32_t)(HC_HCOR_GBL | HC_HCOR_OPCODE_KG_SCM);
14158 + p_HcFrame->actionReg = FmPcdKgBuildReadSchemeActionReg(physicalSchemeId);
14159 + p_HcFrame->extraReg = HC_HCOR_KG_SCHEME_REGS_MASK;
14160 + p_HcFrame->commandSequence = seqNum;
14161 + BUILD_FD(SIZE_OF_HC_FRAME_READ_OR_CC_DYNAMIC);
14162 + if ((err = EnQFrm(p_FmHc, &fmFd, seqNum)) != E_OK)
14163 + {
14164 + PutBuf(p_FmHc, p_HcFrame, seqNum);
14165 + RETURN_ERROR(MINOR, err, NO_MSG);
14166 + }
14167 +
14168 + /* specific change */
14169 + if ((requiredAction & UPDATE_NIA_ENQ_WITHOUT_DMA) &&
14170 + ((FmPcdKgGetNextEngine(p_FmHc->h_FmPcd, relativeSchemeId) == e_FM_PCD_DONE) &&
14171 + (FmPcdKgGetDoneAction(p_FmHc->h_FmPcd, relativeSchemeId) == e_FM_PCD_ENQ_FRAME)))
14172 + {
14173 + tmpReg32 = p_HcFrame->hcSpecificData.schemeRegs.kgse_mode;
14174 + ASSERT_COND(tmpReg32 & (NIA_ENG_BMI | NIA_BMI_AC_ENQ_FRAME));
14175 + p_HcFrame->hcSpecificData.schemeRegs.kgse_mode = tmpReg32 | NIA_BMI_AC_ENQ_FRAME_WITHOUT_DMA;
14176 + }
14177 +
14178 + if ((requiredAction & UPDATE_KG_NIA_CC_WA) &&
14179 + (FmPcdKgGetNextEngine(p_FmHc->h_FmPcd, relativeSchemeId) == e_FM_PCD_CC))
14180 + {
14181 + tmpReg32 = p_HcFrame->hcSpecificData.schemeRegs.kgse_mode;
14182 + ASSERT_COND(tmpReg32 & (NIA_ENG_FM_CTL | NIA_FM_CTL_AC_CC));
14183 + tmpReg32 &= ~NIA_FM_CTL_AC_CC;
14184 + p_HcFrame->hcSpecificData.schemeRegs.kgse_mode = tmpReg32 | NIA_FM_CTL_AC_PRE_CC;
14185 + }
14186 +
14187 + if (requiredAction & UPDATE_KG_OPT_MODE)
14188 + p_HcFrame->hcSpecificData.schemeRegs.kgse_om = value;
14189 +
14190 + if (requiredAction & UPDATE_KG_NIA)
14191 + {
14192 + tmpReg32 = p_HcFrame->hcSpecificData.schemeRegs.kgse_mode;
14193 + tmpReg32 &= ~(NIA_ENG_MASK | NIA_AC_MASK);
14194 + tmpReg32 |= value;
14195 + p_HcFrame->hcSpecificData.schemeRegs.kgse_mode = tmpReg32;
14196 + }
14197 +
14198 + /* Post change general code */
14199 + p_HcFrame->opcode = (uint32_t)(HC_HCOR_GBL | HC_HCOR_OPCODE_KG_SCM);
14200 + p_HcFrame->actionReg = FmPcdKgBuildWriteSchemeActionReg(physicalSchemeId, FALSE);
14201 + p_HcFrame->extraReg = HC_HCOR_KG_SCHEME_REGS_MASK;
14202 +
14203 + BUILD_FD(sizeof(t_HcFrame));
14204 + err = EnQFrm(p_FmHc, &fmFd, seqNum);
14205 +
14206 + PutBuf(p_FmHc, p_HcFrame, seqNum);
14207 +
14208 + if (err != E_OK)
14209 + RETURN_ERROR(MINOR, err, NO_MSG);
14210 + }
14211 + }
14212 +
14213 + return E_OK;
14214 +}
14215 +
14216 +uint32_t FmHcPcdKgGetSchemeCounter(t_Handle h_FmHc, t_Handle h_Scheme)
14217 +{
14218 + t_FmHc *p_FmHc = (t_FmHc*)h_FmHc;
14219 + t_Error err;
14220 + t_HcFrame *p_HcFrame;
14221 + t_DpaaFD fmFd;
14222 + uint32_t retVal;
14223 + uint8_t relativeSchemeId;
14224 + uint8_t physicalSchemeId = FmPcdKgGetSchemeId(h_Scheme);
14225 + uint32_t seqNum;
14226 +
14227 + relativeSchemeId = FmPcdKgGetRelativeSchemeId(p_FmHc->h_FmPcd, physicalSchemeId);
14228 + if ( relativeSchemeId == FM_PCD_KG_NUM_OF_SCHEMES)
14229 + {
14230 + REPORT_ERROR(MAJOR, E_NOT_IN_RANGE, NO_MSG);
14231 + return 0;
14232 + }
14233 +
14234 + /* first read scheme and check that it is valid */
14235 + p_HcFrame = GetBuf(p_FmHc, &seqNum);
14236 + if (!p_HcFrame)
14237 + {
14238 + REPORT_ERROR(MINOR, E_NO_MEMORY, ("HC Frame object"));
14239 + return 0;
14240 + }
14241 + memset(p_HcFrame, 0, sizeof(t_HcFrame));
14242 + p_HcFrame->opcode = (uint32_t)(HC_HCOR_GBL | HC_HCOR_OPCODE_KG_SCM);
14243 + p_HcFrame->actionReg = FmPcdKgBuildReadSchemeActionReg(physicalSchemeId);
14244 + p_HcFrame->extraReg = HC_HCOR_KG_SCHEME_REGS_MASK;
14245 + p_HcFrame->commandSequence = seqNum;
14246 +
14247 + BUILD_FD(SIZE_OF_HC_FRAME_READ_OR_CC_DYNAMIC);
14248 +
14249 + err = EnQFrm(p_FmHc, &fmFd, seqNum);
14250 + if (err != E_OK)
14251 + {
14252 + PutBuf(p_FmHc, p_HcFrame, seqNum);
14253 + REPORT_ERROR(MINOR, err, NO_MSG);
14254 + return 0;
14255 + }
14256 +
14257 + if (!FmPcdKgHwSchemeIsValid(p_HcFrame->hcSpecificData.schemeRegs.kgse_mode))
14258 + {
14259 + PutBuf(p_FmHc, p_HcFrame, seqNum);
14260 + REPORT_ERROR(MAJOR, E_ALREADY_EXISTS, ("Scheme is invalid"));
14261 + return 0;
14262 + }
14263 +
14264 + retVal = p_HcFrame->hcSpecificData.schemeRegs.kgse_spc;
14265 + PutBuf(p_FmHc, p_HcFrame, seqNum);
14266 +
14267 + return retVal;
14268 +}
14269 +
14270 +t_Error FmHcPcdKgSetSchemeCounter(t_Handle h_FmHc, t_Handle h_Scheme, uint32_t value)
14271 +{
14272 + t_FmHc *p_FmHc = (t_FmHc*)h_FmHc;
14273 + t_Error err = E_OK;
14274 + t_HcFrame *p_HcFrame;
14275 + t_DpaaFD fmFd;
14276 + uint8_t relativeSchemeId, physicalSchemeId;
14277 + uint32_t seqNum;
14278 +
14279 + physicalSchemeId = FmPcdKgGetSchemeId(h_Scheme);
14280 + relativeSchemeId = FmPcdKgGetRelativeSchemeId(p_FmHc->h_FmPcd, physicalSchemeId);
14281 + if ( relativeSchemeId == FM_PCD_KG_NUM_OF_SCHEMES)
14282 + RETURN_ERROR(MAJOR, E_NOT_IN_RANGE, NO_MSG);
14283 +
14284 + /* first read scheme and check that it is valid */
14285 + p_HcFrame = GetBuf(p_FmHc, &seqNum);
14286 + if (!p_HcFrame)
14287 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("HC Frame object"));
14288 + memset(p_HcFrame, 0, sizeof(t_HcFrame));
14289 + p_HcFrame->opcode = (uint32_t)(HC_HCOR_GBL | HC_HCOR_OPCODE_KG_SCM);
14290 + p_HcFrame->actionReg = FmPcdKgBuildWriteSchemeActionReg(physicalSchemeId, TRUE);
14291 + p_HcFrame->extraReg = HC_HCOR_KG_SCHEME_COUNTER;
14292 + /* write counter */
14293 + p_HcFrame->hcSpecificData.singleRegForWrite = value;
14294 + p_HcFrame->commandSequence = seqNum;
14295 +
14296 + BUILD_FD(sizeof(t_HcFrame));
14297 +
14298 + err = EnQFrm(p_FmHc, &fmFd, seqNum);
14299 +
14300 + PutBuf(p_FmHc, p_HcFrame, seqNum);
14301 + return err;
14302 +}
14303 +
14304 +t_Error FmHcPcdKgSetClsPlan(t_Handle h_FmHc, t_FmPcdKgInterModuleClsPlanSet *p_Set)
14305 +{
14306 + t_FmHc *p_FmHc = (t_FmHc*)h_FmHc;
14307 + t_HcFrame *p_HcFrame;
14308 + t_DpaaFD fmFd;
14309 + uint8_t i, idx;
14310 + uint32_t seqNum;
14311 + t_Error err = E_OK;
14312 +
14313 + ASSERT_COND(p_FmHc);
14314 +
14315 + p_HcFrame = GetBuf(p_FmHc, &seqNum);
14316 + if (!p_HcFrame)
14317 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("HC Frame object"));
14318 +
14319 + for (i = p_Set->baseEntry; i < (p_Set->baseEntry+p_Set->numOfClsPlanEntries); i+=8)
14320 + {
14321 + memset(p_HcFrame, 0, sizeof(t_HcFrame));
14322 + p_HcFrame->opcode = (uint32_t)(HC_HCOR_GBL | HC_HCOR_OPCODE_KG_SCM);
14323 + p_HcFrame->actionReg = FmPcdKgBuildWriteClsPlanBlockActionReg((uint8_t)(i / CLS_PLAN_NUM_PER_GRP));
14324 + p_HcFrame->extraReg = HC_HCOR_KG_SCHEME_REGS_MASK;
14325 +
14326 + idx = (uint8_t)(i - p_Set->baseEntry);
14327 + ASSERT_COND(idx < FM_PCD_MAX_NUM_OF_CLS_PLANS);
14328 + memcpy(&p_HcFrame->hcSpecificData.clsPlanEntries, &p_Set->vectors[idx], CLS_PLAN_NUM_PER_GRP*sizeof(uint32_t));
14329 + p_HcFrame->commandSequence = seqNum;
14330 +
14331 + BUILD_FD(sizeof(t_HcFrame));
14332 +
14333 + if ((err = EnQFrm(p_FmHc, &fmFd, seqNum)) != E_OK)
14334 + {
14335 + PutBuf(p_FmHc, p_HcFrame, seqNum);
14336 + RETURN_ERROR(MINOR, err, NO_MSG);
14337 + }
14338 + }
14339 +
14340 + PutBuf(p_FmHc, p_HcFrame, seqNum);
14341 + return err;
14342 +}
14343 +
14344 +t_Error FmHcPcdKgDeleteClsPlan(t_Handle h_FmHc, uint8_t grpId)
14345 +{
14346 + t_FmHc *p_FmHc = (t_FmHc*)h_FmHc;
14347 + t_FmPcdKgInterModuleClsPlanSet *p_ClsPlanSet;
14348 +
14349 + p_ClsPlanSet = (t_FmPcdKgInterModuleClsPlanSet *)XX_Malloc(sizeof(t_FmPcdKgInterModuleClsPlanSet));
14350 + if (!p_ClsPlanSet)
14351 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("Classification plan set"));
14352 +
14353 + memset(p_ClsPlanSet, 0, sizeof(t_FmPcdKgInterModuleClsPlanSet));
14354 +
14355 + p_ClsPlanSet->baseEntry = FmPcdKgGetClsPlanGrpBase(p_FmHc->h_FmPcd, grpId);
14356 + p_ClsPlanSet->numOfClsPlanEntries = FmPcdKgGetClsPlanGrpSize(p_FmHc->h_FmPcd, grpId);
14357 + ASSERT_COND(p_ClsPlanSet->numOfClsPlanEntries <= FM_PCD_MAX_NUM_OF_CLS_PLANS);
14358 +
14359 + if (FmHcPcdKgSetClsPlan(p_FmHc, p_ClsPlanSet) != E_OK)
14360 + {
14361 + XX_Free(p_ClsPlanSet);
14362 + RETURN_ERROR(MAJOR, E_INVALID_STATE, NO_MSG);
14363 + }
14364 +
14365 + XX_Free(p_ClsPlanSet);
14366 + FmPcdKgDestroyClsPlanGrp(p_FmHc->h_FmPcd, grpId);
14367 +
14368 + return E_OK;
14369 +}
14370 +
14371 +t_Error FmHcPcdCcCapwapTimeoutReassm(t_Handle h_FmHc, t_FmPcdCcCapwapReassmTimeoutParams *p_CcCapwapReassmTimeoutParams )
14372 +{
14373 + t_FmHc *p_FmHc = (t_FmHc*)h_FmHc;
14374 + t_HcFrame *p_HcFrame;
14375 + t_DpaaFD fmFd;
14376 + t_Error err;
14377 + uint32_t seqNum;
14378 +
14379 + SANITY_CHECK_RETURN_VALUE(h_FmHc, E_INVALID_HANDLE,0);
14380 +
14381 + p_HcFrame = GetBuf(p_FmHc, &seqNum);
14382 + if (!p_HcFrame)
14383 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("HC Frame object"));
14384 +
14385 + memset(p_HcFrame, 0, sizeof(t_HcFrame));
14386 + p_HcFrame->opcode = (uint32_t)(HC_HCOR_GBL | HC_HCOR_OPCODE_CC_CAPWAP_REASSM_TIMEOUT);
14387 + memcpy(&p_HcFrame->hcSpecificData.ccCapwapReassmTimeout, p_CcCapwapReassmTimeoutParams, sizeof(t_FmPcdCcCapwapReassmTimeoutParams));
14388 + p_HcFrame->commandSequence = seqNum;
14389 + BUILD_FD(sizeof(t_HcFrame));
14390 +
14391 + err = EnQFrm(p_FmHc, &fmFd, seqNum);
14392 +
14393 + PutBuf(p_FmHc, p_HcFrame, seqNum);
14394 + return err;
14395 +}
14396 +
14397 +t_Error FmHcPcdCcIpFragScratchPollCmd(t_Handle h_FmHc, bool fill, t_FmPcdCcFragScratchPoolCmdParams *p_FmPcdCcFragScratchPoolCmdParams)
14398 +{
14399 + t_FmHc *p_FmHc = (t_FmHc*)h_FmHc;
14400 + t_HcFrame *p_HcFrame;
14401 + t_DpaaFD fmFd;
14402 + t_Error err;
14403 + uint32_t seqNum;
14404 +
14405 + SANITY_CHECK_RETURN_VALUE(h_FmHc, E_INVALID_HANDLE,0);
14406 +
14407 + p_HcFrame = GetBuf(p_FmHc, &seqNum);
14408 + if (!p_HcFrame)
14409 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("HC Frame object"));
14410 +
14411 + memset(p_HcFrame, 0, sizeof(t_HcFrame));
14412 +
14413 + p_HcFrame->opcode = (uint32_t)(HC_HCOR_GBL | HC_HCOR_OPCODE_CC_IP_FRAG_INITIALIZATION);
14414 + p_HcFrame->actionReg = (uint32_t)(((fill == TRUE) ? 0 : 1) << HC_HCOR_ACTION_REG_IP_FRAG_SCRATCH_POOL_CMD_SHIFT);
14415 + p_HcFrame->actionReg |= p_FmPcdCcFragScratchPoolCmdParams->bufferPoolId << HC_HCOR_ACTION_REG_IP_FRAG_SCRATCH_POOL_BPID;
14416 + if (fill == TRUE)
14417 + {
14418 + p_HcFrame->extraReg = p_FmPcdCcFragScratchPoolCmdParams->numOfBuffers;
14419 + }
14420 + p_HcFrame->commandSequence = seqNum;
14421 +
14422 + BUILD_FD(sizeof(t_HcFrame));
14423 + if ((err = EnQFrm(p_FmHc, &fmFd, seqNum)) != E_OK)
14424 + {
14425 + PutBuf(p_FmHc, p_HcFrame, seqNum);
14426 + RETURN_ERROR(MINOR, err, NO_MSG);
14427 + }
14428 +
14429 + p_FmPcdCcFragScratchPoolCmdParams->numOfBuffers = p_HcFrame->extraReg;
14430 +
14431 + PutBuf(p_FmHc, p_HcFrame, seqNum);
14432 + return E_OK;
14433 +}
14434 +
14435 +t_Error FmHcPcdCcTimeoutReassm(t_Handle h_FmHc, t_FmPcdCcReassmTimeoutParams *p_CcReassmTimeoutParams, uint8_t *p_Result)
14436 +{
14437 + t_FmHc *p_FmHc = (t_FmHc*)h_FmHc;
14438 + t_HcFrame *p_HcFrame;
14439 + t_DpaaFD fmFd;
14440 + t_Error err;
14441 + uint32_t seqNum;
14442 +
14443 + SANITY_CHECK_RETURN_VALUE(h_FmHc, E_INVALID_HANDLE,0);
14444 +
14445 + p_HcFrame = GetBuf(p_FmHc, &seqNum);
14446 + if (!p_HcFrame)
14447 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("HC Frame object"));
14448 +
14449 + memset(p_HcFrame, 0, sizeof(t_HcFrame));
14450 + p_HcFrame->opcode = (uint32_t)(HC_HCOR_GBL | HC_HCOR_OPCODE_CC_REASSM_TIMEOUT);
14451 + p_HcFrame->actionReg = (uint32_t)((p_CcReassmTimeoutParams->activate ? 0 : 1) << HC_HCOR_ACTION_REG_REASSM_TIMEOUT_ACTIVE_SHIFT);
14452 + p_HcFrame->extraReg = (p_CcReassmTimeoutParams->tsbs << HC_HCOR_EXTRA_REG_REASSM_TIMEOUT_TSBS_SHIFT) | p_CcReassmTimeoutParams->iprcpt;
14453 + p_HcFrame->commandSequence = seqNum;
14454 +
14455 + BUILD_FD(sizeof(t_HcFrame));
14456 + if ((err = EnQFrm(p_FmHc, &fmFd, seqNum)) != E_OK)
14457 + {
14458 + PutBuf(p_FmHc, p_HcFrame, seqNum);
14459 + RETURN_ERROR(MINOR, err, NO_MSG);
14460 + }
14461 +
14462 + *p_Result = (uint8_t)
14463 + ((p_HcFrame->actionReg >> HC_HCOR_ACTION_REG_REASSM_TIMEOUT_RES_SHIFT) & HC_HCOR_ACTION_REG_REASSM_TIMEOUT_RES_MASK);
14464 +
14465 + PutBuf(p_FmHc, p_HcFrame, seqNum);
14466 + return E_OK;
14467 +}
14468 +
14469 +t_Error FmHcPcdPlcrCcGetSetParams(t_Handle h_FmHc,uint16_t absoluteProfileId, uint32_t requiredAction)
14470 +{
14471 + t_FmHc *p_FmHc = (t_FmHc*)h_FmHc;
14472 + t_HcFrame *p_HcFrame;
14473 + t_DpaaFD fmFd;
14474 + t_Error err;
14475 + uint32_t tmpReg32 = 0;
14476 + uint32_t requiredActionTmp, requiredActionFlag;
14477 + uint32_t seqNum;
14478 +
14479 + SANITY_CHECK_RETURN_VALUE(h_FmHc, E_INVALID_HANDLE,0);
14480 +
14481 + /* Profile is locked by calling routine */
14482 + /* WARNING - this lock will not be efficient if other HC routine will attempt to change
14483 + * "fmpl_pegnia" "fmpl_peynia" or "fmpl_pernia" without locking Profile !
14484 + */
14485 +
14486 + requiredActionTmp = FmPcdPlcrGetRequiredAction(p_FmHc->h_FmPcd, absoluteProfileId);
14487 + requiredActionFlag = FmPcdPlcrGetRequiredActionFlag(p_FmHc->h_FmPcd, absoluteProfileId);
14488 +
14489 + if (!requiredActionFlag || !(requiredActionTmp & requiredAction))
14490 + {
14491 + if (requiredAction & UPDATE_NIA_ENQ_WITHOUT_DMA)
14492 + {
14493 + p_HcFrame = GetBuf(p_FmHc, &seqNum);
14494 + if (!p_HcFrame)
14495 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("HC Frame object"));
14496 + /* first read scheme and check that it is valid */
14497 + memset(p_HcFrame, 0, sizeof(t_HcFrame));
14498 + p_HcFrame->opcode = (uint32_t)(HC_HCOR_GBL | HC_HCOR_OPCODE_PLCR_PRFL);
14499 + p_HcFrame->actionReg = FmPcdPlcrBuildReadPlcrActionReg(absoluteProfileId);
14500 + p_HcFrame->extraReg = 0x00008000;
14501 + p_HcFrame->commandSequence = seqNum;
14502 +
14503 + BUILD_FD(SIZE_OF_HC_FRAME_READ_OR_CC_DYNAMIC);
14504 +
14505 + if ((err = EnQFrm(p_FmHc, &fmFd, seqNum)) != E_OK)
14506 + {
14507 + PutBuf(p_FmHc, p_HcFrame, seqNum);
14508 + RETURN_ERROR(MINOR, err, NO_MSG);
14509 + }
14510 +
14511 + tmpReg32 = p_HcFrame->hcSpecificData.profileRegs.fmpl_pegnia;
14512 + if (!(tmpReg32 & (NIA_ENG_BMI | NIA_BMI_AC_ENQ_FRAME)))
14513 + {
14514 + PutBuf(p_FmHc, p_HcFrame, seqNum);
14515 + RETURN_ERROR(MAJOR, E_INVALID_STATE,
14516 + ("Next engine of this policer profile has to be assigned to FM_PCD_DONE"));
14517 + }
14518 +
14519 + tmpReg32 |= NIA_BMI_AC_ENQ_FRAME_WITHOUT_DMA;
14520 +
14521 + p_HcFrame->opcode = (uint32_t)(HC_HCOR_GBL | HC_HCOR_OPCODE_PLCR_PRFL);
14522 + p_HcFrame->actionReg = FmPcdPlcrBuildWritePlcrActionReg(absoluteProfileId);
14523 + p_HcFrame->actionReg |= FmPcdPlcrBuildNiaProfileReg(TRUE, FALSE, FALSE);
14524 + p_HcFrame->extraReg = 0x00008000;
14525 + p_HcFrame->hcSpecificData.singleRegForWrite = tmpReg32;
14526 +
14527 + BUILD_FD(SIZE_OF_HC_FRAME_PROFILE_CNT);
14528 +
14529 + if ((err = EnQFrm(p_FmHc, &fmFd, seqNum)) != E_OK)
14530 + {
14531 + PutBuf(p_FmHc, p_HcFrame, seqNum);
14532 + RETURN_ERROR(MINOR, err, NO_MSG);
14533 + }
14534 +
14535 + tmpReg32 = p_HcFrame->hcSpecificData.profileRegs.fmpl_peynia;
14536 + if (!(tmpReg32 & (NIA_ENG_BMI | NIA_BMI_AC_ENQ_FRAME)))
14537 + {
14538 + PutBuf(p_FmHc, p_HcFrame, seqNum);
14539 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Next engine of this policer profile has to be assigned to FM_PCD_DONE"));
14540 + }
14541 +
14542 + tmpReg32 |= NIA_BMI_AC_ENQ_FRAME_WITHOUT_DMA;
14543 +
14544 + p_HcFrame->opcode = (uint32_t)(HC_HCOR_GBL | HC_HCOR_OPCODE_PLCR_PRFL);
14545 + p_HcFrame->actionReg = FmPcdPlcrBuildWritePlcrActionReg(absoluteProfileId);
14546 + p_HcFrame->actionReg |= FmPcdPlcrBuildNiaProfileReg(FALSE, TRUE, FALSE);
14547 + p_HcFrame->extraReg = 0x00008000;
14548 + p_HcFrame->hcSpecificData.singleRegForWrite = tmpReg32;
14549 +
14550 + BUILD_FD(SIZE_OF_HC_FRAME_PROFILE_CNT);
14551 +
14552 + if ((err = EnQFrm(p_FmHc, &fmFd, seqNum)) != E_OK)
14553 + {
14554 + PutBuf(p_FmHc, p_HcFrame, seqNum);
14555 + RETURN_ERROR(MINOR, err, NO_MSG);
14556 + }
14557 +
14558 + tmpReg32 = p_HcFrame->hcSpecificData.profileRegs.fmpl_pernia;
14559 + if (!(tmpReg32 & (NIA_ENG_BMI | NIA_BMI_AC_ENQ_FRAME)))
14560 + {
14561 + PutBuf(p_FmHc, p_HcFrame, seqNum);
14562 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Next engine of this policer profile has to be assigned to FM_PCD_DONE"));
14563 + }
14564 +
14565 + tmpReg32 |= NIA_BMI_AC_ENQ_FRAME_WITHOUT_DMA;
14566 +
14567 + p_HcFrame->opcode = (uint32_t)(HC_HCOR_GBL | HC_HCOR_OPCODE_PLCR_PRFL);
14568 + p_HcFrame->actionReg = FmPcdPlcrBuildWritePlcrActionReg(absoluteProfileId);
14569 + p_HcFrame->actionReg |= FmPcdPlcrBuildNiaProfileReg(FALSE, FALSE, TRUE);
14570 + p_HcFrame->extraReg = 0x00008000;
14571 + p_HcFrame->hcSpecificData.singleRegForWrite = tmpReg32;
14572 +
14573 + BUILD_FD(SIZE_OF_HC_FRAME_PROFILE_CNT);
14574 +
14575 + if ((err = EnQFrm(p_FmHc, &fmFd, seqNum)) != E_OK)
14576 + {
14577 + PutBuf(p_FmHc, p_HcFrame, seqNum);
14578 + RETURN_ERROR(MINOR, err, NO_MSG);
14579 + }
14580 +
14581 + PutBuf(p_FmHc, p_HcFrame, seqNum);
14582 + }
14583 + }
14584 +
14585 + return E_OK;
14586 +}
14587 +
14588 +t_Error FmHcPcdPlcrSetProfile(t_Handle h_FmHc, t_Handle h_Profile, t_FmPcdPlcrProfileRegs *p_PlcrRegs)
14589 +{
14590 + t_FmHc *p_FmHc = (t_FmHc*)h_FmHc;
14591 + t_Error err = E_OK;
14592 + uint16_t profileIndx;
14593 + t_HcFrame *p_HcFrame;
14594 + t_DpaaFD fmFd;
14595 + uint32_t seqNum;
14596 +
14597 + p_HcFrame = GetBuf(p_FmHc, &seqNum);
14598 + if (!p_HcFrame)
14599 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("HC Frame object"));
14600 +
14601 + profileIndx = FmPcdPlcrProfileGetAbsoluteId(h_Profile);
14602 +
14603 + memset(p_HcFrame, 0, sizeof(t_HcFrame));
14604 + p_HcFrame->opcode = (uint32_t)(HC_HCOR_GBL | HC_HCOR_OPCODE_PLCR_PRFL);
14605 + p_HcFrame->actionReg = FmPcdPlcrBuildWritePlcrActionRegs(profileIndx);
14606 + p_HcFrame->extraReg = 0x00008000;
14607 + memcpy(&p_HcFrame->hcSpecificData.profileRegs, p_PlcrRegs, sizeof(t_FmPcdPlcrProfileRegs));
14608 + p_HcFrame->commandSequence = seqNum;
14609 +
14610 + BUILD_FD(sizeof(t_HcFrame));
14611 +
14612 + err = EnQFrm(p_FmHc, &fmFd, seqNum);
14613 +
14614 + PutBuf(p_FmHc, p_HcFrame, seqNum);
14615 +
14616 + if (err != E_OK)
14617 + RETURN_ERROR(MINOR, err, NO_MSG);
14618 +
14619 + return E_OK;
14620 +}
14621 +
14622 +t_Error FmHcPcdPlcrDeleteProfile(t_Handle h_FmHc, t_Handle h_Profile)
14623 +{
14624 + t_FmHc *p_FmHc = (t_FmHc*)h_FmHc;
14625 + uint16_t absoluteProfileId = FmPcdPlcrProfileGetAbsoluteId(h_Profile);
14626 + t_Error err = E_OK;
14627 + t_HcFrame *p_HcFrame;
14628 + t_DpaaFD fmFd;
14629 + uint32_t seqNum;
14630 +
14631 + p_HcFrame = GetBuf(p_FmHc, &seqNum);
14632 + if (!p_HcFrame)
14633 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("HC Frame object"));
14634 + memset(p_HcFrame, 0, sizeof(t_HcFrame));
14635 + p_HcFrame->opcode = (uint32_t)(HC_HCOR_GBL | HC_HCOR_OPCODE_PLCR_PRFL);
14636 + p_HcFrame->actionReg = FmPcdPlcrBuildWritePlcrActionReg(absoluteProfileId);
14637 + p_HcFrame->actionReg |= 0x00008000;
14638 + p_HcFrame->extraReg = 0x00008000;
14639 + memset(&p_HcFrame->hcSpecificData.profileRegs, 0, sizeof(t_FmPcdPlcrProfileRegs));
14640 + p_HcFrame->commandSequence = seqNum;
14641 +
14642 + BUILD_FD(sizeof(t_HcFrame));
14643 +
14644 + err = EnQFrm(p_FmHc, &fmFd, seqNum);
14645 +
14646 + PutBuf(p_FmHc, p_HcFrame, seqNum);
14647 +
14648 + if (err != E_OK)
14649 + RETURN_ERROR(MINOR, err, NO_MSG);
14650 +
14651 + return E_OK;
14652 +}
14653 +
14654 +t_Error FmHcPcdPlcrSetProfileCounter(t_Handle h_FmHc, t_Handle h_Profile, e_FmPcdPlcrProfileCounters counter, uint32_t value)
14655 +{
14656 +
14657 + t_FmHc *p_FmHc = (t_FmHc*)h_FmHc;
14658 + uint16_t absoluteProfileId = FmPcdPlcrProfileGetAbsoluteId(h_Profile);
14659 + t_Error err = E_OK;
14660 + t_HcFrame *p_HcFrame;
14661 + t_DpaaFD fmFd;
14662 + uint32_t seqNum;
14663 +
14664 + /* first read scheme and check that it is valid */
14665 + p_HcFrame = GetBuf(p_FmHc, &seqNum);
14666 + if (!p_HcFrame)
14667 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("HC Frame object"));
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 = FmPcdPlcrBuildWritePlcrActionReg(absoluteProfileId);
14671 + p_HcFrame->actionReg |= FmPcdPlcrBuildCounterProfileReg(counter);
14672 + p_HcFrame->extraReg = 0x00008000;
14673 + p_HcFrame->hcSpecificData.singleRegForWrite = value;
14674 + p_HcFrame->commandSequence = seqNum;
14675 +
14676 + BUILD_FD(SIZE_OF_HC_FRAME_PROFILE_CNT);
14677 +
14678 + err = EnQFrm(p_FmHc, &fmFd, seqNum);
14679 +
14680 + PutBuf(p_FmHc, p_HcFrame, seqNum);
14681 +
14682 + if (err != E_OK)
14683 + RETURN_ERROR(MINOR, err, NO_MSG);
14684 +
14685 + return E_OK;
14686 +}
14687 +
14688 +uint32_t FmHcPcdPlcrGetProfileCounter(t_Handle h_FmHc, t_Handle h_Profile, e_FmPcdPlcrProfileCounters counter)
14689 +{
14690 + t_FmHc *p_FmHc = (t_FmHc*)h_FmHc;
14691 + uint16_t absoluteProfileId = FmPcdPlcrProfileGetAbsoluteId(h_Profile);
14692 + t_Error err;
14693 + t_HcFrame *p_HcFrame;
14694 + t_DpaaFD fmFd;
14695 + uint32_t retVal = 0;
14696 + uint32_t seqNum;
14697 +
14698 + SANITY_CHECK_RETURN_VALUE(h_FmHc, E_INVALID_HANDLE,0);
14699 +
14700 + /* first read scheme and check that it is valid */
14701 + p_HcFrame = GetBuf(p_FmHc, &seqNum);
14702 + if (!p_HcFrame)
14703 + {
14704 + REPORT_ERROR(MINOR, E_NO_MEMORY, ("HC Frame object"));
14705 + return 0;
14706 + }
14707 + memset(p_HcFrame, 0, sizeof(t_HcFrame));
14708 + p_HcFrame->opcode = (uint32_t)(HC_HCOR_GBL | HC_HCOR_OPCODE_PLCR_PRFL);
14709 + p_HcFrame->actionReg = FmPcdPlcrBuildReadPlcrActionReg(absoluteProfileId);
14710 + p_HcFrame->extraReg = 0x00008000;
14711 + p_HcFrame->commandSequence = seqNum;
14712 +
14713 + BUILD_FD(SIZE_OF_HC_FRAME_READ_OR_CC_DYNAMIC);
14714 +
14715 + err = EnQFrm(p_FmHc, &fmFd, seqNum);
14716 + if (err != E_OK)
14717 + {
14718 + PutBuf(p_FmHc, p_HcFrame, seqNum);
14719 + REPORT_ERROR(MINOR, err, NO_MSG);
14720 + return 0;
14721 + }
14722 +
14723 + switch (counter)
14724 + {
14725 + case e_FM_PCD_PLCR_PROFILE_GREEN_PACKET_TOTAL_COUNTER:
14726 + retVal = p_HcFrame->hcSpecificData.profileRegs.fmpl_pegpc;
14727 + break;
14728 + case e_FM_PCD_PLCR_PROFILE_YELLOW_PACKET_TOTAL_COUNTER:
14729 + retVal = p_HcFrame->hcSpecificData.profileRegs.fmpl_peypc;
14730 + break;
14731 + case e_FM_PCD_PLCR_PROFILE_RED_PACKET_TOTAL_COUNTER:
14732 + retVal = p_HcFrame->hcSpecificData.profileRegs.fmpl_perpc;
14733 + break;
14734 + case e_FM_PCD_PLCR_PROFILE_RECOLOURED_YELLOW_PACKET_TOTAL_COUNTER:
14735 + retVal = p_HcFrame->hcSpecificData.profileRegs.fmpl_perypc;
14736 + break;
14737 + case e_FM_PCD_PLCR_PROFILE_RECOLOURED_RED_PACKET_TOTAL_COUNTER:
14738 + retVal = p_HcFrame->hcSpecificData.profileRegs.fmpl_perrpc;
14739 + break;
14740 + default:
14741 + REPORT_ERROR(MAJOR, E_INVALID_SELECTION, NO_MSG);
14742 + }
14743 +
14744 + PutBuf(p_FmHc, p_HcFrame, seqNum);
14745 + return retVal;
14746 +}
14747 +
14748 +t_Error FmHcKgWriteSp(t_Handle h_FmHc, uint8_t hardwarePortId, uint32_t spReg, bool add)
14749 +{
14750 + t_FmHc *p_FmHc = (t_FmHc*)h_FmHc;
14751 + t_HcFrame *p_HcFrame;
14752 + t_DpaaFD fmFd;
14753 + t_Error err = E_OK;
14754 + uint32_t seqNum;
14755 +
14756 + ASSERT_COND(p_FmHc);
14757 +
14758 + p_HcFrame = GetBuf(p_FmHc, &seqNum);
14759 + if (!p_HcFrame)
14760 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("HC Frame object"));
14761 + memset(p_HcFrame, 0, sizeof(t_HcFrame));
14762 + /* first read SP register */
14763 + p_HcFrame->opcode = (uint32_t)(HC_HCOR_GBL | HC_HCOR_OPCODE_KG_SCM);
14764 + p_HcFrame->actionReg = FmPcdKgBuildReadPortSchemeBindActionReg(hardwarePortId);
14765 + p_HcFrame->extraReg = HC_HCOR_KG_SCHEME_REGS_MASK;
14766 + p_HcFrame->commandSequence = seqNum;
14767 +
14768 + BUILD_FD(SIZE_OF_HC_FRAME_PORT_REGS);
14769 +
14770 + if ((err = EnQFrm(p_FmHc, &fmFd, seqNum)) != E_OK)
14771 + {
14772 + PutBuf(p_FmHc, p_HcFrame, seqNum);
14773 + RETURN_ERROR(MINOR, err, NO_MSG);
14774 + }
14775 +
14776 + /* spReg is the first reg, so we can use it both for read and for write */
14777 + if (add)
14778 + p_HcFrame->hcSpecificData.portRegsForRead.spReg |= spReg;
14779 + else
14780 + p_HcFrame->hcSpecificData.portRegsForRead.spReg &= ~spReg;
14781 +
14782 + p_HcFrame->actionReg = FmPcdKgBuildWritePortSchemeBindActionReg(hardwarePortId);
14783 +
14784 + BUILD_FD(sizeof(t_HcFrame));
14785 +
14786 + err = EnQFrm(p_FmHc, &fmFd, seqNum);
14787 +
14788 + PutBuf(p_FmHc, p_HcFrame, seqNum);
14789 +
14790 + if (err != E_OK)
14791 + RETURN_ERROR(MINOR, err, NO_MSG);
14792 +
14793 + return E_OK;
14794 +}
14795 +
14796 +t_Error FmHcKgWriteCpp(t_Handle h_FmHc, uint8_t hardwarePortId, uint32_t cppReg)
14797 +{
14798 + t_FmHc *p_FmHc = (t_FmHc*)h_FmHc;
14799 + t_HcFrame *p_HcFrame;
14800 + t_DpaaFD fmFd;
14801 + t_Error err = E_OK;
14802 + uint32_t seqNum;
14803 +
14804 + ASSERT_COND(p_FmHc);
14805 +
14806 + p_HcFrame = GetBuf(p_FmHc, &seqNum);
14807 + if (!p_HcFrame)
14808 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("HC Frame object"));
14809 + memset(p_HcFrame, 0, sizeof(t_HcFrame));
14810 + /* first read SP register */
14811 + p_HcFrame->opcode = (uint32_t)(HC_HCOR_GBL | HC_HCOR_OPCODE_KG_SCM);
14812 + p_HcFrame->actionReg = FmPcdKgBuildWritePortClsPlanBindActionReg(hardwarePortId);
14813 + p_HcFrame->extraReg = HC_HCOR_KG_SCHEME_REGS_MASK;
14814 + p_HcFrame->hcSpecificData.singleRegForWrite = cppReg;
14815 + p_HcFrame->commandSequence = seqNum;
14816 +
14817 + BUILD_FD(sizeof(t_HcFrame));
14818 +
14819 + err = EnQFrm(p_FmHc, &fmFd, seqNum);
14820 +
14821 + PutBuf(p_FmHc, p_HcFrame, seqNum);
14822 +
14823 + if (err != E_OK)
14824 + RETURN_ERROR(MINOR, err, NO_MSG);
14825 +
14826 + return E_OK;
14827 +}
14828 +
14829 +t_Error FmHcPcdCcDoDynamicChange(t_Handle h_FmHc, uint32_t oldAdAddrOffset, uint32_t newAdAddrOffset)
14830 +{
14831 + t_FmHc *p_FmHc = (t_FmHc*)h_FmHc;
14832 + t_HcFrame *p_HcFrame;
14833 + t_DpaaFD fmFd;
14834 + t_Error err = E_OK;
14835 + uint32_t seqNum;
14836 +
14837 + SANITY_CHECK_RETURN_ERROR(p_FmHc, E_INVALID_HANDLE);
14838 +
14839 + p_HcFrame = GetBuf(p_FmHc, &seqNum);
14840 + if (!p_HcFrame)
14841 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("HC Frame object"));
14842 + memset(p_HcFrame, 0, sizeof(t_HcFrame));
14843 +
14844 + p_HcFrame->opcode = (uint32_t)(HC_HCOR_GBL | HC_HCOR_OPCODE_CC);
14845 + p_HcFrame->actionReg = newAdAddrOffset;
14846 + p_HcFrame->actionReg |= 0xc0000000;
14847 + p_HcFrame->extraReg = oldAdAddrOffset;
14848 + p_HcFrame->commandSequence = seqNum;
14849 +
14850 + BUILD_FD(SIZE_OF_HC_FRAME_READ_OR_CC_DYNAMIC);
14851 +
14852 + err = EnQFrm(p_FmHc, &fmFd, seqNum);
14853 +
14854 + PutBuf(p_FmHc, p_HcFrame, seqNum);
14855 +
14856 + if (err != E_OK)
14857 + RETURN_ERROR(MAJOR, err, NO_MSG);
14858 +
14859 + return E_OK;
14860 +}
14861 +
14862 +t_Error FmHcPcdSync(t_Handle h_FmHc)
14863 +{
14864 + t_FmHc *p_FmHc = (t_FmHc*)h_FmHc;
14865 + t_HcFrame *p_HcFrame;
14866 + t_DpaaFD fmFd;
14867 + t_Error err = E_OK;
14868 + uint32_t seqNum;
14869 +
14870 + ASSERT_COND(p_FmHc);
14871 +
14872 + p_HcFrame = GetBuf(p_FmHc, &seqNum);
14873 + if (!p_HcFrame)
14874 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("HC Frame object"));
14875 + memset(p_HcFrame, 0, sizeof(t_HcFrame));
14876 + /* first read SP register */
14877 + p_HcFrame->opcode = (uint32_t)(HC_HCOR_GBL | HC_HCOR_OPCODE_SYNC);
14878 + p_HcFrame->actionReg = 0;
14879 + p_HcFrame->extraReg = 0;
14880 + p_HcFrame->commandSequence = seqNum;
14881 +
14882 + BUILD_FD(sizeof(t_HcFrame));
14883 +
14884 + err = EnQFrm(p_FmHc, &fmFd, seqNum);
14885 +
14886 + PutBuf(p_FmHc, p_HcFrame, seqNum);
14887 +
14888 + if (err != E_OK)
14889 + RETURN_ERROR(MINOR, err, NO_MSG);
14890 +
14891 + return E_OK;
14892 +}
14893 +
14894 +t_Handle FmHcGetPort(t_Handle h_FmHc)
14895 +{
14896 + t_FmHc *p_FmHc = (t_FmHc*)h_FmHc;
14897 + return p_FmHc->h_HcPortDev;
14898 +}
14899 --- /dev/null
14900 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/Makefile
14901 @@ -0,0 +1,28 @@
14902 +#
14903 +# Makefile for the Freescale Ethernet controllers
14904 +#
14905 +ccflags-y += -DVERSION=\"\"
14906 +#
14907 +#Include netcomm SW specific definitions
14908 +include $(srctree)/drivers/net/ethernet/freescale/sdk_fman/ncsw_config.mk
14909 +
14910 +NCSW_FM_INC = $(srctree)/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/inc
14911 +
14912 +ccflags-y += -I$(NCSW_FM_INC)
14913 +
14914 +obj-y += fsl-ncsw-MAC.o
14915 +
14916 +fsl-ncsw-MAC-objs := dtsec.o dtsec_mii_acc.o fm_mac.o tgec.o tgec_mii_acc.o \
14917 + fman_dtsec.o fman_dtsec_mii_acc.o fman_memac.o \
14918 + fman_tgec.o fman_crc32.o
14919 +
14920 +ifeq ($(CONFIG_FMAN_V3H),y)
14921 +fsl-ncsw-MAC-objs += memac.o memac_mii_acc.o fman_memac_mii_acc.o
14922 +endif
14923 +ifeq ($(CONFIG_FMAN_V3L),y)
14924 +fsl-ncsw-MAC-objs += memac.o memac_mii_acc.o fman_memac_mii_acc.o
14925 +endif
14926 +ifeq ($(CONFIG_FMAN_ARM),y)
14927 +fsl-ncsw-MAC-objs += memac.o memac_mii_acc.o fman_memac_mii_acc.o
14928 +endif
14929 +
14930 --- /dev/null
14931 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/dtsec.c
14932 @@ -0,0 +1,1465 @@
14933 +/*
14934 + * Copyright 2008-2013 Freescale Semiconductor Inc.
14935 + *
14936 + * Redistribution and use in source and binary forms, with or without
14937 + * modification, are permitted provided that the following conditions are met:
14938 + * * Redistributions of source code must retain the above copyright
14939 + * notice, this list of conditions and the following disclaimer.
14940 + * * Redistributions in binary form must reproduce the above copyright
14941 + * notice, this list of conditions and the following disclaimer in the
14942 + * documentation and/or other materials provided with the distribution.
14943 + * * Neither the name of Freescale Semiconductor nor the
14944 + * names of its contributors may be used to endorse or promote products
14945 + * derived from this software without specific prior written permission.
14946 + *
14947 + *
14948 + * ALTERNATIVELY, this software may be distributed under the terms of the
14949 + * GNU General Public License ("GPL") as published by the Free Software
14950 + * Foundation, either version 2 of that License or (at your option) any
14951 + * later version.
14952 + *
14953 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
14954 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
14955 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
14956 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
14957 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
14958 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
14959 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
14960 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
14961 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
14962 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
14963 + */
14964 +
14965 +/******************************************************************************
14966 + @File dtsec.c
14967 +
14968 + @Description FMan dTSEC driver
14969 +*//***************************************************************************/
14970 +
14971 +#include "std_ext.h"
14972 +#include "error_ext.h"
14973 +#include "string_ext.h"
14974 +#include "xx_ext.h"
14975 +#include "endian_ext.h"
14976 +#include "debug_ext.h"
14977 +#include "crc_mac_addr_ext.h"
14978 +
14979 +#include "fm_common.h"
14980 +#include "dtsec.h"
14981 +#include "fsl_fman_dtsec.h"
14982 +#include "fsl_fman_dtsec_mii_acc.h"
14983 +
14984 +/*****************************************************************************/
14985 +/* Internal routines */
14986 +/*****************************************************************************/
14987 +
14988 +static t_Error CheckInitParameters(t_Dtsec *p_Dtsec)
14989 +{
14990 + if (ENET_SPEED_FROM_MODE(p_Dtsec->enetMode) >= e_ENET_SPEED_10000)
14991 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Ethernet 1G MAC driver only supports 1G or lower speeds"));
14992 + if (p_Dtsec->macId >= FM_MAX_NUM_OF_1G_MACS)
14993 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("macId can not be greater than the number of 1G MACs"));
14994 + if (p_Dtsec->addr == 0)
14995 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Ethernet MAC Must have a valid MAC Address"));
14996 + if ((ENET_SPEED_FROM_MODE(p_Dtsec->enetMode) >= e_ENET_SPEED_1000) &&
14997 + p_Dtsec->p_DtsecDriverParam->halfdup_on)
14998 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Ethernet MAC 1G can't work in half duplex"));
14999 + if (p_Dtsec->p_DtsecDriverParam->halfdup_on && (p_Dtsec->p_DtsecDriverParam)->loopback)
15000 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("LoopBack is not supported in halfDuplex mode"));
15001 +#ifdef FM_RX_PREAM_4_ERRATA_DTSEC_A001
15002 + if (p_Dtsec->fmMacControllerDriver.fmRevInfo.majorRev <= 6) /* fixed for rev3 */
15003 + if (p_Dtsec->p_DtsecDriverParam->rx_preamble)
15004 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("preambleRxEn"));
15005 +#endif /* FM_RX_PREAM_4_ERRATA_DTSEC_A001 */
15006 + if (((p_Dtsec->p_DtsecDriverParam)->tx_preamble || (p_Dtsec->p_DtsecDriverParam)->rx_preamble) &&( (p_Dtsec->p_DtsecDriverParam)->preamble_len != 0x7))
15007 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Preamble length should be 0x7 bytes"));
15008 + if ((p_Dtsec->p_DtsecDriverParam)->halfdup_on &&
15009 + (p_Dtsec->p_DtsecDriverParam->tx_time_stamp_en || p_Dtsec->p_DtsecDriverParam->rx_time_stamp_en))
15010 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("dTSEC in half duplex mode has to be with 1588 timeStamping diable"));
15011 + if ((p_Dtsec->p_DtsecDriverParam)->rx_flow && (p_Dtsec->p_DtsecDriverParam)->rx_ctrl_acc )
15012 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Receive control frame are not passed to the system memory so it can not be accept "));
15013 + if ((p_Dtsec->p_DtsecDriverParam)->rx_prepend > MAX_PACKET_ALIGNMENT)
15014 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("packetAlignmentPadding can't be greater than %d ",MAX_PACKET_ALIGNMENT ));
15015 + if (((p_Dtsec->p_DtsecDriverParam)->non_back_to_back_ipg1 > MAX_INTER_PACKET_GAP) ||
15016 + ((p_Dtsec->p_DtsecDriverParam)->non_back_to_back_ipg2 > MAX_INTER_PACKET_GAP) ||
15017 + ((p_Dtsec->p_DtsecDriverParam)->back_to_back_ipg > MAX_INTER_PACKET_GAP))
15018 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Inter packet gap can't be greater than %d ",MAX_INTER_PACKET_GAP ));
15019 + if ((p_Dtsec->p_DtsecDriverParam)->halfdup_alt_backoff_val > MAX_INTER_PALTERNATE_BEB)
15020 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("alternateBackoffVal can't be greater than %d ",MAX_INTER_PALTERNATE_BEB ));
15021 + if ((p_Dtsec->p_DtsecDriverParam)->halfdup_retransmit > MAX_RETRANSMISSION)
15022 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("maxRetransmission can't be greater than %d ",MAX_RETRANSMISSION ));
15023 + if ((p_Dtsec->p_DtsecDriverParam)->halfdup_coll_window > MAX_COLLISION_WINDOW)
15024 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("collisionWindow can't be greater than %d ",MAX_COLLISION_WINDOW ));
15025 +
15026 + /* If Auto negotiation process is disabled, need to */
15027 + /* Set up the PHY using the MII Management Interface */
15028 + if (p_Dtsec->p_DtsecDriverParam->tbipa > MAX_PHYS)
15029 + RETURN_ERROR(MAJOR, E_NOT_IN_RANGE, ("PHY address (should be 0-%d)", MAX_PHYS));
15030 + if (!p_Dtsec->f_Exception)
15031 + RETURN_ERROR(MAJOR, E_INVALID_HANDLE, ("uninitialized f_Exception"));
15032 + if (!p_Dtsec->f_Event)
15033 + RETURN_ERROR(MAJOR, E_INVALID_HANDLE, ("uninitialized f_Event"));
15034 +
15035 +#ifdef FM_LEN_CHECK_ERRATA_FMAN_SW002
15036 + if (p_Dtsec->p_DtsecDriverParam->rx_len_check)
15037 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("LengthCheck!"));
15038 +#endif /* FM_LEN_CHECK_ERRATA_FMAN_SW002 */
15039 +
15040 + return E_OK;
15041 +}
15042 +
15043 +/* ......................................................................... */
15044 +
15045 +static uint32_t GetMacAddrHashCode(uint64_t ethAddr)
15046 +{
15047 + uint32_t crc;
15048 +
15049 + /* CRC calculation */
15050 + GET_MAC_ADDR_CRC(ethAddr, crc);
15051 +
15052 + crc = GetMirror32(crc);
15053 +
15054 + return crc;
15055 +}
15056 +
15057 +/* ......................................................................... */
15058 +
15059 +static void UpdateStatistics(t_Dtsec *p_Dtsec)
15060 +{
15061 + uint32_t car1, car2;
15062 +
15063 + fman_dtsec_get_clear_carry_regs(p_Dtsec->p_MemMap, &car1, &car2);
15064 +
15065 + if (car1)
15066 + {
15067 + if (car1 & CAR1_TR64)
15068 + p_Dtsec->internalStatistics.tr64 += VAL22BIT;
15069 + if (car1 & CAR1_TR127)
15070 + p_Dtsec->internalStatistics.tr127 += VAL22BIT;
15071 + if (car1 & CAR1_TR255)
15072 + p_Dtsec->internalStatistics.tr255 += VAL22BIT;
15073 + if (car1 & CAR1_TR511)
15074 + p_Dtsec->internalStatistics.tr511 += VAL22BIT;
15075 + if (car1 & CAR1_TRK1)
15076 + p_Dtsec->internalStatistics.tr1k += VAL22BIT;
15077 + if (car1 & CAR1_TRMAX)
15078 + p_Dtsec->internalStatistics.trmax += VAL22BIT;
15079 + if (car1 & CAR1_TRMGV)
15080 + p_Dtsec->internalStatistics.trmgv += VAL22BIT;
15081 + if (car1 & CAR1_RBYT)
15082 + p_Dtsec->internalStatistics.rbyt += (uint64_t)VAL32BIT;
15083 + if (car1 & CAR1_RPKT)
15084 + p_Dtsec->internalStatistics.rpkt += VAL22BIT;
15085 + if (car1 & CAR1_RMCA)
15086 + p_Dtsec->internalStatistics.rmca += VAL22BIT;
15087 + if (car1 & CAR1_RBCA)
15088 + p_Dtsec->internalStatistics.rbca += VAL22BIT;
15089 + if (car1 & CAR1_RXPF)
15090 + p_Dtsec->internalStatistics.rxpf += VAL16BIT;
15091 + if (car1 & CAR1_RALN)
15092 + p_Dtsec->internalStatistics.raln += VAL16BIT;
15093 + if (car1 & CAR1_RFLR)
15094 + p_Dtsec->internalStatistics.rflr += VAL16BIT;
15095 + if (car1 & CAR1_RCDE)
15096 + p_Dtsec->internalStatistics.rcde += VAL16BIT;
15097 + if (car1 & CAR1_RCSE)
15098 + p_Dtsec->internalStatistics.rcse += VAL16BIT;
15099 + if (car1 & CAR1_RUND)
15100 + p_Dtsec->internalStatistics.rund += VAL16BIT;
15101 + if (car1 & CAR1_ROVR)
15102 + p_Dtsec->internalStatistics.rovr += VAL16BIT;
15103 + if (car1 & CAR1_RFRG)
15104 + p_Dtsec->internalStatistics.rfrg += VAL16BIT;
15105 + if (car1 & CAR1_RJBR)
15106 + p_Dtsec->internalStatistics.rjbr += VAL16BIT;
15107 + if (car1 & CAR1_RDRP)
15108 + p_Dtsec->internalStatistics.rdrp += VAL16BIT;
15109 + }
15110 + if (car2)
15111 + {
15112 + if (car2 & CAR2_TFCS)
15113 + p_Dtsec->internalStatistics.tfcs += VAL12BIT;
15114 + if (car2 & CAR2_TBYT)
15115 + p_Dtsec->internalStatistics.tbyt += (uint64_t)VAL32BIT;
15116 + if (car2 & CAR2_TPKT)
15117 + p_Dtsec->internalStatistics.tpkt += VAL22BIT;
15118 + if (car2 & CAR2_TMCA)
15119 + p_Dtsec->internalStatistics.tmca += VAL22BIT;
15120 + if (car2 & CAR2_TBCA)
15121 + p_Dtsec->internalStatistics.tbca += VAL22BIT;
15122 + if (car2 & CAR2_TXPF)
15123 + p_Dtsec->internalStatistics.txpf += VAL16BIT;
15124 + if (car2 & CAR2_TDRP)
15125 + p_Dtsec->internalStatistics.tdrp += VAL16BIT;
15126 + }
15127 +}
15128 +
15129 +/* .............................................................................. */
15130 +
15131 +static uint16_t DtsecGetMaxFrameLength(t_Handle h_Dtsec)
15132 +{
15133 + t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec;
15134 +
15135 + SANITY_CHECK_RETURN_VALUE(p_Dtsec, E_INVALID_HANDLE, 0);
15136 + SANITY_CHECK_RETURN_VALUE(!p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE, 0);
15137 +
15138 + return fman_dtsec_get_max_frame_len(p_Dtsec->p_MemMap);
15139 +}
15140 +
15141 +/* .............................................................................. */
15142 +
15143 +static void DtsecIsr(t_Handle h_Dtsec)
15144 +{
15145 + t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec;
15146 + uint32_t event;
15147 + struct dtsec_regs *p_DtsecMemMap = p_Dtsec->p_MemMap;
15148 +
15149 + /* do not handle MDIO events */
15150 + event = fman_dtsec_get_event(p_DtsecMemMap, (uint32_t)(~(DTSEC_IMASK_MMRDEN | DTSEC_IMASK_MMWREN)));
15151 +
15152 + event &= fman_dtsec_get_interrupt_mask(p_DtsecMemMap);
15153 +
15154 + fman_dtsec_ack_event(p_DtsecMemMap, event);
15155 +
15156 + if (event & DTSEC_IMASK_BREN)
15157 + p_Dtsec->f_Exception(p_Dtsec->h_App, e_FM_MAC_EX_1G_BAB_RX);
15158 + if (event & DTSEC_IMASK_RXCEN)
15159 + p_Dtsec->f_Exception(p_Dtsec->h_App, e_FM_MAC_EX_1G_RX_CTL);
15160 + if (event & DTSEC_IMASK_MSROEN)
15161 + UpdateStatistics(p_Dtsec);
15162 + if (event & DTSEC_IMASK_GTSCEN)
15163 + p_Dtsec->f_Exception(p_Dtsec->h_App, e_FM_MAC_EX_1G_GRATEFUL_TX_STP_COMPLET);
15164 + if (event & DTSEC_IMASK_BTEN)
15165 + p_Dtsec->f_Exception(p_Dtsec->h_App, e_FM_MAC_EX_1G_BAB_TX);
15166 + if (event & DTSEC_IMASK_TXCEN)
15167 + p_Dtsec->f_Exception(p_Dtsec->h_App, e_FM_MAC_EX_1G_TX_CTL);
15168 + if (event & DTSEC_IMASK_TXEEN)
15169 + p_Dtsec->f_Exception(p_Dtsec->h_App, e_FM_MAC_EX_1G_TX_ERR);
15170 + if (event & DTSEC_IMASK_LCEN)
15171 + p_Dtsec->f_Exception(p_Dtsec->h_App, e_FM_MAC_EX_1G_LATE_COL);
15172 + if (event & DTSEC_IMASK_CRLEN)
15173 + p_Dtsec->f_Exception(p_Dtsec->h_App, e_FM_MAC_EX_1G_COL_RET_LMT);
15174 + if (event & DTSEC_IMASK_XFUNEN)
15175 + {
15176 +#ifdef FM_TX_LOCKUP_ERRATA_DTSEC6
15177 + if (p_Dtsec->fmMacControllerDriver.fmRevInfo.majorRev == 2)
15178 + {
15179 + uint32_t tpkt1, tmpReg1, tpkt2, tmpReg2, i;
15180 + /* a. Write 0x00E0_0C00 to DTSEC_ID */
15181 + /* This is a read only regidter */
15182 +
15183 + /* b. Read and save the value of TPKT */
15184 + tpkt1 = GET_UINT32(p_DtsecMemMap->tpkt);
15185 +
15186 + /* c. Read the register at dTSEC address offset 0x32C */
15187 + tmpReg1 = GET_UINT32(*(uint32_t*)((uint8_t*)p_DtsecMemMap + 0x32c));
15188 +
15189 + /* d. Compare bits [9:15] to bits [25:31] of the register at address offset 0x32C. */
15190 + if ((tmpReg1 & 0x007F0000) != (tmpReg1 & 0x0000007F))
15191 + {
15192 + /* If they are not equal, save the value of this register and wait for at least
15193 + * MAXFRM*16 ns */
15194 + XX_UDelay((uint32_t)(MIN(DtsecGetMaxFrameLength(p_Dtsec)*16/1000, 1)));
15195 + }
15196 +
15197 + /* e. Read and save TPKT again and read the register at dTSEC address offset
15198 + 0x32C again*/
15199 + tpkt2 = GET_UINT32(p_DtsecMemMap->tpkt);
15200 + tmpReg2 = GET_UINT32(*(uint32_t*)((uint8_t*)p_DtsecMemMap + 0x32c));
15201 +
15202 + /* f. Compare the value of TPKT saved in step b to value read in step e. Also
15203 + compare bits [9:15] of the register at offset 0x32C saved in step d to the value
15204 + of bits [9:15] saved in step e. If the two registers values are unchanged, then
15205 + the transmit portion of the dTSEC controller is locked up and the user should
15206 + proceed to the recover sequence. */
15207 + if ((tpkt1 == tpkt2) && ((tmpReg1 & 0x007F0000) == (tmpReg2 & 0x007F0000)))
15208 + {
15209 + /* recover sequence */
15210 +
15211 + /* a.Write a 1 to RCTRL[GRS]*/
15212 +
15213 + WRITE_UINT32(p_DtsecMemMap->rctrl, GET_UINT32(p_DtsecMemMap->rctrl) | RCTRL_GRS);
15214 +
15215 + /* b.Wait until IEVENT[GRSC]=1, or at least 100 us has elapsed. */
15216 + for (i = 0 ; i < 100 ; i++ )
15217 + {
15218 + if (GET_UINT32(p_DtsecMemMap->ievent) & DTSEC_IMASK_GRSCEN)
15219 + break;
15220 + XX_UDelay(1);
15221 + }
15222 + if (GET_UINT32(p_DtsecMemMap->ievent) & DTSEC_IMASK_GRSCEN)
15223 + WRITE_UINT32(p_DtsecMemMap->ievent, DTSEC_IMASK_GRSCEN);
15224 + else
15225 + DBG(INFO,("Rx lockup due to dTSEC Tx lockup"));
15226 +
15227 + /* c.Write a 1 to bit n of FM_RSTC (offset 0x0CC of FPM)*/
15228 + FmResetMac(p_Dtsec->fmMacControllerDriver.h_Fm, e_FM_MAC_1G, p_Dtsec->fmMacControllerDriver.macId);
15229 +
15230 + /* d.Wait 4 Tx clocks (32 ns) */
15231 + XX_UDelay(1);
15232 +
15233 + /* e.Write a 0 to bit n of FM_RSTC. */
15234 + /* cleared by FMAN */
15235 + }
15236 + }
15237 +#endif /* FM_TX_LOCKUP_ERRATA_DTSEC6 */
15238 +
15239 + p_Dtsec->f_Exception(p_Dtsec->h_App, e_FM_MAC_EX_1G_TX_FIFO_UNDRN);
15240 + }
15241 + if (event & DTSEC_IMASK_MAGEN)
15242 + p_Dtsec->f_Exception(p_Dtsec->h_App, e_FM_MAC_EX_1G_MAG_PCKT);
15243 + if (event & DTSEC_IMASK_GRSCEN)
15244 + p_Dtsec->f_Exception(p_Dtsec->h_App, e_FM_MAC_EX_1G_GRATEFUL_RX_STP_COMPLET);
15245 + if (event & DTSEC_IMASK_TDPEEN)
15246 + p_Dtsec->f_Exception(p_Dtsec->h_App, e_FM_MAC_EX_1G_TX_DATA_ERR);
15247 + if (event & DTSEC_IMASK_RDPEEN)
15248 + p_Dtsec->f_Exception(p_Dtsec->h_App, e_FM_MAC_EX_1G_RX_DATA_ERR);
15249 +
15250 + /* - masked interrupts */
15251 + ASSERT_COND(!(event & DTSEC_IMASK_ABRTEN));
15252 + ASSERT_COND(!(event & DTSEC_IMASK_IFERREN));
15253 +}
15254 +
15255 +static void DtsecMdioIsr(t_Handle h_Dtsec)
15256 +{
15257 + t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec;
15258 + uint32_t event;
15259 + struct dtsec_regs *p_DtsecMemMap = p_Dtsec->p_MemMap;
15260 +
15261 + event = GET_UINT32(p_DtsecMemMap->ievent);
15262 + /* handle only MDIO events */
15263 + event &= (DTSEC_IMASK_MMRDEN | DTSEC_IMASK_MMWREN);
15264 + if (event)
15265 + {
15266 + event &= GET_UINT32(p_DtsecMemMap->imask);
15267 +
15268 + WRITE_UINT32(p_DtsecMemMap->ievent, event);
15269 +
15270 + if (event & DTSEC_IMASK_MMRDEN)
15271 + p_Dtsec->f_Event(p_Dtsec->h_App, e_FM_MAC_EX_1G_MII_MNG_RD_COMPLET);
15272 + if (event & DTSEC_IMASK_MMWREN)
15273 + p_Dtsec->f_Event(p_Dtsec->h_App, e_FM_MAC_EX_1G_MII_MNG_WR_COMPLET);
15274 + }
15275 +}
15276 +
15277 +static void Dtsec1588Isr(t_Handle h_Dtsec)
15278 +{
15279 + t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec;
15280 + uint32_t event;
15281 + struct dtsec_regs *p_DtsecMemMap = p_Dtsec->p_MemMap;
15282 +
15283 + if (p_Dtsec->ptpTsuEnabled)
15284 + {
15285 + event = fman_dtsec_check_and_clear_tmr_event(p_DtsecMemMap);
15286 +
15287 + if (event)
15288 + {
15289 + ASSERT_COND(event & TMR_PEVENT_TSRE);
15290 + p_Dtsec->f_Exception(p_Dtsec->h_App, e_FM_MAC_EX_1G_1588_TS_RX_ERR);
15291 + }
15292 + }
15293 +}
15294 +
15295 +/* ........................................................................... */
15296 +
15297 +static void FreeInitResources(t_Dtsec *p_Dtsec)
15298 +{
15299 + if (p_Dtsec->mdioIrq != NO_IRQ)
15300 + {
15301 + XX_DisableIntr(p_Dtsec->mdioIrq);
15302 + XX_FreeIntr(p_Dtsec->mdioIrq);
15303 + }
15304 + FmUnregisterIntr(p_Dtsec->fmMacControllerDriver.h_Fm, e_FM_MOD_1G_MAC, p_Dtsec->macId, e_FM_INTR_TYPE_ERR);
15305 + FmUnregisterIntr(p_Dtsec->fmMacControllerDriver.h_Fm, e_FM_MOD_1G_MAC, p_Dtsec->macId, e_FM_INTR_TYPE_NORMAL);
15306 +
15307 + /* release the driver's group hash table */
15308 + FreeHashTable(p_Dtsec->p_MulticastAddrHash);
15309 + p_Dtsec->p_MulticastAddrHash = NULL;
15310 +
15311 + /* release the driver's individual hash table */
15312 + FreeHashTable(p_Dtsec->p_UnicastAddrHash);
15313 + p_Dtsec->p_UnicastAddrHash = NULL;
15314 +}
15315 +
15316 +/* ........................................................................... */
15317 +
15318 +static t_Error GracefulStop(t_Dtsec *p_Dtsec, e_CommMode mode)
15319 +{
15320 + struct dtsec_regs *p_MemMap;
15321 +
15322 + ASSERT_COND(p_Dtsec);
15323 +
15324 + p_MemMap = p_Dtsec->p_MemMap;
15325 + ASSERT_COND(p_MemMap);
15326 +
15327 + /* Assert the graceful transmit stop bit */
15328 + if (mode & e_COMM_MODE_RX)
15329 + {
15330 + fman_dtsec_stop_rx(p_MemMap);
15331 +
15332 +#ifdef FM_GRS_ERRATA_DTSEC_A002
15333 + if (p_Dtsec->fmMacControllerDriver.fmRevInfo.majorRev == 2)
15334 + XX_UDelay(100);
15335 +#else /* FM_GRS_ERRATA_DTSEC_A002 */
15336 +#ifdef FM_GTS_AFTER_DROPPED_FRAME_ERRATA_DTSEC_A004839
15337 + XX_UDelay(10);
15338 +#endif /* FM_GTS_AFTER_DROPPED_FRAME_ERRATA_DTSEC_A004839 */
15339 +#endif /* FM_GRS_ERRATA_DTSEC_A002 */
15340 + }
15341 +
15342 + if (mode & e_COMM_MODE_TX)
15343 +#if defined(FM_GTS_ERRATA_DTSEC_A004) || defined(FM_GTS_AFTER_MAC_ABORTED_FRAME_ERRATA_DTSEC_A0012)
15344 + if (p_Dtsec->fmMacControllerDriver.fmRevInfo.majorRev == 2)
15345 + DBG(INFO, ("GTS not supported due to DTSEC_A004 errata."));
15346 +#else /* not defined(FM_GTS_ERRATA_DTSEC_A004) ||... */
15347 +#ifdef FM_GTS_UNDERRUN_ERRATA_DTSEC_A0014
15348 + DBG(INFO, ("GTS not supported due to DTSEC_A0014 errata."));
15349 +#else /* FM_GTS_UNDERRUN_ERRATA_DTSEC_A0014 */
15350 + fman_dtsec_stop_tx(p_MemMap);
15351 +#endif /* FM_GTS_UNDERRUN_ERRATA_DTSEC_A0014 */
15352 +#endif /* defined(FM_GTS_ERRATA_DTSEC_A004) ||... */
15353 +
15354 + return E_OK;
15355 +}
15356 +
15357 +/* .............................................................................. */
15358 +
15359 +static t_Error GracefulRestart(t_Dtsec *p_Dtsec, e_CommMode mode)
15360 +{
15361 + struct dtsec_regs *p_MemMap;
15362 +
15363 + ASSERT_COND(p_Dtsec);
15364 + p_MemMap = p_Dtsec->p_MemMap;
15365 + ASSERT_COND(p_MemMap);
15366 +
15367 + /* clear the graceful receive stop bit */
15368 + if (mode & e_COMM_MODE_TX)
15369 + fman_dtsec_start_tx(p_MemMap);
15370 +
15371 + if (mode & e_COMM_MODE_RX)
15372 + fman_dtsec_start_rx(p_MemMap);
15373 +
15374 + return E_OK;
15375 +}
15376 +
15377 +
15378 +/*****************************************************************************/
15379 +/* dTSEC Configs modification functions */
15380 +/*****************************************************************************/
15381 +
15382 +/* .............................................................................. */
15383 +
15384 +static t_Error DtsecConfigLoopback(t_Handle h_Dtsec, bool newVal)
15385 +{
15386 +
15387 + t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec;
15388 +
15389 + SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE);
15390 + SANITY_CHECK_RETURN_ERROR(p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE);
15391 +
15392 + p_Dtsec->p_DtsecDriverParam->loopback = newVal;
15393 +
15394 + return E_OK;
15395 +}
15396 +
15397 +/* .............................................................................. */
15398 +
15399 +static t_Error DtsecConfigMaxFrameLength(t_Handle h_Dtsec, uint16_t newVal)
15400 +{
15401 + t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec;
15402 +
15403 + SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE);
15404 + SANITY_CHECK_RETURN_ERROR(p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE);
15405 +
15406 + p_Dtsec->p_DtsecDriverParam->maximum_frame = newVal;
15407 +
15408 + return E_OK;
15409 +}
15410 +
15411 +/* .............................................................................. */
15412 +
15413 +static t_Error DtsecConfigPadAndCrc(t_Handle h_Dtsec, bool newVal)
15414 +{
15415 + t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec;
15416 +
15417 + SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE);
15418 + SANITY_CHECK_RETURN_ERROR(p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE);
15419 +
15420 + p_Dtsec->p_DtsecDriverParam->tx_pad_crc = newVal;
15421 +
15422 + return E_OK;
15423 +}
15424 +
15425 +/* .............................................................................. */
15426 +
15427 +static t_Error DtsecConfigHalfDuplex(t_Handle h_Dtsec, bool newVal)
15428 +{
15429 + t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec;
15430 +
15431 + SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE);
15432 + SANITY_CHECK_RETURN_ERROR(p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE);
15433 +
15434 + p_Dtsec->p_DtsecDriverParam->halfdup_on = newVal;
15435 +
15436 + return E_OK;
15437 +}
15438 +
15439 +/* .............................................................................. */
15440 +
15441 +static t_Error DtsecConfigTbiPhyAddr(t_Handle h_Dtsec, uint8_t newVal)
15442 +{
15443 + t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec;
15444 +
15445 + SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE);
15446 + SANITY_CHECK_RETURN_ERROR(p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE);
15447 +
15448 + p_Dtsec->p_DtsecDriverParam->tbi_phy_addr = newVal;
15449 +
15450 + return E_OK;
15451 +}
15452 +
15453 +/* .............................................................................. */
15454 +
15455 +static t_Error DtsecConfigLengthCheck(t_Handle h_Dtsec, bool newVal)
15456 +{
15457 + t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec;
15458 +
15459 + SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE);
15460 + SANITY_CHECK_RETURN_ERROR(p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE);
15461 +
15462 + p_Dtsec->p_DtsecDriverParam->rx_len_check = newVal;
15463 +
15464 + return E_OK;
15465 +}
15466 +
15467 +/* .............................................................................. */
15468 +
15469 +static t_Error DtsecConfigException(t_Handle h_Dtsec, e_FmMacExceptions exception, bool enable)
15470 +{
15471 + t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec;
15472 + uint32_t bitMask = 0;
15473 +
15474 + SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE);
15475 + SANITY_CHECK_RETURN_ERROR(p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE);
15476 +
15477 + if (exception != e_FM_MAC_EX_1G_1588_TS_RX_ERR)
15478 + {
15479 + GET_EXCEPTION_FLAG(bitMask, exception);
15480 + if (bitMask)
15481 + {
15482 + if (enable)
15483 + p_Dtsec->exceptions |= bitMask;
15484 + else
15485 + p_Dtsec->exceptions &= ~bitMask;
15486 + }
15487 + else
15488 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Undefined exception"));
15489 + }
15490 + else
15491 + {
15492 + if (!p_Dtsec->ptpTsuEnabled)
15493 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Exception valid for 1588 only"));
15494 +
15495 + if (enable)
15496 + p_Dtsec->enTsuErrExeption = TRUE;
15497 + else
15498 + p_Dtsec->enTsuErrExeption = FALSE;
15499 + }
15500 +
15501 + return E_OK;
15502 +}
15503 +
15504 +
15505 +/*****************************************************************************/
15506 +/* dTSEC Run Time API functions */
15507 +/*****************************************************************************/
15508 +
15509 +/* .............................................................................. */
15510 +
15511 +static t_Error DtsecEnable(t_Handle h_Dtsec, e_CommMode mode)
15512 +{
15513 + t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec;
15514 +
15515 + SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE);
15516 + SANITY_CHECK_RETURN_ERROR(!p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE);
15517 +
15518 + fman_dtsec_enable(p_Dtsec->p_MemMap,
15519 + (bool)!!(mode & e_COMM_MODE_RX),
15520 + (bool)!!(mode & e_COMM_MODE_TX));
15521 +
15522 + GracefulRestart(p_Dtsec, mode);
15523 +
15524 + return E_OK;
15525 +}
15526 +
15527 +/* .............................................................................. */
15528 +
15529 +static t_Error DtsecDisable (t_Handle h_Dtsec, e_CommMode mode)
15530 +{
15531 + t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec;
15532 +
15533 + SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE);
15534 + SANITY_CHECK_RETURN_ERROR(!p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE);
15535 +
15536 + GracefulStop(p_Dtsec, mode);
15537 +
15538 + fman_dtsec_disable(p_Dtsec->p_MemMap,
15539 + (bool)!!(mode & e_COMM_MODE_RX),
15540 + (bool)!!(mode & e_COMM_MODE_TX));
15541 +
15542 + return E_OK;
15543 +}
15544 +
15545 +/* .............................................................................. */
15546 +
15547 +static t_Error DtsecSetTxPauseFrames(t_Handle h_Dtsec,
15548 + uint8_t priority,
15549 + uint16_t pauseTime,
15550 + uint16_t threshTime)
15551 +{
15552 + t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec;
15553 +
15554 + UNUSED(priority);UNUSED(threshTime);
15555 +
15556 + SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_STATE);
15557 + SANITY_CHECK_RETURN_ERROR(!p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE);
15558 +
15559 +#ifdef FM_BAD_TX_TS_IN_B_2_B_ERRATA_DTSEC_A003
15560 + if (p_Dtsec->fmMacControllerDriver.fmRevInfo.majorRev == 2)
15561 + if (0 < pauseTime && pauseTime <= 320)
15562 + RETURN_ERROR(MINOR, E_INVALID_VALUE,
15563 + ("This pause-time value of %d is illegal due to errata dTSEC-A003!"
15564 + " value should be greater than 320."));
15565 +#endif /* FM_BAD_TX_TS_IN_B_2_B_ERRATA_DTSEC_A003 */
15566 +
15567 + fman_dtsec_set_tx_pause_frames(p_Dtsec->p_MemMap, pauseTime);
15568 + return E_OK;
15569 +}
15570 +
15571 +/* .............................................................................. */
15572 +/* backward compatibility. will be removed in the future. */
15573 +static t_Error DtsecTxMacPause(t_Handle h_Dtsec, uint16_t pauseTime)
15574 +{
15575 + return DtsecSetTxPauseFrames(h_Dtsec, 0, pauseTime, 0);
15576 +}
15577 +
15578 +/* .............................................................................. */
15579 +
15580 +static t_Error DtsecRxIgnoreMacPause(t_Handle h_Dtsec, bool en)
15581 +{
15582 + t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec;
15583 + bool accept_pause = !en;
15584 +
15585 + SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_STATE);
15586 + SANITY_CHECK_RETURN_ERROR(!p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE);
15587 +
15588 + fman_dtsec_handle_rx_pause(p_Dtsec->p_MemMap, accept_pause);
15589 +
15590 + return E_OK;
15591 +}
15592 +
15593 +/* .............................................................................. */
15594 +
15595 +static t_Error DtsecEnable1588TimeStamp(t_Handle h_Dtsec)
15596 +{
15597 + t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec;
15598 +
15599 + SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE);
15600 + SANITY_CHECK_RETURN_ERROR(!p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE);
15601 +
15602 + p_Dtsec->ptpTsuEnabled = TRUE;
15603 + fman_dtsec_set_ts(p_Dtsec->p_MemMap, TRUE);
15604 +
15605 + return E_OK;
15606 +}
15607 +
15608 +/* .............................................................................. */
15609 +
15610 +static t_Error DtsecDisable1588TimeStamp(t_Handle h_Dtsec)
15611 +{
15612 + t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec;
15613 +
15614 + SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE);
15615 + SANITY_CHECK_RETURN_ERROR(!p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE);
15616 +
15617 + p_Dtsec->ptpTsuEnabled = FALSE;
15618 + fman_dtsec_set_ts(p_Dtsec->p_MemMap, FALSE);
15619 +
15620 + return E_OK;
15621 +}
15622 +
15623 +/* .............................................................................. */
15624 +
15625 +static t_Error DtsecGetStatistics(t_Handle h_Dtsec, t_FmMacStatistics *p_Statistics)
15626 +{
15627 + t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec;
15628 + struct dtsec_regs *p_DtsecMemMap;
15629 +
15630 + SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE);
15631 + SANITY_CHECK_RETURN_ERROR(!p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE);
15632 + SANITY_CHECK_RETURN_ERROR(p_Statistics, E_NULL_POINTER);
15633 +
15634 + p_DtsecMemMap = p_Dtsec->p_MemMap;
15635 +
15636 + if (p_Dtsec->statisticsLevel == e_FM_MAC_NONE_STATISTICS)
15637 + RETURN_ERROR(MINOR, E_INVALID_STATE, ("Statistics disabled"));
15638 +
15639 + memset(p_Statistics, 0xff, sizeof(t_FmMacStatistics));
15640 +
15641 + if (p_Dtsec->statisticsLevel == e_FM_MAC_FULL_STATISTICS)
15642 + {
15643 + p_Statistics->eStatPkts64 = fman_dtsec_get_stat_counter(p_DtsecMemMap, E_DTSEC_STAT_TR64)
15644 + + p_Dtsec->internalStatistics.tr64;
15645 + p_Statistics->eStatPkts65to127 = fman_dtsec_get_stat_counter(p_DtsecMemMap, E_DTSEC_STAT_TR127)
15646 + + p_Dtsec->internalStatistics.tr127;
15647 + p_Statistics->eStatPkts128to255 = fman_dtsec_get_stat_counter(p_DtsecMemMap, E_DTSEC_STAT_TR255)
15648 + + p_Dtsec->internalStatistics.tr255;
15649 + p_Statistics->eStatPkts256to511 = fman_dtsec_get_stat_counter(p_DtsecMemMap, E_DTSEC_STAT_TR511)
15650 + + p_Dtsec->internalStatistics.tr511;
15651 + p_Statistics->eStatPkts512to1023 = fman_dtsec_get_stat_counter(p_DtsecMemMap, E_DTSEC_STAT_TR1K)
15652 + + p_Dtsec->internalStatistics.tr1k;
15653 + p_Statistics->eStatPkts1024to1518 = fman_dtsec_get_stat_counter(p_DtsecMemMap, E_DTSEC_STAT_TRMAX)
15654 + + p_Dtsec->internalStatistics.trmax;
15655 + p_Statistics->eStatPkts1519to1522 = fman_dtsec_get_stat_counter(p_DtsecMemMap, E_DTSEC_STAT_TRMGV)
15656 + + p_Dtsec->internalStatistics.trmgv;
15657 +
15658 + /* MIB II */
15659 + p_Statistics->ifInOctets = fman_dtsec_get_stat_counter(p_DtsecMemMap, E_DTSEC_STAT_RBYT)
15660 + + p_Dtsec->internalStatistics.rbyt;
15661 + p_Statistics->ifInPkts = fman_dtsec_get_stat_counter(p_DtsecMemMap, E_DTSEC_STAT_RPKT)
15662 + + p_Dtsec->internalStatistics.rpkt;
15663 + p_Statistics->ifInUcastPkts = 0;
15664 + p_Statistics->ifInMcastPkts = fman_dtsec_get_stat_counter(p_DtsecMemMap, E_DTSEC_STAT_RMCA)
15665 + + p_Dtsec->internalStatistics.rmca;
15666 + p_Statistics->ifInBcastPkts = fman_dtsec_get_stat_counter(p_DtsecMemMap, E_DTSEC_STAT_RBCA)
15667 + + p_Dtsec->internalStatistics.rbca;
15668 + p_Statistics->ifOutOctets = fman_dtsec_get_stat_counter(p_DtsecMemMap, E_DTSEC_STAT_TBYT)
15669 + + p_Dtsec->internalStatistics.tbyt;
15670 + p_Statistics->ifOutPkts = fman_dtsec_get_stat_counter(p_DtsecMemMap, E_DTSEC_STAT_TPKT)
15671 + + p_Dtsec->internalStatistics.tpkt;
15672 + p_Statistics->ifOutUcastPkts = 0;
15673 + p_Statistics->ifOutMcastPkts = fman_dtsec_get_stat_counter(p_DtsecMemMap, E_DTSEC_STAT_TMCA)
15674 + + p_Dtsec->internalStatistics.tmca;
15675 + p_Statistics->ifOutBcastPkts = fman_dtsec_get_stat_counter(p_DtsecMemMap, E_DTSEC_STAT_TBCA)
15676 + + p_Dtsec->internalStatistics.tbca;
15677 + }
15678 +
15679 + p_Statistics->eStatFragments = fman_dtsec_get_stat_counter(p_DtsecMemMap, E_DTSEC_STAT_RFRG)
15680 + + p_Dtsec->internalStatistics.rfrg;
15681 + p_Statistics->eStatJabbers = fman_dtsec_get_stat_counter(p_DtsecMemMap, E_DTSEC_STAT_RJBR)
15682 + + p_Dtsec->internalStatistics.rjbr;
15683 + p_Statistics->eStatsDropEvents = fman_dtsec_get_stat_counter(p_DtsecMemMap, E_DTSEC_STAT_RDRP)
15684 + + p_Dtsec->internalStatistics.rdrp;
15685 + p_Statistics->eStatCRCAlignErrors = fman_dtsec_get_stat_counter(p_DtsecMemMap, E_DTSEC_STAT_RALN)
15686 + + p_Dtsec->internalStatistics.raln;
15687 + p_Statistics->eStatUndersizePkts = fman_dtsec_get_stat_counter(p_DtsecMemMap, E_DTSEC_STAT_RUND)
15688 + + p_Dtsec->internalStatistics.rund;
15689 + p_Statistics->eStatOversizePkts = fman_dtsec_get_stat_counter(p_DtsecMemMap, E_DTSEC_STAT_ROVR)
15690 + + p_Dtsec->internalStatistics.rovr;
15691 + p_Statistics->reStatPause = fman_dtsec_get_stat_counter(p_DtsecMemMap, E_DTSEC_STAT_RXPF)
15692 + + p_Dtsec->internalStatistics.rxpf;
15693 + p_Statistics->teStatPause = fman_dtsec_get_stat_counter(p_DtsecMemMap, E_DTSEC_STAT_TXPF)
15694 + + p_Dtsec->internalStatistics.txpf;
15695 + p_Statistics->ifInDiscards = p_Statistics->eStatsDropEvents;
15696 + p_Statistics->ifInErrors = p_Statistics->eStatsDropEvents + p_Statistics->eStatCRCAlignErrors
15697 + + fman_dtsec_get_stat_counter(p_DtsecMemMap,E_DTSEC_STAT_RFLR) + p_Dtsec->internalStatistics.rflr
15698 + + fman_dtsec_get_stat_counter(p_DtsecMemMap,E_DTSEC_STAT_RCDE) + p_Dtsec->internalStatistics.rcde
15699 + + fman_dtsec_get_stat_counter(p_DtsecMemMap,E_DTSEC_STAT_RCSE) + p_Dtsec->internalStatistics.rcse;
15700 +
15701 + p_Statistics->ifOutDiscards = fman_dtsec_get_stat_counter(p_DtsecMemMap, E_DTSEC_STAT_TDRP)
15702 + + p_Dtsec->internalStatistics.tdrp;
15703 + p_Statistics->ifOutErrors = p_Statistics->ifOutDiscards /**< Number of frames transmitted with error: */
15704 + + fman_dtsec_get_stat_counter(p_DtsecMemMap,E_DTSEC_STAT_TFCS)
15705 + + p_Dtsec->internalStatistics.tfcs;
15706 +
15707 + return E_OK;
15708 +}
15709 +
15710 +/* .............................................................................. */
15711 +
15712 +static t_Error DtsecModifyMacAddress (t_Handle h_Dtsec, t_EnetAddr *p_EnetAddr)
15713 +{
15714 + t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec;
15715 +
15716 + SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE);
15717 + SANITY_CHECK_RETURN_ERROR(!p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE);
15718 +
15719 + /* Initialize MAC Station Address registers (1 & 2) */
15720 + /* Station address have to be swapped (big endian to little endian */
15721 + p_Dtsec->addr = ENET_ADDR_TO_UINT64(*p_EnetAddr);
15722 + fman_dtsec_set_mac_address(p_Dtsec->p_MemMap, (uint8_t *)(*p_EnetAddr));
15723 +
15724 + return E_OK;
15725 +}
15726 +
15727 +/* .............................................................................. */
15728 +
15729 +static t_Error DtsecResetCounters (t_Handle h_Dtsec)
15730 +{
15731 + t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec;
15732 +
15733 + SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE);
15734 + SANITY_CHECK_RETURN_ERROR(!p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE);
15735 +
15736 + /* clear HW counters */
15737 + fman_dtsec_reset_stat(p_Dtsec->p_MemMap);
15738 +
15739 + /* clear SW counters holding carries */
15740 + memset(&p_Dtsec->internalStatistics, 0, sizeof(t_InternalStatistics));
15741 +
15742 + return E_OK;
15743 +}
15744 +
15745 +/* .............................................................................. */
15746 +
15747 +static t_Error DtsecAddExactMatchMacAddress(t_Handle h_Dtsec, t_EnetAddr *p_EthAddr)
15748 +{
15749 + t_Dtsec *p_Dtsec = (t_Dtsec *) h_Dtsec;
15750 + uint64_t ethAddr;
15751 + uint8_t paddrNum;
15752 +
15753 + SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE);
15754 + SANITY_CHECK_RETURN_ERROR(!p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE);
15755 +
15756 + ethAddr = ENET_ADDR_TO_UINT64(*p_EthAddr);
15757 +
15758 + if (ethAddr & GROUP_ADDRESS)
15759 + /* Multicast address has no effect in PADDR */
15760 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Multicast address"));
15761 +
15762 + /* Make sure no PADDR contains this address */
15763 + for (paddrNum = 0; paddrNum < DTSEC_NUM_OF_PADDRS; paddrNum++)
15764 + if (p_Dtsec->indAddrRegUsed[paddrNum])
15765 + if (p_Dtsec->paddr[paddrNum] == ethAddr)
15766 + RETURN_ERROR(MAJOR, E_ALREADY_EXISTS, NO_MSG);
15767 +
15768 + /* Find first unused PADDR */
15769 + for (paddrNum = 0; paddrNum < DTSEC_NUM_OF_PADDRS; paddrNum++)
15770 + if (!(p_Dtsec->indAddrRegUsed[paddrNum]))
15771 + {
15772 + /* mark this PADDR as used */
15773 + p_Dtsec->indAddrRegUsed[paddrNum] = TRUE;
15774 + /* store address */
15775 + p_Dtsec->paddr[paddrNum] = ethAddr;
15776 +
15777 + /* put in hardware */
15778 + fman_dtsec_add_addr_in_paddr(p_Dtsec->p_MemMap, (uint64_t)PTR_TO_UINT(&ethAddr), paddrNum);
15779 + p_Dtsec->numOfIndAddrInRegs++;
15780 +
15781 + return E_OK;
15782 + }
15783 +
15784 + /* No free PADDR */
15785 + RETURN_ERROR(MAJOR, E_FULL, NO_MSG);
15786 +}
15787 +
15788 +/* .............................................................................. */
15789 +
15790 +static t_Error DtsecDelExactMatchMacAddress(t_Handle h_Dtsec, t_EnetAddr *p_EthAddr)
15791 +{
15792 + t_Dtsec *p_Dtsec = (t_Dtsec *) h_Dtsec;
15793 + uint64_t ethAddr;
15794 + uint8_t paddrNum;
15795 +
15796 + SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE);
15797 + SANITY_CHECK_RETURN_ERROR(!p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE);
15798 +
15799 + ethAddr = ENET_ADDR_TO_UINT64(*p_EthAddr);
15800 +
15801 + /* Find used PADDR containing this address */
15802 + for (paddrNum = 0; paddrNum < DTSEC_NUM_OF_PADDRS; paddrNum++)
15803 + {
15804 + if ((p_Dtsec->indAddrRegUsed[paddrNum]) &&
15805 + (p_Dtsec->paddr[paddrNum] == ethAddr))
15806 + {
15807 + /* mark this PADDR as not used */
15808 + p_Dtsec->indAddrRegUsed[paddrNum] = FALSE;
15809 + /* clear in hardware */
15810 + fman_dtsec_clear_addr_in_paddr(p_Dtsec->p_MemMap, paddrNum);
15811 + p_Dtsec->numOfIndAddrInRegs--;
15812 +
15813 + return E_OK;
15814 + }
15815 + }
15816 +
15817 + RETURN_ERROR(MAJOR, E_NOT_FOUND, NO_MSG);
15818 +}
15819 +
15820 +/* .............................................................................. */
15821 +
15822 +static t_Error DtsecAddHashMacAddress(t_Handle h_Dtsec, t_EnetAddr *p_EthAddr)
15823 +{
15824 + t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec;
15825 + t_EthHashEntry *p_HashEntry;
15826 + uint64_t ethAddr;
15827 + int32_t bucket;
15828 + uint32_t crc;
15829 + bool mcast, ghtx;
15830 +
15831 + SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE);
15832 + SANITY_CHECK_RETURN_ERROR(!p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE);
15833 +
15834 + ethAddr = ENET_ADDR_TO_UINT64(*p_EthAddr);
15835 +
15836 + ghtx = (bool)((fman_dtsec_get_rctrl(p_Dtsec->p_MemMap) & RCTRL_GHTX) ? TRUE : FALSE);
15837 + mcast = (bool)((ethAddr & MAC_GROUP_ADDRESS) ? TRUE : FALSE);
15838 +
15839 + if (ghtx && !mcast) /* Cannot handle unicast mac addr when GHTX is on */
15840 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Could not compute hash bucket"));
15841 +
15842 + crc = GetMacAddrHashCode(ethAddr);
15843 +
15844 + /* considering the 9 highest order bits in crc H[8:0]:
15845 + * if ghtx = 0 H[8:6] (highest order 3 bits) identify the hash register
15846 + * and H[5:1] (next 5 bits) identify the hash bit
15847 + * if ghts = 1 H[8:5] (highest order 4 bits) identify the hash register
15848 + * and H[4:0] (next 5 bits) identify the hash bit.
15849 + *
15850 + * In bucket index output the low 5 bits identify the hash register bit,
15851 + * while the higher 4 bits identify the hash register
15852 + */
15853 +
15854 + if (ghtx)
15855 + bucket = (int32_t)((crc >> 23) & 0x1ff);
15856 + else {
15857 + bucket = (int32_t)((crc >> 24) & 0xff);
15858 + /* if !ghtx and mcast the bit must be set in gaddr instead of igaddr. */
15859 + if (mcast)
15860 + bucket += 0x100;
15861 + }
15862 +
15863 + fman_dtsec_set_bucket(p_Dtsec->p_MemMap, bucket, TRUE);
15864 +
15865 + /* Create element to be added to the driver hash table */
15866 + p_HashEntry = (t_EthHashEntry *)XX_Malloc(sizeof(t_EthHashEntry));
15867 + p_HashEntry->addr = ethAddr;
15868 + INIT_LIST(&p_HashEntry->node);
15869 +
15870 + if (ethAddr & MAC_GROUP_ADDRESS)
15871 + /* Group Address */
15872 + LIST_AddToTail(&(p_HashEntry->node), &(p_Dtsec->p_MulticastAddrHash->p_Lsts[bucket]));
15873 + else
15874 + LIST_AddToTail(&(p_HashEntry->node), &(p_Dtsec->p_UnicastAddrHash->p_Lsts[bucket]));
15875 +
15876 + return E_OK;
15877 +}
15878 +
15879 +/* .............................................................................. */
15880 +
15881 +static t_Error DtsecDelHashMacAddress(t_Handle h_Dtsec, t_EnetAddr *p_EthAddr)
15882 +{
15883 + t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec;
15884 + t_List *p_Pos;
15885 + t_EthHashEntry *p_HashEntry = NULL;
15886 + uint64_t ethAddr;
15887 + int32_t bucket;
15888 + uint32_t crc;
15889 + bool mcast, ghtx;
15890 +
15891 + SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE);
15892 + SANITY_CHECK_RETURN_ERROR(!p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE);
15893 +
15894 + ethAddr = ENET_ADDR_TO_UINT64(*p_EthAddr);
15895 +
15896 + ghtx = (bool)((fman_dtsec_get_rctrl(p_Dtsec->p_MemMap) & RCTRL_GHTX) ? TRUE : FALSE);
15897 + mcast = (bool)((ethAddr & MAC_GROUP_ADDRESS) ? TRUE : FALSE);
15898 +
15899 + if (ghtx && !mcast) /* Cannot handle unicast mac addr when GHTX is on */
15900 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Could not compute hash bucket"));
15901 +
15902 + crc = GetMacAddrHashCode(ethAddr);
15903 +
15904 + if (ghtx)
15905 + bucket = (int32_t)((crc >> 23) & 0x1ff);
15906 + else {
15907 + bucket = (int32_t)((crc >> 24) & 0xff);
15908 + /* if !ghtx and mcast the bit must be set in gaddr instead of igaddr. */
15909 + if (mcast)
15910 + bucket += 0x100;
15911 + }
15912 +
15913 + if (ethAddr & MAC_GROUP_ADDRESS)
15914 + {
15915 + /* Group Address */
15916 + LIST_FOR_EACH(p_Pos, &(p_Dtsec->p_MulticastAddrHash->p_Lsts[bucket]))
15917 + {
15918 + p_HashEntry = ETH_HASH_ENTRY_OBJ(p_Pos);
15919 + if (p_HashEntry->addr == ethAddr)
15920 + {
15921 + LIST_DelAndInit(&p_HashEntry->node);
15922 + XX_Free(p_HashEntry);
15923 + break;
15924 + }
15925 + }
15926 + if (LIST_IsEmpty(&p_Dtsec->p_MulticastAddrHash->p_Lsts[bucket]))
15927 + fman_dtsec_set_bucket(p_Dtsec->p_MemMap, bucket, FALSE);
15928 + }
15929 + else
15930 + {
15931 + /* Individual Address */
15932 + LIST_FOR_EACH(p_Pos, &(p_Dtsec->p_UnicastAddrHash->p_Lsts[bucket]))
15933 + {
15934 + p_HashEntry = ETH_HASH_ENTRY_OBJ(p_Pos);
15935 + if (p_HashEntry->addr == ethAddr)
15936 + {
15937 + LIST_DelAndInit(&p_HashEntry->node);
15938 + XX_Free(p_HashEntry);
15939 + break;
15940 + }
15941 + }
15942 + if (LIST_IsEmpty(&p_Dtsec->p_UnicastAddrHash->p_Lsts[bucket]))
15943 + fman_dtsec_set_bucket(p_Dtsec->p_MemMap, bucket, FALSE);
15944 + }
15945 +
15946 + /* address does not exist */
15947 + ASSERT_COND(p_HashEntry != NULL);
15948 +
15949 + return E_OK;
15950 +}
15951 +
15952 +/* .............................................................................. */
15953 +
15954 +static t_Error DtsecSetPromiscuous(t_Handle h_Dtsec, bool newVal)
15955 +{
15956 + t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec;
15957 +
15958 + SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE);
15959 + SANITY_CHECK_RETURN_ERROR(!p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE);
15960 +
15961 + fman_dtsec_set_uc_promisc(p_Dtsec->p_MemMap, newVal);
15962 + fman_dtsec_set_mc_promisc(p_Dtsec->p_MemMap, newVal);
15963 +
15964 + return E_OK;
15965 +}
15966 +
15967 +/* .............................................................................. */
15968 +
15969 +static t_Error DtsecSetStatistics(t_Handle h_Dtsec, e_FmMacStatisticsLevel statisticsLevel)
15970 +{
15971 + t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec;
15972 + t_Error err;
15973 +
15974 + SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE);
15975 + SANITY_CHECK_RETURN_ERROR(!p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE);
15976 +
15977 + p_Dtsec->statisticsLevel = statisticsLevel;
15978 +
15979 + err = (t_Error)fman_dtsec_set_stat_level(p_Dtsec->p_MemMap,
15980 + (enum dtsec_stat_level)statisticsLevel);
15981 + if (err != E_OK)
15982 + return err;
15983 +
15984 + switch (statisticsLevel)
15985 + {
15986 + case (e_FM_MAC_NONE_STATISTICS):
15987 + p_Dtsec->exceptions &= ~DTSEC_IMASK_MSROEN;
15988 + break;
15989 + case (e_FM_MAC_PARTIAL_STATISTICS):
15990 + p_Dtsec->exceptions |= DTSEC_IMASK_MSROEN;
15991 + break;
15992 + case (e_FM_MAC_FULL_STATISTICS):
15993 + p_Dtsec->exceptions |= DTSEC_IMASK_MSROEN;
15994 + break;
15995 + default:
15996 + RETURN_ERROR(MINOR, E_INVALID_SELECTION, NO_MSG);
15997 + }
15998 +
15999 + return E_OK;
16000 +}
16001 +
16002 +/* .............................................................................. */
16003 +
16004 +static t_Error DtsecSetWakeOnLan(t_Handle h_Dtsec, bool en)
16005 +{
16006 + t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec;
16007 +
16008 + SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_STATE);
16009 + SANITY_CHECK_RETURN_ERROR(!p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE);
16010 +
16011 + fman_dtsec_set_wol(p_Dtsec->p_MemMap, en);
16012 +
16013 + return E_OK;
16014 +}
16015 +
16016 +/* .............................................................................. */
16017 +
16018 +static t_Error DtsecAdjustLink(t_Handle h_Dtsec, e_EnetSpeed speed, bool fullDuplex)
16019 +{
16020 + t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec;
16021 + int err;
16022 + enum enet_interface enet_interface;
16023 + enum enet_speed enet_speed;
16024 +
16025 + SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE);
16026 + SANITY_CHECK_RETURN_ERROR(!p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE);
16027 +
16028 + p_Dtsec->enetMode = MAKE_ENET_MODE(ENET_INTERFACE_FROM_MODE(p_Dtsec->enetMode), speed);
16029 + enet_interface = (enum enet_interface) ENET_INTERFACE_FROM_MODE(p_Dtsec->enetMode);
16030 + enet_speed = (enum enet_speed) ENET_SPEED_FROM_MODE(p_Dtsec->enetMode);
16031 + p_Dtsec->halfDuplex = !fullDuplex;
16032 +
16033 + err = fman_dtsec_adjust_link(p_Dtsec->p_MemMap, enet_interface, enet_speed, fullDuplex);
16034 +
16035 + if (err == -EINVAL)
16036 + RETURN_ERROR(MAJOR, E_CONFLICT, ("Ethernet interface does not support Half Duplex mode"));
16037 +
16038 + return (t_Error)err;
16039 +}
16040 +
16041 +/* .............................................................................. */
16042 +
16043 +static t_Error DtsecRestartAutoneg(t_Handle h_Dtsec)
16044 +{
16045 + t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec;
16046 + uint16_t tmpReg16;
16047 +
16048 + SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE);
16049 + SANITY_CHECK_RETURN_ERROR(!p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE);
16050 +
16051 + DTSEC_MII_ReadPhyReg(p_Dtsec, p_Dtsec->tbi_phy_addr, 0, &tmpReg16);
16052 +
16053 + tmpReg16 &= ~( PHY_CR_SPEED0 | PHY_CR_SPEED1 );
16054 + tmpReg16 |= (PHY_CR_ANE | PHY_CR_RESET_AN | PHY_CR_FULLDUPLEX | PHY_CR_SPEED1);
16055 +
16056 + DTSEC_MII_WritePhyReg(p_Dtsec, p_Dtsec->tbi_phy_addr, 0, tmpReg16);
16057 +
16058 + return E_OK;
16059 +}
16060 +
16061 +/* .............................................................................. */
16062 +
16063 +static t_Error DtsecGetId(t_Handle h_Dtsec, uint32_t *macId)
16064 +{
16065 + t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec;
16066 +
16067 + SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE);
16068 + SANITY_CHECK_RETURN_ERROR(!p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE);
16069 +
16070 + *macId = p_Dtsec->macId;
16071 +
16072 + return E_OK;
16073 +}
16074 +
16075 +/* .............................................................................. */
16076 +
16077 +static t_Error DtsecGetVersion(t_Handle h_Dtsec, uint32_t *macVersion)
16078 +{
16079 + t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec;
16080 +
16081 + SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE);
16082 + SANITY_CHECK_RETURN_ERROR(!p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE);
16083 +
16084 + *macVersion = fman_dtsec_get_revision(p_Dtsec->p_MemMap);
16085 +
16086 + return E_OK;
16087 +}
16088 +
16089 +/* .............................................................................. */
16090 +
16091 +static t_Error DtsecSetException(t_Handle h_Dtsec, e_FmMacExceptions exception, bool enable)
16092 +{
16093 + t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec;
16094 + uint32_t bitMask = 0;
16095 +
16096 + SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE);
16097 + SANITY_CHECK_RETURN_ERROR(!p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE);
16098 +
16099 + if (exception != e_FM_MAC_EX_1G_1588_TS_RX_ERR)
16100 + {
16101 + GET_EXCEPTION_FLAG(bitMask, exception);
16102 + if (bitMask)
16103 + {
16104 + if (enable)
16105 + p_Dtsec->exceptions |= bitMask;
16106 + else
16107 + p_Dtsec->exceptions &= ~bitMask;
16108 + }
16109 + else
16110 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Undefined exception"));
16111 +
16112 + if (enable)
16113 + fman_dtsec_enable_interrupt(p_Dtsec->p_MemMap, bitMask);
16114 + else
16115 + fman_dtsec_disable_interrupt(p_Dtsec->p_MemMap, bitMask);
16116 + }
16117 + else
16118 + {
16119 + if (!p_Dtsec->ptpTsuEnabled)
16120 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Exception valid for 1588 only"));
16121 +
16122 + if (enable)
16123 + {
16124 + p_Dtsec->enTsuErrExeption = TRUE;
16125 + fman_dtsec_enable_tmr_interrupt(p_Dtsec->p_MemMap);
16126 + }
16127 + else
16128 + {
16129 + p_Dtsec->enTsuErrExeption = FALSE;
16130 + fman_dtsec_disable_tmr_interrupt(p_Dtsec->p_MemMap);
16131 + }
16132 + }
16133 +
16134 + return E_OK;
16135 +}
16136 +
16137 +
16138 +/*****************************************************************************/
16139 +/* dTSEC Init & Free API */
16140 +/*****************************************************************************/
16141 +
16142 +/* .............................................................................. */
16143 +
16144 +static t_Error DtsecInit(t_Handle h_Dtsec)
16145 +{
16146 + t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec;
16147 + struct dtsec_cfg *p_DtsecDriverParam;
16148 + t_Error err;
16149 + uint16_t maxFrmLn;
16150 + enum enet_interface enet_interface;
16151 + enum enet_speed enet_speed;
16152 + t_EnetAddr ethAddr;
16153 +
16154 + SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE);
16155 + SANITY_CHECK_RETURN_ERROR(p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE);
16156 + SANITY_CHECK_RETURN_ERROR(p_Dtsec->fmMacControllerDriver.h_Fm, E_INVALID_HANDLE);
16157 +
16158 + FM_GetRevision(p_Dtsec->fmMacControllerDriver.h_Fm, &p_Dtsec->fmMacControllerDriver.fmRevInfo);
16159 + CHECK_INIT_PARAMETERS(p_Dtsec, CheckInitParameters);
16160 +
16161 + p_DtsecDriverParam = p_Dtsec->p_DtsecDriverParam;
16162 + p_Dtsec->halfDuplex = p_DtsecDriverParam->halfdup_on;
16163 +
16164 + enet_interface = (enum enet_interface)ENET_INTERFACE_FROM_MODE(p_Dtsec->enetMode);
16165 + enet_speed = (enum enet_speed)ENET_SPEED_FROM_MODE(p_Dtsec->enetMode);
16166 + MAKE_ENET_ADDR_FROM_UINT64(p_Dtsec->addr, ethAddr);
16167 +
16168 + err = (t_Error)fman_dtsec_init(p_Dtsec->p_MemMap,
16169 + p_DtsecDriverParam,
16170 + enet_interface,
16171 + enet_speed,
16172 + (uint8_t*)ethAddr,
16173 + p_Dtsec->fmMacControllerDriver.fmRevInfo.majorRev,
16174 + p_Dtsec->fmMacControllerDriver.fmRevInfo.minorRev,
16175 + p_Dtsec->exceptions);
16176 + if (err)
16177 + {
16178 + FreeInitResources(p_Dtsec);
16179 + RETURN_ERROR(MAJOR, err, ("This DTSEC version does not support the required i/f mode"));
16180 + }
16181 +
16182 + if (ENET_INTERFACE_FROM_MODE(p_Dtsec->enetMode) == e_ENET_IF_SGMII)
16183 + {
16184 + uint16_t tmpReg16;
16185 +
16186 + /* Configure the TBI PHY Control Register */
16187 + tmpReg16 = PHY_TBICON_CLK_SEL | PHY_TBICON_SRESET;
16188 + DTSEC_MII_WritePhyReg(p_Dtsec, (uint8_t)p_DtsecDriverParam->tbipa, 17, tmpReg16);
16189 +
16190 + tmpReg16 = PHY_TBICON_CLK_SEL;
16191 + DTSEC_MII_WritePhyReg(p_Dtsec, (uint8_t)p_DtsecDriverParam->tbipa, 17, tmpReg16);
16192 +
16193 + tmpReg16 = (PHY_CR_PHY_RESET | PHY_CR_ANE | PHY_CR_FULLDUPLEX | PHY_CR_SPEED1);
16194 + DTSEC_MII_WritePhyReg(p_Dtsec, (uint8_t)p_DtsecDriverParam->tbipa, 0, tmpReg16);
16195 +
16196 + if (p_Dtsec->enetMode & ENET_IF_SGMII_BASEX)
16197 + tmpReg16 = PHY_TBIANA_1000X;
16198 + else
16199 + tmpReg16 = PHY_TBIANA_SGMII;
16200 + DTSEC_MII_WritePhyReg(p_Dtsec, (uint8_t)p_DtsecDriverParam->tbipa, 4, tmpReg16);
16201 +
16202 + tmpReg16 = (PHY_CR_ANE | PHY_CR_RESET_AN | PHY_CR_FULLDUPLEX | PHY_CR_SPEED1);
16203 +
16204 + DTSEC_MII_WritePhyReg(p_Dtsec, (uint8_t)p_DtsecDriverParam->tbipa, 0, tmpReg16);
16205 + }
16206 +
16207 + /* Max Frame Length */
16208 + maxFrmLn = fman_dtsec_get_max_frame_len(p_Dtsec->p_MemMap);
16209 + err = FmSetMacMaxFrame(p_Dtsec->fmMacControllerDriver.h_Fm, e_FM_MAC_1G,
16210 + p_Dtsec->fmMacControllerDriver.macId, maxFrmLn);
16211 + if (err)
16212 + RETURN_ERROR(MINOR,err, NO_MSG);
16213 +
16214 + p_Dtsec->p_MulticastAddrHash = AllocHashTable(EXTENDED_HASH_TABLE_SIZE);
16215 + if (!p_Dtsec->p_MulticastAddrHash) {
16216 + FreeInitResources(p_Dtsec);
16217 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("MC hash table is FAILED"));
16218 + }
16219 +
16220 + p_Dtsec->p_UnicastAddrHash = AllocHashTable(HASH_TABLE_SIZE);
16221 + if (!p_Dtsec->p_UnicastAddrHash)
16222 + {
16223 + FreeInitResources(p_Dtsec);
16224 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("UC hash table is FAILED"));
16225 + }
16226 +
16227 + /* register err intr handler for dtsec to FPM (err)*/
16228 + FmRegisterIntr(p_Dtsec->fmMacControllerDriver.h_Fm,
16229 + e_FM_MOD_1G_MAC,
16230 + p_Dtsec->macId,
16231 + e_FM_INTR_TYPE_ERR,
16232 + DtsecIsr,
16233 + p_Dtsec);
16234 + /* register 1588 intr handler for TMR to FPM (normal)*/
16235 + FmRegisterIntr(p_Dtsec->fmMacControllerDriver.h_Fm,
16236 + e_FM_MOD_1G_MAC,
16237 + p_Dtsec->macId,
16238 + e_FM_INTR_TYPE_NORMAL,
16239 + Dtsec1588Isr,
16240 + p_Dtsec);
16241 + /* register normal intr handler for dtsec to main interrupt controller. */
16242 + if (p_Dtsec->mdioIrq != NO_IRQ)
16243 + {
16244 + XX_SetIntr(p_Dtsec->mdioIrq, DtsecMdioIsr, p_Dtsec);
16245 + XX_EnableIntr(p_Dtsec->mdioIrq);
16246 + }
16247 +
16248 + XX_Free(p_DtsecDriverParam);
16249 + p_Dtsec->p_DtsecDriverParam = NULL;
16250 +
16251 + err = DtsecSetStatistics(h_Dtsec, e_FM_MAC_FULL_STATISTICS);
16252 + if (err)
16253 + {
16254 + FreeInitResources(p_Dtsec);
16255 + RETURN_ERROR(MAJOR, err, ("Undefined statistics level"));
16256 + }
16257 +
16258 + return E_OK;
16259 +}
16260 +
16261 +/* ........................................................................... */
16262 +
16263 +static t_Error DtsecFree(t_Handle h_Dtsec)
16264 +{
16265 + t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec;
16266 +
16267 + SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE);
16268 +
16269 + if (p_Dtsec->p_DtsecDriverParam)
16270 + {
16271 + /* Called after config */
16272 + XX_Free(p_Dtsec->p_DtsecDriverParam);
16273 + p_Dtsec->p_DtsecDriverParam = NULL;
16274 + }
16275 + else
16276 + /* Called after init */
16277 + FreeInitResources(p_Dtsec);
16278 +
16279 + XX_Free(p_Dtsec);
16280 +
16281 + return E_OK;
16282 +}
16283 +
16284 +/* .............................................................................. */
16285 +
16286 +static void InitFmMacControllerDriver(t_FmMacControllerDriver *p_FmMacControllerDriver)
16287 +{
16288 + p_FmMacControllerDriver->f_FM_MAC_Init = DtsecInit;
16289 + p_FmMacControllerDriver->f_FM_MAC_Free = DtsecFree;
16290 +
16291 + p_FmMacControllerDriver->f_FM_MAC_SetStatistics = DtsecSetStatistics;
16292 + p_FmMacControllerDriver->f_FM_MAC_ConfigLoopback = DtsecConfigLoopback;
16293 + p_FmMacControllerDriver->f_FM_MAC_ConfigMaxFrameLength = DtsecConfigMaxFrameLength;
16294 +
16295 + p_FmMacControllerDriver->f_FM_MAC_ConfigWan = NULL; /* Not supported on dTSEC */
16296 +
16297 + p_FmMacControllerDriver->f_FM_MAC_ConfigPadAndCrc = DtsecConfigPadAndCrc;
16298 + p_FmMacControllerDriver->f_FM_MAC_ConfigHalfDuplex = DtsecConfigHalfDuplex;
16299 + p_FmMacControllerDriver->f_FM_MAC_ConfigLengthCheck = DtsecConfigLengthCheck;
16300 + p_FmMacControllerDriver->f_FM_MAC_ConfigTbiPhyAddr = DtsecConfigTbiPhyAddr;
16301 + p_FmMacControllerDriver->f_FM_MAC_ConfigException = DtsecConfigException;
16302 + p_FmMacControllerDriver->f_FM_MAC_ConfigResetOnInit = NULL;
16303 +
16304 + p_FmMacControllerDriver->f_FM_MAC_Enable = DtsecEnable;
16305 + p_FmMacControllerDriver->f_FM_MAC_Disable = DtsecDisable;
16306 + p_FmMacControllerDriver->f_FM_MAC_Resume = NULL;
16307 +
16308 + p_FmMacControllerDriver->f_FM_MAC_SetException = DtsecSetException;
16309 +
16310 + p_FmMacControllerDriver->f_FM_MAC_SetPromiscuous = DtsecSetPromiscuous;
16311 + p_FmMacControllerDriver->f_FM_MAC_AdjustLink = DtsecAdjustLink;
16312 + p_FmMacControllerDriver->f_FM_MAC_SetWakeOnLan = DtsecSetWakeOnLan;
16313 + p_FmMacControllerDriver->f_FM_MAC_RestartAutoneg = DtsecRestartAutoneg;
16314 +
16315 + p_FmMacControllerDriver->f_FM_MAC_Enable1588TimeStamp = DtsecEnable1588TimeStamp;
16316 + p_FmMacControllerDriver->f_FM_MAC_Disable1588TimeStamp = DtsecDisable1588TimeStamp;
16317 +
16318 + p_FmMacControllerDriver->f_FM_MAC_SetTxAutoPauseFrames = DtsecTxMacPause;
16319 + p_FmMacControllerDriver->f_FM_MAC_SetTxPauseFrames = DtsecSetTxPauseFrames;
16320 + p_FmMacControllerDriver->f_FM_MAC_SetRxIgnorePauseFrames = DtsecRxIgnoreMacPause;
16321 +
16322 + p_FmMacControllerDriver->f_FM_MAC_ResetCounters = DtsecResetCounters;
16323 + p_FmMacControllerDriver->f_FM_MAC_GetStatistics = DtsecGetStatistics;
16324 + p_FmMacControllerDriver->f_FM_MAC_GetFrameSizeCounters = NULL;
16325 +
16326 + p_FmMacControllerDriver->f_FM_MAC_ModifyMacAddr = DtsecModifyMacAddress;
16327 + p_FmMacControllerDriver->f_FM_MAC_AddHashMacAddr = DtsecAddHashMacAddress;
16328 + p_FmMacControllerDriver->f_FM_MAC_RemoveHashMacAddr = DtsecDelHashMacAddress;
16329 + p_FmMacControllerDriver->f_FM_MAC_AddExactMatchMacAddr = DtsecAddExactMatchMacAddress;
16330 + p_FmMacControllerDriver->f_FM_MAC_RemovelExactMatchMacAddr = DtsecDelExactMatchMacAddress;
16331 + p_FmMacControllerDriver->f_FM_MAC_GetId = DtsecGetId;
16332 + p_FmMacControllerDriver->f_FM_MAC_GetVersion = DtsecGetVersion;
16333 + p_FmMacControllerDriver->f_FM_MAC_GetMaxFrameLength = DtsecGetMaxFrameLength;
16334 +
16335 + p_FmMacControllerDriver->f_FM_MAC_MII_WritePhyReg = DTSEC_MII_WritePhyReg;
16336 + p_FmMacControllerDriver->f_FM_MAC_MII_ReadPhyReg = DTSEC_MII_ReadPhyReg;
16337 +
16338 +}
16339 +
16340 +
16341 +/*****************************************************************************/
16342 +/* dTSEC Config Main Entry */
16343 +/*****************************************************************************/
16344 +
16345 +/* .............................................................................. */
16346 +
16347 +t_Handle DTSEC_Config(t_FmMacParams *p_FmMacParam)
16348 +{
16349 + t_Dtsec *p_Dtsec;
16350 + struct dtsec_cfg *p_DtsecDriverParam;
16351 + uintptr_t baseAddr;
16352 +
16353 + SANITY_CHECK_RETURN_VALUE(p_FmMacParam, E_NULL_POINTER, NULL);
16354 +
16355 + baseAddr = p_FmMacParam->baseAddr;
16356 +
16357 + /* allocate memory for the UCC GETH data structure. */
16358 + p_Dtsec = (t_Dtsec *)XX_Malloc(sizeof(t_Dtsec));
16359 + if (!p_Dtsec)
16360 + {
16361 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("dTSEC driver structure"));
16362 + return NULL;
16363 + }
16364 + memset(p_Dtsec, 0, sizeof(t_Dtsec));
16365 + InitFmMacControllerDriver(&p_Dtsec->fmMacControllerDriver);
16366 +
16367 + /* allocate memory for the dTSEC driver parameters data structure. */
16368 + p_DtsecDriverParam = (struct dtsec_cfg *) XX_Malloc(sizeof(struct dtsec_cfg));
16369 + if (!p_DtsecDriverParam)
16370 + {
16371 + XX_Free(p_Dtsec);
16372 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("dTSEC driver parameters"));
16373 + return NULL;
16374 + }
16375 + memset(p_DtsecDriverParam, 0, sizeof(struct dtsec_cfg));
16376 +
16377 + /* Plant parameter structure pointer */
16378 + p_Dtsec->p_DtsecDriverParam = p_DtsecDriverParam;
16379 +
16380 + fman_dtsec_defconfig(p_DtsecDriverParam);
16381 +
16382 + p_Dtsec->p_MemMap = (struct dtsec_regs *)UINT_TO_PTR(baseAddr);
16383 + p_Dtsec->p_MiiMemMap = (struct dtsec_mii_reg *)UINT_TO_PTR(baseAddr + DTSEC_TO_MII_OFFSET);
16384 + p_Dtsec->addr = ENET_ADDR_TO_UINT64(p_FmMacParam->addr);
16385 + p_Dtsec->enetMode = p_FmMacParam->enetMode;
16386 + p_Dtsec->macId = p_FmMacParam->macId;
16387 + p_Dtsec->exceptions = DEFAULT_exceptions;
16388 + p_Dtsec->mdioIrq = p_FmMacParam->mdioIrq;
16389 + p_Dtsec->f_Exception = p_FmMacParam->f_Exception;
16390 + p_Dtsec->f_Event = p_FmMacParam->f_Event;
16391 + p_Dtsec->h_App = p_FmMacParam->h_App;
16392 + p_Dtsec->ptpTsuEnabled = p_Dtsec->p_DtsecDriverParam->ptp_tsu_en;
16393 + p_Dtsec->enTsuErrExeption = p_Dtsec->p_DtsecDriverParam->ptp_exception_en;
16394 + p_Dtsec->tbi_phy_addr = p_Dtsec->p_DtsecDriverParam->tbi_phy_addr;
16395 +
16396 + return p_Dtsec;
16397 +}
16398 --- /dev/null
16399 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/dtsec.h
16400 @@ -0,0 +1,228 @@
16401 +/*
16402 + * Copyright 2008-2013 Freescale Semiconductor Inc.
16403 + *
16404 + * Redistribution and use in source and binary forms, with or without
16405 + * modification, are permitted provided that the following conditions are met:
16406 + * * Redistributions of source code must retain the above copyright
16407 + * notice, this list of conditions and the following disclaimer.
16408 + * * Redistributions in binary form must reproduce the above copyright
16409 + * notice, this list of conditions and the following disclaimer in the
16410 + * documentation and/or other materials provided with the distribution.
16411 + * * Neither the name of Freescale Semiconductor nor the
16412 + * names of its contributors may be used to endorse or promote products
16413 + * derived from this software without specific prior written permission.
16414 + *
16415 + *
16416 + * ALTERNATIVELY, this software may be distributed under the terms of the
16417 + * GNU General Public License ("GPL") as published by the Free Software
16418 + * Foundation, either version 2 of that License or (at your option) any
16419 + * later version.
16420 + *
16421 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
16422 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
16423 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
16424 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
16425 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
16426 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
16427 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
16428 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
16429 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
16430 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
16431 + */
16432 +
16433 +/******************************************************************************
16434 + @File dtsec.h
16435 +
16436 + @Description FM dTSEC ...
16437 +*//***************************************************************************/
16438 +#ifndef __DTSEC_H
16439 +#define __DTSEC_H
16440 +
16441 +#include "std_ext.h"
16442 +#include "error_ext.h"
16443 +#include "list_ext.h"
16444 +#include "enet_ext.h"
16445 +
16446 +#include "dtsec_mii_acc.h"
16447 +#include "fm_mac.h"
16448 +
16449 +
16450 +#define DEFAULT_exceptions \
16451 + ((uint32_t)(DTSEC_IMASK_BREN | \
16452 + DTSEC_IMASK_RXCEN | \
16453 + DTSEC_IMASK_BTEN | \
16454 + DTSEC_IMASK_TXCEN | \
16455 + DTSEC_IMASK_TXEEN | \
16456 + DTSEC_IMASK_ABRTEN | \
16457 + DTSEC_IMASK_LCEN | \
16458 + DTSEC_IMASK_CRLEN | \
16459 + DTSEC_IMASK_XFUNEN | \
16460 + DTSEC_IMASK_IFERREN | \
16461 + DTSEC_IMASK_MAGEN | \
16462 + DTSEC_IMASK_TDPEEN | \
16463 + DTSEC_IMASK_RDPEEN))
16464 +
16465 +#define GET_EXCEPTION_FLAG(bitMask, exception) switch (exception){ \
16466 + case e_FM_MAC_EX_1G_BAB_RX: \
16467 + bitMask = DTSEC_IMASK_BREN; break; \
16468 + case e_FM_MAC_EX_1G_RX_CTL: \
16469 + bitMask = DTSEC_IMASK_RXCEN; break; \
16470 + case e_FM_MAC_EX_1G_GRATEFUL_TX_STP_COMPLET: \
16471 + bitMask = DTSEC_IMASK_GTSCEN ; break; \
16472 + case e_FM_MAC_EX_1G_BAB_TX: \
16473 + bitMask = DTSEC_IMASK_BTEN ; break; \
16474 + case e_FM_MAC_EX_1G_TX_CTL: \
16475 + bitMask = DTSEC_IMASK_TXCEN ; break; \
16476 + case e_FM_MAC_EX_1G_TX_ERR: \
16477 + bitMask = DTSEC_IMASK_TXEEN ; break; \
16478 + case e_FM_MAC_EX_1G_LATE_COL: \
16479 + bitMask = DTSEC_IMASK_LCEN ; break; \
16480 + case e_FM_MAC_EX_1G_COL_RET_LMT: \
16481 + bitMask = DTSEC_IMASK_CRLEN ; break; \
16482 + case e_FM_MAC_EX_1G_TX_FIFO_UNDRN: \
16483 + bitMask = DTSEC_IMASK_XFUNEN ; break; \
16484 + case e_FM_MAC_EX_1G_MAG_PCKT: \
16485 + bitMask = DTSEC_IMASK_MAGEN ; break; \
16486 + case e_FM_MAC_EX_1G_MII_MNG_RD_COMPLET: \
16487 + bitMask = DTSEC_IMASK_MMRDEN; break; \
16488 + case e_FM_MAC_EX_1G_MII_MNG_WR_COMPLET: \
16489 + bitMask = DTSEC_IMASK_MMWREN ; break; \
16490 + case e_FM_MAC_EX_1G_GRATEFUL_RX_STP_COMPLET: \
16491 + bitMask = DTSEC_IMASK_GRSCEN; break; \
16492 + case e_FM_MAC_EX_1G_TX_DATA_ERR: \
16493 + bitMask = DTSEC_IMASK_TDPEEN; break; \
16494 + case e_FM_MAC_EX_1G_RX_MIB_CNT_OVFL: \
16495 + bitMask = DTSEC_IMASK_MSROEN ; break; \
16496 + default: bitMask = 0;break;}
16497 +
16498 +
16499 +#define MAX_PACKET_ALIGNMENT 31
16500 +#define MAX_INTER_PACKET_GAP 0x7f
16501 +#define MAX_INTER_PALTERNATE_BEB 0x0f
16502 +#define MAX_RETRANSMISSION 0x0f
16503 +#define MAX_COLLISION_WINDOW 0x03ff
16504 +
16505 +
16506 +/********************* From mac ext ******************************************/
16507 +typedef uint32_t t_ErrorDisable;
16508 +
16509 +#define ERROR_DISABLE_TRANSMIT 0x00400000
16510 +#define ERROR_DISABLE_LATE_COLLISION 0x00040000
16511 +#define ERROR_DISABLE_COLLISION_RETRY_LIMIT 0x00020000
16512 +#define ERROR_DISABLE_TxFIFO_UNDERRUN 0x00010000
16513 +#define ERROR_DISABLE_TxABORT 0x00008000
16514 +#define ERROR_DISABLE_INTERFACE 0x00004000
16515 +#define ERROR_DISABLE_TxDATA_PARITY 0x00000002
16516 +#define ERROR_DISABLE_RxDATA_PARITY 0x00000001
16517 +
16518 +/*****************************************************************************/
16519 +#define DTSEC_NUM_OF_PADDRS 15 /* number of pattern match registers (entries) */
16520 +
16521 +#define GROUP_ADDRESS 0x0000010000000000LL /* Group address bit indication */
16522 +
16523 +#define HASH_TABLE_SIZE 256 /* Hash table size (= 32 bits * 8 regs) */
16524 +
16525 +#define HASH_TABLE_SIZE 256 /* Hash table size (32 bits * 8 regs) */
16526 +#define EXTENDED_HASH_TABLE_SIZE 512 /* Extended Hash table size (32 bits * 16 regs) */
16527 +
16528 +#define DTSEC_TO_MII_OFFSET 0x1000 /* number of pattern match registers (entries) */
16529 +
16530 +#define MAX_PHYS 32 /* maximum number of phys */
16531 +
16532 +#define VAL32BIT 0x100000000LL
16533 +#define VAL22BIT 0x00400000
16534 +#define VAL16BIT 0x00010000
16535 +#define VAL12BIT 0x00001000
16536 +
16537 +/* CAR1/2 bits */
16538 +#define CAR1_TR64 0x80000000
16539 +#define CAR1_TR127 0x40000000
16540 +#define CAR1_TR255 0x20000000
16541 +#define CAR1_TR511 0x10000000
16542 +#define CAR1_TRK1 0x08000000
16543 +#define CAR1_TRMAX 0x04000000
16544 +#define CAR1_TRMGV 0x02000000
16545 +
16546 +#define CAR1_RBYT 0x00010000
16547 +#define CAR1_RPKT 0x00008000
16548 +#define CAR1_RMCA 0x00002000
16549 +#define CAR1_RBCA 0x00001000
16550 +#define CAR1_RXPF 0x00000400
16551 +#define CAR1_RALN 0x00000100
16552 +#define CAR1_RFLR 0x00000080
16553 +#define CAR1_RCDE 0x00000040
16554 +#define CAR1_RCSE 0x00000020
16555 +#define CAR1_RUND 0x00000010
16556 +#define CAR1_ROVR 0x00000008
16557 +#define CAR1_RFRG 0x00000004
16558 +#define CAR1_RJBR 0x00000002
16559 +#define CAR1_RDRP 0x00000001
16560 +
16561 +#define CAR2_TFCS 0x00040000
16562 +#define CAR2_TBYT 0x00002000
16563 +#define CAR2_TPKT 0x00001000
16564 +#define CAR2_TMCA 0x00000800
16565 +#define CAR2_TBCA 0x00000400
16566 +#define CAR2_TXPF 0x00000200
16567 +#define CAR2_TDRP 0x00000001
16568 +
16569 +typedef struct t_InternalStatistics
16570 +{
16571 + uint64_t tr64;
16572 + uint64_t tr127;
16573 + uint64_t tr255;
16574 + uint64_t tr511;
16575 + uint64_t tr1k;
16576 + uint64_t trmax;
16577 + uint64_t trmgv;
16578 + uint64_t rfrg;
16579 + uint64_t rjbr;
16580 + uint64_t rdrp;
16581 + uint64_t raln;
16582 + uint64_t rund;
16583 + uint64_t rovr;
16584 + uint64_t rxpf;
16585 + uint64_t txpf;
16586 + uint64_t rbyt;
16587 + uint64_t rpkt;
16588 + uint64_t rmca;
16589 + uint64_t rbca;
16590 + uint64_t rflr;
16591 + uint64_t rcde;
16592 + uint64_t rcse;
16593 + uint64_t tbyt;
16594 + uint64_t tpkt;
16595 + uint64_t tmca;
16596 + uint64_t tbca;
16597 + uint64_t tdrp;
16598 + uint64_t tfcs;
16599 +} t_InternalStatistics;
16600 +
16601 +typedef struct {
16602 + t_FmMacControllerDriver fmMacControllerDriver;
16603 + t_Handle h_App; /**< Handle to the upper layer application */
16604 + struct dtsec_regs *p_MemMap; /**< pointer to dTSEC memory mapped registers. */
16605 + struct dtsec_mii_reg *p_MiiMemMap; /**< pointer to dTSEC MII memory mapped registers. */
16606 + uint64_t addr; /**< MAC address of device; */
16607 + e_EnetMode enetMode; /**< Ethernet physical interface */
16608 + t_FmMacExceptionCallback *f_Exception;
16609 + int mdioIrq;
16610 + t_FmMacExceptionCallback *f_Event;
16611 + bool indAddrRegUsed[DTSEC_NUM_OF_PADDRS]; /**< Whether a particular individual address recognition register is being used */
16612 + uint64_t paddr[DTSEC_NUM_OF_PADDRS]; /**< MAC address for particular individual address recognition register */
16613 + uint8_t numOfIndAddrInRegs; /**< Number of individual addresses in registers for this station. */
16614 + bool halfDuplex;
16615 + t_InternalStatistics internalStatistics;
16616 + t_EthHash *p_MulticastAddrHash; /* pointer to driver's global address hash table */
16617 + t_EthHash *p_UnicastAddrHash; /* pointer to driver's individual address hash table */
16618 + uint8_t macId;
16619 + uint8_t tbi_phy_addr;
16620 + uint32_t exceptions;
16621 + bool ptpTsuEnabled;
16622 + bool enTsuErrExeption;
16623 + e_FmMacStatisticsLevel statisticsLevel;
16624 + struct dtsec_cfg *p_DtsecDriverParam;
16625 +} t_Dtsec;
16626 +
16627 +
16628 +#endif /* __DTSEC_H */
16629 --- /dev/null
16630 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/dtsec_mii_acc.c
16631 @@ -0,0 +1,97 @@
16632 +/*
16633 + * Copyright 2008-2013 Freescale Semiconductor Inc.
16634 + *
16635 + * Redistribution and use in source and binary forms, with or without
16636 + * modification, are permitted provided that the following conditions are met:
16637 + * * Redistributions of source code must retain the above copyright
16638 + * notice, this list of conditions and the following disclaimer.
16639 + * * Redistributions in binary form must reproduce the above copyright
16640 + * notice, this list of conditions and the following disclaimer in the
16641 + * documentation and/or other materials provided with the distribution.
16642 + * * Neither the name of Freescale Semiconductor nor the
16643 + * names of its contributors may be used to endorse or promote products
16644 + * derived from this software without specific prior written permission.
16645 + *
16646 + *
16647 + * ALTERNATIVELY, this software may be distributed under the terms of the
16648 + * GNU General Public License ("GPL") as published by the Free Software
16649 + * Foundation, either version 2 of that License or (at your option) any
16650 + * later version.
16651 + *
16652 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
16653 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
16654 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
16655 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
16656 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
16657 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
16658 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
16659 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
16660 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
16661 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
16662 + */
16663 +
16664 +
16665 +/******************************************************************************
16666 + @File dtsec_mii_acc.c
16667 +
16668 + @Description FM dtsec MII register access MAC ...
16669 +*//***************************************************************************/
16670 +
16671 +#include "error_ext.h"
16672 +#include "std_ext.h"
16673 +#include "fm_mac.h"
16674 +#include "dtsec.h"
16675 +#include "fsl_fman_dtsec_mii_acc.h"
16676 +
16677 +
16678 +/*****************************************************************************/
16679 +t_Error DTSEC_MII_WritePhyReg(t_Handle h_Dtsec,
16680 + uint8_t phyAddr,
16681 + uint8_t reg,
16682 + uint16_t data)
16683 +{
16684 + t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec;
16685 + struct dtsec_mii_reg *miiregs;
16686 + uint16_t dtsec_freq;
16687 + t_Error err;
16688 +
16689 + SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE);
16690 + SANITY_CHECK_RETURN_ERROR(p_Dtsec->p_MiiMemMap, E_INVALID_HANDLE);
16691 +
16692 + dtsec_freq = (uint16_t)(p_Dtsec->fmMacControllerDriver.clkFreq >> 1);
16693 + miiregs = p_Dtsec->p_MiiMemMap;
16694 +
16695 + err = (t_Error)fman_dtsec_mii_write_reg(miiregs, phyAddr, reg, data, dtsec_freq);
16696 +
16697 + return err;
16698 +}
16699 +
16700 +/*****************************************************************************/
16701 +t_Error DTSEC_MII_ReadPhyReg(t_Handle h_Dtsec,
16702 + uint8_t phyAddr,
16703 + uint8_t reg,
16704 + uint16_t *p_Data)
16705 +{
16706 + t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec;
16707 + struct dtsec_mii_reg *miiregs;
16708 + uint16_t dtsec_freq;
16709 + t_Error err;
16710 +
16711 + SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE);
16712 + SANITY_CHECK_RETURN_ERROR(p_Dtsec->p_MiiMemMap, E_INVALID_HANDLE);
16713 +
16714 + dtsec_freq = (uint16_t)(p_Dtsec->fmMacControllerDriver.clkFreq >> 1);
16715 + miiregs = p_Dtsec->p_MiiMemMap;
16716 +
16717 + err = fman_dtsec_mii_read_reg(miiregs, phyAddr, reg, p_Data, dtsec_freq);
16718 +
16719 + if (*p_Data == 0xffff)
16720 + RETURN_ERROR(MINOR, E_NO_DEVICE,
16721 + ("Read wrong data (0xffff): phyAddr 0x%x, reg 0x%x",
16722 + phyAddr, reg));
16723 + if (err)
16724 + RETURN_ERROR(MINOR, (t_Error)err, NO_MSG);
16725 +
16726 + return E_OK;
16727 +}
16728 +
16729 --- /dev/null
16730 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/dtsec_mii_acc.h
16731 @@ -0,0 +1,42 @@
16732 +/*
16733 + * Copyright 2008-2013 Freescale Semiconductor Inc.
16734 + *
16735 + * Redistribution and use in source and binary forms, with or without
16736 + * modification, are permitted provided that the following conditions are met:
16737 + * * Redistributions of source code must retain the above copyright
16738 + * notice, this list of conditions and the following disclaimer.
16739 + * * Redistributions in binary form must reproduce the above copyright
16740 + * notice, this list of conditions and the following disclaimer in the
16741 + * documentation and/or other materials provided with the distribution.
16742 + * * Neither the name of Freescale Semiconductor nor the
16743 + * names of its contributors may be used to endorse or promote products
16744 + * derived from this software without specific prior written permission.
16745 + *
16746 + *
16747 + * ALTERNATIVELY, this software may be distributed under the terms of the
16748 + * GNU General Public License ("GPL") as published by the Free Software
16749 + * Foundation, either version 2 of that License or (at your option) any
16750 + * later version.
16751 + *
16752 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
16753 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
16754 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
16755 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
16756 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
16757 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
16758 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
16759 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
16760 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
16761 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
16762 + */
16763 +
16764 +#ifndef __DTSEC_MII_ACC_H
16765 +#define __DTSEC_MII_ACC_H
16766 +
16767 +#include "std_ext.h"
16768 +
16769 +
16770 +t_Error DTSEC_MII_WritePhyReg(t_Handle h_Dtsec, uint8_t phyAddr, uint8_t reg, uint16_t data);
16771 +t_Error DTSEC_MII_ReadPhyReg(t_Handle h_Dtsec, uint8_t phyAddr, uint8_t reg, uint16_t *p_Data);
16772 +
16773 +#endif /* __DTSEC_MII_ACC_H */
16774 --- /dev/null
16775 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/fm_mac.c
16776 @@ -0,0 +1,674 @@
16777 +/*
16778 + * Copyright 2008-2012 Freescale Semiconductor Inc.
16779 + *
16780 + * Redistribution and use in source and binary forms, with or without
16781 + * modification, are permitted provided that the following conditions are met:
16782 + * * Redistributions of source code must retain the above copyright
16783 + * notice, this list of conditions and the following disclaimer.
16784 + * * Redistributions in binary form must reproduce the above copyright
16785 + * notice, this list of conditions and the following disclaimer in the
16786 + * documentation and/or other materials provided with the distribution.
16787 + * * Neither the name of Freescale Semiconductor nor the
16788 + * names of its contributors may be used to endorse or promote products
16789 + * derived from this software without specific prior written permission.
16790 + *
16791 + *
16792 + * ALTERNATIVELY, this software may be distributed under the terms of the
16793 + * GNU General Public License ("GPL") as published by the Free Software
16794 + * Foundation, either version 2 of that License or (at your option) any
16795 + * later version.
16796 + *
16797 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
16798 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
16799 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
16800 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
16801 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
16802 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
16803 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
16804 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
16805 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
16806 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
16807 + */
16808 +
16809 +
16810 +/******************************************************************************
16811 + @File fm_mac.c
16812 +
16813 + @Description FM MAC ...
16814 +*//***************************************************************************/
16815 +#include "std_ext.h"
16816 +#include "string_ext.h"
16817 +#include "sprint_ext.h"
16818 +#include "error_ext.h"
16819 +#include "fm_ext.h"
16820 +
16821 +#include "fm_common.h"
16822 +#include "fm_mac.h"
16823 +
16824 +
16825 +/* ......................................................................... */
16826 +
16827 +t_Handle FM_MAC_Config (t_FmMacParams *p_FmMacParam)
16828 +{
16829 + t_FmMacControllerDriver *p_FmMacControllerDriver;
16830 + uint16_t fmClkFreq;
16831 +
16832 + SANITY_CHECK_RETURN_VALUE(p_FmMacParam, E_INVALID_HANDLE, NULL);
16833 +
16834 + fmClkFreq = FmGetClockFreq(p_FmMacParam->h_Fm);
16835 + if (fmClkFreq == 0)
16836 + {
16837 + REPORT_ERROR(MAJOR, E_INVALID_STATE, ("Can't get clock for MAC!"));
16838 + return NULL;
16839 + }
16840 +
16841 +#if (DPAA_VERSION == 10)
16842 + if (ENET_SPEED_FROM_MODE(p_FmMacParam->enetMode) < e_ENET_SPEED_10000)
16843 + p_FmMacControllerDriver = (t_FmMacControllerDriver *)DTSEC_Config(p_FmMacParam);
16844 + else
16845 +#if FM_MAX_NUM_OF_10G_MACS > 0
16846 + p_FmMacControllerDriver = (t_FmMacControllerDriver *)TGEC_Config(p_FmMacParam);
16847 +#else
16848 + p_FmMacControllerDriver = NULL;
16849 +#endif /* FM_MAX_NUM_OF_10G_MACS > 0 */
16850 +#else
16851 + p_FmMacControllerDriver = (t_FmMacControllerDriver *)MEMAC_Config(p_FmMacParam);
16852 +#endif /* (DPAA_VERSION == 10) */
16853 +
16854 + if (!p_FmMacControllerDriver)
16855 + return NULL;
16856 +
16857 + p_FmMacControllerDriver->h_Fm = p_FmMacParam->h_Fm;
16858 + p_FmMacControllerDriver->enetMode = p_FmMacParam->enetMode;
16859 + p_FmMacControllerDriver->macId = p_FmMacParam->macId;
16860 + p_FmMacControllerDriver->resetOnInit = DEFAULT_resetOnInit;
16861 +
16862 + p_FmMacControllerDriver->clkFreq = fmClkFreq;
16863 +
16864 + return (t_Handle)p_FmMacControllerDriver;
16865 +}
16866 +
16867 +/* ......................................................................... */
16868 +
16869 +t_Error FM_MAC_Init (t_Handle h_FmMac)
16870 +{
16871 + t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac;
16872 +
16873 + SANITY_CHECK_RETURN_ERROR(p_FmMacControllerDriver, E_INVALID_HANDLE);
16874 +
16875 + if (p_FmMacControllerDriver->resetOnInit &&
16876 + !p_FmMacControllerDriver->f_FM_MAC_ConfigResetOnInit &&
16877 + (FmResetMac(p_FmMacControllerDriver->h_Fm,
16878 + ((ENET_INTERFACE_FROM_MODE(p_FmMacControllerDriver->enetMode) == e_ENET_IF_XGMII) ?
16879 + e_FM_MAC_10G : e_FM_MAC_1G),
16880 + p_FmMacControllerDriver->macId) != E_OK))
16881 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Can't reset MAC!"));
16882 +
16883 + if (p_FmMacControllerDriver->f_FM_MAC_Init)
16884 + return p_FmMacControllerDriver->f_FM_MAC_Init(h_FmMac);
16885 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
16886 +}
16887 +
16888 +/* ......................................................................... */
16889 +
16890 +t_Error FM_MAC_Free (t_Handle h_FmMac)
16891 +{
16892 + t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac;
16893 +
16894 + SANITY_CHECK_RETURN_ERROR(p_FmMacControllerDriver, E_INVALID_HANDLE);
16895 +
16896 + if (p_FmMacControllerDriver->f_FM_MAC_Free)
16897 + return p_FmMacControllerDriver->f_FM_MAC_Free(h_FmMac);
16898 +
16899 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
16900 +}
16901 +
16902 +/* ......................................................................... */
16903 +
16904 +t_Error FM_MAC_ConfigResetOnInit (t_Handle h_FmMac, bool enable)
16905 +{
16906 + t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac;
16907 +
16908 + SANITY_CHECK_RETURN_ERROR(p_FmMacControllerDriver, E_INVALID_HANDLE);
16909 +
16910 + if (p_FmMacControllerDriver->f_FM_MAC_ConfigResetOnInit)
16911 + return p_FmMacControllerDriver->f_FM_MAC_ConfigResetOnInit(h_FmMac, enable);
16912 +
16913 + p_FmMacControllerDriver->resetOnInit = enable;
16914 +
16915 + return E_OK;
16916 +}
16917 +
16918 +/* ......................................................................... */
16919 +
16920 +t_Error FM_MAC_ConfigLoopback (t_Handle h_FmMac, bool newVal)
16921 +{
16922 + t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac;
16923 +
16924 + SANITY_CHECK_RETURN_ERROR(p_FmMacControllerDriver, E_INVALID_HANDLE);
16925 +
16926 + if (p_FmMacControllerDriver->f_FM_MAC_ConfigLoopback)
16927 + return p_FmMacControllerDriver->f_FM_MAC_ConfigLoopback(h_FmMac, newVal);
16928 +
16929 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
16930 +}
16931 +
16932 +/* ......................................................................... */
16933 +
16934 +t_Error FM_MAC_ConfigMaxFrameLength (t_Handle h_FmMac, uint16_t newVal)
16935 +{
16936 + t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac;
16937 +
16938 + SANITY_CHECK_RETURN_ERROR(p_FmMacControllerDriver, E_INVALID_HANDLE);
16939 +
16940 + if (p_FmMacControllerDriver->f_FM_MAC_ConfigMaxFrameLength)
16941 + return p_FmMacControllerDriver->f_FM_MAC_ConfigMaxFrameLength(h_FmMac, newVal);
16942 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
16943 +}
16944 +
16945 +/* ......................................................................... */
16946 +
16947 +t_Error FM_MAC_ConfigWan (t_Handle h_FmMac, bool flag)
16948 +{
16949 + t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac;
16950 +
16951 + SANITY_CHECK_RETURN_ERROR(p_FmMacControllerDriver, E_INVALID_HANDLE);
16952 +
16953 + if (p_FmMacControllerDriver->f_FM_MAC_ConfigWan)
16954 + return p_FmMacControllerDriver->f_FM_MAC_ConfigWan(h_FmMac, flag);
16955 +
16956 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
16957 +}
16958 +
16959 +/* ......................................................................... */
16960 +
16961 +t_Error FM_MAC_ConfigPadAndCrc (t_Handle h_FmMac, bool newVal)
16962 +{
16963 + t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac;
16964 +
16965 + SANITY_CHECK_RETURN_ERROR(p_FmMacControllerDriver, E_INVALID_HANDLE);
16966 +
16967 + if (p_FmMacControllerDriver->f_FM_MAC_ConfigPadAndCrc)
16968 + return p_FmMacControllerDriver->f_FM_MAC_ConfigPadAndCrc(h_FmMac, newVal);
16969 +
16970 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
16971 +}
16972 +
16973 +/* ......................................................................... */
16974 +
16975 +t_Error FM_MAC_ConfigHalfDuplex (t_Handle h_FmMac, bool newVal)
16976 +{
16977 + t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac;
16978 +
16979 + SANITY_CHECK_RETURN_ERROR(p_FmMacControllerDriver, E_INVALID_HANDLE);
16980 +
16981 + if (p_FmMacControllerDriver->f_FM_MAC_ConfigHalfDuplex)
16982 + return p_FmMacControllerDriver->f_FM_MAC_ConfigHalfDuplex(h_FmMac,newVal);
16983 +
16984 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
16985 +}
16986 +
16987 +/* ......................................................................... */
16988 +
16989 +t_Error FM_MAC_ConfigTbiPhyAddr (t_Handle h_FmMac, uint8_t newVal)
16990 +{
16991 + t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac;
16992 +
16993 + SANITY_CHECK_RETURN_ERROR(p_FmMacControllerDriver, E_INVALID_HANDLE);
16994 +
16995 + if (p_FmMacControllerDriver->f_FM_MAC_ConfigTbiPhyAddr)
16996 + return p_FmMacControllerDriver->f_FM_MAC_ConfigTbiPhyAddr(h_FmMac,newVal);
16997 +
16998 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
16999 +}
17000 +
17001 +/* ......................................................................... */
17002 +
17003 +t_Error FM_MAC_ConfigLengthCheck (t_Handle h_FmMac, bool newVal)
17004 +{
17005 + t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac;
17006 +
17007 + SANITY_CHECK_RETURN_ERROR(p_FmMacControllerDriver, E_INVALID_HANDLE);
17008 +
17009 + if (p_FmMacControllerDriver->f_FM_MAC_ConfigLengthCheck)
17010 + return p_FmMacControllerDriver->f_FM_MAC_ConfigLengthCheck(h_FmMac,newVal);
17011 +
17012 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
17013 +}
17014 +
17015 +/* ......................................................................... */
17016 +
17017 +t_Error FM_MAC_ConfigException (t_Handle h_FmMac, e_FmMacExceptions ex, bool enable)
17018 +{
17019 + t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac;
17020 +
17021 + SANITY_CHECK_RETURN_ERROR(p_FmMacControllerDriver, E_INVALID_HANDLE);
17022 +
17023 + if (p_FmMacControllerDriver->f_FM_MAC_ConfigException)
17024 + return p_FmMacControllerDriver->f_FM_MAC_ConfigException(h_FmMac, ex, enable);
17025 +
17026 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
17027 +}
17028 +
17029 +#ifdef FM_TX_ECC_FRMS_ERRATA_10GMAC_A004
17030 +/* ......................................................................... */
17031 +
17032 +t_Error FM_MAC_ConfigSkipFman11Workaround (t_Handle h_FmMac)
17033 +{
17034 + t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac;
17035 +
17036 + SANITY_CHECK_RETURN_ERROR(p_FmMacControllerDriver, E_INVALID_HANDLE);
17037 +
17038 + if (p_FmMacControllerDriver->f_FM_MAC_ConfigSkipFman11Workaround)
17039 + return p_FmMacControllerDriver->f_FM_MAC_ConfigSkipFman11Workaround(h_FmMac);
17040 +
17041 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
17042 +}
17043 +#endif /* FM_TX_ECC_FRMS_ERRATA_10GMAC_A004 */
17044 +
17045 +
17046 +/*****************************************************************************/
17047 +/* Run Time Control */
17048 +/*****************************************************************************/
17049 +
17050 +/* ......................................................................... */
17051 +
17052 +t_Error FM_MAC_Enable (t_Handle h_FmMac, e_CommMode mode)
17053 +{
17054 + t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac;
17055 +
17056 + SANITY_CHECK_RETURN_ERROR(p_FmMacControllerDriver, E_INVALID_HANDLE);
17057 +
17058 + if (p_FmMacControllerDriver->f_FM_MAC_Enable)
17059 + return p_FmMacControllerDriver->f_FM_MAC_Enable(h_FmMac, mode);
17060 +
17061 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
17062 +}
17063 +
17064 +/* ......................................................................... */
17065 +
17066 +t_Error FM_MAC_Disable (t_Handle h_FmMac, e_CommMode mode)
17067 +{
17068 + t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac;
17069 +
17070 + SANITY_CHECK_RETURN_ERROR(p_FmMacControllerDriver, E_INVALID_HANDLE);
17071 +
17072 + if (p_FmMacControllerDriver->f_FM_MAC_Disable)
17073 + return p_FmMacControllerDriver->f_FM_MAC_Disable(h_FmMac, mode);
17074 +
17075 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
17076 +}
17077 +
17078 +t_Error FM_MAC_Resume (t_Handle h_FmMac)
17079 +{
17080 + t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac;
17081 +
17082 + SANITY_CHECK_RETURN_ERROR(p_FmMacControllerDriver, E_INVALID_HANDLE);
17083 +
17084 + if (p_FmMacControllerDriver->f_FM_MAC_Resume)
17085 + return p_FmMacControllerDriver->f_FM_MAC_Resume(h_FmMac);
17086 +
17087 + return E_OK;
17088 +}
17089 +
17090 +/* ......................................................................... */
17091 +
17092 +t_Error FM_MAC_Enable1588TimeStamp (t_Handle h_FmMac)
17093 +{
17094 + t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac;
17095 +
17096 + SANITY_CHECK_RETURN_ERROR(p_FmMacControllerDriver, E_INVALID_HANDLE);
17097 +
17098 + if (p_FmMacControllerDriver->f_FM_MAC_Enable1588TimeStamp)
17099 + return p_FmMacControllerDriver->f_FM_MAC_Enable1588TimeStamp(h_FmMac);
17100 +
17101 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
17102 +}
17103 +
17104 +/* ......................................................................... */
17105 +
17106 +t_Error FM_MAC_Disable1588TimeStamp (t_Handle h_FmMac)
17107 +{
17108 + t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac;
17109 +
17110 + SANITY_CHECK_RETURN_ERROR(p_FmMacControllerDriver, E_INVALID_HANDLE);
17111 +
17112 + if (p_FmMacControllerDriver->f_FM_MAC_Disable1588TimeStamp)
17113 + return p_FmMacControllerDriver->f_FM_MAC_Disable1588TimeStamp(h_FmMac);
17114 +
17115 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
17116 +}
17117 +
17118 +/* ......................................................................... */
17119 +
17120 +t_Error FM_MAC_SetTxAutoPauseFrames(t_Handle h_FmMac,
17121 + uint16_t pauseTime)
17122 +{
17123 + t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac;
17124 +
17125 + SANITY_CHECK_RETURN_ERROR(p_FmMacControllerDriver, E_INVALID_HANDLE);
17126 +
17127 + if (p_FmMacControllerDriver->f_FM_MAC_SetTxAutoPauseFrames)
17128 + return p_FmMacControllerDriver->f_FM_MAC_SetTxAutoPauseFrames(h_FmMac,
17129 + pauseTime);
17130 +
17131 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
17132 +}
17133 +
17134 +/* ......................................................................... */
17135 +
17136 +t_Error FM_MAC_SetTxPauseFrames(t_Handle h_FmMac,
17137 + uint8_t priority,
17138 + uint16_t pauseTime,
17139 + uint16_t threshTime)
17140 +{
17141 + t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac;
17142 +
17143 + SANITY_CHECK_RETURN_ERROR(p_FmMacControllerDriver, E_INVALID_HANDLE);
17144 +
17145 + if (p_FmMacControllerDriver->f_FM_MAC_SetTxPauseFrames)
17146 + return p_FmMacControllerDriver->f_FM_MAC_SetTxPauseFrames(h_FmMac,
17147 + priority,
17148 + pauseTime,
17149 + threshTime);
17150 +
17151 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, NO_MSG);
17152 +}
17153 +
17154 +/* ......................................................................... */
17155 +
17156 +t_Error FM_MAC_SetRxIgnorePauseFrames (t_Handle h_FmMac, bool en)
17157 +{
17158 + t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac;
17159 +
17160 + SANITY_CHECK_RETURN_ERROR(p_FmMacControllerDriver, E_INVALID_HANDLE);
17161 +
17162 + if (p_FmMacControllerDriver->f_FM_MAC_SetRxIgnorePauseFrames)
17163 + return p_FmMacControllerDriver->f_FM_MAC_SetRxIgnorePauseFrames(h_FmMac, en);
17164 +
17165 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
17166 +}
17167 +
17168 +/* ......................................................................... */
17169 +
17170 +t_Error FM_MAC_SetWakeOnLan (t_Handle h_FmMac, bool en)
17171 +{
17172 + t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac;
17173 +
17174 + SANITY_CHECK_RETURN_ERROR(p_FmMacControllerDriver, E_INVALID_HANDLE);
17175 +
17176 + if (p_FmMacControllerDriver->f_FM_MAC_SetWakeOnLan)
17177 + return p_FmMacControllerDriver->f_FM_MAC_SetWakeOnLan(h_FmMac, en);
17178 +
17179 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
17180 +}
17181 +
17182 +/* ......................................................................... */
17183 +
17184 +t_Error FM_MAC_ResetCounters (t_Handle h_FmMac)
17185 +{
17186 + t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac;
17187 +
17188 + SANITY_CHECK_RETURN_ERROR(p_FmMacControllerDriver, E_INVALID_HANDLE);
17189 +
17190 + if (p_FmMacControllerDriver->f_FM_MAC_ResetCounters)
17191 + return p_FmMacControllerDriver->f_FM_MAC_ResetCounters(h_FmMac);
17192 +
17193 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
17194 +}
17195 +
17196 +/* ......................................................................... */
17197 +
17198 +t_Error FM_MAC_SetException(t_Handle h_FmMac, e_FmMacExceptions ex, bool enable)
17199 +{
17200 + t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac;
17201 +
17202 + SANITY_CHECK_RETURN_ERROR(p_FmMacControllerDriver, E_INVALID_HANDLE);
17203 +
17204 + if (p_FmMacControllerDriver->f_FM_MAC_SetException)
17205 + return p_FmMacControllerDriver->f_FM_MAC_SetException(h_FmMac, ex, enable);
17206 +
17207 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
17208 +}
17209 +
17210 +/* ......................................................................... */
17211 +
17212 +t_Error FM_MAC_SetStatistics (t_Handle h_FmMac, e_FmMacStatisticsLevel statisticsLevel)
17213 +{
17214 + t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac;
17215 +
17216 + SANITY_CHECK_RETURN_ERROR(p_FmMacControllerDriver, E_INVALID_HANDLE);
17217 +
17218 + if (p_FmMacControllerDriver->f_FM_MAC_SetStatistics)
17219 + return p_FmMacControllerDriver->f_FM_MAC_SetStatistics(h_FmMac, statisticsLevel);
17220 +
17221 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
17222 +}
17223 +
17224 +/* ......................................................................... */
17225 +
17226 +t_Error FM_MAC_GetStatistics (t_Handle h_FmMac, t_FmMacStatistics *p_Statistics)
17227 +{
17228 + t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac;
17229 +
17230 + SANITY_CHECK_RETURN_ERROR(p_FmMacControllerDriver, E_INVALID_HANDLE);
17231 +
17232 + if (p_FmMacControllerDriver->f_FM_MAC_GetStatistics)
17233 + return p_FmMacControllerDriver->f_FM_MAC_GetStatistics(h_FmMac, p_Statistics);
17234 +
17235 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
17236 +}
17237 +
17238 +/* ......................................................................... */
17239 +
17240 +t_Error FM_MAC_GetFrameSizeCounters(t_Handle h_FmMac, t_FmMacFrameSizeCounters *p_FrameSizeCounters, e_CommMode type)
17241 +{
17242 + t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac;
17243 +
17244 + SANITY_CHECK_RETURN_ERROR(p_FmMacControllerDriver, E_INVALID_HANDLE);
17245 +
17246 + memset(p_FrameSizeCounters, 0, sizeof(t_FmMacFrameSizeCounters));
17247 +
17248 + if (p_FmMacControllerDriver->f_FM_MAC_GetFrameSizeCounters)
17249 + return p_FmMacControllerDriver->f_FM_MAC_GetFrameSizeCounters(h_FmMac, p_FrameSizeCounters, type);
17250 +
17251 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
17252 +}
17253 +
17254 +/* ......................................................................... */
17255 +
17256 +t_Error FM_MAC_ModifyMacAddr (t_Handle h_FmMac, t_EnetAddr *p_EnetAddr)
17257 +{
17258 + t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac;
17259 +
17260 + SANITY_CHECK_RETURN_ERROR(p_FmMacControllerDriver, E_INVALID_HANDLE);
17261 +
17262 + if (p_FmMacControllerDriver->f_FM_MAC_ModifyMacAddr)
17263 + return p_FmMacControllerDriver->f_FM_MAC_ModifyMacAddr(h_FmMac, p_EnetAddr);
17264 +
17265 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
17266 +}
17267 +
17268 +/* ......................................................................... */
17269 +
17270 +t_Error FM_MAC_AddHashMacAddr (t_Handle h_FmMac, t_EnetAddr *p_EnetAddr)
17271 +{
17272 + t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac;
17273 +
17274 + SANITY_CHECK_RETURN_ERROR(p_FmMacControllerDriver, E_INVALID_HANDLE);
17275 +
17276 + if (p_FmMacControllerDriver->f_FM_MAC_AddHashMacAddr)
17277 + return p_FmMacControllerDriver->f_FM_MAC_AddHashMacAddr(h_FmMac, p_EnetAddr);
17278 +
17279 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
17280 +}
17281 +
17282 +/* ......................................................................... */
17283 +
17284 +t_Error FM_MAC_RemoveHashMacAddr (t_Handle h_FmMac, t_EnetAddr *p_EnetAddr)
17285 +{
17286 + t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac;
17287 +
17288 + SANITY_CHECK_RETURN_ERROR(p_FmMacControllerDriver, E_INVALID_HANDLE);
17289 +
17290 + if (p_FmMacControllerDriver->f_FM_MAC_RemoveHashMacAddr)
17291 + return p_FmMacControllerDriver->f_FM_MAC_RemoveHashMacAddr(h_FmMac, p_EnetAddr);
17292 +
17293 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
17294 +}
17295 +
17296 +/* ......................................................................... */
17297 +
17298 +t_Error FM_MAC_AddExactMatchMacAddr (t_Handle h_FmMac, t_EnetAddr *p_EnetAddr)
17299 +{
17300 + t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac;
17301 +
17302 + SANITY_CHECK_RETURN_ERROR(p_FmMacControllerDriver, E_INVALID_HANDLE);
17303 +
17304 + if (p_FmMacControllerDriver->f_FM_MAC_AddExactMatchMacAddr)
17305 + return p_FmMacControllerDriver->f_FM_MAC_AddExactMatchMacAddr(h_FmMac, p_EnetAddr);
17306 +
17307 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
17308 +}
17309 +
17310 +/* ......................................................................... */
17311 +
17312 +t_Error FM_MAC_RemovelExactMatchMacAddr (t_Handle h_FmMac, t_EnetAddr *p_EnetAddr)
17313 +{
17314 + t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac;
17315 +
17316 + SANITY_CHECK_RETURN_ERROR(p_FmMacControllerDriver, E_INVALID_HANDLE);
17317 +
17318 + if (p_FmMacControllerDriver->f_FM_MAC_RemovelExactMatchMacAddr)
17319 + return p_FmMacControllerDriver->f_FM_MAC_RemovelExactMatchMacAddr(h_FmMac, p_EnetAddr);
17320 +
17321 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
17322 +}
17323 +
17324 +/* ......................................................................... */
17325 +
17326 +t_Error FM_MAC_GetVesrion (t_Handle h_FmMac, uint32_t *macVresion)
17327 +{
17328 + t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac;
17329 +
17330 + SANITY_CHECK_RETURN_ERROR(p_FmMacControllerDriver, E_INVALID_HANDLE);
17331 +
17332 + if (p_FmMacControllerDriver->f_FM_MAC_GetVersion)
17333 + return p_FmMacControllerDriver->f_FM_MAC_GetVersion(h_FmMac, macVresion);
17334 +
17335 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
17336 +
17337 +}
17338 +
17339 +/* ......................................................................... */
17340 +
17341 +t_Error FM_MAC_GetId (t_Handle h_FmMac, uint32_t *macId)
17342 +{
17343 + t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac;
17344 +
17345 + SANITY_CHECK_RETURN_ERROR(p_FmMacControllerDriver, E_INVALID_HANDLE);
17346 +
17347 + if (p_FmMacControllerDriver->f_FM_MAC_GetId)
17348 + return p_FmMacControllerDriver->f_FM_MAC_GetId(h_FmMac, macId);
17349 +
17350 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
17351 +}
17352 +
17353 +/* ......................................................................... */
17354 +
17355 +t_Error FM_MAC_SetPromiscuous (t_Handle h_FmMac, bool newVal)
17356 +{
17357 + t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac;
17358 +
17359 + SANITY_CHECK_RETURN_ERROR(p_FmMacControllerDriver, E_INVALID_HANDLE);
17360 +
17361 + if (p_FmMacControllerDriver->f_FM_MAC_SetPromiscuous)
17362 + return p_FmMacControllerDriver->f_FM_MAC_SetPromiscuous(h_FmMac, newVal);
17363 +
17364 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
17365 +}
17366 +
17367 +/* ......................................................................... */
17368 +
17369 +t_Error FM_MAC_AdjustLink(t_Handle h_FmMac, e_EnetSpeed speed, bool fullDuplex)
17370 +{
17371 + t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac;
17372 +
17373 + SANITY_CHECK_RETURN_ERROR(p_FmMacControllerDriver, E_INVALID_HANDLE);
17374 +
17375 + if (p_FmMacControllerDriver->f_FM_MAC_AdjustLink)
17376 + return p_FmMacControllerDriver->f_FM_MAC_AdjustLink(h_FmMac, speed, fullDuplex);
17377 +
17378 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
17379 +}
17380 +
17381 +/* ......................................................................... */
17382 +
17383 +t_Error FM_MAC_RestartAutoneg(t_Handle h_FmMac)
17384 +{
17385 + t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac;
17386 +
17387 + SANITY_CHECK_RETURN_ERROR(p_FmMacControllerDriver, E_INVALID_HANDLE);
17388 +
17389 + if (p_FmMacControllerDriver->f_FM_MAC_RestartAutoneg)
17390 + return p_FmMacControllerDriver->f_FM_MAC_RestartAutoneg(h_FmMac);
17391 +
17392 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
17393 +}
17394 +
17395 +/* ......................................................................... */
17396 +
17397 +t_Error FM_MAC_MII_WritePhyReg (t_Handle h_FmMac, uint8_t phyAddr, uint8_t reg, uint16_t data)
17398 +{
17399 + t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac;
17400 +
17401 + SANITY_CHECK_RETURN_ERROR(p_FmMacControllerDriver, E_INVALID_HANDLE);
17402 +
17403 + if (p_FmMacControllerDriver->f_FM_MAC_MII_WritePhyReg)
17404 + return p_FmMacControllerDriver->f_FM_MAC_MII_WritePhyReg(h_FmMac, phyAddr, reg, data);
17405 +
17406 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
17407 +}
17408 +
17409 +/* ......................................................................... */
17410 +
17411 +t_Error FM_MAC_MII_ReadPhyReg(t_Handle h_FmMac, uint8_t phyAddr, uint8_t reg, uint16_t *p_Data)
17412 +{
17413 + t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac;
17414 +
17415 + SANITY_CHECK_RETURN_ERROR(p_FmMacControllerDriver, E_INVALID_HANDLE);
17416 +
17417 + if (p_FmMacControllerDriver->f_FM_MAC_MII_ReadPhyReg)
17418 + return p_FmMacControllerDriver->f_FM_MAC_MII_ReadPhyReg(h_FmMac, phyAddr, reg, p_Data);
17419 +
17420 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
17421 +}
17422 +
17423 +/* ......................................................................... */
17424 +
17425 +uint16_t FM_MAC_GetMaxFrameLength(t_Handle h_FmMac)
17426 +{
17427 + t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac;
17428 +
17429 + SANITY_CHECK_RETURN_VALUE(p_FmMacControllerDriver, E_INVALID_HANDLE, 0);
17430 +
17431 + if (p_FmMacControllerDriver->f_FM_MAC_GetMaxFrameLength)
17432 + return p_FmMacControllerDriver->f_FM_MAC_GetMaxFrameLength(h_FmMac);
17433 +
17434 + REPORT_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
17435 + return 0;
17436 +}
17437 +
17438 +#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
17439 +/*****************************************************************************/
17440 +t_Error FM_MAC_DumpRegs(t_Handle h_FmMac)
17441 +{
17442 + t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac;
17443 +
17444 + SANITY_CHECK_RETURN_ERROR(p_FmMacControllerDriver, E_INVALID_HANDLE);
17445 +
17446 + if (p_FmMacControllerDriver->f_FM_MAC_DumpRegs)
17447 + return p_FmMacControllerDriver->f_FM_MAC_DumpRegs(h_FmMac);
17448 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
17449 +}
17450 +#endif /* (defined(DEBUG_ERRORS) && ... */
17451 --- /dev/null
17452 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/fm_mac.h
17453 @@ -0,0 +1,226 @@
17454 +/*
17455 + * Copyright 2008-2012 Freescale Semiconductor Inc.
17456 + *
17457 + * Redistribution and use in source and binary forms, with or without
17458 + * modification, are permitted provided that the following conditions are met:
17459 + * * Redistributions of source code must retain the above copyright
17460 + * notice, this list of conditions and the following disclaimer.
17461 + * * Redistributions in binary form must reproduce the above copyright
17462 + * notice, this list of conditions and the following disclaimer in the
17463 + * documentation and/or other materials provided with the distribution.
17464 + * * Neither the name of Freescale Semiconductor nor the
17465 + * names of its contributors may be used to endorse or promote products
17466 + * derived from this software without specific prior written permission.
17467 + *
17468 + *
17469 + * ALTERNATIVELY, this software may be distributed under the terms of the
17470 + * GNU General Public License ("GPL") as published by the Free Software
17471 + * Foundation, either version 2 of that License or (at your option) any
17472 + * later version.
17473 + *
17474 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
17475 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
17476 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
17477 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
17478 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
17479 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
17480 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
17481 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
17482 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
17483 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
17484 + */
17485 +
17486 +
17487 +/******************************************************************************
17488 + @File fm_mac.h
17489 +
17490 + @Description FM MAC ...
17491 +*//***************************************************************************/
17492 +#ifndef __FM_MAC_H
17493 +#define __FM_MAC_H
17494 +
17495 +#include "std_ext.h"
17496 +#include "error_ext.h"
17497 +#include "list_ext.h"
17498 +#include "fm_mac_ext.h"
17499 +#include "fm_common.h"
17500 +
17501 +
17502 +#define __ERR_MODULE__ MODULE_FM_MAC
17503 +
17504 +/**************************************************************************//**
17505 + @Description defaults
17506 +*//***************************************************************************/
17507 +
17508 +
17509 +#define DEFAULT_halfDuplex FALSE
17510 +#define DEFAULT_padAndCrcEnable TRUE
17511 +#define DEFAULT_resetOnInit FALSE
17512 +
17513 +
17514 +typedef struct {
17515 + uint64_t addr; /* Ethernet Address */
17516 + t_List node;
17517 +} t_EthHashEntry;
17518 +#define ETH_HASH_ENTRY_OBJ(ptr) LIST_OBJECT(ptr, t_EthHashEntry, node)
17519 +
17520 +typedef struct {
17521 + uint16_t size;
17522 + t_List *p_Lsts;
17523 +} t_EthHash;
17524 +
17525 +typedef struct {
17526 + t_Error (*f_FM_MAC_Init) (t_Handle h_FmMac);
17527 + t_Error (*f_FM_MAC_Free) (t_Handle h_FmMac);
17528 +
17529 + t_Error (*f_FM_MAC_SetStatistics) (t_Handle h_FmMac, e_FmMacStatisticsLevel statisticsLevel);
17530 + t_Error (*f_FM_MAC_ConfigLoopback) (t_Handle h_FmMac, bool newVal);
17531 + t_Error (*f_FM_MAC_ConfigMaxFrameLength) (t_Handle h_FmMac, uint16_t newVal);
17532 + t_Error (*f_FM_MAC_ConfigWan) (t_Handle h_FmMac, bool flag);
17533 + t_Error (*f_FM_MAC_ConfigPadAndCrc) (t_Handle h_FmMac, bool newVal);
17534 + t_Error (*f_FM_MAC_ConfigHalfDuplex) (t_Handle h_FmMac, bool newVal);
17535 + t_Error (*f_FM_MAC_ConfigLengthCheck) (t_Handle h_FmMac, bool newVal);
17536 + t_Error (*f_FM_MAC_ConfigTbiPhyAddr) (t_Handle h_FmMac, uint8_t newVal);
17537 + t_Error (*f_FM_MAC_ConfigException) (t_Handle h_FmMac, e_FmMacExceptions, bool enable);
17538 + t_Error (*f_FM_MAC_ConfigResetOnInit) (t_Handle h_FmMac, bool enable);
17539 +#ifdef FM_TX_ECC_FRMS_ERRATA_10GMAC_A004
17540 + t_Error (*f_FM_MAC_ConfigSkipFman11Workaround) (t_Handle h_FmMac);
17541 +#endif /* FM_TX_ECC_FRMS_ERRATA_10GMAC_A004 */
17542 +
17543 + t_Error (*f_FM_MAC_SetException) (t_Handle h_FmMac, e_FmMacExceptions ex, bool enable);
17544 +
17545 + t_Error (*f_FM_MAC_Enable) (t_Handle h_FmMac, e_CommMode mode);
17546 + t_Error (*f_FM_MAC_Disable) (t_Handle h_FmMac, e_CommMode mode);
17547 + t_Error (*f_FM_MAC_Resume) (t_Handle h_FmMac);
17548 + t_Error (*f_FM_MAC_Enable1588TimeStamp) (t_Handle h_FmMac);
17549 + t_Error (*f_FM_MAC_Disable1588TimeStamp) (t_Handle h_FmMac);
17550 + t_Error (*f_FM_MAC_Reset) (t_Handle h_FmMac, bool wait);
17551 +
17552 + t_Error (*f_FM_MAC_SetTxAutoPauseFrames) (t_Handle h_FmMac,
17553 + uint16_t pauseTime);
17554 + t_Error (*f_FM_MAC_SetTxPauseFrames) (t_Handle h_FmMac,
17555 + uint8_t priority,
17556 + uint16_t pauseTime,
17557 + uint16_t threshTime);
17558 + t_Error (*f_FM_MAC_SetRxIgnorePauseFrames) (t_Handle h_FmMac, bool en);
17559 +
17560 + t_Error (*f_FM_MAC_ResetCounters) (t_Handle h_FmMac);
17561 + t_Error (*f_FM_MAC_GetStatistics) (t_Handle h_FmMac, t_FmMacStatistics *p_Statistics);
17562 + t_Error (*f_FM_MAC_GetFrameSizeCounters) (t_Handle h_FmMac, t_FmMacFrameSizeCounters *p_FrameSizeCounters, e_CommMode type);
17563 +
17564 + t_Error (*f_FM_MAC_ModifyMacAddr) (t_Handle h_FmMac, t_EnetAddr *p_EnetAddr);
17565 + t_Error (*f_FM_MAC_AddHashMacAddr) (t_Handle h_FmMac, t_EnetAddr *p_EnetAddr);
17566 + t_Error (*f_FM_MAC_RemoveHashMacAddr) (t_Handle h_FmMac, t_EnetAddr *p_EnetAddr);
17567 + t_Error (*f_FM_MAC_AddExactMatchMacAddr) (t_Handle h_FmMac, t_EnetAddr *p_EnetAddr);
17568 + t_Error (*f_FM_MAC_RemovelExactMatchMacAddr) (t_Handle h_FmMac, t_EnetAddr *p_EnetAddr);
17569 +
17570 + t_Error (*f_FM_MAC_SetPromiscuous) (t_Handle h_FmMac, bool newVal);
17571 + t_Error (*f_FM_MAC_AdjustLink) (t_Handle h_FmMac, e_EnetSpeed speed, bool fullDuplex);
17572 + t_Error (*f_FM_MAC_RestartAutoneg) (t_Handle h_FmMac);
17573 +
17574 + t_Error (*f_FM_MAC_SetWakeOnLan) (t_Handle h_FmMac, bool en);
17575 +
17576 + t_Error (*f_FM_MAC_GetId) (t_Handle h_FmMac, uint32_t *macId);
17577 +
17578 + t_Error (*f_FM_MAC_GetVersion) (t_Handle h_FmMac, uint32_t *macVersion);
17579 +
17580 + uint16_t (*f_FM_MAC_GetMaxFrameLength) (t_Handle h_FmMac);
17581 +
17582 + t_Error (*f_FM_MAC_MII_WritePhyReg)(t_Handle h_FmMac, uint8_t phyAddr, uint8_t reg, uint16_t data);
17583 + t_Error (*f_FM_MAC_MII_ReadPhyReg)(t_Handle h_FmMac, uint8_t phyAddr, uint8_t reg, uint16_t *p_Data);
17584 +
17585 +#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
17586 + t_Error (*f_FM_MAC_DumpRegs) (t_Handle h_FmMac);
17587 +#endif /* (defined(DEBUG_ERRORS) && ... */
17588 +
17589 + t_Handle h_Fm;
17590 + t_FmRevisionInfo fmRevInfo;
17591 + e_EnetMode enetMode;
17592 + uint8_t macId;
17593 + bool resetOnInit;
17594 + uint16_t clkFreq;
17595 +} t_FmMacControllerDriver;
17596 +
17597 +
17598 +#if (DPAA_VERSION == 10)
17599 +t_Handle DTSEC_Config(t_FmMacParams *p_FmMacParam);
17600 +t_Handle TGEC_Config(t_FmMacParams *p_FmMacParams);
17601 +#else
17602 +t_Handle MEMAC_Config(t_FmMacParams *p_FmMacParam);
17603 +#endif /* (DPAA_VERSION == 10) */
17604 +uint16_t FM_MAC_GetMaxFrameLength(t_Handle FmMac);
17605 +
17606 +
17607 +/* ........................................................................... */
17608 +
17609 +static __inline__ t_EthHashEntry *DequeueAddrFromHashEntry(t_List *p_AddrLst)
17610 +{
17611 + t_EthHashEntry *p_HashEntry = NULL;
17612 + if (!LIST_IsEmpty(p_AddrLst))
17613 + {
17614 + p_HashEntry = ETH_HASH_ENTRY_OBJ(p_AddrLst->p_Next);
17615 + LIST_DelAndInit(&p_HashEntry->node);
17616 + }
17617 + return p_HashEntry;
17618 +}
17619 +
17620 +/* ........................................................................... */
17621 +
17622 +static __inline__ void FreeHashTable(t_EthHash *p_Hash)
17623 +{
17624 + t_EthHashEntry *p_HashEntry;
17625 + int i = 0;
17626 +
17627 + if (p_Hash)
17628 + {
17629 + if (p_Hash->p_Lsts)
17630 + {
17631 + for (i=0; i<p_Hash->size; i++)
17632 + {
17633 + p_HashEntry = DequeueAddrFromHashEntry(&p_Hash->p_Lsts[i]);
17634 + while (p_HashEntry)
17635 + {
17636 + XX_Free(p_HashEntry);
17637 + p_HashEntry = DequeueAddrFromHashEntry(&p_Hash->p_Lsts[i]);
17638 + }
17639 + }
17640 +
17641 + XX_Free(p_Hash->p_Lsts);
17642 + }
17643 +
17644 + XX_Free(p_Hash);
17645 + }
17646 +}
17647 +
17648 +/* ........................................................................... */
17649 +
17650 +static __inline__ t_EthHash * AllocHashTable(uint16_t size)
17651 +{
17652 + uint32_t i;
17653 + t_EthHash *p_Hash;
17654 +
17655 + /* Allocate address hash table */
17656 + p_Hash = (t_EthHash *)XX_Malloc(sizeof(t_EthHash));
17657 + if (!p_Hash)
17658 + {
17659 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("Address hash table"));
17660 + return NULL;
17661 + }
17662 + p_Hash->size = size;
17663 +
17664 + p_Hash->p_Lsts = (t_List *)XX_Malloc(p_Hash->size*sizeof(t_List));
17665 + if (!p_Hash->p_Lsts)
17666 + {
17667 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("Address hash table"));
17668 + XX_Free(p_Hash);
17669 + return NULL;
17670 + }
17671 +
17672 + for (i=0 ; i<p_Hash->size; i++)
17673 + INIT_LIST(&p_Hash->p_Lsts[i]);
17674 +
17675 + return p_Hash;
17676 +}
17677 +
17678 +
17679 +#endif /* __FM_MAC_H */
17680 --- /dev/null
17681 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/fman_crc32.c
17682 @@ -0,0 +1,119 @@
17683 +/*
17684 + * Copyright 2008-2012 Freescale Semiconductor Inc.
17685 + *
17686 + * Redistribution and use in source and binary forms, with or without
17687 + * modification, are permitted provided that the following conditions are met:
17688 + * * Redistributions of source code must retain the above copyright
17689 + * notice, this list of conditions and the following disclaimer.
17690 + * * Redistributions in binary form must reproduce the above copyright
17691 + * notice, this list of conditions and the following disclaimer in the
17692 + * documentation and/or other materials provided with the distribution.
17693 + * * Neither the name of Freescale Semiconductor nor the
17694 + * names of its contributors may be used to endorse or promote products
17695 + * derived from this software without specific prior written permission.
17696 + *
17697 + *
17698 + * ALTERNATIVELY, this software may be distributed under the terms of the
17699 + * GNU General Public License ("GPL") as published by the Free Software
17700 + * Foundation, either version 2 of that License or (at your option) any
17701 + * later version.
17702 + *
17703 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
17704 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
17705 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
17706 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
17707 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
17708 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
17709 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
17710 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
17711 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
17712 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
17713 + */
17714 +
17715 +
17716 +#include "fman_crc32.h"
17717 +#include "common/general.h"
17718 +
17719 +
17720 +/* precomputed CRC values for address hashing */
17721 +static const uint32_t crc_tbl[256] = {
17722 + 0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f,
17723 + 0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988,
17724 + 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91, 0x1db71064, 0x6ab020f2,
17725 + 0xf3b97148, 0x84be41de, 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7,
17726 + 0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9,
17727 + 0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172,
17728 + 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, 0x35b5a8fa, 0x42b2986c,
17729 + 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59,
17730 + 0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423,
17731 + 0xcfba9599, 0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924,
17732 + 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190, 0x01db7106,
17733 + 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433,
17734 + 0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d,
17735 + 0x91646c97, 0xe6635c01, 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e,
17736 + 0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950,
17737 + 0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65,
17738 + 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, 0x4adfa541, 0x3dd895d7,
17739 + 0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0,
17740 + 0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa,
17741 + 0xbe0b1010, 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,
17742 + 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, 0x2eb40d81,
17743 + 0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a,
17744 + 0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683, 0xe3630b12, 0x94643b84,
17745 + 0x0d6d6a3e, 0x7a6a5aa8, 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1,
17746 + 0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb,
17747 + 0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc,
17748 + 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, 0xd6d6a3e8, 0xa1d1937e,
17749 + 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b,
17750 + 0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55,
17751 + 0x316e8eef, 0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236,
17752 + 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe, 0xb2bd0b28,
17753 + 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d,
17754 + 0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, 0x9c0906a9, 0xeb0e363f,
17755 + 0x72076785, 0x05005713, 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38,
17756 + 0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242,
17757 + 0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777,
17758 + 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, 0x8f659eff, 0xf862ae69,
17759 + 0x616bffd3, 0x166ccf45, 0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2,
17760 + 0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc,
17761 + 0x40df0b66, 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,
17762 + 0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, 0xcdd70693,
17763 + 0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94,
17764 + 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d
17765 +};
17766 +
17767 +/* Get the mirrored value of a byte size number. (0x11010011 --> 0x11001011) */
17768 +static inline uint8_t get_mirror8(uint8_t n)
17769 +{
17770 + uint8_t mirror[16] = {
17771 + 0x00, 0x08, 0x04, 0x0c, 0x02, 0x0a, 0x06, 0x0e,
17772 + 0x01, 0x09, 0x05, 0x0d, 0x03, 0x0b, 0x07, 0x0f
17773 + };
17774 + return (uint8_t)(((mirror[n & 0x0f] << 4) | (mirror[n >> 4])));
17775 +}
17776 +
17777 +static inline uint32_t get_mirror32(uint32_t n)
17778 +{
17779 + return ((uint32_t)get_mirror8((uint8_t)(n))<<24) |
17780 + ((uint32_t)get_mirror8((uint8_t)(n>>8))<<16) |
17781 + ((uint32_t)get_mirror8((uint8_t)(n>>16))<<8) |
17782 + ((uint32_t)get_mirror8((uint8_t)(n>>24)));
17783 +}
17784 +
17785 +uint32_t get_mac_addr_crc(uint64_t _addr)
17786 +{
17787 + uint32_t i;
17788 + uint8_t data;
17789 + uint32_t crc;
17790 +
17791 + /* CRC calculation */
17792 + crc = 0xffffffff;
17793 + for (i = 0; i < 6; i++) {
17794 + data = (uint8_t)(_addr >> ((5-i)*8));
17795 + crc = crc ^ data;
17796 + crc = crc_tbl[crc&0xff] ^ (crc>>8);
17797 + }
17798 +
17799 + crc = get_mirror32(crc);
17800 + return crc;
17801 +}
17802 --- /dev/null
17803 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/fman_crc32.h
17804 @@ -0,0 +1,43 @@
17805 +/*
17806 + * Copyright 2008-2012 Freescale Semiconductor Inc.
17807 + *
17808 + * Redistribution and use in source and binary forms, with or without
17809 + * modification, are permitted provided that the following conditions are met:
17810 + * * Redistributions of source code must retain the above copyright
17811 + * notice, this list of conditions and the following disclaimer.
17812 + * * Redistributions in binary form must reproduce the above copyright
17813 + * notice, this list of conditions and the following disclaimer in the
17814 + * documentation and/or other materials provided with the distribution.
17815 + * * Neither the name of Freescale Semiconductor nor the
17816 + * names of its contributors may be used to endorse or promote products
17817 + * derived from this software without specific prior written permission.
17818 + *
17819 + *
17820 + * ALTERNATIVELY, this software may be distributed under the terms of the
17821 + * GNU General Public License ("GPL") as published by the Free Software
17822 + * Foundation, either version 2 of that License or (at your option) any
17823 + * later version.
17824 + *
17825 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
17826 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
17827 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
17828 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
17829 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
17830 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
17831 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
17832 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
17833 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
17834 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
17835 + */
17836 +
17837 +
17838 +#ifndef __FMAN_CRC32_H
17839 +#define __FMAN_CRC32_H
17840 +
17841 +#include "common/general.h"
17842 +
17843 +
17844 +uint32_t get_mac_addr_crc(uint64_t _addr);
17845 +
17846 +
17847 +#endif /* __FMAN_CRC32_H */
17848 --- /dev/null
17849 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/fman_dtsec.c
17850 @@ -0,0 +1,845 @@
17851 +/*
17852 + * Copyright 2008-2012 Freescale Semiconductor Inc.
17853 + *
17854 + * Redistribution and use in source and binary forms, with or without
17855 + * modification, are permitted provided that the following conditions are met:
17856 + * * Redistributions of source code must retain the above copyright
17857 + * notice, this list of conditions and the following disclaimer.
17858 + * * Redistributions in binary form must reproduce the above copyright
17859 + * notice, this list of conditions and the following disclaimer in the
17860 + * documentation and/or other materials provided with the distribution.
17861 + * * Neither the name of Freescale Semiconductor nor the
17862 + * names of its contributors may be used to endorse or promote products
17863 + * derived from this software without specific prior written permission.
17864 + *
17865 + *
17866 + * ALTERNATIVELY, this software may be distributed under the terms of the
17867 + * GNU General Public License ("GPL") as published by the Free Software
17868 + * Foundation, either version 2 of that License or (at your option) any
17869 + * later version.
17870 + *
17871 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
17872 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
17873 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
17874 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
17875 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
17876 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
17877 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
17878 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
17879 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
17880 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
17881 + */
17882 +
17883 +
17884 +#include "fsl_fman_dtsec.h"
17885 +
17886 +
17887 +void fman_dtsec_stop_rx(struct dtsec_regs *regs)
17888 +{
17889 + /* Assert the graceful stop bit */
17890 + iowrite32be(ioread32be(&regs->rctrl) | RCTRL_GRS, &regs->rctrl);
17891 +}
17892 +
17893 +void fman_dtsec_stop_tx(struct dtsec_regs *regs)
17894 +{
17895 + /* Assert the graceful stop bit */
17896 + iowrite32be(ioread32be(&regs->tctrl) | DTSEC_TCTRL_GTS, &regs->tctrl);
17897 +}
17898 +
17899 +void fman_dtsec_start_tx(struct dtsec_regs *regs)
17900 +{
17901 + /* clear the graceful stop bit */
17902 + iowrite32be(ioread32be(&regs->tctrl) & ~DTSEC_TCTRL_GTS, &regs->tctrl);
17903 +}
17904 +
17905 +void fman_dtsec_start_rx(struct dtsec_regs *regs)
17906 +{
17907 + /* clear the graceful stop bit */
17908 + iowrite32be(ioread32be(&regs->rctrl) & ~RCTRL_GRS, &regs->rctrl);
17909 +}
17910 +
17911 +void fman_dtsec_defconfig(struct dtsec_cfg *cfg)
17912 +{
17913 + cfg->halfdup_on = DEFAULT_HALFDUP_ON;
17914 + cfg->halfdup_retransmit = DEFAULT_HALFDUP_RETRANSMIT;
17915 + cfg->halfdup_coll_window = DEFAULT_HALFDUP_COLL_WINDOW;
17916 + cfg->halfdup_excess_defer = DEFAULT_HALFDUP_EXCESS_DEFER;
17917 + cfg->halfdup_no_backoff = DEFAULT_HALFDUP_NO_BACKOFF;
17918 + cfg->halfdup_bp_no_backoff = DEFAULT_HALFDUP_BP_NO_BACKOFF;
17919 + cfg->halfdup_alt_backoff_val = DEFAULT_HALFDUP_ALT_BACKOFF_VAL;
17920 + cfg->halfdup_alt_backoff_en = DEFAULT_HALFDUP_ALT_BACKOFF_EN;
17921 + cfg->rx_drop_bcast = DEFAULT_RX_DROP_BCAST;
17922 + cfg->rx_short_frm = DEFAULT_RX_SHORT_FRM;
17923 + cfg->rx_len_check = DEFAULT_RX_LEN_CHECK;
17924 + cfg->tx_pad_crc = DEFAULT_TX_PAD_CRC;
17925 + cfg->tx_crc = DEFAULT_TX_CRC;
17926 + cfg->rx_ctrl_acc = DEFAULT_RX_CTRL_ACC;
17927 + cfg->tx_pause_time = DEFAULT_TX_PAUSE_TIME;
17928 + cfg->tbipa = DEFAULT_TBIPA; /* PHY address 0 is reserved (DPAA RM)*/
17929 + cfg->rx_prepend = DEFAULT_RX_PREPEND;
17930 + cfg->ptp_tsu_en = DEFAULT_PTP_TSU_EN;
17931 + cfg->ptp_exception_en = DEFAULT_PTP_EXCEPTION_EN;
17932 + cfg->preamble_len = DEFAULT_PREAMBLE_LEN;
17933 + cfg->rx_preamble = DEFAULT_RX_PREAMBLE;
17934 + cfg->tx_preamble = DEFAULT_TX_PREAMBLE;
17935 + cfg->loopback = DEFAULT_LOOPBACK;
17936 + cfg->rx_time_stamp_en = DEFAULT_RX_TIME_STAMP_EN;
17937 + cfg->tx_time_stamp_en = DEFAULT_TX_TIME_STAMP_EN;
17938 + cfg->rx_flow = DEFAULT_RX_FLOW;
17939 + cfg->tx_flow = DEFAULT_TX_FLOW;
17940 + cfg->rx_group_hash_exd = DEFAULT_RX_GROUP_HASH_EXD;
17941 + cfg->tx_pause_time_extd = DEFAULT_TX_PAUSE_TIME_EXTD;
17942 + cfg->rx_promisc = DEFAULT_RX_PROMISC;
17943 + cfg->non_back_to_back_ipg1 = DEFAULT_NON_BACK_TO_BACK_IPG1;
17944 + cfg->non_back_to_back_ipg2 = DEFAULT_NON_BACK_TO_BACK_IPG2;
17945 + cfg->min_ifg_enforcement = DEFAULT_MIN_IFG_ENFORCEMENT;
17946 + cfg->back_to_back_ipg = DEFAULT_BACK_TO_BACK_IPG;
17947 + cfg->maximum_frame = DEFAULT_MAXIMUM_FRAME;
17948 + cfg->tbi_phy_addr = DEFAULT_TBI_PHY_ADDR;
17949 + cfg->wake_on_lan = DEFAULT_WAKE_ON_LAN;
17950 +}
17951 +
17952 +int fman_dtsec_init(struct dtsec_regs *regs, struct dtsec_cfg *cfg,
17953 + enum enet_interface iface_mode,
17954 + enum enet_speed iface_speed,
17955 + uint8_t *macaddr,
17956 + uint8_t fm_rev_maj,
17957 + uint8_t fm_rev_min,
17958 + uint32_t exception_mask)
17959 +{
17960 + bool is_rgmii = FALSE;
17961 + bool is_sgmii = FALSE;
17962 + bool is_qsgmii = FALSE;
17963 + int i;
17964 + uint32_t tmp;
17965 +
17966 +UNUSED(fm_rev_maj);UNUSED(fm_rev_min);
17967 +
17968 + /* let's start with a soft reset */
17969 + iowrite32be(MACCFG1_SOFT_RESET, &regs->maccfg1);
17970 + iowrite32be(0, &regs->maccfg1);
17971 +
17972 + /*************dtsec_id2******************/
17973 + tmp = ioread32be(&regs->tsec_id2);
17974 +
17975 + /* check RGMII support */
17976 + if (iface_mode == E_ENET_IF_RGMII ||
17977 + iface_mode == E_ENET_IF_RMII)
17978 + if (tmp & DTSEC_ID2_INT_REDUCED_OFF)
17979 + return -EINVAL;
17980 +
17981 + if (iface_mode == E_ENET_IF_SGMII ||
17982 + iface_mode == E_ENET_IF_MII)
17983 + if (tmp & DTSEC_ID2_INT_REDUCED_OFF)
17984 + return -EINVAL;
17985 +
17986 + /***************ECNTRL************************/
17987 +
17988 + is_rgmii = (bool)((iface_mode == E_ENET_IF_RGMII) ? TRUE : FALSE);
17989 + is_sgmii = (bool)((iface_mode == E_ENET_IF_SGMII) ? TRUE : FALSE);
17990 + is_qsgmii = (bool)((iface_mode == E_ENET_IF_QSGMII) ? TRUE : FALSE);
17991 +
17992 + tmp = 0;
17993 + if (is_rgmii || iface_mode == E_ENET_IF_GMII)
17994 + tmp |= DTSEC_ECNTRL_GMIIM;
17995 + if (is_sgmii)
17996 + tmp |= (DTSEC_ECNTRL_SGMIIM | DTSEC_ECNTRL_TBIM);
17997 + if (is_qsgmii)
17998 + tmp |= (DTSEC_ECNTRL_SGMIIM | DTSEC_ECNTRL_TBIM |
17999 + DTSEC_ECNTRL_QSGMIIM);
18000 + if (is_rgmii)
18001 + tmp |= DTSEC_ECNTRL_RPM;
18002 + if (iface_speed == E_ENET_SPEED_100)
18003 + tmp |= DTSEC_ECNTRL_R100M;
18004 +
18005 + iowrite32be(tmp, &regs->ecntrl);
18006 + /***************ECNTRL************************/
18007 +
18008 + /***************TCTRL************************/
18009 + tmp = 0;
18010 + if (cfg->halfdup_on)
18011 + tmp |= DTSEC_TCTRL_THDF;
18012 + if (cfg->tx_time_stamp_en)
18013 + tmp |= DTSEC_TCTRL_TTSE;
18014 +
18015 + iowrite32be(tmp, &regs->tctrl);
18016 +
18017 + /***************TCTRL************************/
18018 +
18019 + /***************PTV************************/
18020 + tmp = 0;
18021 +
18022 +#ifdef FM_SHORT_PAUSE_TIME_ERRATA_DTSEC1
18023 + if ((fm_rev_maj == 1) && (fm_rev_min == 0))
18024 + cfg->tx_pause_time += 2;
18025 +#endif /* FM_SHORT_PAUSE_TIME_ERRATA_DTSEC1 */
18026 +
18027 + if (cfg->tx_pause_time)
18028 + tmp |= cfg->tx_pause_time;
18029 + if (cfg->tx_pause_time_extd)
18030 + tmp |= cfg->tx_pause_time_extd << PTV_PTE_OFST;
18031 + iowrite32be(tmp, &regs->ptv);
18032 +
18033 + /***************RCTRL************************/
18034 + tmp = 0;
18035 + tmp |= ((uint32_t)(cfg->rx_prepend & 0x0000001f)) << 16;
18036 + if (cfg->rx_ctrl_acc)
18037 + tmp |= RCTRL_CFA;
18038 + if (cfg->rx_group_hash_exd)
18039 + tmp |= RCTRL_GHTX;
18040 + if (cfg->rx_time_stamp_en)
18041 + tmp |= RCTRL_RTSE;
18042 + if (cfg->rx_drop_bcast)
18043 + tmp |= RCTRL_BC_REJ;
18044 + if (cfg->rx_short_frm)
18045 + tmp |= RCTRL_RSF;
18046 + if (cfg->rx_promisc)
18047 + tmp |= RCTRL_PROM;
18048 +
18049 + iowrite32be(tmp, &regs->rctrl);
18050 + /***************RCTRL************************/
18051 +
18052 + /*
18053 + * Assign a Phy Address to the TBI (TBIPA).
18054 + * Done also in cases where TBI is not selected to avoid conflict with
18055 + * the external PHY's Physical address
18056 + */
18057 + iowrite32be(cfg->tbipa, &regs->tbipa);
18058 +
18059 + /***************TMR_CTL************************/
18060 + iowrite32be(0, &regs->tmr_ctrl);
18061 +
18062 + if (cfg->ptp_tsu_en) {
18063 + tmp = 0;
18064 + tmp |= TMR_PEVENT_TSRE;
18065 + iowrite32be(tmp, &regs->tmr_pevent);
18066 +
18067 + if (cfg->ptp_exception_en) {
18068 + tmp = 0;
18069 + tmp |= TMR_PEMASK_TSREEN;
18070 + iowrite32be(tmp, &regs->tmr_pemask);
18071 + }
18072 + }
18073 +
18074 + /***************MACCFG1***********************/
18075 + tmp = 0;
18076 + if (cfg->loopback)
18077 + tmp |= MACCFG1_LOOPBACK;
18078 + if (cfg->rx_flow)
18079 + tmp |= MACCFG1_RX_FLOW;
18080 + if (cfg->tx_flow)
18081 + tmp |= MACCFG1_TX_FLOW;
18082 + iowrite32be(tmp, &regs->maccfg1);
18083 +
18084 + /***************MACCFG1***********************/
18085 +
18086 + /***************MACCFG2***********************/
18087 + tmp = 0;
18088 +
18089 + if (iface_speed < E_ENET_SPEED_1000)
18090 + tmp |= MACCFG2_NIBBLE_MODE;
18091 + else if (iface_speed == E_ENET_SPEED_1000)
18092 + tmp |= MACCFG2_BYTE_MODE;
18093 +
18094 + tmp |= ((uint32_t) cfg->preamble_len & 0x0000000f)
18095 + << PREAMBLE_LENGTH_SHIFT;
18096 +
18097 + if (cfg->rx_preamble)
18098 + tmp |= MACCFG2_PRE_AM_Rx_EN;
18099 + if (cfg->tx_preamble)
18100 + tmp |= MACCFG2_PRE_AM_Tx_EN;
18101 + if (cfg->rx_len_check)
18102 + tmp |= MACCFG2_LENGTH_CHECK;
18103 + if (cfg->tx_pad_crc)
18104 + tmp |= MACCFG2_PAD_CRC_EN;
18105 + if (cfg->tx_crc)
18106 + tmp |= MACCFG2_CRC_EN;
18107 + if (!cfg->halfdup_on)
18108 + tmp |= MACCFG2_FULL_DUPLEX;
18109 + iowrite32be(tmp, &regs->maccfg2);
18110 +
18111 + /***************MACCFG2***********************/
18112 +
18113 + /***************IPGIFG************************/
18114 + tmp = (((cfg->non_back_to_back_ipg1 <<
18115 + IPGIFG_NON_BACK_TO_BACK_IPG_1_SHIFT)
18116 + & IPGIFG_NON_BACK_TO_BACK_IPG_1)
18117 + | ((cfg->non_back_to_back_ipg2 <<
18118 + IPGIFG_NON_BACK_TO_BACK_IPG_2_SHIFT)
18119 + & IPGIFG_NON_BACK_TO_BACK_IPG_2)
18120 + | ((cfg->min_ifg_enforcement <<
18121 + IPGIFG_MIN_IFG_ENFORCEMENT_SHIFT)
18122 + & IPGIFG_MIN_IFG_ENFORCEMENT)
18123 + | (cfg->back_to_back_ipg & IPGIFG_BACK_TO_BACK_IPG));
18124 + iowrite32be(tmp, &regs->ipgifg);
18125 +
18126 + /***************IPGIFG************************/
18127 +
18128 + /***************HAFDUP************************/
18129 + tmp = 0;
18130 +
18131 + if (cfg->halfdup_alt_backoff_en)
18132 + tmp = (uint32_t)(HAFDUP_ALT_BEB |
18133 + ((cfg->halfdup_alt_backoff_val & 0x0000000f)
18134 + << HAFDUP_ALTERNATE_BEB_TRUNCATION_SHIFT));
18135 + if (cfg->halfdup_bp_no_backoff)
18136 + tmp |= HAFDUP_BP_NO_BACKOFF;
18137 + if (cfg->halfdup_no_backoff)
18138 + tmp |= HAFDUP_NO_BACKOFF;
18139 + if (cfg->halfdup_excess_defer)
18140 + tmp |= HAFDUP_EXCESS_DEFER;
18141 + tmp |= ((cfg->halfdup_retransmit << HAFDUP_RETRANSMISSION_MAX_SHIFT)
18142 + & HAFDUP_RETRANSMISSION_MAX);
18143 + tmp |= (cfg->halfdup_coll_window & HAFDUP_COLLISION_WINDOW);
18144 +
18145 + iowrite32be(tmp, &regs->hafdup);
18146 + /***************HAFDUP************************/
18147 +
18148 + /***************MAXFRM************************/
18149 + /* Initialize MAXFRM */
18150 + iowrite32be(cfg->maximum_frame, &regs->maxfrm);
18151 +
18152 + /***************MAXFRM************************/
18153 +
18154 + /***************CAM1************************/
18155 + iowrite32be(0xffffffff, &regs->cam1);
18156 + iowrite32be(0xffffffff, &regs->cam2);
18157 +
18158 + /***************IMASK************************/
18159 + iowrite32be(exception_mask, &regs->imask);
18160 + /***************IMASK************************/
18161 +
18162 + /***************IEVENT************************/
18163 + iowrite32be(0xffffffff, &regs->ievent);
18164 +
18165 + /***************MACSTNADDR1/2*****************/
18166 +
18167 + tmp = (uint32_t)((macaddr[5] << 24) |
18168 + (macaddr[4] << 16) |
18169 + (macaddr[3] << 8) |
18170 + macaddr[2]);
18171 + iowrite32be(tmp, &regs->macstnaddr1);
18172 +
18173 + tmp = (uint32_t)((macaddr[1] << 24) |
18174 + (macaddr[0] << 16));
18175 + iowrite32be(tmp, &regs->macstnaddr2);
18176 +
18177 + /***************MACSTNADDR1/2*****************/
18178 +
18179 + /*****************HASH************************/
18180 + for (i = 0; i < NUM_OF_HASH_REGS ; i++) {
18181 + /* Initialize IADDRx */
18182 + iowrite32be(0, &regs->igaddr[i]);
18183 + /* Initialize GADDRx */
18184 + iowrite32be(0, &regs->gaddr[i]);
18185 + }
18186 +
18187 + fman_dtsec_reset_stat(regs);
18188 +
18189 + return 0;
18190 +}
18191 +
18192 +uint16_t fman_dtsec_get_max_frame_len(struct dtsec_regs *regs)
18193 +{
18194 + return (uint16_t)ioread32be(&regs->maxfrm);
18195 +}
18196 +
18197 +void fman_dtsec_set_max_frame_len(struct dtsec_regs *regs, uint16_t length)
18198 +{
18199 + iowrite32be(length, &regs->maxfrm);
18200 +}
18201 +
18202 +void fman_dtsec_set_mac_address(struct dtsec_regs *regs, uint8_t *adr)
18203 +{
18204 + uint32_t tmp;
18205 +
18206 + tmp = (uint32_t)((adr[5] << 24) |
18207 + (adr[4] << 16) |
18208 + (adr[3] << 8) |
18209 + adr[2]);
18210 + iowrite32be(tmp, &regs->macstnaddr1);
18211 +
18212 + tmp = (uint32_t)((adr[1] << 24) |
18213 + (adr[0] << 16));
18214 + iowrite32be(tmp, &regs->macstnaddr2);
18215 +}
18216 +
18217 +void fman_dtsec_get_mac_address(struct dtsec_regs *regs, uint8_t *macaddr)
18218 +{
18219 + uint32_t tmp1, tmp2;
18220 +
18221 + tmp1 = ioread32be(&regs->macstnaddr1);
18222 + tmp2 = ioread32be(&regs->macstnaddr2);
18223 +
18224 + macaddr[0] = (uint8_t)((tmp2 & 0x00ff0000) >> 16);
18225 + macaddr[1] = (uint8_t)((tmp2 & 0xff000000) >> 24);
18226 + macaddr[2] = (uint8_t)(tmp1 & 0x000000ff);
18227 + macaddr[3] = (uint8_t)((tmp1 & 0x0000ff00) >> 8);
18228 + macaddr[4] = (uint8_t)((tmp1 & 0x00ff0000) >> 16);
18229 + macaddr[5] = (uint8_t)((tmp1 & 0xff000000) >> 24);
18230 +}
18231 +
18232 +void fman_dtsec_set_hash_table(struct dtsec_regs *regs, uint32_t crc, bool mcast, bool ghtx)
18233 +{
18234 + int32_t bucket;
18235 + if (ghtx)
18236 + bucket = (int32_t)((crc >> 23) & 0x1ff);
18237 + else {
18238 + bucket = (int32_t)((crc >> 24) & 0xff);
18239 + /* if !ghtx and mcast the bit must be set in gaddr instead of igaddr. */
18240 + if (mcast)
18241 + bucket += 0x100;
18242 + }
18243 + fman_dtsec_set_bucket(regs, bucket, TRUE);
18244 +}
18245 +
18246 +void fman_dtsec_set_bucket(struct dtsec_regs *regs, int bucket, bool enable)
18247 +{
18248 + int reg_idx = (bucket >> 5) & 0xf;
18249 + int bit_idx = bucket & 0x1f;
18250 + uint32_t bit_mask = 0x80000000 >> bit_idx;
18251 + uint32_t *reg;
18252 +
18253 + if (reg_idx > 7)
18254 + reg = &regs->gaddr[reg_idx-8];
18255 + else
18256 + reg = &regs->igaddr[reg_idx];
18257 +
18258 + if (enable)
18259 + iowrite32be(ioread32be(reg) | bit_mask, reg);
18260 + else
18261 + iowrite32be(ioread32be(reg) & (~bit_mask), reg);
18262 +}
18263 +
18264 +void fman_dtsec_reset_filter_table(struct dtsec_regs *regs, bool mcast, bool ucast)
18265 +{
18266 + int i;
18267 + bool ghtx;
18268 +
18269 + ghtx = (bool)((ioread32be(&regs->rctrl) & RCTRL_GHTX) ? TRUE : FALSE);
18270 +
18271 + if (ucast || (ghtx && mcast)) {
18272 + for (i = 0; i < NUM_OF_HASH_REGS; i++)
18273 + iowrite32be(0, &regs->igaddr[i]);
18274 + }
18275 + if (mcast) {
18276 + for (i = 0; i < NUM_OF_HASH_REGS; i++)
18277 + iowrite32be(0, &regs->gaddr[i]);
18278 + }
18279 +}
18280 +
18281 +int fman_dtsec_set_tbi_phy_addr(struct dtsec_regs *regs,
18282 + uint8_t addr)
18283 +{
18284 + if (addr > 0 && addr < 32)
18285 + iowrite32be(addr, &regs->tbipa);
18286 + else
18287 + return -EINVAL;
18288 +
18289 + return 0;
18290 +}
18291 +
18292 +void fman_dtsec_set_wol(struct dtsec_regs *regs, bool en)
18293 +{
18294 + uint32_t tmp;
18295 +
18296 + tmp = ioread32be(&regs->maccfg2);
18297 + if (en)
18298 + tmp |= MACCFG2_MAGIC_PACKET_EN;
18299 + else
18300 + tmp &= ~MACCFG2_MAGIC_PACKET_EN;
18301 + iowrite32be(tmp, &regs->maccfg2);
18302 +}
18303 +
18304 +int fman_dtsec_adjust_link(struct dtsec_regs *regs,
18305 + enum enet_interface iface_mode,
18306 + enum enet_speed speed, bool full_dx)
18307 +{
18308 + uint32_t tmp;
18309 +
18310 + UNUSED(iface_mode);
18311 +
18312 + if ((speed == E_ENET_SPEED_1000) && !full_dx)
18313 + return -EINVAL;
18314 +
18315 + tmp = ioread32be(&regs->maccfg2);
18316 + if (!full_dx)
18317 + tmp &= ~MACCFG2_FULL_DUPLEX;
18318 + else
18319 + tmp |= MACCFG2_FULL_DUPLEX;
18320 +
18321 + tmp &= ~(MACCFG2_NIBBLE_MODE | MACCFG2_BYTE_MODE);
18322 + if (speed < E_ENET_SPEED_1000)
18323 + tmp |= MACCFG2_NIBBLE_MODE;
18324 + else if (speed == E_ENET_SPEED_1000)
18325 + tmp |= MACCFG2_BYTE_MODE;
18326 + iowrite32be(tmp, &regs->maccfg2);
18327 +
18328 + tmp = ioread32be(&regs->ecntrl);
18329 + if (speed == E_ENET_SPEED_100)
18330 + tmp |= DTSEC_ECNTRL_R100M;
18331 + else
18332 + tmp &= ~DTSEC_ECNTRL_R100M;
18333 + iowrite32be(tmp, &regs->ecntrl);
18334 +
18335 + return 0;
18336 +}
18337 +
18338 +void fman_dtsec_set_uc_promisc(struct dtsec_regs *regs, bool enable)
18339 +{
18340 + uint32_t tmp;
18341 +
18342 + tmp = ioread32be(&regs->rctrl);
18343 +
18344 + if (enable)
18345 + tmp |= RCTRL_UPROM;
18346 + else
18347 + tmp &= ~RCTRL_UPROM;
18348 +
18349 + iowrite32be(tmp, &regs->rctrl);
18350 +}
18351 +
18352 +void fman_dtsec_set_mc_promisc(struct dtsec_regs *regs, bool enable)
18353 +{
18354 + uint32_t tmp;
18355 +
18356 + tmp = ioread32be(&regs->rctrl);
18357 +
18358 + if (enable)
18359 + tmp |= RCTRL_MPROM;
18360 + else
18361 + tmp &= ~RCTRL_MPROM;
18362 +
18363 + iowrite32be(tmp, &regs->rctrl);
18364 +}
18365 +
18366 +bool fman_dtsec_get_clear_carry_regs(struct dtsec_regs *regs,
18367 + uint32_t *car1, uint32_t *car2)
18368 +{
18369 + /* read carry registers */
18370 + *car1 = ioread32be(&regs->car1);
18371 + *car2 = ioread32be(&regs->car2);
18372 + /* clear carry registers */
18373 + if (*car1)
18374 + iowrite32be(*car1, &regs->car1);
18375 + if (*car2)
18376 + iowrite32be(*car2, &regs->car2);
18377 +
18378 + return (bool)((*car1 | *car2) ? TRUE : FALSE);
18379 +}
18380 +
18381 +void fman_dtsec_reset_stat(struct dtsec_regs *regs)
18382 +{
18383 + /* clear HW counters */
18384 + iowrite32be(ioread32be(&regs->ecntrl) |
18385 + DTSEC_ECNTRL_CLRCNT, &regs->ecntrl);
18386 +}
18387 +
18388 +int fman_dtsec_set_stat_level(struct dtsec_regs *regs, enum dtsec_stat_level level)
18389 +{
18390 + switch (level) {
18391 + case E_MAC_STAT_NONE:
18392 + iowrite32be(0xffffffff, &regs->cam1);
18393 + iowrite32be(0xffffffff, &regs->cam2);
18394 + iowrite32be(ioread32be(&regs->ecntrl) & ~DTSEC_ECNTRL_STEN,
18395 + &regs->ecntrl);
18396 + iowrite32be(ioread32be(&regs->imask) & ~DTSEC_IMASK_MSROEN,
18397 + &regs->imask);
18398 + break;
18399 + case E_MAC_STAT_PARTIAL:
18400 + iowrite32be(CAM1_ERRORS_ONLY, &regs->cam1);
18401 + iowrite32be(CAM2_ERRORS_ONLY, &regs->cam2);
18402 + iowrite32be(ioread32be(&regs->ecntrl) | DTSEC_ECNTRL_STEN,
18403 + &regs->ecntrl);
18404 + iowrite32be(ioread32be(&regs->imask) | DTSEC_IMASK_MSROEN,
18405 + &regs->imask);
18406 + break;
18407 + case E_MAC_STAT_MIB_GRP1:
18408 + iowrite32be((uint32_t)~CAM1_MIB_GRP_1, &regs->cam1);
18409 + iowrite32be((uint32_t)~CAM2_MIB_GRP_1, &regs->cam2);
18410 + iowrite32be(ioread32be(&regs->ecntrl) | DTSEC_ECNTRL_STEN,
18411 + &regs->ecntrl);
18412 + iowrite32be(ioread32be(&regs->imask) | DTSEC_IMASK_MSROEN,
18413 + &regs->imask);
18414 + break;
18415 + case E_MAC_STAT_FULL:
18416 + iowrite32be(0, &regs->cam1);
18417 + iowrite32be(0, &regs->cam2);
18418 + iowrite32be(ioread32be(&regs->ecntrl) | DTSEC_ECNTRL_STEN,
18419 + &regs->ecntrl);
18420 + iowrite32be(ioread32be(&regs->imask) | DTSEC_IMASK_MSROEN,
18421 + &regs->imask);
18422 + break;
18423 + default:
18424 + return -EINVAL;
18425 + }
18426 +
18427 + return 0;
18428 +}
18429 +
18430 +void fman_dtsec_set_ts(struct dtsec_regs *regs, bool en)
18431 +{
18432 + if (en) {
18433 + iowrite32be(ioread32be(&regs->rctrl) | RCTRL_RTSE,
18434 + &regs->rctrl);
18435 + iowrite32be(ioread32be(&regs->tctrl) | DTSEC_TCTRL_TTSE,
18436 + &regs->tctrl);
18437 + } else {
18438 + iowrite32be(ioread32be(&regs->rctrl) & ~RCTRL_RTSE,
18439 + &regs->rctrl);
18440 + iowrite32be(ioread32be(&regs->tctrl) & ~DTSEC_TCTRL_TTSE,
18441 + &regs->tctrl);
18442 + }
18443 +}
18444 +
18445 +void fman_dtsec_enable(struct dtsec_regs *regs, bool apply_rx, bool apply_tx)
18446 +{
18447 + uint32_t tmp;
18448 +
18449 + tmp = ioread32be(&regs->maccfg1);
18450 +
18451 + if (apply_rx)
18452 + tmp |= MACCFG1_RX_EN ;
18453 +
18454 + if (apply_tx)
18455 + tmp |= MACCFG1_TX_EN ;
18456 +
18457 + iowrite32be(tmp, &regs->maccfg1);
18458 +}
18459 +
18460 +void fman_dtsec_clear_addr_in_paddr(struct dtsec_regs *regs, uint8_t paddr_num)
18461 +{
18462 + iowrite32be(0, &regs->macaddr[paddr_num].exact_match1);
18463 + iowrite32be(0, &regs->macaddr[paddr_num].exact_match2);
18464 +}
18465 +
18466 +void fman_dtsec_add_addr_in_paddr(struct dtsec_regs *regs,
18467 + uint64_t addr,
18468 + uint8_t paddr_num)
18469 +{
18470 + uint32_t tmp;
18471 +
18472 + tmp = (uint32_t)(addr);
18473 + /* swap */
18474 + tmp = (((tmp & 0x000000FF) << 24) |
18475 + ((tmp & 0x0000FF00) << 8) |
18476 + ((tmp & 0x00FF0000) >> 8) |
18477 + ((tmp & 0xFF000000) >> 24));
18478 + iowrite32be(tmp, &regs->macaddr[paddr_num].exact_match1);
18479 +
18480 + tmp = (uint32_t)(addr>>32);
18481 + /* swap */
18482 + tmp = (((tmp & 0x000000FF) << 24) |
18483 + ((tmp & 0x0000FF00) << 8) |
18484 + ((tmp & 0x00FF0000) >> 8) |
18485 + ((tmp & 0xFF000000) >> 24));
18486 + iowrite32be(tmp, &regs->macaddr[paddr_num].exact_match2);
18487 +}
18488 +
18489 +void fman_dtsec_disable(struct dtsec_regs *regs, bool apply_rx, bool apply_tx)
18490 +{
18491 + uint32_t tmp;
18492 +
18493 + tmp = ioread32be(&regs->maccfg1);
18494 +
18495 + if (apply_rx)
18496 + tmp &= ~MACCFG1_RX_EN;
18497 +
18498 + if (apply_tx)
18499 + tmp &= ~MACCFG1_TX_EN;
18500 +
18501 + iowrite32be(tmp, &regs->maccfg1);
18502 +}
18503 +
18504 +void fman_dtsec_set_tx_pause_frames(struct dtsec_regs *regs, uint16_t time)
18505 +{
18506 + uint32_t ptv = 0;
18507 +
18508 + /* fixme: don't enable tx pause for half-duplex */
18509 +
18510 + if (time) {
18511 + ptv = ioread32be(&regs->ptv);
18512 + ptv &= 0xffff0000;
18513 + ptv |= time & 0x0000ffff;
18514 + iowrite32be(ptv, &regs->ptv);
18515 +
18516 + /* trigger the transmission of a flow-control pause frame */
18517 + iowrite32be(ioread32be(&regs->maccfg1) | MACCFG1_TX_FLOW,
18518 + &regs->maccfg1);
18519 + } else
18520 + iowrite32be(ioread32be(&regs->maccfg1) & ~MACCFG1_TX_FLOW,
18521 + &regs->maccfg1);
18522 +}
18523 +
18524 +void fman_dtsec_handle_rx_pause(struct dtsec_regs *regs, bool en)
18525 +{
18526 + uint32_t tmp;
18527 +
18528 + /* todo: check if mac is set to full-duplex */
18529 +
18530 + tmp = ioread32be(&regs->maccfg1);
18531 + if (en)
18532 + tmp |= MACCFG1_RX_FLOW;
18533 + else
18534 + tmp &= ~MACCFG1_RX_FLOW;
18535 + iowrite32be(tmp, &regs->maccfg1);
18536 +}
18537 +
18538 +uint32_t fman_dtsec_get_rctrl(struct dtsec_regs *regs)
18539 +{
18540 + return ioread32be(&regs->rctrl);
18541 +}
18542 +
18543 +uint32_t fman_dtsec_get_revision(struct dtsec_regs *regs)
18544 +{
18545 + return ioread32be(&regs->tsec_id);
18546 +}
18547 +
18548 +uint32_t fman_dtsec_get_event(struct dtsec_regs *regs, uint32_t ev_mask)
18549 +{
18550 + return ioread32be(&regs->ievent) & ev_mask;
18551 +}
18552 +
18553 +void fman_dtsec_ack_event(struct dtsec_regs *regs, uint32_t ev_mask)
18554 +{
18555 + iowrite32be(ev_mask, &regs->ievent);
18556 +}
18557 +
18558 +uint32_t fman_dtsec_get_interrupt_mask(struct dtsec_regs *regs)
18559 +{
18560 + return ioread32be(&regs->imask);
18561 +}
18562 +
18563 +uint32_t fman_dtsec_check_and_clear_tmr_event(struct dtsec_regs *regs)
18564 +{
18565 + uint32_t event;
18566 +
18567 + event = ioread32be(&regs->tmr_pevent);
18568 + event &= ioread32be(&regs->tmr_pemask);
18569 +
18570 + if (event)
18571 + iowrite32be(event, &regs->tmr_pevent);
18572 + return event;
18573 +}
18574 +
18575 +void fman_dtsec_enable_tmr_interrupt(struct dtsec_regs *regs)
18576 +{
18577 + iowrite32be(ioread32be(&regs->tmr_pemask) | TMR_PEMASK_TSREEN,
18578 + &regs->tmr_pemask);
18579 +}
18580 +
18581 +void fman_dtsec_disable_tmr_interrupt(struct dtsec_regs *regs)
18582 +{
18583 + iowrite32be(ioread32be(&regs->tmr_pemask) & ~TMR_PEMASK_TSREEN,
18584 + &regs->tmr_pemask);
18585 +}
18586 +
18587 +void fman_dtsec_enable_interrupt(struct dtsec_regs *regs, uint32_t ev_mask)
18588 +{
18589 + iowrite32be(ioread32be(&regs->imask) | ev_mask, &regs->imask);
18590 +}
18591 +
18592 +void fman_dtsec_disable_interrupt(struct dtsec_regs *regs, uint32_t ev_mask)
18593 +{
18594 + iowrite32be(ioread32be(&regs->imask) & ~ev_mask, &regs->imask);
18595 +}
18596 +
18597 +uint32_t fman_dtsec_get_stat_counter(struct dtsec_regs *regs,
18598 + enum dtsec_stat_counters reg_name)
18599 +{
18600 + uint32_t ret_val;
18601 +
18602 + switch (reg_name) {
18603 + case E_DTSEC_STAT_TR64:
18604 + ret_val = ioread32be(&regs->tr64);
18605 + break;
18606 + case E_DTSEC_STAT_TR127:
18607 + ret_val = ioread32be(&regs->tr127);
18608 + break;
18609 + case E_DTSEC_STAT_TR255:
18610 + ret_val = ioread32be(&regs->tr255);
18611 + break;
18612 + case E_DTSEC_STAT_TR511:
18613 + ret_val = ioread32be(&regs->tr511);
18614 + break;
18615 + case E_DTSEC_STAT_TR1K:
18616 + ret_val = ioread32be(&regs->tr1k);
18617 + break;
18618 + case E_DTSEC_STAT_TRMAX:
18619 + ret_val = ioread32be(&regs->trmax);
18620 + break;
18621 + case E_DTSEC_STAT_TRMGV:
18622 + ret_val = ioread32be(&regs->trmgv);
18623 + break;
18624 + case E_DTSEC_STAT_RBYT:
18625 + ret_val = ioread32be(&regs->rbyt);
18626 + break;
18627 + case E_DTSEC_STAT_RPKT:
18628 + ret_val = ioread32be(&regs->rpkt);
18629 + break;
18630 + case E_DTSEC_STAT_RMCA:
18631 + ret_val = ioread32be(&regs->rmca);
18632 + break;
18633 + case E_DTSEC_STAT_RBCA:
18634 + ret_val = ioread32be(&regs->rbca);
18635 + break;
18636 + case E_DTSEC_STAT_RXPF:
18637 + ret_val = ioread32be(&regs->rxpf);
18638 + break;
18639 + case E_DTSEC_STAT_RALN:
18640 + ret_val = ioread32be(&regs->raln);
18641 + break;
18642 + case E_DTSEC_STAT_RFLR:
18643 + ret_val = ioread32be(&regs->rflr);
18644 + break;
18645 + case E_DTSEC_STAT_RCDE:
18646 + ret_val = ioread32be(&regs->rcde);
18647 + break;
18648 + case E_DTSEC_STAT_RCSE:
18649 + ret_val = ioread32be(&regs->rcse);
18650 + break;
18651 + case E_DTSEC_STAT_RUND:
18652 + ret_val = ioread32be(&regs->rund);
18653 + break;
18654 + case E_DTSEC_STAT_ROVR:
18655 + ret_val = ioread32be(&regs->rovr);
18656 + break;
18657 + case E_DTSEC_STAT_RFRG:
18658 + ret_val = ioread32be(&regs->rfrg);
18659 + break;
18660 + case E_DTSEC_STAT_RJBR:
18661 + ret_val = ioread32be(&regs->rjbr);
18662 + break;
18663 + case E_DTSEC_STAT_RDRP:
18664 + ret_val = ioread32be(&regs->rdrp);
18665 + break;
18666 + case E_DTSEC_STAT_TFCS:
18667 + ret_val = ioread32be(&regs->tfcs);
18668 + break;
18669 + case E_DTSEC_STAT_TBYT:
18670 + ret_val = ioread32be(&regs->tbyt);
18671 + break;
18672 + case E_DTSEC_STAT_TPKT:
18673 + ret_val = ioread32be(&regs->tpkt);
18674 + break;
18675 + case E_DTSEC_STAT_TMCA:
18676 + ret_val = ioread32be(&regs->tmca);
18677 + break;
18678 + case E_DTSEC_STAT_TBCA:
18679 + ret_val = ioread32be(&regs->tbca);
18680 + break;
18681 + case E_DTSEC_STAT_TXPF:
18682 + ret_val = ioread32be(&regs->txpf);
18683 + break;
18684 + case E_DTSEC_STAT_TNCL:
18685 + ret_val = ioread32be(&regs->tncl);
18686 + break;
18687 + case E_DTSEC_STAT_TDRP:
18688 + ret_val = ioread32be(&regs->tdrp);
18689 + break;
18690 + default:
18691 + ret_val = 0;
18692 + }
18693 +
18694 + return ret_val;
18695 +}
18696 --- /dev/null
18697 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/fman_dtsec_mii_acc.c
18698 @@ -0,0 +1,163 @@
18699 +/*
18700 + * Copyright 2008-2013 Freescale Semiconductor Inc.
18701 + *
18702 + * Redistribution and use in source and binary forms, with or without
18703 + * modification, are permitted provided that the following conditions are met:
18704 + * * Redistributions of source code must retain the above copyright
18705 + * notice, this list of conditions and the following disclaimer.
18706 + * * Redistributions in binary form must reproduce the above copyright
18707 + * notice, this list of conditions and the following disclaimer in the
18708 + * documentation and/or other materials provided with the distribution.
18709 + * * Neither the name of Freescale Semiconductor nor the
18710 + * names of its contributors may be used to endorse or promote products
18711 + * derived from this software without specific prior written permission.
18712 + *
18713 + *
18714 + * ALTERNATIVELY, this software may be distributed under the terms of the
18715 + * GNU General Public License ("GPL") as published by the Free Software
18716 + * Foundation, either version 2 of that License or (at your option) any
18717 + * later version.
18718 + *
18719 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
18720 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18721 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
18722 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
18723 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
18724 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
18725 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
18726 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
18727 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
18728 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
18729 + */
18730 +
18731 +
18732 +#include "common/general.h"
18733 +#include "fsl_fman_dtsec_mii_acc.h"
18734 +
18735 +
18736 +/**
18737 + * dtsec_mii_get_div() - calculates the value of the dtsec mii divider
18738 + * @dtsec_freq: dtsec clock frequency (in Mhz)
18739 + *
18740 + * This function calculates the dtsec mii clock divider that determines
18741 + * the MII MDC clock. MII MDC clock will be set to work in the range
18742 + * of 1.5 to 2.5Mhz
18743 + * The output of this function is the value of MIIMCFG[MgmtClk] which
18744 + * implicitly determines the divider value.
18745 + * Note: the dTSEC system clock is equal to 1/2 of the FMan clock.
18746 + *
18747 + * The table below which reflects dtsec_mii_get_div() functionality
18748 + * shows the relations among dtsec_freq, MgmtClk, actual divider
18749 + * and the MII frequency:
18750 + *
18751 + * dtsec freq MgmtClk div MII freq Mhz
18752 + * [0.....80] 1 (1/4)(1/8) [0 to 2.5]
18753 + * [81...120] 2 (1/6)(1/8) [1.6 to 2.5]
18754 + * [121..160] 3 (1/8)(1/8) [1.8 to 2.5]
18755 + * [161..200] 4 (1/10)(1/8) [2.0 to 2.5]
18756 + * [201..280] 5 (1/14)(1/8) [1.8 to 2.5]
18757 + * [281..400] 6 (1/20)(1/8) [1.1 to 2.5]
18758 + * [401..560] 7 (1/28)(1/8) [1.8 to 2.5]
18759 + * [560..frq] 7 (1/28)(1/8) [frq/224]
18760 + *
18761 + * Returns: the MIIMCFG[MgmtClk] appropriate value
18762 + */
18763 +
18764 +static uint8_t dtsec_mii_get_div(uint16_t dtsec_freq)
18765 +{
18766 + uint16_t mgmt_clk;
18767 +
18768 + if (dtsec_freq < 80) mgmt_clk = 1;
18769 + else if (dtsec_freq < 120) mgmt_clk = 2;
18770 + else if (dtsec_freq < 160) mgmt_clk = 3;
18771 + else if (dtsec_freq < 200) mgmt_clk = 4;
18772 + else if (dtsec_freq < 280) mgmt_clk = 5;
18773 + else if (dtsec_freq < 400) mgmt_clk = 6;
18774 + else mgmt_clk = 7;
18775 +
18776 + return (uint8_t)mgmt_clk;
18777 +}
18778 +
18779 +void fman_dtsec_mii_reset(struct dtsec_mii_reg *regs)
18780 +{
18781 + /* Reset the management interface */
18782 + iowrite32be(ioread32be(&regs->miimcfg) | MIIMCFG_RESET_MGMT,
18783 + &regs->miimcfg);
18784 + iowrite32be(ioread32be(&regs->miimcfg) & ~MIIMCFG_RESET_MGMT,
18785 + &regs->miimcfg);
18786 +}
18787 +
18788 +
18789 +int fman_dtsec_mii_write_reg(struct dtsec_mii_reg *regs, uint8_t addr,
18790 + uint8_t reg, uint16_t data, uint16_t dtsec_freq)
18791 +{
18792 + uint32_t tmp;
18793 +
18794 + /* Setup the MII Mgmt clock speed */
18795 + iowrite32be((uint32_t)dtsec_mii_get_div(dtsec_freq), &regs->miimcfg);
18796 + wmb();
18797 +
18798 + /* Stop the MII management read cycle */
18799 + iowrite32be(0, &regs->miimcom);
18800 + /* Dummy read to make sure MIIMCOM is written */
18801 + tmp = ioread32be(&regs->miimcom);
18802 + wmb();
18803 +
18804 + /* Setting up MII Management Address Register */
18805 + tmp = (uint32_t)((addr << MIIMADD_PHY_ADDR_SHIFT) | reg);
18806 + iowrite32be(tmp, &regs->miimadd);
18807 + wmb();
18808 +
18809 + /* Setting up MII Management Control Register with data */
18810 + iowrite32be((uint32_t)data, &regs->miimcon);
18811 + /* Dummy read to make sure MIIMCON is written */
18812 + tmp = ioread32be(&regs->miimcon);
18813 + wmb();
18814 +
18815 + /* Wait until MII management write is complete */
18816 + /* todo: a timeout could be useful here */
18817 + while ((ioread32be(&regs->miimind)) & MIIMIND_BUSY)
18818 + /* busy wait */;
18819 +
18820 + return 0;
18821 +}
18822 +
18823 +int fman_dtsec_mii_read_reg(struct dtsec_mii_reg *regs, uint8_t addr,
18824 + uint8_t reg, uint16_t *data, uint16_t dtsec_freq)
18825 +{
18826 + uint32_t tmp;
18827 +
18828 + /* Setup the MII Mgmt clock speed */
18829 + iowrite32be((uint32_t)dtsec_mii_get_div(dtsec_freq), &regs->miimcfg);
18830 + wmb();
18831 +
18832 + /* Setting up the MII Management Address Register */
18833 + tmp = (uint32_t)((addr << MIIMADD_PHY_ADDR_SHIFT) | reg);
18834 + iowrite32be(tmp, &regs->miimadd);
18835 + wmb();
18836 +
18837 + /* Perform an MII management read cycle */
18838 + iowrite32be(MIIMCOM_READ_CYCLE, &regs->miimcom);
18839 + /* Dummy read to make sure MIIMCOM is written */
18840 + tmp = ioread32be(&regs->miimcom);
18841 + wmb();
18842 +
18843 + /* Wait until MII management read is complete */
18844 + /* todo: a timeout could be useful here */
18845 + while ((ioread32be(&regs->miimind)) & MIIMIND_BUSY)
18846 + /* busy wait */;
18847 +
18848 + /* Read MII management status */
18849 + *data = (uint16_t)ioread32be(&regs->miimstat);
18850 + wmb();
18851 +
18852 + iowrite32be(0, &regs->miimcom);
18853 + /* Dummy read to make sure MIIMCOM is written */
18854 + tmp = ioread32be(&regs->miimcom);
18855 +
18856 + if (*data == 0xffff)
18857 + return -ENXIO;
18858 +
18859 + return 0;
18860 +}
18861 +
18862 --- /dev/null
18863 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/fman_memac.c
18864 @@ -0,0 +1,532 @@
18865 +/*
18866 + * Copyright 2008-2012 Freescale Semiconductor Inc.
18867 + *
18868 + * Redistribution and use in source and binary forms, with or without
18869 + * modification, are permitted provided that the following conditions are met:
18870 + * * Redistributions of source code must retain the above copyright
18871 + * notice, this list of conditions and the following disclaimer.
18872 + * * Redistributions in binary form must reproduce the above copyright
18873 + * notice, this list of conditions and the following disclaimer in the
18874 + * documentation and/or other materials provided with the distribution.
18875 + * * Neither the name of Freescale Semiconductor nor the
18876 + * names of its contributors may be used to endorse or promote products
18877 + * derived from this software without specific prior written permission.
18878 + *
18879 + *
18880 + * ALTERNATIVELY, this software may be distributed under the terms of the
18881 + * GNU General Public License ("GPL") as published by the Free Software
18882 + * Foundation, either version 2 of that License or (at your option) any
18883 + * later version.
18884 + *
18885 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
18886 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18887 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
18888 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
18889 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
18890 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
18891 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
18892 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
18893 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
18894 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
18895 + */
18896 +
18897 +
18898 +#include "fsl_fman_memac.h"
18899 +
18900 +
18901 +uint32_t fman_memac_get_event(struct memac_regs *regs, uint32_t ev_mask)
18902 +{
18903 + return ioread32be(&regs->ievent) & ev_mask;
18904 +}
18905 +
18906 +uint32_t fman_memac_get_interrupt_mask(struct memac_regs *regs)
18907 +{
18908 + return ioread32be(&regs->imask);
18909 +}
18910 +
18911 +void fman_memac_ack_event(struct memac_regs *regs, uint32_t ev_mask)
18912 +{
18913 + iowrite32be(ev_mask, &regs->ievent);
18914 +}
18915 +
18916 +void fman_memac_set_promiscuous(struct memac_regs *regs, bool val)
18917 +{
18918 + uint32_t tmp;
18919 +
18920 + tmp = ioread32be(&regs->command_config);
18921 +
18922 + if (val)
18923 + tmp |= CMD_CFG_PROMIS_EN;
18924 + else
18925 + tmp &= ~CMD_CFG_PROMIS_EN;
18926 +
18927 + iowrite32be(tmp, &regs->command_config);
18928 +}
18929 +
18930 +void fman_memac_clear_addr_in_paddr(struct memac_regs *regs,
18931 + uint8_t paddr_num)
18932 +{
18933 + if (paddr_num == 0) {
18934 + iowrite32be(0, &regs->mac_addr0.mac_addr_l);
18935 + iowrite32be(0, &regs->mac_addr0.mac_addr_u);
18936 + } else {
18937 + iowrite32be(0x0, &regs->mac_addr[paddr_num - 1].mac_addr_l);
18938 + iowrite32be(0x0, &regs->mac_addr[paddr_num - 1].mac_addr_u);
18939 + }
18940 +}
18941 +
18942 +void fman_memac_add_addr_in_paddr(struct memac_regs *regs,
18943 + uint8_t *adr,
18944 + uint8_t paddr_num)
18945 +{
18946 + uint32_t tmp0, tmp1;
18947 +
18948 + tmp0 = (uint32_t)(adr[0] |
18949 + adr[1] << 8 |
18950 + adr[2] << 16 |
18951 + adr[3] << 24);
18952 + tmp1 = (uint32_t)(adr[4] | adr[5] << 8);
18953 +
18954 + if (paddr_num == 0) {
18955 + iowrite32be(tmp0, &regs->mac_addr0.mac_addr_l);
18956 + iowrite32be(tmp1, &regs->mac_addr0.mac_addr_u);
18957 + } else {
18958 + iowrite32be(tmp0, &regs->mac_addr[paddr_num-1].mac_addr_l);
18959 + iowrite32be(tmp1, &regs->mac_addr[paddr_num-1].mac_addr_u);
18960 + }
18961 +}
18962 +
18963 +void fman_memac_enable(struct memac_regs *regs, bool apply_rx, bool apply_tx)
18964 +{
18965 + uint32_t tmp;
18966 +
18967 + tmp = ioread32be(&regs->command_config);
18968 +
18969 + if (apply_rx)
18970 + tmp |= CMD_CFG_RX_EN;
18971 +
18972 + if (apply_tx)
18973 + tmp |= CMD_CFG_TX_EN;
18974 +
18975 + iowrite32be(tmp, &regs->command_config);
18976 +}
18977 +
18978 +void fman_memac_disable(struct memac_regs *regs, bool apply_rx, bool apply_tx)
18979 +{
18980 + uint32_t tmp;
18981 +
18982 + tmp = ioread32be(&regs->command_config);
18983 +
18984 + if (apply_rx)
18985 + tmp &= ~CMD_CFG_RX_EN;
18986 +
18987 + if (apply_tx)
18988 + tmp &= ~CMD_CFG_TX_EN;
18989 +
18990 + iowrite32be(tmp, &regs->command_config);
18991 +}
18992 +
18993 +void fman_memac_reset_stat(struct memac_regs *regs)
18994 +{
18995 + uint32_t tmp;
18996 +
18997 + tmp = ioread32be(&regs->statn_config);
18998 +
18999 + tmp |= STATS_CFG_CLR;
19000 +
19001 + iowrite32be(tmp, &regs->statn_config);
19002 +
19003 + while (ioread32be(&regs->statn_config) & STATS_CFG_CLR);
19004 +}
19005 +
19006 +void fman_memac_reset(struct memac_regs *regs)
19007 +{
19008 + uint32_t tmp;
19009 +
19010 + tmp = ioread32be(&regs->command_config);
19011 +
19012 + tmp |= CMD_CFG_SW_RESET;
19013 +
19014 + iowrite32be(tmp, &regs->command_config);
19015 +
19016 + while (ioread32be(&regs->command_config) & CMD_CFG_SW_RESET);
19017 +}
19018 +
19019 +int fman_memac_init(struct memac_regs *regs,
19020 + struct memac_cfg *cfg,
19021 + enum enet_interface enet_interface,
19022 + enum enet_speed enet_speed,
19023 + bool slow_10g_if,
19024 + uint32_t exceptions)
19025 +{
19026 + uint32_t tmp;
19027 +
19028 + /* Config */
19029 + tmp = 0;
19030 + if (cfg->wan_mode_enable)
19031 + tmp |= CMD_CFG_WAN_MODE;
19032 + if (cfg->promiscuous_mode_enable)
19033 + tmp |= CMD_CFG_PROMIS_EN;
19034 + if (cfg->pause_forward_enable)
19035 + tmp |= CMD_CFG_PAUSE_FWD;
19036 + if (cfg->pause_ignore)
19037 + tmp |= CMD_CFG_PAUSE_IGNORE;
19038 + if (cfg->tx_addr_ins_enable)
19039 + tmp |= CMD_CFG_TX_ADDR_INS;
19040 + if (cfg->loopback_enable)
19041 + tmp |= CMD_CFG_LOOPBACK_EN;
19042 + if (cfg->cmd_frame_enable)
19043 + tmp |= CMD_CFG_CNT_FRM_EN;
19044 + if (cfg->send_idle_enable)
19045 + tmp |= CMD_CFG_SEND_IDLE;
19046 + if (cfg->no_length_check_enable)
19047 + tmp |= CMD_CFG_NO_LEN_CHK;
19048 + if (cfg->rx_sfd_any)
19049 + tmp |= CMD_CFG_SFD_ANY;
19050 + if (cfg->pad_enable)
19051 + tmp |= CMD_CFG_TX_PAD_EN;
19052 + if (cfg->wake_on_lan)
19053 + tmp |= CMD_CFG_MG;
19054 +
19055 + tmp |= CMD_CFG_CRC_FWD;
19056 +
19057 + iowrite32be(tmp, &regs->command_config);
19058 +
19059 + /* Max Frame Length */
19060 + iowrite32be((uint32_t)cfg->max_frame_length, &regs->maxfrm);
19061 +
19062 + /* Pause Time */
19063 + iowrite32be((uint32_t)cfg->pause_quanta, &regs->pause_quanta[0]);
19064 + iowrite32be((uint32_t)0, &regs->pause_thresh[0]);
19065 +
19066 + /* IF_MODE */
19067 + tmp = 0;
19068 + switch (enet_interface) {
19069 + case E_ENET_IF_XGMII:
19070 + case E_ENET_IF_XFI:
19071 + tmp |= IF_MODE_XGMII;
19072 + break;
19073 + default:
19074 + tmp |= IF_MODE_GMII;
19075 + if (enet_interface == E_ENET_IF_RGMII && !cfg->loopback_enable)
19076 + tmp |= IF_MODE_RGMII | IF_MODE_RGMII_AUTO;
19077 + }
19078 + iowrite32be(tmp, &regs->if_mode);
19079 +
19080 + /* TX_FIFO_SECTIONS */
19081 + tmp = 0;
19082 + if (enet_interface == E_ENET_IF_XGMII ||
19083 + enet_interface == E_ENET_IF_XFI) {
19084 + if(slow_10g_if) {
19085 + tmp |= (TX_FIFO_SECTIONS_TX_AVAIL_SLOW_10G |
19086 + TX_FIFO_SECTIONS_TX_EMPTY_DEFAULT_10G);
19087 + } else {
19088 + tmp |= (TX_FIFO_SECTIONS_TX_AVAIL_10G |
19089 + TX_FIFO_SECTIONS_TX_EMPTY_DEFAULT_10G);
19090 + }
19091 + } else {
19092 + tmp |= (TX_FIFO_SECTIONS_TX_AVAIL_1G |
19093 + TX_FIFO_SECTIONS_TX_EMPTY_DEFAULT_1G);
19094 + }
19095 + iowrite32be(tmp, &regs->tx_fifo_sections);
19096 +
19097 + /* clear all pending events and set-up interrupts */
19098 + fman_memac_ack_event(regs, 0xffffffff);
19099 + fman_memac_set_exception(regs, exceptions, TRUE);
19100 +
19101 + return 0;
19102 +}
19103 +
19104 +void fman_memac_set_exception(struct memac_regs *regs, uint32_t val, bool enable)
19105 +{
19106 + uint32_t tmp;
19107 +
19108 + tmp = ioread32be(&regs->imask);
19109 + if (enable)
19110 + tmp |= val;
19111 + else
19112 + tmp &= ~val;
19113 +
19114 + iowrite32be(tmp, &regs->imask);
19115 +}
19116 +
19117 +void fman_memac_reset_filter_table(struct memac_regs *regs)
19118 +{
19119 + uint32_t i;
19120 + for (i = 0; i < 64; i++)
19121 + iowrite32be(i & ~HASH_CTRL_MCAST_EN, &regs->hashtable_ctrl);
19122 +}
19123 +
19124 +void fman_memac_set_hash_table_entry(struct memac_regs *regs, uint32_t crc)
19125 +{
19126 + iowrite32be(crc | HASH_CTRL_MCAST_EN, &regs->hashtable_ctrl);
19127 +}
19128 +
19129 +void fman_memac_set_hash_table(struct memac_regs *regs, uint32_t val)
19130 +{
19131 + iowrite32be(val, &regs->hashtable_ctrl);
19132 +}
19133 +
19134 +uint16_t fman_memac_get_max_frame_len(struct memac_regs *regs)
19135 +{
19136 + uint32_t tmp;
19137 +
19138 + tmp = ioread32be(&regs->maxfrm);
19139 +
19140 + return(uint16_t)tmp;
19141 +}
19142 +
19143 +
19144 +void fman_memac_set_tx_pause_frames(struct memac_regs *regs,
19145 + uint8_t priority,
19146 + uint16_t pause_time,
19147 + uint16_t thresh_time)
19148 +{
19149 + uint32_t tmp;
19150 +
19151 + tmp = ioread32be(&regs->tx_fifo_sections);
19152 +
19153 + if (priority == 0xff) {
19154 + GET_TX_EMPTY_DEFAULT_VALUE(tmp);
19155 + iowrite32be(tmp, &regs->tx_fifo_sections);
19156 +
19157 + tmp = ioread32be(&regs->command_config);
19158 + tmp &= ~CMD_CFG_PFC_MODE;
19159 + priority = 0;
19160 + } else {
19161 + GET_TX_EMPTY_PFC_VALUE(tmp);
19162 + iowrite32be(tmp, &regs->tx_fifo_sections);
19163 +
19164 + tmp = ioread32be(&regs->command_config);
19165 + tmp |= CMD_CFG_PFC_MODE;
19166 + }
19167 +
19168 + iowrite32be(tmp, &regs->command_config);
19169 +
19170 + tmp = ioread32be(&regs->pause_quanta[priority / 2]);
19171 + if (priority % 2)
19172 + tmp &= 0x0000FFFF;
19173 + else
19174 + tmp &= 0xFFFF0000;
19175 + tmp |= ((uint32_t)pause_time << (16 * (priority % 2)));
19176 + iowrite32be(tmp, &regs->pause_quanta[priority / 2]);
19177 +
19178 + tmp = ioread32be(&regs->pause_thresh[priority / 2]);
19179 + if (priority % 2)
19180 + tmp &= 0x0000FFFF;
19181 + else
19182 + tmp &= 0xFFFF0000;
19183 + tmp |= ((uint32_t)thresh_time<<(16 * (priority % 2)));
19184 + iowrite32be(tmp, &regs->pause_thresh[priority / 2]);
19185 +}
19186 +
19187 +void fman_memac_set_rx_ignore_pause_frames(struct memac_regs *regs,bool enable)
19188 +{
19189 + uint32_t tmp;
19190 +
19191 + tmp = ioread32be(&regs->command_config);
19192 + if (enable)
19193 + tmp |= CMD_CFG_PAUSE_IGNORE;
19194 + else
19195 + tmp &= ~CMD_CFG_PAUSE_IGNORE;
19196 +
19197 + iowrite32be(tmp, &regs->command_config);
19198 +}
19199 +
19200 +void fman_memac_set_wol(struct memac_regs *regs, bool enable)
19201 +{
19202 + uint32_t tmp;
19203 +
19204 + tmp = ioread32be(&regs->command_config);
19205 +
19206 + if (enable)
19207 + tmp |= CMD_CFG_MG;
19208 + else
19209 + tmp &= ~CMD_CFG_MG;
19210 +
19211 + iowrite32be(tmp, &regs->command_config);
19212 +}
19213 +
19214 +#define GET_MEMAC_CNTR_64(bn) \
19215 + (ioread32be(&regs->bn ## _l) | \
19216 + ((uint64_t)ioread32be(&regs->bn ## _u) << 32))
19217 +
19218 +uint64_t fman_memac_get_counter(struct memac_regs *regs,
19219 + enum memac_counters reg_name)
19220 +{
19221 + uint64_t ret_val;
19222 +
19223 + switch (reg_name) {
19224 + case E_MEMAC_COUNTER_R64:
19225 + ret_val = GET_MEMAC_CNTR_64(r64);
19226 + break;
19227 + case E_MEMAC_COUNTER_T64:
19228 + ret_val = GET_MEMAC_CNTR_64(t64);
19229 + break;
19230 + case E_MEMAC_COUNTER_R127:
19231 + ret_val = GET_MEMAC_CNTR_64(r127);
19232 + break;
19233 + case E_MEMAC_COUNTER_T127:
19234 + ret_val = GET_MEMAC_CNTR_64(t127);
19235 + break;
19236 + case E_MEMAC_COUNTER_R255:
19237 + ret_val = GET_MEMAC_CNTR_64(r255);
19238 + break;
19239 + case E_MEMAC_COUNTER_T255:
19240 + ret_val = GET_MEMAC_CNTR_64(t255);
19241 + break;
19242 + case E_MEMAC_COUNTER_R511:
19243 + ret_val = GET_MEMAC_CNTR_64(r511);
19244 + break;
19245 + case E_MEMAC_COUNTER_T511:
19246 + ret_val = GET_MEMAC_CNTR_64(t511);
19247 + break;
19248 + case E_MEMAC_COUNTER_R1023:
19249 + ret_val = GET_MEMAC_CNTR_64(r1023);
19250 + break;
19251 + case E_MEMAC_COUNTER_T1023:
19252 + ret_val = GET_MEMAC_CNTR_64(t1023);
19253 + break;
19254 + case E_MEMAC_COUNTER_R1518:
19255 + ret_val = GET_MEMAC_CNTR_64(r1518);
19256 + break;
19257 + case E_MEMAC_COUNTER_T1518:
19258 + ret_val = GET_MEMAC_CNTR_64(t1518);
19259 + break;
19260 + case E_MEMAC_COUNTER_R1519X:
19261 + ret_val = GET_MEMAC_CNTR_64(r1519x);
19262 + break;
19263 + case E_MEMAC_COUNTER_T1519X:
19264 + ret_val = GET_MEMAC_CNTR_64(t1519x);
19265 + break;
19266 + case E_MEMAC_COUNTER_RFRG:
19267 + ret_val = GET_MEMAC_CNTR_64(rfrg);
19268 + break;
19269 + case E_MEMAC_COUNTER_RJBR:
19270 + ret_val = GET_MEMAC_CNTR_64(rjbr);
19271 + break;
19272 + case E_MEMAC_COUNTER_RDRP:
19273 + ret_val = GET_MEMAC_CNTR_64(rdrp);
19274 + break;
19275 + case E_MEMAC_COUNTER_RALN:
19276 + ret_val = GET_MEMAC_CNTR_64(raln);
19277 + break;
19278 + case E_MEMAC_COUNTER_TUND:
19279 + ret_val = GET_MEMAC_CNTR_64(tund);
19280 + break;
19281 + case E_MEMAC_COUNTER_ROVR:
19282 + ret_val = GET_MEMAC_CNTR_64(rovr);
19283 + break;
19284 + case E_MEMAC_COUNTER_RXPF:
19285 + ret_val = GET_MEMAC_CNTR_64(rxpf);
19286 + break;
19287 + case E_MEMAC_COUNTER_TXPF:
19288 + ret_val = GET_MEMAC_CNTR_64(txpf);
19289 + break;
19290 + case E_MEMAC_COUNTER_ROCT:
19291 + ret_val = GET_MEMAC_CNTR_64(roct);
19292 + break;
19293 + case E_MEMAC_COUNTER_RMCA:
19294 + ret_val = GET_MEMAC_CNTR_64(rmca);
19295 + break;
19296 + case E_MEMAC_COUNTER_RBCA:
19297 + ret_val = GET_MEMAC_CNTR_64(rbca);
19298 + break;
19299 + case E_MEMAC_COUNTER_RPKT:
19300 + ret_val = GET_MEMAC_CNTR_64(rpkt);
19301 + break;
19302 + case E_MEMAC_COUNTER_RUCA:
19303 + ret_val = GET_MEMAC_CNTR_64(ruca);
19304 + break;
19305 + case E_MEMAC_COUNTER_RERR:
19306 + ret_val = GET_MEMAC_CNTR_64(rerr);
19307 + break;
19308 + case E_MEMAC_COUNTER_TOCT:
19309 + ret_val = GET_MEMAC_CNTR_64(toct);
19310 + break;
19311 + case E_MEMAC_COUNTER_TMCA:
19312 + ret_val = GET_MEMAC_CNTR_64(tmca);
19313 + break;
19314 + case E_MEMAC_COUNTER_TBCA:
19315 + ret_val = GET_MEMAC_CNTR_64(tbca);
19316 + break;
19317 + case E_MEMAC_COUNTER_TUCA:
19318 + ret_val = GET_MEMAC_CNTR_64(tuca);
19319 + break;
19320 + case E_MEMAC_COUNTER_TERR:
19321 + ret_val = GET_MEMAC_CNTR_64(terr);
19322 + break;
19323 + default:
19324 + ret_val = 0;
19325 + }
19326 +
19327 + return ret_val;
19328 +}
19329 +
19330 +void fman_memac_adjust_link(struct memac_regs *regs,
19331 + enum enet_interface iface_mode,
19332 + enum enet_speed speed, bool full_dx)
19333 +{
19334 + uint32_t tmp;
19335 +
19336 + tmp = ioread32be(&regs->if_mode);
19337 +
19338 + if (full_dx)
19339 + tmp &= ~IF_MODE_HD;
19340 + else
19341 + tmp |= IF_MODE_HD;
19342 +
19343 + if (iface_mode == E_ENET_IF_RGMII) {
19344 + /* Configure RGMII in manual mode */
19345 + tmp &= ~IF_MODE_RGMII_AUTO;
19346 + tmp &= ~IF_MODE_RGMII_SP_MASK;
19347 +
19348 + if (full_dx)
19349 + tmp |= IF_MODE_RGMII_FD;
19350 + else
19351 + tmp &= ~IF_MODE_RGMII_FD;
19352 +
19353 + switch (speed) {
19354 + case E_ENET_SPEED_1000:
19355 + tmp |= IF_MODE_RGMII_1000;
19356 + break;
19357 + case E_ENET_SPEED_100:
19358 + tmp |= IF_MODE_RGMII_100;
19359 + break;
19360 + case E_ENET_SPEED_10:
19361 + tmp |= IF_MODE_RGMII_10;
19362 + break;
19363 + default:
19364 + break;
19365 + }
19366 + }
19367 +
19368 + iowrite32be(tmp, &regs->if_mode);
19369 +}
19370 +
19371 +void fman_memac_defconfig(struct memac_cfg *cfg)
19372 +{
19373 + cfg->reset_on_init = FALSE;
19374 + cfg->wan_mode_enable = FALSE;
19375 + cfg->promiscuous_mode_enable = FALSE;
19376 + cfg->pause_forward_enable = FALSE;
19377 + cfg->pause_ignore = FALSE;
19378 + cfg->tx_addr_ins_enable = FALSE;
19379 + cfg->loopback_enable = FALSE;
19380 + cfg->cmd_frame_enable = FALSE;
19381 + cfg->rx_error_discard = FALSE;
19382 + cfg->send_idle_enable = FALSE;
19383 + cfg->no_length_check_enable = TRUE;
19384 + cfg->lgth_check_nostdr = FALSE;
19385 + cfg->time_stamp_enable = FALSE;
19386 + cfg->tx_ipg_length = DEFAULT_TX_IPG_LENGTH;
19387 + cfg->max_frame_length = DEFAULT_FRAME_LENGTH;
19388 + cfg->pause_quanta = DEFAULT_PAUSE_QUANTA;
19389 + cfg->pad_enable = TRUE;
19390 + cfg->phy_tx_ena_on = FALSE;
19391 + cfg->rx_sfd_any = FALSE;
19392 + cfg->rx_pbl_fwd = FALSE;
19393 + cfg->tx_pbl_fwd = FALSE;
19394 + cfg->debug_mode = FALSE;
19395 + cfg->wake_on_lan = FALSE;
19396 +}
19397 --- /dev/null
19398 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/fman_memac_mii_acc.c
19399 @@ -0,0 +1,213 @@
19400 +/*
19401 + * Copyright 2008-2013 Freescale Semiconductor Inc.
19402 + *
19403 + * Redistribution and use in source and binary forms, with or without
19404 + * modification, are permitted provided that the following conditions are met:
19405 + * * Redistributions of source code must retain the above copyright
19406 + * notice, this list of conditions and the following disclaimer.
19407 + * * Redistributions in binary form must reproduce the above copyright
19408 + * notice, this list of conditions and the following disclaimer in the
19409 + * documentation and/or other materials provided with the distribution.
19410 + * * Neither the name of Freescale Semiconductor nor the
19411 + * names of its contributors may be used to endorse or promote products
19412 + * derived from this software without specific prior written permission.
19413 + *
19414 + *
19415 + * ALTERNATIVELY, this software may be distributed under the terms of the
19416 + * GNU General Public License ("GPL") as published by the Free Software
19417 + * Foundation, either version 2 of that License or (at your option) any
19418 + * later version.
19419 + *
19420 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
19421 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
19422 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19423 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
19424 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
19425 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
19426 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
19427 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
19428 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
19429 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
19430 + */
19431 +
19432 +
19433 +#include "fsl_fman_memac_mii_acc.h"
19434 +
19435 +static void write_phy_reg_10g(struct memac_mii_access_mem_map *mii_regs,
19436 + uint8_t phy_addr, uint8_t reg, uint16_t data)
19437 +{
19438 + uint32_t tmp_reg;
19439 +
19440 + tmp_reg = ioread32be(&mii_regs->mdio_cfg);
19441 + /* Leave only MDIO_CLK_DIV bits set on */
19442 + tmp_reg &= MDIO_CFG_CLK_DIV_MASK;
19443 + /* Set maximum MDIO_HOLD value to allow phy to see
19444 + change of data signal */
19445 + tmp_reg |= MDIO_CFG_HOLD_MASK;
19446 + /* Add 10G interface mode */
19447 + tmp_reg |= MDIO_CFG_ENC45;
19448 + iowrite32be(tmp_reg, &mii_regs->mdio_cfg);
19449 +
19450 + /* Wait for command completion */
19451 + while ((ioread32be(&mii_regs->mdio_cfg)) & MDIO_CFG_BSY)
19452 + udelay(1);
19453 +
19454 + /* Specify phy and register to be accessed */
19455 + iowrite32be(phy_addr, &mii_regs->mdio_ctrl);
19456 + iowrite32be(reg, &mii_regs->mdio_addr);
19457 + wmb();
19458 +
19459 + while ((ioread32be(&mii_regs->mdio_cfg)) & MDIO_CFG_BSY)
19460 + udelay(1);
19461 +
19462 + /* Write data */
19463 + iowrite32be(data, &mii_regs->mdio_data);
19464 + wmb();
19465 +
19466 + /* Wait for write transaction end */
19467 + while ((ioread32be(&mii_regs->mdio_data)) & MDIO_DATA_BSY)
19468 + udelay(1);
19469 +}
19470 +
19471 +static uint32_t read_phy_reg_10g(struct memac_mii_access_mem_map *mii_regs,
19472 + uint8_t phy_addr, uint8_t reg, uint16_t *data)
19473 +{
19474 + uint32_t tmp_reg;
19475 +
19476 + tmp_reg = ioread32be(&mii_regs->mdio_cfg);
19477 + /* Leave only MDIO_CLK_DIV bits set on */
19478 + tmp_reg &= MDIO_CFG_CLK_DIV_MASK;
19479 + /* Set maximum MDIO_HOLD value to allow phy to see
19480 + change of data signal */
19481 + tmp_reg |= MDIO_CFG_HOLD_MASK;
19482 + /* Add 10G interface mode */
19483 + tmp_reg |= MDIO_CFG_ENC45;
19484 + iowrite32be(tmp_reg, &mii_regs->mdio_cfg);
19485 +
19486 + /* Wait for command completion */
19487 + while ((ioread32be(&mii_regs->mdio_cfg)) & MDIO_CFG_BSY)
19488 + udelay(1);
19489 +
19490 + /* Specify phy and register to be accessed */
19491 + iowrite32be(phy_addr, &mii_regs->mdio_ctrl);
19492 + iowrite32be(reg, &mii_regs->mdio_addr);
19493 + wmb();
19494 +
19495 + while ((ioread32be(&mii_regs->mdio_cfg)) & MDIO_CFG_BSY)
19496 + udelay(1);
19497 +
19498 + /* Read cycle */
19499 + tmp_reg = phy_addr;
19500 + tmp_reg |= MDIO_CTL_READ;
19501 + iowrite32be(tmp_reg, &mii_regs->mdio_ctrl);
19502 + wmb();
19503 +
19504 + /* Wait for data to be available */
19505 + while ((ioread32be(&mii_regs->mdio_data)) & MDIO_DATA_BSY)
19506 + udelay(1);
19507 +
19508 + *data = (uint16_t)ioread32be(&mii_regs->mdio_data);
19509 +
19510 + /* Check if there was an error */
19511 + return ioread32be(&mii_regs->mdio_cfg);
19512 +}
19513 +
19514 +static void write_phy_reg_1g(struct memac_mii_access_mem_map *mii_regs,
19515 + uint8_t phy_addr, uint8_t reg, uint16_t data)
19516 +{
19517 + uint32_t tmp_reg;
19518 +
19519 + /* Leave only MDIO_CLK_DIV and MDIO_HOLD bits set on */
19520 + tmp_reg = ioread32be(&mii_regs->mdio_cfg);
19521 + tmp_reg &= (MDIO_CFG_CLK_DIV_MASK | MDIO_CFG_HOLD_MASK);
19522 + iowrite32be(tmp_reg, &mii_regs->mdio_cfg);
19523 +
19524 + /* Wait for command completion */
19525 + while ((ioread32be(&mii_regs->mdio_cfg)) & MDIO_CFG_BSY)
19526 + udelay(1);
19527 +
19528 + /* Write transaction */
19529 + tmp_reg = (phy_addr << MDIO_CTL_PHY_ADDR_SHIFT);
19530 + tmp_reg |= reg;
19531 + iowrite32be(tmp_reg, &mii_regs->mdio_ctrl);
19532 +
19533 + while ((ioread32be(&mii_regs->mdio_cfg)) & MDIO_CFG_BSY)
19534 + udelay(1);
19535 +
19536 + iowrite32be(data, &mii_regs->mdio_data);
19537 +
19538 + wmb();
19539 +
19540 + /* Wait for write transaction to end */
19541 + while ((ioread32be(&mii_regs->mdio_data)) & MDIO_DATA_BSY)
19542 + udelay(1);
19543 +}
19544 +
19545 +static uint32_t read_phy_reg_1g(struct memac_mii_access_mem_map *mii_regs,
19546 + uint8_t phy_addr, uint8_t reg, uint16_t *data)
19547 +{
19548 + uint32_t tmp_reg;
19549 +
19550 + /* Leave only MDIO_CLK_DIV and MDIO_HOLD bits set on */
19551 + tmp_reg = ioread32be(&mii_regs->mdio_cfg);
19552 + tmp_reg &= (MDIO_CFG_CLK_DIV_MASK | MDIO_CFG_HOLD_MASK);
19553 + iowrite32be(tmp_reg, &mii_regs->mdio_cfg);
19554 +
19555 + /* Wait for command completion */
19556 + while ((ioread32be(&mii_regs->mdio_cfg)) & MDIO_CFG_BSY)
19557 + udelay(1);
19558 +
19559 + /* Read transaction */
19560 + tmp_reg = (phy_addr << MDIO_CTL_PHY_ADDR_SHIFT);
19561 + tmp_reg |= reg;
19562 + tmp_reg |= MDIO_CTL_READ;
19563 + iowrite32be(tmp_reg, &mii_regs->mdio_ctrl);
19564 +
19565 + while ((ioread32be(&mii_regs->mdio_cfg)) & MDIO_CFG_BSY)
19566 + udelay(1);
19567 +
19568 + /* Wait for data to be available */
19569 + while ((ioread32be(&mii_regs->mdio_data)) & MDIO_DATA_BSY)
19570 + udelay(1);
19571 +
19572 + *data = (uint16_t)ioread32be(&mii_regs->mdio_data);
19573 +
19574 + /* Check error */
19575 + return ioread32be(&mii_regs->mdio_cfg);
19576 +}
19577 +
19578 +/*****************************************************************************/
19579 +int fman_memac_mii_write_phy_reg(struct memac_mii_access_mem_map *mii_regs,
19580 + uint8_t phy_addr, uint8_t reg, uint16_t data,
19581 + enum enet_speed enet_speed)
19582 +{
19583 + /* Figure out interface type - 10G vs 1G.
19584 + In 10G interface both phy_addr and devAddr present. */
19585 + if (enet_speed == E_ENET_SPEED_10000)
19586 + write_phy_reg_10g(mii_regs, phy_addr, reg, data);
19587 + else
19588 + write_phy_reg_1g(mii_regs, phy_addr, reg, data);
19589 +
19590 + return 0;
19591 +}
19592 +
19593 +/*****************************************************************************/
19594 +int fman_memac_mii_read_phy_reg(struct memac_mii_access_mem_map *mii_regs,
19595 + uint8_t phy_addr, uint8_t reg, uint16_t *data,
19596 + enum enet_speed enet_speed)
19597 +{
19598 + uint32_t ans;
19599 + /* Figure out interface type - 10G vs 1G.
19600 + In 10G interface both phy_addr and devAddr present. */
19601 + if (enet_speed == E_ENET_SPEED_10000)
19602 + ans = read_phy_reg_10g(mii_regs, phy_addr, reg, data);
19603 + else
19604 + ans = read_phy_reg_1g(mii_regs, phy_addr, reg, data);
19605 +
19606 + if (ans & MDIO_CFG_READ_ERR)
19607 + return -EINVAL;
19608 + return 0;
19609 +}
19610 +
19611 +/* ......................................................................... */
19612 +
19613 --- /dev/null
19614 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/fman_tgec.c
19615 @@ -0,0 +1,367 @@
19616 +/*
19617 + * Copyright 2008-2012 Freescale Semiconductor Inc.
19618 + *
19619 + * Redistribution and use in source and binary forms, with or without
19620 + * modification, are permitted provided that the following conditions are met:
19621 + * * Redistributions of source code must retain the above copyright
19622 + * notice, this list of conditions and the following disclaimer.
19623 + * * Redistributions in binary form must reproduce the above copyright
19624 + * notice, this list of conditions and the following disclaimer in the
19625 + * documentation and/or other materials provided with the distribution.
19626 + * * Neither the name of Freescale Semiconductor nor the
19627 + * names of its contributors may be used to endorse or promote products
19628 + * derived from this software without specific prior written permission.
19629 + *
19630 + *
19631 + * ALTERNATIVELY, this software may be distributed under the terms of the
19632 + * GNU General Public License ("GPL") as published by the Free Software
19633 + * Foundation, either version 2 of that License or (at your option) any
19634 + * later version.
19635 + *
19636 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
19637 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
19638 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19639 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
19640 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
19641 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
19642 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
19643 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
19644 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
19645 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
19646 + */
19647 +
19648 +
19649 +#include "fsl_fman_tgec.h"
19650 +
19651 +
19652 +void fman_tgec_set_mac_address(struct tgec_regs *regs, uint8_t *adr)
19653 +{
19654 + uint32_t tmp0, tmp1;
19655 +
19656 + tmp0 = (uint32_t)(adr[0] |
19657 + adr[1] << 8 |
19658 + adr[2] << 16 |
19659 + adr[3] << 24);
19660 + tmp1 = (uint32_t)(adr[4] | adr[5] << 8);
19661 + iowrite32be(tmp0, &regs->mac_addr_0);
19662 + iowrite32be(tmp1, &regs->mac_addr_1);
19663 +}
19664 +
19665 +void fman_tgec_reset_stat(struct tgec_regs *regs)
19666 +{
19667 + uint32_t tmp;
19668 +
19669 + tmp = ioread32be(&regs->command_config);
19670 +
19671 + tmp |= CMD_CFG_STAT_CLR;
19672 +
19673 + iowrite32be(tmp, &regs->command_config);
19674 +
19675 + while (ioread32be(&regs->command_config) & CMD_CFG_STAT_CLR) ;
19676 +}
19677 +
19678 +#define GET_TGEC_CNTR_64(bn) \
19679 + (((uint64_t)ioread32be(&regs->bn ## _u) << 32) | \
19680 + ioread32be(&regs->bn ## _l))
19681 +
19682 +uint64_t fman_tgec_get_counter(struct tgec_regs *regs, enum tgec_counters reg_name)
19683 +{
19684 + uint64_t ret_val;
19685 +
19686 + switch (reg_name) {
19687 + case E_TGEC_COUNTER_R64:
19688 + ret_val = GET_TGEC_CNTR_64(r64);
19689 + break;
19690 + case E_TGEC_COUNTER_R127:
19691 + ret_val = GET_TGEC_CNTR_64(r127);
19692 + break;
19693 + case E_TGEC_COUNTER_R255:
19694 + ret_val = GET_TGEC_CNTR_64(r255);
19695 + break;
19696 + case E_TGEC_COUNTER_R511:
19697 + ret_val = GET_TGEC_CNTR_64(r511);
19698 + break;
19699 + case E_TGEC_COUNTER_R1023:
19700 + ret_val = GET_TGEC_CNTR_64(r1023);
19701 + break;
19702 + case E_TGEC_COUNTER_R1518:
19703 + ret_val = GET_TGEC_CNTR_64(r1518);
19704 + break;
19705 + case E_TGEC_COUNTER_R1519X:
19706 + ret_val = GET_TGEC_CNTR_64(r1519x);
19707 + break;
19708 + case E_TGEC_COUNTER_TRFRG:
19709 + ret_val = GET_TGEC_CNTR_64(trfrg);
19710 + break;
19711 + case E_TGEC_COUNTER_TRJBR:
19712 + ret_val = GET_TGEC_CNTR_64(trjbr);
19713 + break;
19714 + case E_TGEC_COUNTER_RDRP:
19715 + ret_val = GET_TGEC_CNTR_64(rdrp);
19716 + break;
19717 + case E_TGEC_COUNTER_RALN:
19718 + ret_val = GET_TGEC_CNTR_64(raln);
19719 + break;
19720 + case E_TGEC_COUNTER_TRUND:
19721 + ret_val = GET_TGEC_CNTR_64(trund);
19722 + break;
19723 + case E_TGEC_COUNTER_TROVR:
19724 + ret_val = GET_TGEC_CNTR_64(trovr);
19725 + break;
19726 + case E_TGEC_COUNTER_RXPF:
19727 + ret_val = GET_TGEC_CNTR_64(rxpf);
19728 + break;
19729 + case E_TGEC_COUNTER_TXPF:
19730 + ret_val = GET_TGEC_CNTR_64(txpf);
19731 + break;
19732 + case E_TGEC_COUNTER_ROCT:
19733 + ret_val = GET_TGEC_CNTR_64(roct);
19734 + break;
19735 + case E_TGEC_COUNTER_RMCA:
19736 + ret_val = GET_TGEC_CNTR_64(rmca);
19737 + break;
19738 + case E_TGEC_COUNTER_RBCA:
19739 + ret_val = GET_TGEC_CNTR_64(rbca);
19740 + break;
19741 + case E_TGEC_COUNTER_RPKT:
19742 + ret_val = GET_TGEC_CNTR_64(rpkt);
19743 + break;
19744 + case E_TGEC_COUNTER_RUCA:
19745 + ret_val = GET_TGEC_CNTR_64(ruca);
19746 + break;
19747 + case E_TGEC_COUNTER_RERR:
19748 + ret_val = GET_TGEC_CNTR_64(rerr);
19749 + break;
19750 + case E_TGEC_COUNTER_TOCT:
19751 + ret_val = GET_TGEC_CNTR_64(toct);
19752 + break;
19753 + case E_TGEC_COUNTER_TMCA:
19754 + ret_val = GET_TGEC_CNTR_64(tmca);
19755 + break;
19756 + case E_TGEC_COUNTER_TBCA:
19757 + ret_val = GET_TGEC_CNTR_64(tbca);
19758 + break;
19759 + case E_TGEC_COUNTER_TUCA:
19760 + ret_val = GET_TGEC_CNTR_64(tuca);
19761 + break;
19762 + case E_TGEC_COUNTER_TERR:
19763 + ret_val = GET_TGEC_CNTR_64(terr);
19764 + break;
19765 + default:
19766 + ret_val = 0;
19767 + }
19768 +
19769 + return ret_val;
19770 +}
19771 +
19772 +void fman_tgec_enable(struct tgec_regs *regs, bool apply_rx, bool apply_tx)
19773 +{
19774 + uint32_t tmp;
19775 +
19776 + tmp = ioread32be(&regs->command_config);
19777 + if (apply_rx)
19778 + tmp |= CMD_CFG_RX_EN;
19779 + if (apply_tx)
19780 + tmp |= CMD_CFG_TX_EN;
19781 + iowrite32be(tmp, &regs->command_config);
19782 +}
19783 +
19784 +void fman_tgec_disable(struct tgec_regs *regs, bool apply_rx, bool apply_tx)
19785 +{
19786 + uint32_t tmp_reg_32;
19787 +
19788 + tmp_reg_32 = ioread32be(&regs->command_config);
19789 + if (apply_rx)
19790 + tmp_reg_32 &= ~CMD_CFG_RX_EN;
19791 + if (apply_tx)
19792 + tmp_reg_32 &= ~CMD_CFG_TX_EN;
19793 + iowrite32be(tmp_reg_32, &regs->command_config);
19794 +}
19795 +
19796 +void fman_tgec_set_promiscuous(struct tgec_regs *regs, bool val)
19797 +{
19798 + uint32_t tmp;
19799 +
19800 + tmp = ioread32be(&regs->command_config);
19801 + if (val)
19802 + tmp |= CMD_CFG_PROMIS_EN;
19803 + else
19804 + tmp &= ~CMD_CFG_PROMIS_EN;
19805 + iowrite32be(tmp, &regs->command_config);
19806 +}
19807 +
19808 +void fman_tgec_reset_filter_table(struct tgec_regs *regs)
19809 +{
19810 + uint32_t i;
19811 + for (i = 0; i < 512; i++)
19812 + iowrite32be(i & ~TGEC_HASH_MCAST_EN, &regs->hashtable_ctrl);
19813 +}
19814 +
19815 +void fman_tgec_set_hash_table_entry(struct tgec_regs *regs, uint32_t crc)
19816 +{
19817 + uint32_t hash = (crc >> TGEC_HASH_MCAST_SHIFT) & TGEC_HASH_ADR_MSK; /* Take 9 MSB bits */
19818 + iowrite32be(hash | TGEC_HASH_MCAST_EN, &regs->hashtable_ctrl);
19819 +}
19820 +
19821 +void fman_tgec_set_hash_table(struct tgec_regs *regs, uint32_t value)
19822 +{
19823 + iowrite32be(value, &regs->hashtable_ctrl);
19824 +}
19825 +
19826 +void fman_tgec_set_tx_pause_frames(struct tgec_regs *regs, uint16_t pause_time)
19827 +{
19828 + iowrite32be((uint32_t)pause_time, &regs->pause_quant);
19829 +}
19830 +
19831 +void fman_tgec_set_rx_ignore_pause_frames(struct tgec_regs *regs, bool en)
19832 +{
19833 + uint32_t tmp;
19834 +
19835 + tmp = ioread32be(&regs->command_config);
19836 + if (en)
19837 + tmp |= CMD_CFG_PAUSE_IGNORE;
19838 + else
19839 + tmp &= ~CMD_CFG_PAUSE_IGNORE;
19840 + iowrite32be(tmp, &regs->command_config);
19841 +}
19842 +
19843 +void fman_tgec_enable_1588_time_stamp(struct tgec_regs *regs, bool en)
19844 +{
19845 + uint32_t tmp;
19846 +
19847 + tmp = ioread32be(&regs->command_config);
19848 + if (en)
19849 + tmp |= CMD_CFG_EN_TIMESTAMP;
19850 + else
19851 + tmp &= ~CMD_CFG_EN_TIMESTAMP;
19852 + iowrite32be(tmp, &regs->command_config);
19853 +}
19854 +
19855 +uint32_t fman_tgec_get_event(struct tgec_regs *regs, uint32_t ev_mask)
19856 +{
19857 + return ioread32be(&regs->ievent) & ev_mask;
19858 +}
19859 +
19860 +void fman_tgec_ack_event(struct tgec_regs *regs, uint32_t ev_mask)
19861 +{
19862 + iowrite32be(ev_mask, &regs->ievent);
19863 +}
19864 +
19865 +uint32_t fman_tgec_get_interrupt_mask(struct tgec_regs *regs)
19866 +{
19867 + return ioread32be(&regs->imask);
19868 +}
19869 +
19870 +void fman_tgec_add_addr_in_paddr(struct tgec_regs *regs, uint8_t *adr)
19871 +{
19872 + uint32_t tmp0, tmp1;
19873 +
19874 + tmp0 = (uint32_t)(adr[0] |
19875 + adr[1] << 8 |
19876 + adr[2] << 16 |
19877 + adr[3] << 24);
19878 + tmp1 = (uint32_t)(adr[4] | adr[5] << 8);
19879 + iowrite32be(tmp0, &regs->mac_addr_2);
19880 + iowrite32be(tmp1, &regs->mac_addr_3);
19881 +}
19882 +
19883 +void fman_tgec_clear_addr_in_paddr(struct tgec_regs *regs)
19884 +{
19885 + iowrite32be(0, &regs->mac_addr_2);
19886 + iowrite32be(0, &regs->mac_addr_3);
19887 +}
19888 +
19889 +uint32_t fman_tgec_get_revision(struct tgec_regs *regs)
19890 +{
19891 + return ioread32be(&regs->tgec_id);
19892 +}
19893 +
19894 +void fman_tgec_enable_interrupt(struct tgec_regs *regs, uint32_t ev_mask)
19895 +{
19896 + iowrite32be(ioread32be(&regs->imask) | ev_mask, &regs->imask);
19897 +}
19898 +
19899 +void fman_tgec_disable_interrupt(struct tgec_regs *regs, uint32_t ev_mask)
19900 +{
19901 + iowrite32be(ioread32be(&regs->imask) & ~ev_mask, &regs->imask);
19902 +}
19903 +
19904 +uint16_t fman_tgec_get_max_frame_len(struct tgec_regs *regs)
19905 +{
19906 + return (uint16_t) ioread32be(&regs->maxfrm);
19907 +}
19908 +
19909 +void fman_tgec_defconfig(struct tgec_cfg *cfg)
19910 +{
19911 + cfg->wan_mode_enable = DEFAULT_WAN_MODE_ENABLE;
19912 + cfg->promiscuous_mode_enable = DEFAULT_PROMISCUOUS_MODE_ENABLE;
19913 + cfg->pause_forward_enable = DEFAULT_PAUSE_FORWARD_ENABLE;
19914 + cfg->pause_ignore = DEFAULT_PAUSE_IGNORE;
19915 + cfg->tx_addr_ins_enable = DEFAULT_TX_ADDR_INS_ENABLE;
19916 + cfg->loopback_enable = DEFAULT_LOOPBACK_ENABLE;
19917 + cfg->cmd_frame_enable = DEFAULT_CMD_FRAME_ENABLE;
19918 + cfg->rx_error_discard = DEFAULT_RX_ERROR_DISCARD;
19919 + cfg->send_idle_enable = DEFAULT_SEND_IDLE_ENABLE;
19920 + cfg->no_length_check_enable = DEFAULT_NO_LENGTH_CHECK_ENABLE;
19921 + cfg->lgth_check_nostdr = DEFAULT_LGTH_CHECK_NOSTDR;
19922 + cfg->time_stamp_enable = DEFAULT_TIME_STAMP_ENABLE;
19923 + cfg->tx_ipg_length = DEFAULT_TX_IPG_LENGTH;
19924 + cfg->max_frame_length = DEFAULT_MAX_FRAME_LENGTH;
19925 + cfg->pause_quant = DEFAULT_PAUSE_QUANT;
19926 +#ifdef FM_TX_ECC_FRMS_ERRATA_10GMAC_A004
19927 + cfg->skip_fman11_workaround = FALSE;
19928 +#endif /* FM_TX_ECC_FRMS_ERRATA_10GMAC_A004 */
19929 +}
19930 +
19931 +int fman_tgec_init(struct tgec_regs *regs, struct tgec_cfg *cfg,
19932 + uint32_t exception_mask)
19933 +{
19934 + uint32_t tmp;
19935 +
19936 + /* Config */
19937 + tmp = 0x40; /* CRC forward */
19938 + if (cfg->wan_mode_enable)
19939 + tmp |= CMD_CFG_WAN_MODE;
19940 + if (cfg->promiscuous_mode_enable)
19941 + tmp |= CMD_CFG_PROMIS_EN;
19942 + if (cfg->pause_forward_enable)
19943 + tmp |= CMD_CFG_PAUSE_FWD;
19944 + if (cfg->pause_ignore)
19945 + tmp |= CMD_CFG_PAUSE_IGNORE;
19946 + if (cfg->tx_addr_ins_enable)
19947 + tmp |= CMD_CFG_TX_ADDR_INS;
19948 + if (cfg->loopback_enable)
19949 + tmp |= CMD_CFG_LOOPBACK_EN;
19950 + if (cfg->cmd_frame_enable)
19951 + tmp |= CMD_CFG_CMD_FRM_EN;
19952 + if (cfg->rx_error_discard)
19953 + tmp |= CMD_CFG_RX_ER_DISC;
19954 + if (cfg->send_idle_enable)
19955 + tmp |= CMD_CFG_SEND_IDLE;
19956 + if (cfg->no_length_check_enable)
19957 + tmp |= CMD_CFG_NO_LEN_CHK;
19958 + if (cfg->time_stamp_enable)
19959 + tmp |= CMD_CFG_EN_TIMESTAMP;
19960 + iowrite32be(tmp, &regs->command_config);
19961 +
19962 + /* Max Frame Length */
19963 + iowrite32be((uint32_t)cfg->max_frame_length, &regs->maxfrm);
19964 + /* Pause Time */
19965 + iowrite32be(cfg->pause_quant, &regs->pause_quant);
19966 +
19967 + /* clear all pending events and set-up interrupts */
19968 + fman_tgec_ack_event(regs, 0xffffffff);
19969 + fman_tgec_enable_interrupt(regs, exception_mask);
19970 +
19971 + return 0;
19972 +}
19973 +
19974 +void fman_tgec_set_erratum_tx_fifo_corruption_10gmac_a007(struct tgec_regs *regs)
19975 +{
19976 + uint32_t tmp;
19977 +
19978 + /* restore the default tx ipg Length */
19979 + tmp = (ioread32be(&regs->tx_ipg_len) & ~TGEC_TX_IPG_LENGTH_MASK) | 12;
19980 +
19981 + iowrite32be(tmp, &regs->tx_ipg_len);
19982 +}
19983 --- /dev/null
19984 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/memac.c
19985 @@ -0,0 +1,1153 @@
19986 +/*
19987 + * Copyright 2008-2012 Freescale Semiconductor Inc.
19988 + *
19989 + * Redistribution and use in source and binary forms, with or without
19990 + * modification, are permitted provided that the following conditions are met:
19991 + * * Redistributions of source code must retain the above copyright
19992 + * notice, this list of conditions and the following disclaimer.
19993 + * * Redistributions in binary form must reproduce the above copyright
19994 + * notice, this list of conditions and the following disclaimer in the
19995 + * documentation and/or other materials provided with the distribution.
19996 + * * Neither the name of Freescale Semiconductor nor the
19997 + * names of its contributors may be used to endorse or promote products
19998 + * derived from this software without specific prior written permission.
19999 + *
20000 + *
20001 + * ALTERNATIVELY, this software may be distributed under the terms of the
20002 + * GNU General Public License ("GPL") as published by the Free Software
20003 + * Foundation, either version 2 of that License or (at your option) any
20004 + * later version.
20005 + *
20006 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
20007 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
20008 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
20009 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
20010 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
20011 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
20012 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
20013 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
20014 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
20015 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
20016 + */
20017 +
20018 +
20019 +/******************************************************************************
20020 + @File memac.c
20021 +
20022 + @Description FM mEMAC driver
20023 +*//***************************************************************************/
20024 +
20025 +#include "std_ext.h"
20026 +#include "string_ext.h"
20027 +#include "error_ext.h"
20028 +#include "xx_ext.h"
20029 +#include "endian_ext.h"
20030 +#include "debug_ext.h"
20031 +
20032 +#include "fm_common.h"
20033 +#include "memac.h"
20034 +
20035 +
20036 +/*****************************************************************************/
20037 +/* Internal routines */
20038 +/*****************************************************************************/
20039 +
20040 +/* ......................................................................... */
20041 +
20042 +static uint32_t GetMacAddrHashCode(uint64_t ethAddr)
20043 +{
20044 + uint64_t mask1, mask2;
20045 + uint32_t xorVal = 0;
20046 + uint8_t i, j;
20047 +
20048 + for (i=0; i<6; i++)
20049 + {
20050 + mask1 = ethAddr & (uint64_t)0x01;
20051 + ethAddr >>= 1;
20052 +
20053 + for (j=0; j<7; j++)
20054 + {
20055 + mask2 = ethAddr & (uint64_t)0x01;
20056 + mask1 ^= mask2;
20057 + ethAddr >>= 1;
20058 + }
20059 +
20060 + xorVal |= (mask1 << (5-i));
20061 + }
20062 +
20063 + return xorVal;
20064 +}
20065 +
20066 +/* ......................................................................... */
20067 +
20068 +static void SetupSgmiiInternalPhy(t_Memac *p_Memac, uint8_t phyAddr)
20069 +{
20070 + uint16_t tmpReg16;
20071 + e_EnetMode enetMode;
20072 +
20073 + /* In case the higher MACs are used (i.e. the MACs that should support 10G),
20074 + speed=10000 is provided for SGMII ports. Temporary modify enet mode
20075 + to 1G one, so MII functions can work correctly. */
20076 + enetMode = p_Memac->enetMode;
20077 +
20078 + /* SGMII mode + AN enable */
20079 + tmpReg16 = PHY_SGMII_IF_MODE_AN | PHY_SGMII_IF_MODE_SGMII;
20080 + if ((p_Memac->enetMode) == e_ENET_MODE_SGMII_2500)
20081 + tmpReg16 = PHY_SGMII_CR_PHY_RESET | PHY_SGMII_IF_SPEED_GIGABIT | PHY_SGMII_IF_MODE_SGMII;
20082 +
20083 + p_Memac->enetMode = MAKE_ENET_MODE(ENET_INTERFACE_FROM_MODE(p_Memac->enetMode), e_ENET_SPEED_1000);
20084 + MEMAC_MII_WritePhyReg(p_Memac, phyAddr, 0x14, tmpReg16);
20085 +
20086 + /* Device ability according to SGMII specification */
20087 + tmpReg16 = PHY_SGMII_DEV_ABILITY_SGMII;
20088 + MEMAC_MII_WritePhyReg(p_Memac, phyAddr, 0x4, tmpReg16);
20089 +
20090 + /* Adjust link timer for SGMII -
20091 + According to Cisco SGMII specification the timer should be 1.6 ms.
20092 + The link_timer register is configured in units of the clock.
20093 + - When running as 1G SGMII, Serdes clock is 125 MHz, so
20094 + unit = 1 / (125*10^6 Hz) = 8 ns.
20095 + 1.6 ms in units of 8 ns = 1.6ms / 8ns = 2 * 10^5 = 0x30d40
20096 + - When running as 2.5G SGMII, Serdes clock is 312.5 MHz, so
20097 + unit = 1 / (312.5*10^6 Hz) = 3.2 ns.
20098 + 1.6 ms in units of 3.2 ns = 1.6ms / 3.2ns = 5 * 10^5 = 0x7a120.
20099 + Since link_timer value of 1G SGMII will be too short for 2.5 SGMII,
20100 + we always set up here a value of 2.5 SGMII. */
20101 + MEMAC_MII_WritePhyReg(p_Memac, phyAddr, 0x13, 0x0007);
20102 + MEMAC_MII_WritePhyReg(p_Memac, phyAddr, 0x12, 0xa120);
20103 +
20104 + /* Restart AN */
20105 + tmpReg16 = PHY_SGMII_CR_DEF_VAL | PHY_SGMII_CR_RESET_AN;
20106 + MEMAC_MII_WritePhyReg(p_Memac, phyAddr, 0x0, tmpReg16);
20107 +
20108 + /* Restore original enet mode */
20109 + p_Memac->enetMode = enetMode;
20110 +}
20111 +
20112 +/* ......................................................................... */
20113 +
20114 +static void SetupSgmiiInternalPhyBaseX(t_Memac *p_Memac, uint8_t phyAddr)
20115 +{
20116 + uint16_t tmpReg16;
20117 + e_EnetMode enetMode;
20118 +
20119 + /* In case the higher MACs are used (i.e. the MACs that should support 10G),
20120 + speed=10000 is provided for SGMII ports. Temporary modify enet mode
20121 + to 1G one, so MII functions can work correctly. */
20122 + enetMode = p_Memac->enetMode;
20123 + p_Memac->enetMode = MAKE_ENET_MODE(ENET_INTERFACE_FROM_MODE(p_Memac->enetMode), e_ENET_SPEED_1000);
20124 +
20125 + /* 1000BaseX mode */
20126 + tmpReg16 = PHY_SGMII_IF_MODE_1000X;
20127 + MEMAC_MII_WritePhyReg(p_Memac, phyAddr, 0x14, tmpReg16);
20128 +
20129 + /* AN Device capability */
20130 + tmpReg16 = PHY_SGMII_DEV_ABILITY_1000X;
20131 + MEMAC_MII_WritePhyReg(p_Memac, phyAddr, 0x4, tmpReg16);
20132 +
20133 + /* Adjust link timer for SGMII -
20134 + For Serdes 1000BaseX auto-negotiation the timer should be 10 ms.
20135 + The link_timer register is configured in units of the clock.
20136 + - When running as 1G SGMII, Serdes clock is 125 MHz, so
20137 + unit = 1 / (125*10^6 Hz) = 8 ns.
20138 + 10 ms in units of 8 ns = 10ms / 8ns = 1250000 = 0x1312d0
20139 + - When running as 2.5G SGMII, Serdes clock is 312.5 MHz, so
20140 + unit = 1 / (312.5*10^6 Hz) = 3.2 ns.
20141 + 10 ms in units of 3.2 ns = 10ms / 3.2ns = 3125000 = 0x2faf08.
20142 + Since link_timer value of 1G SGMII will be too short for 2.5 SGMII,
20143 + we always set up here a value of 2.5 SGMII. */
20144 + MEMAC_MII_WritePhyReg(p_Memac, phyAddr, 0x13, 0x002f);
20145 + MEMAC_MII_WritePhyReg(p_Memac, phyAddr, 0x12, 0xaf08);
20146 +
20147 + /* Restart AN */
20148 + tmpReg16 = PHY_SGMII_CR_DEF_VAL | PHY_SGMII_CR_RESET_AN;
20149 + MEMAC_MII_WritePhyReg(p_Memac, phyAddr, 0x0, tmpReg16);
20150 +
20151 + /* Restore original enet mode */
20152 + p_Memac->enetMode = enetMode;
20153 +}
20154 +
20155 +/* ......................................................................... */
20156 +
20157 +static t_Error CheckInitParameters(t_Memac *p_Memac)
20158 +{
20159 + e_FmMacType portType;
20160 +
20161 + portType = ((ENET_SPEED_FROM_MODE(p_Memac->enetMode) < e_ENET_SPEED_10000) ? e_FM_MAC_1G : e_FM_MAC_10G);
20162 +
20163 +#if (FM_MAX_NUM_OF_10G_MACS > 0)
20164 + if ((portType == e_FM_MAC_10G) && (p_Memac->macId >= FM_MAX_NUM_OF_10G_MACS))
20165 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("10G MAC ID must be less than %d", FM_MAX_NUM_OF_10G_MACS));
20166 +#endif /* (FM_MAX_NUM_OF_10G_MACS > 0) */
20167 +
20168 + if ((portType == e_FM_MAC_1G) && (p_Memac->macId >= FM_MAX_NUM_OF_1G_MACS))
20169 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("1G MAC ID must be less than %d", FM_MAX_NUM_OF_1G_MACS));
20170 + if (p_Memac->addr == 0)
20171 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Ethernet MAC must have a valid MAC address"));
20172 + if (!p_Memac->f_Exception)
20173 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Uninitialized f_Exception"));
20174 + if (!p_Memac->f_Event)
20175 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Uninitialized f_Event"));
20176 +#ifdef FM_LEN_CHECK_ERRATA_FMAN_SW002
20177 + if (!p_Memac->p_MemacDriverParam->no_length_check_enable)
20178 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("LengthCheck!"));
20179 +#endif /* FM_LEN_CHECK_ERRATA_FMAN_SW002 */
20180 +
20181 + return E_OK;
20182 +}
20183 +
20184 +/* ........................................................................... */
20185 +
20186 +static void MemacErrException(t_Handle h_Memac)
20187 +{
20188 + t_Memac *p_Memac = (t_Memac *)h_Memac;
20189 + uint32_t event, imask;
20190 +
20191 + event = fman_memac_get_event(p_Memac->p_MemMap, 0xffffffff);
20192 + imask = fman_memac_get_interrupt_mask(p_Memac->p_MemMap);
20193 +
20194 + /* Imask include both error and notification/event bits.
20195 + Leaving only error bits enabled by imask.
20196 + The imask error bits are shifted by 16 bits offset from
20197 + their corresponding location in the ievent - hence the >> 16 */
20198 + event &= ((imask & MEMAC_ALL_ERRS_IMASK) >> 16);
20199 +
20200 + fman_memac_ack_event(p_Memac->p_MemMap, event);
20201 +
20202 + if (event & MEMAC_IEVNT_TS_ECC_ER)
20203 + p_Memac->f_Exception(p_Memac->h_App, e_FM_MAC_EX_TS_FIFO_ECC_ERR);
20204 + if (event & MEMAC_IEVNT_TX_ECC_ER)
20205 + p_Memac->f_Exception(p_Memac->h_App, e_FM_MAC_EX_10G_1TX_ECC_ER);
20206 + if (event & MEMAC_IEVNT_RX_ECC_ER)
20207 + p_Memac->f_Exception(p_Memac->h_App, e_FM_MAC_EX_10G_RX_ECC_ER);
20208 +}
20209 +
20210 +static void MemacException(t_Handle h_Memac)
20211 +{
20212 + t_Memac *p_Memac = (t_Memac *)h_Memac;
20213 + uint32_t event, imask;
20214 +
20215 + event = fman_memac_get_event(p_Memac->p_MemMap, 0xffffffff);
20216 + imask = fman_memac_get_interrupt_mask(p_Memac->p_MemMap);
20217 +
20218 + /* Imask include both error and notification/event bits.
20219 + Leaving only error bits enabled by imask.
20220 + The imask error bits are shifted by 16 bits offset from
20221 + their corresponding location in the ievent - hence the >> 16 */
20222 + event &= ((imask & MEMAC_ALL_ERRS_IMASK) >> 16);
20223 +
20224 + fman_memac_ack_event(p_Memac->p_MemMap, event);
20225 +
20226 + if (event & MEMAC_IEVNT_MGI)
20227 + p_Memac->f_Exception(p_Memac->h_App, e_FM_MAC_EX_MAGIC_PACKET_INDICATION);
20228 +}
20229 +
20230 +/* ......................................................................... */
20231 +
20232 +static void FreeInitResources(t_Memac *p_Memac)
20233 +{
20234 + e_FmMacType portType;
20235 +
20236 + portType =
20237 + ((ENET_SPEED_FROM_MODE(p_Memac->enetMode) < e_ENET_SPEED_10000) ? e_FM_MAC_1G : e_FM_MAC_10G);
20238 +
20239 + if (portType == e_FM_MAC_10G)
20240 + FmUnregisterIntr(p_Memac->fmMacControllerDriver.h_Fm, e_FM_MOD_10G_MAC, p_Memac->macId, e_FM_INTR_TYPE_ERR);
20241 + else
20242 + FmUnregisterIntr(p_Memac->fmMacControllerDriver.h_Fm, e_FM_MOD_1G_MAC, p_Memac->macId, e_FM_INTR_TYPE_ERR);
20243 +
20244 + /* release the driver's group hash table */
20245 + FreeHashTable(p_Memac->p_MulticastAddrHash);
20246 + p_Memac->p_MulticastAddrHash = NULL;
20247 +
20248 + /* release the driver's individual hash table */
20249 + FreeHashTable(p_Memac->p_UnicastAddrHash);
20250 + p_Memac->p_UnicastAddrHash = NULL;
20251 +}
20252 +
20253 +
20254 +/*****************************************************************************/
20255 +/* mEMAC API routines */
20256 +/*****************************************************************************/
20257 +
20258 +/* ......................................................................... */
20259 +
20260 +static t_Error MemacEnable(t_Handle h_Memac, e_CommMode mode)
20261 +{
20262 + t_Memac *p_Memac = (t_Memac *)h_Memac;
20263 +
20264 + SANITY_CHECK_RETURN_ERROR(p_Memac, E_INVALID_HANDLE);
20265 + SANITY_CHECK_RETURN_ERROR(!p_Memac->p_MemacDriverParam, E_INVALID_STATE);
20266 +
20267 + fman_memac_enable(p_Memac->p_MemMap, (mode & e_COMM_MODE_RX), (mode & e_COMM_MODE_TX));
20268 +
20269 + return E_OK;
20270 +}
20271 +
20272 +/* ......................................................................... */
20273 +
20274 +static t_Error MemacDisable (t_Handle h_Memac, e_CommMode mode)
20275 +{
20276 + t_Memac *p_Memac = (t_Memac *)h_Memac;
20277 +
20278 + SANITY_CHECK_RETURN_ERROR(p_Memac, E_INVALID_HANDLE);
20279 + SANITY_CHECK_RETURN_ERROR(!p_Memac->p_MemacDriverParam, E_INVALID_STATE);
20280 +
20281 + fman_memac_disable(p_Memac->p_MemMap, (mode & e_COMM_MODE_RX), (mode & e_COMM_MODE_TX));
20282 +
20283 + return E_OK;
20284 +}
20285 +
20286 +/* ......................................................................... */
20287 +
20288 +static t_Error MemacSetPromiscuous(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 + fman_memac_set_promiscuous(p_Memac->p_MemMap, newVal);
20296 +
20297 + return E_OK;
20298 +}
20299 +
20300 +/* .............................................................................. */
20301 +
20302 +static t_Error MemacAdjustLink(t_Handle h_Memac, e_EnetSpeed speed, bool fullDuplex)
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 + if ((speed >= e_ENET_SPEED_1000) && (!fullDuplex))
20310 + RETURN_ERROR(MAJOR, E_CONFLICT,
20311 + ("Ethernet MAC 1G or 10G does not support half-duplex"));
20312 +
20313 + fman_memac_adjust_link(p_Memac->p_MemMap,
20314 + (enum enet_interface)ENET_INTERFACE_FROM_MODE(p_Memac->enetMode),
20315 + (enum enet_speed)speed,
20316 + fullDuplex);
20317 + return E_OK;
20318 +}
20319 +
20320 +
20321 +/*****************************************************************************/
20322 +/* Memac Configs modification functions */
20323 +/*****************************************************************************/
20324 +
20325 +/* ......................................................................... */
20326 +
20327 +static t_Error MemacConfigLoopback(t_Handle h_Memac, bool newVal)
20328 +{
20329 + t_Memac *p_Memac = (t_Memac *)h_Memac;
20330 +
20331 + SANITY_CHECK_RETURN_ERROR(p_Memac, E_INVALID_HANDLE);
20332 + SANITY_CHECK_RETURN_ERROR(p_Memac->p_MemacDriverParam, E_INVALID_STATE);
20333 +
20334 + p_Memac->p_MemacDriverParam->loopback_enable = newVal;
20335 +
20336 + return E_OK;
20337 +}
20338 +
20339 +/* ......................................................................... */
20340 +
20341 +static t_Error MemacConfigWan(t_Handle h_Memac, bool newVal)
20342 +{
20343 + t_Memac *p_Memac = (t_Memac *)h_Memac;
20344 +
20345 + SANITY_CHECK_RETURN_ERROR(p_Memac, E_INVALID_HANDLE);
20346 + SANITY_CHECK_RETURN_ERROR(p_Memac->p_MemacDriverParam, E_INVALID_STATE);
20347 +
20348 + p_Memac->p_MemacDriverParam->wan_mode_enable = newVal;
20349 +
20350 + return E_OK;
20351 +}
20352 +
20353 +/* ......................................................................... */
20354 +
20355 +static t_Error MemacConfigMaxFrameLength(t_Handle h_Memac, uint16_t newVal)
20356 +{
20357 + t_Memac *p_Memac = (t_Memac *)h_Memac;
20358 +
20359 + SANITY_CHECK_RETURN_ERROR(p_Memac, E_INVALID_HANDLE);
20360 + SANITY_CHECK_RETURN_ERROR(p_Memac->p_MemacDriverParam, E_INVALID_STATE);
20361 +
20362 + p_Memac->p_MemacDriverParam->max_frame_length = newVal;
20363 +
20364 + return E_OK;
20365 +}
20366 +
20367 +/* ......................................................................... */
20368 +
20369 +static t_Error MemacConfigPad(t_Handle h_Memac, bool newVal)
20370 +{
20371 + t_Memac *p_Memac = (t_Memac *)h_Memac;
20372 +
20373 + SANITY_CHECK_RETURN_ERROR(p_Memac, E_INVALID_HANDLE);
20374 + SANITY_CHECK_RETURN_ERROR(p_Memac->p_MemacDriverParam, E_INVALID_STATE);
20375 +
20376 + p_Memac->p_MemacDriverParam->pad_enable = newVal;
20377 +
20378 + return E_OK;
20379 +}
20380 +
20381 +/* ......................................................................... */
20382 +
20383 +static t_Error MemacConfigLengthCheck(t_Handle h_Memac, bool newVal)
20384 +{
20385 + t_Memac *p_Memac = (t_Memac *)h_Memac;
20386 +
20387 + SANITY_CHECK_RETURN_ERROR(p_Memac, E_INVALID_HANDLE);
20388 + SANITY_CHECK_RETURN_ERROR(p_Memac->p_MemacDriverParam, E_INVALID_STATE);
20389 +
20390 + p_Memac->p_MemacDriverParam->no_length_check_enable = !newVal;
20391 +
20392 + return E_OK;
20393 +}
20394 +
20395 +/* ......................................................................... */
20396 +
20397 +static t_Error MemacConfigException(t_Handle h_Memac, e_FmMacExceptions exception, bool enable)
20398 +{
20399 + t_Memac *p_Memac = (t_Memac *)h_Memac;
20400 + uint32_t bitMask = 0;
20401 +
20402 + SANITY_CHECK_RETURN_ERROR(p_Memac, E_INVALID_HANDLE);
20403 + SANITY_CHECK_RETURN_ERROR(p_Memac->p_MemacDriverParam, E_INVALID_STATE);
20404 +
20405 + GET_EXCEPTION_FLAG(bitMask, exception);
20406 + if (bitMask)
20407 + {
20408 + if (enable)
20409 + p_Memac->exceptions |= bitMask;
20410 + else
20411 + p_Memac->exceptions &= ~bitMask;
20412 + }
20413 + else
20414 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Undefined exception"));
20415 +
20416 + return E_OK;
20417 +}
20418 +
20419 +/* ......................................................................... */
20420 +
20421 +static t_Error MemacConfigResetOnInit(t_Handle h_Memac, bool enable)
20422 +{
20423 + t_Memac *p_Memac = (t_Memac *)h_Memac;
20424 +
20425 + SANITY_CHECK_RETURN_ERROR(p_Memac, E_INVALID_HANDLE);
20426 + SANITY_CHECK_RETURN_ERROR(p_Memac->p_MemacDriverParam, E_INVALID_STATE);
20427 +
20428 + p_Memac->p_MemacDriverParam->reset_on_init = enable;
20429 +
20430 + return E_OK;
20431 +}
20432 +
20433 +
20434 +/*****************************************************************************/
20435 +/* Memac Run Time API functions */
20436 +/*****************************************************************************/
20437 +
20438 +/* ......................................................................... */
20439 +
20440 +static t_Error MemacSetTxPauseFrames(t_Handle h_Memac,
20441 + uint8_t priority,
20442 + uint16_t pauseTime,
20443 + uint16_t threshTime)
20444 +{
20445 + t_Memac *p_Memac = (t_Memac *)h_Memac;
20446 +
20447 + SANITY_CHECK_RETURN_ERROR(p_Memac, E_INVALID_STATE);
20448 + SANITY_CHECK_RETURN_ERROR(!p_Memac->p_MemacDriverParam, E_INVALID_STATE);
20449 +
20450 + if (priority != 0xFF)
20451 + {
20452 + bool PortConfigured, PreFetchEnabled;
20453 +
20454 + if (FmGetTnumAgingPeriod(p_Memac->fmMacControllerDriver.h_Fm) == 0)
20455 + RETURN_ERROR(MAJOR, E_CONFLICT, ("For PFC operation, TNUM aging must be enabled"));
20456 +
20457 + FmGetPortPreFetchConfiguration(p_Memac->fmMacControllerDriver.h_Fm,
20458 + p_Memac->fmMacControllerDriver.macId,
20459 + &PortConfigured,
20460 + &PreFetchEnabled);
20461 +
20462 + if ((ENET_SPEED_FROM_MODE(p_Memac->fmMacControllerDriver.enetMode) == e_ENET_SPEED_1000) && !PortConfigured)
20463 + DBG(INFO, ("For PFC correct operation, prefetch must be configured on the FM Tx PORT"));
20464 +
20465 + if ((ENET_SPEED_FROM_MODE(p_Memac->fmMacControllerDriver.enetMode) == e_ENET_SPEED_1000) && PortConfigured && !PreFetchEnabled)
20466 + DBG(WARNING, ("For PFC correct operation, prefetch must be configured on the FM Tx PORT"));
20467 + }
20468 +
20469 + fman_memac_set_tx_pause_frames(p_Memac->p_MemMap, priority, pauseTime, threshTime);
20470 +
20471 + return E_OK;
20472 +}
20473 +
20474 +/* ......................................................................... */
20475 +
20476 +static t_Error MemacSetTxAutoPauseFrames(t_Handle h_Memac,
20477 + uint16_t pauseTime)
20478 +{
20479 + return MemacSetTxPauseFrames(h_Memac, FM_MAC_NO_PFC, pauseTime, 0);
20480 +}
20481 +
20482 +/* ......................................................................... */
20483 +
20484 +static t_Error MemacSetRxIgnorePauseFrames(t_Handle h_Memac, bool en)
20485 +{
20486 + t_Memac *p_Memac = (t_Memac *)h_Memac;
20487 +
20488 + SANITY_CHECK_RETURN_ERROR(p_Memac, E_INVALID_STATE);
20489 + SANITY_CHECK_RETURN_ERROR(!p_Memac->p_MemacDriverParam, E_INVALID_STATE);
20490 +
20491 + fman_memac_set_rx_ignore_pause_frames(p_Memac->p_MemMap, en);
20492 +
20493 + return E_OK;
20494 +}
20495 +
20496 +/* ......................................................................... */
20497 +
20498 +static t_Error MemacSetWakeOnLan(t_Handle h_Memac, bool en)
20499 +{
20500 + t_Memac *p_Memac = (t_Memac *)h_Memac;
20501 +
20502 + SANITY_CHECK_RETURN_ERROR(p_Memac, E_INVALID_STATE);
20503 + SANITY_CHECK_RETURN_ERROR(!p_Memac->p_MemacDriverParam, E_INVALID_STATE);
20504 +
20505 + fman_memac_set_wol(p_Memac->p_MemMap, en);
20506 +
20507 + return E_OK;
20508 +}
20509 +
20510 +/* .............................................................................. */
20511 +
20512 +static t_Error MemacEnable1588TimeStamp(t_Handle h_Memac)
20513 +{
20514 + t_Memac *p_Memac = (t_Memac *)h_Memac;
20515 +
20516 + SANITY_CHECK_RETURN_ERROR(p_Memac, E_INVALID_HANDLE);
20517 + SANITY_CHECK_RETURN_ERROR(!p_Memac->p_MemacDriverParam, E_INVALID_STATE);
20518 +UNUSED(p_Memac);
20519 +DBG(WARNING, ("mEMAC has 1588 always enabled!"));
20520 +
20521 + return E_OK;
20522 +}
20523 +
20524 +/* Counters handling */
20525 +/* ......................................................................... */
20526 +
20527 +static t_Error MemacGetStatistics(t_Handle h_Memac, t_FmMacStatistics *p_Statistics)
20528 +{
20529 + t_Memac *p_Memac = (t_Memac *)h_Memac;
20530 +
20531 + SANITY_CHECK_RETURN_ERROR(p_Memac, E_NULL_POINTER);
20532 + SANITY_CHECK_RETURN_ERROR(!p_Memac->p_MemacDriverParam, E_INVALID_STATE);
20533 + SANITY_CHECK_RETURN_ERROR(p_Statistics, E_NULL_POINTER);
20534 +
20535 + p_Statistics->eStatPkts64 = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_R64);
20536 + p_Statistics->eStatPkts65to127 = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_R127);
20537 + p_Statistics->eStatPkts128to255 = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_R255);
20538 + p_Statistics->eStatPkts256to511 = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_R511);
20539 + p_Statistics->eStatPkts512to1023 = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_R1023);
20540 + p_Statistics->eStatPkts1024to1518 = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_R1518);
20541 + p_Statistics->eStatPkts1519to1522 = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_R1519X);
20542 +/* */
20543 + p_Statistics->eStatFragments = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_RFRG);
20544 + p_Statistics->eStatJabbers = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_RJBR);
20545 +
20546 + p_Statistics->eStatsDropEvents = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_RDRP);
20547 + p_Statistics->eStatCRCAlignErrors = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_RALN);
20548 +
20549 + p_Statistics->eStatUndersizePkts = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_TUND);
20550 + p_Statistics->eStatOversizePkts = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_ROVR);
20551 +/* Pause */
20552 + p_Statistics->reStatPause = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_RXPF);
20553 + p_Statistics->teStatPause = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_TXPF);
20554 +
20555 +/* MIB II */
20556 + p_Statistics->ifInOctets = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_ROCT);
20557 + p_Statistics->ifInUcastPkts = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_RUCA);
20558 + p_Statistics->ifInMcastPkts = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_RMCA);
20559 + p_Statistics->ifInBcastPkts = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_RBCA);
20560 + p_Statistics->ifInPkts = p_Statistics->ifInUcastPkts
20561 + + p_Statistics->ifInMcastPkts
20562 + + p_Statistics->ifInBcastPkts;
20563 + p_Statistics->ifInDiscards = 0;
20564 + p_Statistics->ifInErrors = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_RERR);
20565 +
20566 + p_Statistics->ifOutOctets = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_TOCT);
20567 + p_Statistics->ifOutUcastPkts = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_TUCA);
20568 + p_Statistics->ifOutMcastPkts = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_TMCA);
20569 + p_Statistics->ifOutBcastPkts = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_TBCA);
20570 + p_Statistics->ifOutPkts = p_Statistics->ifOutUcastPkts
20571 + + p_Statistics->ifOutMcastPkts
20572 + + p_Statistics->ifOutBcastPkts;
20573 + p_Statistics->ifOutDiscards = 0;
20574 + p_Statistics->ifOutErrors = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_TERR);
20575 +
20576 + return E_OK;
20577 +}
20578 +
20579 +/* ......................................................................... */
20580 +
20581 +static t_Error MemacGetFrameSizeCounters(t_Handle h_Memac, t_FmMacFrameSizeCounters *p_FrameSizeCounters, e_CommMode type)
20582 +{
20583 + t_Memac *p_Memac = (t_Memac *)h_Memac;
20584 +
20585 + SANITY_CHECK_RETURN_ERROR(p_Memac, E_NULL_POINTER);
20586 + SANITY_CHECK_RETURN_ERROR(!p_Memac->p_MemacDriverParam, E_INVALID_STATE);
20587 + SANITY_CHECK_RETURN_ERROR(p_FrameSizeCounters, E_NULL_POINTER);
20588 +
20589 + switch (type)
20590 + {
20591 + case e_COMM_MODE_NONE:
20592 + break;
20593 +
20594 + case e_COMM_MODE_RX:
20595 + p_FrameSizeCounters->count_pkts_64 = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_R64);
20596 + p_FrameSizeCounters->count_pkts_65_to_127 = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_R127);
20597 + p_FrameSizeCounters->count_pkts_128_to_255 = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_R255);
20598 + p_FrameSizeCounters->count_pkts_256_to_511 = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_R511);
20599 + p_FrameSizeCounters->count_pkts_512_to_1023 = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_R1023);
20600 + p_FrameSizeCounters->count_pkts_1024_to_1518 = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_R1518);
20601 + p_FrameSizeCounters->count_pkts_1519_to_1522 = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_R1519X);
20602 + break;
20603 +
20604 + case e_COMM_MODE_TX:
20605 + p_FrameSizeCounters->count_pkts_64 = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_T64);
20606 + p_FrameSizeCounters->count_pkts_65_to_127 = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_T127);
20607 + p_FrameSizeCounters->count_pkts_128_to_255 = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_T255);
20608 + p_FrameSizeCounters->count_pkts_256_to_511 = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_T511);
20609 + p_FrameSizeCounters->count_pkts_512_to_1023 = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_T1023);
20610 + p_FrameSizeCounters->count_pkts_1024_to_1518 = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_T1518);
20611 + p_FrameSizeCounters->count_pkts_1519_to_1522 = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_T1519X);
20612 + break;
20613 +
20614 + case e_COMM_MODE_RX_AND_TX:
20615 + p_FrameSizeCounters->count_pkts_64 = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_R64)
20616 + + fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_T64);
20617 + p_FrameSizeCounters->count_pkts_65_to_127 = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_R127)
20618 + + fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_T127);
20619 + p_FrameSizeCounters->count_pkts_128_to_255 = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_R255)
20620 + + fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_T255);
20621 + p_FrameSizeCounters->count_pkts_256_to_511 = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_R511)
20622 + + fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_T511);
20623 + p_FrameSizeCounters->count_pkts_512_to_1023 = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_R1023)
20624 + + fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_T1023);
20625 + p_FrameSizeCounters->count_pkts_1024_to_1518 = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_R1518)
20626 + + fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_T1518);
20627 + p_FrameSizeCounters->count_pkts_1519_to_1522 = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_R1519X)
20628 + + fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_T1519X);
20629 + break;
20630 + }
20631 +
20632 + return E_OK;
20633 +}
20634 +
20635 +/* ......................................................................... */
20636 +
20637 +static t_Error MemacModifyMacAddress (t_Handle h_Memac, t_EnetAddr *p_EnetAddr)
20638 +{
20639 + t_Memac *p_Memac = (t_Memac *)h_Memac;
20640 +
20641 + SANITY_CHECK_RETURN_ERROR(p_Memac, E_NULL_POINTER);
20642 + SANITY_CHECK_RETURN_ERROR(!p_Memac->p_MemacDriverParam, E_INVALID_STATE);
20643 +
20644 + fman_memac_add_addr_in_paddr(p_Memac->p_MemMap, (uint8_t *)(*p_EnetAddr), 0);
20645 +
20646 + return E_OK;
20647 +}
20648 +
20649 +/* ......................................................................... */
20650 +
20651 +static t_Error MemacResetCounters (t_Handle h_Memac)
20652 +{
20653 + t_Memac *p_Memac = (t_Memac *)h_Memac;
20654 +
20655 + SANITY_CHECK_RETURN_ERROR(p_Memac, E_INVALID_HANDLE);
20656 + SANITY_CHECK_RETURN_ERROR(!p_Memac->p_MemacDriverParam, E_INVALID_STATE);
20657 +
20658 + fman_memac_reset_stat(p_Memac->p_MemMap);
20659 +
20660 + return E_OK;
20661 +}
20662 +
20663 +/* ......................................................................... */
20664 +
20665 +static t_Error MemacAddExactMatchMacAddress(t_Handle h_Memac, t_EnetAddr *p_EthAddr)
20666 +{
20667 + t_Memac *p_Memac = (t_Memac *) h_Memac;
20668 + uint64_t ethAddr;
20669 + uint8_t paddrNum;
20670 +
20671 + SANITY_CHECK_RETURN_ERROR(p_Memac, E_INVALID_HANDLE);
20672 + SANITY_CHECK_RETURN_ERROR(!p_Memac->p_MemacDriverParam, E_INVALID_STATE);
20673 +
20674 + ethAddr = ENET_ADDR_TO_UINT64(*p_EthAddr);
20675 +
20676 + if (ethAddr & GROUP_ADDRESS)
20677 + /* Multicast address has no effect in PADDR */
20678 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Multicast address"));
20679 +
20680 + /* Make sure no PADDR contains this address */
20681 + for (paddrNum = 0; paddrNum < MEMAC_NUM_OF_PADDRS; paddrNum++)
20682 + if (p_Memac->indAddrRegUsed[paddrNum])
20683 + if (p_Memac->paddr[paddrNum] == ethAddr)
20684 + RETURN_ERROR(MAJOR, E_ALREADY_EXISTS, NO_MSG);
20685 +
20686 + /* Find first unused PADDR */
20687 + for (paddrNum = 0; paddrNum < MEMAC_NUM_OF_PADDRS; paddrNum++)
20688 + if (!(p_Memac->indAddrRegUsed[paddrNum]))
20689 + {
20690 + /* mark this PADDR as used */
20691 + p_Memac->indAddrRegUsed[paddrNum] = TRUE;
20692 + /* store address */
20693 + p_Memac->paddr[paddrNum] = ethAddr;
20694 +
20695 + /* put in hardware */
20696 + fman_memac_add_addr_in_paddr(p_Memac->p_MemMap, (uint8_t*)(*p_EthAddr), paddrNum);
20697 + p_Memac->numOfIndAddrInRegs++;
20698 +
20699 + return E_OK;
20700 + }
20701 +
20702 + /* No free PADDR */
20703 + RETURN_ERROR(MAJOR, E_FULL, NO_MSG);
20704 +}
20705 +
20706 +/* ......................................................................... */
20707 +
20708 +static t_Error MemacDelExactMatchMacAddress(t_Handle h_Memac, t_EnetAddr *p_EthAddr)
20709 +{
20710 + t_Memac *p_Memac = (t_Memac *) h_Memac;
20711 + uint64_t ethAddr;
20712 + uint8_t paddrNum;
20713 +
20714 + SANITY_CHECK_RETURN_ERROR(p_Memac, E_INVALID_HANDLE);
20715 + SANITY_CHECK_RETURN_ERROR(!p_Memac->p_MemacDriverParam, E_INVALID_STATE);
20716 +
20717 + ethAddr = ENET_ADDR_TO_UINT64(*p_EthAddr);
20718 +
20719 + /* Find used PADDR containing this address */
20720 + for (paddrNum = 0; paddrNum < MEMAC_NUM_OF_PADDRS; paddrNum++)
20721 + {
20722 + if ((p_Memac->indAddrRegUsed[paddrNum]) &&
20723 + (p_Memac->paddr[paddrNum] == ethAddr))
20724 + {
20725 + /* mark this PADDR as not used */
20726 + p_Memac->indAddrRegUsed[paddrNum] = FALSE;
20727 + /* clear in hardware */
20728 + fman_memac_clear_addr_in_paddr(p_Memac->p_MemMap, paddrNum);
20729 + p_Memac->numOfIndAddrInRegs--;
20730 +
20731 + return E_OK;
20732 + }
20733 + }
20734 +
20735 + RETURN_ERROR(MAJOR, E_NOT_FOUND, NO_MSG);
20736 +}
20737 +
20738 +/* ......................................................................... */
20739 +
20740 +static t_Error MemacGetId(t_Handle h_Memac, uint32_t *macId)
20741 +{
20742 + t_Memac *p_Memac = (t_Memac *)h_Memac;
20743 +
20744 + SANITY_CHECK_RETURN_ERROR(p_Memac, E_INVALID_HANDLE);
20745 + SANITY_CHECK_RETURN_ERROR(!p_Memac->p_MemacDriverParam, E_INVALID_STATE);
20746 +
20747 + *macId = p_Memac->macId;
20748 +
20749 + return E_OK;
20750 +}
20751 +
20752 +/* ......................................................................... */
20753 +
20754 +
20755 +static t_Error MemacAddHashMacAddress(t_Handle h_Memac, t_EnetAddr *p_EthAddr)
20756 +{
20757 + t_Memac *p_Memac = (t_Memac *)h_Memac;
20758 + t_EthHashEntry *p_HashEntry;
20759 + uint32_t hash;
20760 + uint64_t ethAddr;
20761 +
20762 + SANITY_CHECK_RETURN_ERROR(p_Memac, E_NULL_POINTER);
20763 + SANITY_CHECK_RETURN_ERROR(!p_Memac->p_MemacDriverParam, E_INVALID_STATE);
20764 +
20765 + ethAddr = ENET_ADDR_TO_UINT64(*p_EthAddr);
20766 +
20767 + if (!(ethAddr & GROUP_ADDRESS))
20768 + /* Unicast addresses not supported in hash */
20769 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("Unicast Address"));
20770 +
20771 + hash = GetMacAddrHashCode(ethAddr) & HASH_CTRL_ADDR_MASK;
20772 +
20773 + /* Create element to be added to the driver hash table */
20774 + p_HashEntry = (t_EthHashEntry *)XX_Malloc(sizeof(t_EthHashEntry));
20775 + p_HashEntry->addr = ethAddr;
20776 + INIT_LIST(&p_HashEntry->node);
20777 +
20778 + LIST_AddToTail(&(p_HashEntry->node), &(p_Memac->p_MulticastAddrHash->p_Lsts[hash]));
20779 + fman_memac_set_hash_table(p_Memac->p_MemMap, (hash | HASH_CTRL_MCAST_EN));
20780 +
20781 + return E_OK;
20782 +}
20783 +
20784 +/* ......................................................................... */
20785 +
20786 +static t_Error MemacDelHashMacAddress(t_Handle h_Memac, t_EnetAddr *p_EthAddr)
20787 +{
20788 + t_Memac *p_Memac = (t_Memac *)h_Memac;
20789 + t_EthHashEntry *p_HashEntry = NULL;
20790 + t_List *p_Pos;
20791 + uint32_t hash;
20792 + uint64_t ethAddr;
20793 +
20794 + SANITY_CHECK_RETURN_ERROR(p_Memac, E_NULL_POINTER);
20795 + SANITY_CHECK_RETURN_ERROR(!p_Memac->p_MemacDriverParam, E_INVALID_STATE);
20796 +
20797 + ethAddr = ENET_ADDR_TO_UINT64(*p_EthAddr);
20798 +
20799 + hash = GetMacAddrHashCode(ethAddr) & HASH_CTRL_ADDR_MASK;
20800 +
20801 + LIST_FOR_EACH(p_Pos, &(p_Memac->p_MulticastAddrHash->p_Lsts[hash]))
20802 + {
20803 + p_HashEntry = ETH_HASH_ENTRY_OBJ(p_Pos);
20804 + if (p_HashEntry->addr == ethAddr)
20805 + {
20806 + LIST_DelAndInit(&p_HashEntry->node);
20807 + XX_Free(p_HashEntry);
20808 + break;
20809 + }
20810 + }
20811 + if (LIST_IsEmpty(&p_Memac->p_MulticastAddrHash->p_Lsts[hash]))
20812 + fman_memac_set_hash_table(p_Memac->p_MemMap, (hash & ~HASH_CTRL_MCAST_EN));
20813 +
20814 + return E_OK;
20815 +}
20816 +
20817 +
20818 +/* ......................................................................... */
20819 +
20820 +static t_Error MemacSetException(t_Handle h_Memac, e_FmMacExceptions exception, bool enable)
20821 +{
20822 + t_Memac *p_Memac = (t_Memac *)h_Memac;
20823 + uint32_t bitMask = 0;
20824 +
20825 + SANITY_CHECK_RETURN_ERROR(p_Memac, E_INVALID_HANDLE);
20826 + SANITY_CHECK_RETURN_ERROR(!p_Memac->p_MemacDriverParam, E_INVALID_STATE);
20827 +
20828 + GET_EXCEPTION_FLAG(bitMask, exception);
20829 + if (bitMask)
20830 + {
20831 + if (enable)
20832 + p_Memac->exceptions |= bitMask;
20833 + else
20834 + p_Memac->exceptions &= ~bitMask;
20835 + }
20836 + else
20837 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Undefined exception"));
20838 +
20839 + fman_memac_set_exception(p_Memac->p_MemMap, bitMask, enable);
20840 +
20841 + return E_OK;
20842 +}
20843 +
20844 +/* ......................................................................... */
20845 +
20846 +static uint16_t MemacGetMaxFrameLength(t_Handle h_Memac)
20847 +{
20848 + t_Memac *p_Memac = (t_Memac *)h_Memac;
20849 +
20850 + SANITY_CHECK_RETURN_VALUE(p_Memac, E_INVALID_HANDLE, 0);
20851 + SANITY_CHECK_RETURN_VALUE(!p_Memac->p_MemacDriverParam, E_INVALID_STATE, 0);
20852 +
20853 + return fman_memac_get_max_frame_len(p_Memac->p_MemMap);
20854 +}
20855 +
20856 +static t_Error MemacInitInternalPhy(t_Handle h_Memac)
20857 +{
20858 + t_Memac *p_Memac = (t_Memac *)h_Memac;
20859 + uint8_t i, phyAddr;
20860 +
20861 + if (ENET_INTERFACE_FROM_MODE(p_Memac->enetMode) == e_ENET_IF_SGMII)
20862 + {
20863 + /* Configure internal SGMII PHY */
20864 + if (p_Memac->enetMode & ENET_IF_SGMII_BASEX)
20865 + SetupSgmiiInternalPhyBaseX(p_Memac, PHY_MDIO_ADDR);
20866 + else
20867 + SetupSgmiiInternalPhy(p_Memac, PHY_MDIO_ADDR);
20868 + }
20869 + else if (ENET_INTERFACE_FROM_MODE(p_Memac->enetMode) == e_ENET_IF_QSGMII)
20870 + {
20871 + /* Configure 4 internal SGMII PHYs */
20872 + for (i = 0; i < 4; i++)
20873 + {
20874 + /* QSGMII PHY address occupies 3 upper bits of 5-bit
20875 + phyAddress; the lower 2 bits are used to extend
20876 + register address space and access each one of 4
20877 + ports inside QSGMII. */
20878 + phyAddr = (uint8_t)((PHY_MDIO_ADDR << 2) | i);
20879 + if (p_Memac->enetMode & ENET_IF_SGMII_BASEX)
20880 + SetupSgmiiInternalPhyBaseX(p_Memac, phyAddr);
20881 + else
20882 + SetupSgmiiInternalPhy(p_Memac, phyAddr);
20883 + }
20884 + }
20885 + return E_OK;
20886 +}
20887 +
20888 +/*****************************************************************************/
20889 +/* mEMAC Init & Free API */
20890 +/*****************************************************************************/
20891 +
20892 +/* ......................................................................... */
20893 +void *g_MemacRegs;
20894 +static t_Error MemacInit(t_Handle h_Memac)
20895 +{
20896 + t_Memac *p_Memac = (t_Memac *)h_Memac;
20897 + struct memac_cfg *p_MemacDriverParam;
20898 + enum enet_interface enet_interface;
20899 + enum enet_speed enet_speed;
20900 + t_EnetAddr ethAddr;
20901 + e_FmMacType portType;
20902 + t_Error err;
20903 + bool slow_10g_if = FALSE;
20904 + if (p_Memac->macId == 3) /* This is a quick WA */
20905 + g_MemacRegs = p_Memac->p_MemMap;
20906 +
20907 + SANITY_CHECK_RETURN_ERROR(p_Memac, E_INVALID_HANDLE);
20908 + SANITY_CHECK_RETURN_ERROR(p_Memac->p_MemacDriverParam, E_INVALID_STATE);
20909 + SANITY_CHECK_RETURN_ERROR(p_Memac->fmMacControllerDriver.h_Fm, E_INVALID_HANDLE);
20910 +
20911 + FM_GetRevision(p_Memac->fmMacControllerDriver.h_Fm, &p_Memac->fmMacControllerDriver.fmRevInfo);
20912 + if (p_Memac->fmMacControllerDriver.fmRevInfo.majorRev == 6 &&
20913 + p_Memac->fmMacControllerDriver.fmRevInfo.minorRev == 4)
20914 + slow_10g_if = TRUE;
20915 +
20916 + CHECK_INIT_PARAMETERS(p_Memac, CheckInitParameters);
20917 +
20918 + p_MemacDriverParam = p_Memac->p_MemacDriverParam;
20919 +
20920 + portType =
20921 + ((ENET_SPEED_FROM_MODE(p_Memac->enetMode) < e_ENET_SPEED_10000) ? e_FM_MAC_1G : e_FM_MAC_10G);
20922 +
20923 + /* First, reset the MAC if desired. */
20924 + if (p_MemacDriverParam->reset_on_init)
20925 + fman_memac_reset(p_Memac->p_MemMap);
20926 +
20927 + /* MAC Address */
20928 + MAKE_ENET_ADDR_FROM_UINT64(p_Memac->addr, ethAddr);
20929 + fman_memac_add_addr_in_paddr(p_Memac->p_MemMap, (uint8_t*)ethAddr, 0);
20930 +
20931 + enet_interface = (enum enet_interface) ENET_INTERFACE_FROM_MODE(p_Memac->enetMode);
20932 + enet_speed = (enum enet_speed) ENET_SPEED_FROM_MODE(p_Memac->enetMode);
20933 +
20934 + fman_memac_init(p_Memac->p_MemMap,
20935 + p_Memac->p_MemacDriverParam,
20936 + enet_interface,
20937 + enet_speed,
20938 + slow_10g_if,
20939 + p_Memac->exceptions);
20940 +
20941 +#ifdef FM_RX_FIFO_CORRUPT_ERRATA_10GMAC_A006320
20942 + {
20943 + uint32_t tmpReg = 0;
20944 +
20945 + FM_GetRevision(p_Memac->fmMacControllerDriver.h_Fm, &p_Memac->fmMacControllerDriver.fmRevInfo);
20946 + /* check the FMAN version - the bug exists only in rev1 */
20947 + if ((p_Memac->fmMacControllerDriver.fmRevInfo.majorRev == 6) &&
20948 + (p_Memac->fmMacControllerDriver.fmRevInfo.minorRev == 0))
20949 + {
20950 + /* MAC strips CRC from received frames - this workaround should
20951 + decrease the likelihood of bug appearance
20952 + */
20953 + tmpReg = GET_UINT32(p_Memac->p_MemMap->command_config);
20954 + tmpReg &= ~CMD_CFG_CRC_FWD;
20955 + WRITE_UINT32(p_Memac->p_MemMap->command_config, tmpReg);
20956 + /* DBG(WARNING, ("mEMAC strips CRC from received frames as part of A006320 errata workaround"));*/
20957 + }
20958 + }
20959 +#endif /* FM_RX_FIFO_CORRUPT_ERRATA_10GMAC_A006320 */
20960 +
20961 + MemacInitInternalPhy(h_Memac);
20962 +
20963 + /* Max Frame Length */
20964 + err = FmSetMacMaxFrame(p_Memac->fmMacControllerDriver.h_Fm,
20965 + portType,
20966 + p_Memac->fmMacControllerDriver.macId,
20967 + p_MemacDriverParam->max_frame_length);
20968 + if (err)
20969 + RETURN_ERROR(MAJOR, err, ("settings Mac max frame length is FAILED"));
20970 +
20971 + p_Memac->p_MulticastAddrHash = AllocHashTable(HASH_TABLE_SIZE);
20972 + if (!p_Memac->p_MulticastAddrHash)
20973 + {
20974 + FreeInitResources(p_Memac);
20975 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("allocation hash table is FAILED"));
20976 + }
20977 +
20978 + p_Memac->p_UnicastAddrHash = AllocHashTable(HASH_TABLE_SIZE);
20979 + if (!p_Memac->p_UnicastAddrHash)
20980 + {
20981 + FreeInitResources(p_Memac);
20982 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("allocation hash table is FAILED"));
20983 + }
20984 +
20985 + FmRegisterIntr(p_Memac->fmMacControllerDriver.h_Fm,
20986 + (portType == e_FM_MAC_10G) ? e_FM_MOD_10G_MAC : e_FM_MOD_1G_MAC,
20987 + p_Memac->macId,
20988 + e_FM_INTR_TYPE_ERR,
20989 + MemacErrException,
20990 + p_Memac);
20991 +
20992 + FmRegisterIntr(p_Memac->fmMacControllerDriver.h_Fm,
20993 + (portType == e_FM_MAC_10G) ? e_FM_MOD_10G_MAC : e_FM_MOD_1G_MAC,
20994 + p_Memac->macId,
20995 + e_FM_INTR_TYPE_NORMAL,
20996 + MemacException,
20997 + p_Memac);
20998 +
20999 + XX_Free(p_MemacDriverParam);
21000 + p_Memac->p_MemacDriverParam = NULL;
21001 +
21002 + return E_OK;
21003 +}
21004 +
21005 +/* ......................................................................... */
21006 +
21007 +static t_Error MemacFree(t_Handle h_Memac)
21008 +{
21009 + t_Memac *p_Memac = (t_Memac *)h_Memac;
21010 +
21011 + SANITY_CHECK_RETURN_ERROR(p_Memac, E_INVALID_HANDLE);
21012 +
21013 + if (p_Memac->p_MemacDriverParam)
21014 + {
21015 + /* Called after config */
21016 + XX_Free(p_Memac->p_MemacDriverParam);
21017 + p_Memac->p_MemacDriverParam = NULL;
21018 + }
21019 + else
21020 + /* Called after init */
21021 + FreeInitResources(p_Memac);
21022 +
21023 + XX_Free(p_Memac);
21024 +
21025 + return E_OK;
21026 +}
21027 +
21028 +/* ......................................................................... */
21029 +
21030 +static void InitFmMacControllerDriver(t_FmMacControllerDriver *p_FmMacControllerDriver)
21031 +{
21032 + p_FmMacControllerDriver->f_FM_MAC_Init = MemacInit;
21033 + p_FmMacControllerDriver->f_FM_MAC_Free = MemacFree;
21034 +
21035 + p_FmMacControllerDriver->f_FM_MAC_SetStatistics = NULL;
21036 + p_FmMacControllerDriver->f_FM_MAC_ConfigLoopback = MemacConfigLoopback;
21037 + p_FmMacControllerDriver->f_FM_MAC_ConfigMaxFrameLength = MemacConfigMaxFrameLength;
21038 +
21039 + p_FmMacControllerDriver->f_FM_MAC_ConfigWan = MemacConfigWan;
21040 +
21041 + p_FmMacControllerDriver->f_FM_MAC_ConfigPadAndCrc = MemacConfigPad;
21042 + p_FmMacControllerDriver->f_FM_MAC_ConfigHalfDuplex = NULL; /* half-duplex is detected automatically */
21043 + p_FmMacControllerDriver->f_FM_MAC_ConfigLengthCheck = MemacConfigLengthCheck;
21044 +
21045 + p_FmMacControllerDriver->f_FM_MAC_ConfigException = MemacConfigException;
21046 + p_FmMacControllerDriver->f_FM_MAC_ConfigResetOnInit = MemacConfigResetOnInit;
21047 +
21048 + p_FmMacControllerDriver->f_FM_MAC_SetException = MemacSetException;
21049 +
21050 + p_FmMacControllerDriver->f_FM_MAC_Enable1588TimeStamp = MemacEnable1588TimeStamp; /* always enabled */
21051 + p_FmMacControllerDriver->f_FM_MAC_Disable1588TimeStamp = NULL;
21052 +
21053 + p_FmMacControllerDriver->f_FM_MAC_SetPromiscuous = MemacSetPromiscuous;
21054 + p_FmMacControllerDriver->f_FM_MAC_AdjustLink = MemacAdjustLink;
21055 + p_FmMacControllerDriver->f_FM_MAC_RestartAutoneg = NULL;
21056 +
21057 + p_FmMacControllerDriver->f_FM_MAC_Enable = MemacEnable;
21058 + p_FmMacControllerDriver->f_FM_MAC_Disable = MemacDisable;
21059 + p_FmMacControllerDriver->f_FM_MAC_Resume = MemacInitInternalPhy;
21060 +
21061 + p_FmMacControllerDriver->f_FM_MAC_SetTxAutoPauseFrames = MemacSetTxAutoPauseFrames;
21062 + p_FmMacControllerDriver->f_FM_MAC_SetTxPauseFrames = MemacSetTxPauseFrames;
21063 + p_FmMacControllerDriver->f_FM_MAC_SetRxIgnorePauseFrames = MemacSetRxIgnorePauseFrames;
21064 +
21065 + p_FmMacControllerDriver->f_FM_MAC_SetWakeOnLan = MemacSetWakeOnLan;
21066 +
21067 + p_FmMacControllerDriver->f_FM_MAC_ResetCounters = MemacResetCounters;
21068 + p_FmMacControllerDriver->f_FM_MAC_GetStatistics = MemacGetStatistics;
21069 + p_FmMacControllerDriver->f_FM_MAC_GetFrameSizeCounters = MemacGetFrameSizeCounters;
21070 +
21071 + p_FmMacControllerDriver->f_FM_MAC_ModifyMacAddr = MemacModifyMacAddress;
21072 + p_FmMacControllerDriver->f_FM_MAC_AddHashMacAddr = MemacAddHashMacAddress;
21073 + p_FmMacControllerDriver->f_FM_MAC_RemoveHashMacAddr = MemacDelHashMacAddress;
21074 + p_FmMacControllerDriver->f_FM_MAC_AddExactMatchMacAddr = MemacAddExactMatchMacAddress;
21075 + p_FmMacControllerDriver->f_FM_MAC_RemovelExactMatchMacAddr = MemacDelExactMatchMacAddress;
21076 + p_FmMacControllerDriver->f_FM_MAC_GetId = MemacGetId;
21077 + p_FmMacControllerDriver->f_FM_MAC_GetVersion = NULL;
21078 + p_FmMacControllerDriver->f_FM_MAC_GetMaxFrameLength = MemacGetMaxFrameLength;
21079 +
21080 + p_FmMacControllerDriver->f_FM_MAC_MII_WritePhyReg = MEMAC_MII_WritePhyReg;
21081 + p_FmMacControllerDriver->f_FM_MAC_MII_ReadPhyReg = MEMAC_MII_ReadPhyReg;
21082 +}
21083 +
21084 +
21085 +/*****************************************************************************/
21086 +/* mEMAC Config Main Entry */
21087 +/*****************************************************************************/
21088 +
21089 +/* ......................................................................... */
21090 +
21091 +t_Handle MEMAC_Config(t_FmMacParams *p_FmMacParam)
21092 +{
21093 + t_Memac *p_Memac;
21094 + struct memac_cfg *p_MemacDriverParam;
21095 + uintptr_t baseAddr;
21096 +
21097 + SANITY_CHECK_RETURN_VALUE(p_FmMacParam, E_NULL_POINTER, NULL);
21098 +
21099 + baseAddr = p_FmMacParam->baseAddr;
21100 + /* Allocate memory for the mEMAC data structure */
21101 + p_Memac = (t_Memac *)XX_Malloc(sizeof(t_Memac));
21102 + if (!p_Memac)
21103 + {
21104 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("mEMAC driver structure"));
21105 + return NULL;
21106 + }
21107 + memset(p_Memac, 0, sizeof(t_Memac));
21108 + InitFmMacControllerDriver(&p_Memac->fmMacControllerDriver);
21109 +
21110 + /* Allocate memory for the mEMAC driver parameters data structure */
21111 + p_MemacDriverParam = (struct memac_cfg *)XX_Malloc(sizeof(struct memac_cfg));
21112 + if (!p_MemacDriverParam)
21113 + {
21114 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("mEMAC driver parameters"));
21115 + XX_Free(p_Memac);
21116 + return NULL;
21117 + }
21118 + memset(p_MemacDriverParam, 0, sizeof(struct memac_cfg));
21119 +
21120 + /* Plant parameter structure pointer */
21121 + p_Memac->p_MemacDriverParam = p_MemacDriverParam;
21122 +
21123 + fman_memac_defconfig(p_MemacDriverParam);
21124 +
21125 + p_Memac->addr = ENET_ADDR_TO_UINT64(p_FmMacParam->addr);
21126 +
21127 + p_Memac->p_MemMap = (struct memac_regs *)UINT_TO_PTR(baseAddr);
21128 + p_Memac->p_MiiMemMap = (struct memac_mii_access_mem_map*)UINT_TO_PTR(baseAddr + MEMAC_TO_MII_OFFSET);
21129 +
21130 + p_Memac->enetMode = p_FmMacParam->enetMode;
21131 + p_Memac->macId = p_FmMacParam->macId;
21132 + p_Memac->exceptions = MEMAC_default_exceptions;
21133 + p_Memac->f_Exception = p_FmMacParam->f_Exception;
21134 + p_Memac->f_Event = p_FmMacParam->f_Event;
21135 + p_Memac->h_App = p_FmMacParam->h_App;
21136 +
21137 + return p_Memac;
21138 +}
21139 --- /dev/null
21140 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/memac.h
21141 @@ -0,0 +1,110 @@
21142 +/*
21143 + * Copyright 2008-2012 Freescale Semiconductor Inc.
21144 + *
21145 + * Redistribution and use in source and binary forms, with or without
21146 + * modification, are permitted provided that the following conditions are met:
21147 + * * Redistributions of source code must retain the above copyright
21148 + * notice, this list of conditions and the following disclaimer.
21149 + * * Redistributions in binary form must reproduce the above copyright
21150 + * notice, this list of conditions and the following disclaimer in the
21151 + * documentation and/or other materials provided with the distribution.
21152 + * * Neither the name of Freescale Semiconductor nor the
21153 + * names of its contributors may be used to endorse or promote products
21154 + * derived from this software without specific prior written permission.
21155 + *
21156 + *
21157 + * ALTERNATIVELY, this software may be distributed under the terms of the
21158 + * GNU General Public License ("GPL") as published by the Free Software
21159 + * Foundation, either version 2 of that License or (at your option) any
21160 + * later version.
21161 + *
21162 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
21163 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
21164 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
21165 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
21166 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21167 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
21168 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
21169 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
21170 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
21171 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
21172 + */
21173 +
21174 +
21175 +/******************************************************************************
21176 + @File memac.h
21177 +
21178 + @Description FM Multirate Ethernet MAC (mEMAC)
21179 +*//***************************************************************************/
21180 +#ifndef __MEMAC_H
21181 +#define __MEMAC_H
21182 +
21183 +#include "std_ext.h"
21184 +#include "error_ext.h"
21185 +#include "list_ext.h"
21186 +
21187 +#include "fsl_fman_memac_mii_acc.h"
21188 +#include "fm_mac.h"
21189 +#include "fsl_fman_memac.h"
21190 +
21191 +
21192 +#define MEMAC_default_exceptions \
21193 + ((uint32_t)(MEMAC_IMASK_TSECC_ER | MEMAC_IMASK_TECC_ER | MEMAC_IMASK_RECC_ER | MEMAC_IMASK_MGI))
21194 +
21195 +#define GET_EXCEPTION_FLAG(bitMask, exception) switch (exception){ \
21196 + case e_FM_MAC_EX_10G_1TX_ECC_ER: \
21197 + bitMask = MEMAC_IMASK_TECC_ER; break; \
21198 + case e_FM_MAC_EX_10G_RX_ECC_ER: \
21199 + bitMask = MEMAC_IMASK_RECC_ER; break; \
21200 + case e_FM_MAC_EX_TS_FIFO_ECC_ERR: \
21201 + bitMask = MEMAC_IMASK_TSECC_ER; break; \
21202 + case e_FM_MAC_EX_MAGIC_PACKET_INDICATION: \
21203 + bitMask = MEMAC_IMASK_MGI; break; \
21204 + default: bitMask = 0;break;}
21205 +
21206 +
21207 +typedef struct
21208 +{
21209 + t_FmMacControllerDriver fmMacControllerDriver; /**< Upper Mac control block */
21210 + t_Handle h_App; /**< Handle to the upper layer application */
21211 + struct memac_regs *p_MemMap; /**< Pointer to MAC memory mapped registers */
21212 + struct memac_mii_access_mem_map *p_MiiMemMap; /**< Pointer to MII memory mapped registers */
21213 + uint64_t addr; /**< MAC address of device */
21214 + e_EnetMode enetMode; /**< Ethernet physical interface */
21215 + t_FmMacExceptionCallback *f_Exception;
21216 + int mdioIrq;
21217 + t_FmMacExceptionCallback *f_Event;
21218 + bool indAddrRegUsed[MEMAC_NUM_OF_PADDRS]; /**< Whether a particular individual address recognition register is being used */
21219 + uint64_t paddr[MEMAC_NUM_OF_PADDRS]; /**< MAC address for particular individual address recognition register */
21220 + uint8_t numOfIndAddrInRegs; /**< Number of individual addresses in registers for this station. */
21221 + t_EthHash *p_MulticastAddrHash; /**< Pointer to driver's global address hash table */
21222 + t_EthHash *p_UnicastAddrHash; /**< Pointer to driver's individual address hash table */
21223 + bool debugMode;
21224 + uint8_t macId;
21225 + uint32_t exceptions;
21226 + struct memac_cfg *p_MemacDriverParam;
21227 +} t_Memac;
21228 +
21229 +
21230 +/* Internal PHY access */
21231 +#define PHY_MDIO_ADDR 0
21232 +
21233 +/* Internal PHY Registers - SGMII */
21234 +#define PHY_SGMII_CR_PHY_RESET 0x8000
21235 +#define PHY_SGMII_CR_RESET_AN 0x0200
21236 +#define PHY_SGMII_CR_DEF_VAL 0x1140
21237 +#define PHY_SGMII_DEV_ABILITY_SGMII 0x4001
21238 +#define PHY_SGMII_DEV_ABILITY_1000X 0x01A0
21239 +#define PHY_SGMII_IF_SPEED_GIGABIT 0x0008
21240 +#define PHY_SGMII_IF_MODE_AN 0x0002
21241 +#define PHY_SGMII_IF_MODE_SGMII 0x0001
21242 +#define PHY_SGMII_IF_MODE_1000X 0x0000
21243 +
21244 +
21245 +#define MEMAC_TO_MII_OFFSET 0x030 /* Offset from the MEM map to the MDIO mem map */
21246 +
21247 +t_Error MEMAC_MII_WritePhyReg(t_Handle h_Memac, uint8_t phyAddr, uint8_t reg, uint16_t data);
21248 +t_Error MEMAC_MII_ReadPhyReg(t_Handle h_Memac, uint8_t phyAddr, uint8_t reg, uint16_t *p_Data);
21249 +
21250 +
21251 +#endif /* __MEMAC_H */
21252 --- /dev/null
21253 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/memac_mii_acc.c
21254 @@ -0,0 +1,78 @@
21255 +/*
21256 + * Copyright 2008-2012 Freescale Semiconductor Inc.
21257 + *
21258 + * Redistribution and use in source and binary forms, with or without
21259 + * modification, are permitted provided that the following conditions are met:
21260 + * * Redistributions of source code must retain the above copyright
21261 + * notice, this list of conditions and the following disclaimer.
21262 + * * Redistributions in binary form must reproduce the above copyright
21263 + * notice, this list of conditions and the following disclaimer in the
21264 + * documentation and/or other materials provided with the distribution.
21265 + * * Neither the name of Freescale Semiconductor nor the
21266 + * names of its contributors may be used to endorse or promote products
21267 + * derived from this software without specific prior written permission.
21268 + *
21269 + *
21270 + * ALTERNATIVELY, this software may be distributed under the terms of the
21271 + * GNU General Public License ("GPL") as published by the Free Software
21272 + * Foundation, either version 2 of that License or (at your option) any
21273 + * later version.
21274 + *
21275 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
21276 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
21277 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
21278 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
21279 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21280 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
21281 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
21282 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
21283 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
21284 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
21285 + */
21286 +
21287 +
21288 +#include "error_ext.h"
21289 +#include "std_ext.h"
21290 +#include "fm_mac.h"
21291 +#include "memac.h"
21292 +#include "xx_ext.h"
21293 +
21294 +#include "fm_common.h"
21295 +#include "memac_mii_acc.h"
21296 +
21297 +
21298 +/*****************************************************************************/
21299 +t_Error MEMAC_MII_WritePhyReg(t_Handle h_Memac,
21300 + uint8_t phyAddr,
21301 + uint8_t reg,
21302 + uint16_t data)
21303 +{
21304 + t_Memac *p_Memac = (t_Memac *)h_Memac;
21305 +
21306 + SANITY_CHECK_RETURN_ERROR(p_Memac, E_INVALID_HANDLE);
21307 + SANITY_CHECK_RETURN_ERROR(p_Memac->p_MiiMemMap, E_INVALID_HANDLE);
21308 +
21309 + return (t_Error)fman_memac_mii_write_phy_reg(p_Memac->p_MiiMemMap,
21310 + phyAddr,
21311 + reg,
21312 + data,
21313 + (enum enet_speed)ENET_SPEED_FROM_MODE(p_Memac->enetMode));
21314 +}
21315 +
21316 +/*****************************************************************************/
21317 +t_Error MEMAC_MII_ReadPhyReg(t_Handle h_Memac,
21318 + uint8_t phyAddr,
21319 + uint8_t reg,
21320 + uint16_t *p_Data)
21321 +{
21322 + t_Memac *p_Memac = (t_Memac *)h_Memac;
21323 +
21324 + SANITY_CHECK_RETURN_ERROR(p_Memac, E_INVALID_HANDLE);
21325 + SANITY_CHECK_RETURN_ERROR(p_Memac->p_MiiMemMap, E_INVALID_HANDLE);
21326 +
21327 + return fman_memac_mii_read_phy_reg(p_Memac->p_MiiMemMap,
21328 + phyAddr,
21329 + reg,
21330 + p_Data,
21331 + (enum enet_speed)ENET_SPEED_FROM_MODE(p_Memac->enetMode));
21332 +}
21333 --- /dev/null
21334 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/memac_mii_acc.h
21335 @@ -0,0 +1,73 @@
21336 +/*
21337 + * Copyright 2008-2012 Freescale Semiconductor Inc.
21338 + *
21339 + * Redistribution and use in source and binary forms, with or without
21340 + * modification, are permitted provided that the following conditions are met:
21341 + * * Redistributions of source code must retain the above copyright
21342 + * notice, this list of conditions and the following disclaimer.
21343 + * * Redistributions in binary form must reproduce the above copyright
21344 + * notice, this list of conditions and the following disclaimer in the
21345 + * documentation and/or other materials provided with the distribution.
21346 + * * Neither the name of Freescale Semiconductor nor the
21347 + * names of its contributors may be used to endorse or promote products
21348 + * derived from this software without specific prior written permission.
21349 + *
21350 + *
21351 + * ALTERNATIVELY, this software may be distributed under the terms of the
21352 + * GNU General Public License ("GPL") as published by the Free Software
21353 + * Foundation, either version 2 of that License or (at your option) any
21354 + * later version.
21355 + *
21356 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
21357 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
21358 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
21359 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
21360 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21361 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
21362 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
21363 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
21364 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
21365 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
21366 + */
21367 +
21368 +
21369 +#ifndef __MEMAC_MII_ACC_H
21370 +#define __MEMAC_MII_ACC_H
21371 +
21372 +#include "std_ext.h"
21373 +
21374 +
21375 +/* MII Management Registers */
21376 +#define MDIO_CFG_CLK_DIV_MASK 0x0080ff80
21377 +#define MDIO_CFG_CLK_DIV_SHIFT 7
21378 +#define MDIO_CFG_HOLD_MASK 0x0000001c
21379 +#define MDIO_CFG_ENC45 0x00000040
21380 +#define MDIO_CFG_READ_ERR 0x00000002
21381 +#define MDIO_CFG_BSY 0x00000001
21382 +
21383 +#define MDIO_CTL_PHY_ADDR_SHIFT 5
21384 +#define MDIO_CTL_READ 0x00008000
21385 +
21386 +#define MDIO_DATA_BSY 0x80000000
21387 +
21388 +#if defined(__MWERKS__) && !defined(__GNUC__)
21389 +#pragma pack(push,1)
21390 +#endif /* defined(__MWERKS__) && ... */
21391 +
21392 +/*----------------------------------------------------*/
21393 +/* MII Configuration Control Memory Map Registers */
21394 +/*----------------------------------------------------*/
21395 +typedef struct t_MemacMiiAccessMemMap
21396 +{
21397 + volatile uint32_t mdio_cfg; /* 0x030 */
21398 + volatile uint32_t mdio_ctrl; /* 0x034 */
21399 + volatile uint32_t mdio_data; /* 0x038 */
21400 + volatile uint32_t mdio_addr; /* 0x03c */
21401 +} t_MemacMiiAccessMemMap ;
21402 +
21403 +#if defined(__MWERKS__) && !defined(__GNUC__)
21404 +#pragma pack(pop)
21405 +#endif /* defined(__MWERKS__) && ... */
21406 +
21407 +
21408 +#endif /* __MEMAC_MII_ACC_H */
21409 --- /dev/null
21410 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/tgec.c
21411 @@ -0,0 +1,1017 @@
21412 +/*
21413 + * Copyright 2008-2012 Freescale Semiconductor Inc.
21414 + *
21415 + * Redistribution and use in source and binary forms, with or without
21416 + * modification, are permitted provided that the following conditions are met:
21417 + * * Redistributions of source code must retain the above copyright
21418 + * notice, this list of conditions and the following disclaimer.
21419 + * * Redistributions in binary form must reproduce the above copyright
21420 + * notice, this list of conditions and the following disclaimer in the
21421 + * documentation and/or other materials provided with the distribution.
21422 + * * Neither the name of Freescale Semiconductor nor the
21423 + * names of its contributors may be used to endorse or promote products
21424 + * derived from this software without specific prior written permission.
21425 + *
21426 + *
21427 + * ALTERNATIVELY, this software may be distributed under the terms of the
21428 + * GNU General Public License ("GPL") as published by the Free Software
21429 + * Foundation, either version 2 of that License or (at your option) any
21430 + * later version.
21431 + *
21432 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
21433 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
21434 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
21435 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
21436 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21437 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
21438 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
21439 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
21440 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
21441 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
21442 + */
21443 +
21444 +
21445 +/******************************************************************************
21446 + @File tgec.c
21447 +
21448 + @Description FM 10G MAC ...
21449 +*//***************************************************************************/
21450 +
21451 +#include "std_ext.h"
21452 +#include "string_ext.h"
21453 +#include "error_ext.h"
21454 +#include "xx_ext.h"
21455 +#include "endian_ext.h"
21456 +#include "debug_ext.h"
21457 +#include "crc_mac_addr_ext.h"
21458 +
21459 +#include "fm_common.h"
21460 +#include "fsl_fman_tgec.h"
21461 +#include "tgec.h"
21462 +
21463 +
21464 +/*****************************************************************************/
21465 +/* Internal routines */
21466 +/*****************************************************************************/
21467 +
21468 +static t_Error CheckInitParameters(t_Tgec *p_Tgec)
21469 +{
21470 + if (ENET_SPEED_FROM_MODE(p_Tgec->enetMode) < e_ENET_SPEED_10000)
21471 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Ethernet 10G MAC driver only support 10G speed"));
21472 +#if (FM_MAX_NUM_OF_10G_MACS > 0)
21473 + if (p_Tgec->macId >= FM_MAX_NUM_OF_10G_MACS)
21474 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("macId of 10G can not be greater than 0"));
21475 +#endif /* (FM_MAX_NUM_OF_10G_MACS > 0) */
21476 +
21477 + if (p_Tgec->addr == 0)
21478 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Ethernet 10G MAC Must have a valid MAC Address"));
21479 + if (!p_Tgec->f_Exception)
21480 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("uninitialized f_Exception"));
21481 + if (!p_Tgec->f_Event)
21482 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("uninitialized f_Event"));
21483 +#ifdef FM_LEN_CHECK_ERRATA_FMAN_SW002
21484 + if (!p_Tgec->p_TgecDriverParam->no_length_check_enable)
21485 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("LengthCheck!"));
21486 +#endif /* FM_LEN_CHECK_ERRATA_FMAN_SW002 */
21487 + return E_OK;
21488 +}
21489 +
21490 +/* ......................................................................... */
21491 +
21492 +static uint32_t GetMacAddrHashCode(uint64_t ethAddr)
21493 +{
21494 + uint32_t crc;
21495 +
21496 + /* CRC calculation */
21497 + GET_MAC_ADDR_CRC(ethAddr, crc);
21498 +
21499 + crc = GetMirror32(crc);
21500 +
21501 + return crc;
21502 +}
21503 +
21504 +/* ......................................................................... */
21505 +
21506 +static void TgecErrException(t_Handle h_Tgec)
21507 +{
21508 + t_Tgec *p_Tgec = (t_Tgec *)h_Tgec;
21509 + uint32_t event;
21510 + struct tgec_regs *p_TgecMemMap = p_Tgec->p_MemMap;
21511 +
21512 + /* do not handle MDIO events */
21513 + event = fman_tgec_get_event(p_TgecMemMap, ~(TGEC_IMASK_MDIO_SCAN_EVENT | TGEC_IMASK_MDIO_CMD_CMPL));
21514 + event &= fman_tgec_get_interrupt_mask(p_TgecMemMap);
21515 +
21516 + fman_tgec_ack_event(p_TgecMemMap, event);
21517 +
21518 + if (event & TGEC_IMASK_REM_FAULT)
21519 + p_Tgec->f_Exception(p_Tgec->h_App, e_FM_MAC_EX_10G_REM_FAULT);
21520 + if (event & TGEC_IMASK_LOC_FAULT)
21521 + p_Tgec->f_Exception(p_Tgec->h_App, e_FM_MAC_EX_10G_LOC_FAULT);
21522 + if (event & TGEC_IMASK_TX_ECC_ER)
21523 + p_Tgec->f_Exception(p_Tgec->h_App, e_FM_MAC_EX_10G_1TX_ECC_ER);
21524 + if (event & TGEC_IMASK_TX_FIFO_UNFL)
21525 + p_Tgec->f_Exception(p_Tgec->h_App, e_FM_MAC_EX_10G_TX_FIFO_UNFL);
21526 + if (event & TGEC_IMASK_TX_FIFO_OVFL)
21527 + p_Tgec->f_Exception(p_Tgec->h_App, e_FM_MAC_EX_10G_TX_FIFO_OVFL);
21528 + if (event & TGEC_IMASK_TX_ER)
21529 + p_Tgec->f_Exception(p_Tgec->h_App, e_FM_MAC_EX_10G_TX_ER);
21530 + if (event & TGEC_IMASK_RX_FIFO_OVFL)
21531 + p_Tgec->f_Exception(p_Tgec->h_App, e_FM_MAC_EX_10G_RX_FIFO_OVFL);
21532 + if (event & TGEC_IMASK_RX_ECC_ER)
21533 + p_Tgec->f_Exception(p_Tgec->h_App, e_FM_MAC_EX_10G_RX_ECC_ER);
21534 + if (event & TGEC_IMASK_RX_JAB_FRM)
21535 + p_Tgec->f_Exception(p_Tgec->h_App, e_FM_MAC_EX_10G_RX_JAB_FRM);
21536 + if (event & TGEC_IMASK_RX_OVRSZ_FRM)
21537 + p_Tgec->f_Exception(p_Tgec->h_App, e_FM_MAC_EX_10G_RX_OVRSZ_FRM);
21538 + if (event & TGEC_IMASK_RX_RUNT_FRM)
21539 + p_Tgec->f_Exception(p_Tgec->h_App, e_FM_MAC_EX_10G_RX_RUNT_FRM);
21540 + if (event & TGEC_IMASK_RX_FRAG_FRM)
21541 + p_Tgec->f_Exception(p_Tgec->h_App, e_FM_MAC_EX_10G_RX_FRAG_FRM);
21542 + if (event & TGEC_IMASK_RX_LEN_ER)
21543 + p_Tgec->f_Exception(p_Tgec->h_App, e_FM_MAC_EX_10G_RX_LEN_ER);
21544 + if (event & TGEC_IMASK_RX_CRC_ER)
21545 + p_Tgec->f_Exception(p_Tgec->h_App, e_FM_MAC_EX_10G_RX_CRC_ER);
21546 + if (event & TGEC_IMASK_RX_ALIGN_ER)
21547 + p_Tgec->f_Exception(p_Tgec->h_App, e_FM_MAC_EX_10G_RX_ALIGN_ER);
21548 +}
21549 +
21550 +/* ......................................................................... */
21551 +
21552 +static void TgecException(t_Handle h_Tgec)
21553 +{
21554 + t_Tgec *p_Tgec = (t_Tgec *)h_Tgec;
21555 + uint32_t event;
21556 + struct tgec_regs *p_TgecMemMap = p_Tgec->p_MemMap;
21557 +
21558 + /* handle only MDIO events */
21559 + event = fman_tgec_get_event(p_TgecMemMap, (TGEC_IMASK_MDIO_SCAN_EVENT | TGEC_IMASK_MDIO_CMD_CMPL));
21560 + event &= fman_tgec_get_interrupt_mask(p_TgecMemMap);
21561 +
21562 + fman_tgec_ack_event(p_TgecMemMap, event);
21563 +
21564 + if (event & TGEC_IMASK_MDIO_SCAN_EVENT)
21565 + p_Tgec->f_Event(p_Tgec->h_App, e_FM_MAC_EX_10G_MDIO_SCAN_EVENTMDIO);
21566 + if (event & TGEC_IMASK_MDIO_CMD_CMPL)
21567 + p_Tgec->f_Event(p_Tgec->h_App, e_FM_MAC_EX_10G_MDIO_CMD_CMPL);
21568 +}
21569 +
21570 +/* ......................................................................... */
21571 +
21572 +static void FreeInitResources(t_Tgec *p_Tgec)
21573 +{
21574 + if (p_Tgec->mdioIrq != NO_IRQ)
21575 + {
21576 + XX_DisableIntr(p_Tgec->mdioIrq);
21577 + XX_FreeIntr(p_Tgec->mdioIrq);
21578 + }
21579 +
21580 + FmUnregisterIntr(p_Tgec->fmMacControllerDriver.h_Fm, e_FM_MOD_10G_MAC, p_Tgec->macId, e_FM_INTR_TYPE_ERR);
21581 +
21582 + /* release the driver's group hash table */
21583 + FreeHashTable(p_Tgec->p_MulticastAddrHash);
21584 + p_Tgec->p_MulticastAddrHash = NULL;
21585 +
21586 + /* release the driver's individual hash table */
21587 + FreeHashTable(p_Tgec->p_UnicastAddrHash);
21588 + p_Tgec->p_UnicastAddrHash = NULL;
21589 +}
21590 +
21591 +
21592 +/*****************************************************************************/
21593 +/* 10G MAC API routines */
21594 +/*****************************************************************************/
21595 +
21596 +/* ......................................................................... */
21597 +
21598 +static t_Error TgecEnable(t_Handle h_Tgec, e_CommMode mode)
21599 +{
21600 + t_Tgec *p_Tgec = (t_Tgec *)h_Tgec;
21601 +
21602 + SANITY_CHECK_RETURN_ERROR(p_Tgec, E_INVALID_HANDLE);
21603 + SANITY_CHECK_RETURN_ERROR(!p_Tgec->p_TgecDriverParam, E_INVALID_STATE);
21604 +
21605 + fman_tgec_enable(p_Tgec->p_MemMap, (mode & e_COMM_MODE_RX), (mode & e_COMM_MODE_TX));
21606 +
21607 + return E_OK;
21608 +}
21609 +
21610 +/* ......................................................................... */
21611 +
21612 +static t_Error TgecDisable (t_Handle h_Tgec, e_CommMode mode)
21613 +{
21614 + t_Tgec *p_Tgec = (t_Tgec *)h_Tgec;
21615 +
21616 + SANITY_CHECK_RETURN_ERROR(p_Tgec, E_INVALID_HANDLE);
21617 + SANITY_CHECK_RETURN_ERROR(!p_Tgec->p_TgecDriverParam, E_INVALID_STATE);
21618 +
21619 + fman_tgec_disable(p_Tgec->p_MemMap, (mode & e_COMM_MODE_RX), (mode & e_COMM_MODE_TX));
21620 +
21621 + return E_OK;
21622 +}
21623 +
21624 +/* ......................................................................... */
21625 +
21626 +static t_Error TgecSetPromiscuous(t_Handle h_Tgec, bool newVal)
21627 +{
21628 + t_Tgec *p_Tgec = (t_Tgec *)h_Tgec;
21629 +
21630 + SANITY_CHECK_RETURN_ERROR(p_Tgec, E_INVALID_HANDLE);
21631 + SANITY_CHECK_RETURN_ERROR(!p_Tgec->p_TgecDriverParam, E_INVALID_STATE);
21632 +
21633 + fman_tgec_set_promiscuous(p_Tgec->p_MemMap, newVal);
21634 +
21635 + return E_OK;
21636 +}
21637 +
21638 +
21639 +/*****************************************************************************/
21640 +/* Tgec Configs modification functions */
21641 +/*****************************************************************************/
21642 +
21643 +/* ......................................................................... */
21644 +
21645 +static t_Error TgecConfigLoopback(t_Handle h_Tgec, bool newVal)
21646 +{
21647 + t_Tgec *p_Tgec = (t_Tgec *)h_Tgec;
21648 +
21649 + SANITY_CHECK_RETURN_ERROR(p_Tgec, E_INVALID_HANDLE);
21650 + SANITY_CHECK_RETURN_ERROR(p_Tgec->p_TgecDriverParam, E_INVALID_STATE);
21651 +
21652 + p_Tgec->p_TgecDriverParam->loopback_enable = newVal;
21653 +
21654 + return E_OK;
21655 +}
21656 +
21657 +/* ......................................................................... */
21658 +
21659 +static t_Error TgecConfigWan(t_Handle h_Tgec, bool newVal)
21660 +{
21661 + t_Tgec *p_Tgec = (t_Tgec *)h_Tgec;
21662 +
21663 + SANITY_CHECK_RETURN_ERROR(p_Tgec, E_INVALID_HANDLE);
21664 + SANITY_CHECK_RETURN_ERROR(p_Tgec->p_TgecDriverParam, E_INVALID_STATE);
21665 +
21666 + p_Tgec->p_TgecDriverParam->wan_mode_enable = newVal;
21667 +
21668 + return E_OK;
21669 +}
21670 +
21671 +/* ......................................................................... */
21672 +
21673 +static t_Error TgecConfigMaxFrameLength(t_Handle h_Tgec, uint16_t newVal)
21674 +{
21675 + t_Tgec *p_Tgec = (t_Tgec *)h_Tgec;
21676 +
21677 + SANITY_CHECK_RETURN_ERROR(p_Tgec, E_INVALID_HANDLE);
21678 + SANITY_CHECK_RETURN_ERROR(p_Tgec->p_TgecDriverParam, E_INVALID_STATE);
21679 +
21680 + p_Tgec->p_TgecDriverParam->max_frame_length = newVal;
21681 +
21682 + return E_OK;
21683 +}
21684 +
21685 +/* ......................................................................... */
21686 +
21687 +static t_Error TgecConfigLengthCheck(t_Handle h_Tgec, bool newVal)
21688 +{
21689 + t_Tgec *p_Tgec = (t_Tgec *)h_Tgec;
21690 +
21691 + UNUSED(newVal);
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->no_length_check_enable = !newVal;
21697 +
21698 + return E_OK;
21699 +}
21700 +
21701 +/* ......................................................................... */
21702 +
21703 +static t_Error TgecConfigException(t_Handle h_Tgec, e_FmMacExceptions exception, bool enable)
21704 +{
21705 + t_Tgec *p_Tgec = (t_Tgec *)h_Tgec;
21706 + uint32_t bitMask = 0;
21707 +
21708 + SANITY_CHECK_RETURN_ERROR(p_Tgec, E_INVALID_HANDLE);
21709 + SANITY_CHECK_RETURN_ERROR(p_Tgec->p_TgecDriverParam, E_INVALID_STATE);
21710 +
21711 + GET_EXCEPTION_FLAG(bitMask, exception);
21712 + if (bitMask)
21713 + {
21714 + if (enable)
21715 + p_Tgec->exceptions |= bitMask;
21716 + else
21717 + p_Tgec->exceptions &= ~bitMask;
21718 + }
21719 + else
21720 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Undefined exception"));
21721 +
21722 + return E_OK;
21723 +}
21724 +
21725 +#ifdef FM_TX_ECC_FRMS_ERRATA_10GMAC_A004
21726 +/* ......................................................................... */
21727 +
21728 +static t_Error TgecConfigSkipFman11Workaround(t_Handle h_Tgec)
21729 +{
21730 + t_Tgec *p_Tgec = (t_Tgec *)h_Tgec;
21731 +
21732 + SANITY_CHECK_RETURN_ERROR(p_Tgec, E_INVALID_HANDLE);
21733 + SANITY_CHECK_RETURN_ERROR(p_Tgec->p_TgecDriverParam, E_INVALID_STATE);
21734 +
21735 + p_Tgec->p_TgecDriverParam->skip_fman11_workaround = TRUE;
21736 +
21737 + return E_OK;
21738 +}
21739 +#endif /* FM_TX_ECC_FRMS_ERRATA_10GMAC_A004 */
21740 +
21741 +
21742 +/*****************************************************************************/
21743 +/* Tgec Run Time API functions */
21744 +/*****************************************************************************/
21745 +
21746 +/* ......................................................................... */
21747 +/* backward compatibility. will be removed in the future. */
21748 +static t_Error TgecTxMacPause(t_Handle h_Tgec, uint16_t pauseTime)
21749 +{
21750 + t_Tgec *p_Tgec = (t_Tgec *)h_Tgec;
21751 +
21752 + SANITY_CHECK_RETURN_ERROR(p_Tgec, E_INVALID_STATE);
21753 + SANITY_CHECK_RETURN_ERROR(!p_Tgec->p_TgecDriverParam, E_INVALID_STATE);
21754 + fman_tgec_set_tx_pause_frames(p_Tgec->p_MemMap, pauseTime);
21755 +
21756 +
21757 + return E_OK;
21758 +}
21759 +
21760 +/* ......................................................................... */
21761 +
21762 +static t_Error TgecSetTxPauseFrames(t_Handle h_Tgec,
21763 + uint8_t priority,
21764 + uint16_t pauseTime,
21765 + uint16_t threshTime)
21766 +{
21767 + t_Tgec *p_Tgec = (t_Tgec *)h_Tgec;
21768 +
21769 + SANITY_CHECK_RETURN_ERROR(p_Tgec, E_INVALID_STATE);
21770 + SANITY_CHECK_RETURN_ERROR(!p_Tgec->p_TgecDriverParam, E_INVALID_STATE);
21771 +
21772 + UNUSED(priority); UNUSED(threshTime);
21773 +
21774 + fman_tgec_set_tx_pause_frames(p_Tgec->p_MemMap, pauseTime);
21775 +
21776 + return E_OK;
21777 +}
21778 +
21779 +/* ......................................................................... */
21780 +
21781 +static t_Error TgecRxIgnoreMacPause(t_Handle h_Tgec, bool en)
21782 +{
21783 + t_Tgec *p_Tgec = (t_Tgec *)h_Tgec;
21784 +
21785 + SANITY_CHECK_RETURN_ERROR(p_Tgec, E_INVALID_STATE);
21786 + SANITY_CHECK_RETURN_ERROR(!p_Tgec->p_TgecDriverParam, E_INVALID_STATE);
21787 +
21788 + fman_tgec_set_rx_ignore_pause_frames(p_Tgec->p_MemMap, en);
21789 +
21790 + return E_OK;
21791 +}
21792 +
21793 +/* ......................................................................... */
21794 +
21795 +static t_Error TgecGetStatistics(t_Handle h_Tgec, t_FmMacStatistics *p_Statistics)
21796 +{
21797 + t_Tgec *p_Tgec = (t_Tgec *)h_Tgec;
21798 + struct tgec_regs *p_TgecMemMap;
21799 +
21800 + SANITY_CHECK_RETURN_ERROR(p_Tgec, E_NULL_POINTER);
21801 + SANITY_CHECK_RETURN_ERROR(!p_Tgec->p_TgecDriverParam, E_INVALID_STATE);
21802 + SANITY_CHECK_RETURN_ERROR(p_Statistics, E_NULL_POINTER);
21803 +
21804 + p_TgecMemMap = p_Tgec->p_MemMap;
21805 +
21806 + p_Statistics->eStatPkts64 = fman_tgec_get_counter(p_TgecMemMap, E_TGEC_COUNTER_R64);
21807 + p_Statistics->eStatPkts65to127 = fman_tgec_get_counter(p_TgecMemMap, E_TGEC_COUNTER_R127);
21808 + p_Statistics->eStatPkts128to255 = fman_tgec_get_counter(p_TgecMemMap, E_TGEC_COUNTER_R255);
21809 + p_Statistics->eStatPkts256to511 = fman_tgec_get_counter(p_TgecMemMap, E_TGEC_COUNTER_R511);
21810 + p_Statistics->eStatPkts512to1023 = fman_tgec_get_counter(p_TgecMemMap, E_TGEC_COUNTER_R1023);
21811 + p_Statistics->eStatPkts1024to1518 = fman_tgec_get_counter(p_TgecMemMap, E_TGEC_COUNTER_R1518);
21812 + p_Statistics->eStatPkts1519to1522 = fman_tgec_get_counter(p_TgecMemMap, E_TGEC_COUNTER_R1519X);
21813 +/* */
21814 + p_Statistics->eStatFragments = fman_tgec_get_counter(p_TgecMemMap, E_TGEC_COUNTER_TRFRG);
21815 + p_Statistics->eStatJabbers = fman_tgec_get_counter(p_TgecMemMap, E_TGEC_COUNTER_TRJBR);
21816 +
21817 + p_Statistics->eStatsDropEvents = fman_tgec_get_counter(p_TgecMemMap, E_TGEC_COUNTER_RDRP);
21818 + p_Statistics->eStatCRCAlignErrors = fman_tgec_get_counter(p_TgecMemMap, E_TGEC_COUNTER_RALN);
21819 +
21820 + p_Statistics->eStatUndersizePkts = fman_tgec_get_counter(p_TgecMemMap, E_TGEC_COUNTER_TRUND);
21821 + p_Statistics->eStatOversizePkts = fman_tgec_get_counter(p_TgecMemMap, E_TGEC_COUNTER_TROVR);
21822 +/* Pause */
21823 + p_Statistics->reStatPause = fman_tgec_get_counter(p_TgecMemMap, E_TGEC_COUNTER_RXPF);
21824 + p_Statistics->teStatPause = fman_tgec_get_counter(p_TgecMemMap, E_TGEC_COUNTER_TXPF);
21825 +
21826 +/* MIB II */
21827 + p_Statistics->ifInOctets = fman_tgec_get_counter(p_TgecMemMap, E_TGEC_COUNTER_ROCT);
21828 + p_Statistics->ifInUcastPkts = fman_tgec_get_counter(p_TgecMemMap, E_TGEC_COUNTER_RUCA);
21829 + p_Statistics->ifInMcastPkts = fman_tgec_get_counter(p_TgecMemMap, E_TGEC_COUNTER_RMCA);
21830 + p_Statistics->ifInBcastPkts = fman_tgec_get_counter(p_TgecMemMap, E_TGEC_COUNTER_RBCA);
21831 + p_Statistics->ifInPkts = p_Statistics->ifInUcastPkts
21832 + + p_Statistics->ifInMcastPkts
21833 + + p_Statistics->ifInBcastPkts;
21834 + p_Statistics->ifInDiscards = 0;
21835 + p_Statistics->ifInErrors = fman_tgec_get_counter(p_TgecMemMap, E_TGEC_COUNTER_RERR);
21836 +
21837 + p_Statistics->ifOutOctets = fman_tgec_get_counter(p_TgecMemMap, E_TGEC_COUNTER_TOCT);
21838 + p_Statistics->ifOutUcastPkts = fman_tgec_get_counter(p_TgecMemMap, E_TGEC_COUNTER_TUCA);
21839 + p_Statistics->ifOutMcastPkts = fman_tgec_get_counter(p_TgecMemMap, E_TGEC_COUNTER_TMCA);
21840 + p_Statistics->ifOutBcastPkts = fman_tgec_get_counter(p_TgecMemMap, E_TGEC_COUNTER_TBCA);
21841 + p_Statistics->ifOutPkts = p_Statistics->ifOutUcastPkts
21842 + + p_Statistics->ifOutMcastPkts
21843 + + p_Statistics->ifOutBcastPkts;
21844 + p_Statistics->ifOutDiscards = 0;
21845 + p_Statistics->ifOutErrors = fman_tgec_get_counter(p_TgecMemMap, E_TGEC_COUNTER_TERR);
21846 +
21847 + return E_OK;
21848 +}
21849 +
21850 +/* ......................................................................... */
21851 +
21852 +static t_Error TgecGetFrameSizeCounters(t_Handle h_Tgec, t_FmMacFrameSizeCounters *p_FrameSizeCounters, e_CommMode type)
21853 +{
21854 + t_Tgec *p_Tgec = (t_Tgec *)h_Tgec;
21855 + struct tgec_regs *p_TgecMemMap;
21856 +
21857 + SANITY_CHECK_RETURN_ERROR(p_Tgec, E_NULL_POINTER);
21858 + SANITY_CHECK_RETURN_ERROR(!p_Tgec->p_TgecDriverParam, E_INVALID_STATE);
21859 + SANITY_CHECK_RETURN_ERROR(p_FrameSizeCounters, E_NULL_POINTER);
21860 +
21861 + p_TgecMemMap = p_Tgec->p_MemMap;
21862 +
21863 + switch (type)
21864 + {
21865 + case e_COMM_MODE_NONE:
21866 + break;
21867 +
21868 + case e_COMM_MODE_RX:
21869 + p_FrameSizeCounters->count_pkts_64 = fman_tgec_get_counter(p_TgecMemMap, E_TGEC_COUNTER_R64);
21870 + p_FrameSizeCounters->count_pkts_65_to_127 = fman_tgec_get_counter(p_TgecMemMap, E_TGEC_COUNTER_R127);
21871 + p_FrameSizeCounters->count_pkts_128_to_255 = fman_tgec_get_counter(p_TgecMemMap, E_TGEC_COUNTER_R255);
21872 + p_FrameSizeCounters->count_pkts_256_to_511 = fman_tgec_get_counter(p_TgecMemMap, E_TGEC_COUNTER_R511);
21873 + p_FrameSizeCounters->count_pkts_512_to_1023 = fman_tgec_get_counter(p_TgecMemMap, E_TGEC_COUNTER_R1023);
21874 + p_FrameSizeCounters->count_pkts_1024_to_1518 = fman_tgec_get_counter(p_TgecMemMap, E_TGEC_COUNTER_R1518);
21875 + p_FrameSizeCounters->count_pkts_1519_to_1522 = fman_tgec_get_counter(p_TgecMemMap, E_TGEC_COUNTER_R1519X);
21876 + break;
21877 +
21878 + case e_COMM_MODE_TX:
21879 + //Tx counters not supported
21880 + break;
21881 +
21882 + case e_COMM_MODE_RX_AND_TX:
21883 + //Tx counters not supported
21884 + break;
21885 + }
21886 +
21887 + return E_OK;
21888 +}
21889 +
21890 +
21891 +/* ......................................................................... */
21892 +
21893 +static t_Error TgecEnable1588TimeStamp(t_Handle h_Tgec)
21894 +{
21895 + t_Tgec *p_Tgec = (t_Tgec *)h_Tgec;
21896 +
21897 + SANITY_CHECK_RETURN_ERROR(p_Tgec, E_INVALID_HANDLE);
21898 + SANITY_CHECK_RETURN_ERROR(!p_Tgec->p_TgecDriverParam, E_INVALID_STATE);
21899 +
21900 + fman_tgec_enable_1588_time_stamp(p_Tgec->p_MemMap, 1);
21901 +
21902 + return E_OK;
21903 +}
21904 +
21905 +/* ......................................................................... */
21906 +
21907 +static t_Error TgecDisable1588TimeStamp(t_Handle h_Tgec)
21908 +{
21909 + t_Tgec *p_Tgec = (t_Tgec *)h_Tgec;
21910 +
21911 + SANITY_CHECK_RETURN_ERROR(p_Tgec, E_INVALID_HANDLE);
21912 + SANITY_CHECK_RETURN_ERROR(!p_Tgec->p_TgecDriverParam, E_INVALID_STATE);
21913 +
21914 + fman_tgec_enable_1588_time_stamp(p_Tgec->p_MemMap, 0);
21915 +
21916 + return E_OK;
21917 +}
21918 +
21919 +/* ......................................................................... */
21920 +
21921 +static t_Error TgecModifyMacAddress (t_Handle h_Tgec, t_EnetAddr *p_EnetAddr)
21922 +{
21923 + t_Tgec *p_Tgec = (t_Tgec *)h_Tgec;
21924 +
21925 + SANITY_CHECK_RETURN_ERROR(p_Tgec, E_NULL_POINTER);
21926 + SANITY_CHECK_RETURN_ERROR(!p_Tgec->p_TgecDriverParam, E_INVALID_STATE);
21927 +
21928 + p_Tgec->addr = ENET_ADDR_TO_UINT64(*p_EnetAddr);
21929 + fman_tgec_set_mac_address(p_Tgec->p_MemMap, (uint8_t *)(*p_EnetAddr));
21930 +
21931 + return E_OK;
21932 +}
21933 +
21934 +/* ......................................................................... */
21935 +
21936 +static t_Error TgecResetCounters (t_Handle h_Tgec)
21937 +{
21938 + t_Tgec *p_Tgec = (t_Tgec *)h_Tgec;
21939 +
21940 + SANITY_CHECK_RETURN_ERROR(p_Tgec, E_INVALID_HANDLE);
21941 + SANITY_CHECK_RETURN_ERROR(!p_Tgec->p_TgecDriverParam, E_INVALID_STATE);
21942 +
21943 + fman_tgec_reset_stat(p_Tgec->p_MemMap);
21944 +
21945 + return E_OK;
21946 +}
21947 +
21948 +/* ......................................................................... */
21949 +
21950 +static t_Error TgecAddExactMatchMacAddress(t_Handle h_Tgec, t_EnetAddr *p_EthAddr)
21951 +{
21952 + t_Tgec *p_Tgec = (t_Tgec *) h_Tgec;
21953 + uint64_t ethAddr;
21954 + uint8_t paddrNum;
21955 +
21956 + SANITY_CHECK_RETURN_ERROR(p_Tgec, E_INVALID_HANDLE);
21957 + SANITY_CHECK_RETURN_ERROR(!p_Tgec->p_TgecDriverParam, E_INVALID_STATE);
21958 +
21959 + ethAddr = ENET_ADDR_TO_UINT64(*p_EthAddr);
21960 +
21961 + if (ethAddr & GROUP_ADDRESS)
21962 + /* Multicast address has no effect in PADDR */
21963 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Multicast address"));
21964 +
21965 + /* Make sure no PADDR contains this address */
21966 + for (paddrNum = 0; paddrNum < TGEC_NUM_OF_PADDRS; paddrNum++)
21967 + if (p_Tgec->indAddrRegUsed[paddrNum])
21968 + if (p_Tgec->paddr[paddrNum] == ethAddr)
21969 + RETURN_ERROR(MAJOR, E_ALREADY_EXISTS, NO_MSG);
21970 +
21971 + /* Find first unused PADDR */
21972 + for (paddrNum = 0; paddrNum < TGEC_NUM_OF_PADDRS; paddrNum++)
21973 + {
21974 + if (!(p_Tgec->indAddrRegUsed[paddrNum]))
21975 + {
21976 + /* mark this PADDR as used */
21977 + p_Tgec->indAddrRegUsed[paddrNum] = TRUE;
21978 + /* store address */
21979 + p_Tgec->paddr[paddrNum] = ethAddr;
21980 +
21981 + /* put in hardware */
21982 + fman_tgec_add_addr_in_paddr(p_Tgec->p_MemMap, (uint8_t*)(*p_EthAddr)/* , paddrNum */);
21983 + p_Tgec->numOfIndAddrInRegs++;
21984 +
21985 + return E_OK;
21986 + }
21987 + }
21988 +
21989 + /* No free PADDR */
21990 + RETURN_ERROR(MAJOR, E_FULL, NO_MSG);
21991 +}
21992 +
21993 +/* ......................................................................... */
21994 +
21995 +static t_Error TgecDelExactMatchMacAddress(t_Handle h_Tgec, t_EnetAddr *p_EthAddr)
21996 +{
21997 + t_Tgec *p_Tgec = (t_Tgec *) h_Tgec;
21998 + uint64_t ethAddr;
21999 + uint8_t paddrNum;
22000 +
22001 + SANITY_CHECK_RETURN_ERROR(p_Tgec, E_INVALID_HANDLE);
22002 + SANITY_CHECK_RETURN_ERROR(!p_Tgec->p_TgecDriverParam, E_INVALID_STATE);
22003 +
22004 + ethAddr = ENET_ADDR_TO_UINT64(*p_EthAddr);
22005 +
22006 + /* Find used PADDR containing this address */
22007 + for (paddrNum = 0; paddrNum < TGEC_NUM_OF_PADDRS; paddrNum++)
22008 + {
22009 + if ((p_Tgec->indAddrRegUsed[paddrNum]) &&
22010 + (p_Tgec->paddr[paddrNum] == ethAddr))
22011 + {
22012 + /* mark this PADDR as not used */
22013 + p_Tgec->indAddrRegUsed[paddrNum] = FALSE;
22014 + /* clear in hardware */
22015 + fman_tgec_clear_addr_in_paddr(p_Tgec->p_MemMap /*, paddrNum */);
22016 + p_Tgec->numOfIndAddrInRegs--;
22017 +
22018 + return E_OK;
22019 + }
22020 + }
22021 +
22022 + RETURN_ERROR(MAJOR, E_NOT_FOUND, NO_MSG);
22023 +}
22024 +
22025 +/* ......................................................................... */
22026 +
22027 +static t_Error TgecAddHashMacAddress(t_Handle h_Tgec, t_EnetAddr *p_EthAddr)
22028 +{
22029 + t_Tgec *p_Tgec = (t_Tgec *)h_Tgec;
22030 + t_EthHashEntry *p_HashEntry;
22031 + uint32_t crc;
22032 + uint32_t hash;
22033 + uint64_t ethAddr;
22034 +
22035 + SANITY_CHECK_RETURN_ERROR(p_Tgec, E_NULL_POINTER);
22036 + SANITY_CHECK_RETURN_ERROR(!p_Tgec->p_TgecDriverParam, E_INVALID_STATE);
22037 +
22038 + ethAddr = ENET_ADDR_TO_UINT64(*p_EthAddr);
22039 +
22040 + if (!(ethAddr & GROUP_ADDRESS))
22041 + /* Unicast addresses not supported in hash */
22042 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("Unicast Address"));
22043 +
22044 + /* CRC calculation */
22045 + crc = GetMacAddrHashCode(ethAddr);
22046 +
22047 + hash = (crc >> TGEC_HASH_MCAST_SHIFT) & TGEC_HASH_ADR_MSK; /* Take 9 MSB bits */
22048 +
22049 + /* Create element to be added to the driver hash table */
22050 + p_HashEntry = (t_EthHashEntry *)XX_Malloc(sizeof(t_EthHashEntry));
22051 + p_HashEntry->addr = ethAddr;
22052 + INIT_LIST(&p_HashEntry->node);
22053 +
22054 + LIST_AddToTail(&(p_HashEntry->node), &(p_Tgec->p_MulticastAddrHash->p_Lsts[hash]));
22055 + fman_tgec_set_hash_table(p_Tgec->p_MemMap, (hash | TGEC_HASH_MCAST_EN));
22056 +
22057 + return E_OK;
22058 +}
22059 +
22060 +/* ......................................................................... */
22061 +
22062 +static t_Error TgecDelHashMacAddress(t_Handle h_Tgec, t_EnetAddr *p_EthAddr)
22063 +{
22064 + t_Tgec *p_Tgec = (t_Tgec *)h_Tgec;
22065 + t_EthHashEntry *p_HashEntry = NULL;
22066 + t_List *p_Pos;
22067 + uint32_t crc;
22068 + uint32_t hash;
22069 + uint64_t ethAddr;
22070 +
22071 + SANITY_CHECK_RETURN_ERROR(p_Tgec, E_NULL_POINTER);
22072 + SANITY_CHECK_RETURN_ERROR(!p_Tgec->p_TgecDriverParam, E_INVALID_STATE);
22073 +
22074 + ethAddr = ((*(uint64_t *)p_EthAddr) >> 16);
22075 +
22076 + /* CRC calculation */
22077 + crc = GetMacAddrHashCode(ethAddr);
22078 +
22079 + hash = (crc >> TGEC_HASH_MCAST_SHIFT) & TGEC_HASH_ADR_MSK; /* Take 9 MSB bits */
22080 +
22081 + LIST_FOR_EACH(p_Pos, &(p_Tgec->p_MulticastAddrHash->p_Lsts[hash]))
22082 + {
22083 + p_HashEntry = ETH_HASH_ENTRY_OBJ(p_Pos);
22084 + if (p_HashEntry->addr == ethAddr)
22085 + {
22086 + LIST_DelAndInit(&p_HashEntry->node);
22087 + XX_Free(p_HashEntry);
22088 + break;
22089 + }
22090 + }
22091 + if (LIST_IsEmpty(&p_Tgec->p_MulticastAddrHash->p_Lsts[hash]))
22092 + fman_tgec_set_hash_table(p_Tgec->p_MemMap, (hash & ~TGEC_HASH_MCAST_EN));
22093 +
22094 + return E_OK;
22095 +}
22096 +
22097 +/* ......................................................................... */
22098 +
22099 +static t_Error TgecGetId(t_Handle h_Tgec, uint32_t *macId)
22100 +{
22101 + t_Tgec *p_Tgec = (t_Tgec *)h_Tgec;
22102 +
22103 + SANITY_CHECK_RETURN_ERROR(p_Tgec, E_INVALID_HANDLE);
22104 + SANITY_CHECK_RETURN_ERROR(!p_Tgec->p_TgecDriverParam, E_INVALID_STATE);
22105 +
22106 + UNUSED(p_Tgec);
22107 + UNUSED(macId);
22108 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("TgecGetId Not Supported"));
22109 +}
22110 +
22111 +/* ......................................................................... */
22112 +
22113 +static t_Error TgecGetVersion(t_Handle h_Tgec, uint32_t *macVersion)
22114 +{
22115 + t_Tgec *p_Tgec = (t_Tgec *)h_Tgec;
22116 +
22117 + SANITY_CHECK_RETURN_ERROR(p_Tgec, E_INVALID_HANDLE);
22118 + SANITY_CHECK_RETURN_ERROR(!p_Tgec->p_TgecDriverParam, E_INVALID_STATE);
22119 +
22120 + *macVersion = fman_tgec_get_revision(p_Tgec->p_MemMap);
22121 +
22122 + return E_OK;
22123 +}
22124 +
22125 +/* ......................................................................... */
22126 +
22127 +static t_Error TgecSetExcpetion(t_Handle h_Tgec, e_FmMacExceptions exception, bool enable)
22128 +{
22129 + t_Tgec *p_Tgec = (t_Tgec *)h_Tgec;
22130 + uint32_t bitMask = 0;
22131 +
22132 + SANITY_CHECK_RETURN_ERROR(p_Tgec, E_INVALID_HANDLE);
22133 + SANITY_CHECK_RETURN_ERROR(!p_Tgec->p_TgecDriverParam, E_INVALID_STATE);
22134 +
22135 + GET_EXCEPTION_FLAG(bitMask, exception);
22136 + if (bitMask)
22137 + {
22138 + if (enable)
22139 + p_Tgec->exceptions |= bitMask;
22140 + else
22141 + p_Tgec->exceptions &= ~bitMask;
22142 + }
22143 + else
22144 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Undefined exception"));
22145 +
22146 + if (enable)
22147 + fman_tgec_enable_interrupt(p_Tgec->p_MemMap, bitMask);
22148 + else
22149 + fman_tgec_disable_interrupt(p_Tgec->p_MemMap, bitMask);
22150 +
22151 + return E_OK;
22152 +}
22153 +
22154 +/* ......................................................................... */
22155 +
22156 +static uint16_t TgecGetMaxFrameLength(t_Handle h_Tgec)
22157 +{
22158 + t_Tgec *p_Tgec = (t_Tgec *)h_Tgec;
22159 +
22160 + SANITY_CHECK_RETURN_VALUE(p_Tgec, E_INVALID_HANDLE, 0);
22161 + SANITY_CHECK_RETURN_VALUE(!p_Tgec->p_TgecDriverParam, E_INVALID_STATE, 0);
22162 +
22163 + return fman_tgec_get_max_frame_len(p_Tgec->p_MemMap);
22164 +}
22165 +
22166 +/* ......................................................................... */
22167 +
22168 +#ifdef FM_TX_ECC_FRMS_ERRATA_10GMAC_A004
22169 +static t_Error TgecTxEccWorkaround(t_Tgec *p_Tgec)
22170 +{
22171 + t_Error err;
22172 +
22173 +#if defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0)
22174 + XX_Print("Applying 10G TX ECC workaround (10GMAC-A004) ... ");
22175 +#endif /* (DEBUG_ERRORS > 0) */
22176 + /* enable and set promiscuous */
22177 + fman_tgec_enable(p_Tgec->p_MemMap, TRUE, TRUE);
22178 + fman_tgec_set_promiscuous(p_Tgec->p_MemMap, TRUE);
22179 + err = Fm10GTxEccWorkaround(p_Tgec->fmMacControllerDriver.h_Fm, p_Tgec->macId);
22180 + /* disable */
22181 + fman_tgec_set_promiscuous(p_Tgec->p_MemMap, FALSE);
22182 + fman_tgec_enable(p_Tgec->p_MemMap, FALSE, FALSE);
22183 + fman_tgec_reset_stat(p_Tgec->p_MemMap);
22184 + fman_tgec_ack_event(p_Tgec->p_MemMap, 0xffffffff);
22185 +#if defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0)
22186 + if (err)
22187 + XX_Print("FAILED!\n");
22188 + else
22189 + XX_Print("done.\n");
22190 +#endif /* (DEBUG_ERRORS > 0) */
22191 +
22192 + return err;
22193 +}
22194 +#endif /* FM_TX_ECC_FRMS_ERRATA_10GMAC_A004 */
22195 +
22196 +/*****************************************************************************/
22197 +/* FM Init & Free API */
22198 +/*****************************************************************************/
22199 +
22200 +/* ......................................................................... */
22201 +
22202 +static t_Error TgecInit(t_Handle h_Tgec)
22203 +{
22204 + t_Tgec *p_Tgec = (t_Tgec *)h_Tgec;
22205 + struct tgec_cfg *p_TgecDriverParam;
22206 + t_EnetAddr ethAddr;
22207 + t_Error err;
22208 +
22209 + SANITY_CHECK_RETURN_ERROR(p_Tgec, E_INVALID_HANDLE);
22210 + SANITY_CHECK_RETURN_ERROR(p_Tgec->p_TgecDriverParam, E_INVALID_STATE);
22211 + SANITY_CHECK_RETURN_ERROR(p_Tgec->fmMacControllerDriver.h_Fm, E_INVALID_HANDLE);
22212 +
22213 + FM_GetRevision(p_Tgec->fmMacControllerDriver.h_Fm, &p_Tgec->fmMacControllerDriver.fmRevInfo);
22214 + CHECK_INIT_PARAMETERS(p_Tgec, CheckInitParameters);
22215 +
22216 + p_TgecDriverParam = p_Tgec->p_TgecDriverParam;
22217 +
22218 + MAKE_ENET_ADDR_FROM_UINT64(p_Tgec->addr, ethAddr);
22219 + fman_tgec_set_mac_address(p_Tgec->p_MemMap, (uint8_t *)ethAddr);
22220 +
22221 + /* interrupts */
22222 +#ifdef FM_10G_REM_N_LCL_FLT_EX_10GMAC_ERRATA_SW005
22223 + {
22224 + if (p_Tgec->fmMacControllerDriver.fmRevInfo.majorRev <=2)
22225 + p_Tgec->exceptions &= ~(TGEC_IMASK_REM_FAULT | TGEC_IMASK_LOC_FAULT);
22226 + }
22227 +#endif /* FM_10G_REM_N_LCL_FLT_EX_10GMAC_ERRATA_SW005 */
22228 +
22229 +#ifdef FM_TX_ECC_FRMS_ERRATA_10GMAC_A004
22230 + if (!p_Tgec->p_TgecDriverParam->skip_fman11_workaround &&
22231 + ((err = TgecTxEccWorkaround(p_Tgec)) != E_OK))
22232 + {
22233 + FreeInitResources(p_Tgec);
22234 + REPORT_ERROR(MINOR, err, ("TgecTxEccWorkaround FAILED"));
22235 + }
22236 +#endif /* FM_TX_ECC_FRMS_ERRATA_10GMAC_A004 */
22237 +
22238 + err = fman_tgec_init(p_Tgec->p_MemMap, p_TgecDriverParam, p_Tgec->exceptions);
22239 + if (err)
22240 + {
22241 + FreeInitResources(p_Tgec);
22242 + RETURN_ERROR(MAJOR, err, ("This TGEC version does not support the required i/f mode"));
22243 + }
22244 +
22245 + /* Max Frame Length */
22246 + err = FmSetMacMaxFrame(p_Tgec->fmMacControllerDriver.h_Fm,
22247 + e_FM_MAC_10G,
22248 + p_Tgec->fmMacControllerDriver.macId,
22249 + p_TgecDriverParam->max_frame_length);
22250 + if (err != E_OK)
22251 + {
22252 + FreeInitResources(p_Tgec);
22253 + RETURN_ERROR(MINOR, err, NO_MSG);
22254 + }
22255 +/* we consider having no IPC a non crasher... */
22256 +
22257 +#ifdef FM_TX_FIFO_CORRUPTION_ERRATA_10GMAC_A007
22258 + if (p_Tgec->fmMacControllerDriver.fmRevInfo.majorRev == 2)
22259 + fman_tgec_set_erratum_tx_fifo_corruption_10gmac_a007(p_Tgec->p_MemMap);
22260 +#endif /* FM_TX_FIFO_CORRUPTION_ERRATA_10GMAC_A007 */
22261 +
22262 + p_Tgec->p_MulticastAddrHash = AllocHashTable(HASH_TABLE_SIZE);
22263 + if (!p_Tgec->p_MulticastAddrHash)
22264 + {
22265 + FreeInitResources(p_Tgec);
22266 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("allocation hash table is FAILED"));
22267 + }
22268 +
22269 + p_Tgec->p_UnicastAddrHash = AllocHashTable(HASH_TABLE_SIZE);
22270 + if (!p_Tgec->p_UnicastAddrHash)
22271 + {
22272 + FreeInitResources(p_Tgec);
22273 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("allocation hash table is FAILED"));
22274 + }
22275 +
22276 + FmRegisterIntr(p_Tgec->fmMacControllerDriver.h_Fm,
22277 + e_FM_MOD_10G_MAC,
22278 + p_Tgec->macId,
22279 + e_FM_INTR_TYPE_ERR,
22280 + TgecErrException,
22281 + p_Tgec);
22282 + if (p_Tgec->mdioIrq != NO_IRQ)
22283 + {
22284 + XX_SetIntr(p_Tgec->mdioIrq, TgecException, p_Tgec);
22285 + XX_EnableIntr(p_Tgec->mdioIrq);
22286 + }
22287 +
22288 + XX_Free(p_TgecDriverParam);
22289 + p_Tgec->p_TgecDriverParam = NULL;
22290 +
22291 + return E_OK;
22292 +}
22293 +
22294 +/* ......................................................................... */
22295 +
22296 +static t_Error TgecFree(t_Handle h_Tgec)
22297 +{
22298 + t_Tgec *p_Tgec = (t_Tgec *)h_Tgec;
22299 +
22300 + SANITY_CHECK_RETURN_ERROR(p_Tgec, E_INVALID_HANDLE);
22301 +
22302 + if (p_Tgec->p_TgecDriverParam)
22303 + {
22304 + /* Called after config */
22305 + XX_Free(p_Tgec->p_TgecDriverParam);
22306 + p_Tgec->p_TgecDriverParam = NULL;
22307 + }
22308 + else
22309 + /* Called after init */
22310 + FreeInitResources(p_Tgec);
22311 +
22312 + XX_Free(p_Tgec);
22313 +
22314 + return E_OK;
22315 +}
22316 +
22317 +/* ......................................................................... */
22318 +
22319 +static void InitFmMacControllerDriver(t_FmMacControllerDriver *p_FmMacControllerDriver)
22320 +{
22321 + p_FmMacControllerDriver->f_FM_MAC_Init = TgecInit;
22322 + p_FmMacControllerDriver->f_FM_MAC_Free = TgecFree;
22323 +
22324 + p_FmMacControllerDriver->f_FM_MAC_SetStatistics = NULL;
22325 + p_FmMacControllerDriver->f_FM_MAC_ConfigLoopback = TgecConfigLoopback;
22326 + p_FmMacControllerDriver->f_FM_MAC_ConfigMaxFrameLength = TgecConfigMaxFrameLength;
22327 +
22328 + p_FmMacControllerDriver->f_FM_MAC_ConfigWan = TgecConfigWan;
22329 +
22330 + p_FmMacControllerDriver->f_FM_MAC_ConfigPadAndCrc = NULL; /* TGEC always works with pad+crc */
22331 + p_FmMacControllerDriver->f_FM_MAC_ConfigHalfDuplex = NULL; /* half-duplex is not supported in xgec */
22332 + p_FmMacControllerDriver->f_FM_MAC_ConfigLengthCheck = TgecConfigLengthCheck;
22333 + p_FmMacControllerDriver->f_FM_MAC_ConfigException = TgecConfigException;
22334 + p_FmMacControllerDriver->f_FM_MAC_ConfigResetOnInit = NULL;
22335 +
22336 +#ifdef FM_TX_ECC_FRMS_ERRATA_10GMAC_A004
22337 + p_FmMacControllerDriver->f_FM_MAC_ConfigSkipFman11Workaround= TgecConfigSkipFman11Workaround;
22338 +#endif /* FM_TX_ECC_FRMS_ERRATA_10GMAC_A004 */
22339 +
22340 + p_FmMacControllerDriver->f_FM_MAC_SetException = TgecSetExcpetion;
22341 +
22342 + p_FmMacControllerDriver->f_FM_MAC_Enable1588TimeStamp = TgecEnable1588TimeStamp;
22343 + p_FmMacControllerDriver->f_FM_MAC_Disable1588TimeStamp = TgecDisable1588TimeStamp;
22344 +
22345 + p_FmMacControllerDriver->f_FM_MAC_SetPromiscuous = TgecSetPromiscuous;
22346 + p_FmMacControllerDriver->f_FM_MAC_AdjustLink = NULL;
22347 + p_FmMacControllerDriver->f_FM_MAC_SetWakeOnLan = NULL;
22348 + p_FmMacControllerDriver->f_FM_MAC_RestartAutoneg = NULL;
22349 +
22350 + p_FmMacControllerDriver->f_FM_MAC_Enable = TgecEnable;
22351 + p_FmMacControllerDriver->f_FM_MAC_Disable = TgecDisable;
22352 + p_FmMacControllerDriver->f_FM_MAC_Resume = NULL;
22353 +
22354 + p_FmMacControllerDriver->f_FM_MAC_SetTxAutoPauseFrames = TgecTxMacPause;
22355 + p_FmMacControllerDriver->f_FM_MAC_SetTxPauseFrames = TgecSetTxPauseFrames;
22356 + p_FmMacControllerDriver->f_FM_MAC_SetRxIgnorePauseFrames = TgecRxIgnoreMacPause;
22357 +
22358 + p_FmMacControllerDriver->f_FM_MAC_ResetCounters = TgecResetCounters;
22359 + p_FmMacControllerDriver->f_FM_MAC_GetStatistics = TgecGetStatistics;
22360 + p_FmMacControllerDriver->f_FM_MAC_GetFrameSizeCounters = TgecGetFrameSizeCounters;
22361 +
22362 + p_FmMacControllerDriver->f_FM_MAC_ModifyMacAddr = TgecModifyMacAddress;
22363 + p_FmMacControllerDriver->f_FM_MAC_AddHashMacAddr = TgecAddHashMacAddress;
22364 + p_FmMacControllerDriver->f_FM_MAC_RemoveHashMacAddr = TgecDelHashMacAddress;
22365 + p_FmMacControllerDriver->f_FM_MAC_AddExactMatchMacAddr = TgecAddExactMatchMacAddress;
22366 + p_FmMacControllerDriver->f_FM_MAC_RemovelExactMatchMacAddr = TgecDelExactMatchMacAddress;
22367 + p_FmMacControllerDriver->f_FM_MAC_GetId = TgecGetId;
22368 + p_FmMacControllerDriver->f_FM_MAC_GetVersion = TgecGetVersion;
22369 + p_FmMacControllerDriver->f_FM_MAC_GetMaxFrameLength = TgecGetMaxFrameLength;
22370 +
22371 + p_FmMacControllerDriver->f_FM_MAC_MII_WritePhyReg = TGEC_MII_WritePhyReg;
22372 + p_FmMacControllerDriver->f_FM_MAC_MII_ReadPhyReg = TGEC_MII_ReadPhyReg;
22373 +}
22374 +
22375 +
22376 +/*****************************************************************************/
22377 +/* Tgec Config Main Entry */
22378 +/*****************************************************************************/
22379 +
22380 +/* ......................................................................... */
22381 +
22382 +t_Handle TGEC_Config(t_FmMacParams *p_FmMacParam)
22383 +{
22384 + t_Tgec *p_Tgec;
22385 + struct tgec_cfg *p_TgecDriverParam;
22386 + uintptr_t baseAddr;
22387 +
22388 + SANITY_CHECK_RETURN_VALUE(p_FmMacParam, E_NULL_POINTER, NULL);
22389 +
22390 + baseAddr = p_FmMacParam->baseAddr;
22391 + /* allocate memory for the UCC GETH data structure. */
22392 + p_Tgec = (t_Tgec *)XX_Malloc(sizeof(t_Tgec));
22393 + if (!p_Tgec)
22394 + {
22395 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("10G MAC driver structure"));
22396 + return NULL;
22397 + }
22398 + memset(p_Tgec, 0, sizeof(t_Tgec));
22399 + InitFmMacControllerDriver(&p_Tgec->fmMacControllerDriver);
22400 +
22401 + /* allocate memory for the 10G MAC driver parameters data structure. */
22402 + p_TgecDriverParam = (struct tgec_cfg *) XX_Malloc(sizeof(struct tgec_cfg));
22403 + if (!p_TgecDriverParam)
22404 + {
22405 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("10G MAC driver parameters"));
22406 + XX_Free(p_Tgec);
22407 + return NULL;
22408 + }
22409 + memset(p_TgecDriverParam, 0, sizeof(struct tgec_cfg));
22410 +
22411 + /* Plant parameter structure pointer */
22412 + p_Tgec->p_TgecDriverParam = p_TgecDriverParam;
22413 +
22414 + fman_tgec_defconfig(p_TgecDriverParam);
22415 +
22416 + p_Tgec->p_MemMap = (struct tgec_regs *)UINT_TO_PTR(baseAddr);
22417 + p_Tgec->p_MiiMemMap = (t_TgecMiiAccessMemMap *)UINT_TO_PTR(baseAddr + TGEC_TO_MII_OFFSET);
22418 + p_Tgec->addr = ENET_ADDR_TO_UINT64(p_FmMacParam->addr);
22419 + p_Tgec->enetMode = p_FmMacParam->enetMode;
22420 + p_Tgec->macId = p_FmMacParam->macId;
22421 + p_Tgec->exceptions = DEFAULT_exceptions;
22422 + p_Tgec->mdioIrq = p_FmMacParam->mdioIrq;
22423 + p_Tgec->f_Exception = p_FmMacParam->f_Exception;
22424 + p_Tgec->f_Event = p_FmMacParam->f_Event;
22425 + p_Tgec->h_App = p_FmMacParam->h_App;
22426 +
22427 + return p_Tgec;
22428 +}
22429 --- /dev/null
22430 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/tgec.h
22431 @@ -0,0 +1,151 @@
22432 +/*
22433 + * Copyright 2008-2012 Freescale Semiconductor Inc.
22434 + *
22435 + * Redistribution and use in source and binary forms, with or without
22436 + * modification, are permitted provided that the following conditions are met:
22437 + * * Redistributions of source code must retain the above copyright
22438 + * notice, this list of conditions and the following disclaimer.
22439 + * * Redistributions in binary form must reproduce the above copyright
22440 + * notice, this list of conditions and the following disclaimer in the
22441 + * documentation and/or other materials provided with the distribution.
22442 + * * Neither the name of Freescale Semiconductor nor the
22443 + * names of its contributors may be used to endorse or promote products
22444 + * derived from this software without specific prior written permission.
22445 + *
22446 + *
22447 + * ALTERNATIVELY, this software may be distributed under the terms of the
22448 + * GNU General Public License ("GPL") as published by the Free Software
22449 + * Foundation, either version 2 of that License or (at your option) any
22450 + * later version.
22451 + *
22452 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
22453 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
22454 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
22455 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
22456 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
22457 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22458 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
22459 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22460 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
22461 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
22462 + */
22463 +
22464 +
22465 +/******************************************************************************
22466 + @File tgec.h
22467 +
22468 + @Description FM 10G MAC ...
22469 +*//***************************************************************************/
22470 +#ifndef __TGEC_H
22471 +#define __TGEC_H
22472 +
22473 +#include "std_ext.h"
22474 +#include "error_ext.h"
22475 +#include "list_ext.h"
22476 +#include "enet_ext.h"
22477 +
22478 +#include "tgec_mii_acc.h"
22479 +#include "fm_mac.h"
22480 +
22481 +
22482 +#define DEFAULT_exceptions \
22483 + ((uint32_t)(TGEC_IMASK_MDIO_SCAN_EVENT | \
22484 + TGEC_IMASK_REM_FAULT | \
22485 + TGEC_IMASK_LOC_FAULT | \
22486 + TGEC_IMASK_TX_ECC_ER | \
22487 + TGEC_IMASK_TX_FIFO_UNFL | \
22488 + TGEC_IMASK_TX_FIFO_OVFL | \
22489 + TGEC_IMASK_TX_ER | \
22490 + TGEC_IMASK_RX_FIFO_OVFL | \
22491 + TGEC_IMASK_RX_ECC_ER | \
22492 + TGEC_IMASK_RX_JAB_FRM | \
22493 + TGEC_IMASK_RX_OVRSZ_FRM | \
22494 + TGEC_IMASK_RX_RUNT_FRM | \
22495 + TGEC_IMASK_RX_FRAG_FRM | \
22496 + TGEC_IMASK_RX_CRC_ER | \
22497 + TGEC_IMASK_RX_ALIGN_ER))
22498 +
22499 +#define GET_EXCEPTION_FLAG(bitMask, exception) switch (exception){ \
22500 + case e_FM_MAC_EX_10G_MDIO_SCAN_EVENTMDIO: \
22501 + bitMask = TGEC_IMASK_MDIO_SCAN_EVENT ; break; \
22502 + case e_FM_MAC_EX_10G_MDIO_CMD_CMPL: \
22503 + bitMask = TGEC_IMASK_MDIO_CMD_CMPL ; break; \
22504 + case e_FM_MAC_EX_10G_REM_FAULT: \
22505 + bitMask = TGEC_IMASK_REM_FAULT ; break; \
22506 + case e_FM_MAC_EX_10G_LOC_FAULT: \
22507 + bitMask = TGEC_IMASK_LOC_FAULT ; break; \
22508 + case e_FM_MAC_EX_10G_1TX_ECC_ER: \
22509 + bitMask = TGEC_IMASK_TX_ECC_ER ; break; \
22510 + case e_FM_MAC_EX_10G_TX_FIFO_UNFL: \
22511 + bitMask = TGEC_IMASK_TX_FIFO_UNFL ; break; \
22512 + case e_FM_MAC_EX_10G_TX_FIFO_OVFL: \
22513 + bitMask = TGEC_IMASK_TX_FIFO_OVFL ; break; \
22514 + case e_FM_MAC_EX_10G_TX_ER: \
22515 + bitMask = TGEC_IMASK_TX_ER ; break; \
22516 + case e_FM_MAC_EX_10G_RX_FIFO_OVFL: \
22517 + bitMask = TGEC_IMASK_RX_FIFO_OVFL ; break; \
22518 + case e_FM_MAC_EX_10G_RX_ECC_ER: \
22519 + bitMask = TGEC_IMASK_RX_ECC_ER ; break; \
22520 + case e_FM_MAC_EX_10G_RX_JAB_FRM: \
22521 + bitMask = TGEC_IMASK_RX_JAB_FRM ; break; \
22522 + case e_FM_MAC_EX_10G_RX_OVRSZ_FRM: \
22523 + bitMask = TGEC_IMASK_RX_OVRSZ_FRM ; break; \
22524 + case e_FM_MAC_EX_10G_RX_RUNT_FRM: \
22525 + bitMask = TGEC_IMASK_RX_RUNT_FRM ; break; \
22526 + case e_FM_MAC_EX_10G_RX_FRAG_FRM: \
22527 + bitMask = TGEC_IMASK_RX_FRAG_FRM ; break; \
22528 + case e_FM_MAC_EX_10G_RX_LEN_ER: \
22529 + bitMask = TGEC_IMASK_RX_LEN_ER ; break; \
22530 + case e_FM_MAC_EX_10G_RX_CRC_ER: \
22531 + bitMask = TGEC_IMASK_RX_CRC_ER ; break; \
22532 + case e_FM_MAC_EX_10G_RX_ALIGN_ER: \
22533 + bitMask = TGEC_IMASK_RX_ALIGN_ER ; break; \
22534 + default: bitMask = 0;break;}
22535 +
22536 +#define MAX_PACKET_ALIGNMENT 31
22537 +#define MAX_INTER_PACKET_GAP 0x7f
22538 +#define MAX_INTER_PALTERNATE_BEB 0x0f
22539 +#define MAX_RETRANSMISSION 0x0f
22540 +#define MAX_COLLISION_WINDOW 0x03ff
22541 +
22542 +#define TGEC_NUM_OF_PADDRS 1 /* number of pattern match registers (entries) */
22543 +
22544 +#define GROUP_ADDRESS 0x0000010000000000LL /* Group address bit indication */
22545 +
22546 +#define HASH_TABLE_SIZE 512 /* Hash table size (= 32 bits * 8 regs) */
22547 +
22548 +#define TGEC_TO_MII_OFFSET 0x1030 /* Offset from the MEM map to the MDIO mem map */
22549 +
22550 +/* 10-gigabit Ethernet MAC Controller ID (10GEC_ID) */
22551 +#define TGEC_ID_ID 0xffff0000
22552 +#define TGEC_ID_MAC_VERSION 0x0000FF00
22553 +#define TGEC_ID_MAC_REV 0x000000ff
22554 +
22555 +
22556 +typedef struct {
22557 + t_FmMacControllerDriver fmMacControllerDriver; /**< Upper Mac control block */
22558 + t_Handle h_App; /**< Handle to the upper layer application */
22559 + struct tgec_regs *p_MemMap; /**< pointer to 10G memory mapped registers. */
22560 + t_TgecMiiAccessMemMap *p_MiiMemMap; /**< pointer to MII memory mapped registers. */
22561 + uint64_t addr; /**< MAC address of device; */
22562 + e_EnetMode enetMode; /**< Ethernet physical interface */
22563 + t_FmMacExceptionCallback *f_Exception;
22564 + int mdioIrq;
22565 + t_FmMacExceptionCallback *f_Event;
22566 + bool indAddrRegUsed[TGEC_NUM_OF_PADDRS]; /**< Whether a particular individual address recognition register is being used */
22567 + uint64_t paddr[TGEC_NUM_OF_PADDRS]; /**< MAC address for particular individual address recognition register */
22568 + uint8_t numOfIndAddrInRegs; /**< Number of individual addresses in registers for this station. */
22569 + t_EthHash *p_MulticastAddrHash; /**< pointer to driver's global address hash table */
22570 + t_EthHash *p_UnicastAddrHash; /**< pointer to driver's individual address hash table */
22571 + bool debugMode;
22572 + uint8_t macId;
22573 + uint32_t exceptions;
22574 + struct tgec_cfg *p_TgecDriverParam;
22575 +} t_Tgec;
22576 +
22577 +
22578 +t_Error TGEC_MII_WritePhyReg(t_Handle h_Tgec, uint8_t phyAddr, uint8_t reg, uint16_t data);
22579 +t_Error TGEC_MII_ReadPhyReg(t_Handle h_Tgec, uint8_t phyAddr, uint8_t reg, uint16_t *p_Data);
22580 +
22581 +
22582 +#endif /* __TGEC_H */
22583 --- /dev/null
22584 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/tgec_mii_acc.c
22585 @@ -0,0 +1,139 @@
22586 +/*
22587 + * Copyright 2008-2012 Freescale Semiconductor Inc.
22588 + *
22589 + * Redistribution and use in source and binary forms, with or without
22590 + * modification, are permitted provided that the following conditions are met:
22591 + * * Redistributions of source code must retain the above copyright
22592 + * notice, this list of conditions and the following disclaimer.
22593 + * * Redistributions in binary form must reproduce the above copyright
22594 + * notice, this list of conditions and the following disclaimer in the
22595 + * documentation and/or other materials provided with the distribution.
22596 + * * Neither the name of Freescale Semiconductor nor the
22597 + * names of its contributors may be used to endorse or promote products
22598 + * derived from this software without specific prior written permission.
22599 + *
22600 + *
22601 + * ALTERNATIVELY, this software may be distributed under the terms of the
22602 + * GNU General Public License ("GPL") as published by the Free Software
22603 + * Foundation, either version 2 of that License or (at your option) any
22604 + * later version.
22605 + *
22606 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
22607 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
22608 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
22609 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
22610 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
22611 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22612 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
22613 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22614 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
22615 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
22616 + */
22617 +
22618 +
22619 +
22620 +#include "error_ext.h"
22621 +#include "std_ext.h"
22622 +#include "fm_mac.h"
22623 +#include "tgec.h"
22624 +#include "xx_ext.h"
22625 +
22626 +#include "fm_common.h"
22627 +
22628 +
22629 +/*****************************************************************************/
22630 +t_Error TGEC_MII_WritePhyReg(t_Handle h_Tgec,
22631 + uint8_t phyAddr,
22632 + uint8_t reg,
22633 + uint16_t data)
22634 +{
22635 + t_Tgec *p_Tgec = (t_Tgec *)h_Tgec;
22636 + t_TgecMiiAccessMemMap *p_MiiAccess;
22637 + uint32_t cfgStatusReg;
22638 +
22639 + SANITY_CHECK_RETURN_ERROR(p_Tgec, E_INVALID_HANDLE);
22640 + SANITY_CHECK_RETURN_ERROR(p_Tgec->p_MiiMemMap, E_INVALID_HANDLE);
22641 +
22642 + p_MiiAccess = p_Tgec->p_MiiMemMap;
22643 +
22644 + /* Configure MII */
22645 + cfgStatusReg = GET_UINT32(p_MiiAccess->mdio_cfg_status);
22646 + cfgStatusReg &= ~MIIMCOM_DIV_MASK;
22647 + /* (one half of fm clock => 2.5Mhz) */
22648 + cfgStatusReg |=((((p_Tgec->fmMacControllerDriver.clkFreq*10)/2)/25) << MIIMCOM_DIV_SHIFT);
22649 + WRITE_UINT32(p_MiiAccess->mdio_cfg_status, cfgStatusReg);
22650 +
22651 + while ((GET_UINT32(p_MiiAccess->mdio_cfg_status)) & MIIMIND_BUSY)
22652 + XX_UDelay (1);
22653 +
22654 + WRITE_UINT32(p_MiiAccess->mdio_command, phyAddr);
22655 +
22656 + WRITE_UINT32(p_MiiAccess->mdio_regaddr, reg);
22657 +
22658 + CORE_MemoryBarrier();
22659 +
22660 + while ((GET_UINT32(p_MiiAccess->mdio_cfg_status)) & MIIMIND_BUSY)
22661 + XX_UDelay (1);
22662 +
22663 + WRITE_UINT32(p_MiiAccess->mdio_data, data);
22664 +
22665 + CORE_MemoryBarrier();
22666 +
22667 + while ((GET_UINT32(p_MiiAccess->mdio_data)) & MIIDATA_BUSY)
22668 + XX_UDelay (1);
22669 +
22670 + return E_OK;
22671 +}
22672 +
22673 +/*****************************************************************************/
22674 +t_Error TGEC_MII_ReadPhyReg(t_Handle h_Tgec,
22675 + uint8_t phyAddr,
22676 + uint8_t reg,
22677 + uint16_t *p_Data)
22678 +{
22679 + t_Tgec *p_Tgec = (t_Tgec *)h_Tgec;
22680 + t_TgecMiiAccessMemMap *p_MiiAccess;
22681 + uint32_t cfgStatusReg;
22682 +
22683 + SANITY_CHECK_RETURN_ERROR(p_Tgec, E_INVALID_HANDLE);
22684 + SANITY_CHECK_RETURN_ERROR(p_Tgec->p_MiiMemMap, E_INVALID_HANDLE);
22685 +
22686 + p_MiiAccess = p_Tgec->p_MiiMemMap;
22687 +
22688 + /* Configure MII */
22689 + cfgStatusReg = GET_UINT32(p_MiiAccess->mdio_cfg_status);
22690 + cfgStatusReg &= ~MIIMCOM_DIV_MASK;
22691 + /* (one half of fm clock => 2.5Mhz) */
22692 + cfgStatusReg |=((((p_Tgec->fmMacControllerDriver.clkFreq*10)/2)/25) << MIIMCOM_DIV_SHIFT);
22693 + WRITE_UINT32(p_MiiAccess->mdio_cfg_status, cfgStatusReg);
22694 +
22695 + while ((GET_UINT32(p_MiiAccess->mdio_cfg_status)) & MIIMIND_BUSY)
22696 + XX_UDelay (1);
22697 +
22698 + WRITE_UINT32(p_MiiAccess->mdio_command, phyAddr);
22699 +
22700 + WRITE_UINT32(p_MiiAccess->mdio_regaddr, reg);
22701 +
22702 + CORE_MemoryBarrier();
22703 +
22704 + while ((GET_UINT32(p_MiiAccess->mdio_cfg_status)) & MIIMIND_BUSY)
22705 + XX_UDelay (1);
22706 +
22707 + WRITE_UINT32(p_MiiAccess->mdio_command, (uint32_t)(phyAddr | MIIMCOM_READ_CYCLE));
22708 +
22709 + CORE_MemoryBarrier();
22710 +
22711 + while ((GET_UINT32(p_MiiAccess->mdio_data)) & MIIDATA_BUSY)
22712 + XX_UDelay (1);
22713 +
22714 + *p_Data = (uint16_t)GET_UINT32(p_MiiAccess->mdio_data);
22715 +
22716 + cfgStatusReg = GET_UINT32(p_MiiAccess->mdio_cfg_status);
22717 +
22718 + if (cfgStatusReg & MIIMIND_READ_ERROR)
22719 + RETURN_ERROR(MINOR, E_INVALID_VALUE,
22720 + ("Read Error: phyAddr 0x%x, dev 0x%x, reg 0x%x, cfgStatusReg 0x%x",
22721 + ((phyAddr & 0xe0)>>5), (phyAddr & 0x1f), reg, cfgStatusReg));
22722 +
22723 + return E_OK;
22724 +}
22725 --- /dev/null
22726 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/tgec_mii_acc.h
22727 @@ -0,0 +1,80 @@
22728 +/*
22729 + * Copyright 2008-2012 Freescale Semiconductor Inc.
22730 + *
22731 + * Redistribution and use in source and binary forms, with or without
22732 + * modification, are permitted provided that the following conditions are met:
22733 + * * Redistributions of source code must retain the above copyright
22734 + * notice, this list of conditions and the following disclaimer.
22735 + * * Redistributions in binary form must reproduce the above copyright
22736 + * notice, this list of conditions and the following disclaimer in the
22737 + * documentation and/or other materials provided with the distribution.
22738 + * * Neither the name of Freescale Semiconductor nor the
22739 + * names of its contributors may be used to endorse or promote products
22740 + * derived from this software without specific prior written permission.
22741 + *
22742 + *
22743 + * ALTERNATIVELY, this software may be distributed under the terms of the
22744 + * GNU General Public License ("GPL") as published by the Free Software
22745 + * Foundation, either version 2 of that License or (at your option) any
22746 + * later version.
22747 + *
22748 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
22749 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
22750 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
22751 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
22752 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
22753 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22754 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
22755 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22756 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
22757 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
22758 + */
22759 +
22760 +
22761 +#ifndef __TGEC_MII_ACC_H
22762 +#define __TGEC_MII_ACC_H
22763 +
22764 +#include "std_ext.h"
22765 +
22766 +
22767 +/* MII Management Command Register */
22768 +#define MIIMCOM_READ_POST_INCREMENT 0x00004000
22769 +#define MIIMCOM_READ_CYCLE 0x00008000
22770 +#define MIIMCOM_SCAN_CYCLE 0x00000800
22771 +#define MIIMCOM_PREAMBLE_DISABLE 0x00000400
22772 +
22773 +#define MIIMCOM_MDIO_HOLD_1_REG_CLK 0
22774 +#define MIIMCOM_MDIO_HOLD_2_REG_CLK 1
22775 +#define MIIMCOM_MDIO_HOLD_3_REG_CLK 2
22776 +#define MIIMCOM_MDIO_HOLD_4_REG_CLK 3
22777 +
22778 +#define MIIMCOM_DIV_MASK 0x0000ff00
22779 +#define MIIMCOM_DIV_SHIFT 8
22780 +
22781 +/* MII Management Indicator Register */
22782 +#define MIIMIND_BUSY 0x00000001
22783 +#define MIIMIND_READ_ERROR 0x00000002
22784 +
22785 +#define MIIDATA_BUSY 0x80000000
22786 +
22787 +#if defined(__MWERKS__) && !defined(__GNUC__)
22788 +#pragma pack(push,1)
22789 +#endif /* defined(__MWERKS__) && ... */
22790 +
22791 +/*----------------------------------------------------*/
22792 +/* MII Configuration Control Memory Map Registers */
22793 +/*----------------------------------------------------*/
22794 +typedef _Packed struct t_TgecMiiAccessMemMap
22795 +{
22796 + volatile uint32_t mdio_cfg_status; /* 0x030 */
22797 + volatile uint32_t mdio_command; /* 0x034 */
22798 + volatile uint32_t mdio_data; /* 0x038 */
22799 + volatile uint32_t mdio_regaddr; /* 0x03c */
22800 +} _PackedType t_TgecMiiAccessMemMap ;
22801 +
22802 +#if defined(__MWERKS__) && !defined(__GNUC__)
22803 +#pragma pack(pop)
22804 +#endif /* defined(__MWERKS__) && ... */
22805 +
22806 +
22807 +#endif /* __TGEC_MII_ACC_H */
22808 --- /dev/null
22809 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MACSEC/Makefile
22810 @@ -0,0 +1,15 @@
22811 +#
22812 +# Makefile for the Freescale Ethernet controllers
22813 +#
22814 +ccflags-y += -DVERSION=\"\"
22815 +#
22816 +#Include netcomm SW specific definitions
22817 +include $(srctree)/drivers/net/ethernet/freescale/sdk_fman/ncsw_config.mk
22818 +
22819 +NCSW_FM_INC = $(srctree)/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/inc
22820 +
22821 +ccflags-y += -I$(NCSW_FM_INC)
22822 +
22823 +obj-y += fsl-ncsw-macsec.o
22824 +
22825 +fsl-ncsw-macsec-objs := fm_macsec.o fm_macsec_guest.o fm_macsec_master.o fm_macsec_secy.o
22826 --- /dev/null
22827 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MACSEC/fm_macsec.c
22828 @@ -0,0 +1,237 @@
22829 +/*
22830 + * Copyright 2008-2015 Freescale Semiconductor Inc.
22831 + *
22832 + * Redistribution and use in source and binary forms, with or without
22833 + * modification, are permitted provided that the following conditions are met:
22834 + * * Redistributions of source code must retain the above copyright
22835 + * notice, this list of conditions and the following disclaimer.
22836 + * * Redistributions in binary form must reproduce the above copyright
22837 + * notice, this list of conditions and the following disclaimer in the
22838 + * documentation and/or other materials provided with the distribution.
22839 + * * Neither the name of Freescale Semiconductor nor the
22840 + * names of its contributors may be used to endorse or promote products
22841 + * derived from this software without specific prior written permission.
22842 + *
22843 + *
22844 + * ALTERNATIVELY, this software may be distributed under the terms of the
22845 + * GNU General Public License ("GPL") as published by the Free Software
22846 + * Foundation, either version 2 of that License or (at your option) any
22847 + * later version.
22848 + *
22849 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
22850 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
22851 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
22852 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
22853 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
22854 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22855 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
22856 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22857 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
22858 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
22859 + */
22860 +/******************************************************************************
22861 +
22862 + @File fm_macsec.c
22863 +
22864 + @Description FM MACSEC driver routines implementation.
22865 +*//***************************************************************************/
22866 +
22867 +#include "std_ext.h"
22868 +#include "error_ext.h"
22869 +#include "xx_ext.h"
22870 +#include "string_ext.h"
22871 +#include "sprint_ext.h"
22872 +#include "debug_ext.h"
22873 +
22874 +#include "fm_macsec.h"
22875 +
22876 +
22877 +/****************************************/
22878 +/* API Init unit functions */
22879 +/****************************************/
22880 +t_Handle FM_MACSEC_Config(t_FmMacsecParams *p_FmMacsecParam)
22881 +{
22882 + t_FmMacsecControllerDriver *p_FmMacsecControllerDriver;
22883 +
22884 + SANITY_CHECK_RETURN_VALUE(p_FmMacsecParam, E_INVALID_HANDLE, NULL);
22885 +
22886 + if (p_FmMacsecParam->guestMode)
22887 + p_FmMacsecControllerDriver = (t_FmMacsecControllerDriver *)FM_MACSEC_GUEST_Config(p_FmMacsecParam);
22888 + else
22889 + p_FmMacsecControllerDriver = (t_FmMacsecControllerDriver *)FM_MACSEC_MASTER_Config(p_FmMacsecParam);
22890 +
22891 + if (!p_FmMacsecControllerDriver)
22892 + return NULL;
22893 +
22894 + return (t_Handle)p_FmMacsecControllerDriver;
22895 +}
22896 +
22897 +t_Error FM_MACSEC_Init(t_Handle h_FmMacsec)
22898 +{
22899 + t_FmMacsecControllerDriver *p_FmMacsecControllerDriver = (t_FmMacsecControllerDriver *)h_FmMacsec;
22900 +
22901 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecControllerDriver, E_INVALID_HANDLE);
22902 +
22903 + if (p_FmMacsecControllerDriver->f_FM_MACSEC_Init)
22904 + return p_FmMacsecControllerDriver->f_FM_MACSEC_Init(h_FmMacsec);
22905 +
22906 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
22907 +}
22908 +
22909 +t_Error FM_MACSEC_Free(t_Handle h_FmMacsec)
22910 +{
22911 + t_FmMacsecControllerDriver *p_FmMacsecControllerDriver = (t_FmMacsecControllerDriver *)h_FmMacsec;
22912 +
22913 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecControllerDriver, E_INVALID_HANDLE);
22914 +
22915 + if (p_FmMacsecControllerDriver->f_FM_MACSEC_Free)
22916 + return p_FmMacsecControllerDriver->f_FM_MACSEC_Free(h_FmMacsec);
22917 +
22918 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
22919 +}
22920 +
22921 +t_Error FM_MACSEC_ConfigUnknownSciFrameTreatment(t_Handle h_FmMacsec, e_FmMacsecUnknownSciFrameTreatment treatMode)
22922 +{
22923 + t_FmMacsecControllerDriver *p_FmMacsecControllerDriver = (t_FmMacsecControllerDriver *)h_FmMacsec;
22924 +
22925 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecControllerDriver, E_INVALID_HANDLE);
22926 +
22927 + if (p_FmMacsecControllerDriver->f_FM_MACSEC_ConfigUnknownSciFrameTreatment)
22928 + return p_FmMacsecControllerDriver->f_FM_MACSEC_ConfigUnknownSciFrameTreatment(h_FmMacsec, treatMode);
22929 +
22930 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
22931 +}
22932 +
22933 +t_Error FM_MACSEC_ConfigInvalidTagsFrameTreatment(t_Handle h_FmMacsec, bool deliverUncontrolled)
22934 +{
22935 + t_FmMacsecControllerDriver *p_FmMacsecControllerDriver = (t_FmMacsecControllerDriver *)h_FmMacsec;
22936 +
22937 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecControllerDriver, E_INVALID_HANDLE);
22938 +
22939 + if (p_FmMacsecControllerDriver->f_FM_MACSEC_ConfigInvalidTagsFrameTreatment)
22940 + return p_FmMacsecControllerDriver->f_FM_MACSEC_ConfigInvalidTagsFrameTreatment(h_FmMacsec, deliverUncontrolled);
22941 +
22942 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
22943 +}
22944 +
22945 +t_Error FM_MACSEC_ConfigEncryptWithNoChangedTextFrameTreatment(t_Handle h_FmMacsec, bool discardUncontrolled)
22946 +{
22947 + t_FmMacsecControllerDriver *p_FmMacsecControllerDriver = (t_FmMacsecControllerDriver *)h_FmMacsec;
22948 +
22949 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecControllerDriver, E_INVALID_HANDLE);
22950 +
22951 + if (p_FmMacsecControllerDriver->f_FM_MACSEC_ConfigEncryptWithNoChangedTextFrameTreatment)
22952 + return p_FmMacsecControllerDriver->f_FM_MACSEC_ConfigEncryptWithNoChangedTextFrameTreatment(h_FmMacsec, discardUncontrolled);
22953 +
22954 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
22955 +}
22956 +
22957 +t_Error FM_MACSEC_ConfigUntagFrameTreatment(t_Handle h_FmMacsec, e_FmMacsecUntagFrameTreatment treatMode)
22958 +{
22959 + t_FmMacsecControllerDriver *p_FmMacsecControllerDriver = (t_FmMacsecControllerDriver *)h_FmMacsec;
22960 +
22961 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecControllerDriver, E_INVALID_HANDLE);
22962 +
22963 + if (p_FmMacsecControllerDriver->f_FM_MACSEC_ConfigUntagFrameTreatment)
22964 + return p_FmMacsecControllerDriver->f_FM_MACSEC_ConfigUntagFrameTreatment(h_FmMacsec, treatMode);
22965 +
22966 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
22967 +}
22968 +
22969 +t_Error FM_MACSEC_ConfigPnExhaustionThreshold(t_Handle h_FmMacsec, uint32_t pnExhThr)
22970 +{
22971 + t_FmMacsecControllerDriver *p_FmMacsecControllerDriver = (t_FmMacsecControllerDriver *)h_FmMacsec;
22972 +
22973 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecControllerDriver, E_INVALID_HANDLE);
22974 +
22975 + if (p_FmMacsecControllerDriver->f_FM_MACSEC_ConfigPnExhaustionThreshold)
22976 + return p_FmMacsecControllerDriver->f_FM_MACSEC_ConfigPnExhaustionThreshold(h_FmMacsec, pnExhThr);
22977 +
22978 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
22979 +}
22980 +
22981 +t_Error FM_MACSEC_ConfigKeysUnreadable(t_Handle h_FmMacsec)
22982 +{
22983 + t_FmMacsecControllerDriver *p_FmMacsecControllerDriver = (t_FmMacsecControllerDriver *)h_FmMacsec;
22984 +
22985 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecControllerDriver, E_INVALID_HANDLE);
22986 +
22987 + if (p_FmMacsecControllerDriver->f_FM_MACSEC_ConfigKeysUnreadable)
22988 + return p_FmMacsecControllerDriver->f_FM_MACSEC_ConfigKeysUnreadable(h_FmMacsec);
22989 +
22990 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
22991 +}
22992 +
22993 +t_Error FM_MACSEC_ConfigSectagWithoutSCI(t_Handle h_FmMacsec)
22994 +{
22995 + t_FmMacsecControllerDriver *p_FmMacsecControllerDriver = (t_FmMacsecControllerDriver *)h_FmMacsec;
22996 +
22997 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecControllerDriver, E_INVALID_HANDLE);
22998 +
22999 + if (p_FmMacsecControllerDriver->f_FM_MACSEC_ConfigSectagWithoutSCI)
23000 + return p_FmMacsecControllerDriver->f_FM_MACSEC_ConfigSectagWithoutSCI(h_FmMacsec);
23001 +
23002 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
23003 +}
23004 +
23005 +t_Error FM_MACSEC_ConfigException(t_Handle h_FmMacsec, e_FmMacsecExceptions exception, bool enable)
23006 +{
23007 + t_FmMacsecControllerDriver *p_FmMacsecControllerDriver = (t_FmMacsecControllerDriver *)h_FmMacsec;
23008 +
23009 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecControllerDriver, E_INVALID_HANDLE);
23010 +
23011 + if (p_FmMacsecControllerDriver->f_FM_MACSEC_ConfigException)
23012 + return p_FmMacsecControllerDriver->f_FM_MACSEC_ConfigException(h_FmMacsec, exception, enable);
23013 +
23014 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
23015 +}
23016 +
23017 +t_Error FM_MACSEC_GetRevision(t_Handle h_FmMacsec, uint32_t *p_MacsecRevision)
23018 +{
23019 + t_FmMacsecControllerDriver *p_FmMacsecControllerDriver = (t_FmMacsecControllerDriver *)h_FmMacsec;
23020 +
23021 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecControllerDriver, E_INVALID_HANDLE);
23022 +
23023 + if (p_FmMacsecControllerDriver->f_FM_MACSEC_GetRevision)
23024 + return p_FmMacsecControllerDriver->f_FM_MACSEC_GetRevision(h_FmMacsec, p_MacsecRevision);
23025 +
23026 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
23027 +}
23028 +
23029 +
23030 +t_Error FM_MACSEC_Enable(t_Handle h_FmMacsec)
23031 +{
23032 + t_FmMacsecControllerDriver *p_FmMacsecControllerDriver = (t_FmMacsecControllerDriver *)h_FmMacsec;
23033 +
23034 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecControllerDriver, E_INVALID_HANDLE);
23035 +
23036 + if (p_FmMacsecControllerDriver->f_FM_MACSEC_Enable)
23037 + return p_FmMacsecControllerDriver->f_FM_MACSEC_Enable(h_FmMacsec);
23038 +
23039 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
23040 +}
23041 +
23042 +t_Error FM_MACSEC_Disable(t_Handle h_FmMacsec)
23043 +{
23044 + t_FmMacsecControllerDriver *p_FmMacsecControllerDriver = (t_FmMacsecControllerDriver *)h_FmMacsec;
23045 +
23046 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecControllerDriver, E_INVALID_HANDLE);
23047 +
23048 + if (p_FmMacsecControllerDriver->f_FM_MACSEC_Disable)
23049 + return p_FmMacsecControllerDriver->f_FM_MACSEC_Disable(h_FmMacsec);
23050 +
23051 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
23052 +}
23053 +
23054 +t_Error FM_MACSEC_SetException(t_Handle h_FmMacsec, e_FmMacsecExceptions exception, bool enable)
23055 +{
23056 + t_FmMacsecControllerDriver *p_FmMacsecControllerDriver = (t_FmMacsecControllerDriver *)h_FmMacsec;
23057 +
23058 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecControllerDriver, E_INVALID_HANDLE);
23059 +
23060 + if (p_FmMacsecControllerDriver->f_FM_MACSEC_SetException)
23061 + return p_FmMacsecControllerDriver->f_FM_MACSEC_SetException(h_FmMacsec, exception, enable);
23062 +
23063 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
23064 +}
23065 +
23066 --- /dev/null
23067 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MACSEC/fm_macsec.h
23068 @@ -0,0 +1,203 @@
23069 +/*
23070 + * Copyright 2008-2015 Freescale Semiconductor Inc.
23071 + *
23072 + * Redistribution and use in source and binary forms, with or without
23073 + * modification, are permitted provided that the following conditions are met:
23074 + * * Redistributions of source code must retain the above copyright
23075 + * notice, this list of conditions and the following disclaimer.
23076 + * * Redistributions in binary form must reproduce the above copyright
23077 + * notice, this list of conditions and the following disclaimer in the
23078 + * documentation and/or other materials provided with the distribution.
23079 + * * Neither the name of Freescale Semiconductor nor the
23080 + * names of its contributors may be used to endorse or promote products
23081 + * derived from this software without specific prior written permission.
23082 + *
23083 + *
23084 + * ALTERNATIVELY, this software may be distributed under the terms of the
23085 + * GNU General Public License ("GPL") as published by the Free Software
23086 + * Foundation, either version 2 of that License or (at your option) any
23087 + * later version.
23088 + *
23089 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
23090 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
23091 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
23092 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
23093 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
23094 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
23095 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23096 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23097 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
23098 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
23099 + */
23100 +
23101 +/******************************************************************************
23102 + @File fm_macsec.h
23103 +
23104 + @Description FM MACSEC internal structures and definitions.
23105 +*//***************************************************************************/
23106 +#ifndef __FM_MACSEC_H
23107 +#define __FM_MACSEC_H
23108 +
23109 +#include "error_ext.h"
23110 +#include "std_ext.h"
23111 +#include "fm_macsec_ext.h"
23112 +
23113 +#include "fm_common.h"
23114 +
23115 +
23116 +#define __ERR_MODULE__ MODULE_FM_MACSEC
23117 +
23118 +
23119 +typedef struct
23120 +{
23121 + t_Error (*f_FM_MACSEC_Init) (t_Handle h_FmMacsec);
23122 + t_Error (*f_FM_MACSEC_Free) (t_Handle h_FmMacsec);
23123 +
23124 + t_Error (*f_FM_MACSEC_ConfigUnknownSciFrameTreatment) (t_Handle h_FmMacsec, e_FmMacsecUnknownSciFrameTreatment treatMode);
23125 + t_Error (*f_FM_MACSEC_ConfigInvalidTagsFrameTreatment) (t_Handle h_FmMacsec, bool deliverUncontrolled);
23126 + t_Error (*f_FM_MACSEC_ConfigEncryptWithNoChangedTextFrameTreatment) (t_Handle h_FmMacsec, bool discardUncontrolled);
23127 + t_Error (*f_FM_MACSEC_ConfigChangedTextWithNoEncryptFrameTreatment) (t_Handle h_FmMacsec, bool deliverUncontrolled);
23128 + t_Error (*f_FM_MACSEC_ConfigUntagFrameTreatment) (t_Handle h_FmMacsec, e_FmMacsecUntagFrameTreatment treatMode);
23129 + t_Error (*f_FM_MACSEC_ConfigOnlyScbIsSetFrameTreatment) (t_Handle h_FmMacsec, bool deliverUncontrolled);
23130 + t_Error (*f_FM_MACSEC_ConfigPnExhaustionThreshold) (t_Handle h_FmMacsec, uint32_t pnExhThr);
23131 + t_Error (*f_FM_MACSEC_ConfigKeysUnreadable) (t_Handle h_FmMacsec);
23132 + t_Error (*f_FM_MACSEC_ConfigSectagWithoutSCI) (t_Handle h_FmMacsec);
23133 + t_Error (*f_FM_MACSEC_ConfigException) (t_Handle h_FmMacsec, e_FmMacsecExceptions exception, bool enable);
23134 +
23135 + t_Error (*f_FM_MACSEC_GetRevision) (t_Handle h_FmMacsec, uint32_t *p_MacsecRevision);
23136 + t_Error (*f_FM_MACSEC_Enable) (t_Handle h_FmMacsec);
23137 + t_Error (*f_FM_MACSEC_Disable) (t_Handle h_FmMacsec);
23138 + t_Error (*f_FM_MACSEC_SetException) (t_Handle h_FmMacsec, e_FmMacsecExceptions exception, bool enable);
23139 +
23140 +} t_FmMacsecControllerDriver;
23141 +
23142 +t_Handle FM_MACSEC_GUEST_Config(t_FmMacsecParams *p_FmMacsecParam);
23143 +t_Handle FM_MACSEC_MASTER_Config(t_FmMacsecParams *p_FmMacsecParams);
23144 +
23145 +/***********************************************************************/
23146 +/* MACSEC internal routines */
23147 +/***********************************************************************/
23148 +
23149 +/**************************************************************************//**
23150 +
23151 + @Group FM_MACSEC_InterModule_grp FM MACSEC Inter-Module Unit
23152 +
23153 + @Description FM MACSEC Inter Module functions -
23154 + These are not User API routines but routines that may be called
23155 + from other modules. This will be the case in a single core environment,
23156 + where instead of using the XX messaging mechanism, the routines may be
23157 + called from other modules. In a multicore environment, the other modules may
23158 + be run by other cores and therefore these routines may not be called directly.
23159 +
23160 + @{
23161 +*//***************************************************************************/
23162 +
23163 +#define MAX_NUM_OF_SA_PER_SC 4
23164 +
23165 +typedef enum
23166 +{
23167 + e_SC_RX = 0,
23168 + e_SC_TX
23169 +} e_ScType;
23170 +
23171 +typedef enum
23172 +{
23173 + e_SC_SA_A = 0,
23174 + e_SC_SA_B ,
23175 + e_SC_SA_C ,
23176 + e_SC_SA_D
23177 +} e_ScSaId;
23178 +
23179 +typedef struct
23180 +{
23181 + uint32_t scId;
23182 + macsecSCI_t sci;
23183 + bool replayProtect;
23184 + uint32_t replayWindow;
23185 + e_FmMacsecValidFrameBehavior validateFrames;
23186 + uint16_t confidentialityOffset;
23187 + e_FmMacsecSecYCipherSuite cipherSuite;
23188 +} t_RxScParams;
23189 +
23190 +typedef struct
23191 +{
23192 + uint32_t scId;
23193 + macsecSCI_t sci;
23194 + bool protectFrames;
23195 + e_FmMacsecSciInsertionMode sciInsertionMode;
23196 + bool confidentialityEnable;
23197 + uint16_t confidentialityOffset;
23198 + e_FmMacsecSecYCipherSuite cipherSuite;
23199 +} t_TxScParams;
23200 +
23201 +typedef enum e_FmMacsecGlobalExceptions {
23202 + e_FM_MACSEC_EX_TX_SC, /**< Tx Sc 0 frame discarded error. */
23203 + e_FM_MACSEC_EX_ECC /**< MACSEC memory ECC multiple-bit error. */
23204 +} e_FmMacsecGlobalExceptions;
23205 +
23206 +typedef enum e_FmMacsecGlobalEvents {
23207 + e_FM_MACSEC_EV_TX_SC_NEXT_PN /**< Tx Sc 0 Next Pn exhaustion threshold reached. */
23208 +} e_FmMacsecGlobalEvents;
23209 +
23210 +/**************************************************************************//**
23211 + @Description Enum for inter-module interrupts registration
23212 +*//***************************************************************************/
23213 +typedef enum e_FmMacsecEventModules{
23214 + e_FM_MACSEC_MOD_SC_TX,
23215 + e_FM_MACSEC_MOD_DUMMY_LAST
23216 +} e_FmMacsecEventModules;
23217 +
23218 +typedef enum e_FmMacsecInterModuleEvent {
23219 + e_FM_MACSEC_EV_SC_TX,
23220 + e_FM_MACSEC_EV_ERR_SC_TX,
23221 + e_FM_MACSEC_EV_DUMMY_LAST
23222 +} e_FmMacsecInterModuleEvent;
23223 +
23224 +#define NUM_OF_INTER_MODULE_EVENTS (NUM_OF_TX_SC * 2)
23225 +
23226 +#define GET_MACSEC_MODULE_EVENT(mod, id, intrType, event) \
23227 + switch(mod){ \
23228 + case e_FM_MACSEC_MOD_SC_TX: \
23229 + event = (intrType == e_FM_INTR_TYPE_ERR) ? \
23230 + e_FM_MACSEC_EV_ERR_SC_TX: \
23231 + e_FM_MACSEC_EV_SC_TX; \
23232 + event += (uint8_t)(2 * id);break; \
23233 + break; \
23234 + default:event = e_FM_MACSEC_EV_DUMMY_LAST; \
23235 + break;}
23236 +
23237 +void FmMacsecRegisterIntr(t_Handle h_FmMacsec,
23238 + e_FmMacsecEventModules module,
23239 + uint8_t modId,
23240 + e_FmIntrType intrType,
23241 + void (*f_Isr) (t_Handle h_Arg, uint32_t id),
23242 + t_Handle h_Arg);
23243 +
23244 +void FmMacsecUnregisterIntr(t_Handle h_FmMacsec,
23245 + e_FmMacsecEventModules module,
23246 + uint8_t modId,
23247 + e_FmIntrType intrType);
23248 +
23249 +t_Error FmMacsecAllocScs(t_Handle h_FmMacsec, e_ScType type, bool isPtp, uint32_t numOfScs, uint32_t *p_ScIds);
23250 +t_Error FmMacsecFreeScs(t_Handle h_FmMacsec, e_ScType type, uint32_t numOfScs, uint32_t *p_ScIds);
23251 +t_Error FmMacsecCreateRxSc(t_Handle h_FmMacsec, t_RxScParams *p_RxScParams);
23252 +t_Error FmMacsecDeleteRxSc(t_Handle h_FmMacsec, uint32_t scId);
23253 +t_Error FmMacsecCreateTxSc(t_Handle h_FmMacsec, t_TxScParams *p_RxScParams);
23254 +t_Error FmMacsecDeleteTxSc(t_Handle h_FmMacsec, uint32_t scId);
23255 +t_Error FmMacsecCreateRxSa(t_Handle h_FmMacsec, uint32_t scId, e_ScSaId saId, macsecAN_t an, uint32_t lowestPn, macsecSAKey_t key);
23256 +t_Error FmMacsecCreateTxSa(t_Handle h_FmMacsec, uint32_t scId, e_ScSaId saId, macsecSAKey_t key);
23257 +t_Error FmMacsecDeleteRxSa(t_Handle h_FmMacsec, uint32_t scId, e_ScSaId saId);
23258 +t_Error FmMacsecDeleteTxSa(t_Handle h_FmMacsec, uint32_t scId, e_ScSaId saId);
23259 +t_Error FmMacsecRxSaSetReceive(t_Handle h_FmMacsec, uint32_t scId, e_ScSaId saId, bool enableReceive);
23260 +t_Error FmMacsecRxSaUpdateNextPn(t_Handle h_FmMacsec, uint32_t scId, e_ScSaId saId, uint32_t updtNextPN);
23261 +t_Error FmMacsecRxSaUpdateLowestPn(t_Handle h_FmMacsec, uint32_t scId, e_ScSaId saId, uint32_t updtLowestPN);
23262 +t_Error FmMacsecTxSaSetActive(t_Handle h_FmMacsec, uint32_t scId, e_ScSaId saId, macsecAN_t an);
23263 +t_Error FmMacsecTxSaGetActive(t_Handle h_FmMacsec, uint32_t scId, macsecAN_t *p_An);
23264 +t_Error FmMacsecSetPTP(t_Handle h_FmMacsec, bool enable);
23265 +
23266 +t_Error FmMacsecSetException(t_Handle h_FmMacsec, e_FmMacsecGlobalExceptions exception, uint32_t scId, bool enable);
23267 +t_Error FmMacsecSetEvent(t_Handle h_FmMacsec, e_FmMacsecGlobalEvents event, uint32_t scId, bool enable);
23268 +
23269 +
23270 +
23271 +#endif /* __FM_MACSEC_H */
23272 --- /dev/null
23273 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MACSEC/fm_macsec_guest.c
23274 @@ -0,0 +1,59 @@
23275 +/*
23276 + * Copyright 2008-2015 Freescale Semiconductor Inc.
23277 + *
23278 + * Redistribution and use in source and binary forms, with or without
23279 + * modification, are permitted provided that the following conditions are met:
23280 + * * Redistributions of source code must retain the above copyright
23281 + * notice, this list of conditions and the following disclaimer.
23282 + * * Redistributions in binary form must reproduce the above copyright
23283 + * notice, this list of conditions and the following disclaimer in the
23284 + * documentation and/or other materials provided with the distribution.
23285 + * * Neither the name of Freescale Semiconductor nor the
23286 + * names of its contributors may be used to endorse or promote products
23287 + * derived from this software without specific prior written permission.
23288 + *
23289 + *
23290 + * ALTERNATIVELY, this software may be distributed under the terms of the
23291 + * GNU General Public License ("GPL") as published by the Free Software
23292 + * Foundation, either version 2 of that License or (at your option) any
23293 + * later version.
23294 + *
23295 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
23296 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
23297 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
23298 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
23299 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
23300 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
23301 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23302 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23303 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
23304 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
23305 + */
23306 +
23307 +/******************************************************************************
23308 + @File fm_macsec.c
23309 +
23310 + @Description FM MACSEC driver routines implementation.
23311 +*//***************************************************************************/
23312 +
23313 +#include "std_ext.h"
23314 +#include "error_ext.h"
23315 +#include "xx_ext.h"
23316 +#include "string_ext.h"
23317 +#include "sprint_ext.h"
23318 +#include "debug_ext.h"
23319 +#include "fm_macsec.h"
23320 +
23321 +
23322 +/****************************************/
23323 +/* static functions */
23324 +/****************************************/
23325 +
23326 +/****************************************/
23327 +/* API Init unit functions */
23328 +/****************************************/
23329 +t_Handle FM_MACSEC_GUEST_Config(t_FmMacsecParams *p_FmMacsecParam)
23330 +{
23331 + UNUSED(p_FmMacsecParam);
23332 + return NULL;
23333 +}
23334 --- /dev/null
23335 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MACSEC/fm_macsec_master.c
23336 @@ -0,0 +1,1031 @@
23337 +/*
23338 + * Copyright 2008-2015 Freescale Semiconductor Inc.
23339 + *
23340 + * Redistribution and use in source and binary forms, with or without
23341 + * modification, are permitted provided that the following conditions are met:
23342 + * * Redistributions of source code must retain the above copyright
23343 + * notice, this list of conditions and the following disclaimer.
23344 + * * Redistributions in binary form must reproduce the above copyright
23345 + * notice, this list of conditions and the following disclaimer in the
23346 + * documentation and/or other materials provided with the distribution.
23347 + * * Neither the name of Freescale Semiconductor nor the
23348 + * names of its contributors may be used to endorse or promote products
23349 + * derived from this software without specific prior written permission.
23350 + *
23351 + *
23352 + * ALTERNATIVELY, this software may be distributed under the terms of the
23353 + * GNU General Public License ("GPL") as published by the Free Software
23354 + * Foundation, either version 2 of that License or (at your option) any
23355 + * later version.
23356 + *
23357 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
23358 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
23359 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
23360 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
23361 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
23362 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
23363 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23364 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23365 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
23366 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
23367 + */
23368 +
23369 +/******************************************************************************
23370 + @File fm_macsec.c
23371 +
23372 + @Description FM MACSEC driver routines implementation.
23373 +*//***************************************************************************/
23374 +
23375 +#include "std_ext.h"
23376 +#include "error_ext.h"
23377 +#include "xx_ext.h"
23378 +#include "string_ext.h"
23379 +#include "sprint_ext.h"
23380 +#include "fm_mac_ext.h"
23381 +
23382 +#include "fm_macsec_master.h"
23383 +
23384 +
23385 +extern uint16_t FM_MAC_GetMaxFrameLength(t_Handle FmMac);
23386 +
23387 +
23388 +/****************************************/
23389 +/* static functions */
23390 +/****************************************/
23391 +static t_Error CheckFmMacsecParameters(t_FmMacsec *p_FmMacsec)
23392 +{
23393 + if (!p_FmMacsec->f_Exception)
23394 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Exceptions callback not provided"));
23395 +
23396 + return E_OK;
23397 +}
23398 +
23399 +static void UnimplementedIsr(t_Handle h_Arg, uint32_t id)
23400 +{
23401 + UNUSED(h_Arg); UNUSED(id);
23402 +
23403 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Unimplemented Isr!"));
23404 +}
23405 +
23406 +static void MacsecEventIsr(t_Handle h_FmMacsec)
23407 +{
23408 + t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec;
23409 + uint32_t events,event,i;
23410 +
23411 + SANITY_CHECK_RETURN(p_FmMacsec, E_INVALID_HANDLE);
23412 +
23413 + events = GET_UINT32(p_FmMacsec->p_FmMacsecRegs->evr);
23414 + events |= GET_UINT32(p_FmMacsec->p_FmMacsecRegs->ever);
23415 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->evr,events);
23416 +
23417 + for (i=0; i<NUM_OF_TX_SC; i++)
23418 + if (events & FM_MACSEC_EV_TX_SC_NEXT_PN(i))
23419 + {
23420 + GET_MACSEC_MODULE_EVENT(e_FM_MACSEC_MOD_SC_TX, i, e_FM_INTR_TYPE_NORMAL, event);
23421 + p_FmMacsec->intrMng[event].f_Isr(p_FmMacsec->intrMng[event].h_SrcHandle, i);
23422 + }
23423 +}
23424 +
23425 +static void MacsecErrorIsr(t_Handle h_FmMacsec)
23426 +{
23427 + t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec;
23428 + uint32_t errors,error,i;
23429 +
23430 + SANITY_CHECK_RETURN(p_FmMacsec, E_INVALID_HANDLE);
23431 +
23432 + errors = GET_UINT32(p_FmMacsec->p_FmMacsecRegs->err);
23433 + errors |= GET_UINT32(p_FmMacsec->p_FmMacsecRegs->erer);
23434 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->err,errors);
23435 +
23436 + for (i=0; i<NUM_OF_TX_SC; i++)
23437 + if (errors & FM_MACSEC_EX_TX_SC(i))
23438 + {
23439 + GET_MACSEC_MODULE_EVENT(e_FM_MACSEC_MOD_SC_TX, i, e_FM_INTR_TYPE_ERR, error);
23440 + p_FmMacsec->intrMng[error].f_Isr(p_FmMacsec->intrMng[error].h_SrcHandle, i);
23441 + }
23442 +
23443 + if (errors & FM_MACSEC_EX_ECC)
23444 + {
23445 + uint8_t eccType;
23446 + uint32_t tmpReg;
23447 +
23448 + tmpReg = GET_UINT32(p_FmMacsec->p_FmMacsecRegs->meec);
23449 + ASSERT_COND(tmpReg & MECC_CAP);
23450 + eccType = (uint8_t)((tmpReg & MECC_CET) >> MECC_CET_SHIFT);
23451 +
23452 + if (!eccType && (p_FmMacsec->userExceptions & FM_MACSEC_USER_EX_SINGLE_BIT_ECC))
23453 + p_FmMacsec->f_Exception(p_FmMacsec->h_App,e_FM_MACSEC_EX_SINGLE_BIT_ECC);
23454 + else if (eccType && (p_FmMacsec->userExceptions & FM_MACSEC_USER_EX_MULTI_BIT_ECC))
23455 + p_FmMacsec->f_Exception(p_FmMacsec->h_App,e_FM_MACSEC_EX_MULTI_BIT_ECC);
23456 + else
23457 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->meec,tmpReg);
23458 + }
23459 +}
23460 +
23461 +static t_Error MacsecInit(t_Handle h_FmMacsec)
23462 +{
23463 + t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec;
23464 + t_FmMacsecDriverParam *p_FmMacsecDriverParam = NULL;
23465 + uint32_t tmpReg,i,macId;
23466 +
23467 + SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE);
23468 + SANITY_CHECK_RETURN_ERROR(p_FmMacsec->p_FmMacsecDriverParam, E_INVALID_HANDLE);
23469 +
23470 + CHECK_INIT_PARAMETERS(p_FmMacsec, CheckFmMacsecParameters);
23471 +
23472 + p_FmMacsecDriverParam = p_FmMacsec->p_FmMacsecDriverParam;
23473 +
23474 + for (i=0;i<e_FM_MACSEC_EV_DUMMY_LAST;i++)
23475 + p_FmMacsec->intrMng[i].f_Isr = UnimplementedIsr;
23476 +
23477 + tmpReg = 0;
23478 + tmpReg |= (p_FmMacsecDriverParam->changedTextWithNoEncryptDeliverUncontrolled << CFG_UECT_SHIFT)|
23479 + (p_FmMacsecDriverParam->onlyScbIsSetDeliverUncontrolled << CFG_ESCBT_SHIFT) |
23480 + (p_FmMacsecDriverParam->unknownSciTreatMode << CFG_USFT_SHIFT) |
23481 + (p_FmMacsecDriverParam->invalidTagsDeliverUncontrolled << CFG_ITT_SHIFT) |
23482 + (p_FmMacsecDriverParam->encryptWithNoChangedTextDiscardUncontrolled << CFG_KFT_SHIFT) |
23483 + (p_FmMacsecDriverParam->untagTreatMode << CFG_UFT_SHIFT) |
23484 + (p_FmMacsecDriverParam->keysUnreadable << CFG_KSS_SHIFT) |
23485 + (p_FmMacsecDriverParam->reservedSc0 << CFG_S0I_SHIFT) |
23486 + (p_FmMacsecDriverParam->byPassMode << CFG_BYPN_SHIFT);
23487 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->cfg, tmpReg);
23488 +
23489 + tmpReg = FM_MAC_GetMaxFrameLength(p_FmMacsec->h_FmMac);
23490 + /* At least Ethernet FCS (4 bytes) overhead must be subtracted from MFL.
23491 + * In addition, the SCI (8 bytes) overhead might be subtracted as well. */
23492 + tmpReg -= p_FmMacsecDriverParam->mflSubtract;
23493 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->mfl, tmpReg);
23494 +
23495 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->tpnet, p_FmMacsecDriverParam->pnExhThr);
23496 +
23497 + if (!p_FmMacsec->userExceptions)
23498 + p_FmMacsec->exceptions &= ~FM_MACSEC_EX_ECC;
23499 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->erer, p_FmMacsec->exceptions);
23500 +
23501 + p_FmMacsec->numRxScAvailable = NUM_OF_RX_SC;
23502 + if (p_FmMacsecDriverParam->reservedSc0)
23503 + p_FmMacsec->numRxScAvailable --;
23504 + p_FmMacsec->numTxScAvailable = NUM_OF_TX_SC;
23505 +
23506 + XX_Free(p_FmMacsecDriverParam);
23507 + p_FmMacsec->p_FmMacsecDriverParam = NULL;
23508 +
23509 + FM_MAC_GetId(p_FmMacsec->h_FmMac, &macId);
23510 + FmRegisterIntr(p_FmMacsec->h_Fm,
23511 + e_FM_MOD_MACSEC,
23512 + (uint8_t)macId,
23513 + e_FM_INTR_TYPE_NORMAL,
23514 + MacsecEventIsr,
23515 + p_FmMacsec);
23516 +
23517 + FmRegisterIntr(p_FmMacsec->h_Fm,
23518 + e_FM_MOD_MACSEC,
23519 + 0,
23520 + e_FM_INTR_TYPE_ERR,
23521 + MacsecErrorIsr,
23522 + p_FmMacsec);
23523 +
23524 + return E_OK;
23525 +}
23526 +
23527 +static t_Error MacsecFree(t_Handle h_FmMacsec)
23528 +{
23529 + t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec;
23530 + uint32_t macId;
23531 +
23532 + SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE);
23533 + SANITY_CHECK_RETURN_ERROR(!p_FmMacsec->p_FmMacsecDriverParam, E_INVALID_HANDLE);
23534 +
23535 + FM_MAC_GetId(p_FmMacsec->h_FmMac, &macId);
23536 + FmUnregisterIntr(p_FmMacsec->h_Fm,
23537 + e_FM_MOD_MACSEC,
23538 + (uint8_t)macId,
23539 + e_FM_INTR_TYPE_NORMAL);
23540 +
23541 + FmUnregisterIntr(p_FmMacsec->h_Fm,
23542 + e_FM_MOD_MACSEC,
23543 + 0,
23544 + e_FM_INTR_TYPE_ERR);
23545 +
23546 + if (p_FmMacsec->rxScSpinLock)
23547 + XX_FreeSpinlock(p_FmMacsec->rxScSpinLock);
23548 + if (p_FmMacsec->txScSpinLock)
23549 + XX_FreeSpinlock(p_FmMacsec->txScSpinLock);
23550 +
23551 + XX_Free(p_FmMacsec);
23552 +
23553 + return E_OK;
23554 +}
23555 +
23556 +static t_Error MacsecConfigUnknownSciFrameTreatment(t_Handle h_FmMacsec, e_FmMacsecUnknownSciFrameTreatment treatMode)
23557 +{
23558 + t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec;
23559 +
23560 + SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE);
23561 + SANITY_CHECK_RETURN_ERROR(p_FmMacsec->p_FmMacsecDriverParam, E_INVALID_HANDLE);
23562 +
23563 + p_FmMacsec->p_FmMacsecDriverParam->unknownSciTreatMode = treatMode;
23564 +
23565 + return E_OK;
23566 +}
23567 +
23568 +static t_Error MacsecConfigInvalidTagsFrameTreatment(t_Handle h_FmMacsec, bool deliverUncontrolled)
23569 +{
23570 + t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec;
23571 +
23572 + SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE);
23573 + SANITY_CHECK_RETURN_ERROR(p_FmMacsec->p_FmMacsecDriverParam, E_INVALID_HANDLE);
23574 +
23575 + p_FmMacsec->p_FmMacsecDriverParam->invalidTagsDeliverUncontrolled = deliverUncontrolled;
23576 +
23577 + return E_OK;
23578 +}
23579 +
23580 +static t_Error MacsecConfigChangedTextWithNoEncryptFrameTreatment(t_Handle h_FmMacsec, bool deliverUncontrolled)
23581 +{
23582 + t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec;
23583 +
23584 + SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE);
23585 + SANITY_CHECK_RETURN_ERROR(p_FmMacsec->p_FmMacsecDriverParam, E_INVALID_HANDLE);
23586 +
23587 + p_FmMacsec->p_FmMacsecDriverParam->changedTextWithNoEncryptDeliverUncontrolled = deliverUncontrolled;
23588 +
23589 + return E_OK;
23590 +}
23591 +
23592 +static t_Error MacsecConfigOnlyScbIsSetFrameTreatment(t_Handle h_FmMacsec, bool deliverUncontrolled)
23593 +{
23594 + t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec;
23595 +
23596 + SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE);
23597 + SANITY_CHECK_RETURN_ERROR(p_FmMacsec->p_FmMacsecDriverParam, E_INVALID_HANDLE);
23598 +
23599 + p_FmMacsec->p_FmMacsecDriverParam->onlyScbIsSetDeliverUncontrolled = deliverUncontrolled;
23600 +
23601 + return E_OK;
23602 +}
23603 +
23604 +static t_Error MacsecConfigEncryptWithNoChangedTextFrameTreatment(t_Handle h_FmMacsec, bool discardUncontrolled)
23605 +{
23606 + t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec;
23607 +
23608 + SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE);
23609 + SANITY_CHECK_RETURN_ERROR(p_FmMacsec->p_FmMacsecDriverParam, E_INVALID_HANDLE);
23610 +
23611 + p_FmMacsec->p_FmMacsecDriverParam->encryptWithNoChangedTextDiscardUncontrolled = discardUncontrolled;
23612 +
23613 + return E_OK;
23614 +}
23615 +
23616 +static t_Error MacsecConfigUntagFrameTreatment(t_Handle h_FmMacsec, e_FmMacsecUntagFrameTreatment treatMode)
23617 +{
23618 + t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec;
23619 +
23620 + SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE);
23621 + SANITY_CHECK_RETURN_ERROR(p_FmMacsec->p_FmMacsecDriverParam, E_INVALID_HANDLE);
23622 +
23623 + p_FmMacsec->p_FmMacsecDriverParam->untagTreatMode = treatMode;
23624 +
23625 + return E_OK;
23626 +}
23627 +
23628 +static t_Error MacsecConfigPnExhaustionThreshold(t_Handle h_FmMacsec, uint32_t pnExhThr)
23629 +{
23630 + t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec;
23631 +
23632 + SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE);
23633 + SANITY_CHECK_RETURN_ERROR(p_FmMacsec->p_FmMacsecDriverParam, E_INVALID_HANDLE);
23634 +
23635 + p_FmMacsec->p_FmMacsecDriverParam->pnExhThr = pnExhThr;
23636 +
23637 + return E_OK;
23638 +}
23639 +
23640 +static t_Error MacsecConfigKeysUnreadable(t_Handle h_FmMacsec)
23641 +{
23642 + t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec;
23643 +
23644 + SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE);
23645 + SANITY_CHECK_RETURN_ERROR(p_FmMacsec->p_FmMacsecDriverParam, E_INVALID_HANDLE);
23646 +
23647 + p_FmMacsec->p_FmMacsecDriverParam->keysUnreadable = TRUE;
23648 +
23649 + return E_OK;
23650 +}
23651 +
23652 +static t_Error MacsecConfigSectagWithoutSCI(t_Handle h_FmMacsec)
23653 +{
23654 + t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec;
23655 +
23656 + SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE);
23657 + SANITY_CHECK_RETURN_ERROR(p_FmMacsec->p_FmMacsecDriverParam, E_INVALID_HANDLE);
23658 +
23659 + p_FmMacsec->p_FmMacsecDriverParam->sectagOverhead -= MACSEC_SCI_SIZE;
23660 + p_FmMacsec->p_FmMacsecDriverParam->mflSubtract += MACSEC_SCI_SIZE;
23661 +
23662 + return E_OK;
23663 +}
23664 +
23665 +static t_Error MacsecConfigException(t_Handle h_FmMacsec, e_FmMacsecExceptions exception, bool enable)
23666 +{
23667 + t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec;
23668 + uint32_t bitMask = 0;
23669 +
23670 + SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE);
23671 + SANITY_CHECK_RETURN_ERROR(p_FmMacsec->p_FmMacsecDriverParam, E_INVALID_HANDLE);
23672 +
23673 + GET_USER_EXCEPTION_FLAG(bitMask, exception);
23674 + if (bitMask)
23675 + {
23676 + if (enable)
23677 + p_FmMacsec->userExceptions |= bitMask;
23678 + else
23679 + p_FmMacsec->userExceptions &= ~bitMask;
23680 + }
23681 + else
23682 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Undefined exception"));
23683 +
23684 + return E_OK;
23685 +}
23686 +
23687 +static t_Error MacsecGetRevision(t_Handle h_FmMacsec, uint32_t *p_MacsecRevision)
23688 +{
23689 + t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec;
23690 +
23691 + SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE);
23692 + SANITY_CHECK_RETURN_ERROR(!p_FmMacsec->p_FmMacsecDriverParam, E_INVALID_HANDLE);
23693 +
23694 + *p_MacsecRevision = GET_UINT32(p_FmMacsec->p_FmMacsecRegs->ip_rev1);
23695 +
23696 + return E_OK;
23697 +}
23698 +
23699 +static t_Error MacsecEnable(t_Handle h_FmMacsec)
23700 +{
23701 + t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec;
23702 + uint32_t tmpReg;
23703 +
23704 + SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE);
23705 + SANITY_CHECK_RETURN_ERROR(!p_FmMacsec->p_FmMacsecDriverParam, E_INVALID_HANDLE);
23706 +
23707 + tmpReg = GET_UINT32(p_FmMacsec->p_FmMacsecRegs->cfg);
23708 + tmpReg |= CFG_BYPN;
23709 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->cfg,tmpReg);
23710 +
23711 + return E_OK;
23712 +}
23713 +
23714 +static t_Error MacsecDisable(t_Handle h_FmMacsec)
23715 +{
23716 + t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec;
23717 + uint32_t tmpReg;
23718 +
23719 + SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE);
23720 + SANITY_CHECK_RETURN_ERROR(!p_FmMacsec->p_FmMacsecDriverParam, E_INVALID_HANDLE);
23721 +
23722 + tmpReg = GET_UINT32(p_FmMacsec->p_FmMacsecRegs->cfg);
23723 + tmpReg &= ~CFG_BYPN;
23724 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->cfg,tmpReg);
23725 +
23726 + return E_OK;
23727 +}
23728 +
23729 +static t_Error MacsecSetException(t_Handle h_FmMacsec, e_FmMacsecExceptions exception, bool enable)
23730 +{
23731 + t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec;
23732 + uint32_t bitMask;
23733 +
23734 + SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE);
23735 + SANITY_CHECK_RETURN_ERROR(!p_FmMacsec->p_FmMacsecDriverParam, E_INVALID_HANDLE);
23736 +
23737 + GET_USER_EXCEPTION_FLAG(bitMask, exception);
23738 + if (bitMask)
23739 + {
23740 + if (enable)
23741 + p_FmMacsec->userExceptions |= bitMask;
23742 + else
23743 + p_FmMacsec->userExceptions &= ~bitMask;
23744 + }
23745 + else
23746 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Undefined exception"));
23747 +
23748 + if (!p_FmMacsec->userExceptions)
23749 + p_FmMacsec->exceptions &= ~FM_MACSEC_EX_ECC;
23750 + else
23751 + p_FmMacsec->exceptions |= FM_MACSEC_EX_ECC;
23752 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->erer, p_FmMacsec->exceptions);
23753 +
23754 + return E_OK;
23755 +}
23756 +
23757 +static void InitFmMacsecControllerDriver(t_FmMacsecControllerDriver *p_FmMacsecControllerDriver)
23758 +{
23759 + p_FmMacsecControllerDriver->f_FM_MACSEC_Init = MacsecInit;
23760 + p_FmMacsecControllerDriver->f_FM_MACSEC_Free = MacsecFree;
23761 + p_FmMacsecControllerDriver->f_FM_MACSEC_ConfigUnknownSciFrameTreatment = MacsecConfigUnknownSciFrameTreatment;
23762 + p_FmMacsecControllerDriver->f_FM_MACSEC_ConfigInvalidTagsFrameTreatment = MacsecConfigInvalidTagsFrameTreatment;
23763 + p_FmMacsecControllerDriver->f_FM_MACSEC_ConfigEncryptWithNoChangedTextFrameTreatment = MacsecConfigEncryptWithNoChangedTextFrameTreatment;
23764 + p_FmMacsecControllerDriver->f_FM_MACSEC_ConfigUntagFrameTreatment = MacsecConfigUntagFrameTreatment;
23765 + p_FmMacsecControllerDriver->f_FM_MACSEC_ConfigChangedTextWithNoEncryptFrameTreatment = MacsecConfigChangedTextWithNoEncryptFrameTreatment;
23766 + p_FmMacsecControllerDriver->f_FM_MACSEC_ConfigOnlyScbIsSetFrameTreatment = MacsecConfigOnlyScbIsSetFrameTreatment;
23767 + p_FmMacsecControllerDriver->f_FM_MACSEC_ConfigPnExhaustionThreshold = MacsecConfigPnExhaustionThreshold;
23768 + p_FmMacsecControllerDriver->f_FM_MACSEC_ConfigKeysUnreadable = MacsecConfigKeysUnreadable;
23769 + p_FmMacsecControllerDriver->f_FM_MACSEC_ConfigSectagWithoutSCI = MacsecConfigSectagWithoutSCI;
23770 + p_FmMacsecControllerDriver->f_FM_MACSEC_ConfigException = MacsecConfigException;
23771 + p_FmMacsecControllerDriver->f_FM_MACSEC_GetRevision = MacsecGetRevision;
23772 + p_FmMacsecControllerDriver->f_FM_MACSEC_Enable = MacsecEnable;
23773 + p_FmMacsecControllerDriver->f_FM_MACSEC_Disable = MacsecDisable;
23774 + p_FmMacsecControllerDriver->f_FM_MACSEC_SetException = MacsecSetException;
23775 +}
23776 +
23777 +/****************************************/
23778 +/* Inter-Module functions */
23779 +/****************************************/
23780 +
23781 +void FmMacsecRegisterIntr(t_Handle h_FmMacsec,
23782 + e_FmMacsecEventModules module,
23783 + uint8_t modId,
23784 + e_FmIntrType intrType,
23785 + void (*f_Isr) (t_Handle h_Arg, uint32_t id),
23786 + t_Handle h_Arg)
23787 +{
23788 + t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec;
23789 + uint8_t event= 0;
23790 +
23791 + SANITY_CHECK_RETURN(p_FmMacsec, E_INVALID_HANDLE);
23792 +
23793 + GET_MACSEC_MODULE_EVENT(module, modId, intrType, event);
23794 +
23795 + ASSERT_COND(event != e_FM_MACSEC_EV_DUMMY_LAST);
23796 + p_FmMacsec->intrMng[event].f_Isr = f_Isr;
23797 + p_FmMacsec->intrMng[event].h_SrcHandle = h_Arg;
23798 +}
23799 +
23800 +void FmMacsecUnregisterIntr(t_Handle h_FmMacsec,
23801 + e_FmMacsecEventModules module,
23802 + uint8_t modId,
23803 + e_FmIntrType intrType)
23804 +{
23805 + t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec;
23806 + uint8_t event= 0;
23807 +
23808 + SANITY_CHECK_RETURN(p_FmMacsec, E_INVALID_HANDLE);
23809 +
23810 + GET_MACSEC_MODULE_EVENT(module, modId,intrType, event);
23811 +
23812 + ASSERT_COND(event != e_FM_MACSEC_EV_DUMMY_LAST);
23813 + p_FmMacsec->intrMng[event].f_Isr = NULL;
23814 + p_FmMacsec->intrMng[event].h_SrcHandle = NULL;
23815 +}
23816 +
23817 +t_Error FmMacsecAllocScs(t_Handle h_FmMacsec, e_ScType type, bool isPtp, uint32_t numOfScs, uint32_t *p_ScIds)
23818 +{
23819 + t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec;
23820 + t_Error err = E_OK;
23821 + bool *p_ScTable;
23822 + uint32_t *p_ScAvailable,i;
23823 +
23824 + SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE);
23825 + SANITY_CHECK_RETURN_ERROR(p_ScIds, E_INVALID_HANDLE);
23826 + SANITY_CHECK_RETURN_ERROR(numOfScs, E_INVALID_HANDLE);
23827 +
23828 + if (type == e_SC_RX)
23829 + {
23830 + p_ScTable = (bool *)p_FmMacsec->rxScTable;
23831 + p_ScAvailable = &p_FmMacsec->numRxScAvailable;
23832 + i = (NUM_OF_RX_SC - 1);
23833 + }
23834 + else
23835 + {
23836 + p_ScTable = (bool *)p_FmMacsec->txScTable;
23837 + p_ScAvailable = &p_FmMacsec->numTxScAvailable;
23838 + i = (NUM_OF_TX_SC - 1);
23839 +
23840 + }
23841 + if (*p_ScAvailable < numOfScs)
23842 + RETURN_ERROR(MINOR, E_NOT_AVAILABLE, ("Not enough SCs available"));
23843 +
23844 + if (isPtp)
23845 + {
23846 + i = 0;
23847 + if (p_ScTable[i])
23848 + RETURN_ERROR(MINOR, E_NOT_AVAILABLE, ("Sc 0 Not available"));
23849 + }
23850 +
23851 + for (;numOfScs;i--)
23852 + {
23853 + if (p_ScTable[i])
23854 + continue;
23855 + numOfScs --;
23856 + (*p_ScAvailable)--;
23857 + p_ScIds[numOfScs] = i;
23858 + p_ScTable[i] = TRUE;
23859 + }
23860 +
23861 + return err;
23862 +}
23863 +
23864 +t_Error FmMacsecFreeScs(t_Handle h_FmMacsec, e_ScType type, uint32_t numOfScs, uint32_t *p_ScIds)
23865 +{
23866 + t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec;
23867 + t_Error err = E_OK;
23868 + bool *p_ScTable;
23869 + uint32_t *p_ScAvailable,maxNumOfSc,i;
23870 +
23871 + SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE);
23872 + SANITY_CHECK_RETURN_ERROR(p_ScIds, E_INVALID_HANDLE);
23873 + SANITY_CHECK_RETURN_ERROR(numOfScs, E_INVALID_HANDLE);
23874 +
23875 + if (type == e_SC_RX)
23876 + {
23877 + p_ScTable = (bool *)p_FmMacsec->rxScTable;
23878 + p_ScAvailable = &p_FmMacsec->numRxScAvailable;
23879 + maxNumOfSc = NUM_OF_RX_SC;
23880 + }
23881 + else
23882 + {
23883 + p_ScTable = (bool *)p_FmMacsec->txScTable;
23884 + p_ScAvailable = &p_FmMacsec->numTxScAvailable;
23885 + maxNumOfSc = NUM_OF_TX_SC;
23886 + }
23887 +
23888 + if ((*p_ScAvailable + numOfScs) > maxNumOfSc)
23889 + RETURN_ERROR(MINOR, E_FULL, ("Too much SCs"));
23890 +
23891 + for (i=0;i<numOfScs;i++)
23892 + {
23893 + p_ScTable[p_ScIds[i]] = FALSE;
23894 + (*p_ScAvailable)++;
23895 + }
23896 +
23897 + return err;
23898 +
23899 +}
23900 +
23901 +t_Error FmMacsecSetPTP(t_Handle h_FmMacsec, bool enable)
23902 +{
23903 + t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec;
23904 + uint32_t tmpReg = 0;
23905 +
23906 + SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE);
23907 +
23908 + tmpReg = GET_UINT32(p_FmMacsec->p_FmMacsecRegs->cfg);
23909 + if (enable && (tmpReg & CFG_S0I))
23910 + RETURN_ERROR(MINOR, E_INVALID_STATE, ("MACSEC already in point-to-point mode"));
23911 +
23912 + if (enable)
23913 + tmpReg |= CFG_S0I;
23914 + else
23915 + tmpReg &= ~CFG_S0I;
23916 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->cfg, tmpReg);
23917 +
23918 + return E_OK;
23919 +}
23920 +
23921 +t_Error FmMacsecCreateRxSc(t_Handle h_FmMacsec, t_RxScParams *p_RxScParams)
23922 +{
23923 + t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec;
23924 + t_Error err = E_OK;
23925 + uint32_t tmpReg = 0, intFlags;
23926 +
23927 + SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE);
23928 + SANITY_CHECK_RETURN_ERROR(p_RxScParams, E_INVALID_HANDLE);
23929 + SANITY_CHECK_RETURN_ERROR(p_RxScParams->scId < NUM_OF_RX_SC, E_INVALID_HANDLE);
23930 +
23931 + intFlags = XX_LockIntrSpinlock(p_FmMacsec->rxScSpinLock);
23932 +
23933 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->rxsca, p_RxScParams->scId);
23934 + tmpReg = GET_UINT32(p_FmMacsec->p_FmMacsecRegs->rxsccfg);
23935 + if (tmpReg & RX_SCCFG_SCI_EN_MASK)
23936 + {
23937 + XX_UnlockIntrSpinlock(p_FmMacsec->rxScSpinLock, intFlags);
23938 + RETURN_ERROR(MINOR, E_INVALID_STATE, ("Rx Sc %d must be disable",p_RxScParams->scId));
23939 + }
23940 +
23941 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->rxsci1h, GET_SCI_FIRST_HALF(p_RxScParams->sci));
23942 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->rxsci2h, GET_SCI_SECOND_HALF(p_RxScParams->sci));
23943 + tmpReg |= ((p_RxScParams->replayProtect << RX_SCCFG_RP_SHIFT) & RX_SCCFG_RP_MASK);
23944 + tmpReg |= ((p_RxScParams->validateFrames << RX_SCCFG_VF_SHIFT) & RX_SCCFG_VF_MASK);
23945 + tmpReg |= ((p_RxScParams->confidentialityOffset << RX_SCCFG_CO_SHIFT) & RX_SCCFG_CO_MASK);
23946 + tmpReg |= RX_SCCFG_SCI_EN_MASK;
23947 + tmpReg |= (p_RxScParams->cipherSuite << RX_SCCFG_CS_SHIFT);
23948 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->rxsccfg, tmpReg);
23949 +
23950 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->rpw, p_RxScParams->replayWindow);
23951 +
23952 + XX_UnlockIntrSpinlock(p_FmMacsec->rxScSpinLock, intFlags);
23953 +
23954 + return err;
23955 +}
23956 +
23957 +t_Error FmMacsecDeleteRxSc(t_Handle h_FmMacsec, uint32_t scId)
23958 +{
23959 + t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec;
23960 + t_Error err = E_OK;
23961 + uint32_t tmpReg = 0, intFlags;
23962 +
23963 + SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE);
23964 + SANITY_CHECK_RETURN_ERROR(scId < NUM_OF_RX_SC, E_INVALID_HANDLE);
23965 +
23966 + intFlags = XX_LockIntrSpinlock(p_FmMacsec->rxScSpinLock);
23967 +
23968 + tmpReg &= ~RX_SCCFG_SCI_EN_MASK;
23969 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->rxsca, scId);
23970 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->rxsccfg, tmpReg);
23971 +
23972 + XX_UnlockIntrSpinlock(p_FmMacsec->rxScSpinLock, intFlags);
23973 +
23974 + return err;
23975 +}
23976 +
23977 +t_Error FmMacsecCreateTxSc(t_Handle h_FmMacsec, t_TxScParams *p_TxScParams)
23978 +{
23979 + t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec;
23980 + t_Error err = E_OK;
23981 + uint32_t tmpReg = 0, intFlags;
23982 + bool alwaysIncludeSCI = FALSE, useES = FALSE, useSCB = FALSE;
23983 +
23984 + SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE);
23985 + SANITY_CHECK_RETURN_ERROR(p_TxScParams, E_INVALID_HANDLE);
23986 + SANITY_CHECK_RETURN_ERROR(p_TxScParams->scId < NUM_OF_TX_SC, E_INVALID_HANDLE);
23987 +
23988 + intFlags = XX_LockIntrSpinlock(p_FmMacsec->txScSpinLock);
23989 +
23990 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->txsca, p_TxScParams->scId);
23991 +
23992 + tmpReg = GET_UINT32(p_FmMacsec->p_FmMacsecRegs->txsccfg);
23993 + if (tmpReg & TX_SCCFG_SCE_MASK)
23994 + {
23995 + XX_UnlockIntrSpinlock(p_FmMacsec->txScSpinLock, intFlags);
23996 + RETURN_ERROR(MINOR, E_INVALID_STATE, ("Tx Sc %d must be disable",p_TxScParams->scId));
23997 + }
23998 +
23999 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->txsci1h, GET_SCI_FIRST_HALF(p_TxScParams->sci));
24000 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->txsci2h, GET_SCI_SECOND_HALF(p_TxScParams->sci));
24001 + alwaysIncludeSCI = (p_TxScParams->sciInsertionMode == e_FM_MACSEC_SCI_INSERTION_MODE_EXPLICIT_SECTAG);
24002 + useES = (p_TxScParams->sciInsertionMode == e_FM_MACSEC_SCI_INSERTION_MODE_EXPLICIT_MAC_SA);
24003 +
24004 + tmpReg |= ((p_TxScParams->protectFrames << TX_SCCFG_PF_SHIFT) & TX_SCCFG_PF_MASK);
24005 + tmpReg |= ((alwaysIncludeSCI << TX_SCCFG_AIS_SHIFT) & TX_SCCFG_AIS_MASK);
24006 + tmpReg |= ((useES << TX_SCCFG_UES_SHIFT) & TX_SCCFG_UES_MASK);
24007 + tmpReg |= ((useSCB << TX_SCCFG_USCB_SHIFT) & TX_SCCFG_USCB_MASK);
24008 + tmpReg |= ((p_TxScParams->confidentialityEnable << TX_SCCFG_CE_SHIFT) & TX_SCCFG_CE_MASK);
24009 + tmpReg |= ((p_TxScParams->confidentialityOffset << TX_SCCFG_CO_SHIFT) & TX_SCCFG_CO_MASK);
24010 + tmpReg |= TX_SCCFG_SCE_MASK;
24011 + tmpReg |= (p_TxScParams->cipherSuite << TX_SCCFG_CS_SHIFT);
24012 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->txsccfg, tmpReg);
24013 +
24014 + XX_UnlockIntrSpinlock(p_FmMacsec->txScSpinLock, intFlags);
24015 +
24016 + return err;
24017 +}
24018 +
24019 +t_Error FmMacsecDeleteTxSc(t_Handle h_FmMacsec, uint32_t scId)
24020 +{
24021 + t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec;
24022 + t_Error err = E_OK;
24023 + uint32_t tmpReg = 0, intFlags;
24024 +
24025 + SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE);
24026 + SANITY_CHECK_RETURN_ERROR(scId < NUM_OF_TX_SC, E_INVALID_HANDLE);
24027 +
24028 + intFlags = XX_LockIntrSpinlock(p_FmMacsec->txScSpinLock);
24029 +
24030 + tmpReg &= ~TX_SCCFG_SCE_MASK;
24031 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->txsca, scId);
24032 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->txsccfg, tmpReg);
24033 +
24034 + XX_UnlockIntrSpinlock(p_FmMacsec->txScSpinLock, intFlags);
24035 +
24036 + return err;
24037 +}
24038 +
24039 +t_Error FmMacsecCreateRxSa(t_Handle h_FmMacsec, uint32_t scId, e_ScSaId saId, macsecAN_t an, uint32_t lowestPn, macsecSAKey_t key)
24040 +{
24041 + t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec;
24042 + t_Error err = E_OK;
24043 + uint32_t tmpReg = 0, intFlags;
24044 +
24045 + SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE);
24046 + SANITY_CHECK_RETURN_ERROR(scId < NUM_OF_RX_SC, E_INVALID_HANDLE);
24047 + SANITY_CHECK_RETURN_ERROR(saId < NUM_OF_SA_PER_RX_SC, E_INVALID_HANDLE);
24048 +
24049 + intFlags = XX_LockIntrSpinlock(p_FmMacsec->rxScSpinLock);
24050 +
24051 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->rxsca, scId);
24052 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->fmMacsecRxScSa[saId].rxsanpn, DEFAULT_initNextPn);
24053 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->fmMacsecRxScSa[saId].rxsalpn, lowestPn);
24054 + MemCpy8((void*)p_FmMacsec->p_FmMacsecRegs->fmMacsecRxScSa[saId].rxsak, key, sizeof(macsecSAKey_t));
24055 +
24056 + tmpReg |= RX_SACFG_ACTIVE;
24057 + tmpReg |= ((an << RX_SACFG_AN_SHIFT) & RX_SACFG_AN_MASK);
24058 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->fmMacsecRxScSa[saId].rxsacs, tmpReg);
24059 +
24060 + XX_UnlockIntrSpinlock(p_FmMacsec->rxScSpinLock, intFlags);
24061 +
24062 + return err;
24063 +}
24064 +
24065 +t_Error FmMacsecCreateTxSa(t_Handle h_FmMacsec, uint32_t scId, e_ScSaId saId, macsecSAKey_t key)
24066 +{
24067 + t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec;
24068 + t_Error err = E_OK;
24069 + uint32_t tmpReg = 0, intFlags;
24070 +
24071 + SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE);
24072 + SANITY_CHECK_RETURN_ERROR(scId < NUM_OF_RX_SC, E_INVALID_HANDLE);
24073 + SANITY_CHECK_RETURN_ERROR(saId < NUM_OF_SA_PER_TX_SC, E_INVALID_HANDLE);
24074 +
24075 + intFlags = XX_LockIntrSpinlock(p_FmMacsec->txScSpinLock);
24076 +
24077 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->txsca, scId);
24078 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->fmMacsecTxScSa[saId].txsanpn, DEFAULT_initNextPn);
24079 + MemCpy8((void*)p_FmMacsec->p_FmMacsecRegs->fmMacsecTxScSa[saId].txsak, key, sizeof(macsecSAKey_t));
24080 +
24081 + tmpReg |= TX_SACFG_ACTIVE;
24082 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->fmMacsecTxScSa[saId].txsacs, tmpReg);
24083 +
24084 + XX_UnlockIntrSpinlock(p_FmMacsec->txScSpinLock, intFlags);
24085 +
24086 + return err;
24087 +}
24088 +
24089 +t_Error FmMacsecDeleteRxSa(t_Handle h_FmMacsec, uint32_t scId, e_ScSaId saId)
24090 +{
24091 + t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec;
24092 + t_Error err = E_OK;
24093 + uint32_t tmpReg = 0, i, intFlags;
24094 +
24095 + SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE);
24096 + SANITY_CHECK_RETURN_ERROR(scId < NUM_OF_RX_SC, E_INVALID_HANDLE);
24097 + SANITY_CHECK_RETURN_ERROR(saId < NUM_OF_SA_PER_RX_SC, E_INVALID_HANDLE);
24098 +
24099 + intFlags = XX_LockIntrSpinlock(p_FmMacsec->rxScSpinLock);
24100 +
24101 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->rxsca, scId);
24102 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->fmMacsecRxScSa[saId].rxsanpn, 0x0);
24103 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->fmMacsecRxScSa[saId].rxsalpn, 0x0);
24104 + for (i=0; i<4; i++)
24105 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->fmMacsecRxScSa[saId].rxsak[i], 0x0);
24106 +
24107 + tmpReg |= RX_SACFG_ACTIVE;
24108 + tmpReg &= ~RX_SACFG_EN_MASK;
24109 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->fmMacsecRxScSa[saId].rxsacs, tmpReg);
24110 +
24111 + XX_UnlockIntrSpinlock(p_FmMacsec->rxScSpinLock, intFlags);
24112 +
24113 + return err;
24114 +}
24115 +
24116 +t_Error FmMacsecDeleteTxSa(t_Handle h_FmMacsec, uint32_t scId, e_ScSaId saId)
24117 +{
24118 + t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec;
24119 + t_Error err = E_OK;
24120 + uint32_t tmpReg = 0, i, intFlags;
24121 +
24122 + SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE);
24123 + SANITY_CHECK_RETURN_ERROR(scId < NUM_OF_RX_SC, E_INVALID_HANDLE);
24124 + SANITY_CHECK_RETURN_ERROR(saId < NUM_OF_SA_PER_TX_SC, E_INVALID_HANDLE);
24125 +
24126 + intFlags = XX_LockIntrSpinlock(p_FmMacsec->txScSpinLock);
24127 +
24128 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->txsca, scId);
24129 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->fmMacsecTxScSa[saId].txsanpn, 0x0);
24130 + for (i=0; i<4; i++)
24131 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->fmMacsecTxScSa[saId].txsak[i], 0x0);
24132 +
24133 + tmpReg |= TX_SACFG_ACTIVE;
24134 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->fmMacsecTxScSa[saId].txsacs, tmpReg);
24135 +
24136 + XX_UnlockIntrSpinlock(p_FmMacsec->txScSpinLock, intFlags);
24137 +
24138 + return err;
24139 +}
24140 +
24141 +t_Error FmMacsecRxSaSetReceive(t_Handle h_FmMacsec, uint32_t scId, e_ScSaId saId, bool enableReceive)
24142 +{
24143 + t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec;
24144 + t_Error err = E_OK;
24145 + uint32_t tmpReg = 0, intFlags;
24146 +
24147 + SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE);
24148 + SANITY_CHECK_RETURN_ERROR(scId < NUM_OF_RX_SC, E_INVALID_HANDLE);
24149 + SANITY_CHECK_RETURN_ERROR(saId < NUM_OF_SA_PER_RX_SC, E_INVALID_HANDLE);
24150 +
24151 + intFlags = XX_LockIntrSpinlock(p_FmMacsec->rxScSpinLock);
24152 +
24153 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->rxsca, scId);
24154 + tmpReg = GET_UINT32(p_FmMacsec->p_FmMacsecRegs->fmMacsecRxScSa[saId].rxsacs);
24155 + if (enableReceive)
24156 + tmpReg |= RX_SACFG_EN_MASK;
24157 + else
24158 + tmpReg &= ~RX_SACFG_EN_MASK;
24159 +
24160 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->fmMacsecRxScSa[saId].rxsacs, tmpReg);
24161 +
24162 + XX_UnlockIntrSpinlock(p_FmMacsec->rxScSpinLock, intFlags);
24163 +
24164 + return err;
24165 +}
24166 +
24167 +t_Error FmMacsecRxSaUpdateNextPn(t_Handle h_FmMacsec, uint32_t scId, e_ScSaId saId, uint32_t updtNextPN)
24168 +{
24169 + t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec;
24170 + t_Error err = E_OK;
24171 + uint32_t intFlags;
24172 +
24173 + SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE);
24174 + SANITY_CHECK_RETURN_ERROR(scId < NUM_OF_RX_SC, E_INVALID_HANDLE);
24175 + SANITY_CHECK_RETURN_ERROR(saId < NUM_OF_SA_PER_RX_SC, E_INVALID_HANDLE);
24176 +
24177 + intFlags = XX_LockIntrSpinlock(p_FmMacsec->rxScSpinLock);
24178 +
24179 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->rxsca, scId);
24180 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->fmMacsecRxScSa[saId].rxsanpn, updtNextPN);
24181 +
24182 + XX_UnlockIntrSpinlock(p_FmMacsec->rxScSpinLock, intFlags);
24183 +
24184 + return err;
24185 +}
24186 +
24187 +t_Error FmMacsecRxSaUpdateLowestPn(t_Handle h_FmMacsec, uint32_t scId, e_ScSaId saId, uint32_t updtLowestPN)
24188 +{
24189 + t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec;
24190 + t_Error err = E_OK;
24191 + uint32_t intFlags;
24192 +
24193 + SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE);
24194 + SANITY_CHECK_RETURN_ERROR(scId < NUM_OF_RX_SC, E_INVALID_HANDLE);
24195 + SANITY_CHECK_RETURN_ERROR(saId < NUM_OF_SA_PER_RX_SC, E_INVALID_HANDLE);
24196 +
24197 + intFlags = XX_LockIntrSpinlock(p_FmMacsec->rxScSpinLock);
24198 +
24199 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->rxsca, scId);
24200 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->fmMacsecRxScSa[saId].rxsalpn, updtLowestPN);
24201 +
24202 + XX_UnlockIntrSpinlock(p_FmMacsec->rxScSpinLock, intFlags);
24203 +
24204 + return err;
24205 +}
24206 +
24207 +t_Error FmMacsecTxSaSetActive(t_Handle h_FmMacsec, uint32_t scId, e_ScSaId saId, macsecAN_t an)
24208 +{
24209 + t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec;
24210 + t_Error err = E_OK;
24211 + uint32_t tmpReg = 0, intFlags;
24212 +
24213 + SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE);
24214 + SANITY_CHECK_RETURN_ERROR(scId < NUM_OF_RX_SC, E_INVALID_HANDLE);
24215 + SANITY_CHECK_RETURN_ERROR(saId < NUM_OF_SA_PER_TX_SC, E_INVALID_HANDLE);
24216 +
24217 + intFlags = XX_LockIntrSpinlock(p_FmMacsec->txScSpinLock);
24218 +
24219 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->txsca, scId);
24220 +
24221 + tmpReg = GET_UINT32(p_FmMacsec->p_FmMacsecRegs->txsccfg);
24222 +
24223 + tmpReg |= ((an << TX_SCCFG_AN_SHIFT) & TX_SCCFG_AN_MASK);
24224 + tmpReg |= ((saId << TX_SCCFG_ASA_SHIFT) & TX_SCCFG_ASA_MASK);
24225 +
24226 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->txsccfg, tmpReg);
24227 +
24228 + XX_UnlockIntrSpinlock(p_FmMacsec->txScSpinLock, intFlags);
24229 +
24230 + return err;
24231 +}
24232 +
24233 +t_Error FmMacsecTxSaGetActive(t_Handle h_FmMacsec, uint32_t scId, macsecAN_t *p_An)
24234 +{
24235 + t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec;
24236 + t_Error err = E_OK;
24237 + uint32_t tmpReg = 0, intFlags;
24238 +
24239 + SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE);
24240 + SANITY_CHECK_RETURN_ERROR(scId < NUM_OF_RX_SC, E_INVALID_HANDLE);
24241 + SANITY_CHECK_RETURN_ERROR(p_An, E_INVALID_HANDLE);
24242 +
24243 + intFlags = XX_LockIntrSpinlock(p_FmMacsec->txScSpinLock);
24244 +
24245 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->txsca, scId);
24246 +
24247 + tmpReg = GET_UINT32(p_FmMacsec->p_FmMacsecRegs->txsccfg);
24248 +
24249 + XX_UnlockIntrSpinlock(p_FmMacsec->txScSpinLock, intFlags);
24250 +
24251 + *p_An = (macsecAN_t)((tmpReg & TX_SCCFG_AN_MASK) >> TX_SCCFG_AN_SHIFT);
24252 +
24253 + return err;
24254 +}
24255 +
24256 +t_Error FmMacsecSetException(t_Handle h_FmMacsec, e_FmMacsecGlobalExceptions exception, uint32_t scId, bool enable)
24257 +{
24258 + t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec;
24259 + uint32_t bitMask;
24260 +
24261 + SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE);
24262 + SANITY_CHECK_RETURN_ERROR(!p_FmMacsec->p_FmMacsecDriverParam, E_INVALID_HANDLE);
24263 +
24264 + GET_EXCEPTION_FLAG(bitMask, exception, scId);
24265 + if (bitMask)
24266 + {
24267 + if (enable)
24268 + p_FmMacsec->exceptions |= bitMask;
24269 + else
24270 + p_FmMacsec->exceptions &= ~bitMask;
24271 + }
24272 + else
24273 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Undefined exception"));
24274 +
24275 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->erer, p_FmMacsec->exceptions);
24276 +
24277 + return E_OK;
24278 +}
24279 +
24280 +t_Error FmMacsecSetEvent(t_Handle h_FmMacsec, e_FmMacsecGlobalEvents event, uint32_t scId, bool enable)
24281 +{
24282 + t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec;
24283 + uint32_t bitMask;
24284 +
24285 + SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE);
24286 + SANITY_CHECK_RETURN_ERROR(!p_FmMacsec->p_FmMacsecDriverParam, E_INVALID_HANDLE);
24287 +
24288 + GET_EVENT_FLAG(bitMask, event, scId);
24289 + if (bitMask)
24290 + {
24291 + if (enable)
24292 + p_FmMacsec->events |= bitMask;
24293 + else
24294 + p_FmMacsec->events &= ~bitMask;
24295 + }
24296 + else
24297 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Undefined event"));
24298 +
24299 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->ever, p_FmMacsec->events);
24300 +
24301 + return E_OK;
24302 +}
24303 +
24304 +/****************************************/
24305 +/* API Init unit functions */
24306 +/****************************************/
24307 +t_Handle FM_MACSEC_MASTER_Config(t_FmMacsecParams *p_FmMacsecParam)
24308 +{
24309 + t_FmMacsec *p_FmMacsec;
24310 + uint32_t macId;
24311 +
24312 + /* Allocate FM MACSEC structure */
24313 + p_FmMacsec = (t_FmMacsec *) XX_Malloc(sizeof(t_FmMacsec));
24314 + if (!p_FmMacsec)
24315 + {
24316 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FM MACSEC driver structure"));
24317 + return NULL;
24318 + }
24319 + memset(p_FmMacsec, 0, sizeof(t_FmMacsec));
24320 + InitFmMacsecControllerDriver(&p_FmMacsec->fmMacsecControllerDriver);
24321 +
24322 + /* Allocate the FM MACSEC driver's parameters structure */
24323 + p_FmMacsec->p_FmMacsecDriverParam = (t_FmMacsecDriverParam *)XX_Malloc(sizeof(t_FmMacsecDriverParam));
24324 + if (!p_FmMacsec->p_FmMacsecDriverParam)
24325 + {
24326 + XX_Free(p_FmMacsec);
24327 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FM MACSEC driver parameters"));
24328 + return NULL;
24329 + }
24330 + memset(p_FmMacsec->p_FmMacsecDriverParam, 0, sizeof(t_FmMacsecDriverParam));
24331 +
24332 + /* Initialize FM MACSEC parameters which will be kept by the driver */
24333 + p_FmMacsec->h_Fm = p_FmMacsecParam->h_Fm;
24334 + p_FmMacsec->h_FmMac = p_FmMacsecParam->nonGuestParams.h_FmMac;
24335 + p_FmMacsec->p_FmMacsecRegs = (t_FmMacsecRegs *)UINT_TO_PTR(p_FmMacsecParam->nonGuestParams.baseAddr);
24336 + p_FmMacsec->f_Exception = p_FmMacsecParam->nonGuestParams.f_Exception;
24337 + p_FmMacsec->h_App = p_FmMacsecParam->nonGuestParams.h_App;
24338 + p_FmMacsec->userExceptions = DEFAULT_userExceptions;
24339 + p_FmMacsec->exceptions = DEFAULT_exceptions;
24340 + p_FmMacsec->events = DEFAULT_events;
24341 + p_FmMacsec->rxScSpinLock = XX_InitSpinlock();
24342 + p_FmMacsec->txScSpinLock = XX_InitSpinlock();
24343 +
24344 + /* Initialize FM MACSEC driver parameters parameters (for initialization phase only) */
24345 + p_FmMacsec->p_FmMacsecDriverParam->unknownSciTreatMode = DEFAULT_unknownSciFrameTreatment;
24346 + p_FmMacsec->p_FmMacsecDriverParam->invalidTagsDeliverUncontrolled = DEFAULT_invalidTagsFrameTreatment;
24347 + p_FmMacsec->p_FmMacsecDriverParam->encryptWithNoChangedTextDiscardUncontrolled = DEFAULT_encryptWithNoChangedTextFrameTreatment;
24348 + p_FmMacsec->p_FmMacsecDriverParam->untagTreatMode = DEFAULT_untagFrameTreatment;
24349 + p_FmMacsec->p_FmMacsecDriverParam->keysUnreadable = DEFAULT_keysUnreadable;
24350 + p_FmMacsec->p_FmMacsecDriverParam->reservedSc0 = DEFAULT_sc0ReservedForPTP;
24351 + p_FmMacsec->p_FmMacsecDriverParam->byPassMode = !DEFAULT_normalMode;
24352 + p_FmMacsec->p_FmMacsecDriverParam->pnExhThr = DEFAULT_pnExhThr;
24353 + p_FmMacsec->p_FmMacsecDriverParam->sectagOverhead = DEFAULT_sectagOverhead;
24354 + p_FmMacsec->p_FmMacsecDriverParam->mflSubtract = DEFAULT_mflSubtract;
24355 + /* build the FM MACSEC master IPC address */
24356 + memset(p_FmMacsec->fmMacsecModuleName, 0, (sizeof(char))*MODULE_NAME_SIZE);
24357 + FM_MAC_GetId(p_FmMacsec->h_FmMac,&macId);
24358 + if (Sprint (p_FmMacsec->fmMacsecModuleName, "FM-%d-MAC-%d-MACSEC-Master",
24359 + FmGetId(p_FmMacsec->h_Fm),macId) != 24)
24360 + {
24361 + XX_Free(p_FmMacsec->p_FmMacsecDriverParam);
24362 + XX_Free(p_FmMacsec);
24363 + REPORT_ERROR(MAJOR, E_INVALID_STATE, ("Sprint failed"));
24364 + return NULL;
24365 + }
24366 + return p_FmMacsec;
24367 +}
24368 --- /dev/null
24369 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MACSEC/fm_macsec_master.h
24370 @@ -0,0 +1,479 @@
24371 +/*
24372 + * Copyright 2008-2015 Freescale Semiconductor Inc.
24373 + *
24374 + * Redistribution and use in source and binary forms, with or without
24375 + * modification, are permitted provided that the following conditions are met:
24376 + * * Redistributions of source code must retain the above copyright
24377 + * notice, this list of conditions and the following disclaimer.
24378 + * * Redistributions in binary form must reproduce the above copyright
24379 + * notice, this list of conditions and the following disclaimer in the
24380 + * documentation and/or other materials provided with the distribution.
24381 + * * Neither the name of Freescale Semiconductor nor the
24382 + * names of its contributors may be used to endorse or promote products
24383 + * derived from this software without specific prior written permission.
24384 + *
24385 + *
24386 + * ALTERNATIVELY, this software may be distributed under the terms of the
24387 + * GNU General Public License ("GPL") as published by the Free Software
24388 + * Foundation, either version 2 of that License or (at your option) any
24389 + * later version.
24390 + *
24391 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
24392 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
24393 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
24394 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
24395 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
24396 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
24397 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
24398 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24399 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
24400 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24401 + */
24402 +
24403 +/******************************************************************************
24404 + @File fm_macsec_master.h
24405 +
24406 + @Description FM MACSEC internal structures and definitions.
24407 +*//***************************************************************************/
24408 +#ifndef __FM_MACSEC_MASTER_H
24409 +#define __FM_MACSEC_MASTER_H
24410 +
24411 +#include "error_ext.h"
24412 +#include "std_ext.h"
24413 +
24414 +#include "fm_macsec.h"
24415 +
24416 +
24417 +#define MACSEC_ICV_SIZE 16
24418 +#define MACSEC_SECTAG_SIZE 16
24419 +#define MACSEC_SCI_SIZE 8
24420 +#define MACSEC_FCS_SIZE 4
24421 +
24422 +/**************************************************************************//**
24423 + @Description Exceptions
24424 +*//***************************************************************************/
24425 +
24426 +#define FM_MACSEC_EX_TX_SC_0 0x80000000
24427 +#define FM_MACSEC_EX_TX_SC(sc) (FM_MACSEC_EX_TX_SC_0 >> (sc))
24428 +#define FM_MACSEC_EX_ECC 0x00000001
24429 +
24430 +#define GET_EXCEPTION_FLAG(bitMask, exception, id) switch (exception){ \
24431 + case e_FM_MACSEC_EX_TX_SC: \
24432 + bitMask = FM_MACSEC_EX_TX_SC(id); break; \
24433 + case e_FM_MACSEC_EX_ECC: \
24434 + bitMask = FM_MACSEC_EX_ECC; break; \
24435 + default: bitMask = 0;break;}
24436 +
24437 +#define FM_MACSEC_USER_EX_SINGLE_BIT_ECC 0x80000000
24438 +#define FM_MACSEC_USER_EX_MULTI_BIT_ECC 0x40000000
24439 +
24440 +#define GET_USER_EXCEPTION_FLAG(bitMask, exception) switch (exception){ \
24441 + case e_FM_MACSEC_EX_SINGLE_BIT_ECC: \
24442 + bitMask = FM_MACSEC_USER_EX_SINGLE_BIT_ECC; break; \
24443 + case e_FM_MACSEC_EX_MULTI_BIT_ECC: \
24444 + bitMask = FM_MACSEC_USER_EX_MULTI_BIT_ECC; break; \
24445 + default: bitMask = 0;break;}
24446 +
24447 +/**************************************************************************//**
24448 + @Description Events
24449 +*//***************************************************************************/
24450 +
24451 +#define FM_MACSEC_EV_TX_SC_0_NEXT_PN 0x80000000
24452 +#define FM_MACSEC_EV_TX_SC_NEXT_PN(sc) (FM_MACSEC_EV_TX_SC_0_NEXT_PN >> (sc))
24453 +
24454 +#define GET_EVENT_FLAG(bitMask, event, id) switch (event){ \
24455 + case e_FM_MACSEC_EV_TX_SC_NEXT_PN: \
24456 + bitMask = FM_MACSEC_EV_TX_SC_NEXT_PN(id); break; \
24457 + default: bitMask = 0;break;}
24458 +
24459 +/**************************************************************************//**
24460 + @Description Defaults
24461 +*//***************************************************************************/
24462 +#define DEFAULT_userExceptions (FM_MACSEC_USER_EX_SINGLE_BIT_ECC |\
24463 + FM_MACSEC_USER_EX_MULTI_BIT_ECC)
24464 +
24465 +#define DEFAULT_exceptions (FM_MACSEC_EX_TX_SC(0) |\
24466 + FM_MACSEC_EX_TX_SC(1) |\
24467 + FM_MACSEC_EX_TX_SC(2) |\
24468 + FM_MACSEC_EX_TX_SC(3) |\
24469 + FM_MACSEC_EX_TX_SC(4) |\
24470 + FM_MACSEC_EX_TX_SC(5) |\
24471 + FM_MACSEC_EX_TX_SC(6) |\
24472 + FM_MACSEC_EX_TX_SC(7) |\
24473 + FM_MACSEC_EX_TX_SC(8) |\
24474 + FM_MACSEC_EX_TX_SC(9) |\
24475 + FM_MACSEC_EX_TX_SC(10) |\
24476 + FM_MACSEC_EX_TX_SC(11) |\
24477 + FM_MACSEC_EX_TX_SC(12) |\
24478 + FM_MACSEC_EX_TX_SC(13) |\
24479 + FM_MACSEC_EX_TX_SC(14) |\
24480 + FM_MACSEC_EX_TX_SC(15) |\
24481 + FM_MACSEC_EX_ECC )
24482 +
24483 +#define DEFAULT_events (FM_MACSEC_EV_TX_SC_NEXT_PN(0) |\
24484 + FM_MACSEC_EV_TX_SC_NEXT_PN(1) |\
24485 + FM_MACSEC_EV_TX_SC_NEXT_PN(2) |\
24486 + FM_MACSEC_EV_TX_SC_NEXT_PN(3) |\
24487 + FM_MACSEC_EV_TX_SC_NEXT_PN(4) |\
24488 + FM_MACSEC_EV_TX_SC_NEXT_PN(5) |\
24489 + FM_MACSEC_EV_TX_SC_NEXT_PN(6) |\
24490 + FM_MACSEC_EV_TX_SC_NEXT_PN(7) |\
24491 + FM_MACSEC_EV_TX_SC_NEXT_PN(8) |\
24492 + FM_MACSEC_EV_TX_SC_NEXT_PN(9) |\
24493 + FM_MACSEC_EV_TX_SC_NEXT_PN(10) |\
24494 + FM_MACSEC_EV_TX_SC_NEXT_PN(11) |\
24495 + FM_MACSEC_EV_TX_SC_NEXT_PN(12) |\
24496 + FM_MACSEC_EV_TX_SC_NEXT_PN(13) |\
24497 + FM_MACSEC_EV_TX_SC_NEXT_PN(14) |\
24498 + FM_MACSEC_EV_TX_SC_NEXT_PN(15) )
24499 +
24500 +#define DEFAULT_unknownSciFrameTreatment e_FM_MACSEC_UNKNOWN_SCI_FRAME_TREATMENT_DISCARD_BOTH
24501 +#define DEFAULT_invalidTagsFrameTreatment FALSE
24502 +#define DEFAULT_encryptWithNoChangedTextFrameTreatment FALSE
24503 +#define DEFAULT_untagFrameTreatment e_FM_MACSEC_UNTAG_FRAME_TREATMENT_DELIVER_UNCONTROLLED_DISCARD_CONTROLLED
24504 +#define DEFAULT_changedTextWithNoEncryptFrameTreatment FALSE
24505 +#define DEFAULT_onlyScbIsSetFrameTreatment FALSE
24506 +#define DEFAULT_keysUnreadable FALSE
24507 +#define DEFAULT_normalMode TRUE
24508 +#define DEFAULT_sc0ReservedForPTP FALSE
24509 +#define DEFAULT_initNextPn 1
24510 +#define DEFAULT_pnExhThr 0xffffffff
24511 +#define DEFAULT_sectagOverhead (MACSEC_ICV_SIZE + MACSEC_SECTAG_SIZE)
24512 +#define DEFAULT_mflSubtract MACSEC_FCS_SIZE
24513 +
24514 +
24515 +/**************************************************************************//**
24516 + @Description Memory Mapped Registers
24517 +*//***************************************************************************/
24518 +
24519 +#if defined(__MWERKS__) && !defined(__GNUC__)
24520 +#pragma pack(push,1)
24521 +#endif /* defined(__MWERKS__) && ... */
24522 +
24523 +typedef _Packed struct
24524 +{
24525 + /* MACsec configuration */
24526 + volatile uint32_t cfg; /**< MACsec configuration */
24527 + volatile uint32_t et; /**< MACsec EtherType */
24528 + volatile uint8_t res1[56]; /**< reserved */
24529 + volatile uint32_t mfl; /**< Maximum Frame Length */
24530 + volatile uint32_t tpnet; /**< TX Packet Number exhaustion threshold */
24531 + volatile uint8_t res2[56]; /**< reserved */
24532 + volatile uint32_t rxsca; /**< RX SC access select */
24533 + volatile uint8_t res3[60]; /**< reserved */
24534 + volatile uint32_t txsca; /**< TX SC access select */
24535 + volatile uint8_t res4[60]; /**< reserved */
24536 +
24537 + /* RX configuration, status and statistic */
24538 + volatile uint32_t rxsci1h; /**< RX Secure Channel Identifier first half */
24539 + volatile uint32_t rxsci2h; /**< RX Secure Channel Identifier second half */
24540 + volatile uint8_t res5[8]; /**< reserved */
24541 + volatile uint32_t ifio1hs; /**< ifInOctets first half Statistic */
24542 + volatile uint32_t ifio2hs; /**< ifInOctets second half Statistic */
24543 + volatile uint32_t ifiups; /**< ifInUcastPkts Statistic */
24544 + volatile uint8_t res6[4]; /**< reserved */
24545 + volatile uint32_t ifimps; /**< ifInMulticastPkts Statistic */
24546 + volatile uint32_t ifibps; /**< ifInBroadcastPkts Statistic */
24547 + volatile uint32_t rxsccfg; /**< RX Secure Channel configuration */
24548 + volatile uint32_t rpw; /**< replayWindow */
24549 + volatile uint8_t res7[16]; /**< reserved */
24550 + volatile uint32_t inov1hs; /**< InOctetsValidated first half Statistic */
24551 + volatile uint32_t inov2hs; /**< InOctetsValidated second half Statistic */
24552 + volatile uint32_t inod1hs; /**< InOctetsDecrypted first half Statistic */
24553 + volatile uint32_t inod2hs; /**< InOctetsDecrypted second half Statistic */
24554 + volatile uint32_t rxscipus; /**< RX Secure Channel InPktsUnchecked Statistic */
24555 + volatile uint32_t rxscipds; /**< RX Secure Channel InPktsDelayed Statistic */
24556 + volatile uint32_t rxscipls; /**< RX Secure Channel InPktsLate Statistic */
24557 + volatile uint8_t res8[4]; /**< reserved */
24558 + volatile uint32_t rxaninuss[MAX_NUM_OF_SA_PER_SC]; /**< RX AN 0-3 InNotUsingSA Statistic */
24559 + volatile uint32_t rxanipuss[MAX_NUM_OF_SA_PER_SC]; /**< RX AN 0-3 InPktsUnusedSA Statistic */
24560 + _Packed struct
24561 + {
24562 + volatile uint32_t rxsacs; /**< RX Security Association configuration and status */
24563 + volatile uint32_t rxsanpn; /**< RX Security Association nextPN */
24564 + volatile uint32_t rxsalpn; /**< RX Security Association lowestPN */
24565 + volatile uint32_t rxsaipos; /**< RX Security Association InPktsOK Statistic */
24566 + volatile uint32_t rxsak[4]; /**< RX Security Association key (128 bit) */
24567 + volatile uint32_t rxsah[4]; /**< RX Security Association hash (128 bit) */
24568 + volatile uint32_t rxsaipis; /**< RX Security Association InPktsInvalid Statistic */
24569 + volatile uint32_t rxsaipnvs; /**< RX Security Association InPktsNotValid Statistic */
24570 + volatile uint8_t res9[8]; /**< reserved */
24571 + } _PackedType fmMacsecRxScSa[NUM_OF_SA_PER_RX_SC];
24572 +
24573 + /* TX configuration, status and statistic */
24574 + volatile uint32_t txsci1h; /**< TX Secure Channel Identifier first half */
24575 + volatile uint32_t txsci2h; /**< TX Secure Channel Identifier second half */
24576 + volatile uint8_t res10[8]; /**< reserved */
24577 + volatile uint32_t ifoo1hs; /**< ifOutOctets first half Statistic */
24578 + volatile uint32_t ifoo2hs; /**< ifOutOctets second half Statistic */
24579 + volatile uint32_t ifoups; /**< ifOutUcastPkts Statistic */
24580 + volatile uint32_t opus; /**< OutPktsUntagged Statistic */
24581 + volatile uint32_t ifomps; /**< ifOutMulticastPkts Statistic */
24582 + volatile uint32_t ifobps; /**< ifOutBroadcastPkts Statistic */
24583 + volatile uint32_t txsccfg; /**< TX Secure Channel configuration */
24584 + volatile uint32_t optls; /**< OutPktsTooLong Statistic */
24585 + volatile uint8_t res11[16]; /**< reserved */
24586 + volatile uint32_t oop1hs; /**< OutOctetsProtected first half Statistic */
24587 + volatile uint32_t oop2hs; /**< OutOctetsProtected second half Statistic */
24588 + volatile uint32_t ooe1hs; /**< OutOctetsEncrypted first half Statistic */
24589 + volatile uint32_t ooe2hs; /**< OutOctetsEncrypted second half Statistic */
24590 + volatile uint8_t res12[48]; /**< reserved */
24591 + _Packed struct
24592 + {
24593 + volatile uint32_t txsacs; /**< TX Security Association configuration and status */
24594 + volatile uint32_t txsanpn; /**< TX Security Association nextPN */
24595 + volatile uint32_t txsaopps; /**< TX Security Association OutPktsProtected Statistic */
24596 + volatile uint32_t txsaopes; /**< TX Security Association OutPktsEncrypted Statistic */
24597 + volatile uint32_t txsak[4]; /**< TX Security Association key (128 bit) */
24598 + volatile uint32_t txsah[4]; /**< TX Security Association hash (128 bit) */
24599 + volatile uint8_t res13[16]; /**< reserved */
24600 + } _PackedType fmMacsecTxScSa[NUM_OF_SA_PER_TX_SC];
24601 + volatile uint8_t res14[248]; /**< reserved */
24602 +
24603 + /* Global configuration and status */
24604 + volatile uint32_t ip_rev1; /**< MACsec IP Block Revision 1 register */
24605 + volatile uint32_t ip_rev2; /**< MACsec IP Block Revision 2 register */
24606 + volatile uint32_t evr; /**< MACsec Event Register */
24607 + volatile uint32_t ever; /**< MACsec Event Enable Register */
24608 + volatile uint32_t evfr; /**< MACsec Event Force Register */
24609 + volatile uint32_t err; /**< MACsec Error Register */
24610 + volatile uint32_t erer; /**< MACsec Error Enable Register */
24611 + volatile uint32_t erfr; /**< MACsec Error Force Register */
24612 + volatile uint8_t res15[40]; /**< reserved */
24613 + volatile uint32_t meec; /**< MACsec Memory ECC Error Capture Register */
24614 + volatile uint32_t idle; /**< MACsec Idle status Register */
24615 + volatile uint8_t res16[184]; /**< reserved */
24616 + /* DEBUG */
24617 + volatile uint32_t rxec; /**< MACsec RX error capture Register */
24618 + volatile uint8_t res17[28]; /**< reserved */
24619 + volatile uint32_t txec; /**< MACsec TX error capture Register */
24620 + volatile uint8_t res18[220]; /**< reserved */
24621 +
24622 + /* Macsec Rx global statistic */
24623 + volatile uint32_t ifiocp1hs; /**< ifInOctetsCp first half Statistic */
24624 + volatile uint32_t ifiocp2hs; /**< ifInOctetsCp second half Statistic */
24625 + volatile uint32_t ifiupcps; /**< ifInUcastPktsCp Statistic */
24626 + volatile uint8_t res19[4]; /**< reserved */
24627 + volatile uint32_t ifioup1hs; /**< ifInOctetsUp first half Statistic */
24628 + volatile uint32_t ifioup2hs; /**< ifInOctetsUp second half Statistic */
24629 + volatile uint32_t ifiupups; /**< ifInUcastPktsUp Statistic */
24630 + volatile uint8_t res20[4]; /**< reserved */
24631 + volatile uint32_t ifimpcps; /**< ifInMulticastPktsCp Statistic */
24632 + volatile uint32_t ifibpcps; /**< ifInBroadcastPktsCp Statistic */
24633 + volatile uint32_t ifimpups; /**< ifInMulticastPktsUp Statistic */
24634 + volatile uint32_t ifibpups; /**< ifInBroadcastPktsUp Statistic */
24635 + volatile uint32_t ipwts; /**< InPktsWithoutTag Statistic */
24636 + volatile uint32_t ipkays; /**< InPktsKaY Statistic */
24637 + volatile uint32_t ipbts; /**< InPktsBadTag Statistic */
24638 + volatile uint32_t ipsnfs; /**< InPktsSCINotFound Statistic */
24639 + volatile uint32_t ipuecs; /**< InPktsUnsupportedEC Statistic */
24640 + volatile uint32_t ipescbs; /**< InPktsEponSingleCopyBroadcast Statistic */
24641 + volatile uint32_t iptls; /**< InPktsTooLong Statistic */
24642 + volatile uint8_t res21[52]; /**< reserved */
24643 +
24644 + /* Macsec Tx global statistic */
24645 + volatile uint32_t opds; /**< OutPktsDiscarded Statistic */
24646 +#if (DPAA_VERSION >= 11)
24647 + volatile uint8_t res22[124]; /**< reserved */
24648 + _Packed struct
24649 + {
24650 + volatile uint32_t rxsak[8]; /**< RX Security Association key (128/256 bit) */
24651 + volatile uint8_t res23[32]; /**< reserved */
24652 + } _PackedType rxScSaKey[NUM_OF_SA_PER_RX_SC];
24653 + _Packed struct
24654 + {
24655 + volatile uint32_t txsak[8]; /**< TX Security Association key (128/256 bit) */
24656 + volatile uint8_t res24[32]; /**< reserved */
24657 + } _PackedType txScSaKey[NUM_OF_SA_PER_TX_SC];
24658 +#endif /* (DPAA_VERSION >= 11) */
24659 +} _PackedType t_FmMacsecRegs;
24660 +
24661 +#if defined(__MWERKS__) && !defined(__GNUC__)
24662 +#pragma pack(pop)
24663 +#endif /* defined(__MWERKS__) && ... */
24664 +
24665 +
24666 +/**************************************************************************//**
24667 + @Description General defines
24668 +*//***************************************************************************/
24669 +
24670 +#define SCI_HIGH_MASK 0xffffffff00000000LL
24671 +#define SCI_LOW_MASK 0x00000000ffffffffLL
24672 +
24673 +#define LONG_SHIFT 32
24674 +
24675 +#define GET_SCI_FIRST_HALF(sci) (uint32_t)((macsecSCI_t)((macsecSCI_t)(sci) & SCI_HIGH_MASK) >> LONG_SHIFT)
24676 +#define GET_SCI_SECOND_HALF(sci) (uint32_t)((macsecSCI_t)(sci) & SCI_LOW_MASK)
24677 +
24678 +/**************************************************************************//**
24679 + @Description Configuration defines
24680 +*//***************************************************************************/
24681 +
24682 +/* masks */
24683 +#define CFG_UECT 0x00000800
24684 +#define CFG_ESCBT 0x00000400
24685 +#define CFG_USFT 0x00000300
24686 +#define CFG_ITT 0x00000080
24687 +#define CFG_KFT 0x00000040
24688 +#define CFG_UFT 0x00000030
24689 +#define CFG_KSS 0x00000004
24690 +#define CFG_BYPN 0x00000002
24691 +#define CFG_S0I 0x00000001
24692 +
24693 +#define ET_TYPE 0x0000ffff
24694 +
24695 +#define MFL_MAX_LEN 0x0000ffff
24696 +
24697 +#define RXSCA_SC_SEL 0x0000000f
24698 +
24699 +#define TXSCA_SC_SEL 0x0000000f
24700 +
24701 +#define IP_REV_1_IP_ID 0xffff0000
24702 +#define IP_REV_1_IP_MJ 0x0000ff00
24703 +#define IP_REV_1_IP_MM 0x000000ff
24704 +
24705 +#define IP_REV_2_IP_INT 0x00ff0000
24706 +#define IP_REV_2_IP_ERR 0x0000ff00
24707 +#define IP_REV_2_IP_CFG 0x000000ff
24708 +
24709 +#define MECC_CAP 0x80000000
24710 +#define MECC_CET 0x40000000
24711 +#define MECC_SERCNT 0x00ff0000
24712 +#define MECC_MEMADDR 0x000001ff
24713 +
24714 +/* shifts */
24715 +#define CFG_UECT_SHIFT (31-20)
24716 +#define CFG_ESCBT_SHIFT (31-21)
24717 +#define CFG_USFT_SHIFT (31-23)
24718 +#define CFG_ITT_SHIFT (31-24)
24719 +#define CFG_KFT_SHIFT (31-25)
24720 +#define CFG_UFT_SHIFT (31-27)
24721 +#define CFG_KSS_SHIFT (31-29)
24722 +#define CFG_BYPN_SHIFT (31-30)
24723 +#define CFG_S0I_SHIFT (31-31)
24724 +
24725 +#define IP_REV_1_IP_ID_SHIFT (31-15)
24726 +#define IP_REV_1_IP_MJ_SHIFT (31-23)
24727 +#define IP_REV_1_IP_MM_SHIFT (31-31)
24728 +
24729 +#define IP_REV_2_IP_INT_SHIFT (31-15)
24730 +#define IP_REV_2_IP_ERR_SHIFT (31-23)
24731 +#define IP_REV_2_IP_CFG_SHIFT (31-31)
24732 +
24733 +#define MECC_CAP_SHIFT (31-0)
24734 +#define MECC_CET_SHIFT (31-1)
24735 +#define MECC_SERCNT_SHIFT (31-15)
24736 +#define MECC_MEMADDR_SHIFT (31-31)
24737 +
24738 +/**************************************************************************//**
24739 + @Description RX SC defines
24740 +*//***************************************************************************/
24741 +
24742 +/* masks */
24743 +#define RX_SCCFG_SCI_EN_MASK 0x00000800
24744 +#define RX_SCCFG_RP_MASK 0x00000400
24745 +#define RX_SCCFG_VF_MASK 0x00000300
24746 +#define RX_SCCFG_CO_MASK 0x0000003f
24747 +
24748 +/* shifts */
24749 +#define RX_SCCFG_SCI_EN_SHIFT (31-20)
24750 +#define RX_SCCFG_RP_SHIFT (31-21)
24751 +#define RX_SCCFG_VF_SHIFT (31-23)
24752 +#define RX_SCCFG_CO_SHIFT (31-31)
24753 +#define RX_SCCFG_CS_SHIFT (31-7)
24754 +
24755 +/**************************************************************************//**
24756 + @Description RX SA defines
24757 +*//***************************************************************************/
24758 +
24759 +/* masks */
24760 +#define RX_SACFG_ACTIVE 0x80000000
24761 +#define RX_SACFG_AN_MASK 0x00000006
24762 +#define RX_SACFG_EN_MASK 0x00000001
24763 +
24764 +/* shifts */
24765 +#define RX_SACFG_AN_SHIFT (31-30)
24766 +#define RX_SACFG_EN_SHIFT (31-31)
24767 +
24768 +/**************************************************************************//**
24769 + @Description TX SC defines
24770 +*//***************************************************************************/
24771 +
24772 +/* masks */
24773 +#define TX_SCCFG_AN_MASK 0x000c0000
24774 +#define TX_SCCFG_ASA_MASK 0x00020000
24775 +#define TX_SCCFG_SCE_MASK 0x00010000
24776 +#define TX_SCCFG_CO_MASK 0x00003f00
24777 +#define TX_SCCFG_CE_MASK 0x00000010
24778 +#define TX_SCCFG_PF_MASK 0x00000008
24779 +#define TX_SCCFG_AIS_MASK 0x00000004
24780 +#define TX_SCCFG_UES_MASK 0x00000002
24781 +#define TX_SCCFG_USCB_MASK 0x00000001
24782 +
24783 +/* shifts */
24784 +#define TX_SCCFG_AN_SHIFT (31-13)
24785 +#define TX_SCCFG_ASA_SHIFT (31-14)
24786 +#define TX_SCCFG_SCE_SHIFT (31-15)
24787 +#define TX_SCCFG_CO_SHIFT (31-23)
24788 +#define TX_SCCFG_CE_SHIFT (31-27)
24789 +#define TX_SCCFG_PF_SHIFT (31-28)
24790 +#define TX_SCCFG_AIS_SHIFT (31-29)
24791 +#define TX_SCCFG_UES_SHIFT (31-30)
24792 +#define TX_SCCFG_USCB_SHIFT (31-31)
24793 +#define TX_SCCFG_CS_SHIFT (31-7)
24794 +
24795 +/**************************************************************************//**
24796 + @Description TX SA defines
24797 +*//***************************************************************************/
24798 +
24799 +/* masks */
24800 +#define TX_SACFG_ACTIVE 0x80000000
24801 +
24802 +
24803 +typedef struct
24804 +{
24805 + void (*f_Isr) (t_Handle h_Arg, uint32_t id);
24806 + t_Handle h_SrcHandle;
24807 +} t_FmMacsecIntrSrc;
24808 +
24809 +typedef struct
24810 +{
24811 + e_FmMacsecUnknownSciFrameTreatment unknownSciTreatMode;
24812 + bool invalidTagsDeliverUncontrolled;
24813 + bool changedTextWithNoEncryptDeliverUncontrolled;
24814 + bool onlyScbIsSetDeliverUncontrolled;
24815 + bool encryptWithNoChangedTextDiscardUncontrolled;
24816 + e_FmMacsecUntagFrameTreatment untagTreatMode;
24817 + uint32_t pnExhThr;
24818 + bool keysUnreadable;
24819 + bool byPassMode;
24820 + bool reservedSc0;
24821 + uint32_t sectagOverhead;
24822 + uint32_t mflSubtract;
24823 +} t_FmMacsecDriverParam;
24824 +
24825 +typedef struct
24826 +{
24827 + t_FmMacsecControllerDriver fmMacsecControllerDriver;
24828 + t_Handle h_Fm;
24829 + t_FmMacsecRegs *p_FmMacsecRegs;
24830 + t_Handle h_FmMac; /**< A handle to the FM MAC object related to */
24831 + char fmMacsecModuleName[MODULE_NAME_SIZE];
24832 + t_FmMacsecIntrSrc intrMng[NUM_OF_INTER_MODULE_EVENTS];
24833 + uint32_t events;
24834 + uint32_t exceptions;
24835 + uint32_t userExceptions;
24836 + t_FmMacsecExceptionsCallback *f_Exception; /**< Exception Callback Routine */
24837 + t_Handle h_App; /**< A handle to an application layer object; This handle will
24838 + be passed by the driver upon calling the above callbacks */
24839 + bool rxScTable[NUM_OF_RX_SC];
24840 + uint32_t numRxScAvailable;
24841 + bool txScTable[NUM_OF_TX_SC];
24842 + uint32_t numTxScAvailable;
24843 + t_Handle rxScSpinLock;
24844 + t_Handle txScSpinLock;
24845 + t_FmMacsecDriverParam *p_FmMacsecDriverParam;
24846 +} t_FmMacsec;
24847 +
24848 +
24849 +#endif /* __FM_MACSEC_MASTER_H */
24850 --- /dev/null
24851 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MACSEC/fm_macsec_secy.c
24852 @@ -0,0 +1,883 @@
24853 +/*
24854 + * Copyright 2008-2015 Freescale Semiconductor Inc.
24855 + *
24856 + * Redistribution and use in source and binary forms, with or without
24857 + * modification, are permitted provided that the following conditions are met:
24858 + * * Redistributions of source code must retain the above copyright
24859 + * notice, this list of conditions and the following disclaimer.
24860 + * * Redistributions in binary form must reproduce the above copyright
24861 + * notice, this list of conditions and the following disclaimer in the
24862 + * documentation and/or other materials provided with the distribution.
24863 + * * Neither the name of Freescale Semiconductor nor the
24864 + * names of its contributors may be used to endorse or promote products
24865 + * derived from this software without specific prior written permission.
24866 + *
24867 + *
24868 + * ALTERNATIVELY, this software may be distributed under the terms of the
24869 + * GNU General Public License ("GPL") as published by the Free Software
24870 + * Foundation, either version 2 of that License or (at your option) any
24871 + * later version.
24872 + *
24873 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
24874 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
24875 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
24876 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
24877 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
24878 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
24879 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
24880 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24881 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
24882 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24883 + */
24884 +
24885 +/******************************************************************************
24886 + @File fm_macsec_secy.c
24887 +
24888 + @Description FM MACSEC SECY driver routines implementation.
24889 +*//***************************************************************************/
24890 +
24891 +#include "std_ext.h"
24892 +#include "error_ext.h"
24893 +#include "xx_ext.h"
24894 +#include "string_ext.h"
24895 +#include "sprint_ext.h"
24896 +
24897 +#include "fm_macsec_secy.h"
24898 +
24899 +
24900 +/****************************************/
24901 +/* static functions */
24902 +/****************************************/
24903 +static void FmMacsecSecYExceptionsIsr(t_Handle h_FmMacsecSecY, uint32_t id)
24904 +{
24905 + t_FmMacsecSecY *p_FmMacsecSecY = (t_FmMacsecSecY *)h_FmMacsecSecY;
24906 +
24907 + UNUSED(id);
24908 + SANITY_CHECK_RETURN(p_FmMacsecSecY, E_INVALID_HANDLE);
24909 +
24910 + if (p_FmMacsecSecY->exceptions & FM_MACSEC_SECY_EX_FRAME_DISCARDED)
24911 + p_FmMacsecSecY->f_Exception(p_FmMacsecSecY->h_App, e_FM_MACSEC_SECY_EX_FRAME_DISCARDED);
24912 +}
24913 +
24914 +static void FmMacsecSecYEventsIsr(t_Handle h_FmMacsecSecY, uint32_t id)
24915 +{
24916 + t_FmMacsecSecY *p_FmMacsecSecY = (t_FmMacsecSecY *)h_FmMacsecSecY;
24917 +
24918 + UNUSED(id);
24919 + SANITY_CHECK_RETURN(p_FmMacsecSecY, E_INVALID_HANDLE);
24920 +
24921 + if (p_FmMacsecSecY->events & FM_MACSEC_SECY_EV_NEXT_PN)
24922 + p_FmMacsecSecY->f_Event(p_FmMacsecSecY->h_App, e_FM_MACSEC_SECY_EV_NEXT_PN);
24923 +}
24924 +
24925 +static t_Error CheckFmMacsecSecYParameters(t_FmMacsecSecY *p_FmMacsecSecY)
24926 +{
24927 + if (!p_FmMacsecSecY->f_Exception)
24928 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Exceptions callback not provided"));
24929 +
24930 + if (!p_FmMacsecSecY->f_Event)
24931 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Events callback not provided"));
24932 +
24933 + if (!p_FmMacsecSecY->numOfRxSc)
24934 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Num of Rx Scs must be greater than '0'"));
24935 +
24936 +
24937 + return E_OK;
24938 +}
24939 +
24940 +static t_Handle FmMacsecSecYCreateSc(t_FmMacsecSecY *p_FmMacsecSecY,
24941 + macsecSCI_t sci,
24942 + e_FmMacsecSecYCipherSuite cipherSuite,
24943 + e_ScType type)
24944 +{
24945 + t_SecYSc *p_ScTable;
24946 + void *p_Params;
24947 + uint32_t numOfSc,i;
24948 + t_Error err = E_OK;
24949 + t_RxScParams rxScParams;
24950 + t_TxScParams txScParams;
24951 +
24952 + ASSERT_COND(p_FmMacsecSecY);
24953 + ASSERT_COND(p_FmMacsecSecY->h_FmMacsec);
24954 +
24955 + if (type == e_SC_RX)
24956 + {
24957 + memset(&rxScParams, 0, sizeof(rxScParams));
24958 + i = (NUM_OF_RX_SC - 1);
24959 + p_ScTable = p_FmMacsecSecY->p_RxSc;
24960 + numOfSc = p_FmMacsecSecY->numOfRxSc;
24961 + rxScParams.confidentialityOffset = p_FmMacsecSecY->confidentialityOffset;
24962 + rxScParams.replayProtect = p_FmMacsecSecY->replayProtect;
24963 + rxScParams.replayWindow = p_FmMacsecSecY->replayWindow;
24964 + rxScParams.validateFrames = p_FmMacsecSecY->validateFrames;
24965 + rxScParams.cipherSuite = cipherSuite;
24966 + p_Params = &rxScParams;
24967 + }
24968 + else
24969 + {
24970 + memset(&txScParams, 0, sizeof(txScParams));
24971 + i = (NUM_OF_TX_SC - 1);
24972 + p_ScTable = p_FmMacsecSecY->p_TxSc;
24973 + numOfSc = p_FmMacsecSecY->numOfTxSc;
24974 + txScParams.sciInsertionMode = p_FmMacsecSecY->sciInsertionMode;
24975 + txScParams.protectFrames = p_FmMacsecSecY->protectFrames;
24976 + txScParams.confidentialityEnable = p_FmMacsecSecY->confidentialityEnable;
24977 + txScParams.confidentialityOffset = p_FmMacsecSecY->confidentialityOffset;
24978 + txScParams.cipherSuite = cipherSuite;
24979 + p_Params = &txScParams;
24980 + }
24981 +
24982 + for (i=0;i<numOfSc;i++)
24983 + if (!p_ScTable[i].inUse)
24984 + break;
24985 + if (i == numOfSc)
24986 + {
24987 + REPORT_ERROR(MAJOR, E_FULL, ("FM MACSEC SECY SC"));
24988 + return NULL;
24989 + }
24990 +
24991 + if (type == e_SC_RX)
24992 + {
24993 + ((t_RxScParams *)p_Params)->scId = p_ScTable[i].scId;
24994 + ((t_RxScParams *)p_Params)->sci = sci;
24995 + if ((err = FmMacsecCreateRxSc(p_FmMacsecSecY->h_FmMacsec, (t_RxScParams *)p_Params)) != E_OK)
24996 + {
24997 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FM MACSEC SECY RX SC"));
24998 + return NULL;
24999 + }
25000 + }
25001 + else
25002 + {
25003 + ((t_TxScParams *)p_Params)->scId = p_ScTable[i].scId;
25004 + ((t_TxScParams *)p_Params)->sci = sci;
25005 + if ((err = FmMacsecCreateTxSc(p_FmMacsecSecY->h_FmMacsec, (t_TxScParams *)p_Params)) != E_OK)
25006 + {
25007 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FM MACSEC SECY TX SC"));
25008 + return NULL;
25009 + }
25010 + }
25011 +
25012 + p_ScTable[i].inUse = TRUE;
25013 + return &p_ScTable[i];
25014 +}
25015 +
25016 +static t_Error FmMacsecSecYDeleteSc(t_FmMacsecSecY *p_FmMacsecSecY, t_SecYSc *p_FmSecYSc, e_ScType type)
25017 +{
25018 + t_Error err = E_OK;
25019 +
25020 + ASSERT_COND(p_FmMacsecSecY);
25021 + ASSERT_COND(p_FmMacsecSecY->h_FmMacsec);
25022 + ASSERT_COND(p_FmSecYSc);
25023 +
25024 + if (type == e_SC_RX)
25025 + {
25026 + if ((err = FmMacsecDeleteRxSc(p_FmMacsecSecY->h_FmMacsec, p_FmSecYSc->scId)) != E_OK)
25027 + RETURN_ERROR(MINOR, err, NO_MSG);
25028 + }
25029 + else
25030 + if ((err = FmMacsecDeleteTxSc(p_FmMacsecSecY->h_FmMacsec, p_FmSecYSc->scId)) != E_OK)
25031 + RETURN_ERROR(MINOR, err, NO_MSG);
25032 +
25033 + p_FmSecYSc->inUse = FALSE;
25034 +
25035 + return err;
25036 +}
25037 +
25038 +/****************************************/
25039 +/* API Init unit functions */
25040 +/****************************************/
25041 +t_Handle FM_MACSEC_SECY_Config(t_FmMacsecSecYParams *p_FmMacsecSecYParam)
25042 +{
25043 + t_FmMacsecSecY *p_FmMacsecSecY;
25044 +
25045 + /* Allocate FM MACSEC structure */
25046 + p_FmMacsecSecY = (t_FmMacsecSecY *) XX_Malloc(sizeof(t_FmMacsecSecY));
25047 + if (!p_FmMacsecSecY)
25048 + {
25049 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FM MACSEC SECY driver structure"));
25050 + return NULL;
25051 + }
25052 + memset(p_FmMacsecSecY, 0, sizeof(t_FmMacsecSecY));
25053 +
25054 + /* Allocate the FM MACSEC driver's parameters structure */
25055 + p_FmMacsecSecY->p_FmMacsecSecYDriverParam = (t_FmMacsecSecYDriverParam *)XX_Malloc(sizeof(t_FmMacsecSecYDriverParam));
25056 + if (!p_FmMacsecSecY->p_FmMacsecSecYDriverParam)
25057 + {
25058 + XX_Free(p_FmMacsecSecY);
25059 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FM MACSEC SECY driver parameters"));
25060 + return NULL;
25061 + }
25062 + memset(p_FmMacsecSecY->p_FmMacsecSecYDriverParam, 0, sizeof(t_FmMacsecSecYDriverParam));
25063 +
25064 + /* Initialize FM MACSEC SECY parameters which will be kept by the driver */
25065 + p_FmMacsecSecY->h_FmMacsec = p_FmMacsecSecYParam->h_FmMacsec;
25066 + p_FmMacsecSecY->f_Event = p_FmMacsecSecYParam->f_Event;
25067 + p_FmMacsecSecY->f_Exception = p_FmMacsecSecYParam->f_Exception;
25068 + p_FmMacsecSecY->h_App = p_FmMacsecSecYParam->h_App;
25069 + p_FmMacsecSecY->confidentialityEnable = DEFAULT_confidentialityEnable;
25070 + p_FmMacsecSecY->confidentialityOffset = DEFAULT_confidentialityOffset;
25071 + p_FmMacsecSecY->validateFrames = DEFAULT_validateFrames;
25072 + p_FmMacsecSecY->replayProtect = DEFAULT_replayEnable;
25073 + p_FmMacsecSecY->replayWindow = DEFAULT_replayWindow;
25074 + p_FmMacsecSecY->protectFrames = DEFAULT_protectFrames;
25075 + p_FmMacsecSecY->sciInsertionMode = DEFAULT_sciInsertionMode;
25076 + p_FmMacsecSecY->isPointToPoint = DEFAULT_ptp;
25077 + p_FmMacsecSecY->numOfRxSc = p_FmMacsecSecYParam->numReceiveChannels;
25078 + p_FmMacsecSecY->numOfTxSc = DEFAULT_numOfTxSc;
25079 + p_FmMacsecSecY->exceptions = DEFAULT_exceptions;
25080 + p_FmMacsecSecY->events = DEFAULT_events;
25081 +
25082 + memcpy(&p_FmMacsecSecY->p_FmMacsecSecYDriverParam->txScParams,
25083 + &p_FmMacsecSecYParam->txScParams,
25084 + sizeof(t_FmMacsecSecYSCParams));
25085 + return p_FmMacsecSecY;
25086 +}
25087 +
25088 +t_Error FM_MACSEC_SECY_Init(t_Handle h_FmMacsecSecY)
25089 +{
25090 + t_FmMacsecSecY *p_FmMacsecSecY = (t_FmMacsecSecY *)h_FmMacsecSecY;
25091 + t_FmMacsecSecYDriverParam *p_FmMacsecSecYDriverParam = NULL;
25092 + uint32_t rxScIds[NUM_OF_RX_SC], txScIds[NUM_OF_TX_SC], i, j;
25093 + t_Error err;
25094 +
25095 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY, E_INVALID_HANDLE);
25096 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY->p_FmMacsecSecYDriverParam, E_INVALID_HANDLE);
25097 +
25098 + CHECK_INIT_PARAMETERS(p_FmMacsecSecY, CheckFmMacsecSecYParameters);
25099 +
25100 + p_FmMacsecSecYDriverParam = p_FmMacsecSecY->p_FmMacsecSecYDriverParam;
25101 +
25102 + if ((p_FmMacsecSecY->isPointToPoint) &&
25103 + ((err = FmMacsecSetPTP(p_FmMacsecSecY->h_FmMacsec, TRUE)) != E_OK))
25104 + RETURN_ERROR(MAJOR, err, ("Can't set Poin-to-Point"));
25105 +
25106 + /* Rx Sc Allocation */
25107 + p_FmMacsecSecY->p_RxSc = (t_SecYSc *)XX_Malloc(sizeof(t_SecYSc) * p_FmMacsecSecY->numOfRxSc);
25108 + if (!p_FmMacsecSecY->p_RxSc)
25109 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("FM MACSEC SECY RX SC"));
25110 + memset(p_FmMacsecSecY->p_RxSc, 0, sizeof(t_SecYSc) * p_FmMacsecSecY->numOfRxSc);
25111 + if ((err = FmMacsecAllocScs(p_FmMacsecSecY->h_FmMacsec, e_SC_RX, p_FmMacsecSecY->isPointToPoint, p_FmMacsecSecY->numOfRxSc, rxScIds)) != E_OK)
25112 + {
25113 + if (p_FmMacsecSecY->p_TxSc)
25114 + XX_Free(p_FmMacsecSecY->p_TxSc);
25115 + if (p_FmMacsecSecY->p_RxSc)
25116 + XX_Free(p_FmMacsecSecY->p_RxSc);
25117 + return ERROR_CODE(err);
25118 + }
25119 + for (i=0; i<p_FmMacsecSecY->numOfRxSc; i++)
25120 + {
25121 + p_FmMacsecSecY->p_RxSc[i].scId = rxScIds[i];
25122 + p_FmMacsecSecY->p_RxSc[i].type = e_SC_RX;
25123 + for (j=0; j<MAX_NUM_OF_SA_PER_SC;j++)
25124 + p_FmMacsecSecY->p_RxSc[i].sa[j].saId = (e_ScSaId)SECY_AN_FREE_VALUE;
25125 + }
25126 +
25127 + /* Tx Sc Allocation */
25128 + p_FmMacsecSecY->p_TxSc = (t_SecYSc *)XX_Malloc(sizeof(t_SecYSc) * p_FmMacsecSecY->numOfTxSc);
25129 + if (!p_FmMacsecSecY->p_TxSc)
25130 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("FM MACSEC SECY TX SC"));
25131 + memset(p_FmMacsecSecY->p_TxSc, 0, sizeof(t_SecYSc) * p_FmMacsecSecY->numOfTxSc);
25132 +
25133 + if ((err = FmMacsecAllocScs(p_FmMacsecSecY->h_FmMacsec, e_SC_TX, p_FmMacsecSecY->isPointToPoint, p_FmMacsecSecY->numOfTxSc, txScIds)) != E_OK)
25134 + {
25135 + if (p_FmMacsecSecY->p_TxSc)
25136 + XX_Free(p_FmMacsecSecY->p_TxSc);
25137 + if (p_FmMacsecSecY->p_RxSc)
25138 + XX_Free(p_FmMacsecSecY->p_RxSc);
25139 + return ERROR_CODE(err);
25140 + }
25141 + for (i=0; i<p_FmMacsecSecY->numOfTxSc; i++)
25142 + {
25143 + p_FmMacsecSecY->p_TxSc[i].scId = txScIds[i];
25144 + p_FmMacsecSecY->p_TxSc[i].type = e_SC_TX;
25145 + for (j=0; j<MAX_NUM_OF_SA_PER_SC;j++)
25146 + p_FmMacsecSecY->p_TxSc[i].sa[j].saId = (e_ScSaId)SECY_AN_FREE_VALUE;
25147 + FmMacsecRegisterIntr(p_FmMacsecSecY->h_FmMacsec,
25148 + e_FM_MACSEC_MOD_SC_TX,
25149 + (uint8_t)txScIds[i],
25150 + e_FM_INTR_TYPE_ERR,
25151 + FmMacsecSecYExceptionsIsr,
25152 + p_FmMacsecSecY);
25153 + FmMacsecRegisterIntr(p_FmMacsecSecY->h_FmMacsec,
25154 + e_FM_MACSEC_MOD_SC_TX,
25155 + (uint8_t)txScIds[i],
25156 + e_FM_INTR_TYPE_NORMAL,
25157 + FmMacsecSecYEventsIsr,
25158 + p_FmMacsecSecY);
25159 +
25160 + if (p_FmMacsecSecY->exceptions & FM_MACSEC_SECY_EX_FRAME_DISCARDED)
25161 + FmMacsecSetException(p_FmMacsecSecY->h_FmMacsec, e_FM_MACSEC_EX_TX_SC, txScIds[i], TRUE);
25162 + if (p_FmMacsecSecY->events & FM_MACSEC_SECY_EV_NEXT_PN)
25163 + FmMacsecSetEvent(p_FmMacsecSecY->h_FmMacsec, e_FM_MACSEC_EV_TX_SC_NEXT_PN, txScIds[i], TRUE);
25164 + }
25165 +
25166 + FmMacsecSecYCreateSc(p_FmMacsecSecY,
25167 + p_FmMacsecSecYDriverParam->txScParams.sci,
25168 + p_FmMacsecSecYDriverParam->txScParams.cipherSuite,
25169 + e_SC_TX);
25170 + XX_Free(p_FmMacsecSecYDriverParam);
25171 + p_FmMacsecSecY->p_FmMacsecSecYDriverParam = NULL;
25172 +
25173 + return E_OK;
25174 +}
25175 +
25176 +t_Error FM_MACSEC_SECY_Free(t_Handle h_FmMacsecSecY)
25177 +{
25178 + t_FmMacsecSecY *p_FmMacsecSecY = (t_FmMacsecSecY *)h_FmMacsecSecY;
25179 + t_Error err = E_OK;
25180 + uint32_t rxScIds[NUM_OF_RX_SC], txScIds[NUM_OF_TX_SC], i;
25181 +
25182 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY, E_INVALID_HANDLE);
25183 + SANITY_CHECK_RETURN_ERROR(!p_FmMacsecSecY->p_FmMacsecSecYDriverParam, E_INVALID_STATE);
25184 +
25185 + if (p_FmMacsecSecY->isPointToPoint)
25186 + FmMacsecSetPTP(p_FmMacsecSecY->h_FmMacsec, FALSE);
25187 + if (p_FmMacsecSecY->p_RxSc)
25188 + {
25189 + for (i=0; i<p_FmMacsecSecY->numOfRxSc; i++)
25190 + rxScIds[i] = p_FmMacsecSecY->p_RxSc[i].scId;
25191 + if ((err = FmMacsecFreeScs(p_FmMacsecSecY->h_FmMacsec, e_SC_RX, p_FmMacsecSecY->numOfRxSc, rxScIds)) != E_OK)
25192 + return ERROR_CODE(err);
25193 + XX_Free(p_FmMacsecSecY->p_RxSc);
25194 + }
25195 + if (p_FmMacsecSecY->p_TxSc)
25196 + {
25197 + FmMacsecSecYDeleteSc(p_FmMacsecSecY, &p_FmMacsecSecY->p_TxSc[0], e_SC_TX);
25198 +
25199 + for (i=0; i<p_FmMacsecSecY->numOfTxSc; i++) {
25200 + txScIds[i] = p_FmMacsecSecY->p_TxSc[i].scId;
25201 + FmMacsecUnregisterIntr(p_FmMacsecSecY->h_FmMacsec,
25202 + e_FM_MACSEC_MOD_SC_TX,
25203 + (uint8_t)txScIds[i],
25204 + e_FM_INTR_TYPE_ERR);
25205 + FmMacsecUnregisterIntr(p_FmMacsecSecY->h_FmMacsec,
25206 + e_FM_MACSEC_MOD_SC_TX,
25207 + (uint8_t)txScIds[i],
25208 + e_FM_INTR_TYPE_NORMAL);
25209 +
25210 + if (p_FmMacsecSecY->exceptions & FM_MACSEC_SECY_EX_FRAME_DISCARDED)
25211 + FmMacsecSetException(p_FmMacsecSecY->h_FmMacsec, e_FM_MACSEC_EX_TX_SC, txScIds[i], FALSE);
25212 + if (p_FmMacsecSecY->events & FM_MACSEC_SECY_EV_NEXT_PN)
25213 + FmMacsecSetEvent(p_FmMacsecSecY->h_FmMacsec, e_FM_MACSEC_EV_TX_SC_NEXT_PN, txScIds[i], FALSE);
25214 + }
25215 +
25216 + if ((err = FmMacsecFreeScs(p_FmMacsecSecY->h_FmMacsec, e_SC_TX, p_FmMacsecSecY->numOfTxSc, txScIds)) != E_OK)
25217 + return ERROR_CODE(err);
25218 + XX_Free(p_FmMacsecSecY->p_TxSc);
25219 + }
25220 +
25221 + XX_Free(p_FmMacsecSecY);
25222 +
25223 + return err;
25224 +}
25225 +
25226 +t_Error FM_MACSEC_SECY_ConfigSciInsertionMode(t_Handle h_FmMacsecSecY, e_FmMacsecSciInsertionMode sciInsertionMode)
25227 +{
25228 + t_FmMacsecSecY *p_FmMacsecSecY = (t_FmMacsecSecY *)h_FmMacsecSecY;
25229 +
25230 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY, E_INVALID_HANDLE);
25231 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY->p_FmMacsecSecYDriverParam, E_INVALID_STATE);
25232 +
25233 + p_FmMacsecSecY->sciInsertionMode = sciInsertionMode;
25234 +
25235 + return E_OK;
25236 +}
25237 +
25238 +t_Error FM_MACSEC_SECY_ConfigProtectFrames(t_Handle h_FmMacsecSecY, bool protectFrames)
25239 +{
25240 + t_FmMacsecSecY *p_FmMacsecSecY = (t_FmMacsecSecY *)h_FmMacsecSecY;
25241 +
25242 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY, E_INVALID_HANDLE);
25243 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY->p_FmMacsecSecYDriverParam, E_INVALID_STATE);
25244 +
25245 + p_FmMacsecSecY->protectFrames = protectFrames;
25246 +
25247 + return E_OK;
25248 +}
25249 +
25250 +t_Error FM_MACSEC_SECY_ConfigReplayWindow(t_Handle h_FmMacsecSecY, bool replayProtect, uint32_t replayWindow)
25251 +{
25252 + t_FmMacsecSecY *p_FmMacsecSecY = (t_FmMacsecSecY *)h_FmMacsecSecY;
25253 +
25254 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY, E_INVALID_HANDLE);
25255 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY->p_FmMacsecSecYDriverParam, E_INVALID_STATE);
25256 +
25257 + p_FmMacsecSecY->replayProtect = replayProtect;
25258 + p_FmMacsecSecY->replayWindow = replayWindow;
25259 +
25260 + return E_OK;
25261 +}
25262 +
25263 +t_Error FM_MACSEC_SECY_ConfigValidationMode(t_Handle h_FmMacsecSecY, e_FmMacsecValidFrameBehavior validateFrames)
25264 +{
25265 + t_FmMacsecSecY *p_FmMacsecSecY = (t_FmMacsecSecY *)h_FmMacsecSecY;
25266 +
25267 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY, E_INVALID_HANDLE);
25268 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY->p_FmMacsecSecYDriverParam, E_INVALID_STATE);
25269 +
25270 + p_FmMacsecSecY->validateFrames = validateFrames;
25271 +
25272 + return E_OK;
25273 +}
25274 +
25275 +t_Error FM_MACSEC_SECY_ConfigConfidentiality(t_Handle h_FmMacsecSecY, bool confidentialityEnable, uint16_t confidentialityOffset)
25276 +{
25277 + t_FmMacsecSecY *p_FmMacsecSecY = (t_FmMacsecSecY *)h_FmMacsecSecY;
25278 +
25279 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY, E_INVALID_HANDLE);
25280 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY->p_FmMacsecSecYDriverParam, E_INVALID_STATE);
25281 +
25282 + p_FmMacsecSecY->confidentialityEnable = confidentialityEnable;
25283 + p_FmMacsecSecY->confidentialityOffset = confidentialityOffset;
25284 +
25285 + return E_OK;
25286 +}
25287 +
25288 +t_Error FM_MACSEC_SECY_ConfigPointToPoint(t_Handle h_FmMacsecSecY)
25289 +{
25290 + t_FmMacsecSecY *p_FmMacsecSecY = (t_FmMacsecSecY *)h_FmMacsecSecY;
25291 +
25292 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY, E_INVALID_HANDLE);
25293 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY->p_FmMacsecSecYDriverParam, E_INVALID_STATE);
25294 +
25295 + p_FmMacsecSecY->numOfRxSc = 1;
25296 + p_FmMacsecSecY->isPointToPoint = TRUE;
25297 + p_FmMacsecSecY->sciInsertionMode = e_FM_MACSEC_SCI_INSERTION_MODE_IMPLICT_PTP;
25298 +
25299 + return E_OK;
25300 +}
25301 +
25302 +t_Error FM_MACSEC_SECY_ConfigException(t_Handle h_FmMacsecSecY, e_FmMacsecSecYExceptions exception, bool enable)
25303 +{
25304 + t_FmMacsecSecY *p_FmMacsecSecY = (t_FmMacsecSecY *)h_FmMacsecSecY;
25305 + uint32_t bitMask = 0;
25306 +
25307 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY, E_INVALID_HANDLE);
25308 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY->p_FmMacsecSecYDriverParam, E_INVALID_STATE);
25309 +
25310 + GET_EXCEPTION_FLAG(bitMask, exception);
25311 + if (bitMask)
25312 + {
25313 + if (enable)
25314 + p_FmMacsecSecY->exceptions |= bitMask;
25315 + else
25316 + p_FmMacsecSecY->exceptions &= ~bitMask;
25317 + }
25318 + else
25319 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Undefined exception"));
25320 +
25321 + return E_OK;
25322 +}
25323 +
25324 +t_Error FM_MACSEC_SECY_ConfigEvent(t_Handle h_FmMacsecSecY, e_FmMacsecSecYEvents event, bool enable)
25325 +{
25326 + t_FmMacsecSecY *p_FmMacsecSecY = (t_FmMacsecSecY *)h_FmMacsecSecY;
25327 + uint32_t bitMask = 0;
25328 +
25329 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY, E_INVALID_HANDLE);
25330 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY->p_FmMacsecSecYDriverParam, E_INVALID_STATE);
25331 +
25332 + GET_EVENT_FLAG(bitMask, event);
25333 + if (bitMask)
25334 + {
25335 + if (enable)
25336 + p_FmMacsecSecY->events |= bitMask;
25337 + else
25338 + p_FmMacsecSecY->events &= ~bitMask;
25339 + }
25340 + else
25341 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Undefined event"));
25342 +
25343 + return E_OK;
25344 +}
25345 +
25346 +t_Handle FM_MACSEC_SECY_CreateRxSc(t_Handle h_FmMacsecSecY, t_FmMacsecSecYSCParams *p_ScParams)
25347 +{
25348 + t_FmMacsecSecY *p_FmMacsecSecY = (t_FmMacsecSecY *)h_FmMacsecSecY;
25349 +
25350 + SANITY_CHECK_RETURN_VALUE(p_FmMacsecSecY, E_INVALID_HANDLE, NULL);
25351 + SANITY_CHECK_RETURN_VALUE(p_FmMacsecSecY->h_FmMacsec, E_INVALID_HANDLE, NULL);
25352 + SANITY_CHECK_RETURN_VALUE(p_ScParams, E_NULL_POINTER, NULL);
25353 + SANITY_CHECK_RETURN_VALUE(!p_FmMacsecSecY->p_FmMacsecSecYDriverParam, E_INVALID_STATE, NULL);
25354 +
25355 + return FmMacsecSecYCreateSc(p_FmMacsecSecY, p_ScParams->sci, p_ScParams->cipherSuite, e_SC_RX);
25356 +}
25357 +
25358 +t_Error FM_MACSEC_SECY_DeleteRxSc(t_Handle h_FmMacsecSecY, t_Handle h_Sc)
25359 +{
25360 + t_FmMacsecSecY *p_FmMacsecSecY = (t_FmMacsecSecY *)h_FmMacsecSecY;
25361 + t_SecYSc *p_FmSecYSc = (t_SecYSc *)h_Sc;
25362 +
25363 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY, E_INVALID_HANDLE);
25364 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY->h_FmMacsec, E_INVALID_HANDLE);
25365 + SANITY_CHECK_RETURN_ERROR(!p_FmMacsecSecY->p_FmMacsecSecYDriverParam, E_INVALID_STATE);
25366 + SANITY_CHECK_RETURN_ERROR(p_FmSecYSc, E_INVALID_HANDLE);
25367 +
25368 + return FmMacsecSecYDeleteSc(p_FmMacsecSecY, p_FmSecYSc, e_SC_RX);
25369 +}
25370 +
25371 +t_Error FM_MACSEC_SECY_CreateRxSa(t_Handle h_FmMacsecSecY, t_Handle h_Sc, macsecAN_t an, uint32_t lowestPn, macsecSAKey_t key)
25372 +{
25373 + t_FmMacsecSecY *p_FmMacsecSecY = (t_FmMacsecSecY *)h_FmMacsecSecY;
25374 + t_SecYSc *p_FmSecYSc = (t_SecYSc *)h_Sc;
25375 + t_Error err = E_OK;
25376 +
25377 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY, E_INVALID_HANDLE);
25378 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY->h_FmMacsec, E_INVALID_HANDLE);
25379 + SANITY_CHECK_RETURN_ERROR(!p_FmMacsecSecY->p_FmMacsecSecYDriverParam, E_INVALID_STATE);
25380 + SANITY_CHECK_RETURN_ERROR(p_FmSecYSc, E_INVALID_HANDLE);
25381 + SANITY_CHECK_RETURN_ERROR(an < MAX_NUM_OF_SA_PER_SC, E_INVALID_STATE);
25382 +
25383 + if (p_FmSecYSc->sa[an].saId != SECY_AN_FREE_VALUE)
25384 + RETURN_ERROR(MINOR, E_INVALID_STATE, ("An %d is already assigned",an));
25385 +
25386 + if ((err = FmMacsecCreateRxSa(p_FmMacsecSecY->h_FmMacsec, p_FmSecYSc->scId, (e_ScSaId)p_FmSecYSc->numOfSa, an, lowestPn, key)) != E_OK)
25387 + RETURN_ERROR(MINOR, err, NO_MSG);
25388 +
25389 + p_FmSecYSc->sa[an].saId = (e_ScSaId)p_FmSecYSc->numOfSa++;
25390 + return err;
25391 +}
25392 +
25393 +t_Error FM_MACSEC_SECY_DeleteRxSa(t_Handle h_FmMacsecSecY, t_Handle h_Sc, macsecAN_t an)
25394 +{
25395 + t_FmMacsecSecY *p_FmMacsecSecY = (t_FmMacsecSecY *)h_FmMacsecSecY;
25396 + t_SecYSc *p_FmSecYSc = (t_SecYSc *)h_Sc;
25397 + t_Error err = E_OK;
25398 +
25399 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY, E_INVALID_HANDLE);
25400 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY->h_FmMacsec, E_INVALID_HANDLE);
25401 + SANITY_CHECK_RETURN_ERROR(!p_FmMacsecSecY->p_FmMacsecSecYDriverParam, E_INVALID_STATE);
25402 + SANITY_CHECK_RETURN_ERROR(p_FmSecYSc, E_INVALID_HANDLE);
25403 + SANITY_CHECK_RETURN_ERROR(an < MAX_NUM_OF_SA_PER_SC, E_INVALID_STATE);
25404 +
25405 + if (p_FmSecYSc->sa[an].saId == SECY_AN_FREE_VALUE)
25406 + RETURN_ERROR(MINOR, E_INVALID_STATE, ("An %d is already deleted",an));
25407 +
25408 + if ((err = FmMacsecDeleteRxSa(p_FmMacsecSecY->h_FmMacsec, p_FmSecYSc->scId, p_FmSecYSc->sa[an].saId)) != E_OK)
25409 + RETURN_ERROR(MINOR, err, NO_MSG);
25410 +
25411 + p_FmSecYSc->numOfSa--;
25412 + p_FmSecYSc->sa[an].saId = (e_ScSaId)SECY_AN_FREE_VALUE;
25413 + /* TODO - check if statistics need to be read*/
25414 + return err;
25415 +}
25416 +
25417 +t_Error FM_MACSEC_SECY_RxSaEnableReceive(t_Handle h_FmMacsecSecY, t_Handle h_Sc, macsecAN_t an)
25418 +{
25419 + t_FmMacsecSecY *p_FmMacsecSecY = (t_FmMacsecSecY *)h_FmMacsecSecY;
25420 + t_SecYSc *p_FmSecYSc = (t_SecYSc *)h_Sc;
25421 + t_Error err = E_OK;
25422 +
25423 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY, E_INVALID_HANDLE);
25424 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY->h_FmMacsec, E_INVALID_HANDLE);
25425 + SANITY_CHECK_RETURN_ERROR(!p_FmMacsecSecY->p_FmMacsecSecYDriverParam, E_INVALID_STATE);
25426 + SANITY_CHECK_RETURN_ERROR(p_FmSecYSc, E_INVALID_HANDLE);
25427 + SANITY_CHECK_RETURN_ERROR(an < MAX_NUM_OF_SA_PER_SC, E_INVALID_STATE);
25428 +
25429 + if (p_FmSecYSc->sa[an].saId == SECY_AN_FREE_VALUE)
25430 + RETURN_ERROR(MINOR, E_INVALID_STATE, ("An %d is not configured",an));
25431 +
25432 + if ((err = FmMacsecRxSaSetReceive(p_FmMacsecSecY->h_FmMacsec,p_FmSecYSc->scId, p_FmSecYSc->sa[an].saId, TRUE)) != E_OK)
25433 + RETURN_ERROR(MINOR, err, NO_MSG);
25434 +
25435 + p_FmSecYSc->sa[an].active = TRUE;
25436 + return err;
25437 +}
25438 +
25439 +t_Error FM_MACSEC_SECY_RxSaDisableReceive(t_Handle h_FmMacsecSecY, t_Handle h_Sc, macsecAN_t an)
25440 +{
25441 + t_FmMacsecSecY *p_FmMacsecSecY = (t_FmMacsecSecY *)h_FmMacsecSecY;
25442 + t_SecYSc *p_FmSecYSc = (t_SecYSc *)h_Sc;
25443 + t_Error err = E_OK;
25444 +
25445 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY, E_INVALID_HANDLE);
25446 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY->h_FmMacsec, E_INVALID_HANDLE);
25447 + SANITY_CHECK_RETURN_ERROR(!p_FmMacsecSecY->p_FmMacsecSecYDriverParam, E_INVALID_STATE);
25448 + SANITY_CHECK_RETURN_ERROR(p_FmSecYSc, E_INVALID_HANDLE);
25449 + SANITY_CHECK_RETURN_ERROR(an < MAX_NUM_OF_SA_PER_SC, E_INVALID_STATE);
25450 +
25451 + if (p_FmSecYSc->sa[an].saId == SECY_AN_FREE_VALUE)
25452 + RETURN_ERROR(MINOR, E_INVALID_STATE, ("An %d is not configured",an));
25453 +
25454 + if ((err = FmMacsecRxSaSetReceive(p_FmMacsecSecY->h_FmMacsec,p_FmSecYSc->scId, p_FmSecYSc->sa[an].saId, FALSE)) != E_OK)
25455 + RETURN_ERROR(MINOR, err, NO_MSG);
25456 +
25457 + p_FmSecYSc->sa[an].active = FALSE;
25458 + return err;
25459 +}
25460 +
25461 +t_Error FM_MACSEC_SECY_RxSaUpdateNextPn(t_Handle h_FmMacsecSecY, t_Handle h_Sc, macsecAN_t an, uint32_t updtNextPN)
25462 +{
25463 + t_FmMacsecSecY *p_FmMacsecSecY = (t_FmMacsecSecY *)h_FmMacsecSecY;
25464 + t_SecYSc *p_FmSecYSc = (t_SecYSc *)h_Sc;
25465 + t_Error err = E_OK;
25466 +
25467 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY, E_INVALID_HANDLE);
25468 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY->h_FmMacsec, E_INVALID_HANDLE);
25469 + SANITY_CHECK_RETURN_ERROR(!p_FmMacsecSecY->p_FmMacsecSecYDriverParam, E_INVALID_STATE);
25470 + SANITY_CHECK_RETURN_ERROR(p_FmSecYSc, E_INVALID_HANDLE);
25471 + SANITY_CHECK_RETURN_ERROR(an < MAX_NUM_OF_SA_PER_SC, E_INVALID_STATE);
25472 +
25473 + if (p_FmSecYSc->sa[an].saId == SECY_AN_FREE_VALUE)
25474 + RETURN_ERROR(MINOR, E_INVALID_STATE, ("An %d is not configured",an));
25475 +
25476 + if ((err = FmMacsecRxSaUpdateNextPn(p_FmMacsecSecY->h_FmMacsec,p_FmSecYSc->scId, p_FmSecYSc->sa[an].saId, updtNextPN)) != E_OK)
25477 + RETURN_ERROR(MINOR, err, NO_MSG);
25478 +
25479 + return err;
25480 +}
25481 +
25482 +t_Error FM_MACSEC_SECY_RxSaUpdateLowestPn(t_Handle h_FmMacsecSecY, t_Handle h_Sc, macsecAN_t an, uint32_t updtLowestPN)
25483 +{
25484 + t_FmMacsecSecY *p_FmMacsecSecY = (t_FmMacsecSecY *)h_FmMacsecSecY;
25485 + t_SecYSc *p_FmSecYSc = (t_SecYSc *)h_Sc;
25486 + t_Error err = E_OK;
25487 +
25488 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY, E_INVALID_HANDLE);
25489 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY->h_FmMacsec, E_INVALID_HANDLE);
25490 + SANITY_CHECK_RETURN_ERROR(!p_FmMacsecSecY->p_FmMacsecSecYDriverParam, E_INVALID_STATE);
25491 + SANITY_CHECK_RETURN_ERROR(p_FmSecYSc, E_INVALID_HANDLE);
25492 + SANITY_CHECK_RETURN_ERROR(an < MAX_NUM_OF_SA_PER_SC, E_INVALID_STATE);
25493 +
25494 + if (p_FmSecYSc->sa[an].saId == SECY_AN_FREE_VALUE)
25495 + RETURN_ERROR(MINOR, E_INVALID_STATE, ("An %d is not configured",an));
25496 +
25497 + if ((err = FmMacsecRxSaUpdateLowestPn(p_FmMacsecSecY->h_FmMacsec,p_FmSecYSc->scId, p_FmSecYSc->sa[an].saId, updtLowestPN)) != E_OK)
25498 + RETURN_ERROR(MINOR, err, NO_MSG);
25499 +
25500 + return err;
25501 +}
25502 +
25503 +t_Error FM_MACSEC_SECY_RxSaModifyKey(t_Handle h_FmMacsecSecY, t_Handle h_Sc, macsecAN_t an, macsecSAKey_t key)
25504 +{
25505 + t_FmMacsecSecY *p_FmMacsecSecY = (t_FmMacsecSecY *)h_FmMacsecSecY;
25506 + t_SecYSc *p_FmSecYSc = (t_SecYSc *)h_Sc;
25507 + t_Error err = E_OK;
25508 +
25509 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY, E_INVALID_HANDLE);
25510 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY->h_FmMacsec, E_INVALID_HANDLE);
25511 + SANITY_CHECK_RETURN_ERROR(!p_FmMacsecSecY->p_FmMacsecSecYDriverParam, E_INVALID_STATE);
25512 + SANITY_CHECK_RETURN_ERROR(p_FmSecYSc, E_INVALID_HANDLE);
25513 + SANITY_CHECK_RETURN_ERROR(an < MAX_NUM_OF_SA_PER_SC, E_INVALID_STATE);
25514 +
25515 + if (p_FmSecYSc->sa[an].saId == SECY_AN_FREE_VALUE)
25516 + RETURN_ERROR(MINOR, E_INVALID_STATE, ("An %d is not configured",an));
25517 +
25518 + if (p_FmSecYSc->sa[an].active)
25519 + if ((err = FmMacsecRxSaSetReceive(p_FmMacsecSecY->h_FmMacsec, p_FmSecYSc->scId, p_FmSecYSc->sa[an].saId, FALSE)) != E_OK)
25520 + RETURN_ERROR(MINOR, err, NO_MSG);
25521 +
25522 + /* TODO - statistics should be read */
25523 +
25524 + if ((err = FmMacsecCreateRxSa(p_FmMacsecSecY->h_FmMacsec, p_FmSecYSc->scId, p_FmSecYSc->sa[an].saId, an, 1, key)) != E_OK)
25525 + RETURN_ERROR(MINOR, err, NO_MSG);
25526 +
25527 + if (p_FmSecYSc->sa[an].active)
25528 + if ((err = FmMacsecRxSaSetReceive(p_FmMacsecSecY->h_FmMacsec, p_FmSecYSc->scId, p_FmSecYSc->sa[an].saId, TRUE)) != E_OK)
25529 + RETURN_ERROR(MINOR, err, NO_MSG);
25530 + return err;
25531 +}
25532 +
25533 +
25534 +t_Error FM_MACSEC_SECY_CreateTxSa(t_Handle h_FmMacsecSecY, macsecAN_t an, macsecSAKey_t key)
25535 +{
25536 + t_FmMacsecSecY *p_FmMacsecSecY = (t_FmMacsecSecY *)h_FmMacsecSecY;
25537 + t_SecYSc *p_FmSecYSc;
25538 + t_Error err = E_OK;
25539 +
25540 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY, E_INVALID_HANDLE);
25541 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY->h_FmMacsec, E_INVALID_HANDLE);
25542 + SANITY_CHECK_RETURN_ERROR(!p_FmMacsecSecY->p_FmMacsecSecYDriverParam, E_INVALID_STATE);
25543 + p_FmSecYSc = &p_FmMacsecSecY->p_TxSc[0];
25544 + SANITY_CHECK_RETURN_ERROR(p_FmSecYSc, E_INVALID_HANDLE);
25545 + SANITY_CHECK_RETURN_ERROR(an < MAX_NUM_OF_SA_PER_SC, E_INVALID_STATE);
25546 +
25547 + if (p_FmSecYSc->sa[an].saId != SECY_AN_FREE_VALUE)
25548 + RETURN_ERROR(MINOR, err, ("An %d is already assigned",an));
25549 +
25550 + if ((err = FmMacsecCreateTxSa(p_FmMacsecSecY->h_FmMacsec,p_FmSecYSc->scId, (e_ScSaId)p_FmSecYSc->numOfSa, key)) != E_OK)
25551 + RETURN_ERROR(MINOR, err, NO_MSG);
25552 +
25553 + p_FmSecYSc->sa[an].saId = (e_ScSaId)p_FmSecYSc->numOfSa++;
25554 + return err;
25555 +}
25556 +
25557 +t_Error FM_MACSEC_SECY_DeleteTxSa(t_Handle h_FmMacsecSecY, macsecAN_t an)
25558 +{
25559 + t_FmMacsecSecY *p_FmMacsecSecY = (t_FmMacsecSecY *)h_FmMacsecSecY;
25560 + t_SecYSc *p_FmSecYSc;
25561 + t_Error err = E_OK;
25562 +
25563 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY, E_INVALID_HANDLE);
25564 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY->h_FmMacsec, E_INVALID_HANDLE);
25565 + SANITY_CHECK_RETURN_ERROR(!p_FmMacsecSecY->p_FmMacsecSecYDriverParam, E_INVALID_STATE);
25566 + p_FmSecYSc = &p_FmMacsecSecY->p_TxSc[0];
25567 + SANITY_CHECK_RETURN_ERROR(p_FmSecYSc, E_INVALID_HANDLE);
25568 + SANITY_CHECK_RETURN_ERROR(an < MAX_NUM_OF_SA_PER_SC, E_INVALID_STATE);
25569 +
25570 + if (p_FmSecYSc->sa[an].saId == SECY_AN_FREE_VALUE)
25571 + RETURN_ERROR(MINOR, E_INVALID_STATE, ("An %d is already deleted",an));
25572 +
25573 + if ((err = FmMacsecDeleteTxSa(p_FmMacsecSecY->h_FmMacsec, p_FmSecYSc->scId, p_FmSecYSc->sa[an].saId)) != E_OK)
25574 + RETURN_ERROR(MINOR, err, NO_MSG);
25575 +
25576 + p_FmSecYSc->numOfSa--;
25577 + p_FmSecYSc->sa[an].saId = (e_ScSaId)SECY_AN_FREE_VALUE;
25578 + /* TODO - check if statistics need to be read*/
25579 + return err;
25580 +}
25581 +
25582 +t_Error FM_MACSEC_SECY_TxSaModifyKey(t_Handle h_FmMacsecSecY, macsecAN_t nextActiveAn, macsecSAKey_t key)
25583 +{
25584 + t_FmMacsecSecY *p_FmMacsecSecY = (t_FmMacsecSecY *)h_FmMacsecSecY;
25585 + t_SecYSc *p_FmSecYSc;
25586 + macsecAN_t currentAn;
25587 + t_Error err = E_OK;
25588 +
25589 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY, E_INVALID_HANDLE);
25590 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY->h_FmMacsec, E_INVALID_HANDLE);
25591 + SANITY_CHECK_RETURN_ERROR(!p_FmMacsecSecY->p_FmMacsecSecYDriverParam, E_INVALID_STATE);
25592 + p_FmSecYSc = &p_FmMacsecSecY->p_TxSc[0];
25593 + SANITY_CHECK_RETURN_ERROR(p_FmSecYSc, E_INVALID_HANDLE);
25594 + SANITY_CHECK_RETURN_ERROR(nextActiveAn < MAX_NUM_OF_SA_PER_SC, E_INVALID_STATE);
25595 +
25596 + if ((err = FmMacsecTxSaGetActive(p_FmMacsecSecY->h_FmMacsec,
25597 + p_FmSecYSc->scId,
25598 + &currentAn)) != E_OK)
25599 + RETURN_ERROR(MINOR, err, NO_MSG);
25600 +
25601 + if ((err = FmMacsecTxSaSetActive(p_FmMacsecSecY->h_FmMacsec,
25602 + p_FmSecYSc->scId,
25603 + p_FmSecYSc->sa[nextActiveAn].saId,
25604 + nextActiveAn)) != E_OK)
25605 + RETURN_ERROR(MINOR, err, NO_MSG);
25606 +
25607 + /* TODO - statistics should be read */
25608 +
25609 + if ((err = FmMacsecCreateTxSa(p_FmMacsecSecY->h_FmMacsec, p_FmSecYSc->scId, p_FmSecYSc->sa[currentAn].saId, key)) != E_OK)
25610 + RETURN_ERROR(MINOR, err, NO_MSG);
25611 +
25612 + return err;
25613 +}
25614 +
25615 +t_Error FM_MACSEC_SECY_TxSaSetActive(t_Handle h_FmMacsecSecY, macsecAN_t an)
25616 +{
25617 + t_FmMacsecSecY *p_FmMacsecSecY = (t_FmMacsecSecY *)h_FmMacsecSecY;
25618 + t_SecYSc *p_FmSecYSc;
25619 + t_Error err = E_OK;
25620 +
25621 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY, E_INVALID_HANDLE);
25622 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY->h_FmMacsec, E_INVALID_HANDLE);
25623 + SANITY_CHECK_RETURN_ERROR(!p_FmMacsecSecY->p_FmMacsecSecYDriverParam, E_INVALID_STATE);
25624 + p_FmSecYSc = &p_FmMacsecSecY->p_TxSc[0];
25625 + SANITY_CHECK_RETURN_ERROR(p_FmSecYSc, E_INVALID_HANDLE);
25626 + SANITY_CHECK_RETURN_ERROR(an < MAX_NUM_OF_SA_PER_SC, E_INVALID_STATE);
25627 +
25628 + if (p_FmSecYSc->sa[an].saId == SECY_AN_FREE_VALUE)
25629 + RETURN_ERROR(MINOR, E_INVALID_STATE, ("An %d is not configured",an));
25630 +
25631 + if ((err = FmMacsecTxSaSetActive(p_FmMacsecSecY->h_FmMacsec,
25632 + p_FmSecYSc->scId,
25633 + p_FmSecYSc->sa[an].saId,
25634 + an)) != E_OK)
25635 + RETURN_ERROR(MINOR, err, NO_MSG);
25636 +
25637 + return err;
25638 +}
25639 +
25640 +t_Error FM_MACSEC_SECY_TxSaGetActive(t_Handle h_FmMacsecSecY, macsecAN_t *p_An)
25641 +{
25642 + t_FmMacsecSecY *p_FmMacsecSecY = (t_FmMacsecSecY *)h_FmMacsecSecY;
25643 + t_SecYSc *p_FmSecYSc;
25644 + t_Error err = E_OK;
25645 +
25646 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY, E_INVALID_HANDLE);
25647 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY->h_FmMacsec, E_INVALID_HANDLE);
25648 + SANITY_CHECK_RETURN_ERROR(!p_FmMacsecSecY->p_FmMacsecSecYDriverParam, E_INVALID_STATE);
25649 + p_FmSecYSc = &p_FmMacsecSecY->p_TxSc[0];
25650 + SANITY_CHECK_RETURN_ERROR(p_FmSecYSc, E_INVALID_HANDLE);
25651 + SANITY_CHECK_RETURN_ERROR(p_An, E_INVALID_HANDLE);
25652 +
25653 + if ((err = FmMacsecTxSaGetActive(p_FmMacsecSecY->h_FmMacsec,
25654 + p_FmSecYSc->scId,
25655 + p_An)) != E_OK)
25656 + RETURN_ERROR(MINOR, err, NO_MSG);
25657 +
25658 + return err;
25659 +}
25660 +
25661 +t_Error FM_MACSEC_SECY_GetRxScPhysId(t_Handle h_FmMacsecSecY, t_Handle h_Sc, uint32_t *p_ScPhysId)
25662 +{
25663 + t_SecYSc *p_FmSecYSc = (t_SecYSc *)h_Sc;
25664 + t_Error err = E_OK;
25665 +
25666 + SANITY_CHECK_RETURN_ERROR(h_FmMacsecSecY, E_INVALID_HANDLE);
25667 + SANITY_CHECK_RETURN_ERROR(((t_FmMacsecSecY *)h_FmMacsecSecY)->h_FmMacsec, E_INVALID_HANDLE);
25668 + SANITY_CHECK_RETURN_ERROR(!((t_FmMacsecSecY *)h_FmMacsecSecY)->p_FmMacsecSecYDriverParam, E_INVALID_STATE);
25669 + SANITY_CHECK_RETURN_ERROR(p_FmSecYSc, E_INVALID_HANDLE);
25670 +#ifdef DISABLE_SANITY_CHECKS
25671 + UNUSED(h_FmMacsecSecY);
25672 +#endif /* DISABLE_SANITY_CHECKS */
25673 +
25674 + *p_ScPhysId = p_FmSecYSc->scId;
25675 + return err;
25676 +}
25677 +
25678 +t_Error FM_MACSEC_SECY_GetTxScPhysId(t_Handle h_FmMacsecSecY, uint32_t *p_ScPhysId)
25679 +{
25680 + t_FmMacsecSecY *p_FmMacsecSecY = (t_FmMacsecSecY *)h_FmMacsecSecY;
25681 + t_SecYSc *p_FmSecYSc;
25682 + t_Error err = E_OK;
25683 +
25684 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY, E_INVALID_HANDLE);
25685 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY->h_FmMacsec, E_INVALID_HANDLE);
25686 + SANITY_CHECK_RETURN_ERROR(!p_FmMacsecSecY->p_FmMacsecSecYDriverParam, E_INVALID_STATE);
25687 + p_FmSecYSc = &p_FmMacsecSecY->p_TxSc[0];
25688 + SANITY_CHECK_RETURN_ERROR(p_FmSecYSc, E_INVALID_HANDLE);
25689 +
25690 + *p_ScPhysId = p_FmSecYSc->scId;
25691 + return err;
25692 +}
25693 +
25694 +t_Error FM_MACSEC_SECY_SetException(t_Handle h_FmMacsecSecY, e_FmMacsecExceptions exception, bool enable)
25695 +{
25696 + UNUSED(h_FmMacsecSecY);UNUSED(exception);UNUSED(enable);
25697 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
25698 +}
25699 +
25700 +t_Error FM_MACSEC_SECY_SetEvent(t_Handle h_FmMacsecSecY, e_FmMacsecSecYEvents event, bool enable)
25701 +{
25702 + UNUSED(h_FmMacsecSecY);UNUSED(event);UNUSED(enable);
25703 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
25704 +}
25705 +
25706 +t_Error FM_MACSEC_SECY_GetStatistics(t_Handle h_FmMacsecSecY, t_FmMacsecSecYStatistics *p_Statistics)
25707 +{
25708 + UNUSED(h_FmMacsecSecY);UNUSED(p_Statistics);
25709 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
25710 +}
25711 +
25712 +t_Error FM_MACSEC_SECY_RxScGetStatistics(t_Handle h_FmMacsecSecY, t_Handle h_Sc, t_FmMacsecSecYRxScStatistics *p_Statistics)
25713 +{
25714 + UNUSED(h_FmMacsecSecY);UNUSED(h_Sc);UNUSED(p_Statistics);
25715 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
25716 +}
25717 +
25718 +t_Error FM_MACSEC_SECY_RxSaGetStatistics(t_Handle h_FmMacsecSecY, t_Handle h_Sc, macsecAN_t an, t_FmMacsecSecYRxSaStatistics *p_Statistics)
25719 +{
25720 + UNUSED(h_FmMacsecSecY);UNUSED(h_Sc);UNUSED(an);UNUSED(p_Statistics);
25721 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
25722 +}
25723 +
25724 +t_Error FM_MACSEC_SECY_TxScGetStatistics(t_Handle h_FmMacsecSecY, t_FmMacsecSecYTxScStatistics *p_Statistics)
25725 +{
25726 + UNUSED(h_FmMacsecSecY);UNUSED(p_Statistics);
25727 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
25728 +}
25729 +
25730 +t_Error FM_MACSEC_SECY_TxSaGetStatistics(t_Handle h_FmMacsecSecY, macsecAN_t an, t_FmMacsecSecYTxSaStatistics *p_Statistics)
25731 +{
25732 + UNUSED(h_FmMacsecSecY);UNUSED(an);UNUSED(p_Statistics);
25733 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
25734 +}
25735 +
25736 --- /dev/null
25737 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MACSEC/fm_macsec_secy.h
25738 @@ -0,0 +1,144 @@
25739 +/*
25740 + * Copyright 2008-2015 Freescale Semiconductor Inc.
25741 + *
25742 + * Redistribution and use in source and binary forms, with or without
25743 + * modification, are permitted provided that the following conditions are met:
25744 + * * Redistributions of source code must retain the above copyright
25745 + * notice, this list of conditions and the following disclaimer.
25746 + * * Redistributions in binary form must reproduce the above copyright
25747 + * notice, this list of conditions and the following disclaimer in the
25748 + * documentation and/or other materials provided with the distribution.
25749 + * * Neither the name of Freescale Semiconductor nor the
25750 + * names of its contributors may be used to endorse or promote products
25751 + * derived from this software without specific prior written permission.
25752 + *
25753 + *
25754 + * ALTERNATIVELY, this software may be distributed under the terms of the
25755 + * GNU General Public License ("GPL") as published by the Free Software
25756 + * Foundation, either version 2 of that License or (at your option) any
25757 + * later version.
25758 + *
25759 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
25760 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
25761 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
25762 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
25763 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
25764 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
25765 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
25766 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25767 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25768 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25769 + */
25770 +
25771 +/******************************************************************************
25772 + @File fm_macsec_secy.h
25773 +
25774 + @Description FM MACSEC SecY internal structures and definitions.
25775 +*//***************************************************************************/
25776 +#ifndef __FM_MACSEC_SECY_H
25777 +#define __FM_MACSEC_SECY_H
25778 +
25779 +#include "error_ext.h"
25780 +#include "std_ext.h"
25781 +
25782 +#include "fm_macsec.h"
25783 +
25784 +
25785 +/**************************************************************************//**
25786 + @Description Exceptions
25787 +*//***************************************************************************/
25788 +
25789 +#define FM_MACSEC_SECY_EX_FRAME_DISCARDED 0x80000000
25790 +
25791 +#define GET_EXCEPTION_FLAG(bitMask, exception) switch (exception){ \
25792 + case e_FM_MACSEC_SECY_EX_FRAME_DISCARDED: \
25793 + bitMask = FM_MACSEC_SECY_EX_FRAME_DISCARDED; break; \
25794 + default: bitMask = 0;break;}
25795 +
25796 +/**************************************************************************//**
25797 + @Description Events
25798 +*//***************************************************************************/
25799 +
25800 +#define FM_MACSEC_SECY_EV_NEXT_PN 0x80000000
25801 +
25802 +#define GET_EVENT_FLAG(bitMask, event) switch (event){ \
25803 + case e_FM_MACSEC_SECY_EV_NEXT_PN: \
25804 + bitMask = FM_MACSEC_SECY_EV_NEXT_PN; break; \
25805 + default: bitMask = 0;break;}
25806 +
25807 +/**************************************************************************//**
25808 + @Description Defaults
25809 +*//***************************************************************************/
25810 +
25811 +#define DEFAULT_exceptions (FM_MACSEC_SECY_EX_FRAME_DISCARDED)
25812 +#define DEFAULT_events (FM_MACSEC_SECY_EV_NEXT_PN)
25813 +#define DEFAULT_numOfTxSc 1
25814 +#define DEFAULT_confidentialityEnable FALSE
25815 +#define DEFAULT_confidentialityOffset 0
25816 +#define DEFAULT_sciInsertionMode e_FM_MACSEC_SCI_INSERTION_MODE_EXPLICIT_SECTAG
25817 +#define DEFAULT_validateFrames e_FM_MACSEC_VALID_FRAME_BEHAVIOR_STRICT
25818 +#define DEFAULT_replayEnable FALSE
25819 +#define DEFAULT_replayWindow 0
25820 +#define DEFAULT_protectFrames TRUE
25821 +#define DEFAULT_ptp FALSE
25822 +
25823 +/**************************************************************************//**
25824 + @Description General defines
25825 +*//***************************************************************************/
25826 +
25827 +#define SECY_AN_FREE_VALUE MAX_NUM_OF_SA_PER_SC
25828 +
25829 +
25830 +typedef struct {
25831 + e_ScSaId saId;
25832 + bool active;
25833 + union {
25834 + t_FmMacsecSecYRxSaStatistics rxSaStatistics;
25835 + t_FmMacsecSecYTxSaStatistics txSaStatistics;
25836 + };
25837 +} t_SecYSa;
25838 +
25839 +typedef struct {
25840 + bool inUse;
25841 + uint32_t scId;
25842 + e_ScType type;
25843 + uint8_t numOfSa;
25844 + t_SecYSa sa[MAX_NUM_OF_SA_PER_SC];
25845 + union {
25846 + t_FmMacsecSecYRxScStatistics rxScStatistics;
25847 + t_FmMacsecSecYTxScStatistics txScStatistics;
25848 + };
25849 +} t_SecYSc;
25850 +
25851 +typedef struct {
25852 + t_FmMacsecSecYSCParams txScParams; /**< Tx SC Params */
25853 +} t_FmMacsecSecYDriverParam;
25854 +
25855 +typedef struct {
25856 + t_Handle h_FmMacsec;
25857 + bool confidentialityEnable; /**< TRUE - confidentiality protection and integrity protection
25858 + FALSE - no confidentiality protection, only integrity protection*/
25859 + uint16_t confidentialityOffset; /**< The number of initial octets of each MSDU without confidentiality protection
25860 + common values are 0, 30, and 50 */
25861 + bool replayProtect; /**< replay protection function mode */
25862 + uint32_t replayWindow; /**< the size of the replay window */
25863 + e_FmMacsecValidFrameBehavior validateFrames; /**< validation function mode */
25864 + e_FmMacsecSciInsertionMode sciInsertionMode;
25865 + bool protectFrames;
25866 + bool isPointToPoint;
25867 + e_FmMacsecSecYCipherSuite cipherSuite; /**< Cipher suite to be used for this SecY */
25868 + uint32_t numOfRxSc; /**< Number of receive channels */
25869 + uint32_t numOfTxSc; /**< Number of transmit channels */
25870 + t_SecYSc *p_RxSc;
25871 + t_SecYSc *p_TxSc;
25872 + uint32_t events;
25873 + uint32_t exceptions;
25874 + t_FmMacsecSecYExceptionsCallback *f_Exception; /**< TODO */
25875 + t_FmMacsecSecYEventsCallback *f_Event; /**< TODO */
25876 + t_Handle h_App;
25877 + t_FmMacsecSecYStatistics statistics;
25878 + t_FmMacsecSecYDriverParam *p_FmMacsecSecYDriverParam;
25879 +} t_FmMacsecSecY;
25880 +
25881 +
25882 +#endif /* __FM_MACSEC_SECY_H */
25883 --- /dev/null
25884 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Makefile
25885 @@ -0,0 +1,23 @@
25886 +#
25887 +# Makefile for the Freescale Ethernet controllers
25888 +#
25889 +ccflags-y += -DVERSION=\"\"
25890 +#
25891 +#Include netcomm SW specific definitions
25892 +include $(srctree)/drivers/net/ethernet/freescale/sdk_fman/ncsw_config.mk
25893 +NCSW_FM_INC = $(srctree)/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/inc
25894 +
25895 +ccflags-y += -I$(NCSW_FM_INC)
25896 +
25897 +
25898 +obj-y += fsl-ncsw-PFM1.o
25899 +
25900 +fsl-ncsw-PFM1-objs := fm.o fm_muram.o fman.o
25901 +
25902 +obj-y += MAC/
25903 +obj-y += Pcd/
25904 +obj-y += SP/
25905 +obj-y += Port/
25906 +obj-y += HC/
25907 +obj-y += Rtc/
25908 +obj-y += MACSEC/
25909 --- /dev/null
25910 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/Makefile
25911 @@ -0,0 +1,26 @@
25912 +#
25913 +# Makefile for the Freescale Ethernet controllers
25914 +#
25915 +ccflags-y += -DVERSION=\"\"
25916 +#
25917 +#Include netcomm SW specific definitions
25918 +include $(srctree)/drivers/net/ethernet/freescale/sdk_fman/ncsw_config.mk
25919 +
25920 +NCSW_FM_INC = $(srctree)/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/inc
25921 +
25922 +ccflags-y += -I$(NCSW_FM_INC)
25923 +
25924 +obj-y += fsl-ncsw-Pcd.o
25925 +
25926 +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
25927 +
25928 +ifeq ($(CONFIG_FMAN_V3H),y)
25929 +fsl-ncsw-Pcd-objs += fm_replic.o
25930 +endif
25931 +ifeq ($(CONFIG_FMAN_V3L),y)
25932 +fsl-ncsw-Pcd-objs += fm_replic.o
25933 +endif
25934 +ifeq ($(CONFIG_FMAN_ARM),y)
25935 +fsl-ncsw-Pcd-objs += fm_replic.o
25936 +endif
25937 +
25938 --- /dev/null
25939 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/crc64.h
25940 @@ -0,0 +1,360 @@
25941 +/*
25942 + * Copyright 2008-2012 Freescale Semiconductor Inc.
25943 + *
25944 + * Redistribution and use in source and binary forms, with or without
25945 + * modification, are permitted provided that the following conditions are met:
25946 + * * Redistributions of source code must retain the above copyright
25947 + * notice, this list of conditions and the following disclaimer.
25948 + * * Redistributions in binary form must reproduce the above copyright
25949 + * notice, this list of conditions and the following disclaimer in the
25950 + * documentation and/or other materials provided with the distribution.
25951 + * * Neither the name of Freescale Semiconductor nor the
25952 + * names of its contributors may be used to endorse or promote products
25953 + * derived from this software without specific prior written permission.
25954 + *
25955 + *
25956 + * ALTERNATIVELY, this software may be distributed under the terms of the
25957 + * GNU General Public License ("GPL") as published by the Free Software
25958 + * Foundation, either version 2 of that License or (at your option) any
25959 + * later version.
25960 + *
25961 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
25962 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
25963 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
25964 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
25965 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
25966 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
25967 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
25968 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25969 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25970 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25971 + */
25972 +
25973 +
25974 + /**************************************************************************//**
25975 + @File crc64.h
25976 +
25977 + @Description brief This file contains the CRC64 Table, and __inline__
25978 + functions used for calculating crc.
25979 +*//***************************************************************************/
25980 +#ifndef __CRC64_H
25981 +#define __CRC64_H
25982 +
25983 +#include "std_ext.h"
25984 +
25985 +
25986 +#define BITS_PER_BYTE 8
25987 +
25988 +#define CRC64_EXPON_ECMA_182 0xC96C5795D7870F42ULL
25989 +#define CRC64_DEFAULT_INITVAL 0xFFFFFFFFFFFFFFFFULL
25990 +
25991 +#define CRC64_BYTE_MASK 0xFF
25992 +#define CRC64_TABLE_ENTRIES ( 1 << BITS_PER_BYTE )
25993 +#define CRC64_ODD_MASK 1
25994 +
25995 +
25996 +/**
25997 + \brief '64 bit crc' Table
25998 + */
25999 +struct crc64_t {
26000 + uint64_t initial; /**< Initial seed */
26001 + uint64_t table[CRC64_TABLE_ENTRIES]; /**< CRC table entries */
26002 +};
26003 +
26004 +
26005 +static struct crc64_t CRC64_ECMA_182 = {
26006 + CRC64_DEFAULT_INITVAL,
26007 + {
26008 + 0x0000000000000000ULL,
26009 + 0xb32e4cbe03a75f6fULL,
26010 + 0xf4843657a840a05bULL,
26011 + 0x47aa7ae9abe7ff34ULL,
26012 + 0x7bd0c384ff8f5e33ULL,
26013 + 0xc8fe8f3afc28015cULL,
26014 + 0x8f54f5d357cffe68ULL,
26015 + 0x3c7ab96d5468a107ULL,
26016 + 0xf7a18709ff1ebc66ULL,
26017 + 0x448fcbb7fcb9e309ULL,
26018 + 0x0325b15e575e1c3dULL,
26019 + 0xb00bfde054f94352ULL,
26020 + 0x8c71448d0091e255ULL,
26021 + 0x3f5f08330336bd3aULL,
26022 + 0x78f572daa8d1420eULL,
26023 + 0xcbdb3e64ab761d61ULL,
26024 + 0x7d9ba13851336649ULL,
26025 + 0xceb5ed8652943926ULL,
26026 + 0x891f976ff973c612ULL,
26027 + 0x3a31dbd1fad4997dULL,
26028 + 0x064b62bcaebc387aULL,
26029 + 0xb5652e02ad1b6715ULL,
26030 + 0xf2cf54eb06fc9821ULL,
26031 + 0x41e11855055bc74eULL,
26032 + 0x8a3a2631ae2dda2fULL,
26033 + 0x39146a8fad8a8540ULL,
26034 + 0x7ebe1066066d7a74ULL,
26035 + 0xcd905cd805ca251bULL,
26036 + 0xf1eae5b551a2841cULL,
26037 + 0x42c4a90b5205db73ULL,
26038 + 0x056ed3e2f9e22447ULL,
26039 + 0xb6409f5cfa457b28ULL,
26040 + 0xfb374270a266cc92ULL,
26041 + 0x48190ecea1c193fdULL,
26042 + 0x0fb374270a266cc9ULL,
26043 + 0xbc9d3899098133a6ULL,
26044 + 0x80e781f45de992a1ULL,
26045 + 0x33c9cd4a5e4ecdceULL,
26046 + 0x7463b7a3f5a932faULL,
26047 + 0xc74dfb1df60e6d95ULL,
26048 + 0x0c96c5795d7870f4ULL,
26049 + 0xbfb889c75edf2f9bULL,
26050 + 0xf812f32ef538d0afULL,
26051 + 0x4b3cbf90f69f8fc0ULL,
26052 + 0x774606fda2f72ec7ULL,
26053 + 0xc4684a43a15071a8ULL,
26054 + 0x83c230aa0ab78e9cULL,
26055 + 0x30ec7c140910d1f3ULL,
26056 + 0x86ace348f355aadbULL,
26057 + 0x3582aff6f0f2f5b4ULL,
26058 + 0x7228d51f5b150a80ULL,
26059 + 0xc10699a158b255efULL,
26060 + 0xfd7c20cc0cdaf4e8ULL,
26061 + 0x4e526c720f7dab87ULL,
26062 + 0x09f8169ba49a54b3ULL,
26063 + 0xbad65a25a73d0bdcULL,
26064 + 0x710d64410c4b16bdULL,
26065 + 0xc22328ff0fec49d2ULL,
26066 + 0x85895216a40bb6e6ULL,
26067 + 0x36a71ea8a7ace989ULL,
26068 + 0x0adda7c5f3c4488eULL,
26069 + 0xb9f3eb7bf06317e1ULL,
26070 + 0xfe5991925b84e8d5ULL,
26071 + 0x4d77dd2c5823b7baULL,
26072 + 0x64b62bcaebc387a1ULL,
26073 + 0xd7986774e864d8ceULL,
26074 + 0x90321d9d438327faULL,
26075 + 0x231c512340247895ULL,
26076 + 0x1f66e84e144cd992ULL,
26077 + 0xac48a4f017eb86fdULL,
26078 + 0xebe2de19bc0c79c9ULL,
26079 + 0x58cc92a7bfab26a6ULL,
26080 + 0x9317acc314dd3bc7ULL,
26081 + 0x2039e07d177a64a8ULL,
26082 + 0x67939a94bc9d9b9cULL,
26083 + 0xd4bdd62abf3ac4f3ULL,
26084 + 0xe8c76f47eb5265f4ULL,
26085 + 0x5be923f9e8f53a9bULL,
26086 + 0x1c4359104312c5afULL,
26087 + 0xaf6d15ae40b59ac0ULL,
26088 + 0x192d8af2baf0e1e8ULL,
26089 + 0xaa03c64cb957be87ULL,
26090 + 0xeda9bca512b041b3ULL,
26091 + 0x5e87f01b11171edcULL,
26092 + 0x62fd4976457fbfdbULL,
26093 + 0xd1d305c846d8e0b4ULL,
26094 + 0x96797f21ed3f1f80ULL,
26095 + 0x2557339fee9840efULL,
26096 + 0xee8c0dfb45ee5d8eULL,
26097 + 0x5da24145464902e1ULL,
26098 + 0x1a083bacedaefdd5ULL,
26099 + 0xa9267712ee09a2baULL,
26100 + 0x955cce7fba6103bdULL,
26101 + 0x267282c1b9c65cd2ULL,
26102 + 0x61d8f8281221a3e6ULL,
26103 + 0xd2f6b4961186fc89ULL,
26104 + 0x9f8169ba49a54b33ULL,
26105 + 0x2caf25044a02145cULL,
26106 + 0x6b055fede1e5eb68ULL,
26107 + 0xd82b1353e242b407ULL,
26108 + 0xe451aa3eb62a1500ULL,
26109 + 0x577fe680b58d4a6fULL,
26110 + 0x10d59c691e6ab55bULL,
26111 + 0xa3fbd0d71dcdea34ULL,
26112 + 0x6820eeb3b6bbf755ULL,
26113 + 0xdb0ea20db51ca83aULL,
26114 + 0x9ca4d8e41efb570eULL,
26115 + 0x2f8a945a1d5c0861ULL,
26116 + 0x13f02d374934a966ULL,
26117 + 0xa0de61894a93f609ULL,
26118 + 0xe7741b60e174093dULL,
26119 + 0x545a57dee2d35652ULL,
26120 + 0xe21ac88218962d7aULL,
26121 + 0x5134843c1b317215ULL,
26122 + 0x169efed5b0d68d21ULL,
26123 + 0xa5b0b26bb371d24eULL,
26124 + 0x99ca0b06e7197349ULL,
26125 + 0x2ae447b8e4be2c26ULL,
26126 + 0x6d4e3d514f59d312ULL,
26127 + 0xde6071ef4cfe8c7dULL,
26128 + 0x15bb4f8be788911cULL,
26129 + 0xa6950335e42fce73ULL,
26130 + 0xe13f79dc4fc83147ULL,
26131 + 0x521135624c6f6e28ULL,
26132 + 0x6e6b8c0f1807cf2fULL,
26133 + 0xdd45c0b11ba09040ULL,
26134 + 0x9aefba58b0476f74ULL,
26135 + 0x29c1f6e6b3e0301bULL,
26136 + 0xc96c5795d7870f42ULL,
26137 + 0x7a421b2bd420502dULL,
26138 + 0x3de861c27fc7af19ULL,
26139 + 0x8ec62d7c7c60f076ULL,
26140 + 0xb2bc941128085171ULL,
26141 + 0x0192d8af2baf0e1eULL,
26142 + 0x4638a2468048f12aULL,
26143 + 0xf516eef883efae45ULL,
26144 + 0x3ecdd09c2899b324ULL,
26145 + 0x8de39c222b3eec4bULL,
26146 + 0xca49e6cb80d9137fULL,
26147 + 0x7967aa75837e4c10ULL,
26148 + 0x451d1318d716ed17ULL,
26149 + 0xf6335fa6d4b1b278ULL,
26150 + 0xb199254f7f564d4cULL,
26151 + 0x02b769f17cf11223ULL,
26152 + 0xb4f7f6ad86b4690bULL,
26153 + 0x07d9ba1385133664ULL,
26154 + 0x4073c0fa2ef4c950ULL,
26155 + 0xf35d8c442d53963fULL,
26156 + 0xcf273529793b3738ULL,
26157 + 0x7c0979977a9c6857ULL,
26158 + 0x3ba3037ed17b9763ULL,
26159 + 0x888d4fc0d2dcc80cULL,
26160 + 0x435671a479aad56dULL,
26161 + 0xf0783d1a7a0d8a02ULL,
26162 + 0xb7d247f3d1ea7536ULL,
26163 + 0x04fc0b4dd24d2a59ULL,
26164 + 0x3886b22086258b5eULL,
26165 + 0x8ba8fe9e8582d431ULL,
26166 + 0xcc0284772e652b05ULL,
26167 + 0x7f2cc8c92dc2746aULL,
26168 + 0x325b15e575e1c3d0ULL,
26169 + 0x8175595b76469cbfULL,
26170 + 0xc6df23b2dda1638bULL,
26171 + 0x75f16f0cde063ce4ULL,
26172 + 0x498bd6618a6e9de3ULL,
26173 + 0xfaa59adf89c9c28cULL,
26174 + 0xbd0fe036222e3db8ULL,
26175 + 0x0e21ac88218962d7ULL,
26176 + 0xc5fa92ec8aff7fb6ULL,
26177 + 0x76d4de52895820d9ULL,
26178 + 0x317ea4bb22bfdfedULL,
26179 + 0x8250e80521188082ULL,
26180 + 0xbe2a516875702185ULL,
26181 + 0x0d041dd676d77eeaULL,
26182 + 0x4aae673fdd3081deULL,
26183 + 0xf9802b81de97deb1ULL,
26184 + 0x4fc0b4dd24d2a599ULL,
26185 + 0xfceef8632775faf6ULL,
26186 + 0xbb44828a8c9205c2ULL,
26187 + 0x086ace348f355aadULL,
26188 + 0x34107759db5dfbaaULL,
26189 + 0x873e3be7d8faa4c5ULL,
26190 + 0xc094410e731d5bf1ULL,
26191 + 0x73ba0db070ba049eULL,
26192 + 0xb86133d4dbcc19ffULL,
26193 + 0x0b4f7f6ad86b4690ULL,
26194 + 0x4ce50583738cb9a4ULL,
26195 + 0xffcb493d702be6cbULL,
26196 + 0xc3b1f050244347ccULL,
26197 + 0x709fbcee27e418a3ULL,
26198 + 0x3735c6078c03e797ULL,
26199 + 0x841b8ab98fa4b8f8ULL,
26200 + 0xadda7c5f3c4488e3ULL,
26201 + 0x1ef430e13fe3d78cULL,
26202 + 0x595e4a08940428b8ULL,
26203 + 0xea7006b697a377d7ULL,
26204 + 0xd60abfdbc3cbd6d0ULL,
26205 + 0x6524f365c06c89bfULL,
26206 + 0x228e898c6b8b768bULL,
26207 + 0x91a0c532682c29e4ULL,
26208 + 0x5a7bfb56c35a3485ULL,
26209 + 0xe955b7e8c0fd6beaULL,
26210 + 0xaeffcd016b1a94deULL,
26211 + 0x1dd181bf68bdcbb1ULL,
26212 + 0x21ab38d23cd56ab6ULL,
26213 + 0x9285746c3f7235d9ULL,
26214 + 0xd52f0e859495caedULL,
26215 + 0x6601423b97329582ULL,
26216 + 0xd041dd676d77eeaaULL,
26217 + 0x636f91d96ed0b1c5ULL,
26218 + 0x24c5eb30c5374ef1ULL,
26219 + 0x97eba78ec690119eULL,
26220 + 0xab911ee392f8b099ULL,
26221 + 0x18bf525d915feff6ULL,
26222 + 0x5f1528b43ab810c2ULL,
26223 + 0xec3b640a391f4fadULL,
26224 + 0x27e05a6e926952ccULL,
26225 + 0x94ce16d091ce0da3ULL,
26226 + 0xd3646c393a29f297ULL,
26227 + 0x604a2087398eadf8ULL,
26228 + 0x5c3099ea6de60cffULL,
26229 + 0xef1ed5546e415390ULL,
26230 + 0xa8b4afbdc5a6aca4ULL,
26231 + 0x1b9ae303c601f3cbULL,
26232 + 0x56ed3e2f9e224471ULL,
26233 + 0xe5c372919d851b1eULL,
26234 + 0xa26908783662e42aULL,
26235 + 0x114744c635c5bb45ULL,
26236 + 0x2d3dfdab61ad1a42ULL,
26237 + 0x9e13b115620a452dULL,
26238 + 0xd9b9cbfcc9edba19ULL,
26239 + 0x6a978742ca4ae576ULL,
26240 + 0xa14cb926613cf817ULL,
26241 + 0x1262f598629ba778ULL,
26242 + 0x55c88f71c97c584cULL,
26243 + 0xe6e6c3cfcadb0723ULL,
26244 + 0xda9c7aa29eb3a624ULL,
26245 + 0x69b2361c9d14f94bULL,
26246 + 0x2e184cf536f3067fULL,
26247 + 0x9d36004b35545910ULL,
26248 + 0x2b769f17cf112238ULL,
26249 + 0x9858d3a9ccb67d57ULL,
26250 + 0xdff2a94067518263ULL,
26251 + 0x6cdce5fe64f6dd0cULL,
26252 + 0x50a65c93309e7c0bULL,
26253 + 0xe388102d33392364ULL,
26254 + 0xa4226ac498dedc50ULL,
26255 + 0x170c267a9b79833fULL,
26256 + 0xdcd7181e300f9e5eULL,
26257 + 0x6ff954a033a8c131ULL,
26258 + 0x28532e49984f3e05ULL,
26259 + 0x9b7d62f79be8616aULL,
26260 + 0xa707db9acf80c06dULL,
26261 + 0x14299724cc279f02ULL,
26262 + 0x5383edcd67c06036ULL,
26263 + 0xe0ada17364673f59ULL
26264 + }
26265 +};
26266 +
26267 +
26268 +/**
26269 + \brief Initializes the crc seed
26270 + */
26271 +static __inline__ uint64_t crc64_init(void)
26272 +{
26273 + return CRC64_ECMA_182.initial;
26274 +}
26275 +
26276 +/**
26277 + \brief Computes 64 bit the crc
26278 + \param[in] data Pointer to the Data in the frame
26279 + \param[in] len Length of the Data
26280 + \param[in] crc seed
26281 + \return calculated crc
26282 + */
26283 +static __inline__ uint64_t crc64_compute(void const *data,
26284 + uint32_t len,
26285 + uint64_t seed)
26286 +{
26287 + uint32_t i;
26288 + uint64_t crc = seed;
26289 + uint8_t *bdata = (uint8_t *) data;
26290 +
26291 + for (i = 0; i < len; i++)
26292 + crc =
26293 + CRC64_ECMA_182.
26294 + table[(crc ^ *bdata++) & CRC64_BYTE_MASK] ^ (crc >> 8);
26295 +
26296 + return crc;
26297 +}
26298 +
26299 +
26300 +#endif /* __CRC64_H */
26301 --- /dev/null
26302 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/fm_cc.c
26303 @@ -0,0 +1,7582 @@
26304 +/*
26305 + * Copyright 2008-2012 Freescale Semiconductor Inc.
26306 + *
26307 + * Redistribution and use in source and binary forms, with or without
26308 + * modification, are permitted provided that the following conditions are met:
26309 + * * Redistributions of source code must retain the above copyright
26310 + * notice, this list of conditions and the following disclaimer.
26311 + * * Redistributions in binary form must reproduce the above copyright
26312 + * notice, this list of conditions and the following disclaimer in the
26313 + * documentation and/or other materials provided with the distribution.
26314 + * * Neither the name of Freescale Semiconductor nor the
26315 + * names of its contributors may be used to endorse or promote products
26316 + * derived from this software without specific prior written permission.
26317 + *
26318 + *
26319 + * ALTERNATIVELY, this software may be distributed under the terms of the
26320 + * GNU General Public License ("GPL") as published by the Free Software
26321 + * Foundation, either version 2 of that License or (at your option) any
26322 + * later version.
26323 + *
26324 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
26325 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
26326 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
26327 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
26328 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
26329 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
26330 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
26331 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26332 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
26333 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26334 + */
26335 +
26336 +
26337 +/******************************************************************************
26338 + @File fm_cc.c
26339 +
26340 + @Description FM Coarse Classifier implementation
26341 + *//***************************************************************************/
26342 +#include <linux/math64.h>
26343 +#include "std_ext.h"
26344 +#include "error_ext.h"
26345 +#include "string_ext.h"
26346 +#include "debug_ext.h"
26347 +#include "fm_pcd_ext.h"
26348 +#include "fm_muram_ext.h"
26349 +
26350 +#include "fm_common.h"
26351 +#include "fm_pcd.h"
26352 +#include "fm_hc.h"
26353 +#include "fm_cc.h"
26354 +#include "crc64.h"
26355 +
26356 +/****************************************/
26357 +/* static functions */
26358 +/****************************************/
26359 +
26360 +
26361 +static t_Error CcRootTryLock(t_Handle h_FmPcdCcTree)
26362 +{
26363 + t_FmPcdCcTree *p_FmPcdCcTree = (t_FmPcdCcTree *)h_FmPcdCcTree;
26364 +
26365 + ASSERT_COND(h_FmPcdCcTree);
26366 +
26367 + if (FmPcdLockTryLock(p_FmPcdCcTree->p_Lock))
26368 + return E_OK;
26369 +
26370 + return ERROR_CODE(E_BUSY);
26371 +}
26372 +
26373 +static void CcRootReleaseLock(t_Handle h_FmPcdCcTree)
26374 +{
26375 + t_FmPcdCcTree *p_FmPcdCcTree = (t_FmPcdCcTree *)h_FmPcdCcTree;
26376 +
26377 + ASSERT_COND(h_FmPcdCcTree);
26378 +
26379 + FmPcdLockUnlock(p_FmPcdCcTree->p_Lock);
26380 +}
26381 +
26382 +static void UpdateNodeOwner(t_FmPcdCcNode *p_CcNode, bool add)
26383 +{
26384 + uint32_t intFlags;
26385 +
26386 + ASSERT_COND(p_CcNode);
26387 +
26388 + intFlags = XX_LockIntrSpinlock(p_CcNode->h_Spinlock);
26389 +
26390 + if (add)
26391 + p_CcNode->owners++;
26392 + else
26393 + {
26394 + ASSERT_COND(p_CcNode->owners);
26395 + p_CcNode->owners--;
26396 + }
26397 +
26398 + XX_UnlockIntrSpinlock(p_CcNode->h_Spinlock, intFlags);
26399 +}
26400 +
26401 +static __inline__ t_FmPcdStatsObj* DequeueStatsObj(t_List *p_List)
26402 +{
26403 + t_FmPcdStatsObj *p_StatsObj = NULL;
26404 + t_List *p_Next;
26405 +
26406 + if (!LIST_IsEmpty(p_List))
26407 + {
26408 + p_Next = LIST_FIRST(p_List);
26409 + p_StatsObj = LIST_OBJECT(p_Next, t_FmPcdStatsObj, node);
26410 + ASSERT_COND(p_StatsObj);
26411 + LIST_DelAndInit(p_Next);
26412 + }
26413 +
26414 + return p_StatsObj;
26415 +}
26416 +
26417 +static __inline__ void EnqueueStatsObj(t_List *p_List,
26418 + t_FmPcdStatsObj *p_StatsObj)
26419 +{
26420 + LIST_AddToTail(&p_StatsObj->node, p_List);
26421 +}
26422 +
26423 +static void FreeStatObjects(t_List *p_List, t_Handle h_FmMuram)
26424 +{
26425 + t_FmPcdStatsObj *p_StatsObj;
26426 +
26427 + while (!LIST_IsEmpty(p_List))
26428 + {
26429 + p_StatsObj = DequeueStatsObj(p_List);
26430 + ASSERT_COND(p_StatsObj);
26431 +
26432 + FM_MURAM_FreeMem(h_FmMuram, p_StatsObj->h_StatsAd);
26433 + FM_MURAM_FreeMem(h_FmMuram, p_StatsObj->h_StatsCounters);
26434 +
26435 + XX_Free(p_StatsObj);
26436 + }
26437 +}
26438 +
26439 +static t_FmPcdStatsObj* GetStatsObj(t_FmPcdCcNode *p_CcNode)
26440 +{
26441 + t_FmPcdStatsObj* p_StatsObj;
26442 + t_Handle h_FmMuram;
26443 +
26444 + ASSERT_COND(p_CcNode);
26445 +
26446 + /* If 'maxNumOfKeys' was passed, all statistics object were preallocated
26447 + upon node initialization */
26448 + if (p_CcNode->maxNumOfKeys)
26449 + {
26450 + p_StatsObj = DequeueStatsObj(&p_CcNode->availableStatsLst);
26451 +
26452 + /* Clean statistics counters & ADs */
26453 + MemSet8(p_StatsObj->h_StatsAd, 0, FM_PCD_CC_AD_ENTRY_SIZE);
26454 + MemSet8(p_StatsObj->h_StatsCounters, 0, p_CcNode->countersArraySize);
26455 + }
26456 + else
26457 + {
26458 + h_FmMuram = ((t_FmPcd *)(p_CcNode->h_FmPcd))->h_FmMuram;
26459 + ASSERT_COND(h_FmMuram);
26460 +
26461 + p_StatsObj = XX_Malloc(sizeof(t_FmPcdStatsObj));
26462 + if (!p_StatsObj)
26463 + {
26464 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("statistics object"));
26465 + return NULL;
26466 + }
26467 +
26468 + p_StatsObj->h_StatsAd = (t_Handle)FM_MURAM_AllocMem(
26469 + h_FmMuram, FM_PCD_CC_AD_ENTRY_SIZE, FM_PCD_CC_AD_TABLE_ALIGN);
26470 + if (!p_StatsObj->h_StatsAd)
26471 + {
26472 + XX_Free(p_StatsObj);
26473 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("MURAM allocation for statistics ADs"));
26474 + return NULL;
26475 + }
26476 + MemSet8(p_StatsObj->h_StatsAd, 0, FM_PCD_CC_AD_ENTRY_SIZE);
26477 +
26478 + p_StatsObj->h_StatsCounters = (t_Handle)FM_MURAM_AllocMem(
26479 + h_FmMuram, p_CcNode->countersArraySize,
26480 + FM_PCD_CC_AD_TABLE_ALIGN);
26481 + if (!p_StatsObj->h_StatsCounters)
26482 + {
26483 + FM_MURAM_FreeMem(h_FmMuram, p_StatsObj->h_StatsAd);
26484 + XX_Free(p_StatsObj);
26485 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("MURAM allocation for statistics counters"));
26486 + return NULL;
26487 + }
26488 + MemSet8(p_StatsObj->h_StatsCounters, 0, p_CcNode->countersArraySize);
26489 + }
26490 +
26491 + return p_StatsObj;
26492 +}
26493 +
26494 +static void PutStatsObj(t_FmPcdCcNode *p_CcNode, t_FmPcdStatsObj *p_StatsObj)
26495 +{
26496 + t_Handle h_FmMuram;
26497 +
26498 + ASSERT_COND(p_CcNode);
26499 + ASSERT_COND(p_StatsObj);
26500 +
26501 + /* If 'maxNumOfKeys' was passed, all statistics object were preallocated
26502 + upon node initialization and now will be enqueued back to the list */
26503 + if (p_CcNode->maxNumOfKeys)
26504 + {
26505 + /* Clean statistics counters */
26506 + MemSet8(p_StatsObj->h_StatsCounters, 0, p_CcNode->countersArraySize);
26507 +
26508 + /* Clean statistics ADs */
26509 + MemSet8(p_StatsObj->h_StatsAd, 0, FM_PCD_CC_AD_ENTRY_SIZE);
26510 +
26511 + EnqueueStatsObj(&p_CcNode->availableStatsLst, p_StatsObj);
26512 + }
26513 + else
26514 + {
26515 + h_FmMuram = ((t_FmPcd *)(p_CcNode->h_FmPcd))->h_FmMuram;
26516 + ASSERT_COND(h_FmMuram);
26517 +
26518 + FM_MURAM_FreeMem(h_FmMuram, p_StatsObj->h_StatsAd);
26519 + FM_MURAM_FreeMem(h_FmMuram, p_StatsObj->h_StatsCounters);
26520 +
26521 + XX_Free(p_StatsObj);
26522 + }
26523 +}
26524 +
26525 +static void SetStatsCounters(t_AdOfTypeStats *p_StatsAd,
26526 + uint32_t statsCountersAddr)
26527 +{
26528 + uint32_t tmp = (statsCountersAddr & FM_PCD_AD_STATS_COUNTERS_ADDR_MASK);
26529 +
26530 + WRITE_UINT32(p_StatsAd->statsTableAddr, tmp);
26531 +}
26532 +
26533 +
26534 +static void UpdateStatsAd(t_FmPcdCcStatsParams *p_FmPcdCcStatsParams,
26535 + t_Handle h_Ad, uint64_t physicalMuramBase)
26536 +{
26537 + t_AdOfTypeStats *p_StatsAd;
26538 + uint32_t statsCountersAddr, nextActionAddr, tmp;
26539 +#if (DPAA_VERSION >= 11)
26540 + uint32_t frameLengthRangesAddr;
26541 +#endif /* (DPAA_VERSION >= 11) */
26542 +
26543 + p_StatsAd = (t_AdOfTypeStats *)p_FmPcdCcStatsParams->h_StatsAd;
26544 +
26545 + tmp = FM_PCD_AD_STATS_TYPE;
26546 +
26547 +#if (DPAA_VERSION >= 11)
26548 + if (p_FmPcdCcStatsParams->h_StatsFLRs)
26549 + {
26550 + frameLengthRangesAddr = (uint32_t)((XX_VirtToPhys(
26551 + p_FmPcdCcStatsParams->h_StatsFLRs) - physicalMuramBase));
26552 + tmp |= (frameLengthRangesAddr & FM_PCD_AD_STATS_FLR_ADDR_MASK);
26553 + }
26554 +#endif /* (DPAA_VERSION >= 11) */
26555 + WRITE_UINT32(p_StatsAd->profileTableAddr, tmp);
26556 +
26557 + nextActionAddr = (uint32_t)((XX_VirtToPhys(h_Ad) - physicalMuramBase));
26558 + tmp = 0;
26559 + tmp |= (uint32_t)((nextActionAddr << FM_PCD_AD_STATS_NEXT_ACTION_SHIFT)
26560 + & FM_PCD_AD_STATS_NEXT_ACTION_MASK);
26561 + tmp |= (FM_PCD_AD_STATS_NAD_EN | FM_PCD_AD_STATS_OP_CODE);
26562 +
26563 +#if (DPAA_VERSION >= 11)
26564 + if (p_FmPcdCcStatsParams->h_StatsFLRs)
26565 + tmp |= FM_PCD_AD_STATS_FLR_EN;
26566 +#endif /* (DPAA_VERSION >= 11) */
26567 +
26568 + WRITE_UINT32(p_StatsAd->nextActionIndx, tmp);
26569 +
26570 + statsCountersAddr = (uint32_t)((XX_VirtToPhys(
26571 + p_FmPcdCcStatsParams->h_StatsCounters) - physicalMuramBase));
26572 + SetStatsCounters(p_StatsAd, statsCountersAddr);
26573 +}
26574 +
26575 +static void FillAdOfTypeContLookup(t_Handle h_Ad,
26576 + t_FmPcdCcStatsParams *p_FmPcdCcStatsParams,
26577 + t_Handle h_FmPcd, t_Handle p_CcNode,
26578 + t_Handle h_Manip, t_Handle h_FrmReplic)
26579 +{
26580 + t_FmPcdCcNode *p_Node = (t_FmPcdCcNode *)p_CcNode;
26581 + t_AdOfTypeContLookup *p_AdContLookup = (t_AdOfTypeContLookup *)h_Ad;
26582 + t_Handle h_TmpAd;
26583 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
26584 + uint32_t tmpReg32;
26585 + t_Handle p_AdNewPtr = NULL;
26586 +
26587 + UNUSED(h_Manip);
26588 + UNUSED(h_FrmReplic);
26589 +
26590 + /* there are 3 cases handled in this routine of building a "Continue lookup" type AD.
26591 + * Case 1: No Manip. The action descriptor is built within the match table.
26592 + * p_AdResult = p_AdNewPtr;
26593 + * Case 2: Manip exists. A new AD is created - p_AdNewPtr. It is initialized
26594 + * either in the FmPcdManipUpdateAdResultForCc routine or it was already
26595 + * initialized and returned here.
26596 + * p_AdResult (within the match table) will be initialized after
26597 + * this routine returns and point to the existing AD.
26598 + * Case 3: Manip exists. The action descriptor is built within the match table.
26599 + * FmPcdManipUpdateAdContLookupForCc returns a NULL p_AdNewPtr.
26600 + */
26601 +
26602 + /* As default, the "new" ptr is the current one. i.e. the content of the result
26603 + * AD will be written into the match table itself (case (1))*/
26604 + p_AdNewPtr = p_AdContLookup;
26605 +
26606 + /* Initialize an action descriptor, if current statistics mode requires an Ad */
26607 + if (p_FmPcdCcStatsParams)
26608 + {
26609 + ASSERT_COND(p_FmPcdCcStatsParams->h_StatsAd);
26610 + ASSERT_COND(p_FmPcdCcStatsParams->h_StatsCounters);
26611 +
26612 + /* Swapping addresses between statistics Ad and the current lookup AD */
26613 + h_TmpAd = p_FmPcdCcStatsParams->h_StatsAd;
26614 + p_FmPcdCcStatsParams->h_StatsAd = h_Ad;
26615 + h_Ad = h_TmpAd;
26616 +
26617 + p_AdNewPtr = h_Ad;
26618 + p_AdContLookup = h_Ad;
26619 +
26620 + /* Init statistics Ad and connect current lookup AD as 'next action' from statistics Ad */
26621 + UpdateStatsAd(p_FmPcdCcStatsParams, h_Ad, p_FmPcd->physicalMuramBase);
26622 + }
26623 +
26624 +#if DPAA_VERSION >= 11
26625 + if (h_Manip && h_FrmReplic)
26626 + FmPcdManipUpdateAdContLookupForCc(
26627 + h_Manip,
26628 + h_Ad,
26629 + &p_AdNewPtr,
26630 + (uint32_t)((XX_VirtToPhys(
26631 + FrmReplicGroupGetSourceTableDescriptor(h_FrmReplic))
26632 + - p_FmPcd->physicalMuramBase)));
26633 + else
26634 + if (h_FrmReplic)
26635 + FrmReplicGroupUpdateAd(h_FrmReplic, h_Ad, &p_AdNewPtr);
26636 + else
26637 +#endif /* (DPAA_VERSION >= 11) */
26638 + if (h_Manip)
26639 + FmPcdManipUpdateAdContLookupForCc(
26640 + h_Manip,
26641 + h_Ad,
26642 + &p_AdNewPtr,
26643 +
26644 +#ifdef FM_CAPWAP_SUPPORT
26645 + /*no check for opcode of manip - this step can be reached only with capwap_applic_specific*/
26646 + (uint32_t)((XX_VirtToPhys(p_Node->h_AdTable) - p_FmPcd->physicalMuramBase))
26647 +#else /* not FM_CAPWAP_SUPPORT */
26648 + (uint32_t)((XX_VirtToPhys(p_Node->h_Ad)
26649 + - p_FmPcd->physicalMuramBase))
26650 +#endif /* not FM_CAPWAP_SUPPORT */
26651 + );
26652 +
26653 + /* if (p_AdNewPtr = NULL) --> Done. (case (3)) */
26654 + if (p_AdNewPtr)
26655 + {
26656 + /* cases (1) & (2) */
26657 + tmpReg32 = 0;
26658 + tmpReg32 |= FM_PCD_AD_CONT_LOOKUP_TYPE;
26659 + tmpReg32 |=
26660 + p_Node->sizeOfExtraction ? ((p_Node->sizeOfExtraction - 1) << 24) :
26661 + 0;
26662 + tmpReg32 |= (uint32_t)(XX_VirtToPhys(p_Node->h_AdTable)
26663 + - p_FmPcd->physicalMuramBase);
26664 + WRITE_UINT32(p_AdContLookup->ccAdBase, tmpReg32);
26665 +
26666 + tmpReg32 = 0;
26667 + tmpReg32 |= p_Node->numOfKeys << 24;
26668 + tmpReg32 |= (p_Node->lclMask ? FM_PCD_AD_CONT_LOOKUP_LCL_MASK : 0);
26669 + tmpReg32 |=
26670 + p_Node->h_KeysMatchTable ? (uint32_t)(XX_VirtToPhys(
26671 + p_Node->h_KeysMatchTable) - p_FmPcd->physicalMuramBase) :
26672 + 0;
26673 + WRITE_UINT32(p_AdContLookup->matchTblPtr, tmpReg32);
26674 +
26675 + tmpReg32 = 0;
26676 + tmpReg32 |= p_Node->prsArrayOffset << 24;
26677 + tmpReg32 |= p_Node->offset << 16;
26678 + tmpReg32 |= p_Node->parseCode;
26679 + WRITE_UINT32(p_AdContLookup->pcAndOffsets, tmpReg32);
26680 +
26681 + MemCpy8((void*)&p_AdContLookup->gmask, p_Node->p_GlblMask,
26682 + CC_GLBL_MASK_SIZE);
26683 + }
26684 +}
26685 +
26686 +static t_Error AllocAndFillAdForContLookupManip(t_Handle h_CcNode)
26687 +{
26688 + t_FmPcdCcNode *p_CcNode = (t_FmPcdCcNode *)h_CcNode;
26689 + uint32_t intFlags;
26690 +
26691 + ASSERT_COND(p_CcNode);
26692 +
26693 + intFlags = XX_LockIntrSpinlock(p_CcNode->h_Spinlock);
26694 +
26695 + if (!p_CcNode->h_Ad)
26696 + {
26697 + if (p_CcNode->maxNumOfKeys)
26698 + p_CcNode->h_Ad = p_CcNode->h_TmpAd;
26699 + else
26700 + p_CcNode->h_Ad = (t_Handle)FM_MURAM_AllocMem(
26701 + ((t_FmPcd *)(p_CcNode->h_FmPcd))->h_FmMuram,
26702 + FM_PCD_CC_AD_ENTRY_SIZE, FM_PCD_CC_AD_TABLE_ALIGN);
26703 +
26704 + XX_UnlockIntrSpinlock(p_CcNode->h_Spinlock, intFlags);
26705 +
26706 + if (!p_CcNode->h_Ad)
26707 + RETURN_ERROR(MAJOR, E_NO_MEMORY,
26708 + ("MURAM allocation for CC action descriptor"));
26709 +
26710 + MemSet8(p_CcNode->h_Ad, 0, FM_PCD_CC_AD_ENTRY_SIZE);
26711 +
26712 + FillAdOfTypeContLookup(p_CcNode->h_Ad, NULL, p_CcNode->h_FmPcd,
26713 + p_CcNode, NULL, NULL);
26714 + }
26715 + else
26716 + XX_UnlockIntrSpinlock(p_CcNode->h_Spinlock, intFlags);
26717 +
26718 + return E_OK;
26719 +}
26720 +
26721 +static t_Error SetRequiredAction1(
26722 + t_Handle h_FmPcd, uint32_t requiredAction,
26723 + t_FmPcdCcKeyAndNextEngineParams *p_CcKeyAndNextEngineParamsTmp,
26724 + t_Handle h_AdTmp, uint16_t numOfEntries, t_Handle h_Tree)
26725 +{
26726 + t_AdOfTypeResult *p_AdTmp = (t_AdOfTypeResult *)h_AdTmp;
26727 + uint32_t tmpReg32;
26728 + t_Error err;
26729 + t_FmPcdCcNode *p_CcNode;
26730 + int i = 0;
26731 + uint16_t tmp = 0;
26732 + uint16_t profileId;
26733 + uint8_t relativeSchemeId, physicalSchemeId;
26734 + t_CcNodeInformation ccNodeInfo;
26735 +
26736 + for (i = 0; i < numOfEntries; i++)
26737 + {
26738 + if (i == 0)
26739 + h_AdTmp = PTR_MOVE(h_AdTmp, i*FM_PCD_CC_AD_ENTRY_SIZE);
26740 + else
26741 + h_AdTmp = PTR_MOVE(h_AdTmp, FM_PCD_CC_AD_ENTRY_SIZE);
26742 +
26743 + switch (p_CcKeyAndNextEngineParamsTmp[i].nextEngineParams.nextEngine)
26744 + {
26745 + case (e_FM_PCD_CC):
26746 + if (requiredAction)
26747 + {
26748 + p_CcNode =
26749 + p_CcKeyAndNextEngineParamsTmp[i].nextEngineParams.params.ccParams.h_CcNode;
26750 + ASSERT_COND(p_CcNode);
26751 + if (p_CcNode->shadowAction == requiredAction)
26752 + break;
26753 + if ((requiredAction & UPDATE_CC_WITH_TREE)
26754 + && !(p_CcNode->shadowAction & UPDATE_CC_WITH_TREE))
26755 + {
26756 +
26757 + memset(&ccNodeInfo, 0, sizeof(t_CcNodeInformation));
26758 + ccNodeInfo.h_CcNode = h_Tree;
26759 + EnqueueNodeInfoToRelevantLst(&p_CcNode->ccTreesLst,
26760 + &ccNodeInfo, NULL);
26761 + p_CcKeyAndNextEngineParamsTmp[i].shadowAction |=
26762 + UPDATE_CC_WITH_TREE;
26763 + }
26764 + if ((requiredAction & UPDATE_CC_SHADOW_CLEAR)
26765 + && !(p_CcNode->shadowAction & UPDATE_CC_SHADOW_CLEAR))
26766 + {
26767 +
26768 + p_CcNode->shadowAction = 0;
26769 + }
26770 +
26771 + if ((requiredAction & UPDATE_CC_WITH_DELETE_TREE)
26772 + && !(p_CcNode->shadowAction
26773 + & UPDATE_CC_WITH_DELETE_TREE))
26774 + {
26775 + DequeueNodeInfoFromRelevantLst(&p_CcNode->ccTreesLst,
26776 + h_Tree, NULL);
26777 + p_CcKeyAndNextEngineParamsTmp[i].shadowAction |=
26778 + UPDATE_CC_WITH_DELETE_TREE;
26779 + }
26780 + if (p_CcNode->keyAndNextEngineParams[p_CcNode->numOfKeys].nextEngineParams.nextEngine
26781 + != e_FM_PCD_INVALID)
26782 + tmp = (uint8_t)(p_CcNode->numOfKeys + 1);
26783 + else
26784 + tmp = p_CcNode->numOfKeys;
26785 + err = SetRequiredAction1(h_FmPcd, requiredAction,
26786 + p_CcNode->keyAndNextEngineParams,
26787 + p_CcNode->h_AdTable, tmp, h_Tree);
26788 + if (err != E_OK)
26789 + return err;
26790 + if (requiredAction != UPDATE_CC_SHADOW_CLEAR)
26791 + p_CcNode->shadowAction |= requiredAction;
26792 + }
26793 + break;
26794 +
26795 + case (e_FM_PCD_KG):
26796 + if ((requiredAction & UPDATE_NIA_ENQ_WITHOUT_DMA)
26797 + && !(p_CcKeyAndNextEngineParamsTmp[i].shadowAction
26798 + & UPDATE_NIA_ENQ_WITHOUT_DMA))
26799 + {
26800 + physicalSchemeId =
26801 + FmPcdKgGetSchemeId(
26802 + p_CcKeyAndNextEngineParamsTmp[i].nextEngineParams.params.kgParams.h_DirectScheme);
26803 + relativeSchemeId = FmPcdKgGetRelativeSchemeId(
26804 + h_FmPcd, physicalSchemeId);
26805 + if (relativeSchemeId == FM_PCD_KG_NUM_OF_SCHEMES)
26806 + RETURN_ERROR(MAJOR, E_NOT_IN_RANGE, NO_MSG);
26807 + if (!FmPcdKgIsSchemeValidSw(
26808 + p_CcKeyAndNextEngineParamsTmp[i].nextEngineParams.params.kgParams.h_DirectScheme))
26809 + RETURN_ERROR(MAJOR, E_INVALID_STATE,
26810 + ("Invalid direct scheme."));
26811 + if (!KgIsSchemeAlwaysDirect(h_FmPcd, relativeSchemeId))
26812 + RETURN_ERROR(
26813 + MAJOR, E_INVALID_STATE,
26814 + ("For this action scheme has to be direct."));
26815 + err =
26816 + FmPcdKgCcGetSetParams(
26817 + h_FmPcd,
26818 + p_CcKeyAndNextEngineParamsTmp[i].nextEngineParams.params.kgParams.h_DirectScheme,
26819 + requiredAction, 0);
26820 + if (err != E_OK)
26821 + RETURN_ERROR(MAJOR, err, NO_MSG);
26822 + p_CcKeyAndNextEngineParamsTmp[i].shadowAction |=
26823 + requiredAction;
26824 + }
26825 + break;
26826 +
26827 + case (e_FM_PCD_PLCR):
26828 + if ((requiredAction & UPDATE_NIA_ENQ_WITHOUT_DMA)
26829 + && !(p_CcKeyAndNextEngineParamsTmp[i].shadowAction
26830 + & UPDATE_NIA_ENQ_WITHOUT_DMA))
26831 + {
26832 + if (!p_CcKeyAndNextEngineParamsTmp[i].nextEngineParams.params.plcrParams.overrideParams)
26833 + RETURN_ERROR(
26834 + MAJOR,
26835 + E_NOT_SUPPORTED,
26836 + ("In this initialization only overrideFqid can be initialized"));
26837 + if (!p_CcKeyAndNextEngineParamsTmp[i].nextEngineParams.params.plcrParams.sharedProfile)
26838 + RETURN_ERROR(
26839 + MAJOR,
26840 + E_NOT_SUPPORTED,
26841 + ("In this initialization only overrideFqid can be initialized"));
26842 + err =
26843 + FmPcdPlcrGetAbsoluteIdByProfileParams(
26844 + h_FmPcd,
26845 + e_FM_PCD_PLCR_SHARED,
26846 + NULL,
26847 + p_CcKeyAndNextEngineParamsTmp[i].nextEngineParams.params.plcrParams.newRelativeProfileId,
26848 + &profileId);
26849 + if (err != E_OK)
26850 + RETURN_ERROR(MAJOR, err, NO_MSG);
26851 + err = FmPcdPlcrCcGetSetParams(h_FmPcd, profileId,
26852 + requiredAction);
26853 + if (err != E_OK)
26854 + RETURN_ERROR(MAJOR, err, NO_MSG);
26855 + p_CcKeyAndNextEngineParamsTmp[i].shadowAction |=
26856 + requiredAction;
26857 + }
26858 + break;
26859 +
26860 + case (e_FM_PCD_DONE):
26861 + if ((requiredAction & UPDATE_NIA_ENQ_WITHOUT_DMA)
26862 + && !(p_CcKeyAndNextEngineParamsTmp[i].shadowAction
26863 + & UPDATE_NIA_ENQ_WITHOUT_DMA))
26864 + {
26865 + tmpReg32 = GET_UINT32(p_AdTmp->nia);
26866 + if ((tmpReg32 & GET_NIA_BMI_AC_ENQ_FRAME(h_FmPcd))
26867 + != GET_NIA_BMI_AC_ENQ_FRAME(h_FmPcd))
26868 + RETURN_ERROR(
26869 + MAJOR,
26870 + E_INVALID_STATE,
26871 + ("Next engine was previously assigned not as PCD_DONE"));
26872 + tmpReg32 |= NIA_BMI_AC_ENQ_FRAME_WITHOUT_DMA;
26873 + WRITE_UINT32(p_AdTmp->nia, tmpReg32);
26874 + p_CcKeyAndNextEngineParamsTmp[i].shadowAction |=
26875 + requiredAction;
26876 + }
26877 + break;
26878 +
26879 + default:
26880 + break;
26881 + }
26882 + }
26883 +
26884 + return E_OK;
26885 +}
26886 +
26887 +static t_Error SetRequiredAction(
26888 + t_Handle h_FmPcd, uint32_t requiredAction,
26889 + t_FmPcdCcKeyAndNextEngineParams *p_CcKeyAndNextEngineParamsTmp,
26890 + t_Handle h_AdTmp, uint16_t numOfEntries, t_Handle h_Tree)
26891 +{
26892 + t_Error err = SetRequiredAction1(h_FmPcd, requiredAction,
26893 + p_CcKeyAndNextEngineParamsTmp, h_AdTmp,
26894 + numOfEntries, h_Tree);
26895 + if (err != E_OK)
26896 + return err;
26897 + return SetRequiredAction1(h_FmPcd, UPDATE_CC_SHADOW_CLEAR,
26898 + p_CcKeyAndNextEngineParamsTmp, h_AdTmp,
26899 + numOfEntries, h_Tree);
26900 +}
26901 +
26902 +static t_Error ReleaseModifiedDataStructure(
26903 + t_Handle h_FmPcd, t_List *h_FmPcdOldPointersLst,
26904 + t_List *h_FmPcdNewPointersLst,
26905 + t_FmPcdModifyCcKeyAdditionalParams *p_AdditionalParams,
26906 + bool useShadowStructs)
26907 +{
26908 + t_List *p_Pos;
26909 + t_Error err = E_OK;
26910 + t_CcNodeInformation ccNodeInfo, *p_CcNodeInformation;
26911 + t_Handle h_Muram;
26912 + t_FmPcdCcNode *p_FmPcdCcNextNode, *p_FmPcdCcWorkingOnNode;
26913 + t_List *p_UpdateLst;
26914 + uint32_t intFlags;
26915 +
26916 + SANITY_CHECK_RETURN_ERROR(h_FmPcd, E_INVALID_HANDLE);
26917 + SANITY_CHECK_RETURN_ERROR(p_AdditionalParams->h_CurrentNode,
26918 + E_INVALID_HANDLE);
26919 + SANITY_CHECK_RETURN_ERROR(h_FmPcdOldPointersLst, E_INVALID_HANDLE);
26920 + SANITY_CHECK_RETURN_ERROR(h_FmPcdNewPointersLst, E_INVALID_HANDLE);
26921 +
26922 + /* We don't update subtree of the new node with new tree because it was done in the previous stage */
26923 + if (p_AdditionalParams->h_NodeForAdd)
26924 + {
26925 + p_FmPcdCcNextNode = (t_FmPcdCcNode*)p_AdditionalParams->h_NodeForAdd;
26926 +
26927 + if (!p_AdditionalParams->tree)
26928 + p_UpdateLst = &p_FmPcdCcNextNode->ccPrevNodesLst;
26929 + else
26930 + p_UpdateLst = &p_FmPcdCcNextNode->ccTreeIdLst;
26931 +
26932 + p_CcNodeInformation = FindNodeInfoInReleventLst(
26933 + p_UpdateLst, p_AdditionalParams->h_CurrentNode,
26934 + p_FmPcdCcNextNode->h_Spinlock);
26935 +
26936 + if (p_CcNodeInformation)
26937 + p_CcNodeInformation->index++;
26938 + else
26939 + {
26940 + memset(&ccNodeInfo, 0, sizeof(t_CcNodeInformation));
26941 + ccNodeInfo.h_CcNode = (t_Handle)p_AdditionalParams->h_CurrentNode;
26942 + ccNodeInfo.index = 1;
26943 + EnqueueNodeInfoToRelevantLst(p_UpdateLst, &ccNodeInfo,
26944 + p_FmPcdCcNextNode->h_Spinlock);
26945 + }
26946 + if (p_AdditionalParams->h_ManipForAdd)
26947 + {
26948 + p_CcNodeInformation = FindNodeInfoInReleventLst(
26949 + FmPcdManipGetNodeLstPointedOnThisManip(
26950 + p_AdditionalParams->h_ManipForAdd),
26951 + p_AdditionalParams->h_CurrentNode,
26952 + FmPcdManipGetSpinlock(p_AdditionalParams->h_ManipForAdd));
26953 +
26954 + if (p_CcNodeInformation)
26955 + p_CcNodeInformation->index++;
26956 + else
26957 + {
26958 + memset(&ccNodeInfo, 0, sizeof(t_CcNodeInformation));
26959 + ccNodeInfo.h_CcNode =
26960 + (t_Handle)p_AdditionalParams->h_CurrentNode;
26961 + ccNodeInfo.index = 1;
26962 + EnqueueNodeInfoToRelevantLst(
26963 + FmPcdManipGetNodeLstPointedOnThisManip(
26964 + p_AdditionalParams->h_ManipForAdd),
26965 + &ccNodeInfo,
26966 + FmPcdManipGetSpinlock(
26967 + p_AdditionalParams->h_ManipForAdd));
26968 + }
26969 + }
26970 + }
26971 +
26972 + if (p_AdditionalParams->h_NodeForRmv)
26973 + {
26974 + p_FmPcdCcNextNode = (t_FmPcdCcNode*)p_AdditionalParams->h_NodeForRmv;
26975 +
26976 + if (!p_AdditionalParams->tree)
26977 + {
26978 + p_UpdateLst = &p_FmPcdCcNextNode->ccPrevNodesLst;
26979 + p_FmPcdCcWorkingOnNode =
26980 + (t_FmPcdCcNode *)(p_AdditionalParams->h_CurrentNode);
26981 +
26982 + for (p_Pos = LIST_FIRST(&p_FmPcdCcWorkingOnNode->ccTreesLst);
26983 + p_Pos != (&p_FmPcdCcWorkingOnNode->ccTreesLst); p_Pos =
26984 + LIST_NEXT(p_Pos))
26985 + {
26986 + p_CcNodeInformation = CC_NODE_F_OBJECT(p_Pos);
26987 +
26988 + ASSERT_COND(p_CcNodeInformation->h_CcNode);
26989 +
26990 + err =
26991 + SetRequiredAction(
26992 + h_FmPcd,
26993 + UPDATE_CC_WITH_DELETE_TREE,
26994 + &((t_FmPcdCcNode *)(p_AdditionalParams->h_CurrentNode))->keyAndNextEngineParams[p_AdditionalParams->savedKeyIndex],
26995 + PTR_MOVE(((t_FmPcdCcNode *)(p_AdditionalParams->h_CurrentNode))->h_AdTable, p_AdditionalParams->savedKeyIndex*FM_PCD_CC_AD_ENTRY_SIZE),
26996 + 1, p_CcNodeInformation->h_CcNode);
26997 + }
26998 + }
26999 + else
27000 + {
27001 + p_UpdateLst = &p_FmPcdCcNextNode->ccTreeIdLst;
27002 +
27003 + err =
27004 + SetRequiredAction(
27005 + h_FmPcd,
27006 + UPDATE_CC_WITH_DELETE_TREE,
27007 + &((t_FmPcdCcTree *)(p_AdditionalParams->h_CurrentNode))->keyAndNextEngineParams[p_AdditionalParams->savedKeyIndex],
27008 + UINT_TO_PTR(((t_FmPcdCcTree *)(p_AdditionalParams->h_CurrentNode))->ccTreeBaseAddr + p_AdditionalParams->savedKeyIndex*FM_PCD_CC_AD_ENTRY_SIZE),
27009 + 1, p_AdditionalParams->h_CurrentNode);
27010 + }
27011 + if (err)
27012 + return err;
27013 +
27014 + /* We remove from the subtree of the removed node tree because it wasn't done in the previous stage
27015 + Update ccPrevNodesLst or ccTreeIdLst of the removed node
27016 + Update of the node owner */
27017 + p_CcNodeInformation = FindNodeInfoInReleventLst(
27018 + p_UpdateLst, p_AdditionalParams->h_CurrentNode,
27019 + p_FmPcdCcNextNode->h_Spinlock);
27020 +
27021 + ASSERT_COND(p_CcNodeInformation);
27022 + ASSERT_COND(p_CcNodeInformation->index);
27023 +
27024 + p_CcNodeInformation->index--;
27025 +
27026 + if (p_CcNodeInformation->index == 0)
27027 + DequeueNodeInfoFromRelevantLst(p_UpdateLst,
27028 + p_AdditionalParams->h_CurrentNode,
27029 + p_FmPcdCcNextNode->h_Spinlock);
27030 +
27031 + UpdateNodeOwner(p_FmPcdCcNextNode, FALSE);
27032 +
27033 + if (p_AdditionalParams->h_ManipForRmv)
27034 + {
27035 + p_CcNodeInformation = FindNodeInfoInReleventLst(
27036 + FmPcdManipGetNodeLstPointedOnThisManip(
27037 + p_AdditionalParams->h_ManipForRmv),
27038 + p_AdditionalParams->h_CurrentNode,
27039 + FmPcdManipGetSpinlock(p_AdditionalParams->h_ManipForRmv));
27040 +
27041 + ASSERT_COND(p_CcNodeInformation);
27042 + ASSERT_COND(p_CcNodeInformation->index);
27043 +
27044 + p_CcNodeInformation->index--;
27045 +
27046 + if (p_CcNodeInformation->index == 0)
27047 + DequeueNodeInfoFromRelevantLst(
27048 + FmPcdManipGetNodeLstPointedOnThisManip(
27049 + p_AdditionalParams->h_ManipForRmv),
27050 + p_AdditionalParams->h_CurrentNode,
27051 + FmPcdManipGetSpinlock(
27052 + p_AdditionalParams->h_ManipForRmv));
27053 + }
27054 + }
27055 +
27056 + if (p_AdditionalParams->h_ManipForRmv)
27057 + FmPcdManipUpdateOwner(p_AdditionalParams->h_ManipForRmv, FALSE);
27058 +
27059 + if (p_AdditionalParams->p_StatsObjForRmv)
27060 + PutStatsObj((t_FmPcdCcNode *)(p_AdditionalParams->h_CurrentNode),
27061 + p_AdditionalParams->p_StatsObjForRmv);
27062 +
27063 +#if (DPAA_VERSION >= 11)
27064 + if (p_AdditionalParams->h_FrmReplicForRmv)
27065 + FrmReplicGroupUpdateOwner(p_AdditionalParams->h_FrmReplicForRmv,
27066 + FALSE/* remove */);
27067 +#endif /* (DPAA_VERSION >= 11) */
27068 +
27069 + if (!useShadowStructs)
27070 + {
27071 + h_Muram = FmPcdGetMuramHandle(h_FmPcd);
27072 + ASSERT_COND(h_Muram);
27073 +
27074 + if ((p_AdditionalParams->tree && !((t_FmPcd *)h_FmPcd)->p_CcShadow)
27075 + || (!p_AdditionalParams->tree
27076 + && !((t_FmPcdCcNode *)(p_AdditionalParams->h_CurrentNode))->maxNumOfKeys))
27077 + {
27078 + /* We release new AD which was allocated and updated for copy from to actual AD */
27079 + for (p_Pos = LIST_FIRST(h_FmPcdNewPointersLst);
27080 + p_Pos != (h_FmPcdNewPointersLst); p_Pos = LIST_NEXT(p_Pos))
27081 + {
27082 +
27083 + p_CcNodeInformation = CC_NODE_F_OBJECT(p_Pos);
27084 + ASSERT_COND(p_CcNodeInformation->h_CcNode);
27085 + FM_MURAM_FreeMem(h_Muram, p_CcNodeInformation->h_CcNode);
27086 + }
27087 + }
27088 +
27089 + /* Free Old data structure if it has to be freed - new data structure was allocated*/
27090 + if (p_AdditionalParams->p_AdTableOld)
27091 + FM_MURAM_FreeMem(h_Muram, p_AdditionalParams->p_AdTableOld);
27092 +
27093 + if (p_AdditionalParams->p_KeysMatchTableOld)
27094 + FM_MURAM_FreeMem(h_Muram, p_AdditionalParams->p_KeysMatchTableOld);
27095 + }
27096 +
27097 + /* Update current modified node with changed fields if it's required*/
27098 + if (!p_AdditionalParams->tree)
27099 + {
27100 + if (p_AdditionalParams->p_AdTableNew)
27101 + ((t_FmPcdCcNode *)(p_AdditionalParams->h_CurrentNode))->h_AdTable =
27102 + p_AdditionalParams->p_AdTableNew;
27103 +
27104 + if (p_AdditionalParams->p_KeysMatchTableNew)
27105 + ((t_FmPcdCcNode *)(p_AdditionalParams->h_CurrentNode))->h_KeysMatchTable =
27106 + p_AdditionalParams->p_KeysMatchTableNew;
27107 +
27108 + /* Locking node's spinlock before updating 'keys and next engine' structure,
27109 + as it maybe used to retrieve keys statistics */
27110 + intFlags =
27111 + XX_LockIntrSpinlock(
27112 + ((t_FmPcdCcNode *)(p_AdditionalParams->h_CurrentNode))->h_Spinlock);
27113 +
27114 + ((t_FmPcdCcNode *)(p_AdditionalParams->h_CurrentNode))->numOfKeys =
27115 + p_AdditionalParams->numOfKeys;
27116 +
27117 + memcpy(((t_FmPcdCcNode *)(p_AdditionalParams->h_CurrentNode))->keyAndNextEngineParams,
27118 + &p_AdditionalParams->keyAndNextEngineParams,
27119 + sizeof(t_FmPcdCcKeyAndNextEngineParams) * (CC_MAX_NUM_OF_KEYS));
27120 +
27121 + XX_UnlockIntrSpinlock(
27122 + ((t_FmPcdCcNode *)(p_AdditionalParams->h_CurrentNode))->h_Spinlock,
27123 + intFlags);
27124 + }
27125 + else
27126 + {
27127 + uint8_t numEntries =
27128 + ((t_FmPcdCcTree *)(p_AdditionalParams->h_CurrentNode))->numOfEntries;
27129 + ASSERT_COND(numEntries < FM_PCD_MAX_NUM_OF_CC_GROUPS);
27130 + memcpy(&((t_FmPcdCcTree *)(p_AdditionalParams->h_CurrentNode))->keyAndNextEngineParams,
27131 + &p_AdditionalParams->keyAndNextEngineParams,
27132 + sizeof(t_FmPcdCcKeyAndNextEngineParams) * numEntries);
27133 + }
27134 +
27135 + ReleaseLst(h_FmPcdOldPointersLst);
27136 + ReleaseLst(h_FmPcdNewPointersLst);
27137 +
27138 + XX_Free(p_AdditionalParams);
27139 +
27140 + return E_OK;
27141 +}
27142 +
27143 +static t_Handle BuildNewAd(
27144 + t_Handle h_Ad,
27145 + t_FmPcdModifyCcKeyAdditionalParams *p_FmPcdModifyCcKeyAdditionalParams,
27146 + t_FmPcdCcNode *p_CcNode,
27147 + t_FmPcdCcNextEngineParams *p_FmPcdCcNextEngineParams)
27148 +{
27149 + t_FmPcdCcNode *p_FmPcdCcNodeTmp;
27150 + t_Handle h_OrigAd = NULL;
27151 +
27152 + p_FmPcdCcNodeTmp = (t_FmPcdCcNode*)XX_Malloc(sizeof(t_FmPcdCcNode));
27153 + if (!p_FmPcdCcNodeTmp)
27154 + {
27155 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("p_FmPcdCcNodeTmp"));
27156 + return NULL;
27157 + }
27158 + memset(p_FmPcdCcNodeTmp, 0, sizeof(t_FmPcdCcNode));
27159 +
27160 + p_FmPcdCcNodeTmp->numOfKeys = p_FmPcdModifyCcKeyAdditionalParams->numOfKeys;
27161 + p_FmPcdCcNodeTmp->h_KeysMatchTable =
27162 + p_FmPcdModifyCcKeyAdditionalParams->p_KeysMatchTableNew;
27163 + p_FmPcdCcNodeTmp->h_AdTable =
27164 + p_FmPcdModifyCcKeyAdditionalParams->p_AdTableNew;
27165 +
27166 + p_FmPcdCcNodeTmp->lclMask = p_CcNode->lclMask;
27167 + p_FmPcdCcNodeTmp->parseCode = p_CcNode->parseCode;
27168 + p_FmPcdCcNodeTmp->offset = p_CcNode->offset;
27169 + p_FmPcdCcNodeTmp->prsArrayOffset = p_CcNode->prsArrayOffset;
27170 + p_FmPcdCcNodeTmp->ctrlFlow = p_CcNode->ctrlFlow;
27171 + p_FmPcdCcNodeTmp->ccKeySizeAccExtraction = p_CcNode->ccKeySizeAccExtraction;
27172 + p_FmPcdCcNodeTmp->sizeOfExtraction = p_CcNode->sizeOfExtraction;
27173 + p_FmPcdCcNodeTmp->glblMaskSize = p_CcNode->glblMaskSize;
27174 + p_FmPcdCcNodeTmp->p_GlblMask = p_CcNode->p_GlblMask;
27175 +
27176 + if (p_FmPcdCcNextEngineParams->nextEngine == e_FM_PCD_CC)
27177 + {
27178 + if (p_FmPcdCcNextEngineParams->h_Manip)
27179 + {
27180 + h_OrigAd = p_CcNode->h_Ad;
27181 + if (AllocAndFillAdForContLookupManip(
27182 + p_FmPcdCcNextEngineParams->params.ccParams.h_CcNode)
27183 + != E_OK)
27184 + {
27185 + REPORT_ERROR(MAJOR, E_INVALID_STATE, NO_MSG);
27186 + XX_Free(p_FmPcdCcNodeTmp);
27187 + return NULL;
27188 + }
27189 + }
27190 + FillAdOfTypeContLookup(h_Ad, NULL, p_CcNode->h_FmPcd, p_FmPcdCcNodeTmp,
27191 + h_OrigAd ? NULL : p_FmPcdCcNextEngineParams->h_Manip, NULL);
27192 + }
27193 +
27194 +#if (DPAA_VERSION >= 11)
27195 + if ((p_FmPcdCcNextEngineParams->nextEngine == e_FM_PCD_FR)
27196 + && (p_FmPcdCcNextEngineParams->params.frParams.h_FrmReplic))
27197 + {
27198 + FillAdOfTypeContLookup(
27199 + h_Ad, NULL, p_CcNode->h_FmPcd, p_FmPcdCcNodeTmp,
27200 + p_FmPcdCcNextEngineParams->h_Manip,
27201 + p_FmPcdCcNextEngineParams->params.frParams.h_FrmReplic);
27202 + }
27203 +#endif /* (DPAA_VERSION >= 11) */
27204 +
27205 + XX_Free(p_FmPcdCcNodeTmp);
27206 +
27207 + return E_OK;
27208 +}
27209 +
27210 +static t_Error DynamicChangeHc(
27211 + t_Handle h_FmPcd, t_List *h_OldPointersLst, t_List *h_NewPointersLst,
27212 + t_FmPcdModifyCcKeyAdditionalParams *p_AdditionalParams,
27213 + bool useShadowStructs)
27214 +{
27215 + t_List *p_PosOld, *p_PosNew;
27216 + uint32_t oldAdAddrOffset, newAdAddrOffset;
27217 + uint16_t i = 0;
27218 + t_Error err = E_OK;
27219 + uint8_t numOfModifiedPtr;
27220 +
27221 + ASSERT_COND(h_FmPcd);
27222 + ASSERT_COND(h_OldPointersLst);
27223 + ASSERT_COND(h_NewPointersLst);
27224 +
27225 + numOfModifiedPtr = (uint8_t)LIST_NumOfObjs(h_OldPointersLst);
27226 +
27227 + if (numOfModifiedPtr)
27228 + {
27229 + p_PosNew = LIST_FIRST(h_NewPointersLst);
27230 + p_PosOld = LIST_FIRST(h_OldPointersLst);
27231 +
27232 + /* Retrieve address of new AD */
27233 + newAdAddrOffset = FmPcdCcGetNodeAddrOffsetFromNodeInfo(h_FmPcd,
27234 + p_PosNew);
27235 + if (newAdAddrOffset == (uint32_t)ILLEGAL_BASE)
27236 + {
27237 + ReleaseModifiedDataStructure(h_FmPcd, h_OldPointersLst,
27238 + h_NewPointersLst,
27239 + p_AdditionalParams, useShadowStructs);
27240 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("New AD address"));
27241 + }
27242 +
27243 + for (i = 0; i < numOfModifiedPtr; i++)
27244 + {
27245 + /* Retrieve address of current AD */
27246 + oldAdAddrOffset = FmPcdCcGetNodeAddrOffsetFromNodeInfo(h_FmPcd,
27247 + p_PosOld);
27248 + if (oldAdAddrOffset == (uint32_t)ILLEGAL_BASE)
27249 + {
27250 + ReleaseModifiedDataStructure(h_FmPcd, h_OldPointersLst,
27251 + h_NewPointersLst,
27252 + p_AdditionalParams,
27253 + useShadowStructs);
27254 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Old AD address"));
27255 + }
27256 +
27257 + /* Invoke host command to copy from new AD to old AD */
27258 + err = FmHcPcdCcDoDynamicChange(((t_FmPcd *)h_FmPcd)->h_Hc,
27259 + oldAdAddrOffset, newAdAddrOffset);
27260 + if (err)
27261 + {
27262 + ReleaseModifiedDataStructure(h_FmPcd, h_OldPointersLst,
27263 + h_NewPointersLst,
27264 + p_AdditionalParams,
27265 + useShadowStructs);
27266 + RETURN_ERROR(
27267 + MAJOR,
27268 + err,
27269 + ("For part of nodes changes are done - situation is danger"));
27270 + }
27271 +
27272 + p_PosOld = LIST_NEXT(p_PosOld);
27273 + }
27274 + }
27275 + return E_OK;
27276 +}
27277 +
27278 +static t_Error DoDynamicChange(
27279 + t_Handle h_FmPcd, t_List *h_OldPointersLst, t_List *h_NewPointersLst,
27280 + t_FmPcdModifyCcKeyAdditionalParams *p_AdditionalParams,
27281 + bool useShadowStructs)
27282 +{
27283 + t_FmPcdCcNode *p_CcNode =
27284 + (t_FmPcdCcNode *)(p_AdditionalParams->h_CurrentNode);
27285 + t_List *p_PosNew;
27286 + t_CcNodeInformation *p_CcNodeInfo;
27287 + t_FmPcdCcNextEngineParams nextEngineParams;
27288 + t_Handle h_Ad;
27289 + uint32_t keySize;
27290 + t_Error err = E_OK;
27291 + uint8_t numOfModifiedPtr;
27292 +
27293 + ASSERT_COND(h_FmPcd);
27294 +
27295 + memset(&nextEngineParams, 0, sizeof(t_FmPcdCcNextEngineParams));
27296 +
27297 + numOfModifiedPtr = (uint8_t)LIST_NumOfObjs(h_OldPointersLst);
27298 +
27299 + if (numOfModifiedPtr)
27300 + {
27301 +
27302 + p_PosNew = LIST_FIRST(h_NewPointersLst);
27303 +
27304 + /* Invoke host-command to copy from the new Ad to existing Ads */
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 + if (useShadowStructs)
27311 + {
27312 + /* When the host-command above has ended, the old structures are 'free'and we can update
27313 + them by copying from the new shadow structures. */
27314 + if (p_CcNode->lclMask)
27315 + keySize = (uint32_t)(2 * p_CcNode->ccKeySizeAccExtraction);
27316 + else
27317 + keySize = p_CcNode->ccKeySizeAccExtraction;
27318 +
27319 + MemCpy8(p_AdditionalParams->p_KeysMatchTableOld,
27320 + p_AdditionalParams->p_KeysMatchTableNew,
27321 + p_CcNode->maxNumOfKeys * keySize * sizeof(uint8_t));
27322 +
27323 + MemCpy8(
27324 + p_AdditionalParams->p_AdTableOld,
27325 + p_AdditionalParams->p_AdTableNew,
27326 + (uint32_t)((p_CcNode->maxNumOfKeys + 1)
27327 + * FM_PCD_CC_AD_ENTRY_SIZE));
27328 +
27329 + /* Retrieve the address of the allocated Ad */
27330 + p_CcNodeInfo = CC_NODE_F_OBJECT(p_PosNew);
27331 + h_Ad = p_CcNodeInfo->h_CcNode;
27332 +
27333 + /* Build a new Ad that holds the old (now updated) structures */
27334 + p_AdditionalParams->p_KeysMatchTableNew =
27335 + p_AdditionalParams->p_KeysMatchTableOld;
27336 + p_AdditionalParams->p_AdTableNew = p_AdditionalParams->p_AdTableOld;
27337 +
27338 + nextEngineParams.nextEngine = e_FM_PCD_CC;
27339 + nextEngineParams.params.ccParams.h_CcNode = (t_Handle)p_CcNode;
27340 +
27341 + BuildNewAd(h_Ad, p_AdditionalParams, p_CcNode, &nextEngineParams);
27342 +
27343 + /* HC to copy from the new Ad (old updated structures) to current Ad (uses shadow structures) */
27344 + err = DynamicChangeHc(h_FmPcd, h_OldPointersLst, h_NewPointersLst,
27345 + p_AdditionalParams, useShadowStructs);
27346 + if (err)
27347 + RETURN_ERROR(MAJOR, err, NO_MSG);
27348 + }
27349 + }
27350 +
27351 + err = ReleaseModifiedDataStructure(h_FmPcd, h_OldPointersLst,
27352 + h_NewPointersLst,
27353 + p_AdditionalParams, useShadowStructs);
27354 + if (err)
27355 + RETURN_ERROR(MAJOR, err, NO_MSG);
27356 +
27357 + return E_OK;
27358 +}
27359 +
27360 +#ifdef FM_CAPWAP_SUPPORT
27361 +static bool IsCapwapApplSpecific(t_Handle h_Node)
27362 +{
27363 + t_FmPcdCcNode *p_CcNode = (t_FmPcdCcNode *)h_Node;
27364 + bool isManipForCapwapApplSpecificBuild = FALSE;
27365 + int i = 0;
27366 +
27367 + ASSERT_COND(h_Node);
27368 + /* assumption that this function called only for INDEXED_FLOW_ID - so no miss*/
27369 + for (i = 0; i < p_CcNode->numOfKeys; i++)
27370 + {
27371 + if ( p_CcNode->keyAndNextEngineParams[i].nextEngineParams.h_Manip &&
27372 + FmPcdManipIsCapwapApplSpecific(p_CcNode->keyAndNextEngineParams[i].nextEngineParams.h_Manip))
27373 + {
27374 + isManipForCapwapApplSpecificBuild = TRUE;
27375 + break;
27376 + }
27377 + }
27378 + return isManipForCapwapApplSpecificBuild;
27379 +
27380 +}
27381 +#endif /* FM_CAPWAP_SUPPORT */
27382 +
27383 +static t_Error CcUpdateParam(
27384 + t_Handle h_FmPcd, t_Handle h_PcdParams, t_Handle h_FmPort,
27385 + t_FmPcdCcKeyAndNextEngineParams *p_CcKeyAndNextEngineParams,
27386 + uint16_t numOfEntries, t_Handle h_Ad, bool validate, uint16_t level,
27387 + t_Handle h_FmTree, bool modify)
27388 +{
27389 + t_FmPcdCcNode *p_CcNode;
27390 + t_Error err;
27391 + uint16_t tmp = 0;
27392 + int i = 0;
27393 + t_FmPcdCcTree *p_CcTree = (t_FmPcdCcTree *)h_FmTree;
27394 +
27395 + level++;
27396 +
27397 + if (p_CcTree->h_IpReassemblyManip)
27398 + {
27399 + err = FmPcdManipUpdate(h_FmPcd, h_PcdParams, h_FmPort,
27400 + p_CcTree->h_IpReassemblyManip, NULL, validate,
27401 + level, h_FmTree, modify);
27402 + if (err)
27403 + RETURN_ERROR(MAJOR, err, NO_MSG);
27404 + }
27405 +
27406 + if (p_CcTree->h_CapwapReassemblyManip)
27407 + {
27408 + err = FmPcdManipUpdate(h_FmPcd, h_PcdParams, h_FmPort,
27409 + p_CcTree->h_CapwapReassemblyManip, NULL, validate,
27410 + level, h_FmTree, modify);
27411 + if (err)
27412 + RETURN_ERROR(MAJOR, err, NO_MSG);
27413 + }
27414 +
27415 + if (numOfEntries)
27416 + {
27417 + for (i = 0; i < numOfEntries; i++)
27418 + {
27419 + if (i == 0)
27420 + h_Ad = PTR_MOVE(h_Ad, i*FM_PCD_CC_AD_ENTRY_SIZE);
27421 + else
27422 + h_Ad = PTR_MOVE(h_Ad, FM_PCD_CC_AD_ENTRY_SIZE);
27423 +
27424 + if (p_CcKeyAndNextEngineParams[i].nextEngineParams.nextEngine
27425 + == e_FM_PCD_CC)
27426 + {
27427 + p_CcNode =
27428 + p_CcKeyAndNextEngineParams[i].nextEngineParams.params.ccParams.h_CcNode;
27429 + ASSERT_COND(p_CcNode);
27430 +
27431 + if (p_CcKeyAndNextEngineParams[i].nextEngineParams.h_Manip)
27432 + {
27433 + err =
27434 + FmPcdManipUpdate(
27435 + h_FmPcd,
27436 + NULL,
27437 + h_FmPort,
27438 + p_CcKeyAndNextEngineParams[i].nextEngineParams.h_Manip,
27439 + h_Ad, validate, level, h_FmTree, modify);
27440 + if (err)
27441 + RETURN_ERROR(MAJOR, err, NO_MSG);
27442 + }
27443 +
27444 + if (p_CcNode->keyAndNextEngineParams[p_CcNode->numOfKeys].nextEngineParams.nextEngine
27445 + != e_FM_PCD_INVALID)
27446 + tmp = (uint8_t)(p_CcNode->numOfKeys + 1);
27447 + else
27448 + tmp = p_CcNode->numOfKeys;
27449 +
27450 + err = CcUpdateParam(h_FmPcd, h_PcdParams, h_FmPort,
27451 + p_CcNode->keyAndNextEngineParams, tmp,
27452 + p_CcNode->h_AdTable, validate, level,
27453 + h_FmTree, modify);
27454 + if (err)
27455 + RETURN_ERROR(MAJOR, err, NO_MSG);
27456 + }
27457 + else
27458 + {
27459 + if (p_CcKeyAndNextEngineParams[i].nextEngineParams.h_Manip)
27460 + {
27461 + err =
27462 + FmPcdManipUpdate(
27463 + h_FmPcd,
27464 + NULL,
27465 + h_FmPort,
27466 + p_CcKeyAndNextEngineParams[i].nextEngineParams.h_Manip,
27467 + h_Ad, validate, level, h_FmTree, modify);
27468 + if (err)
27469 + RETURN_ERROR(MAJOR, err, NO_MSG);
27470 + }
27471 + }
27472 + }
27473 + }
27474 +
27475 + return E_OK;
27476 +}
27477 +
27478 +static ccPrivateInfo_t IcDefineCode(t_FmPcdCcNodeParams *p_CcNodeParam)
27479 +{
27480 + switch (p_CcNodeParam->extractCcParams.extractNonHdr.action)
27481 + {
27482 + case (e_FM_PCD_ACTION_EXACT_MATCH):
27483 + switch (p_CcNodeParam->extractCcParams.extractNonHdr.src)
27484 + {
27485 + case (e_FM_PCD_EXTRACT_FROM_KEY):
27486 + return CC_PRIVATE_INFO_IC_KEY_EXACT_MATCH;
27487 + case (e_FM_PCD_EXTRACT_FROM_HASH):
27488 + return CC_PRIVATE_INFO_IC_HASH_EXACT_MATCH;
27489 + default:
27490 + return CC_PRIVATE_INFO_NONE;
27491 + }
27492 +
27493 + case (e_FM_PCD_ACTION_INDEXED_LOOKUP):
27494 + switch (p_CcNodeParam->extractCcParams.extractNonHdr.src)
27495 + {
27496 + case (e_FM_PCD_EXTRACT_FROM_HASH):
27497 + return CC_PRIVATE_INFO_IC_HASH_INDEX_LOOKUP;
27498 + case (e_FM_PCD_EXTRACT_FROM_FLOW_ID):
27499 + return CC_PRIVATE_INFO_IC_DEQ_FQID_INDEX_LOOKUP;
27500 + default:
27501 + return CC_PRIVATE_INFO_NONE;
27502 + }
27503 +
27504 + default:
27505 + break;
27506 + }
27507 +
27508 + return CC_PRIVATE_INFO_NONE;
27509 +}
27510 +
27511 +static t_CcNodeInformation * DequeueAdditionalInfoFromRelevantLst(
27512 + t_List *p_List)
27513 +{
27514 + t_CcNodeInformation *p_CcNodeInfo = NULL;
27515 +
27516 + if (!LIST_IsEmpty(p_List))
27517 + {
27518 + p_CcNodeInfo = CC_NODE_F_OBJECT(p_List->p_Next);
27519 + LIST_DelAndInit(&p_CcNodeInfo->node);
27520 + }
27521 +
27522 + return p_CcNodeInfo;
27523 +}
27524 +
27525 +void ReleaseLst(t_List *p_List)
27526 +{
27527 + t_CcNodeInformation *p_CcNodeInfo = NULL;
27528 +
27529 + if (!LIST_IsEmpty(p_List))
27530 + {
27531 + p_CcNodeInfo = DequeueAdditionalInfoFromRelevantLst(p_List);
27532 + while (p_CcNodeInfo)
27533 + {
27534 + XX_Free(p_CcNodeInfo);
27535 + p_CcNodeInfo = DequeueAdditionalInfoFromRelevantLst(p_List);
27536 + }
27537 + }
27538 +
27539 + LIST_Del(p_List);
27540 +}
27541 +
27542 +static void DeleteNode(t_FmPcdCcNode *p_CcNode)
27543 +{
27544 + uint32_t i;
27545 +
27546 + if (!p_CcNode)
27547 + return;
27548 +
27549 + if (p_CcNode->p_GlblMask)
27550 + {
27551 + XX_Free(p_CcNode->p_GlblMask);
27552 + p_CcNode->p_GlblMask = NULL;
27553 + }
27554 +
27555 + if (p_CcNode->h_KeysMatchTable)
27556 + {
27557 + FM_MURAM_FreeMem(FmPcdGetMuramHandle(p_CcNode->h_FmPcd),
27558 + p_CcNode->h_KeysMatchTable);
27559 + p_CcNode->h_KeysMatchTable = NULL;
27560 + }
27561 +
27562 + if (p_CcNode->h_AdTable)
27563 + {
27564 + FM_MURAM_FreeMem(FmPcdGetMuramHandle(p_CcNode->h_FmPcd),
27565 + p_CcNode->h_AdTable);
27566 + p_CcNode->h_AdTable = NULL;
27567 + }
27568 +
27569 + if (p_CcNode->h_Ad)
27570 + {
27571 + FM_MURAM_FreeMem(FmPcdGetMuramHandle(p_CcNode->h_FmPcd),
27572 + p_CcNode->h_Ad);
27573 + p_CcNode->h_Ad = NULL;
27574 + p_CcNode->h_TmpAd = NULL;
27575 + }
27576 +
27577 + if (p_CcNode->h_StatsFLRs)
27578 + {
27579 + FM_MURAM_FreeMem(FmPcdGetMuramHandle(p_CcNode->h_FmPcd),
27580 + p_CcNode->h_StatsFLRs);
27581 + p_CcNode->h_StatsFLRs = NULL;
27582 + }
27583 +
27584 + if (p_CcNode->h_Spinlock)
27585 + {
27586 + XX_FreeSpinlock(p_CcNode->h_Spinlock);
27587 + p_CcNode->h_Spinlock = NULL;
27588 + }
27589 +
27590 + /* Restore the original counters pointer instead of the mutual pointer (mutual to all hash buckets) */
27591 + if (p_CcNode->isHashBucket
27592 + && (p_CcNode->statisticsMode != e_FM_PCD_CC_STATS_MODE_NONE))
27593 + p_CcNode->keyAndNextEngineParams[p_CcNode->numOfKeys].p_StatsObj->h_StatsCounters =
27594 + p_CcNode->h_PrivMissStatsCounters;
27595 +
27596 + /* Releasing all currently used statistics objects, including 'miss' entry */
27597 + for (i = 0; i < p_CcNode->numOfKeys + 1; i++)
27598 + if (p_CcNode->keyAndNextEngineParams[i].p_StatsObj)
27599 + PutStatsObj(p_CcNode,
27600 + p_CcNode->keyAndNextEngineParams[i].p_StatsObj);
27601 +
27602 + if (!LIST_IsEmpty(&p_CcNode->availableStatsLst))
27603 + {
27604 + t_Handle h_FmMuram = FmPcdGetMuramHandle(p_CcNode->h_FmPcd);
27605 + ASSERT_COND(h_FmMuram);
27606 +
27607 + FreeStatObjects(&p_CcNode->availableStatsLst, h_FmMuram);
27608 + }
27609 +
27610 + LIST_Del(&p_CcNode->availableStatsLst);
27611 +
27612 + ReleaseLst(&p_CcNode->availableStatsLst);
27613 + ReleaseLst(&p_CcNode->ccPrevNodesLst);
27614 + ReleaseLst(&p_CcNode->ccTreeIdLst);
27615 + ReleaseLst(&p_CcNode->ccTreesLst);
27616 +
27617 + XX_Free(p_CcNode);
27618 +}
27619 +
27620 +static void DeleteTree(t_FmPcdCcTree *p_FmPcdTree, t_FmPcd *p_FmPcd)
27621 +{
27622 + if (p_FmPcdTree)
27623 + {
27624 + if (p_FmPcdTree->ccTreeBaseAddr)
27625 + {
27626 + FM_MURAM_FreeMem(FmPcdGetMuramHandle(p_FmPcd),
27627 + UINT_TO_PTR(p_FmPcdTree->ccTreeBaseAddr));
27628 + p_FmPcdTree->ccTreeBaseAddr = 0;
27629 + }
27630 +
27631 + ReleaseLst(&p_FmPcdTree->fmPortsLst);
27632 +
27633 + XX_Free(p_FmPcdTree);
27634 + }
27635 +}
27636 +
27637 +static void GetCcExtractKeySize(uint8_t parseCodeRealSize,
27638 + uint8_t *parseCodeCcSize)
27639 +{
27640 + if ((parseCodeRealSize > 0) && (parseCodeRealSize < 2))
27641 + *parseCodeCcSize = 1;
27642 + else
27643 + if (parseCodeRealSize == 2)
27644 + *parseCodeCcSize = 2;
27645 + else
27646 + if ((parseCodeRealSize > 2) && (parseCodeRealSize <= 4))
27647 + *parseCodeCcSize = 4;
27648 + else
27649 + if ((parseCodeRealSize > 4) && (parseCodeRealSize <= 8))
27650 + *parseCodeCcSize = 8;
27651 + else
27652 + if ((parseCodeRealSize > 8) && (parseCodeRealSize <= 16))
27653 + *parseCodeCcSize = 16;
27654 + else
27655 + if ((parseCodeRealSize > 16)
27656 + && (parseCodeRealSize <= 24))
27657 + *parseCodeCcSize = 24;
27658 + else
27659 + if ((parseCodeRealSize > 24)
27660 + && (parseCodeRealSize <= 32))
27661 + *parseCodeCcSize = 32;
27662 + else
27663 + if ((parseCodeRealSize > 32)
27664 + && (parseCodeRealSize <= 40))
27665 + *parseCodeCcSize = 40;
27666 + else
27667 + if ((parseCodeRealSize > 40)
27668 + && (parseCodeRealSize <= 48))
27669 + *parseCodeCcSize = 48;
27670 + else
27671 + if ((parseCodeRealSize > 48)
27672 + && (parseCodeRealSize <= 56))
27673 + *parseCodeCcSize = 56;
27674 + else
27675 + *parseCodeCcSize = 0;
27676 +}
27677 +
27678 +static void GetSizeHeaderField(e_NetHeaderType hdr, t_FmPcdFields field,
27679 + uint8_t *parseCodeRealSize)
27680 +{
27681 + switch (hdr)
27682 + {
27683 + case (HEADER_TYPE_ETH):
27684 + switch (field.eth)
27685 + {
27686 + case (NET_HEADER_FIELD_ETH_DA):
27687 + *parseCodeRealSize = 6;
27688 + break;
27689 +
27690 + case (NET_HEADER_FIELD_ETH_SA):
27691 + *parseCodeRealSize = 6;
27692 + break;
27693 +
27694 + case (NET_HEADER_FIELD_ETH_TYPE):
27695 + *parseCodeRealSize = 2;
27696 + break;
27697 +
27698 + default:
27699 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported1"));
27700 + *parseCodeRealSize = CC_SIZE_ILLEGAL;
27701 + break;
27702 + }
27703 + break;
27704 +
27705 + case (HEADER_TYPE_PPPoE):
27706 + switch (field.pppoe)
27707 + {
27708 + case (NET_HEADER_FIELD_PPPoE_PID):
27709 + *parseCodeRealSize = 2;
27710 + break;
27711 +
27712 + default:
27713 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported1"));
27714 + *parseCodeRealSize = CC_SIZE_ILLEGAL;
27715 + break;
27716 + }
27717 + break;
27718 +
27719 + case (HEADER_TYPE_VLAN):
27720 + switch (field.vlan)
27721 + {
27722 + case (NET_HEADER_FIELD_VLAN_TCI):
27723 + *parseCodeRealSize = 2;
27724 + break;
27725 +
27726 + default:
27727 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported2"));
27728 + *parseCodeRealSize = CC_SIZE_ILLEGAL;
27729 + break;
27730 + }
27731 + break;
27732 +
27733 + case (HEADER_TYPE_MPLS):
27734 + switch (field.mpls)
27735 + {
27736 + case (NET_HEADER_FIELD_MPLS_LABEL_STACK):
27737 + *parseCodeRealSize = 4;
27738 + break;
27739 +
27740 + default:
27741 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported3"));
27742 + *parseCodeRealSize = CC_SIZE_ILLEGAL;
27743 + break;
27744 + }
27745 + break;
27746 +
27747 + case (HEADER_TYPE_IPv4):
27748 + switch (field.ipv4)
27749 + {
27750 + case (NET_HEADER_FIELD_IPv4_DST_IP):
27751 + case (NET_HEADER_FIELD_IPv4_SRC_IP):
27752 + *parseCodeRealSize = 4;
27753 + break;
27754 +
27755 + case (NET_HEADER_FIELD_IPv4_TOS):
27756 + case (NET_HEADER_FIELD_IPv4_PROTO):
27757 + *parseCodeRealSize = 1;
27758 + break;
27759 +
27760 + case (NET_HEADER_FIELD_IPv4_DST_IP
27761 + | NET_HEADER_FIELD_IPv4_SRC_IP):
27762 + *parseCodeRealSize = 8;
27763 + break;
27764 +
27765 + case (NET_HEADER_FIELD_IPv4_TTL):
27766 + *parseCodeRealSize = 1;
27767 + break;
27768 +
27769 + default:
27770 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported4"));
27771 + *parseCodeRealSize = CC_SIZE_ILLEGAL;
27772 + break;
27773 + }
27774 + break;
27775 +
27776 + case (HEADER_TYPE_IPv6):
27777 + switch (field.ipv6)
27778 + {
27779 + case (NET_HEADER_FIELD_IPv6_VER | NET_HEADER_FIELD_IPv6_FL
27780 + | NET_HEADER_FIELD_IPv6_TC):
27781 + *parseCodeRealSize = 4;
27782 + break;
27783 +
27784 + case (NET_HEADER_FIELD_IPv6_NEXT_HDR):
27785 + case (NET_HEADER_FIELD_IPv6_HOP_LIMIT):
27786 + *parseCodeRealSize = 1;
27787 + break;
27788 +
27789 + case (NET_HEADER_FIELD_IPv6_DST_IP):
27790 + case (NET_HEADER_FIELD_IPv6_SRC_IP):
27791 + *parseCodeRealSize = 16;
27792 + break;
27793 +
27794 + default:
27795 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported5"));
27796 + *parseCodeRealSize = CC_SIZE_ILLEGAL;
27797 + break;
27798 + }
27799 + break;
27800 +
27801 + case (HEADER_TYPE_IP):
27802 + switch (field.ip)
27803 + {
27804 + case (NET_HEADER_FIELD_IP_DSCP):
27805 + case (NET_HEADER_FIELD_IP_PROTO):
27806 + *parseCodeRealSize = 1;
27807 + break;
27808 +
27809 + default:
27810 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported5"));
27811 + *parseCodeRealSize = CC_SIZE_ILLEGAL;
27812 + break;
27813 + }
27814 + break;
27815 +
27816 + case (HEADER_TYPE_GRE):
27817 + switch (field.gre)
27818 + {
27819 + case (NET_HEADER_FIELD_GRE_TYPE):
27820 + *parseCodeRealSize = 2;
27821 + break;
27822 +
27823 + default:
27824 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported6"));
27825 + *parseCodeRealSize = CC_SIZE_ILLEGAL;
27826 + break;
27827 + }
27828 + break;
27829 +
27830 + case (HEADER_TYPE_MINENCAP):
27831 + switch (field.minencap)
27832 + {
27833 + case (NET_HEADER_FIELD_MINENCAP_TYPE):
27834 + *parseCodeRealSize = 1;
27835 + break;
27836 +
27837 + case (NET_HEADER_FIELD_MINENCAP_DST_IP):
27838 + case (NET_HEADER_FIELD_MINENCAP_SRC_IP):
27839 + *parseCodeRealSize = 4;
27840 + break;
27841 +
27842 + case (NET_HEADER_FIELD_MINENCAP_SRC_IP
27843 + | NET_HEADER_FIELD_MINENCAP_DST_IP):
27844 + *parseCodeRealSize = 8;
27845 + break;
27846 +
27847 + default:
27848 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported7"));
27849 + *parseCodeRealSize = CC_SIZE_ILLEGAL;
27850 + break;
27851 + }
27852 + break;
27853 +
27854 + case (HEADER_TYPE_TCP):
27855 + switch (field.tcp)
27856 + {
27857 + case (NET_HEADER_FIELD_TCP_PORT_SRC):
27858 + case (NET_HEADER_FIELD_TCP_PORT_DST):
27859 + *parseCodeRealSize = 2;
27860 + break;
27861 +
27862 + case (NET_HEADER_FIELD_TCP_PORT_SRC
27863 + | NET_HEADER_FIELD_TCP_PORT_DST):
27864 + *parseCodeRealSize = 4;
27865 + break;
27866 +
27867 + default:
27868 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported8"));
27869 + *parseCodeRealSize = CC_SIZE_ILLEGAL;
27870 + break;
27871 + }
27872 + break;
27873 +
27874 + case (HEADER_TYPE_UDP):
27875 + switch (field.udp)
27876 + {
27877 + case (NET_HEADER_FIELD_UDP_PORT_SRC):
27878 + case (NET_HEADER_FIELD_UDP_PORT_DST):
27879 + *parseCodeRealSize = 2;
27880 + break;
27881 +
27882 + case (NET_HEADER_FIELD_UDP_PORT_SRC
27883 + | NET_HEADER_FIELD_UDP_PORT_DST):
27884 + *parseCodeRealSize = 4;
27885 + break;
27886 +
27887 + default:
27888 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported9"));
27889 + *parseCodeRealSize = CC_SIZE_ILLEGAL;
27890 + break;
27891 + }
27892 + break;
27893 +
27894 + default:
27895 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported10"));
27896 + *parseCodeRealSize = CC_SIZE_ILLEGAL;
27897 + break;
27898 + }
27899 +}
27900 +
27901 +t_Error ValidateNextEngineParams(
27902 + t_Handle h_FmPcd, t_FmPcdCcNextEngineParams *p_FmPcdCcNextEngineParams,
27903 + e_FmPcdCcStatsMode statsMode)
27904 +{
27905 + uint16_t absoluteProfileId;
27906 + t_Error err = E_OK;
27907 + uint8_t relativeSchemeId;
27908 +
27909 + if ((statsMode == e_FM_PCD_CC_STATS_MODE_NONE)
27910 + && (p_FmPcdCcNextEngineParams->statisticsEn))
27911 + RETURN_ERROR(
27912 + MAJOR,
27913 + E_CONFLICT,
27914 + ("Statistics are requested for a key, but statistics mode was set"
27915 + "to 'NONE' upon initialization"));
27916 +
27917 + switch (p_FmPcdCcNextEngineParams->nextEngine)
27918 + {
27919 + case (e_FM_PCD_INVALID):
27920 + err = E_NOT_SUPPORTED;
27921 + break;
27922 +
27923 + case (e_FM_PCD_DONE):
27924 + if ((p_FmPcdCcNextEngineParams->params.enqueueParams.action
27925 + == e_FM_PCD_ENQ_FRAME)
27926 + && p_FmPcdCcNextEngineParams->params.enqueueParams.overrideFqid)
27927 + {
27928 + if (!p_FmPcdCcNextEngineParams->params.enqueueParams.newFqid)
27929 + RETURN_ERROR(
27930 + MAJOR,
27931 + E_CONFLICT,
27932 + ("When overrideFqid is set, newFqid must not be zero"));
27933 + if (p_FmPcdCcNextEngineParams->params.enqueueParams.newFqid
27934 + & ~0x00FFFFFF)
27935 + RETURN_ERROR(
27936 + MAJOR, E_INVALID_VALUE,
27937 + ("fqidForCtrlFlow must be between 1 and 2^24-1"));
27938 + }
27939 + break;
27940 +
27941 + case (e_FM_PCD_KG):
27942 + relativeSchemeId =
27943 + FmPcdKgGetRelativeSchemeId(
27944 + h_FmPcd,
27945 + FmPcdKgGetSchemeId(
27946 + p_FmPcdCcNextEngineParams->params.kgParams.h_DirectScheme));
27947 + if (relativeSchemeId == FM_PCD_KG_NUM_OF_SCHEMES)
27948 + RETURN_ERROR(MAJOR, E_NOT_IN_RANGE, NO_MSG);
27949 + if (!FmPcdKgIsSchemeValidSw(
27950 + p_FmPcdCcNextEngineParams->params.kgParams.h_DirectScheme))
27951 + RETURN_ERROR(MAJOR, E_INVALID_STATE,
27952 + ("not valid schemeIndex in KG next engine param"));
27953 + if (!KgIsSchemeAlwaysDirect(h_FmPcd, relativeSchemeId))
27954 + RETURN_ERROR(
27955 + MAJOR,
27956 + E_INVALID_STATE,
27957 + ("CC Node may point only to a scheme that is always direct."));
27958 + break;
27959 +
27960 + case (e_FM_PCD_PLCR):
27961 + if (p_FmPcdCcNextEngineParams->params.plcrParams.overrideParams)
27962 + {
27963 + /* if private policer profile, it may be uninitialized yet, therefore no checks are done at this stage */
27964 + if (p_FmPcdCcNextEngineParams->params.plcrParams.sharedProfile)
27965 + {
27966 + err =
27967 + FmPcdPlcrGetAbsoluteIdByProfileParams(
27968 + h_FmPcd,
27969 + e_FM_PCD_PLCR_SHARED,
27970 + NULL,
27971 + p_FmPcdCcNextEngineParams->params.plcrParams.newRelativeProfileId,
27972 + &absoluteProfileId);
27973 + if (err)
27974 + RETURN_ERROR(MAJOR, err,
27975 + ("Shared profile offset is out of range"));
27976 + if (!FmPcdPlcrIsProfileValid(h_FmPcd, absoluteProfileId))
27977 + RETURN_ERROR(MAJOR, E_INVALID_STATE,
27978 + ("Invalid profile"));
27979 + }
27980 + }
27981 + break;
27982 +
27983 + case (e_FM_PCD_HASH):
27984 + p_FmPcdCcNextEngineParams->nextEngine = e_FM_PCD_CC;
27985 + case (e_FM_PCD_CC):
27986 + if (!p_FmPcdCcNextEngineParams->params.ccParams.h_CcNode)
27987 + RETURN_ERROR(MAJOR, E_NULL_POINTER,
27988 + ("handler to next Node is NULL"));
27989 + break;
27990 +
27991 +#if (DPAA_VERSION >= 11)
27992 + case (e_FM_PCD_FR):
27993 + if (!p_FmPcdCcNextEngineParams->params.frParams.h_FrmReplic)
27994 + err = E_NOT_SUPPORTED;
27995 + break;
27996 +#endif /* (DPAA_VERSION >= 11) */
27997 +
27998 + default:
27999 + RETURN_ERROR(MAJOR, E_INVALID_STATE,
28000 + ("Next engine is not correct"));
28001 + }
28002 +
28003 +
28004 + return err;
28005 +}
28006 +
28007 +static uint8_t GetGenParseCode(e_FmPcdExtractFrom src,
28008 + uint32_t offset, bool glblMask,
28009 + uint8_t *parseArrayOffset, bool fromIc,
28010 + ccPrivateInfo_t icCode)
28011 +{
28012 + if (!fromIc)
28013 + {
28014 + switch (src)
28015 + {
28016 + case (e_FM_PCD_EXTRACT_FROM_FRAME_START):
28017 + if (glblMask)
28018 + return CC_PC_GENERIC_WITH_MASK;
28019 + else
28020 + return CC_PC_GENERIC_WITHOUT_MASK;
28021 +
28022 + case (e_FM_PCD_EXTRACT_FROM_CURR_END_OF_PARSE):
28023 + *parseArrayOffset = CC_PC_PR_NEXT_HEADER_OFFSET;
28024 + if (offset)
28025 + return CC_PR_OFFSET;
28026 + else
28027 + return CC_PR_WITHOUT_OFFSET;
28028 +
28029 + default:
28030 + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("Illegal 'extract from' src"));
28031 + return CC_PC_ILLEGAL;
28032 + }
28033 + }
28034 + else
28035 + {
28036 + switch (icCode)
28037 + {
28038 + case (CC_PRIVATE_INFO_IC_KEY_EXACT_MATCH):
28039 + *parseArrayOffset = 0x50;
28040 + return CC_PC_GENERIC_IC_GMASK;
28041 +
28042 + case (CC_PRIVATE_INFO_IC_HASH_EXACT_MATCH):
28043 + *parseArrayOffset = 0x48;
28044 + return CC_PC_GENERIC_IC_GMASK;
28045 +
28046 + case (CC_PRIVATE_INFO_IC_HASH_INDEX_LOOKUP):
28047 + *parseArrayOffset = 0x48;
28048 + return CC_PC_GENERIC_IC_HASH_INDEXED;
28049 +
28050 + case (CC_PRIVATE_INFO_IC_DEQ_FQID_INDEX_LOOKUP):
28051 + *parseArrayOffset = 0x16;
28052 + return CC_PC_GENERIC_IC_HASH_INDEXED;
28053 +
28054 + default:
28055 + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("Illegal 'extract from' src"));
28056 + break;
28057 + }
28058 + }
28059 +
28060 + return CC_PC_ILLEGAL;
28061 +}
28062 +
28063 +static uint8_t GetFullFieldParseCode(e_NetHeaderType hdr, e_FmPcdHdrIndex index,
28064 + t_FmPcdFields field)
28065 +{
28066 + switch (hdr)
28067 + {
28068 + case (HEADER_TYPE_NONE):
28069 + ASSERT_COND(FALSE);
28070 + return CC_PC_ILLEGAL;
28071 +
28072 + case (HEADER_TYPE_ETH):
28073 + switch (field.eth)
28074 + {
28075 + case (NET_HEADER_FIELD_ETH_DA):
28076 + return CC_PC_FF_MACDST;
28077 + case (NET_HEADER_FIELD_ETH_SA):
28078 + return CC_PC_FF_MACSRC;
28079 + case (NET_HEADER_FIELD_ETH_TYPE):
28080 + return CC_PC_FF_ETYPE;
28081 + default:
28082 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
28083 + return CC_PC_ILLEGAL;
28084 + }
28085 +
28086 + case (HEADER_TYPE_VLAN):
28087 + switch (field.vlan)
28088 + {
28089 + case (NET_HEADER_FIELD_VLAN_TCI):
28090 + if ((index == e_FM_PCD_HDR_INDEX_NONE)
28091 + || (index == e_FM_PCD_HDR_INDEX_1))
28092 + return CC_PC_FF_TCI1;
28093 + if (index == e_FM_PCD_HDR_INDEX_LAST)
28094 + return CC_PC_FF_TCI2;
28095 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
28096 + return CC_PC_ILLEGAL;
28097 + default:
28098 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
28099 + return CC_PC_ILLEGAL;
28100 + }
28101 +
28102 + case (HEADER_TYPE_MPLS):
28103 + switch (field.mpls)
28104 + {
28105 + case (NET_HEADER_FIELD_MPLS_LABEL_STACK):
28106 + if ((index == e_FM_PCD_HDR_INDEX_NONE)
28107 + || (index == e_FM_PCD_HDR_INDEX_1))
28108 + return CC_PC_FF_MPLS1;
28109 + if (index == e_FM_PCD_HDR_INDEX_LAST)
28110 + return CC_PC_FF_MPLS_LAST;
28111 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal MPLS index"));
28112 + return CC_PC_ILLEGAL;
28113 + default:
28114 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
28115 + return CC_PC_ILLEGAL;
28116 + }
28117 +
28118 + case (HEADER_TYPE_IPv4):
28119 + switch (field.ipv4)
28120 + {
28121 + case (NET_HEADER_FIELD_IPv4_DST_IP):
28122 + if ((index == e_FM_PCD_HDR_INDEX_NONE)
28123 + || (index == e_FM_PCD_HDR_INDEX_1))
28124 + return CC_PC_FF_IPV4DST1;
28125 + if (index == e_FM_PCD_HDR_INDEX_2)
28126 + return CC_PC_FF_IPV4DST2;
28127 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal IPv4 index"));
28128 + return CC_PC_ILLEGAL;
28129 + case (NET_HEADER_FIELD_IPv4_TOS):
28130 + if ((index == e_FM_PCD_HDR_INDEX_NONE)
28131 + || (index == e_FM_PCD_HDR_INDEX_1))
28132 + return CC_PC_FF_IPV4IPTOS_TC1;
28133 + if (index == e_FM_PCD_HDR_INDEX_2)
28134 + return CC_PC_FF_IPV4IPTOS_TC2;
28135 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal IPv4 index"));
28136 + return CC_PC_ILLEGAL;
28137 + case (NET_HEADER_FIELD_IPv4_PROTO):
28138 + if ((index == e_FM_PCD_HDR_INDEX_NONE)
28139 + || (index == e_FM_PCD_HDR_INDEX_1))
28140 + return CC_PC_FF_IPV4PTYPE1;
28141 + if (index == e_FM_PCD_HDR_INDEX_2)
28142 + return CC_PC_FF_IPV4PTYPE2;
28143 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal IPv4 index"));
28144 + return CC_PC_ILLEGAL;
28145 + case (NET_HEADER_FIELD_IPv4_SRC_IP):
28146 + if ((index == e_FM_PCD_HDR_INDEX_NONE)
28147 + || (index == e_FM_PCD_HDR_INDEX_1))
28148 + return CC_PC_FF_IPV4SRC1;
28149 + if (index == e_FM_PCD_HDR_INDEX_2)
28150 + return CC_PC_FF_IPV4SRC2;
28151 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal IPv4 index"));
28152 + return CC_PC_ILLEGAL;
28153 + case (NET_HEADER_FIELD_IPv4_SRC_IP
28154 + | NET_HEADER_FIELD_IPv4_DST_IP):
28155 + if ((index == e_FM_PCD_HDR_INDEX_NONE)
28156 + || (index == e_FM_PCD_HDR_INDEX_1))
28157 + return CC_PC_FF_IPV4SRC1_IPV4DST1;
28158 + if (index == e_FM_PCD_HDR_INDEX_2)
28159 + return CC_PC_FF_IPV4SRC2_IPV4DST2;
28160 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal IPv4 index"));
28161 + return CC_PC_ILLEGAL;
28162 + case (NET_HEADER_FIELD_IPv4_TTL):
28163 + return CC_PC_FF_IPV4TTL;
28164 + default:
28165 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
28166 + return CC_PC_ILLEGAL;
28167 + }
28168 +
28169 + case (HEADER_TYPE_IPv6):
28170 + switch (field.ipv6)
28171 + {
28172 + case (NET_HEADER_FIELD_IPv6_VER | NET_HEADER_FIELD_IPv6_FL
28173 + | NET_HEADER_FIELD_IPv6_TC):
28174 + if ((index == e_FM_PCD_HDR_INDEX_NONE)
28175 + || (index == e_FM_PCD_HDR_INDEX_1))
28176 + return CC_PC_FF_IPTOS_IPV6TC1_IPV6FLOW1;
28177 + if (index == e_FM_PCD_HDR_INDEX_2)
28178 + return CC_PC_FF_IPTOS_IPV6TC2_IPV6FLOW2;
28179 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal IPv6 index"));
28180 + return CC_PC_ILLEGAL;
28181 +
28182 + case (NET_HEADER_FIELD_IPv6_NEXT_HDR):
28183 + if ((index == e_FM_PCD_HDR_INDEX_NONE)
28184 + || (index == e_FM_PCD_HDR_INDEX_1))
28185 + return CC_PC_FF_IPV6PTYPE1;
28186 + if (index == e_FM_PCD_HDR_INDEX_2)
28187 + return CC_PC_FF_IPV6PTYPE2;
28188 + if (index == e_FM_PCD_HDR_INDEX_LAST)
28189 + return CC_PC_FF_IPPID;
28190 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal IPv6 index"));
28191 + return CC_PC_ILLEGAL;
28192 +
28193 + case (NET_HEADER_FIELD_IPv6_DST_IP):
28194 + if ((index == e_FM_PCD_HDR_INDEX_NONE)
28195 + || (index == e_FM_PCD_HDR_INDEX_1))
28196 + return CC_PC_FF_IPV6DST1;
28197 + if (index == e_FM_PCD_HDR_INDEX_2)
28198 + return CC_PC_FF_IPV6DST2;
28199 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal IPv6 index"));
28200 + return CC_PC_ILLEGAL;
28201 +
28202 + case (NET_HEADER_FIELD_IPv6_SRC_IP):
28203 + if ((index == e_FM_PCD_HDR_INDEX_NONE)
28204 + || (index == e_FM_PCD_HDR_INDEX_1))
28205 + return CC_PC_FF_IPV6SRC1;
28206 + if (index == e_FM_PCD_HDR_INDEX_2)
28207 + return CC_PC_FF_IPV6SRC2;
28208 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal IPv6 index"));
28209 + return CC_PC_ILLEGAL;
28210 +
28211 + case (NET_HEADER_FIELD_IPv6_HOP_LIMIT):
28212 + return CC_PC_FF_IPV6HOP_LIMIT;
28213 +
28214 + default:
28215 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
28216 + return CC_PC_ILLEGAL;
28217 + }
28218 +
28219 + case (HEADER_TYPE_IP):
28220 + switch (field.ip)
28221 + {
28222 + case (NET_HEADER_FIELD_IP_DSCP):
28223 + if ((index == e_FM_PCD_HDR_INDEX_NONE)
28224 + || (index == e_FM_PCD_HDR_INDEX_1))
28225 + return CC_PC_FF_IPDSCP;
28226 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal IP index"));
28227 + return CC_PC_ILLEGAL;
28228 +
28229 + case (NET_HEADER_FIELD_IP_PROTO):
28230 + if (index == e_FM_PCD_HDR_INDEX_LAST)
28231 + return CC_PC_FF_IPPID;
28232 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal IP index"));
28233 + return CC_PC_ILLEGAL;
28234 +
28235 + default:
28236 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
28237 + return CC_PC_ILLEGAL;
28238 + }
28239 +
28240 + case (HEADER_TYPE_GRE):
28241 + switch (field.gre)
28242 + {
28243 + case (NET_HEADER_FIELD_GRE_TYPE):
28244 + return CC_PC_FF_GREPTYPE;
28245 +
28246 + default:
28247 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
28248 + return CC_PC_ILLEGAL;
28249 + }
28250 +
28251 + case (HEADER_TYPE_MINENCAP):
28252 + switch (field.minencap)
28253 + {
28254 + case (NET_HEADER_FIELD_MINENCAP_TYPE):
28255 + return CC_PC_FF_MINENCAP_PTYPE;
28256 +
28257 + case (NET_HEADER_FIELD_MINENCAP_DST_IP):
28258 + return CC_PC_FF_MINENCAP_IPDST;
28259 +
28260 + case (NET_HEADER_FIELD_MINENCAP_SRC_IP):
28261 + return CC_PC_FF_MINENCAP_IPSRC;
28262 +
28263 + case (NET_HEADER_FIELD_MINENCAP_SRC_IP
28264 + | NET_HEADER_FIELD_MINENCAP_DST_IP):
28265 + return CC_PC_FF_MINENCAP_IPSRC_IPDST;
28266 +
28267 + default:
28268 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
28269 + return CC_PC_ILLEGAL;
28270 + }
28271 +
28272 + case (HEADER_TYPE_TCP):
28273 + switch (field.tcp)
28274 + {
28275 + case (NET_HEADER_FIELD_TCP_PORT_SRC):
28276 + return CC_PC_FF_L4PSRC;
28277 +
28278 + case (NET_HEADER_FIELD_TCP_PORT_DST):
28279 + return CC_PC_FF_L4PDST;
28280 +
28281 + case (NET_HEADER_FIELD_TCP_PORT_DST
28282 + | NET_HEADER_FIELD_TCP_PORT_SRC):
28283 + return CC_PC_FF_L4PSRC_L4PDST;
28284 +
28285 + default:
28286 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
28287 + return CC_PC_ILLEGAL;
28288 + }
28289 +
28290 + case (HEADER_TYPE_PPPoE):
28291 + switch (field.pppoe)
28292 + {
28293 + case (NET_HEADER_FIELD_PPPoE_PID):
28294 + return CC_PC_FF_PPPPID;
28295 +
28296 + default:
28297 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
28298 + return CC_PC_ILLEGAL;
28299 + }
28300 +
28301 + case (HEADER_TYPE_UDP):
28302 + switch (field.udp)
28303 + {
28304 + case (NET_HEADER_FIELD_UDP_PORT_SRC):
28305 + return CC_PC_FF_L4PSRC;
28306 +
28307 + case (NET_HEADER_FIELD_UDP_PORT_DST):
28308 + return CC_PC_FF_L4PDST;
28309 +
28310 + case (NET_HEADER_FIELD_UDP_PORT_DST
28311 + | NET_HEADER_FIELD_UDP_PORT_SRC):
28312 + return CC_PC_FF_L4PSRC_L4PDST;
28313 +
28314 + default:
28315 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
28316 + return CC_PC_ILLEGAL;
28317 + }
28318 +
28319 + default:
28320 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
28321 + return CC_PC_ILLEGAL;
28322 + }
28323 +}
28324 +
28325 +static uint8_t GetPrParseCode(e_NetHeaderType hdr, e_FmPcdHdrIndex hdrIndex,
28326 + uint32_t offset, bool glblMask,
28327 + uint8_t *parseArrayOffset)
28328 +{
28329 + bool offsetRelevant = FALSE;
28330 +
28331 + if (offset)
28332 + offsetRelevant = TRUE;
28333 +
28334 + switch (hdr)
28335 + {
28336 + case (HEADER_TYPE_NONE):
28337 + ASSERT_COND(FALSE);
28338 + return CC_PC_ILLEGAL;
28339 +
28340 + case (HEADER_TYPE_ETH):
28341 + *parseArrayOffset = (uint8_t)CC_PC_PR_ETH_OFFSET;
28342 + break;
28343 +
28344 + case (HEADER_TYPE_USER_DEFINED_SHIM1):
28345 + if (offset || glblMask)
28346 + *parseArrayOffset = (uint8_t)CC_PC_PR_USER_DEFINED_SHIM1_OFFSET;
28347 + else
28348 + return CC_PC_PR_SHIM1;
28349 + break;
28350 +
28351 + case (HEADER_TYPE_USER_DEFINED_SHIM2):
28352 + if (offset || glblMask)
28353 + *parseArrayOffset = (uint8_t)CC_PC_PR_USER_DEFINED_SHIM2_OFFSET;
28354 + else
28355 + return CC_PC_PR_SHIM2;
28356 + break;
28357 +
28358 + case (HEADER_TYPE_LLC_SNAP):
28359 + *parseArrayOffset = CC_PC_PR_USER_LLC_SNAP_OFFSET;
28360 + break;
28361 +
28362 + case (HEADER_TYPE_PPPoE):
28363 + *parseArrayOffset = CC_PC_PR_PPPOE_OFFSET;
28364 + break;
28365 +
28366 + case (HEADER_TYPE_MPLS):
28367 + if ((hdrIndex == e_FM_PCD_HDR_INDEX_NONE)
28368 + || (hdrIndex == e_FM_PCD_HDR_INDEX_1))
28369 + *parseArrayOffset = CC_PC_PR_MPLS1_OFFSET;
28370 + else
28371 + if (hdrIndex == e_FM_PCD_HDR_INDEX_LAST)
28372 + *parseArrayOffset = CC_PC_PR_MPLS_LAST_OFFSET;
28373 + else
28374 + {
28375 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal MPLS header index"));
28376 + return CC_PC_ILLEGAL;
28377 + }
28378 + break;
28379 +
28380 + case (HEADER_TYPE_IPv4):
28381 + case (HEADER_TYPE_IPv6):
28382 + if ((hdrIndex == e_FM_PCD_HDR_INDEX_NONE)
28383 + || (hdrIndex == e_FM_PCD_HDR_INDEX_1))
28384 + *parseArrayOffset = CC_PC_PR_IP1_OFFSET;
28385 + else
28386 + if (hdrIndex == e_FM_PCD_HDR_INDEX_2)
28387 + *parseArrayOffset = CC_PC_PR_IP_LAST_OFFSET;
28388 + else
28389 + {
28390 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal IP header index"));
28391 + return CC_PC_ILLEGAL;
28392 + }
28393 + break;
28394 +
28395 + case (HEADER_TYPE_MINENCAP):
28396 + *parseArrayOffset = CC_PC_PR_MINENC_OFFSET;
28397 + break;
28398 +
28399 + case (HEADER_TYPE_GRE):
28400 + *parseArrayOffset = CC_PC_PR_GRE_OFFSET;
28401 + break;
28402 +
28403 + case (HEADER_TYPE_TCP):
28404 + case (HEADER_TYPE_UDP):
28405 + case (HEADER_TYPE_IPSEC_AH):
28406 + case (HEADER_TYPE_IPSEC_ESP):
28407 + case (HEADER_TYPE_DCCP):
28408 + case (HEADER_TYPE_SCTP):
28409 + *parseArrayOffset = CC_PC_PR_L4_OFFSET;
28410 + break;
28411 +
28412 + default:
28413 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal IP header for this type of operation"));
28414 + return CC_PC_ILLEGAL;
28415 + }
28416 +
28417 + if (offsetRelevant)
28418 + return CC_PR_OFFSET;
28419 + else
28420 + return CC_PR_WITHOUT_OFFSET;
28421 +}
28422 +
28423 +static uint8_t GetFieldParseCode(e_NetHeaderType hdr, t_FmPcdFields field,
28424 + uint32_t offset, uint8_t *parseArrayOffset,
28425 + e_FmPcdHdrIndex hdrIndex)
28426 +{
28427 + bool offsetRelevant = FALSE;
28428 +
28429 + if (offset)
28430 + offsetRelevant = TRUE;
28431 +
28432 + switch (hdr)
28433 + {
28434 + case (HEADER_TYPE_NONE):
28435 + ASSERT_COND(FALSE);
28436 + break;
28437 + case (HEADER_TYPE_ETH):
28438 + switch (field.eth)
28439 + {
28440 + case (NET_HEADER_FIELD_ETH_TYPE):
28441 + *parseArrayOffset = CC_PC_PR_ETYPE_LAST_OFFSET;
28442 + break;
28443 +
28444 + default:
28445 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
28446 + return CC_PC_ILLEGAL;
28447 + }
28448 + break;
28449 +
28450 + case (HEADER_TYPE_VLAN):
28451 + switch (field.vlan)
28452 + {
28453 + case (NET_HEADER_FIELD_VLAN_TCI):
28454 + if ((hdrIndex == e_FM_PCD_HDR_INDEX_NONE)
28455 + || (hdrIndex == e_FM_PCD_HDR_INDEX_1))
28456 + *parseArrayOffset = CC_PC_PR_VLAN1_OFFSET;
28457 + else
28458 + if (hdrIndex == e_FM_PCD_HDR_INDEX_LAST)
28459 + *parseArrayOffset = CC_PC_PR_VLAN2_OFFSET;
28460 + break;
28461 +
28462 + default:
28463 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
28464 + return CC_PC_ILLEGAL;
28465 + }
28466 + break;
28467 +
28468 + default:
28469 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal header "));
28470 + return CC_PC_ILLEGAL;
28471 + }
28472 +
28473 + if (offsetRelevant)
28474 + return CC_PR_OFFSET;
28475 + else
28476 + return CC_PR_WITHOUT_OFFSET;
28477 +}
28478 +
28479 +static void FillAdOfTypeResult(t_Handle h_Ad,
28480 + t_FmPcdCcStatsParams *p_FmPcdCcStatsParams,
28481 + t_FmPcd *p_FmPcd,
28482 + t_FmPcdCcNextEngineParams *p_CcNextEngineParams)
28483 +{
28484 + t_AdOfTypeResult *p_AdResult = (t_AdOfTypeResult *)h_Ad;
28485 + t_Handle h_TmpAd;
28486 + uint32_t tmp = 0, tmpNia = 0;
28487 + uint16_t profileId;
28488 + t_Handle p_AdNewPtr = NULL;
28489 + t_Error err = E_OK;
28490 +
28491 + /* There are 3 cases handled in this routine of building a "result" type AD.
28492 + * Case 1: No Manip. The action descriptor is built within the match table.
28493 + * Case 2: Manip exists. A new AD is created - p_AdNewPtr. It is initialized
28494 + * either in the FmPcdManipUpdateAdResultForCc routine or it was already
28495 + * initialized and returned here.
28496 + * p_AdResult (within the match table) will be initialized after
28497 + * this routine returns and point to the existing AD.
28498 + * Case 3: Manip exists. The action descriptor is built within the match table.
28499 + * FmPcdManipUpdateAdResultForCc returns a NULL p_AdNewPtr.
28500 + *
28501 + * If statistics were enabled and the statistics mode of this node requires
28502 + * a statistics Ad, it will be placed after the result Ad and before the
28503 + * manip Ad, if manip Ad exists here.
28504 + */
28505 +
28506 + /* As default, the "new" ptr is the current one. i.e. the content of the result
28507 + * AD will be written into the match table itself (case (1))*/
28508 + p_AdNewPtr = p_AdResult;
28509 +
28510 + /* Initialize an action descriptor, if current statistics mode requires an Ad */
28511 + if (p_FmPcdCcStatsParams)
28512 + {
28513 + ASSERT_COND(p_FmPcdCcStatsParams->h_StatsAd);
28514 + ASSERT_COND(p_FmPcdCcStatsParams->h_StatsCounters);
28515 +
28516 + /* Swapping addresses between statistics Ad and the current lookup AD addresses */
28517 + h_TmpAd = p_FmPcdCcStatsParams->h_StatsAd;
28518 + p_FmPcdCcStatsParams->h_StatsAd = h_Ad;
28519 + h_Ad = h_TmpAd;
28520 +
28521 + p_AdNewPtr = h_Ad;
28522 + p_AdResult = h_Ad;
28523 +
28524 + /* Init statistics Ad and connect current lookup AD as 'next action' from statistics Ad */
28525 + UpdateStatsAd(p_FmPcdCcStatsParams, h_Ad, p_FmPcd->physicalMuramBase);
28526 + }
28527 +
28528 + /* Create manip and return p_AdNewPtr to either a new descriptor or NULL */
28529 + if (p_CcNextEngineParams->h_Manip)
28530 + FmPcdManipUpdateAdResultForCc(p_CcNextEngineParams->h_Manip,
28531 + p_CcNextEngineParams, h_Ad, &p_AdNewPtr);
28532 +
28533 + /* if (p_AdNewPtr = NULL) --> Done. (case (3)) */
28534 + if (p_AdNewPtr)
28535 + {
28536 + /* case (1) and (2) */
28537 + switch (p_CcNextEngineParams->nextEngine)
28538 + {
28539 + case (e_FM_PCD_DONE):
28540 + if (p_CcNextEngineParams->params.enqueueParams.action
28541 + == e_FM_PCD_ENQ_FRAME)
28542 + {
28543 + if (p_CcNextEngineParams->params.enqueueParams.overrideFqid)
28544 + {
28545 + tmp = FM_PCD_AD_RESULT_CONTRL_FLOW_TYPE;
28546 + tmp |=
28547 + p_CcNextEngineParams->params.enqueueParams.newFqid;
28548 +#if (DPAA_VERSION >= 11)
28549 + tmp |=
28550 + (p_CcNextEngineParams->params.enqueueParams.newRelativeStorageProfileId
28551 + & FM_PCD_AD_RESULT_VSP_MASK)
28552 + << FM_PCD_AD_RESULT_VSP_SHIFT;
28553 +#endif /* (DPAA_VERSION >= 11) */
28554 + }
28555 + else
28556 + {
28557 + tmp = FM_PCD_AD_RESULT_DATA_FLOW_TYPE;
28558 + tmp |= FM_PCD_AD_RESULT_PLCR_DIS;
28559 + }
28560 + }
28561 +
28562 + if (p_CcNextEngineParams->params.enqueueParams.action
28563 + == e_FM_PCD_DROP_FRAME)
28564 + tmpNia |= GET_NIA_BMI_AC_DISCARD_FRAME(p_FmPcd);
28565 + else
28566 + tmpNia |= GET_NIA_BMI_AC_ENQ_FRAME(p_FmPcd);
28567 + break;
28568 +
28569 + case (e_FM_PCD_KG):
28570 + if (p_CcNextEngineParams->params.kgParams.overrideFqid)
28571 + {
28572 + tmp = FM_PCD_AD_RESULT_CONTRL_FLOW_TYPE;
28573 + tmp |= p_CcNextEngineParams->params.kgParams.newFqid;
28574 +#if (DPAA_VERSION >= 11)
28575 + tmp |=
28576 + (p_CcNextEngineParams->params.kgParams.newRelativeStorageProfileId
28577 + & FM_PCD_AD_RESULT_VSP_MASK)
28578 + << FM_PCD_AD_RESULT_VSP_SHIFT;
28579 +#endif /* (DPAA_VERSION >= 11) */
28580 + }
28581 + else
28582 + {
28583 + tmp = FM_PCD_AD_RESULT_DATA_FLOW_TYPE;
28584 + tmp |= FM_PCD_AD_RESULT_PLCR_DIS;
28585 + }
28586 + tmpNia = NIA_KG_DIRECT;
28587 + tmpNia |= NIA_ENG_KG;
28588 + tmpNia |= NIA_KG_CC_EN;
28589 + tmpNia |= FmPcdKgGetSchemeId(
28590 + p_CcNextEngineParams->params.kgParams.h_DirectScheme);
28591 + break;
28592 +
28593 + case (e_FM_PCD_PLCR):
28594 + if (p_CcNextEngineParams->params.plcrParams.overrideParams)
28595 + {
28596 + tmp = FM_PCD_AD_RESULT_CONTRL_FLOW_TYPE;
28597 +
28598 + /* if private policer profile, it may be uninitialized yet, therefore no checks are done at this stage */
28599 + if (p_CcNextEngineParams->params.plcrParams.sharedProfile)
28600 + {
28601 + tmpNia |= NIA_PLCR_ABSOLUTE;
28602 + err = FmPcdPlcrGetAbsoluteIdByProfileParams(
28603 + (t_Handle)p_FmPcd,
28604 + e_FM_PCD_PLCR_SHARED,
28605 + NULL,
28606 + p_CcNextEngineParams->params.plcrParams.newRelativeProfileId,
28607 + &profileId);
28608 +
28609 + if (err != E_OK) {
28610 + REPORT_ERROR(MAJOR, err, NO_MSG);
28611 + return;
28612 + }
28613 +
28614 + }
28615 + else
28616 + profileId =
28617 + p_CcNextEngineParams->params.plcrParams.newRelativeProfileId;
28618 +
28619 + tmp |= p_CcNextEngineParams->params.plcrParams.newFqid;
28620 +#if (DPAA_VERSION >= 11)
28621 + tmp |=
28622 + (p_CcNextEngineParams->params.plcrParams.newRelativeStorageProfileId
28623 + & FM_PCD_AD_RESULT_VSP_MASK)
28624 + << FM_PCD_AD_RESULT_VSP_SHIFT;
28625 +#endif /* (DPAA_VERSION >= 11) */
28626 + WRITE_UINT32(
28627 + p_AdResult->plcrProfile,
28628 + (uint32_t)((uint32_t)profileId << FM_PCD_AD_PROFILEID_FOR_CNTRL_SHIFT));
28629 + }
28630 + else
28631 + tmp = FM_PCD_AD_RESULT_DATA_FLOW_TYPE;
28632 +
28633 + tmpNia |=
28634 + NIA_ENG_PLCR
28635 + | p_CcNextEngineParams->params.plcrParams.newRelativeProfileId;
28636 + break;
28637 +
28638 + default:
28639 + return;
28640 + }WRITE_UINT32(p_AdResult->fqid, tmp);
28641 +
28642 + if (p_CcNextEngineParams->h_Manip)
28643 + {
28644 + tmp = GET_UINT32(p_AdResult->plcrProfile);
28645 + tmp |= (uint32_t)(XX_VirtToPhys(p_AdNewPtr)
28646 + - (p_FmPcd->physicalMuramBase)) >> 4;
28647 + WRITE_UINT32(p_AdResult->plcrProfile, tmp);
28648 +
28649 + tmpNia |= FM_PCD_AD_RESULT_EXTENDED_MODE;
28650 + tmpNia |= FM_PCD_AD_RESULT_NADEN;
28651 + }
28652 +
28653 +#if (DPAA_VERSION >= 11)
28654 + tmpNia |= FM_PCD_AD_RESULT_NO_OM_VSPE;
28655 +#endif /* (DPAA_VERSION >= 11) */
28656 + WRITE_UINT32(p_AdResult->nia, tmpNia);
28657 + }
28658 +}
28659 +
28660 +static t_Error CcUpdateParams(t_Handle h_FmPcd, t_Handle h_PcdParams,
28661 + t_Handle h_FmPort, t_Handle h_FmTree,
28662 + bool validate)
28663 +{
28664 + t_FmPcdCcTree *p_CcTree = (t_FmPcdCcTree *)h_FmTree;
28665 +
28666 + return CcUpdateParam(h_FmPcd, h_PcdParams, h_FmPort,
28667 + p_CcTree->keyAndNextEngineParams,
28668 + p_CcTree->numOfEntries,
28669 + UINT_TO_PTR(p_CcTree->ccTreeBaseAddr), validate, 0,
28670 + h_FmTree, FALSE);
28671 +}
28672 +
28673 +
28674 +static void ReleaseNewNodeCommonPart(
28675 + t_FmPcdModifyCcKeyAdditionalParams *p_AdditionalInfo)
28676 +{
28677 + if (p_AdditionalInfo->p_AdTableNew)
28678 + FM_MURAM_FreeMem(
28679 + FmPcdGetMuramHandle(
28680 + ((t_FmPcdCcNode *)(p_AdditionalInfo->h_CurrentNode))->h_FmPcd),
28681 + p_AdditionalInfo->p_AdTableNew);
28682 +
28683 + if (p_AdditionalInfo->p_KeysMatchTableNew)
28684 + FM_MURAM_FreeMem(
28685 + FmPcdGetMuramHandle(
28686 + ((t_FmPcdCcNode *)(p_AdditionalInfo->h_CurrentNode))->h_FmPcd),
28687 + p_AdditionalInfo->p_KeysMatchTableNew);
28688 +}
28689 +
28690 +static t_Error UpdateGblMask(t_FmPcdCcNode *p_CcNode, uint8_t keySize,
28691 + uint8_t *p_Mask)
28692 +{
28693 + uint8_t prvGlblMaskSize = p_CcNode->glblMaskSize;
28694 +
28695 + if (p_Mask && !p_CcNode->glblMaskUpdated && (keySize <= 4)
28696 + && !p_CcNode->lclMask)
28697 + {
28698 + if (p_CcNode->parseCode && (p_CcNode->parseCode != CC_PC_FF_TCI1)
28699 + && (p_CcNode->parseCode != CC_PC_FF_TCI2)
28700 + && (p_CcNode->parseCode != CC_PC_FF_MPLS1)
28701 + && (p_CcNode->parseCode != CC_PC_FF_MPLS_LAST)
28702 + && (p_CcNode->parseCode != CC_PC_FF_IPV4IPTOS_TC1)
28703 + && (p_CcNode->parseCode != CC_PC_FF_IPV4IPTOS_TC2)
28704 + && (p_CcNode->parseCode != CC_PC_FF_IPTOS_IPV6TC1_IPV6FLOW1)
28705 + && (p_CcNode->parseCode != CC_PC_FF_IPDSCP)
28706 + && (p_CcNode->parseCode != CC_PC_FF_IPTOS_IPV6TC2_IPV6FLOW2))
28707 + {
28708 + p_CcNode->glblMaskSize = 0;
28709 + p_CcNode->lclMask = TRUE;
28710 + }
28711 + else
28712 + {
28713 + memcpy(p_CcNode->p_GlblMask, p_Mask, (sizeof(uint8_t)) * keySize);
28714 + p_CcNode->glblMaskUpdated = TRUE;
28715 + p_CcNode->glblMaskSize = 4;
28716 + }
28717 + }
28718 + else
28719 + if (p_Mask && (keySize <= 4) && !p_CcNode->lclMask)
28720 + {
28721 + if (memcmp(p_CcNode->p_GlblMask, p_Mask, keySize) != 0)
28722 + {
28723 + p_CcNode->lclMask = TRUE;
28724 + p_CcNode->glblMaskSize = 0;
28725 + }
28726 + }
28727 + else
28728 + if (!p_Mask && p_CcNode->glblMaskUpdated && (keySize <= 4))
28729 + {
28730 + uint32_t tmpMask = 0xffffffff;
28731 + if (memcmp(p_CcNode->p_GlblMask, &tmpMask, 4) != 0)
28732 + {
28733 + p_CcNode->lclMask = TRUE;
28734 + p_CcNode->glblMaskSize = 0;
28735 + }
28736 + }
28737 + else
28738 + if (p_Mask)
28739 + {
28740 + p_CcNode->lclMask = TRUE;
28741 + p_CcNode->glblMaskSize = 0;
28742 + }
28743 +
28744 + /* In static mode (maxNumOfKeys > 0), local mask is supported
28745 + only is mask support was enabled at initialization */
28746 + if (p_CcNode->maxNumOfKeys && (!p_CcNode->maskSupport) && p_CcNode->lclMask)
28747 + {
28748 + p_CcNode->lclMask = FALSE;
28749 + p_CcNode->glblMaskSize = prvGlblMaskSize;
28750 + return ERROR_CODE(E_NOT_SUPPORTED);
28751 + }
28752 +
28753 + return E_OK;
28754 +}
28755 +
28756 +static __inline__ t_Handle GetNewAd(t_Handle h_FmPcdCcNodeOrTree, bool isTree)
28757 +{
28758 + t_FmPcd *p_FmPcd;
28759 + t_Handle h_Ad;
28760 +
28761 + if (isTree)
28762 + p_FmPcd = (t_FmPcd *)(((t_FmPcdCcTree *)h_FmPcdCcNodeOrTree)->h_FmPcd);
28763 + else
28764 + p_FmPcd = (t_FmPcd *)(((t_FmPcdCcNode *)h_FmPcdCcNodeOrTree)->h_FmPcd);
28765 +
28766 + if ((isTree && p_FmPcd->p_CcShadow)
28767 + || (!isTree && ((t_FmPcdCcNode *)h_FmPcdCcNodeOrTree)->maxNumOfKeys))
28768 + {
28769 + /* The allocated shadow is divided as follows:
28770 + 0 . . . 16 . . .
28771 + ---------------------------------------------------
28772 + | Shadow | Shadow Keys | Shadow Next |
28773 + | Ad | Match Table | Engine Table |
28774 + | (16 bytes) | (maximal size) | (maximal size) |
28775 + ---------------------------------------------------
28776 + */
28777 + if (!p_FmPcd->p_CcShadow)
28778 + {
28779 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("CC Shadow not allocated"));
28780 + return NULL;
28781 + }
28782 +
28783 + h_Ad = p_FmPcd->p_CcShadow;
28784 + }
28785 + else
28786 + {
28787 + h_Ad = (t_Handle)FM_MURAM_AllocMem(FmPcdGetMuramHandle(p_FmPcd),
28788 + FM_PCD_CC_AD_ENTRY_SIZE,
28789 + FM_PCD_CC_AD_TABLE_ALIGN);
28790 + if (!h_Ad)
28791 + {
28792 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("MURAM allocation for CC node action descriptor"));
28793 + return NULL;
28794 + }
28795 + }
28796 +
28797 + return h_Ad;
28798 +}
28799 +
28800 +static t_Error BuildNewNodeCommonPart(
28801 + t_FmPcdCcNode *p_CcNode, int *size,
28802 + t_FmPcdModifyCcKeyAdditionalParams *p_AdditionalInfo)
28803 +{
28804 + t_FmPcd *p_FmPcd = (t_FmPcd *)p_CcNode->h_FmPcd;
28805 +
28806 + if (p_CcNode->lclMask)
28807 + *size = 2 * p_CcNode->ccKeySizeAccExtraction;
28808 + else
28809 + *size = p_CcNode->ccKeySizeAccExtraction;
28810 +
28811 + if (p_CcNode->maxNumOfKeys == 0)
28812 + {
28813 + p_AdditionalInfo->p_AdTableNew = (t_Handle)FM_MURAM_AllocMem(
28814 + FmPcdGetMuramHandle(p_FmPcd),
28815 + (uint32_t)((p_AdditionalInfo->numOfKeys + 1)
28816 + * FM_PCD_CC_AD_ENTRY_SIZE),
28817 + FM_PCD_CC_AD_TABLE_ALIGN);
28818 + if (!p_AdditionalInfo->p_AdTableNew)
28819 + RETURN_ERROR(
28820 + MAJOR, E_NO_MEMORY,
28821 + ("MURAM allocation for CC node action descriptors table"));
28822 +
28823 + p_AdditionalInfo->p_KeysMatchTableNew = (t_Handle)FM_MURAM_AllocMem(
28824 + FmPcdGetMuramHandle(p_FmPcd),
28825 + (uint32_t)(*size * sizeof(uint8_t)
28826 + * (p_AdditionalInfo->numOfKeys + 1)),
28827 + FM_PCD_CC_KEYS_MATCH_TABLE_ALIGN);
28828 + if (!p_AdditionalInfo->p_KeysMatchTableNew)
28829 + {
28830 + FM_MURAM_FreeMem(FmPcdGetMuramHandle(p_CcNode->h_FmPcd),
28831 + p_AdditionalInfo->p_AdTableNew);
28832 + p_AdditionalInfo->p_AdTableNew = NULL;
28833 + RETURN_ERROR(MAJOR, E_NO_MEMORY,
28834 + ("MURAM allocation for CC node key match table"));
28835 + }
28836 +
28837 + MemSet8(
28838 + (uint8_t*)p_AdditionalInfo->p_AdTableNew,
28839 + 0,
28840 + (uint32_t)((p_AdditionalInfo->numOfKeys + 1)
28841 + * FM_PCD_CC_AD_ENTRY_SIZE));
28842 + MemSet8((uint8_t*)p_AdditionalInfo->p_KeysMatchTableNew, 0,
28843 + *size * sizeof(uint8_t) * (p_AdditionalInfo->numOfKeys + 1));
28844 + }
28845 + else
28846 + {
28847 + /* The allocated shadow is divided as follows:
28848 + 0 . . . 16 . . .
28849 + ---------------------------------------------------
28850 + | Shadow | Shadow Keys | Shadow Next |
28851 + | Ad | Match Table | Engine Table |
28852 + | (16 bytes) | (maximal size) | (maximal size) |
28853 + ---------------------------------------------------
28854 + */
28855 +
28856 + if (!p_FmPcd->p_CcShadow)
28857 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("CC Shadow not allocated"));
28858 +
28859 + p_AdditionalInfo->p_KeysMatchTableNew =
28860 + PTR_MOVE(p_FmPcd->p_CcShadow, FM_PCD_CC_AD_ENTRY_SIZE);
28861 + p_AdditionalInfo->p_AdTableNew =
28862 + PTR_MOVE(p_AdditionalInfo->p_KeysMatchTableNew, p_CcNode->keysMatchTableMaxSize);
28863 +
28864 + MemSet8(
28865 + (uint8_t*)p_AdditionalInfo->p_AdTableNew,
28866 + 0,
28867 + (uint32_t)((p_CcNode->maxNumOfKeys + 1)
28868 + * FM_PCD_CC_AD_ENTRY_SIZE));
28869 + MemSet8((uint8_t*)p_AdditionalInfo->p_KeysMatchTableNew, 0,
28870 + (*size) * sizeof(uint8_t) * (p_CcNode->maxNumOfKeys));
28871 + }
28872 +
28873 + p_AdditionalInfo->p_AdTableOld = p_CcNode->h_AdTable;
28874 + p_AdditionalInfo->p_KeysMatchTableOld = p_CcNode->h_KeysMatchTable;
28875 +
28876 + return E_OK;
28877 +}
28878 +
28879 +static t_Error BuildNewNodeAddOrMdfyKeyAndNextEngine(
28880 + t_Handle h_FmPcd, t_FmPcdCcNode *p_CcNode, uint16_t keyIndex,
28881 + t_FmPcdCcKeyParams *p_KeyParams,
28882 + t_FmPcdModifyCcKeyAdditionalParams *p_AdditionalInfo, bool add)
28883 +{
28884 + t_Error err = E_OK;
28885 + t_Handle p_AdTableNewTmp, p_KeysMatchTableNewTmp;
28886 + t_Handle p_KeysMatchTableOldTmp, p_AdTableOldTmp;
28887 + int size;
28888 + int i = 0, j = 0;
28889 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
28890 + uint32_t requiredAction = 0;
28891 + bool prvLclMask;
28892 + t_CcNodeInformation *p_CcNodeInformation;
28893 + t_FmPcdCcStatsParams statsParams = { 0 };
28894 + t_List *p_Pos;
28895 + t_FmPcdStatsObj *p_StatsObj;
28896 +
28897 + /* Check that new NIA is legal */
28898 + err = ValidateNextEngineParams(h_FmPcd, &p_KeyParams->ccNextEngineParams,
28899 + p_CcNode->statisticsMode);
28900 + if (err)
28901 + RETURN_ERROR(MAJOR, err, NO_MSG);
28902 +
28903 + prvLclMask = p_CcNode->lclMask;
28904 +
28905 + /* Check that new key is not require update of localMask */
28906 + err = UpdateGblMask(p_CcNode, p_CcNode->ccKeySizeAccExtraction,
28907 + p_KeyParams->p_Mask);
28908 + if (err)
28909 + RETURN_ERROR(MAJOR, err, (NO_MSG));
28910 +
28911 + /* Update internal data structure with new next engine for the given index */
28912 + memcpy(&p_AdditionalInfo->keyAndNextEngineParams[keyIndex].nextEngineParams,
28913 + &p_KeyParams->ccNextEngineParams, sizeof(t_FmPcdCcNextEngineParams));
28914 +
28915 + memcpy(p_AdditionalInfo->keyAndNextEngineParams[keyIndex].key,
28916 + p_KeyParams->p_Key, p_CcNode->userSizeOfExtraction);
28917 +
28918 + if ((p_AdditionalInfo->keyAndNextEngineParams[keyIndex].nextEngineParams.nextEngine
28919 + == e_FM_PCD_CC)
28920 + && p_AdditionalInfo->keyAndNextEngineParams[keyIndex].nextEngineParams.h_Manip)
28921 + {
28922 + err =
28923 + AllocAndFillAdForContLookupManip(
28924 + p_AdditionalInfo->keyAndNextEngineParams[keyIndex].nextEngineParams.params.ccParams.h_CcNode);
28925 + if (err)
28926 + RETURN_ERROR(MAJOR, err, (NO_MSG));
28927 + }
28928 +
28929 + if (p_KeyParams->p_Mask)
28930 + memcpy(p_AdditionalInfo->keyAndNextEngineParams[keyIndex].mask,
28931 + p_KeyParams->p_Mask, p_CcNode->userSizeOfExtraction);
28932 + else
28933 + memset(p_AdditionalInfo->keyAndNextEngineParams[keyIndex].mask, 0xFF,
28934 + p_CcNode->userSizeOfExtraction);
28935 +
28936 + /* Update numOfKeys */
28937 + if (add)
28938 + p_AdditionalInfo->numOfKeys = (uint8_t)(p_CcNode->numOfKeys + 1);
28939 + else
28940 + p_AdditionalInfo->numOfKeys = (uint8_t)p_CcNode->numOfKeys;
28941 +
28942 + /* Allocate new tables in MURAM: keys match table and action descriptors table */
28943 + err = BuildNewNodeCommonPart(p_CcNode, &size, p_AdditionalInfo);
28944 + if (err)
28945 + RETURN_ERROR(MAJOR, err, NO_MSG);
28946 +
28947 + /* Check that manip is legal and what requiredAction is necessary for this manip */
28948 + if (p_KeyParams->ccNextEngineParams.h_Manip)
28949 + {
28950 + err = FmPcdManipCheckParamsForCcNextEngine(
28951 + &p_KeyParams->ccNextEngineParams, &requiredAction);
28952 + if (err)
28953 + RETURN_ERROR(MAJOR, err, (NO_MSG));
28954 + }
28955 +
28956 + p_AdditionalInfo->keyAndNextEngineParams[keyIndex].requiredAction =
28957 + requiredAction;
28958 + p_AdditionalInfo->keyAndNextEngineParams[keyIndex].requiredAction |=
28959 + UPDATE_CC_WITH_TREE;
28960 +
28961 + /* Update new Ad and new Key Table according to new requirement */
28962 + i = 0;
28963 + for (j = 0; j < p_AdditionalInfo->numOfKeys; j++)
28964 + {
28965 + p_AdTableNewTmp =
28966 + PTR_MOVE(p_AdditionalInfo->p_AdTableNew, j*FM_PCD_CC_AD_ENTRY_SIZE);
28967 +
28968 + if (j == keyIndex)
28969 + {
28970 + if (p_KeyParams->ccNextEngineParams.statisticsEn)
28971 + {
28972 + /* Allocate a statistics object that holds statistics AD and counters.
28973 + - For added key - New statistics AD and counters pointer need to be allocated
28974 + new statistics object. If statistics were enabled, we need to replace the
28975 + existing descriptor with a new descriptor with nullified counters.
28976 + */
28977 + p_StatsObj = GetStatsObj(p_CcNode);
28978 + ASSERT_COND(p_StatsObj);
28979 +
28980 + /* Store allocated statistics object */
28981 + ASSERT_COND(keyIndex < CC_MAX_NUM_OF_KEYS);
28982 + p_AdditionalInfo->keyAndNextEngineParams[keyIndex].p_StatsObj =
28983 + p_StatsObj;
28984 +
28985 + statsParams.h_StatsAd = p_StatsObj->h_StatsAd;
28986 + statsParams.h_StatsCounters = p_StatsObj->h_StatsCounters;
28987 +#if (DPAA_VERSION >= 11)
28988 + statsParams.h_StatsFLRs = p_CcNode->h_StatsFLRs;
28989 +
28990 +#endif /* (DPAA_VERSION >= 11) */
28991 +
28992 + /* Building action descriptor for the received new key */
28993 + NextStepAd(p_AdTableNewTmp, &statsParams,
28994 + &p_KeyParams->ccNextEngineParams, p_FmPcd);
28995 + }
28996 + else
28997 + {
28998 + /* Building action descriptor for the received new key */
28999 + NextStepAd(p_AdTableNewTmp, NULL,
29000 + &p_KeyParams->ccNextEngineParams, p_FmPcd);
29001 + }
29002 +
29003 + /* Copy the received new key into keys match table */
29004 + p_KeysMatchTableNewTmp =
29005 + PTR_MOVE(p_AdditionalInfo->p_KeysMatchTableNew, j*size*sizeof(uint8_t));
29006 +
29007 + MemCpy8((void*)p_KeysMatchTableNewTmp, p_KeyParams->p_Key,
29008 + p_CcNode->userSizeOfExtraction);
29009 +
29010 + /* Update mask for the received new key */
29011 + if (p_CcNode->lclMask)
29012 + {
29013 + if (p_KeyParams->p_Mask)
29014 + {
29015 + MemCpy8(PTR_MOVE(p_KeysMatchTableNewTmp,
29016 + p_CcNode->ccKeySizeAccExtraction),
29017 + p_KeyParams->p_Mask,
29018 + p_CcNode->userSizeOfExtraction);
29019 + }
29020 + else
29021 + if (p_CcNode->ccKeySizeAccExtraction > 4)
29022 + {
29023 + MemSet8(PTR_MOVE(p_KeysMatchTableNewTmp,
29024 + p_CcNode->ccKeySizeAccExtraction),
29025 + 0xff, p_CcNode->userSizeOfExtraction);
29026 + }
29027 + else
29028 + {
29029 + MemCpy8(PTR_MOVE(p_KeysMatchTableNewTmp,
29030 + p_CcNode->ccKeySizeAccExtraction),
29031 + p_CcNode->p_GlblMask,
29032 + p_CcNode->userSizeOfExtraction);
29033 + }
29034 + }
29035 +
29036 + /* If key modification requested, the old entry is omitted and replaced by the new parameters */
29037 + if (!add)
29038 + i++;
29039 + }
29040 + else
29041 + {
29042 + /* Copy existing action descriptors to the newly allocated Ad table */
29043 + p_AdTableOldTmp =
29044 + PTR_MOVE(p_AdditionalInfo->p_AdTableOld, i*FM_PCD_CC_AD_ENTRY_SIZE);
29045 + MemCpy8(p_AdTableNewTmp, p_AdTableOldTmp,
29046 + FM_PCD_CC_AD_ENTRY_SIZE);
29047 +
29048 + /* Copy existing keys and their masks to the newly allocated keys match table */
29049 + p_KeysMatchTableNewTmp =
29050 + PTR_MOVE(p_AdditionalInfo->p_KeysMatchTableNew, j * size * sizeof(uint8_t));
29051 + p_KeysMatchTableOldTmp =
29052 + PTR_MOVE(p_AdditionalInfo->p_KeysMatchTableOld, i * size * sizeof(uint8_t));
29053 +
29054 + if (p_CcNode->lclMask)
29055 + {
29056 + if (prvLclMask)
29057 + {
29058 + MemCpy8(
29059 + PTR_MOVE(p_KeysMatchTableNewTmp, p_CcNode->ccKeySizeAccExtraction),
29060 + PTR_MOVE(p_KeysMatchTableOldTmp, p_CcNode->ccKeySizeAccExtraction),
29061 + p_CcNode->ccKeySizeAccExtraction);
29062 + }
29063 + else
29064 + {
29065 + p_KeysMatchTableOldTmp =
29066 + PTR_MOVE(p_CcNode->h_KeysMatchTable,
29067 + i * (int)p_CcNode->ccKeySizeAccExtraction * sizeof(uint8_t));
29068 +
29069 + if (p_CcNode->ccKeySizeAccExtraction > 4)
29070 + {
29071 + MemSet8(PTR_MOVE(p_KeysMatchTableNewTmp,
29072 + p_CcNode->ccKeySizeAccExtraction),
29073 + 0xff, p_CcNode->userSizeOfExtraction);
29074 + }
29075 + else
29076 + {
29077 + MemCpy8(PTR_MOVE(p_KeysMatchTableNewTmp,
29078 + p_CcNode->ccKeySizeAccExtraction),
29079 + p_CcNode->p_GlblMask,
29080 + p_CcNode->userSizeOfExtraction);
29081 + }
29082 + }
29083 + }
29084 +
29085 + MemCpy8(p_KeysMatchTableNewTmp, p_KeysMatchTableOldTmp,
29086 + p_CcNode->ccKeySizeAccExtraction);
29087 +
29088 + i++;
29089 + }
29090 + }
29091 +
29092 + /* Miss action descriptor */
29093 + p_AdTableNewTmp =
29094 + PTR_MOVE(p_AdditionalInfo->p_AdTableNew, j * FM_PCD_CC_AD_ENTRY_SIZE);
29095 + p_AdTableOldTmp =
29096 + PTR_MOVE(p_AdditionalInfo->p_AdTableOld, i * FM_PCD_CC_AD_ENTRY_SIZE);
29097 + MemCpy8(p_AdTableNewTmp, p_AdTableOldTmp, FM_PCD_CC_AD_ENTRY_SIZE);
29098 +
29099 + if (!LIST_IsEmpty(&p_CcNode->ccTreesLst))
29100 + {
29101 + LIST_FOR_EACH(p_Pos, &p_CcNode->ccTreesLst)
29102 + {
29103 + p_CcNodeInformation = CC_NODE_F_OBJECT(p_Pos);
29104 + ASSERT_COND(p_CcNodeInformation->h_CcNode);
29105 + /* Update the manipulation which has to be updated from parameters of the port */
29106 + /* It's has to be updated with restrictions defined in the function */
29107 + err =
29108 + SetRequiredAction(
29109 + p_CcNode->h_FmPcd,
29110 + p_CcNode->shadowAction
29111 + | p_AdditionalInfo->keyAndNextEngineParams[keyIndex].requiredAction,
29112 + &p_AdditionalInfo->keyAndNextEngineParams[keyIndex],
29113 + PTR_MOVE(p_AdditionalInfo->p_AdTableNew, keyIndex*FM_PCD_CC_AD_ENTRY_SIZE),
29114 + 1, p_CcNodeInformation->h_CcNode);
29115 + if (err)
29116 + RETURN_ERROR(MAJOR, err, (NO_MSG));
29117 +
29118 + err =
29119 + CcUpdateParam(
29120 + p_CcNode->h_FmPcd,
29121 + NULL,
29122 + NULL,
29123 + &p_AdditionalInfo->keyAndNextEngineParams[keyIndex],
29124 + 1,
29125 + PTR_MOVE(p_AdditionalInfo->p_AdTableNew, keyIndex*FM_PCD_CC_AD_ENTRY_SIZE),
29126 + TRUE, p_CcNodeInformation->index,
29127 + p_CcNodeInformation->h_CcNode, TRUE);
29128 + if (err)
29129 + RETURN_ERROR(MAJOR, err, (NO_MSG));
29130 + }
29131 + }
29132 +
29133 + if (p_CcNode->lclMask)
29134 + memset(p_CcNode->p_GlblMask, 0xff, CC_GLBL_MASK_SIZE * sizeof(uint8_t));
29135 +
29136 + if (p_KeyParams->ccNextEngineParams.nextEngine == e_FM_PCD_CC)
29137 + p_AdditionalInfo->h_NodeForAdd =
29138 + p_KeyParams->ccNextEngineParams.params.ccParams.h_CcNode;
29139 + if (p_KeyParams->ccNextEngineParams.h_Manip)
29140 + p_AdditionalInfo->h_ManipForAdd =
29141 + p_KeyParams->ccNextEngineParams.h_Manip;
29142 +
29143 +#if (DPAA_VERSION >= 11)
29144 + if ((p_KeyParams->ccNextEngineParams.nextEngine == e_FM_PCD_FR)
29145 + && (p_KeyParams->ccNextEngineParams.params.frParams.h_FrmReplic))
29146 + p_AdditionalInfo->h_FrmReplicForAdd =
29147 + p_KeyParams->ccNextEngineParams.params.frParams.h_FrmReplic;
29148 +#endif /* (DPAA_VERSION >= 11) */
29149 +
29150 + if (!add)
29151 + {
29152 + if (p_CcNode->keyAndNextEngineParams[keyIndex].nextEngineParams.nextEngine
29153 + == e_FM_PCD_CC)
29154 + p_AdditionalInfo->h_NodeForRmv =
29155 + p_CcNode->keyAndNextEngineParams[keyIndex].nextEngineParams.params.ccParams.h_CcNode;
29156 +
29157 + if (p_CcNode->keyAndNextEngineParams[keyIndex].nextEngineParams.h_Manip)
29158 + p_AdditionalInfo->h_ManipForRmv =
29159 + p_CcNode->keyAndNextEngineParams[keyIndex].nextEngineParams.h_Manip;
29160 +
29161 + /* If statistics were previously enabled, store the old statistics object to be released */
29162 + if (p_CcNode->keyAndNextEngineParams[keyIndex].p_StatsObj)
29163 + {
29164 + p_AdditionalInfo->p_StatsObjForRmv =
29165 + p_CcNode->keyAndNextEngineParams[keyIndex].p_StatsObj;
29166 + }
29167 +
29168 +#if (DPAA_VERSION >= 11)
29169 + if ((p_CcNode->keyAndNextEngineParams[keyIndex].nextEngineParams.nextEngine
29170 + == e_FM_PCD_FR)
29171 + && (p_CcNode->keyAndNextEngineParams[keyIndex].nextEngineParams.params.frParams.h_FrmReplic))
29172 + p_AdditionalInfo->h_FrmReplicForRmv =
29173 + p_CcNode->keyAndNextEngineParams[keyIndex].nextEngineParams.params.frParams.h_FrmReplic;
29174 +#endif /* (DPAA_VERSION >= 11) */
29175 + }
29176 +
29177 + return E_OK;
29178 +}
29179 +
29180 +static t_Error BuildNewNodeRemoveKey(
29181 + t_FmPcdCcNode *p_CcNode, uint16_t keyIndex,
29182 + t_FmPcdModifyCcKeyAdditionalParams *p_AdditionalInfo)
29183 +{
29184 + int i = 0, j = 0;
29185 + t_Handle p_AdTableNewTmp, p_KeysMatchTableNewTmp;
29186 + t_Handle p_KeysMatchTableOldTmp, p_AdTableOldTmp;
29187 + int size;
29188 + t_Error err = E_OK;
29189 +
29190 + /*save new numOfKeys*/
29191 + p_AdditionalInfo->numOfKeys = (uint16_t)(p_CcNode->numOfKeys - 1);
29192 +
29193 + /*function which allocates in the memory new KeyTbl, AdTbl*/
29194 + err = BuildNewNodeCommonPart(p_CcNode, &size, p_AdditionalInfo);
29195 + if (err)
29196 + RETURN_ERROR(MAJOR, err, NO_MSG);
29197 +
29198 + /*update new Ad and new Key Table according to new requirement*/
29199 + for (i = 0, j = 0; j < p_CcNode->numOfKeys; i++, j++)
29200 + {
29201 + if (j == keyIndex)
29202 + j++;
29203 +
29204 + if (j == p_CcNode->numOfKeys)
29205 + break;
29206 + p_AdTableNewTmp =
29207 + PTR_MOVE(p_AdditionalInfo->p_AdTableNew, i * FM_PCD_CC_AD_ENTRY_SIZE);
29208 + p_AdTableOldTmp =
29209 + PTR_MOVE(p_AdditionalInfo->p_AdTableOld, j * FM_PCD_CC_AD_ENTRY_SIZE);
29210 + MemCpy8(p_AdTableNewTmp, p_AdTableOldTmp, FM_PCD_CC_AD_ENTRY_SIZE);
29211 +
29212 + p_KeysMatchTableOldTmp =
29213 + PTR_MOVE(p_AdditionalInfo->p_KeysMatchTableOld, j * size * sizeof(uint8_t));
29214 + p_KeysMatchTableNewTmp =
29215 + PTR_MOVE(p_AdditionalInfo->p_KeysMatchTableNew, i * size * sizeof(uint8_t));
29216 + MemCpy8(p_KeysMatchTableNewTmp, p_KeysMatchTableOldTmp,
29217 + size * sizeof(uint8_t));
29218 + }
29219 +
29220 + p_AdTableNewTmp =
29221 + PTR_MOVE(p_AdditionalInfo->p_AdTableNew, i * FM_PCD_CC_AD_ENTRY_SIZE);
29222 + p_AdTableOldTmp =
29223 + PTR_MOVE(p_AdditionalInfo->p_AdTableOld, j * FM_PCD_CC_AD_ENTRY_SIZE);
29224 + MemCpy8(p_AdTableNewTmp, p_AdTableOldTmp, FM_PCD_CC_AD_ENTRY_SIZE);
29225 +
29226 + if (p_CcNode->keyAndNextEngineParams[keyIndex].nextEngineParams.nextEngine
29227 + == e_FM_PCD_CC)
29228 + p_AdditionalInfo->h_NodeForRmv =
29229 + p_CcNode->keyAndNextEngineParams[keyIndex].nextEngineParams.params.ccParams.h_CcNode;
29230 +
29231 + if (p_CcNode->keyAndNextEngineParams[keyIndex].nextEngineParams.h_Manip)
29232 + p_AdditionalInfo->h_ManipForRmv =
29233 + p_CcNode->keyAndNextEngineParams[keyIndex].nextEngineParams.h_Manip;
29234 +
29235 + /* If statistics were previously enabled, store the old statistics object to be released */
29236 + if (p_CcNode->keyAndNextEngineParams[keyIndex].p_StatsObj)
29237 + {
29238 + p_AdditionalInfo->p_StatsObjForRmv =
29239 + p_CcNode->keyAndNextEngineParams[keyIndex].p_StatsObj;
29240 + }
29241 +
29242 +#if (DPAA_VERSION >= 11)
29243 + if ((p_CcNode->keyAndNextEngineParams[keyIndex].nextEngineParams.nextEngine
29244 + == e_FM_PCD_FR)
29245 + && (p_CcNode->keyAndNextEngineParams[keyIndex].nextEngineParams.params.frParams.h_FrmReplic))
29246 + p_AdditionalInfo->h_FrmReplicForRmv =
29247 + p_CcNode->keyAndNextEngineParams[keyIndex].nextEngineParams.params.frParams.h_FrmReplic;
29248 +#endif /* (DPAA_VERSION >= 11) */
29249 +
29250 + return E_OK;
29251 +}
29252 +
29253 +static t_Error BuildNewNodeModifyKey(
29254 + t_FmPcdCcNode *p_CcNode, uint16_t keyIndex, uint8_t *p_Key,
29255 + uint8_t *p_Mask, t_FmPcdModifyCcKeyAdditionalParams *p_AdditionalInfo)
29256 +{
29257 + t_FmPcd *p_FmPcd = (t_FmPcd *)p_CcNode->h_FmPcd;
29258 + t_Error err = E_OK;
29259 + t_Handle p_AdTableNewTmp, p_KeysMatchTableNewTmp;
29260 + t_Handle p_KeysMatchTableOldTmp, p_AdTableOldTmp;
29261 + int size;
29262 + int i = 0, j = 0;
29263 + bool prvLclMask;
29264 + t_FmPcdStatsObj *p_StatsObj, tmpStatsObj;
29265 + p_AdditionalInfo->numOfKeys = p_CcNode->numOfKeys;
29266 +
29267 + prvLclMask = p_CcNode->lclMask;
29268 +
29269 + /* Check that new key is not require update of localMask */
29270 + err = UpdateGblMask(p_CcNode, p_CcNode->ccKeySizeAccExtraction, p_Mask);
29271 + if (err)
29272 + RETURN_ERROR(MAJOR, err, (NO_MSG));
29273 +
29274 + /* Update internal data structure with new next engine for the given index */
29275 + memcpy(p_AdditionalInfo->keyAndNextEngineParams[keyIndex].key, p_Key,
29276 + p_CcNode->userSizeOfExtraction);
29277 +
29278 + if (p_Mask)
29279 + memcpy(p_AdditionalInfo->keyAndNextEngineParams[keyIndex].mask, p_Mask,
29280 + p_CcNode->userSizeOfExtraction);
29281 + else
29282 + memset(p_AdditionalInfo->keyAndNextEngineParams[keyIndex].mask, 0xFF,
29283 + p_CcNode->userSizeOfExtraction);
29284 +
29285 + /*function which build in the memory new KeyTbl, AdTbl*/
29286 + err = BuildNewNodeCommonPart(p_CcNode, &size, p_AdditionalInfo);
29287 + if (err)
29288 + RETURN_ERROR(MAJOR, err, NO_MSG);
29289 +
29290 + /*fill the New AdTable and New KeyTable*/
29291 + for (j = 0, i = 0; j < p_AdditionalInfo->numOfKeys; j++, i++)
29292 + {
29293 + p_AdTableNewTmp =
29294 + PTR_MOVE(p_AdditionalInfo->p_AdTableNew, j*FM_PCD_CC_AD_ENTRY_SIZE);
29295 + p_AdTableOldTmp =
29296 + PTR_MOVE(p_AdditionalInfo->p_AdTableOld, i*FM_PCD_CC_AD_ENTRY_SIZE);
29297 +
29298 + MemCpy8(p_AdTableNewTmp, p_AdTableOldTmp, FM_PCD_CC_AD_ENTRY_SIZE);
29299 +
29300 + if (j == keyIndex)
29301 + {
29302 + ASSERT_COND(keyIndex < CC_MAX_NUM_OF_KEYS);
29303 + if (p_CcNode->keyAndNextEngineParams[keyIndex].p_StatsObj)
29304 + {
29305 + /* As statistics were enabled, we need to update the existing
29306 + statistics descriptor with a new nullified counters. */
29307 + p_StatsObj = GetStatsObj(p_CcNode);
29308 + ASSERT_COND(p_StatsObj);
29309 +
29310 + SetStatsCounters(
29311 + p_AdTableNewTmp,
29312 + (uint32_t)((XX_VirtToPhys(p_StatsObj->h_StatsCounters)
29313 + - p_FmPcd->physicalMuramBase)));
29314 +
29315 + tmpStatsObj.h_StatsAd = p_StatsObj->h_StatsAd;
29316 + tmpStatsObj.h_StatsCounters = p_StatsObj->h_StatsCounters;
29317 +
29318 + /* As we need to replace only the counters, we build a new statistics
29319 + object that holds the old AD and the new counters - this will be the
29320 + currently used statistics object.
29321 + The newly allocated AD is not required and may be released back to
29322 + the available objects with the previous counters pointer. */
29323 + p_StatsObj->h_StatsAd =
29324 + p_CcNode->keyAndNextEngineParams[keyIndex].p_StatsObj->h_StatsAd;
29325 +
29326 + p_CcNode->keyAndNextEngineParams[keyIndex].p_StatsObj->h_StatsAd =
29327 + tmpStatsObj.h_StatsAd;
29328 +
29329 + /* Store allocated statistics object */
29330 + p_AdditionalInfo->keyAndNextEngineParams[keyIndex].p_StatsObj =
29331 + p_StatsObj;
29332 +
29333 + /* As statistics were previously enabled, store the old statistics object to be released */
29334 + p_AdditionalInfo->p_StatsObjForRmv =
29335 + p_CcNode->keyAndNextEngineParams[keyIndex].p_StatsObj;
29336 + }
29337 +
29338 + p_KeysMatchTableNewTmp =
29339 + PTR_MOVE(p_AdditionalInfo->p_KeysMatchTableNew, j * size * sizeof(uint8_t));
29340 +
29341 + MemCpy8(p_KeysMatchTableNewTmp, p_Key,
29342 + p_CcNode->userSizeOfExtraction);
29343 +
29344 + if (p_CcNode->lclMask)
29345 + {
29346 + if (p_Mask)
29347 + MemCpy8(PTR_MOVE(p_KeysMatchTableNewTmp,
29348 + p_CcNode->ccKeySizeAccExtraction),
29349 + p_Mask, p_CcNode->userSizeOfExtraction);
29350 + else
29351 + if (p_CcNode->ccKeySizeAccExtraction > 4)
29352 + MemSet8(PTR_MOVE(p_KeysMatchTableNewTmp,
29353 + p_CcNode->ccKeySizeAccExtraction),
29354 + 0xff, p_CcNode->userSizeOfExtraction);
29355 + else
29356 + MemCpy8(PTR_MOVE(p_KeysMatchTableNewTmp,
29357 + p_CcNode->ccKeySizeAccExtraction),
29358 + p_CcNode->p_GlblMask,
29359 + p_CcNode->userSizeOfExtraction);
29360 + }
29361 + }
29362 + else
29363 + {
29364 + p_KeysMatchTableNewTmp =
29365 + PTR_MOVE(p_AdditionalInfo->p_KeysMatchTableNew, j * size * sizeof(uint8_t));
29366 + p_KeysMatchTableOldTmp =
29367 + PTR_MOVE(p_CcNode->h_KeysMatchTable, i * size * sizeof(uint8_t));
29368 +
29369 + if (p_CcNode->lclMask)
29370 + {
29371 + if (prvLclMask)
29372 + MemCpy8(
29373 + PTR_MOVE(p_KeysMatchTableNewTmp, p_CcNode->ccKeySizeAccExtraction),
29374 + PTR_MOVE(p_KeysMatchTableOldTmp, p_CcNode->ccKeySizeAccExtraction),
29375 + p_CcNode->userSizeOfExtraction);
29376 + else
29377 + {
29378 + p_KeysMatchTableOldTmp =
29379 + PTR_MOVE(p_CcNode->h_KeysMatchTable,
29380 + i * (int)p_CcNode->ccKeySizeAccExtraction * sizeof(uint8_t));
29381 +
29382 + if (p_CcNode->ccKeySizeAccExtraction > 4)
29383 + MemSet8(PTR_MOVE(p_KeysMatchTableNewTmp,
29384 + p_CcNode->ccKeySizeAccExtraction),
29385 + 0xff, p_CcNode->userSizeOfExtraction);
29386 + else
29387 + MemCpy8(
29388 + PTR_MOVE(p_KeysMatchTableNewTmp, p_CcNode->ccKeySizeAccExtraction),
29389 + p_CcNode->p_GlblMask,
29390 + p_CcNode->userSizeOfExtraction);
29391 + }
29392 + }
29393 + MemCpy8((void*)p_KeysMatchTableNewTmp, p_KeysMatchTableOldTmp,
29394 + p_CcNode->ccKeySizeAccExtraction);
29395 + }
29396 + }
29397 +
29398 + p_AdTableNewTmp =
29399 + PTR_MOVE(p_AdditionalInfo->p_AdTableNew, j * FM_PCD_CC_AD_ENTRY_SIZE);
29400 + p_AdTableOldTmp = PTR_MOVE(p_CcNode->h_AdTable, i * FM_PCD_CC_AD_ENTRY_SIZE);
29401 +
29402 + MemCpy8(p_AdTableNewTmp, p_AdTableOldTmp, FM_PCD_CC_AD_ENTRY_SIZE);
29403 +
29404 + return E_OK;
29405 +}
29406 +
29407 +static t_Error BuildNewNodeModifyNextEngine(
29408 + t_Handle h_FmPcd, t_Handle h_FmPcdCcNodeOrTree, uint16_t keyIndex,
29409 + t_FmPcdCcNextEngineParams *p_CcNextEngineParams, t_List *h_OldLst,
29410 + t_List *h_NewLst, t_FmPcdModifyCcKeyAdditionalParams *p_AdditionalInfo)
29411 +{
29412 + t_Error err = E_OK;
29413 + uint32_t requiredAction = 0;
29414 + t_List *p_Pos;
29415 + t_CcNodeInformation *p_CcNodeInformation, ccNodeInfo;
29416 + t_Handle p_Ad;
29417 + t_FmPcdCcNode *p_FmPcdCcNode1 = NULL;
29418 + t_FmPcdCcTree *p_FmPcdCcTree = NULL;
29419 + t_FmPcdStatsObj *p_StatsObj;
29420 + t_FmPcdCcStatsParams statsParams = { 0 };
29421 +
29422 + ASSERT_COND(p_CcNextEngineParams);
29423 +
29424 + /* check that new NIA is legal */
29425 + if (!p_AdditionalInfo->tree)
29426 + err = ValidateNextEngineParams(
29427 + h_FmPcd, p_CcNextEngineParams,
29428 + ((t_FmPcdCcNode *)h_FmPcdCcNodeOrTree)->statisticsMode);
29429 + else
29430 + /* Statistics are not supported for CC root */
29431 + err = ValidateNextEngineParams(h_FmPcd, p_CcNextEngineParams,
29432 + e_FM_PCD_CC_STATS_MODE_NONE);
29433 + if (err)
29434 + RETURN_ERROR(MAJOR, err, NO_MSG);
29435 +
29436 + /* Update internal data structure for next engine per index (index - key) */
29437 + memcpy(&p_AdditionalInfo->keyAndNextEngineParams[keyIndex].nextEngineParams,
29438 + p_CcNextEngineParams, sizeof(t_FmPcdCcNextEngineParams));
29439 +
29440 + /* Check that manip is legal and what requiredAction is necessary for this manip */
29441 + if (p_CcNextEngineParams->h_Manip)
29442 + {
29443 + err = FmPcdManipCheckParamsForCcNextEngine(p_CcNextEngineParams,
29444 + &requiredAction);
29445 + if (err)
29446 + RETURN_ERROR(MAJOR, err, (NO_MSG));
29447 + }
29448 +
29449 + if (!p_AdditionalInfo->tree)
29450 + {
29451 + p_FmPcdCcNode1 = (t_FmPcdCcNode *)h_FmPcdCcNodeOrTree;
29452 + p_AdditionalInfo->numOfKeys = p_FmPcdCcNode1->numOfKeys;
29453 + p_Ad = p_FmPcdCcNode1->h_AdTable;
29454 +
29455 + if (p_FmPcdCcNode1->keyAndNextEngineParams[keyIndex].nextEngineParams.nextEngine
29456 + == e_FM_PCD_CC)
29457 + p_AdditionalInfo->h_NodeForRmv =
29458 + p_FmPcdCcNode1->keyAndNextEngineParams[keyIndex].nextEngineParams.params.ccParams.h_CcNode;
29459 +
29460 + if (p_FmPcdCcNode1->keyAndNextEngineParams[keyIndex].nextEngineParams.h_Manip)
29461 + p_AdditionalInfo->h_ManipForRmv =
29462 + p_FmPcdCcNode1->keyAndNextEngineParams[keyIndex].nextEngineParams.h_Manip;
29463 +
29464 +#if (DPAA_VERSION >= 11)
29465 + if ((p_FmPcdCcNode1->keyAndNextEngineParams[keyIndex].nextEngineParams.nextEngine
29466 + == e_FM_PCD_FR)
29467 + && (p_FmPcdCcNode1->keyAndNextEngineParams[keyIndex].nextEngineParams.params.frParams.h_FrmReplic))
29468 + p_AdditionalInfo->h_FrmReplicForRmv =
29469 + p_FmPcdCcNode1->keyAndNextEngineParams[keyIndex].nextEngineParams.params.frParams.h_FrmReplic;
29470 +#endif /* (DPAA_VERSION >= 11) */
29471 + }
29472 + else
29473 + {
29474 + p_FmPcdCcTree = (t_FmPcdCcTree *)h_FmPcdCcNodeOrTree;
29475 + p_Ad = UINT_TO_PTR(p_FmPcdCcTree->ccTreeBaseAddr);
29476 +
29477 + if (p_FmPcdCcTree->keyAndNextEngineParams[keyIndex].nextEngineParams.nextEngine
29478 + == e_FM_PCD_CC)
29479 + p_AdditionalInfo->h_NodeForRmv =
29480 + p_FmPcdCcTree->keyAndNextEngineParams[keyIndex].nextEngineParams.params.ccParams.h_CcNode;
29481 +
29482 + if (p_FmPcdCcTree->keyAndNextEngineParams[keyIndex].nextEngineParams.h_Manip)
29483 + p_AdditionalInfo->h_ManipForRmv =
29484 + p_FmPcdCcTree->keyAndNextEngineParams[keyIndex].nextEngineParams.h_Manip;
29485 +
29486 +#if (DPAA_VERSION >= 11)
29487 + if ((p_FmPcdCcTree->keyAndNextEngineParams[keyIndex].nextEngineParams.nextEngine
29488 + == e_FM_PCD_FR)
29489 + && (p_FmPcdCcTree->keyAndNextEngineParams[keyIndex].nextEngineParams.params.frParams.h_FrmReplic))
29490 + p_AdditionalInfo->h_FrmReplicForRmv =
29491 + p_FmPcdCcTree->keyAndNextEngineParams[keyIndex].nextEngineParams.params.frParams.h_FrmReplic;
29492 +#endif /* (DPAA_VERSION >= 11) */
29493 + }
29494 +
29495 + if ((p_CcNextEngineParams->nextEngine == e_FM_PCD_CC)
29496 + && p_CcNextEngineParams->h_Manip)
29497 + {
29498 + err = AllocAndFillAdForContLookupManip(
29499 + p_CcNextEngineParams->params.ccParams.h_CcNode);
29500 + if (err)
29501 + RETURN_ERROR(MAJOR, err, (NO_MSG));
29502 + }
29503 +
29504 + ASSERT_COND(p_Ad);
29505 +
29506 + memset(&ccNodeInfo, 0, sizeof(t_CcNodeInformation));
29507 + ccNodeInfo.h_CcNode = PTR_MOVE(p_Ad, keyIndex * FM_PCD_CC_AD_ENTRY_SIZE);
29508 +
29509 + /* If statistics were enabled, this Ad is the statistics Ad. Need to follow its
29510 + nextAction to retrieve the actual Nia-Ad. If statistics should remain enabled,
29511 + only the actual Nia-Ad should be modified. */
29512 + if ((!p_AdditionalInfo->tree)
29513 + && (((t_FmPcdCcNode *)h_FmPcdCcNodeOrTree)->keyAndNextEngineParams[keyIndex].p_StatsObj)
29514 + && (p_CcNextEngineParams->statisticsEn))
29515 + ccNodeInfo.h_CcNode =
29516 + ((t_FmPcdCcNode *)h_FmPcdCcNodeOrTree)->keyAndNextEngineParams[keyIndex].p_StatsObj->h_StatsAd;
29517 +
29518 + EnqueueNodeInfoToRelevantLst(h_OldLst, &ccNodeInfo, NULL);
29519 +
29520 + memset(&ccNodeInfo, 0, sizeof(t_CcNodeInformation));
29521 + p_Ad = GetNewAd(h_FmPcdCcNodeOrTree, p_AdditionalInfo->tree);
29522 + if (!p_Ad)
29523 + RETURN_ERROR(MAJOR, E_NO_MEMORY,
29524 + ("MURAM allocation for CC node action descriptor"));
29525 + MemSet8((uint8_t *)p_Ad, 0, FM_PCD_CC_AD_ENTRY_SIZE);
29526 +
29527 + /* If statistics were not enabled before, but requested now - Allocate a statistics
29528 + object that holds statistics AD and counters. */
29529 + if ((!p_AdditionalInfo->tree)
29530 + && (!((t_FmPcdCcNode *)h_FmPcdCcNodeOrTree)->keyAndNextEngineParams[keyIndex].p_StatsObj)
29531 + && (p_CcNextEngineParams->statisticsEn))
29532 + {
29533 + p_StatsObj = GetStatsObj((t_FmPcdCcNode *)h_FmPcdCcNodeOrTree);
29534 + ASSERT_COND(p_StatsObj);
29535 +
29536 + /* Store allocated statistics object */
29537 + p_AdditionalInfo->keyAndNextEngineParams[keyIndex].p_StatsObj =
29538 + p_StatsObj;
29539 +
29540 + statsParams.h_StatsAd = p_StatsObj->h_StatsAd;
29541 + statsParams.h_StatsCounters = p_StatsObj->h_StatsCounters;
29542 +
29543 +#if (DPAA_VERSION >= 11)
29544 + statsParams.h_StatsFLRs =
29545 + ((t_FmPcdCcNode *)h_FmPcdCcNodeOrTree)->h_StatsFLRs;
29546 +
29547 +#endif /* (DPAA_VERSION >= 11) */
29548 +
29549 + NextStepAd(p_Ad, &statsParams, p_CcNextEngineParams, h_FmPcd);
29550 + }
29551 + else
29552 + NextStepAd(p_Ad, NULL, p_CcNextEngineParams, h_FmPcd);
29553 +
29554 + ccNodeInfo.h_CcNode = p_Ad;
29555 + EnqueueNodeInfoToRelevantLst(h_NewLst, &ccNodeInfo, NULL);
29556 +
29557 + p_AdditionalInfo->keyAndNextEngineParams[keyIndex].requiredAction =
29558 + requiredAction;
29559 + p_AdditionalInfo->keyAndNextEngineParams[keyIndex].requiredAction |=
29560 + UPDATE_CC_WITH_TREE;
29561 +
29562 + if (!p_AdditionalInfo->tree)
29563 + {
29564 + ASSERT_COND(p_FmPcdCcNode1);
29565 + if (!LIST_IsEmpty(&p_FmPcdCcNode1->ccTreesLst))
29566 + {
29567 + LIST_FOR_EACH(p_Pos, &p_FmPcdCcNode1->ccTreesLst)
29568 + {
29569 + p_CcNodeInformation = CC_NODE_F_OBJECT(p_Pos);
29570 +
29571 + ASSERT_COND(p_CcNodeInformation->h_CcNode);
29572 + /* Update the manipulation which has to be updated from parameters of the port
29573 + it's has to be updated with restrictions defined in the function */
29574 +
29575 + err =
29576 + SetRequiredAction(
29577 + p_FmPcdCcNode1->h_FmPcd,
29578 + p_FmPcdCcNode1->shadowAction
29579 + | p_AdditionalInfo->keyAndNextEngineParams[keyIndex].requiredAction,
29580 + &p_AdditionalInfo->keyAndNextEngineParams[keyIndex],
29581 + p_Ad, 1, p_CcNodeInformation->h_CcNode);
29582 + if (err)
29583 + RETURN_ERROR(MAJOR, err, (NO_MSG));
29584 +
29585 + err = CcUpdateParam(
29586 + p_FmPcdCcNode1->h_FmPcd, NULL, NULL,
29587 + &p_AdditionalInfo->keyAndNextEngineParams[keyIndex], 1,
29588 + p_Ad, TRUE, p_CcNodeInformation->index,
29589 + p_CcNodeInformation->h_CcNode, TRUE);
29590 + if (err)
29591 + RETURN_ERROR(MAJOR, err, (NO_MSG));
29592 + }
29593 + }
29594 + }
29595 + else
29596 + {
29597 + ASSERT_COND(p_FmPcdCcTree);
29598 +
29599 + err =
29600 + SetRequiredAction(
29601 + h_FmPcd,
29602 + p_FmPcdCcTree->requiredAction
29603 + | p_AdditionalInfo->keyAndNextEngineParams[keyIndex].requiredAction,
29604 + &p_AdditionalInfo->keyAndNextEngineParams[keyIndex],
29605 + p_Ad, 1, (t_Handle)p_FmPcdCcTree);
29606 + if (err)
29607 + RETURN_ERROR(MAJOR, err, (NO_MSG));
29608 +
29609 + err = CcUpdateParam(h_FmPcd, NULL, NULL,
29610 + &p_AdditionalInfo->keyAndNextEngineParams[keyIndex],
29611 + 1, p_Ad, TRUE, 0, (t_Handle)p_FmPcdCcTree, TRUE);
29612 + if (err)
29613 + RETURN_ERROR(MAJOR, err, (NO_MSG));
29614 + }
29615 +
29616 + if (p_CcNextEngineParams->nextEngine == e_FM_PCD_CC)
29617 + p_AdditionalInfo->h_NodeForAdd =
29618 + p_CcNextEngineParams->params.ccParams.h_CcNode;
29619 + if (p_CcNextEngineParams->h_Manip)
29620 + p_AdditionalInfo->h_ManipForAdd = p_CcNextEngineParams->h_Manip;
29621 +
29622 + /* If statistics were previously enabled, but now are disabled,
29623 + store the old statistics object to be released */
29624 + if ((!p_AdditionalInfo->tree)
29625 + && (((t_FmPcdCcNode *)h_FmPcdCcNodeOrTree)->keyAndNextEngineParams[keyIndex].p_StatsObj)
29626 + && (!p_CcNextEngineParams->statisticsEn))
29627 + {
29628 + p_AdditionalInfo->p_StatsObjForRmv =
29629 + ((t_FmPcdCcNode *)h_FmPcdCcNodeOrTree)->keyAndNextEngineParams[keyIndex].p_StatsObj;
29630 +
29631 +
29632 + p_AdditionalInfo->keyAndNextEngineParams[keyIndex].p_StatsObj = NULL;
29633 + }
29634 +#if (DPAA_VERSION >= 11)
29635 + if ((p_CcNextEngineParams->nextEngine == e_FM_PCD_FR)
29636 + && (p_CcNextEngineParams->params.frParams.h_FrmReplic))
29637 + p_AdditionalInfo->h_FrmReplicForAdd =
29638 + p_CcNextEngineParams->params.frParams.h_FrmReplic;
29639 +#endif /* (DPAA_VERSION >= 11) */
29640 +
29641 + return E_OK;
29642 +}
29643 +
29644 +static void UpdateAdPtrOfNodesWhichPointsOnCrntMdfNode(
29645 + t_FmPcdCcNode *p_CrntMdfNode, t_List *h_OldLst,
29646 + t_FmPcdCcNextEngineParams **p_NextEngineParams)
29647 +{
29648 + t_CcNodeInformation *p_CcNodeInformation;
29649 + t_FmPcdCcNode *p_NodePtrOnCurrentMdfNode = NULL;
29650 + t_List *p_Pos;
29651 + int i = 0;
29652 + t_Handle p_AdTablePtOnCrntCurrentMdfNode/*, p_AdTableNewModified*/;
29653 + t_CcNodeInformation ccNodeInfo;
29654 +
29655 + LIST_FOR_EACH(p_Pos, &p_CrntMdfNode->ccPrevNodesLst)
29656 + {
29657 + p_CcNodeInformation = CC_NODE_F_OBJECT(p_Pos);
29658 + p_NodePtrOnCurrentMdfNode =
29659 + (t_FmPcdCcNode *)p_CcNodeInformation->h_CcNode;
29660 +
29661 + ASSERT_COND(p_NodePtrOnCurrentMdfNode);
29662 +
29663 + /* Search in the previous node which exact index points on this current modified node for getting AD */
29664 + for (i = 0; i < p_NodePtrOnCurrentMdfNode->numOfKeys + 1; i++)
29665 + {
29666 + if (p_NodePtrOnCurrentMdfNode->keyAndNextEngineParams[i].nextEngineParams.nextEngine
29667 + == e_FM_PCD_CC)
29668 + {
29669 + if (p_NodePtrOnCurrentMdfNode->keyAndNextEngineParams[i].nextEngineParams.params.ccParams.h_CcNode
29670 + == (t_Handle)p_CrntMdfNode)
29671 + {
29672 + if (p_NodePtrOnCurrentMdfNode->keyAndNextEngineParams[i].nextEngineParams.h_Manip)
29673 + p_AdTablePtOnCrntCurrentMdfNode = p_CrntMdfNode->h_Ad;
29674 + else
29675 + if (p_NodePtrOnCurrentMdfNode->keyAndNextEngineParams[i].p_StatsObj)
29676 + p_AdTablePtOnCrntCurrentMdfNode =
29677 + p_NodePtrOnCurrentMdfNode->keyAndNextEngineParams[i].p_StatsObj->h_StatsAd;
29678 + else
29679 + p_AdTablePtOnCrntCurrentMdfNode =
29680 + PTR_MOVE(p_NodePtrOnCurrentMdfNode->h_AdTable, i*FM_PCD_CC_AD_ENTRY_SIZE);
29681 +
29682 + memset(&ccNodeInfo, 0, sizeof(t_CcNodeInformation));
29683 + ccNodeInfo.h_CcNode = p_AdTablePtOnCrntCurrentMdfNode;
29684 + EnqueueNodeInfoToRelevantLst(h_OldLst, &ccNodeInfo, NULL);
29685 +
29686 + if (!(*p_NextEngineParams))
29687 + *p_NextEngineParams =
29688 + &p_NodePtrOnCurrentMdfNode->keyAndNextEngineParams[i].nextEngineParams;
29689 + }
29690 + }
29691 + }
29692 +
29693 + ASSERT_COND(i != p_NodePtrOnCurrentMdfNode->numOfKeys);
29694 + }
29695 +}
29696 +
29697 +static void UpdateAdPtrOfTreesWhichPointsOnCrntMdfNode(
29698 + t_FmPcdCcNode *p_CrntMdfNode, t_List *h_OldLst,
29699 + t_FmPcdCcNextEngineParams **p_NextEngineParams)
29700 +{
29701 + t_CcNodeInformation *p_CcNodeInformation;
29702 + t_FmPcdCcTree *p_TreePtrOnCurrentMdfNode = NULL;
29703 + t_List *p_Pos;
29704 + int i = 0;
29705 + t_Handle p_AdTableTmp;
29706 + t_CcNodeInformation ccNodeInfo;
29707 +
29708 + LIST_FOR_EACH(p_Pos, &p_CrntMdfNode->ccTreeIdLst)
29709 + {
29710 + p_CcNodeInformation = CC_NODE_F_OBJECT(p_Pos);
29711 + p_TreePtrOnCurrentMdfNode =
29712 + (t_FmPcdCcTree *)p_CcNodeInformation->h_CcNode;
29713 +
29714 + ASSERT_COND(p_TreePtrOnCurrentMdfNode);
29715 +
29716 + /*search in the trees which exact index points on this current modified node for getting AD */
29717 + for (i = 0; i < p_TreePtrOnCurrentMdfNode->numOfEntries; i++)
29718 + {
29719 + if (p_TreePtrOnCurrentMdfNode->keyAndNextEngineParams[i].nextEngineParams.nextEngine
29720 + == e_FM_PCD_CC)
29721 + {
29722 + if (p_TreePtrOnCurrentMdfNode->keyAndNextEngineParams[i].nextEngineParams.params.ccParams.h_CcNode
29723 + == (t_Handle)p_CrntMdfNode)
29724 + {
29725 + p_AdTableTmp =
29726 + UINT_TO_PTR(p_TreePtrOnCurrentMdfNode->ccTreeBaseAddr + i*FM_PCD_CC_AD_ENTRY_SIZE);
29727 + memset(&ccNodeInfo, 0, sizeof(t_CcNodeInformation));
29728 + ccNodeInfo.h_CcNode = p_AdTableTmp;
29729 + EnqueueNodeInfoToRelevantLst(h_OldLst, &ccNodeInfo, NULL);
29730 +
29731 + if (!(*p_NextEngineParams))
29732 + *p_NextEngineParams =
29733 + &p_TreePtrOnCurrentMdfNode->keyAndNextEngineParams[i].nextEngineParams;
29734 + }
29735 + }
29736 + }
29737 +
29738 + ASSERT_COND(i == p_TreePtrOnCurrentMdfNode->numOfEntries);
29739 + }
29740 +}
29741 +
29742 +static t_FmPcdModifyCcKeyAdditionalParams * ModifyNodeCommonPart(
29743 + t_Handle h_FmPcdCcNodeOrTree, uint16_t keyIndex,
29744 + e_ModifyState modifyState, bool ttlCheck, bool hashCheck, bool tree)
29745 +{
29746 + t_FmPcdModifyCcKeyAdditionalParams *p_FmPcdModifyCcKeyAdditionalParams;
29747 + int i = 0, j = 0;
29748 + bool wasUpdate = FALSE;
29749 + t_FmPcdCcNode *p_CcNode = NULL;
29750 + t_FmPcdCcTree *p_FmPcdCcTree;
29751 + uint16_t numOfKeys;
29752 + t_FmPcdCcKeyAndNextEngineParams *p_KeyAndNextEngineParams;
29753 +
29754 + SANITY_CHECK_RETURN_VALUE(h_FmPcdCcNodeOrTree, E_INVALID_HANDLE, NULL);
29755 +
29756 + if (!tree)
29757 + {
29758 + p_CcNode = (t_FmPcdCcNode *)h_FmPcdCcNodeOrTree;
29759 + numOfKeys = p_CcNode->numOfKeys;
29760 +
29761 + /* node has to be pointed by another node or tree */
29762 +
29763 + p_KeyAndNextEngineParams = (t_FmPcdCcKeyAndNextEngineParams *)XX_Malloc(
29764 + sizeof(t_FmPcdCcKeyAndNextEngineParams) * (numOfKeys + 1));
29765 + if (!p_KeyAndNextEngineParams)
29766 + {
29767 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("Next engine and required action structure"));
29768 + return NULL;
29769 + }
29770 + memcpy(p_KeyAndNextEngineParams, p_CcNode->keyAndNextEngineParams,
29771 + (numOfKeys + 1) * sizeof(t_FmPcdCcKeyAndNextEngineParams));
29772 +
29773 + if (ttlCheck)
29774 + {
29775 + if ((p_CcNode->parseCode == CC_PC_FF_IPV4TTL)
29776 + || (p_CcNode->parseCode == CC_PC_FF_IPV6HOP_LIMIT))
29777 + {
29778 + XX_Free(p_KeyAndNextEngineParams);
29779 + 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"));
29780 + return NULL;
29781 + }
29782 + }
29783 +
29784 + if (hashCheck)
29785 + {
29786 + if (p_CcNode->parseCode == CC_PC_GENERIC_IC_HASH_INDEXED)
29787 + {
29788 + XX_Free(p_KeyAndNextEngineParams);
29789 + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("nodeId of CC_PC_GENERIC_IC_HASH_INDEXED can not be used for this operation"));
29790 + return NULL;
29791 + }
29792 + }
29793 + }
29794 + else
29795 + {
29796 + p_FmPcdCcTree = (t_FmPcdCcTree *)h_FmPcdCcNodeOrTree;
29797 + numOfKeys = p_FmPcdCcTree->numOfEntries;
29798 +
29799 + p_KeyAndNextEngineParams = (t_FmPcdCcKeyAndNextEngineParams *)XX_Malloc(
29800 + sizeof(t_FmPcdCcKeyAndNextEngineParams)
29801 + * FM_PCD_MAX_NUM_OF_CC_GROUPS);
29802 + if (!p_KeyAndNextEngineParams)
29803 + {
29804 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("Next engine and required action structure"));
29805 + return NULL;
29806 + }
29807 + memcpy(p_KeyAndNextEngineParams,
29808 + p_FmPcdCcTree->keyAndNextEngineParams,
29809 + FM_PCD_MAX_NUM_OF_CC_GROUPS
29810 + * sizeof(t_FmPcdCcKeyAndNextEngineParams));
29811 + }
29812 +
29813 + p_FmPcdModifyCcKeyAdditionalParams =
29814 + (t_FmPcdModifyCcKeyAdditionalParams *)XX_Malloc(
29815 + sizeof(t_FmPcdModifyCcKeyAdditionalParams));
29816 + if (!p_FmPcdModifyCcKeyAdditionalParams)
29817 + {
29818 + XX_Free(p_KeyAndNextEngineParams);
29819 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("Allocation of internal data structure FAILED"));
29820 + return NULL;
29821 + }
29822 + memset(p_FmPcdModifyCcKeyAdditionalParams, 0,
29823 + sizeof(t_FmPcdModifyCcKeyAdditionalParams));
29824 +
29825 + p_FmPcdModifyCcKeyAdditionalParams->h_CurrentNode = h_FmPcdCcNodeOrTree;
29826 + p_FmPcdModifyCcKeyAdditionalParams->savedKeyIndex = keyIndex;
29827 +
29828 + while (i < numOfKeys)
29829 + {
29830 + if ((j == keyIndex) && !wasUpdate)
29831 + {
29832 + if (modifyState == e_MODIFY_STATE_ADD)
29833 + j++;
29834 + else
29835 + if (modifyState == e_MODIFY_STATE_REMOVE)
29836 + i++;
29837 + wasUpdate = TRUE;
29838 + }
29839 + else
29840 + {
29841 + memcpy(&p_FmPcdModifyCcKeyAdditionalParams->keyAndNextEngineParams[j],
29842 + p_KeyAndNextEngineParams + i,
29843 + sizeof(t_FmPcdCcKeyAndNextEngineParams));
29844 + i++;
29845 + j++;
29846 + }
29847 + }
29848 +
29849 + if (keyIndex == numOfKeys)
29850 + {
29851 + if (modifyState == e_MODIFY_STATE_ADD)
29852 + j++;
29853 + }
29854 +
29855 + memcpy(&p_FmPcdModifyCcKeyAdditionalParams->keyAndNextEngineParams[j],
29856 + p_KeyAndNextEngineParams + numOfKeys,
29857 + sizeof(t_FmPcdCcKeyAndNextEngineParams));
29858 +
29859 + XX_Free(p_KeyAndNextEngineParams);
29860 +
29861 + return p_FmPcdModifyCcKeyAdditionalParams;
29862 +}
29863 +
29864 +static t_Error UpdatePtrWhichPointOnCrntMdfNode(
29865 + t_FmPcdCcNode *p_CcNode,
29866 + t_FmPcdModifyCcKeyAdditionalParams *p_FmPcdModifyCcKeyAdditionalParams,
29867 + t_List *h_OldLst, t_List *h_NewLst)
29868 +{
29869 + t_FmPcdCcNextEngineParams *p_NextEngineParams = NULL;
29870 + t_CcNodeInformation ccNodeInfo = { 0 };
29871 + t_Handle h_NewAd;
29872 + t_Handle h_OrigAd = NULL;
29873 +
29874 + /* Building a list of all action descriptors that point to the previous node */
29875 + if (!LIST_IsEmpty(&p_CcNode->ccPrevNodesLst))
29876 + UpdateAdPtrOfNodesWhichPointsOnCrntMdfNode(p_CcNode, h_OldLst,
29877 + &p_NextEngineParams);
29878 +
29879 + if (!LIST_IsEmpty(&p_CcNode->ccTreeIdLst))
29880 + UpdateAdPtrOfTreesWhichPointsOnCrntMdfNode(p_CcNode, h_OldLst,
29881 + &p_NextEngineParams);
29882 +
29883 + /* This node must be found as next engine of one of its previous nodes or trees*/
29884 + if (p_NextEngineParams)
29885 + {
29886 + /* Building a new action descriptor that points to the modified node */
29887 + h_NewAd = GetNewAd(p_CcNode, FALSE);
29888 + if (!h_NewAd)
29889 + RETURN_ERROR(MAJOR, E_NO_MEMORY, NO_MSG);
29890 + MemSet8(h_NewAd, 0, FM_PCD_CC_AD_ENTRY_SIZE);
29891 +
29892 + h_OrigAd = p_CcNode->h_Ad;
29893 + BuildNewAd(h_NewAd, p_FmPcdModifyCcKeyAdditionalParams, p_CcNode,
29894 + p_NextEngineParams);
29895 +
29896 + ccNodeInfo.h_CcNode = h_NewAd;
29897 + EnqueueNodeInfoToRelevantLst(h_NewLst, &ccNodeInfo, NULL);
29898 +
29899 + if (p_NextEngineParams->h_Manip && !h_OrigAd)
29900 + FmPcdManipUpdateOwner(p_NextEngineParams->h_Manip, FALSE);
29901 + }
29902 + return E_OK;
29903 +}
29904 +
29905 +static void UpdateCcRootOwner(t_FmPcdCcTree *p_FmPcdCcTree, bool add)
29906 +{
29907 + ASSERT_COND(p_FmPcdCcTree);
29908 +
29909 + /* this routine must be protected by the calling routine! */
29910 +
29911 + if (add)
29912 + p_FmPcdCcTree->owners++;
29913 + else
29914 + {
29915 + ASSERT_COND(p_FmPcdCcTree->owners);
29916 + p_FmPcdCcTree->owners--;
29917 + }
29918 +}
29919 +
29920 +static t_Error CheckAndSetManipParamsWithCcNodeParams(t_FmPcdCcNode *p_CcNode)
29921 +{
29922 + t_Error err = E_OK;
29923 + int i = 0;
29924 +
29925 + for (i = 0; i < p_CcNode->numOfKeys; i++)
29926 + {
29927 + if (p_CcNode->keyAndNextEngineParams[i].nextEngineParams.h_Manip)
29928 + {
29929 + err =
29930 + FmPcdManipCheckParamsWithCcNodeParams(
29931 + p_CcNode->keyAndNextEngineParams[i].nextEngineParams.h_Manip,
29932 + (t_Handle)p_CcNode);
29933 + if (err)
29934 + return err;
29935 + }
29936 + }
29937 +
29938 + return err;
29939 +}
29940 +static t_Error ValidateAndCalcStatsParams(t_FmPcdCcNode *p_CcNode,
29941 + t_FmPcdCcNodeParams *p_CcNodeParam,
29942 + uint32_t *p_NumOfRanges,
29943 + uint32_t *p_CountersArraySize)
29944 +{
29945 + e_FmPcdCcStatsMode statisticsMode = p_CcNode->statisticsMode;
29946 + uint32_t i;
29947 +
29948 + UNUSED(p_CcNodeParam);
29949 +
29950 + switch (statisticsMode)
29951 + {
29952 + case e_FM_PCD_CC_STATS_MODE_NONE:
29953 + for (i = 0; i < p_CcNode->numOfKeys; i++)
29954 + if (p_CcNodeParam->keysParams.keyParams[i].ccNextEngineParams.statisticsEn)
29955 + RETURN_ERROR(
29956 + MAJOR,
29957 + E_INVALID_VALUE,
29958 + ("Statistics cannot be enabled for key %d when statistics mode was set to 'NONE'", i));
29959 + return E_OK;
29960 +
29961 + case e_FM_PCD_CC_STATS_MODE_FRAME:
29962 + case e_FM_PCD_CC_STATS_MODE_BYTE_AND_FRAME:
29963 + *p_NumOfRanges = 1;
29964 + *p_CountersArraySize = 2 * FM_PCD_CC_STATS_COUNTER_SIZE;
29965 + return E_OK;
29966 +
29967 +#if (DPAA_VERSION >= 11)
29968 + case e_FM_PCD_CC_STATS_MODE_RMON:
29969 + {
29970 + uint16_t *p_FrameLengthRanges =
29971 + p_CcNodeParam->keysParams.frameLengthRanges;
29972 + uint32_t i;
29973 +
29974 + if (p_FrameLengthRanges[0] <= 0)
29975 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Statistics mode"));
29976 +
29977 + if (p_FrameLengthRanges[0] == 0xFFFF)
29978 + {
29979 + *p_NumOfRanges = 1;
29980 + *p_CountersArraySize = 2 * FM_PCD_CC_STATS_COUNTER_SIZE;
29981 + return E_OK;
29982 + }
29983 +
29984 + for (i = 1; i < FM_PCD_CC_STATS_MAX_NUM_OF_FLR; i++)
29985 + {
29986 + if (p_FrameLengthRanges[i - 1] >= p_FrameLengthRanges[i])
29987 + RETURN_ERROR(
29988 + MAJOR,
29989 + E_INVALID_VALUE,
29990 + ("Frame length range must be larger at least by 1 from preceding range"));
29991 +
29992 + /* Stop when last range is reached */
29993 + if (p_FrameLengthRanges[i] == 0xFFFF)
29994 + break;
29995 + }
29996 +
29997 + if ((i >= FM_PCD_CC_STATS_MAX_NUM_OF_FLR)
29998 + || (p_FrameLengthRanges[i] != 0xFFFF))
29999 + RETURN_ERROR(MAJOR, E_INVALID_VALUE,
30000 + ("Last Frame length range must be 0xFFFF"));
30001 +
30002 + *p_NumOfRanges = i + 1;
30003 +
30004 + /* Allocate an extra counter for byte count, as counters
30005 + array always begins with byte count */
30006 + *p_CountersArraySize = (*p_NumOfRanges + 1)
30007 + * FM_PCD_CC_STATS_COUNTER_SIZE;
30008 +
30009 + }
30010 + return E_OK;
30011 +#endif /* (DPAA_VERSION >= 11) */
30012 +
30013 + default:
30014 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Statistics mode"));
30015 + }
30016 +}
30017 +
30018 +static t_Error CheckParams(t_Handle h_FmPcd, t_FmPcdCcNodeParams *p_CcNodeParam,
30019 + t_FmPcdCcNode *p_CcNode, bool *isKeyTblAlloc)
30020 +{
30021 + int tmp = 0;
30022 + t_FmPcdCcKeyParams *p_KeyParams;
30023 + t_Error err;
30024 + uint32_t requiredAction = 0;
30025 +
30026 + /* Validate statistics parameters */
30027 + err = ValidateAndCalcStatsParams(p_CcNode, p_CcNodeParam,
30028 + &(p_CcNode->numOfStatsFLRs),
30029 + &(p_CcNode->countersArraySize));
30030 + if (err)
30031 + RETURN_ERROR(MAJOR, err, ("Invalid statistics parameters"));
30032 +
30033 + /* Validate next engine parameters on Miss */
30034 + err = ValidateNextEngineParams(
30035 + h_FmPcd, &p_CcNodeParam->keysParams.ccNextEngineParamsForMiss,
30036 + p_CcNode->statisticsMode);
30037 + if (err)
30038 + RETURN_ERROR(MAJOR, err,
30039 + ("For this node MissNextEngineParams are not valid"));
30040 +
30041 + if (p_CcNodeParam->keysParams.ccNextEngineParamsForMiss.h_Manip)
30042 + {
30043 + err = FmPcdManipCheckParamsForCcNextEngine(
30044 + &p_CcNodeParam->keysParams.ccNextEngineParamsForMiss,
30045 + &requiredAction);
30046 + if (err)
30047 + RETURN_ERROR(MAJOR, err, (NO_MSG));
30048 + }
30049 +
30050 + memcpy(&p_CcNode->keyAndNextEngineParams[p_CcNode->numOfKeys].nextEngineParams,
30051 + &p_CcNodeParam->keysParams.ccNextEngineParamsForMiss,
30052 + sizeof(t_FmPcdCcNextEngineParams));
30053 +
30054 + p_CcNode->keyAndNextEngineParams[p_CcNode->numOfKeys].requiredAction =
30055 + requiredAction;
30056 +
30057 + if ((p_CcNode->keyAndNextEngineParams[p_CcNode->numOfKeys].nextEngineParams.nextEngine
30058 + == e_FM_PCD_CC)
30059 + && p_CcNode->keyAndNextEngineParams[p_CcNode->numOfKeys].nextEngineParams.h_Manip)
30060 + {
30061 + err =
30062 + AllocAndFillAdForContLookupManip(
30063 + p_CcNode->keyAndNextEngineParams[p_CcNode->numOfKeys].nextEngineParams.params.ccParams.h_CcNode);
30064 + if (err)
30065 + RETURN_ERROR(MAJOR, err, (NO_MSG));
30066 + }
30067 +
30068 + for (tmp = 0; tmp < p_CcNode->numOfKeys; tmp++)
30069 + {
30070 + p_KeyParams = &p_CcNodeParam->keysParams.keyParams[tmp];
30071 +
30072 + if (!p_KeyParams->p_Key)
30073 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("p_Key is not initialized"));
30074 +
30075 + err = ValidateNextEngineParams(h_FmPcd,
30076 + &p_KeyParams->ccNextEngineParams,
30077 + p_CcNode->statisticsMode);
30078 + if (err)
30079 + RETURN_ERROR(MAJOR, err, (NO_MSG));
30080 +
30081 + err = UpdateGblMask(p_CcNode, p_CcNodeParam->keysParams.keySize,
30082 + p_KeyParams->p_Mask);
30083 + if (err)
30084 + RETURN_ERROR(MAJOR, err, (NO_MSG));
30085 +
30086 + if (p_KeyParams->ccNextEngineParams.h_Manip)
30087 + {
30088 + err = FmPcdManipCheckParamsForCcNextEngine(
30089 + &p_KeyParams->ccNextEngineParams, &requiredAction);
30090 + if (err)
30091 + RETURN_ERROR(MAJOR, err, (NO_MSG));
30092 + }
30093 +
30094 + /* Store 'key' parameters - key, mask (if passed by the user) */
30095 + memcpy(p_CcNode->keyAndNextEngineParams[tmp].key, p_KeyParams->p_Key,
30096 + p_CcNodeParam->keysParams.keySize);
30097 +
30098 + if (p_KeyParams->p_Mask)
30099 + memcpy(p_CcNode->keyAndNextEngineParams[tmp].mask,
30100 + p_KeyParams->p_Mask, p_CcNodeParam->keysParams.keySize);
30101 + else
30102 + memset((void *)(p_CcNode->keyAndNextEngineParams[tmp].mask), 0xFF,
30103 + p_CcNodeParam->keysParams.keySize);
30104 +
30105 + /* Store next engine parameters */
30106 + memcpy(&p_CcNode->keyAndNextEngineParams[tmp].nextEngineParams,
30107 + &p_KeyParams->ccNextEngineParams,
30108 + sizeof(t_FmPcdCcNextEngineParams));
30109 +
30110 + p_CcNode->keyAndNextEngineParams[tmp].requiredAction = requiredAction;
30111 +
30112 + if ((p_CcNode->keyAndNextEngineParams[tmp].nextEngineParams.nextEngine
30113 + == e_FM_PCD_CC)
30114 + && p_CcNode->keyAndNextEngineParams[tmp].nextEngineParams.h_Manip)
30115 + {
30116 + err =
30117 + AllocAndFillAdForContLookupManip(
30118 + p_CcNode->keyAndNextEngineParams[tmp].nextEngineParams.params.ccParams.h_CcNode);
30119 + if (err)
30120 + RETURN_ERROR(MAJOR, err, (NO_MSG));
30121 + }
30122 + }
30123 +
30124 + if (p_CcNode->maxNumOfKeys)
30125 + {
30126 + if (p_CcNode->maxNumOfKeys < p_CcNode->numOfKeys)
30127 + RETURN_ERROR(
30128 + MAJOR,
30129 + E_INVALID_VALUE,
30130 + ("Number of keys exceed the provided maximal number of keys"));
30131 + }
30132 +
30133 + *isKeyTblAlloc = TRUE;
30134 +
30135 + return E_OK;
30136 +}
30137 +
30138 +static t_Error Ipv4TtlOrIpv6HopLimitCheckParams(
30139 + t_Handle h_FmPcd, t_FmPcdCcNodeParams *p_CcNodeParam,
30140 + t_FmPcdCcNode *p_CcNode, bool *isKeyTblAlloc)
30141 +{
30142 + int tmp = 0;
30143 + t_FmPcdCcKeyParams *p_KeyParams;
30144 + t_Error err;
30145 + uint8_t key = 0x01;
30146 + uint32_t requiredAction = 0;
30147 +
30148 + if (p_CcNode->numOfKeys != 1)
30149 + RETURN_ERROR(
30150 + MAJOR,
30151 + E_INVALID_VALUE,
30152 + ("For node of the type IPV4_TTL or IPV6_HOP_LIMIT the maximal supported 'numOfKeys' is 1"));
30153 +
30154 + if ((p_CcNodeParam->keysParams.maxNumOfKeys)
30155 + && (p_CcNodeParam->keysParams.maxNumOfKeys != 1))
30156 + RETURN_ERROR(
30157 + MAJOR,
30158 + E_INVALID_VALUE,
30159 + ("For node of the type IPV4_TTL or IPV6_HOP_LIMIT the maximal supported 'maxNumOfKeys' is 1"));
30160 +
30161 + /* Validate statistics parameters */
30162 + err = ValidateAndCalcStatsParams(p_CcNode, p_CcNodeParam,
30163 + &(p_CcNode->numOfStatsFLRs),
30164 + &(p_CcNode->countersArraySize));
30165 + if (err)
30166 + RETURN_ERROR(MAJOR, err, ("Invalid statistics parameters"));
30167 +
30168 + err = ValidateNextEngineParams(
30169 + h_FmPcd, &p_CcNodeParam->keysParams.ccNextEngineParamsForMiss,
30170 + p_CcNodeParam->keysParams.statisticsMode);
30171 + if (err)
30172 + RETURN_ERROR(MAJOR, err,
30173 + ("For this node MissNextEngineParams are not valid"));
30174 +
30175 + if (p_CcNodeParam->keysParams.ccNextEngineParamsForMiss.h_Manip)
30176 + {
30177 + err = FmPcdManipCheckParamsForCcNextEngine(
30178 + &p_CcNodeParam->keysParams.ccNextEngineParamsForMiss,
30179 + &requiredAction);
30180 + if (err)
30181 + RETURN_ERROR(MAJOR, err, (NO_MSG));
30182 + }
30183 +
30184 + memcpy(&p_CcNode->keyAndNextEngineParams[p_CcNode->numOfKeys].nextEngineParams,
30185 + &p_CcNodeParam->keysParams.ccNextEngineParamsForMiss,
30186 + sizeof(t_FmPcdCcNextEngineParams));
30187 +
30188 + p_CcNode->keyAndNextEngineParams[p_CcNode->numOfKeys].requiredAction =
30189 + requiredAction;
30190 +
30191 + if ((p_CcNode->keyAndNextEngineParams[p_CcNode->numOfKeys].nextEngineParams.nextEngine
30192 + == e_FM_PCD_CC)
30193 + && p_CcNode->keyAndNextEngineParams[p_CcNode->numOfKeys].nextEngineParams.h_Manip)
30194 + {
30195 + err =
30196 + AllocAndFillAdForContLookupManip(
30197 + p_CcNode->keyAndNextEngineParams[p_CcNode->numOfKeys].nextEngineParams.params.ccParams.h_CcNode);
30198 + if (err)
30199 + RETURN_ERROR(MAJOR, err, (NO_MSG));
30200 + }
30201 +
30202 + for (tmp = 0; tmp < p_CcNode->numOfKeys; tmp++)
30203 + {
30204 + p_KeyParams = &p_CcNodeParam->keysParams.keyParams[tmp];
30205 +
30206 + if (p_KeyParams->p_Mask)
30207 + RETURN_ERROR(
30208 + MAJOR,
30209 + E_INVALID_VALUE,
30210 + ("For node of the type IPV4_TTL or IPV6_HOP_LIMIT p_Mask can not be initialized"));
30211 +
30212 + if (memcmp(p_KeyParams->p_Key, &key, 1) != 0)
30213 + RETURN_ERROR(
30214 + MAJOR,
30215 + E_INVALID_VALUE,
30216 + ("For node of the type IPV4_TTL or IPV6_HOP_LIMIT p_Key has to be 1"));
30217 +
30218 + err = ValidateNextEngineParams(h_FmPcd,
30219 + &p_KeyParams->ccNextEngineParams,
30220 + p_CcNode->statisticsMode);
30221 + if (err)
30222 + RETURN_ERROR(MAJOR, err, (NO_MSG));
30223 +
30224 + if (p_KeyParams->ccNextEngineParams.h_Manip)
30225 + {
30226 + err = FmPcdManipCheckParamsForCcNextEngine(
30227 + &p_KeyParams->ccNextEngineParams, &requiredAction);
30228 + if (err)
30229 + RETURN_ERROR(MAJOR, err, (NO_MSG));
30230 + }
30231 +
30232 + /* Store 'key' parameters - key (fixed to 0x01), key size of 1 byte and full mask */
30233 + p_CcNode->keyAndNextEngineParams[tmp].key[0] = key;
30234 + p_CcNode->keyAndNextEngineParams[tmp].mask[0] = 0xFF;
30235 +
30236 + /* Store NextEngine parameters */
30237 + memcpy(&p_CcNode->keyAndNextEngineParams[tmp].nextEngineParams,
30238 + &p_KeyParams->ccNextEngineParams,
30239 + sizeof(t_FmPcdCcNextEngineParams));
30240 +
30241 + if ((p_CcNode->keyAndNextEngineParams[tmp].nextEngineParams.nextEngine
30242 + == e_FM_PCD_CC)
30243 + && p_CcNode->keyAndNextEngineParams[tmp].nextEngineParams.h_Manip)
30244 + {
30245 + err =
30246 + AllocAndFillAdForContLookupManip(
30247 + p_CcNode->keyAndNextEngineParams[tmp].nextEngineParams.params.ccParams.h_CcNode);
30248 + if (err)
30249 + RETURN_ERROR(MAJOR, err, (NO_MSG));
30250 + }
30251 + p_CcNode->keyAndNextEngineParams[tmp].requiredAction = requiredAction;
30252 + }
30253 +
30254 + *isKeyTblAlloc = FALSE;
30255 +
30256 + return E_OK;
30257 +}
30258 +
30259 +static t_Error IcHashIndexedCheckParams(t_Handle h_FmPcd,
30260 + t_FmPcdCcNodeParams *p_CcNodeParam,
30261 + t_FmPcdCcNode *p_CcNode,
30262 + bool *isKeyTblAlloc)
30263 +{
30264 + int tmp = 0, countOnes = 0;
30265 + t_FmPcdCcKeyParams *p_KeyParams;
30266 + t_Error err;
30267 + uint16_t glblMask = p_CcNodeParam->extractCcParams.extractNonHdr.icIndxMask;
30268 + uint16_t countMask = (uint16_t)(glblMask >> 4);
30269 + uint32_t requiredAction = 0;
30270 +
30271 + if (glblMask & 0x000f)
30272 + RETURN_ERROR(MAJOR, E_INVALID_VALUE,
30273 + ("icIndxMask has to be with last nibble 0"));
30274 +
30275 + while (countMask)
30276 + {
30277 + countOnes++;
30278 + countMask = (uint16_t)(countMask >> 1);
30279 + }
30280 +
30281 + if (!POWER_OF_2(p_CcNode->numOfKeys))
30282 + RETURN_ERROR(
30283 + MAJOR,
30284 + E_INVALID_VALUE,
30285 + ("For Node of the type INDEXED numOfKeys has to be powerOfTwo"));
30286 +
30287 + if (p_CcNode->numOfKeys != ((uint32_t)1 << countOnes))
30288 + RETURN_ERROR(
30289 + MAJOR,
30290 + E_INVALID_VALUE,
30291 + ("For Node of the type IC_HASH_INDEXED numOfKeys has to be powerOfTwo"));
30292 +
30293 + if (p_CcNodeParam->keysParams.maxNumOfKeys
30294 + && (p_CcNodeParam->keysParams.maxNumOfKeys != p_CcNode->numOfKeys))
30295 + RETURN_ERROR(
30296 + MAJOR,
30297 + E_INVALID_VALUE,
30298 + ("For Node of the type INDEXED 'maxNumOfKeys' should be 0 or equal 'numOfKeys'"));
30299 +
30300 + /* Validate statistics parameters */
30301 + err = ValidateAndCalcStatsParams(p_CcNode, p_CcNodeParam,
30302 + &(p_CcNode->numOfStatsFLRs),
30303 + &(p_CcNode->countersArraySize));
30304 + if (err)
30305 + RETURN_ERROR(MAJOR, err, ("Invalid statistics parameters"));
30306 +
30307 + err = ValidateNextEngineParams(
30308 + h_FmPcd, &p_CcNodeParam->keysParams.ccNextEngineParamsForMiss,
30309 + p_CcNode->statisticsMode);
30310 + if (GET_ERROR_TYPE(err) != E_NOT_SUPPORTED)
30311 + RETURN_ERROR(
30312 + MAJOR,
30313 + err,
30314 + ("MissNextEngineParams for the node of the type IC_INDEX_HASH has to be UnInitialized"));
30315 +
30316 + for (tmp = 0; tmp < p_CcNode->numOfKeys; tmp++)
30317 + {
30318 + p_KeyParams = &p_CcNodeParam->keysParams.keyParams[tmp];
30319 +
30320 + if (p_KeyParams->p_Mask || p_KeyParams->p_Key)
30321 + RETURN_ERROR(
30322 + MAJOR,
30323 + E_INVALID_VALUE,
30324 + ("For Node of the type IC_HASH_INDEXED p_Key or p_Mask has to be NULL"));
30325 +
30326 + if ((glblMask & (tmp * 16)) == (tmp * 16))
30327 + {
30328 + err = ValidateNextEngineParams(h_FmPcd,
30329 + &p_KeyParams->ccNextEngineParams,
30330 + p_CcNode->statisticsMode);
30331 + if (err)
30332 + RETURN_ERROR(
30333 + MAJOR,
30334 + err,
30335 + ("This index has to be initialized for the node of the type IC_INDEX_HASH according to settings of GlobalMask "));
30336 +
30337 + if (p_KeyParams->ccNextEngineParams.h_Manip)
30338 + {
30339 + err = FmPcdManipCheckParamsForCcNextEngine(
30340 + &p_KeyParams->ccNextEngineParams, &requiredAction);
30341 + if (err)
30342 + RETURN_ERROR(MAJOR, err, (NO_MSG));
30343 + p_CcNode->keyAndNextEngineParams[tmp].requiredAction =
30344 + requiredAction;
30345 + }
30346 +
30347 + memcpy(&p_CcNode->keyAndNextEngineParams[tmp].nextEngineParams,
30348 + &p_KeyParams->ccNextEngineParams,
30349 + sizeof(t_FmPcdCcNextEngineParams));
30350 +
30351 + if ((p_CcNode->keyAndNextEngineParams[tmp].nextEngineParams.nextEngine
30352 + == e_FM_PCD_CC)
30353 + && p_CcNode->keyAndNextEngineParams[tmp].nextEngineParams.h_Manip)
30354 + {
30355 + err =
30356 + AllocAndFillAdForContLookupManip(
30357 + p_CcNode->keyAndNextEngineParams[tmp].nextEngineParams.params.ccParams.h_CcNode);
30358 + if (err)
30359 + RETURN_ERROR(MAJOR, err, (NO_MSG));
30360 + }
30361 + }
30362 + else
30363 + {
30364 + err = ValidateNextEngineParams(h_FmPcd,
30365 + &p_KeyParams->ccNextEngineParams,
30366 + p_CcNode->statisticsMode);
30367 + if (GET_ERROR_TYPE(err) != E_NOT_SUPPORTED)
30368 + RETURN_ERROR(
30369 + MAJOR,
30370 + err,
30371 + ("This index has to be UnInitialized for the node of the type IC_INDEX_HASH according to settings of GlobalMask"));
30372 + }
30373 + }
30374 +
30375 + *isKeyTblAlloc = FALSE;
30376 + cpu_to_be16s(&glblMask);
30377 + memcpy(PTR_MOVE(p_CcNode->p_GlblMask, 2), &glblMask, 2);
30378 +
30379 + return E_OK;
30380 +}
30381 +
30382 +static t_Error ModifyNextEngineParamNode(
30383 + t_Handle h_FmPcd, t_Handle h_FmPcdCcNode, uint16_t keyIndex,
30384 + t_FmPcdCcNextEngineParams *p_FmPcdCcNextEngineParams)
30385 +{
30386 + t_FmPcdCcNode *p_CcNode = (t_FmPcdCcNode *)h_FmPcdCcNode;
30387 + t_FmPcd *p_FmPcd;
30388 + t_List h_OldPointersLst, h_NewPointersLst;
30389 + t_FmPcdModifyCcKeyAdditionalParams *p_ModifyKeyParams;
30390 + t_Error err = E_OK;
30391 +
30392 + SANITY_CHECK_RETURN_ERROR(h_FmPcd, E_INVALID_VALUE);
30393 + SANITY_CHECK_RETURN_ERROR(p_CcNode, E_INVALID_HANDLE);
30394 +
30395 + if (keyIndex >= p_CcNode->numOfKeys)
30396 + RETURN_ERROR(MAJOR, E_INVALID_STATE,
30397 + ("keyIndex > previously cleared last index + 1"));
30398 +
30399 + p_FmPcd = (t_FmPcd *)p_CcNode->h_FmPcd;
30400 +
30401 + INIT_LIST(&h_OldPointersLst);
30402 + INIT_LIST(&h_NewPointersLst);
30403 +
30404 + p_ModifyKeyParams = ModifyNodeCommonPart(p_CcNode, keyIndex,
30405 + e_MODIFY_STATE_CHANGE, FALSE,
30406 + FALSE, FALSE);
30407 + if (!p_ModifyKeyParams)
30408 + RETURN_ERROR(MAJOR, E_INVALID_STATE, NO_MSG);
30409 +
30410 + if (p_CcNode->maxNumOfKeys
30411 + && !TRY_LOCK(p_FmPcd->h_ShadowSpinlock, &p_FmPcd->shadowLock))
30412 + {
30413 + XX_Free(p_ModifyKeyParams);
30414 + return ERROR_CODE(E_BUSY);
30415 + }
30416 +
30417 + err = BuildNewNodeModifyNextEngine(h_FmPcd, p_CcNode, keyIndex,
30418 + p_FmPcdCcNextEngineParams,
30419 + &h_OldPointersLst, &h_NewPointersLst,
30420 + p_ModifyKeyParams);
30421 + if (err)
30422 + {
30423 + XX_Free(p_ModifyKeyParams);
30424 + if (p_CcNode->maxNumOfKeys)
30425 + RELEASE_LOCK(p_FmPcd->shadowLock);
30426 + RETURN_ERROR(MAJOR, err, NO_MSG);
30427 + }
30428 +
30429 + err = DoDynamicChange(p_FmPcd, &h_OldPointersLst, &h_NewPointersLst,
30430 + p_ModifyKeyParams, FALSE);
30431 +
30432 + if (p_CcNode->maxNumOfKeys)
30433 + RELEASE_LOCK(p_FmPcd->shadowLock);
30434 +
30435 + ReleaseLst(&h_OldPointersLst);
30436 + ReleaseLst(&h_NewPointersLst);
30437 +
30438 + return err;
30439 +}
30440 +
30441 +static t_Error FindKeyIndex(t_Handle h_CcNode, uint8_t keySize, uint8_t *p_Key,
30442 + uint8_t *p_Mask, uint16_t *p_KeyIndex)
30443 +{
30444 + t_FmPcdCcNode *p_CcNode = (t_FmPcdCcNode *)h_CcNode;
30445 + uint8_t tmpMask[FM_PCD_MAX_SIZE_OF_KEY];
30446 + uint16_t i;
30447 +
30448 + ASSERT_COND(p_Key);
30449 + ASSERT_COND(p_KeyIndex);
30450 + ASSERT_COND(keySize < FM_PCD_MAX_SIZE_OF_KEY);
30451 +
30452 + if (keySize != p_CcNode->userSizeOfExtraction)
30453 + RETURN_ERROR(
30454 + MINOR, E_INVALID_VALUE,
30455 + ("Key size doesn't match the extraction size of the node"));
30456 +
30457 + /* If user didn't pass a mask for this key, we'll look for full extraction mask */
30458 + if (!p_Mask)
30459 + memset(tmpMask, 0xFF, keySize);
30460 +
30461 + for (i = 0; i < p_CcNode->numOfKeys; i++)
30462 + {
30463 + /* Comparing received key */
30464 + if (memcmp(p_Key, p_CcNode->keyAndNextEngineParams[i].key, keySize)
30465 + == 0)
30466 + {
30467 + if (p_Mask)
30468 + {
30469 + /* If a user passed a mask for this key, it must match to the existing key's mask for a correct match */
30470 + if (memcmp(p_Mask, p_CcNode->keyAndNextEngineParams[i].mask,
30471 + keySize) == 0)
30472 + {
30473 + *p_KeyIndex = i;
30474 + return E_OK;
30475 + }
30476 + }
30477 + else
30478 + {
30479 + /* If user didn't pass a mask for this key, check if the existing key mask is full extraction */
30480 + if (memcmp(tmpMask, p_CcNode->keyAndNextEngineParams[i].mask,
30481 + keySize) == 0)
30482 + {
30483 + *p_KeyIndex = i;
30484 + return E_OK;
30485 + }
30486 + }
30487 + }
30488 + }
30489 +
30490 + return ERROR_CODE(E_NOT_FOUND);
30491 +}
30492 +
30493 +static t_Error CalcAndUpdateCcShadow(t_FmPcdCcNode *p_CcNode,
30494 + bool isKeyTblAlloc,
30495 + uint32_t *p_MatchTableSize,
30496 + uint32_t *p_AdTableSize)
30497 +{
30498 + uint32_t shadowSize;
30499 + t_Error err;
30500 +
30501 + /* Calculate keys table maximal size - each entry consists of a key and a mask,
30502 + (if local mask support is requested) */
30503 + *p_MatchTableSize = p_CcNode->ccKeySizeAccExtraction * sizeof(uint8_t)
30504 + * p_CcNode->maxNumOfKeys;
30505 +
30506 + if (p_CcNode->maskSupport)
30507 + *p_MatchTableSize *= 2;
30508 +
30509 + /* Calculate next action descriptors table, including one more entry for miss */
30510 + *p_AdTableSize = (uint32_t)((p_CcNode->maxNumOfKeys + 1)
30511 + * FM_PCD_CC_AD_ENTRY_SIZE);
30512 +
30513 + /* Calculate maximal shadow size of this node.
30514 + All shadow structures will be used for runtime modifications host command. If
30515 + keys table was allocated for this node, the keys table and next engines table may
30516 + be modified in run time (entries added or removed), so shadow tables are requires.
30517 + Otherwise, the only supported runtime modification is a specific next engine update
30518 + and this requires shadow memory of a single AD */
30519 +
30520 + /* Shadow size should be enough to hold the following 3 structures:
30521 + * 1 - an action descriptor */
30522 + shadowSize = FM_PCD_CC_AD_ENTRY_SIZE;
30523 +
30524 + /* 2 - keys match table, if was allocated for the current node */
30525 + if (isKeyTblAlloc)
30526 + shadowSize += *p_MatchTableSize;
30527 +
30528 + /* 3 - next action descriptors table */
30529 + shadowSize += *p_AdTableSize;
30530 +
30531 + /* Update shadow to the calculated size */
30532 + err = FmPcdUpdateCcShadow(p_CcNode->h_FmPcd, (uint32_t)shadowSize,
30533 + FM_PCD_CC_AD_TABLE_ALIGN);
30534 + if (err != E_OK)
30535 + {
30536 + DeleteNode(p_CcNode);
30537 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("MURAM allocation for CC node shadow"));
30538 + }
30539 +
30540 + return E_OK;
30541 +}
30542 +
30543 +static t_Error AllocStatsObjs(t_FmPcdCcNode *p_CcNode)
30544 +{
30545 + t_FmPcdStatsObj *p_StatsObj;
30546 + t_Handle h_FmMuram, h_StatsAd, h_StatsCounters;
30547 + uint32_t i;
30548 +
30549 + h_FmMuram = FmPcdGetMuramHandle(p_CcNode->h_FmPcd);
30550 + if (!h_FmMuram)
30551 + RETURN_ERROR(MAJOR, E_INVALID_HANDLE, ("FM MURAM"));
30552 +
30553 + /* Allocate statistics ADs and statistics counter. An extra pair (AD + counters)
30554 + will be allocated to support runtime modifications */
30555 + for (i = 0; i < p_CcNode->maxNumOfKeys + 2; i++)
30556 + {
30557 + /* Allocate list object structure */
30558 + p_StatsObj = XX_Malloc(sizeof(t_FmPcdStatsObj));
30559 + if (!p_StatsObj)
30560 + {
30561 + FreeStatObjects(&p_CcNode->availableStatsLst, h_FmMuram);
30562 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("Statistics object"));
30563 + }
30564 + memset(p_StatsObj, 0, sizeof(t_FmPcdStatsObj));
30565 +
30566 + /* Allocate statistics AD from MURAM */
30567 + h_StatsAd = (t_Handle)FM_MURAM_AllocMem(h_FmMuram,
30568 + FM_PCD_CC_AD_ENTRY_SIZE,
30569 + FM_PCD_CC_AD_TABLE_ALIGN);
30570 + if (!h_StatsAd)
30571 + {
30572 + FreeStatObjects(&p_CcNode->availableStatsLst, h_FmMuram);
30573 + XX_Free(p_StatsObj);
30574 + RETURN_ERROR(MAJOR, E_NO_MEMORY,
30575 + ("MURAM allocation for statistics ADs"));
30576 + }
30577 + MemSet8(h_StatsAd, 0, FM_PCD_CC_AD_ENTRY_SIZE);
30578 +
30579 + /* Allocate statistics counters from MURAM */
30580 + h_StatsCounters = (t_Handle)FM_MURAM_AllocMem(
30581 + h_FmMuram, p_CcNode->countersArraySize,
30582 + FM_PCD_CC_AD_TABLE_ALIGN);
30583 + if (!h_StatsCounters)
30584 + {
30585 + FreeStatObjects(&p_CcNode->availableStatsLst, h_FmMuram);
30586 + FM_MURAM_FreeMem(h_FmMuram, h_StatsAd);
30587 + XX_Free(p_StatsObj);
30588 + RETURN_ERROR(MAJOR, E_NO_MEMORY,
30589 + ("MURAM allocation for statistics counters"));
30590 + }
30591 + MemSet8(h_StatsCounters, 0, p_CcNode->countersArraySize);
30592 +
30593 + p_StatsObj->h_StatsAd = h_StatsAd;
30594 + p_StatsObj->h_StatsCounters = h_StatsCounters;
30595 +
30596 + EnqueueStatsObj(&p_CcNode->availableStatsLst, p_StatsObj);
30597 + }
30598 +
30599 + return E_OK;
30600 +}
30601 +
30602 +static t_Error MatchTableGetKeyStatistics(
30603 + t_FmPcdCcNode *p_CcNode, uint16_t keyIndex,
30604 + t_FmPcdCcKeyStatistics *p_KeyStatistics)
30605 +{
30606 + uint32_t *p_StatsCounters, i;
30607 +
30608 + if (p_CcNode->statisticsMode == e_FM_PCD_CC_STATS_MODE_NONE)
30609 + RETURN_ERROR(MAJOR, E_INVALID_STATE,
30610 + ("Statistics were not enabled for this match table"));
30611 +
30612 + if (!p_CcNode->keyAndNextEngineParams[keyIndex].p_StatsObj)
30613 + RETURN_ERROR(MAJOR, E_INVALID_STATE,
30614 + ("Statistics were not enabled for this key"));
30615 +
30616 + memset(p_KeyStatistics, 0, sizeof(t_FmPcdCcKeyStatistics));
30617 +
30618 + p_StatsCounters =
30619 + p_CcNode->keyAndNextEngineParams[keyIndex].p_StatsObj->h_StatsCounters;
30620 + ASSERT_COND(p_StatsCounters);
30621 +
30622 + p_KeyStatistics->byteCount = GET_UINT32(*p_StatsCounters);
30623 +
30624 + for (i = 1; i <= p_CcNode->numOfStatsFLRs; i++)
30625 + {
30626 + p_StatsCounters =
30627 + PTR_MOVE(p_StatsCounters, FM_PCD_CC_STATS_COUNTER_SIZE);
30628 +
30629 + p_KeyStatistics->frameCount += GET_UINT32(*p_StatsCounters);
30630 +
30631 +#if (DPAA_VERSION >= 11)
30632 + p_KeyStatistics->frameLengthRangeCount[i - 1] =
30633 + GET_UINT32(*p_StatsCounters);
30634 +#endif /* (DPAA_VERSION >= 11) */
30635 + }
30636 +
30637 + return E_OK;
30638 +}
30639 +
30640 +static t_Error MatchTableSet(t_Handle h_FmPcd, t_FmPcdCcNode *p_CcNode,
30641 + t_FmPcdCcNodeParams *p_CcNodeParam)
30642 +{
30643 + t_FmPcd *p_FmPcd = (t_FmPcd *)h_FmPcd;
30644 + t_FmPcdCcNode *p_FmPcdCcNextNode;
30645 + t_Error err = E_OK;
30646 + uint32_t tmp, keySize;
30647 + bool glblMask = FALSE;
30648 + t_FmPcdCcKeyParams *p_KeyParams;
30649 + t_Handle h_FmMuram, p_KeysMatchTblTmp, p_AdTableTmp;
30650 +#if (DPAA_VERSION >= 11)
30651 + t_Handle h_StatsFLRs;
30652 +#endif /* (DPAA_VERSION >= 11) */
30653 + bool fullField = FALSE;
30654 + ccPrivateInfo_t icCode = CC_PRIVATE_INFO_NONE;
30655 + bool isKeyTblAlloc, fromIc = FALSE;
30656 + uint32_t matchTableSize, adTableSize;
30657 + t_CcNodeInformation ccNodeInfo, *p_CcInformation;
30658 + t_FmPcdStatsObj *p_StatsObj;
30659 + t_FmPcdCcStatsParams statsParams = { 0 };
30660 + t_Handle h_Manip;
30661 +
30662 + ASSERT_COND(h_FmPcd);
30663 + ASSERT_COND(p_CcNode);
30664 + ASSERT_COND(p_CcNodeParam);
30665 +
30666 + p_CcNode->p_GlblMask = (t_Handle)XX_Malloc(
30667 + CC_GLBL_MASK_SIZE * sizeof(uint8_t));
30668 + memset(p_CcNode->p_GlblMask, 0, CC_GLBL_MASK_SIZE * sizeof(uint8_t));
30669 +
30670 + p_CcNode->h_FmPcd = h_FmPcd;
30671 + p_CcNode->numOfKeys = p_CcNodeParam->keysParams.numOfKeys;
30672 + p_CcNode->maxNumOfKeys = p_CcNodeParam->keysParams.maxNumOfKeys;
30673 + p_CcNode->maskSupport = p_CcNodeParam->keysParams.maskSupport;
30674 + p_CcNode->statisticsMode = p_CcNodeParam->keysParams.statisticsMode;
30675 +
30676 + /* For backward compatibility - even if statistics mode is nullified,
30677 + we'll fix it to frame mode so we can support per-key request for
30678 + statistics using 'statisticsEn' in next engine parameters */
30679 + if (!p_CcNode->maxNumOfKeys
30680 + && (p_CcNode->statisticsMode == e_FM_PCD_CC_STATS_MODE_NONE))
30681 + p_CcNode->statisticsMode = e_FM_PCD_CC_STATS_MODE_FRAME;
30682 +
30683 + h_FmMuram = FmPcdGetMuramHandle(h_FmPcd);
30684 + if (!h_FmMuram)
30685 + RETURN_ERROR(MAJOR, E_INVALID_HANDLE, ("FM MURAM"));
30686 +
30687 + INIT_LIST(&p_CcNode->ccPrevNodesLst);
30688 + INIT_LIST(&p_CcNode->ccTreeIdLst);
30689 + INIT_LIST(&p_CcNode->ccTreesLst);
30690 + INIT_LIST(&p_CcNode->availableStatsLst);
30691 +
30692 + p_CcNode->h_Spinlock = XX_InitSpinlock();
30693 + if (!p_CcNode->h_Spinlock)
30694 + {
30695 + DeleteNode(p_CcNode);
30696 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("CC node spinlock"));
30697 + }
30698 +
30699 + if ((p_CcNodeParam->extractCcParams.type == e_FM_PCD_EXTRACT_BY_HDR)
30700 + && ((p_CcNodeParam->extractCcParams.extractByHdr.hdr
30701 + == HEADER_TYPE_IPv4)
30702 + || (p_CcNodeParam->extractCcParams.extractByHdr.hdr
30703 + == HEADER_TYPE_IPv6))
30704 + && (p_CcNodeParam->extractCcParams.extractByHdr.type
30705 + == e_FM_PCD_EXTRACT_FULL_FIELD)
30706 + && ((p_CcNodeParam->extractCcParams.extractByHdr.extractByHdrType.fullField.ipv6
30707 + == NET_HEADER_FIELD_IPv6_HOP_LIMIT)
30708 + || (p_CcNodeParam->extractCcParams.extractByHdr.extractByHdrType.fullField.ipv4
30709 + == NET_HEADER_FIELD_IPv4_TTL)))
30710 + {
30711 + err = Ipv4TtlOrIpv6HopLimitCheckParams(h_FmPcd, p_CcNodeParam, p_CcNode,
30712 + &isKeyTblAlloc);
30713 + glblMask = FALSE;
30714 + }
30715 + else
30716 + if ((p_CcNodeParam->extractCcParams.type == e_FM_PCD_EXTRACT_NON_HDR)
30717 + && ((p_CcNodeParam->extractCcParams.extractNonHdr.src
30718 + == e_FM_PCD_EXTRACT_FROM_KEY)
30719 + || (p_CcNodeParam->extractCcParams.extractNonHdr.src
30720 + == e_FM_PCD_EXTRACT_FROM_HASH)
30721 + || (p_CcNodeParam->extractCcParams.extractNonHdr.src
30722 + == e_FM_PCD_EXTRACT_FROM_FLOW_ID)))
30723 + {
30724 + if ((p_CcNodeParam->extractCcParams.extractNonHdr.src
30725 + == e_FM_PCD_EXTRACT_FROM_FLOW_ID)
30726 + && (p_CcNodeParam->extractCcParams.extractNonHdr.offset != 0))
30727 + {
30728 + DeleteNode(p_CcNode);
30729 + RETURN_ERROR(
30730 + MAJOR,
30731 + E_INVALID_VALUE,
30732 + ("In the case of the extraction from e_FM_PCD_EXTRACT_FROM_FLOW_ID offset has to be 0"));
30733 + }
30734 +
30735 + icCode = IcDefineCode(p_CcNodeParam);
30736 + fromIc = TRUE;
30737 + if (icCode == CC_PRIVATE_INFO_NONE)
30738 + {
30739 + DeleteNode(p_CcNode);
30740 + RETURN_ERROR(
30741 + MAJOR,
30742 + E_INVALID_STATE,
30743 + ("user asked extraction from IC and field in internal context or action wasn't initialized in the right way"));
30744 + }
30745 +
30746 + if ((icCode == CC_PRIVATE_INFO_IC_DEQ_FQID_INDEX_LOOKUP)
30747 + || (icCode == CC_PRIVATE_INFO_IC_HASH_INDEX_LOOKUP))
30748 + {
30749 + err = IcHashIndexedCheckParams(h_FmPcd, p_CcNodeParam, p_CcNode,
30750 + &isKeyTblAlloc);
30751 + glblMask = TRUE;
30752 + }
30753 + else
30754 + {
30755 + err = CheckParams(h_FmPcd, p_CcNodeParam, p_CcNode,
30756 + &isKeyTblAlloc);
30757 + if (p_CcNode->glblMaskSize)
30758 + glblMask = TRUE;
30759 + }
30760 + }
30761 + else
30762 + {
30763 + err = CheckParams(h_FmPcd, p_CcNodeParam, p_CcNode, &isKeyTblAlloc);
30764 + if (p_CcNode->glblMaskSize)
30765 + glblMask = TRUE;
30766 + }
30767 +
30768 + if (err)
30769 + {
30770 + DeleteNode(p_CcNode);
30771 + RETURN_ERROR(MAJOR, err, NO_MSG);
30772 + }
30773 +
30774 + switch (p_CcNodeParam->extractCcParams.type)
30775 + {
30776 + case (e_FM_PCD_EXTRACT_BY_HDR):
30777 + switch (p_CcNodeParam->extractCcParams.extractByHdr.type)
30778 + {
30779 + case (e_FM_PCD_EXTRACT_FULL_FIELD):
30780 + p_CcNode->parseCode =
30781 + GetFullFieldParseCode(
30782 + p_CcNodeParam->extractCcParams.extractByHdr.hdr,
30783 + p_CcNodeParam->extractCcParams.extractByHdr.hdrIndex,
30784 + p_CcNodeParam->extractCcParams.extractByHdr.extractByHdrType.fullField);
30785 + GetSizeHeaderField(
30786 + p_CcNodeParam->extractCcParams.extractByHdr.hdr,
30787 + p_CcNodeParam->extractCcParams.extractByHdr.extractByHdrType.fullField,
30788 + &p_CcNode->sizeOfExtraction);
30789 + fullField = TRUE;
30790 + if ((p_CcNode->parseCode != CC_PC_FF_TCI1)
30791 + && (p_CcNode->parseCode != CC_PC_FF_TCI2)
30792 + && (p_CcNode->parseCode != CC_PC_FF_MPLS1)
30793 + && (p_CcNode->parseCode != CC_PC_FF_MPLS_LAST)
30794 + && (p_CcNode->parseCode != CC_PC_FF_IPV4IPTOS_TC1)
30795 + && (p_CcNode->parseCode != CC_PC_FF_IPV4IPTOS_TC2)
30796 + && (p_CcNode->parseCode
30797 + != CC_PC_FF_IPTOS_IPV6TC1_IPV6FLOW1)
30798 + && (p_CcNode->parseCode != CC_PC_FF_IPDSCP)
30799 + && (p_CcNode->parseCode
30800 + != CC_PC_FF_IPTOS_IPV6TC2_IPV6FLOW2)
30801 + && glblMask)
30802 + {
30803 + glblMask = FALSE;
30804 + p_CcNode->glblMaskSize = 4;
30805 + p_CcNode->lclMask = TRUE;
30806 + }
30807 + break;
30808 +
30809 + case (e_FM_PCD_EXTRACT_FROM_HDR):
30810 + p_CcNode->sizeOfExtraction =
30811 + p_CcNodeParam->extractCcParams.extractByHdr.extractByHdrType.fromHdr.size;
30812 + p_CcNode->offset =
30813 + p_CcNodeParam->extractCcParams.extractByHdr.extractByHdrType.fromHdr.offset;
30814 + p_CcNode->userOffset =
30815 + p_CcNodeParam->extractCcParams.extractByHdr.extractByHdrType.fromHdr.offset;
30816 + p_CcNode->parseCode =
30817 + GetPrParseCode(
30818 + p_CcNodeParam->extractCcParams.extractByHdr.hdr,
30819 + p_CcNodeParam->extractCcParams.extractByHdr.hdrIndex,
30820 + p_CcNode->offset, glblMask,
30821 + &p_CcNode->prsArrayOffset);
30822 + break;
30823 +
30824 + case (e_FM_PCD_EXTRACT_FROM_FIELD):
30825 + p_CcNode->offset =
30826 + p_CcNodeParam->extractCcParams.extractByHdr.extractByHdrType.fromField.offset;
30827 + p_CcNode->userOffset =
30828 + p_CcNodeParam->extractCcParams.extractByHdr.extractByHdrType.fromField.offset;
30829 + p_CcNode->sizeOfExtraction =
30830 + p_CcNodeParam->extractCcParams.extractByHdr.extractByHdrType.fromField.size;
30831 + p_CcNode->parseCode =
30832 + GetFieldParseCode(
30833 + p_CcNodeParam->extractCcParams.extractByHdr.hdr,
30834 + p_CcNodeParam->extractCcParams.extractByHdr.extractByHdrType.fromField.field,
30835 + p_CcNode->offset,
30836 + &p_CcNode->prsArrayOffset,
30837 + p_CcNodeParam->extractCcParams.extractByHdr.hdrIndex);
30838 + break;
30839 +
30840 + default:
30841 + DeleteNode(p_CcNode);
30842 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION, NO_MSG);
30843 + }
30844 + break;
30845 +
30846 + case (e_FM_PCD_EXTRACT_NON_HDR):
30847 + /* get the field code for the generic extract */
30848 + p_CcNode->sizeOfExtraction =
30849 + p_CcNodeParam->extractCcParams.extractNonHdr.size;
30850 + p_CcNode->offset =
30851 + p_CcNodeParam->extractCcParams.extractNonHdr.offset;
30852 + p_CcNode->userOffset =
30853 + p_CcNodeParam->extractCcParams.extractNonHdr.offset;
30854 + p_CcNode->parseCode = GetGenParseCode(
30855 + p_CcNodeParam->extractCcParams.extractNonHdr.src,
30856 + p_CcNode->offset, glblMask, &p_CcNode->prsArrayOffset,
30857 + fromIc, icCode);
30858 +
30859 + if (p_CcNode->parseCode == CC_PC_GENERIC_IC_HASH_INDEXED)
30860 + {
30861 + if ((p_CcNode->offset + p_CcNode->sizeOfExtraction) > 8)
30862 + {
30863 + DeleteNode(p_CcNode);
30864 + RETURN_ERROR(
30865 + MAJOR,
30866 + E_INVALID_SELECTION,
30867 + ("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)"));
30868 + }
30869 + }
30870 + if ((p_CcNode->parseCode == CC_PC_GENERIC_IC_GMASK)
30871 + || (p_CcNode->parseCode == CC_PC_GENERIC_IC_HASH_INDEXED))
30872 + {
30873 + p_CcNode->offset += p_CcNode->prsArrayOffset;
30874 + p_CcNode->prsArrayOffset = 0;
30875 + }
30876 + break;
30877 +
30878 + default:
30879 + DeleteNode(p_CcNode);
30880 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION, NO_MSG);
30881 + }
30882 +
30883 + if (p_CcNode->parseCode == CC_PC_ILLEGAL)
30884 + {
30885 + DeleteNode(p_CcNode);
30886 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("illegal extraction type"));
30887 + }
30888 +
30889 + if ((p_CcNode->sizeOfExtraction > FM_PCD_MAX_SIZE_OF_KEY)
30890 + || !p_CcNode->sizeOfExtraction)
30891 + {
30892 + DeleteNode(p_CcNode);
30893 + RETURN_ERROR(MAJOR, E_INVALID_VALUE,
30894 + ("sizeOfExatrction can not be greater than 56 and not 0"));
30895 + }
30896 +
30897 + if (p_CcNodeParam->keysParams.keySize != p_CcNode->sizeOfExtraction)
30898 + {
30899 + DeleteNode(p_CcNode);
30900 + RETURN_ERROR(MAJOR, E_INVALID_VALUE,
30901 + ("keySize has to be equal to sizeOfExtraction"));
30902 + }
30903 +
30904 + p_CcNode->userSizeOfExtraction = p_CcNode->sizeOfExtraction;
30905 +
30906 + if (!glblMask)
30907 + memset(p_CcNode->p_GlblMask, 0xff, CC_GLBL_MASK_SIZE * sizeof(uint8_t));
30908 +
30909 + err = CheckAndSetManipParamsWithCcNodeParams(p_CcNode);
30910 + if (err != E_OK)
30911 + {
30912 + DeleteNode(p_CcNode);
30913 + RETURN_ERROR(MAJOR, E_INVALID_VALUE,
30914 + ("keySize has to be equal to sizeOfExtraction"));
30915 + }
30916 +
30917 + /* Calculating matching table entry size by rounding up the user-defined size of extraction to valid entry size */
30918 + GetCcExtractKeySize(p_CcNode->sizeOfExtraction,
30919 + &p_CcNode->ccKeySizeAccExtraction);
30920 +
30921 + /* If local mask is used, it is stored next to each key in the keys match table */
30922 + if (p_CcNode->lclMask)
30923 + keySize = (uint32_t)(2 * p_CcNode->ccKeySizeAccExtraction);
30924 + else
30925 + keySize = p_CcNode->ccKeySizeAccExtraction;
30926 +
30927 + /* Update CC shadow with maximal size required by this node */
30928 + if (p_CcNode->maxNumOfKeys)
30929 + {
30930 + err = CalcAndUpdateCcShadow(p_CcNode, isKeyTblAlloc, &matchTableSize,
30931 + &adTableSize);
30932 + if (err != E_OK)
30933 + {
30934 + DeleteNode(p_CcNode);
30935 + RETURN_ERROR(MAJOR, err, NO_MSG);
30936 + }
30937 +
30938 + p_CcNode->keysMatchTableMaxSize = matchTableSize;
30939 +
30940 + if (p_CcNode->statisticsMode != e_FM_PCD_CC_STATS_MODE_NONE)
30941 + {
30942 + err = AllocStatsObjs(p_CcNode);
30943 + if (err != E_OK)
30944 + {
30945 + DeleteNode(p_CcNode);
30946 + RETURN_ERROR(MAJOR, err, NO_MSG);
30947 + }
30948 + }
30949 +
30950 + /* If manipulation will be initialized before this node, it will use the table
30951 + descriptor in the AD table of previous node and this node will need an extra
30952 + AD as his table descriptor. */
30953 + p_CcNode->h_TmpAd = (t_Handle)FM_MURAM_AllocMem(
30954 + h_FmMuram, FM_PCD_CC_AD_ENTRY_SIZE, FM_PCD_CC_AD_TABLE_ALIGN);
30955 + if (!p_CcNode->h_TmpAd)
30956 + {
30957 + DeleteNode(p_CcNode);
30958 + RETURN_ERROR(MAJOR, E_NO_MEMORY,
30959 + ("MURAM allocation for CC action descriptor"));
30960 + }
30961 + }
30962 + else
30963 + {
30964 + matchTableSize = (uint32_t)(keySize * sizeof(uint8_t)
30965 + * (p_CcNode->numOfKeys + 1));
30966 + adTableSize = (uint32_t)(FM_PCD_CC_AD_ENTRY_SIZE
30967 + * (p_CcNode->numOfKeys + 1));
30968 + }
30969 +
30970 +#if (DPAA_VERSION >= 11)
30971 + switch (p_CcNode->statisticsMode)
30972 + {
30973 +
30974 + case e_FM_PCD_CC_STATS_MODE_RMON:
30975 + /* If RMON statistics or RMON conditional statistics modes are requested,
30976 + allocate frame length ranges array */
30977 + p_CcNode->h_StatsFLRs = FM_MURAM_AllocMem(
30978 + h_FmMuram,
30979 + (uint32_t)(p_CcNode->numOfStatsFLRs)
30980 + * FM_PCD_CC_STATS_FLR_SIZE,
30981 + FM_PCD_CC_AD_TABLE_ALIGN);
30982 +
30983 + if (!p_CcNode->h_StatsFLRs)
30984 + {
30985 + DeleteNode(p_CcNode);
30986 + RETURN_ERROR(
30987 + MAJOR, E_NO_MEMORY,
30988 + ("MURAM allocation for CC frame length ranges array"));
30989 + }
30990 +
30991 + /* Initialize using value received from the user */
30992 + for (tmp = 0; tmp < p_CcNode->numOfStatsFLRs; tmp++)
30993 + {
30994 + uint16_t flr =
30995 + cpu_to_be16(p_CcNodeParam->keysParams.frameLengthRanges[tmp]);
30996 +
30997 + h_StatsFLRs =
30998 + PTR_MOVE(p_CcNode->h_StatsFLRs, tmp * FM_PCD_CC_STATS_FLR_SIZE);
30999 +
31000 + MemCpy8(h_StatsFLRs,
31001 + &flr,
31002 + FM_PCD_CC_STATS_FLR_SIZE);
31003 + }
31004 + break;
31005 +
31006 + default:
31007 + break;
31008 + }
31009 +#endif /* (DPAA_VERSION >= 11) */
31010 +
31011 + /* Allocate keys match table. Not required for some CC nodes, for example for IPv4 TTL
31012 + identification, IPv6 hop count identification, etc. */
31013 + if (isKeyTblAlloc)
31014 + {
31015 + p_CcNode->h_KeysMatchTable = (t_Handle)FM_MURAM_AllocMem(
31016 + h_FmMuram, matchTableSize, FM_PCD_CC_KEYS_MATCH_TABLE_ALIGN);
31017 + if (!p_CcNode->h_KeysMatchTable)
31018 + {
31019 + DeleteNode(p_CcNode);
31020 + RETURN_ERROR(MAJOR, E_NO_MEMORY,
31021 + ("MURAM allocation for CC node key match table"));
31022 + }
31023 + MemSet8((uint8_t *)p_CcNode->h_KeysMatchTable, 0, matchTableSize);
31024 + }
31025 +
31026 + /* Allocate action descriptors table */
31027 + p_CcNode->h_AdTable = (t_Handle)FM_MURAM_AllocMem(h_FmMuram, adTableSize,
31028 + FM_PCD_CC_AD_TABLE_ALIGN);
31029 + if (!p_CcNode->h_AdTable)
31030 + {
31031 + DeleteNode(p_CcNode);
31032 + RETURN_ERROR(MAJOR, E_NO_MEMORY,
31033 + ("MURAM allocation for CC node action descriptors table"));
31034 + }
31035 + MemSet8((uint8_t *)p_CcNode->h_AdTable, 0, adTableSize);
31036 +
31037 + p_KeysMatchTblTmp = p_CcNode->h_KeysMatchTable;
31038 + p_AdTableTmp = p_CcNode->h_AdTable;
31039 +
31040 + /* For each key, create the key and the next step AD */
31041 + for (tmp = 0; tmp < p_CcNode->numOfKeys; tmp++)
31042 + {
31043 + p_KeyParams = &p_CcNodeParam->keysParams.keyParams[tmp];
31044 +
31045 + if (p_KeysMatchTblTmp)
31046 + {
31047 + /* Copy the key */
31048 + MemCpy8((void*)p_KeysMatchTblTmp, p_KeyParams->p_Key,
31049 + p_CcNode->sizeOfExtraction);
31050 +
31051 + /* Copy the key mask or initialize it to 0xFF..F */
31052 + if (p_CcNode->lclMask && p_KeyParams->p_Mask)
31053 + {
31054 + MemCpy8(PTR_MOVE(p_KeysMatchTblTmp,
31055 + p_CcNode->ccKeySizeAccExtraction), /* User's size of extraction rounded up to a valid matching table entry size */
31056 + p_KeyParams->p_Mask, p_CcNode->sizeOfExtraction); /* Exact size of extraction as received from the user */
31057 + }
31058 + else
31059 + if (p_CcNode->lclMask)
31060 + {
31061 + MemSet8(PTR_MOVE(p_KeysMatchTblTmp,
31062 + p_CcNode->ccKeySizeAccExtraction), /* User's size of extraction rounded up to a valid matching table entry size */
31063 + 0xff, p_CcNode->sizeOfExtraction); /* Exact size of extraction as received from the user */
31064 + }
31065 +
31066 + p_KeysMatchTblTmp =
31067 + PTR_MOVE(p_KeysMatchTblTmp, keySize * sizeof(uint8_t));
31068 + }
31069 +
31070 + /* Create the next action descriptor in the match table */
31071 + if (p_KeyParams->ccNextEngineParams.statisticsEn)
31072 + {
31073 + p_StatsObj = GetStatsObj(p_CcNode);
31074 + ASSERT_COND(p_StatsObj);
31075 +
31076 + statsParams.h_StatsAd = p_StatsObj->h_StatsAd;
31077 + statsParams.h_StatsCounters = p_StatsObj->h_StatsCounters;
31078 +#if (DPAA_VERSION >= 11)
31079 + statsParams.h_StatsFLRs = p_CcNode->h_StatsFLRs;
31080 +
31081 +#endif /* (DPAA_VERSION >= 11) */
31082 + NextStepAd(p_AdTableTmp, &statsParams,
31083 + &p_KeyParams->ccNextEngineParams, p_FmPcd);
31084 +
31085 + p_CcNode->keyAndNextEngineParams[tmp].p_StatsObj = p_StatsObj;
31086 + }
31087 + else
31088 + {
31089 + NextStepAd(p_AdTableTmp, NULL, &p_KeyParams->ccNextEngineParams,
31090 + p_FmPcd);
31091 +
31092 + p_CcNode->keyAndNextEngineParams[tmp].p_StatsObj = NULL;
31093 + }
31094 +
31095 + p_AdTableTmp = PTR_MOVE(p_AdTableTmp, FM_PCD_CC_AD_ENTRY_SIZE);
31096 + }
31097 +
31098 + /* Update next engine for the 'miss' entry */
31099 + if (p_CcNodeParam->keysParams.ccNextEngineParamsForMiss.statisticsEn)
31100 + {
31101 + p_StatsObj = GetStatsObj(p_CcNode);
31102 + ASSERT_COND(p_StatsObj);
31103 +
31104 + /* All 'bucket' nodes of a hash table should share the same statistics counters,
31105 + allocated by the hash table. So, if this node is a bucket of a hash table,
31106 + we'll replace the locally allocated counters with the shared counters. */
31107 + if (p_CcNode->isHashBucket)
31108 + {
31109 + ASSERT_COND(p_CcNode->h_MissStatsCounters);
31110 +
31111 + /* Store original counters pointer and replace it with mutual preallocated pointer */
31112 + p_CcNode->h_PrivMissStatsCounters = p_StatsObj->h_StatsCounters;
31113 + p_StatsObj->h_StatsCounters = p_CcNode->h_MissStatsCounters;
31114 + }
31115 +
31116 + statsParams.h_StatsAd = p_StatsObj->h_StatsAd;
31117 + statsParams.h_StatsCounters = p_StatsObj->h_StatsCounters;
31118 +#if (DPAA_VERSION >= 11)
31119 + statsParams.h_StatsFLRs = p_CcNode->h_StatsFLRs;
31120 +
31121 +#endif /* (DPAA_VERSION >= 11) */
31122 +
31123 + NextStepAd(p_AdTableTmp, &statsParams,
31124 + &p_CcNodeParam->keysParams.ccNextEngineParamsForMiss,
31125 + p_FmPcd);
31126 +
31127 + p_CcNode->keyAndNextEngineParams[tmp].p_StatsObj = p_StatsObj;
31128 + }
31129 + else
31130 + {
31131 + NextStepAd(p_AdTableTmp, NULL,
31132 + &p_CcNodeParam->keysParams.ccNextEngineParamsForMiss,
31133 + p_FmPcd);
31134 +
31135 + p_CcNode->keyAndNextEngineParams[tmp].p_StatsObj = NULL;
31136 + }
31137 +
31138 + /* This parameter will be used to initialize the "key length" field in the action descriptor
31139 + that points to this node and it should be 0 for full field extraction */
31140 + if (fullField == TRUE)
31141 + p_CcNode->sizeOfExtraction = 0;
31142 +
31143 + for (tmp = 0; tmp < MIN(p_CcNode->numOfKeys + 1, CC_MAX_NUM_OF_KEYS); tmp++)
31144 + {
31145 + if (p_CcNode->keyAndNextEngineParams[tmp].nextEngineParams.nextEngine
31146 + == e_FM_PCD_CC)
31147 + {
31148 + p_FmPcdCcNextNode =
31149 + (t_FmPcdCcNode*)p_CcNode->keyAndNextEngineParams[tmp].nextEngineParams.params.ccParams.h_CcNode;
31150 + p_CcInformation = FindNodeInfoInReleventLst(
31151 + &p_FmPcdCcNextNode->ccPrevNodesLst, (t_Handle)p_CcNode,
31152 + p_FmPcdCcNextNode->h_Spinlock);
31153 + if (!p_CcInformation)
31154 + {
31155 + memset(&ccNodeInfo, 0, sizeof(t_CcNodeInformation));
31156 + ccNodeInfo.h_CcNode = (t_Handle)p_CcNode;
31157 + ccNodeInfo.index = 1;
31158 + EnqueueNodeInfoToRelevantLst(&p_FmPcdCcNextNode->ccPrevNodesLst,
31159 + &ccNodeInfo,
31160 + p_FmPcdCcNextNode->h_Spinlock);
31161 + }
31162 + else
31163 + p_CcInformation->index++;
31164 +
31165 + if (p_CcNode->keyAndNextEngineParams[tmp].nextEngineParams.h_Manip)
31166 + {
31167 + h_Manip =
31168 + p_CcNode->keyAndNextEngineParams[tmp].nextEngineParams.h_Manip;
31169 + p_CcInformation = FindNodeInfoInReleventLst(
31170 + FmPcdManipGetNodeLstPointedOnThisManip(h_Manip),
31171 + (t_Handle)p_CcNode, FmPcdManipGetSpinlock(h_Manip));
31172 + if (!p_CcInformation)
31173 + {
31174 + memset(&ccNodeInfo, 0, sizeof(t_CcNodeInformation));
31175 + ccNodeInfo.h_CcNode = (t_Handle)p_CcNode;
31176 + ccNodeInfo.index = 1;
31177 + EnqueueNodeInfoToRelevantLst(
31178 + FmPcdManipGetNodeLstPointedOnThisManip(h_Manip),
31179 + &ccNodeInfo, FmPcdManipGetSpinlock(h_Manip));
31180 + }
31181 + else
31182 + p_CcInformation->index++;
31183 + }
31184 + }
31185 + }
31186 +
31187 + p_AdTableTmp = p_CcNode->h_AdTable;
31188 +
31189 + if (!FmPcdLockTryLockAll(h_FmPcd))
31190 + {
31191 + FM_PCD_MatchTableDelete((t_Handle)p_CcNode);
31192 + DBG(TRACE, ("FmPcdLockTryLockAll failed"));
31193 + return ERROR_CODE(E_BUSY);
31194 + }
31195 +
31196 + /* Required action for each next engine */
31197 + for (tmp = 0; tmp < MIN(p_CcNode->numOfKeys + 1, CC_MAX_NUM_OF_KEYS); tmp++)
31198 + {
31199 + if (p_CcNode->keyAndNextEngineParams[tmp].requiredAction)
31200 + {
31201 + err = SetRequiredAction(
31202 + h_FmPcd,
31203 + p_CcNode->keyAndNextEngineParams[tmp].requiredAction,
31204 + &p_CcNode->keyAndNextEngineParams[tmp], p_AdTableTmp, 1,
31205 + NULL);
31206 + if (err)
31207 + {
31208 + FmPcdLockUnlockAll(h_FmPcd);
31209 + FM_PCD_MatchTableDelete((t_Handle)p_CcNode);
31210 + RETURN_ERROR(MAJOR, err, NO_MSG);
31211 + }
31212 + p_AdTableTmp = PTR_MOVE(p_AdTableTmp, FM_PCD_CC_AD_ENTRY_SIZE);
31213 + }
31214 + }
31215 +
31216 + FmPcdLockUnlockAll(h_FmPcd);
31217 +
31218 + return E_OK;
31219 +}
31220 +/************************** End of static functions **************************/
31221 +
31222 +/*****************************************************************************/
31223 +/* Inter-module API routines */
31224 +/*****************************************************************************/
31225 +
31226 +t_CcNodeInformation* FindNodeInfoInReleventLst(t_List *p_List, t_Handle h_Info,
31227 + t_Handle h_Spinlock)
31228 +{
31229 + t_CcNodeInformation *p_CcInformation;
31230 + t_List *p_Pos;
31231 + uint32_t intFlags;
31232 +
31233 + intFlags = XX_LockIntrSpinlock(h_Spinlock);
31234 +
31235 + for (p_Pos = LIST_FIRST(p_List); p_Pos != (p_List);
31236 + p_Pos = LIST_NEXT(p_Pos))
31237 + {
31238 + p_CcInformation = CC_NODE_F_OBJECT(p_Pos);
31239 +
31240 + ASSERT_COND(p_CcInformation->h_CcNode);
31241 +
31242 + if (p_CcInformation->h_CcNode == h_Info)
31243 + {
31244 + XX_UnlockIntrSpinlock(h_Spinlock, intFlags);
31245 + return p_CcInformation;
31246 + }
31247 + }
31248 +
31249 + XX_UnlockIntrSpinlock(h_Spinlock, intFlags);
31250 +
31251 + return NULL;
31252 +}
31253 +
31254 +void EnqueueNodeInfoToRelevantLst(t_List *p_List, t_CcNodeInformation *p_CcInfo,
31255 + t_Handle h_Spinlock)
31256 +{
31257 + t_CcNodeInformation *p_CcInformation;
31258 + uint32_t intFlags = 0;
31259 +
31260 + p_CcInformation = (t_CcNodeInformation *)XX_Malloc(
31261 + sizeof(t_CcNodeInformation));
31262 +
31263 + if (p_CcInformation)
31264 + {
31265 + memset(p_CcInformation, 0, sizeof(t_CcNodeInformation));
31266 + memcpy(p_CcInformation, p_CcInfo, sizeof(t_CcNodeInformation));
31267 + INIT_LIST(&p_CcInformation->node);
31268 +
31269 + if (h_Spinlock)
31270 + intFlags = XX_LockIntrSpinlock(h_Spinlock);
31271 +
31272 + LIST_AddToTail(&p_CcInformation->node, p_List);
31273 +
31274 + if (h_Spinlock)
31275 + XX_UnlockIntrSpinlock(h_Spinlock, intFlags);
31276 + }
31277 + else
31278 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("CC Node Information"));
31279 +}
31280 +
31281 +void DequeueNodeInfoFromRelevantLst(t_List *p_List, t_Handle h_Info,
31282 + t_Handle h_Spinlock)
31283 +{
31284 + t_CcNodeInformation *p_CcInformation = NULL;
31285 + uint32_t intFlags = 0;
31286 + t_List *p_Pos;
31287 +
31288 + if (h_Spinlock)
31289 + intFlags = XX_LockIntrSpinlock(h_Spinlock);
31290 +
31291 + if (LIST_IsEmpty(p_List))
31292 + {
31293 + XX_RestoreAllIntr(intFlags);
31294 + return;
31295 + }
31296 +
31297 + for (p_Pos = LIST_FIRST(p_List); p_Pos != (p_List);
31298 + p_Pos = LIST_NEXT(p_Pos))
31299 + {
31300 + p_CcInformation = CC_NODE_F_OBJECT(p_Pos);
31301 + ASSERT_COND(p_CcInformation);
31302 + ASSERT_COND(p_CcInformation->h_CcNode);
31303 + if (p_CcInformation->h_CcNode == h_Info)
31304 + break;
31305 + }
31306 +
31307 + if (p_CcInformation)
31308 + {
31309 + LIST_DelAndInit(&p_CcInformation->node);
31310 + XX_Free(p_CcInformation);
31311 + }
31312 +
31313 + if (h_Spinlock)
31314 + XX_UnlockIntrSpinlock(h_Spinlock, intFlags);
31315 +}
31316 +
31317 +void NextStepAd(t_Handle h_Ad, t_FmPcdCcStatsParams *p_FmPcdCcStatsParams,
31318 + t_FmPcdCcNextEngineParams *p_FmPcdCcNextEngineParams,
31319 + t_FmPcd *p_FmPcd)
31320 +{
31321 + switch (p_FmPcdCcNextEngineParams->nextEngine)
31322 + {
31323 + case (e_FM_PCD_KG):
31324 + case (e_FM_PCD_PLCR):
31325 + case (e_FM_PCD_DONE):
31326 + /* if NIA is not CC, create a "result" type AD */
31327 + FillAdOfTypeResult(h_Ad, p_FmPcdCcStatsParams, p_FmPcd,
31328 + p_FmPcdCcNextEngineParams);
31329 + break;
31330 +#if (DPAA_VERSION >= 11)
31331 + case (e_FM_PCD_FR):
31332 + if (p_FmPcdCcNextEngineParams->params.frParams.h_FrmReplic)
31333 + {
31334 + FillAdOfTypeContLookup(
31335 + h_Ad, p_FmPcdCcStatsParams, p_FmPcd,
31336 + p_FmPcdCcNextEngineParams->params.ccParams.h_CcNode,
31337 + p_FmPcdCcNextEngineParams->h_Manip,
31338 + p_FmPcdCcNextEngineParams->params.frParams.h_FrmReplic);
31339 + FrmReplicGroupUpdateOwner(
31340 + p_FmPcdCcNextEngineParams->params.frParams.h_FrmReplic,
31341 + TRUE/* add */);
31342 + }
31343 + break;
31344 +#endif /* (DPAA_VERSION >= 11) */
31345 +
31346 + case (e_FM_PCD_CC):
31347 + /* if NIA is not CC, create a TD to continue the CC lookup */
31348 + FillAdOfTypeContLookup(
31349 + h_Ad, p_FmPcdCcStatsParams, p_FmPcd,
31350 + p_FmPcdCcNextEngineParams->params.ccParams.h_CcNode,
31351 + p_FmPcdCcNextEngineParams->h_Manip, NULL);
31352 +
31353 + UpdateNodeOwner(p_FmPcdCcNextEngineParams->params.ccParams.h_CcNode,
31354 + TRUE);
31355 + break;
31356 +
31357 + default:
31358 + return;
31359 + }
31360 +}
31361 +
31362 +t_Error FmPcdCcTreeAddIPR(t_Handle h_FmPcd, t_Handle h_FmTree,
31363 + t_Handle h_NetEnv, t_Handle h_IpReassemblyManip,
31364 + bool createSchemes)
31365 +{
31366 + t_FmPcdCcTree *p_FmPcdCcTree = (t_FmPcdCcTree *)h_FmTree;
31367 + t_FmPcdCcNextEngineParams nextEngineParams;
31368 + t_NetEnvParams netEnvParams;
31369 + t_Handle h_Ad;
31370 + bool isIpv6Present;
31371 + uint8_t ipv4GroupId, ipv6GroupId;
31372 + t_Error err;
31373 +
31374 + ASSERT_COND(p_FmPcdCcTree);
31375 +
31376 + /* this routine must be protected by the calling routine! */
31377 +
31378 + memset(&nextEngineParams, 0, sizeof(t_FmPcdCcNextEngineParams));
31379 + memset(&netEnvParams, 0, sizeof(t_NetEnvParams));
31380 +
31381 + h_Ad = UINT_TO_PTR(p_FmPcdCcTree->ccTreeBaseAddr);
31382 +
31383 + isIpv6Present = FmPcdManipIpReassmIsIpv6Hdr(h_IpReassemblyManip);
31384 +
31385 + if (isIpv6Present
31386 + && (p_FmPcdCcTree->numOfEntries > (FM_PCD_MAX_NUM_OF_CC_GROUPS - 2)))
31387 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("need two free entries for IPR"));
31388 +
31389 + if (p_FmPcdCcTree->numOfEntries > (FM_PCD_MAX_NUM_OF_CC_GROUPS - 1))
31390 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("need two free entries for IPR"));
31391 +
31392 + nextEngineParams.nextEngine = e_FM_PCD_DONE;
31393 + nextEngineParams.h_Manip = h_IpReassemblyManip;
31394 +
31395 + /* Lock tree */
31396 + err = CcRootTryLock(p_FmPcdCcTree);
31397 + if (err)
31398 + return ERROR_CODE(E_BUSY);
31399 +
31400 + if (p_FmPcdCcTree->h_IpReassemblyManip == h_IpReassemblyManip)
31401 + {
31402 + CcRootReleaseLock(p_FmPcdCcTree);
31403 + return E_OK;
31404 + }
31405 +
31406 + if ((p_FmPcdCcTree->h_IpReassemblyManip)
31407 + && (p_FmPcdCcTree->h_IpReassemblyManip != h_IpReassemblyManip))
31408 + {
31409 + CcRootReleaseLock(p_FmPcdCcTree);
31410 + RETURN_ERROR(MAJOR, E_INVALID_STATE,
31411 + ("This tree was previously updated with different IPR"));
31412 + }
31413 +
31414 + /* Initialize IPR for the first time for this tree */
31415 + if (isIpv6Present)
31416 + {
31417 + ipv6GroupId = p_FmPcdCcTree->numOfGrps++;
31418 + p_FmPcdCcTree->fmPcdGroupParam[ipv6GroupId].baseGroupEntry =
31419 + (FM_PCD_MAX_NUM_OF_CC_GROUPS - 2);
31420 +
31421 + if (createSchemes)
31422 + {
31423 + err = FmPcdManipBuildIpReassmScheme(h_FmPcd, h_NetEnv,
31424 + p_FmPcdCcTree,
31425 + h_IpReassemblyManip, FALSE,
31426 + ipv6GroupId);
31427 + if (err)
31428 + {
31429 + p_FmPcdCcTree->numOfGrps--;
31430 + CcRootReleaseLock(p_FmPcdCcTree);
31431 + RETURN_ERROR(MAJOR, err, NO_MSG);
31432 + }
31433 + }
31434 +
31435 + NextStepAd(
31436 + PTR_MOVE(h_Ad, (FM_PCD_MAX_NUM_OF_CC_GROUPS-2) * FM_PCD_CC_AD_ENTRY_SIZE),
31437 + NULL, &nextEngineParams, h_FmPcd);
31438 + }
31439 +
31440 + ipv4GroupId = p_FmPcdCcTree->numOfGrps++;
31441 + p_FmPcdCcTree->fmPcdGroupParam[ipv4GroupId].totalBitsMask = 0;
31442 + p_FmPcdCcTree->fmPcdGroupParam[ipv4GroupId].baseGroupEntry =
31443 + (FM_PCD_MAX_NUM_OF_CC_GROUPS - 1);
31444 +
31445 + if (createSchemes)
31446 + {
31447 + err = FmPcdManipBuildIpReassmScheme(h_FmPcd, h_NetEnv, p_FmPcdCcTree,
31448 + h_IpReassemblyManip, TRUE,
31449 + ipv4GroupId);
31450 + if (err)
31451 + {
31452 + p_FmPcdCcTree->numOfGrps--;
31453 + if (isIpv6Present)
31454 + {
31455 + p_FmPcdCcTree->numOfGrps--;
31456 + FmPcdManipDeleteIpReassmSchemes(h_IpReassemblyManip);
31457 + }
31458 + CcRootReleaseLock(p_FmPcdCcTree);
31459 + RETURN_ERROR(MAJOR, err, NO_MSG);
31460 + }
31461 + }
31462 +
31463 + NextStepAd(
31464 + PTR_MOVE(h_Ad, (FM_PCD_MAX_NUM_OF_CC_GROUPS-1) * FM_PCD_CC_AD_ENTRY_SIZE),
31465 + NULL, &nextEngineParams, h_FmPcd);
31466 +
31467 + p_FmPcdCcTree->h_IpReassemblyManip = h_IpReassemblyManip;
31468 +
31469 + CcRootReleaseLock(p_FmPcdCcTree);
31470 +
31471 + return E_OK;
31472 +}
31473 +
31474 +t_Error FmPcdCcTreeAddCPR(t_Handle h_FmPcd, t_Handle h_FmTree,
31475 + t_Handle h_NetEnv, t_Handle h_ReassemblyManip,
31476 + bool createSchemes)
31477 +{
31478 + t_FmPcdCcTree *p_FmPcdCcTree = (t_FmPcdCcTree *)h_FmTree;
31479 + t_FmPcdCcNextEngineParams nextEngineParams;
31480 + t_NetEnvParams netEnvParams;
31481 + t_Handle h_Ad;
31482 + uint8_t groupId;
31483 + t_Error err;
31484 +
31485 + ASSERT_COND(p_FmPcdCcTree);
31486 +
31487 + /* this routine must be protected by the calling routine! */
31488 + memset(&nextEngineParams, 0, sizeof(t_FmPcdCcNextEngineParams));
31489 + memset(&netEnvParams, 0, sizeof(t_NetEnvParams));
31490 +
31491 + h_Ad = UINT_TO_PTR(p_FmPcdCcTree->ccTreeBaseAddr);
31492 +
31493 + if (p_FmPcdCcTree->numOfEntries > (FM_PCD_MAX_NUM_OF_CC_GROUPS - 1))
31494 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("need one free entries for CPR"));
31495 +
31496 + nextEngineParams.nextEngine = e_FM_PCD_DONE;
31497 + nextEngineParams.h_Manip = h_ReassemblyManip;
31498 +
31499 + /* Lock tree */
31500 + err = CcRootTryLock(p_FmPcdCcTree);
31501 + if (err)
31502 + return ERROR_CODE(E_BUSY);
31503 +
31504 + if (p_FmPcdCcTree->h_CapwapReassemblyManip == h_ReassemblyManip)
31505 + {
31506 + CcRootReleaseLock(p_FmPcdCcTree);
31507 + return E_OK;
31508 + }
31509 +
31510 + if ((p_FmPcdCcTree->h_CapwapReassemblyManip)
31511 + && (p_FmPcdCcTree->h_CapwapReassemblyManip != h_ReassemblyManip))
31512 + {
31513 + CcRootReleaseLock(p_FmPcdCcTree);
31514 + RETURN_ERROR(MAJOR, E_INVALID_STATE,
31515 + ("This tree was previously updated with different CPR"));
31516 + }
31517 +
31518 + groupId = p_FmPcdCcTree->numOfGrps++;
31519 + p_FmPcdCcTree->fmPcdGroupParam[groupId].baseGroupEntry =
31520 + (FM_PCD_MAX_NUM_OF_CC_GROUPS - 1);
31521 +
31522 + if (createSchemes)
31523 + {
31524 + err = FmPcdManipBuildCapwapReassmScheme(h_FmPcd, h_NetEnv,
31525 + p_FmPcdCcTree,
31526 + h_ReassemblyManip, groupId);
31527 + if (err)
31528 + {
31529 + p_FmPcdCcTree->numOfGrps--;
31530 + CcRootReleaseLock(p_FmPcdCcTree);
31531 + RETURN_ERROR(MAJOR, err, NO_MSG);
31532 + }
31533 + }
31534 +
31535 + NextStepAd(
31536 + PTR_MOVE(h_Ad, (FM_PCD_MAX_NUM_OF_CC_GROUPS-1) * FM_PCD_CC_AD_ENTRY_SIZE),
31537 + NULL, &nextEngineParams, h_FmPcd);
31538 +
31539 + p_FmPcdCcTree->h_CapwapReassemblyManip = h_ReassemblyManip;
31540 +
31541 + CcRootReleaseLock(p_FmPcdCcTree);
31542 +
31543 + return E_OK;
31544 +}
31545 +
31546 +t_Handle FmPcdCcTreeGetSavedManipParams(t_Handle h_FmTree)
31547 +{
31548 + t_FmPcdCcTree *p_FmPcdCcTree = (t_FmPcdCcTree *)h_FmTree;
31549 +
31550 + ASSERT_COND(p_FmPcdCcTree);
31551 +
31552 + return p_FmPcdCcTree->h_FmPcdCcSavedManipParams;
31553 +}
31554 +
31555 +void FmPcdCcTreeSetSavedManipParams(t_Handle h_FmTree,
31556 + t_Handle h_SavedManipParams)
31557 +{
31558 + t_FmPcdCcTree *p_FmPcdCcTree = (t_FmPcdCcTree *)h_FmTree;
31559 +
31560 + ASSERT_COND(p_FmPcdCcTree);
31561 +
31562 + p_FmPcdCcTree->h_FmPcdCcSavedManipParams = h_SavedManipParams;
31563 +}
31564 +
31565 +uint8_t FmPcdCcGetParseCode(t_Handle h_CcNode)
31566 +{
31567 + t_FmPcdCcNode *p_CcNode = (t_FmPcdCcNode *)h_CcNode;
31568 +
31569 + ASSERT_COND(p_CcNode);
31570 +
31571 + return p_CcNode->parseCode;
31572 +}
31573 +
31574 +uint8_t FmPcdCcGetOffset(t_Handle h_CcNode)
31575 +{
31576 + t_FmPcdCcNode *p_CcNode = (t_FmPcdCcNode *)h_CcNode;
31577 +
31578 + ASSERT_COND(p_CcNode);
31579 +
31580 + return p_CcNode->offset;
31581 +}
31582 +
31583 +uint16_t FmPcdCcGetNumOfKeys(t_Handle h_CcNode)
31584 +{
31585 + t_FmPcdCcNode *p_CcNode = (t_FmPcdCcNode *)h_CcNode;
31586 +
31587 + ASSERT_COND(p_CcNode);
31588 +
31589 + return p_CcNode->numOfKeys;
31590 +}
31591 +
31592 +t_Error FmPcdCcModifyNextEngineParamTree(
31593 + t_Handle h_FmPcd, t_Handle h_FmPcdCcTree, uint8_t grpId, uint8_t index,
31594 + t_FmPcdCcNextEngineParams *p_FmPcdCcNextEngineParams)
31595 +{
31596 + t_FmPcdCcTree *p_FmPcdCcTree = (t_FmPcdCcTree *)h_FmPcdCcTree;
31597 + t_FmPcd *p_FmPcd;
31598 + t_List h_OldPointersLst, h_NewPointersLst;
31599 + uint16_t keyIndex;
31600 + t_FmPcdModifyCcKeyAdditionalParams *p_ModifyKeyParams;
31601 + t_Error err = E_OK;
31602 +
31603 + SANITY_CHECK_RETURN_ERROR(h_FmPcd, E_INVALID_HANDLE);
31604 + SANITY_CHECK_RETURN_ERROR(h_FmPcdCcTree, E_INVALID_HANDLE);
31605 + SANITY_CHECK_RETURN_ERROR((grpId <= 7), E_INVALID_VALUE);
31606 +
31607 + if (grpId >= p_FmPcdCcTree->numOfGrps)
31608 + RETURN_ERROR(MAJOR, E_INVALID_HANDLE,
31609 + ("grpId you asked > numOfGroup of relevant tree"));
31610 +
31611 + if (index >= p_FmPcdCcTree->fmPcdGroupParam[grpId].numOfEntriesInGroup)
31612 + RETURN_ERROR(MAJOR, E_INVALID_HANDLE, ("index > numOfEntriesInGroup"));
31613 +
31614 + p_FmPcd = (t_FmPcd *)h_FmPcd;
31615 +
31616 + INIT_LIST(&h_OldPointersLst);
31617 + INIT_LIST(&h_NewPointersLst);
31618 +
31619 + keyIndex = (uint16_t)(p_FmPcdCcTree->fmPcdGroupParam[grpId].baseGroupEntry
31620 + + index);
31621 +
31622 + p_ModifyKeyParams = ModifyNodeCommonPart(p_FmPcdCcTree, keyIndex,
31623 + e_MODIFY_STATE_CHANGE, FALSE,
31624 + FALSE, TRUE);
31625 + if (!p_ModifyKeyParams)
31626 + RETURN_ERROR(MAJOR, E_INVALID_STATE, NO_MSG);
31627 +
31628 + p_ModifyKeyParams->tree = TRUE;
31629 +
31630 + if (p_FmPcd->p_CcShadow
31631 + && !TRY_LOCK(p_FmPcd->h_ShadowSpinlock, &p_FmPcd->shadowLock))
31632 + {
31633 + XX_Free(p_ModifyKeyParams);
31634 + return ERROR_CODE(E_BUSY);
31635 + }
31636 +
31637 + err = BuildNewNodeModifyNextEngine(p_FmPcd, p_FmPcdCcTree, keyIndex,
31638 + p_FmPcdCcNextEngineParams,
31639 + &h_OldPointersLst, &h_NewPointersLst,
31640 + p_ModifyKeyParams);
31641 + if (err)
31642 + {
31643 + XX_Free(p_ModifyKeyParams);
31644 + RETURN_ERROR(MAJOR, err, NO_MSG);
31645 + }
31646 +
31647 + err = DoDynamicChange(p_FmPcd, &h_OldPointersLst, &h_NewPointersLst,
31648 + p_ModifyKeyParams, FALSE);
31649 +
31650 + if (p_FmPcd->p_CcShadow)
31651 + RELEASE_LOCK(p_FmPcd->shadowLock);
31652 +
31653 + ReleaseLst(&h_OldPointersLst);
31654 + ReleaseLst(&h_NewPointersLst);
31655 +
31656 + return err;
31657 +
31658 +}
31659 +
31660 +t_Error FmPcdCcRemoveKey(t_Handle h_FmPcd, t_Handle h_FmPcdCcNode,
31661 + uint16_t keyIndex)
31662 +{
31663 +
31664 + t_FmPcdCcNode *p_CcNode = (t_FmPcdCcNode *)h_FmPcdCcNode;
31665 + t_FmPcd *p_FmPcd;
31666 + t_FmPcdModifyCcKeyAdditionalParams *p_ModifyKeyParams;
31667 + t_List h_OldPointersLst, h_NewPointersLst;
31668 + bool useShadowStructs = FALSE;
31669 + t_Error err = E_OK;
31670 +
31671 + if (keyIndex >= p_CcNode->numOfKeys)
31672 + RETURN_ERROR(MAJOR, E_INVALID_VALUE,
31673 + ("impossible to remove key when numOfKeys <= keyIndex"));
31674 +
31675 + if (p_CcNode->h_FmPcd != h_FmPcd)
31676 + RETURN_ERROR(
31677 + MAJOR,
31678 + E_INVALID_VALUE,
31679 + ("handler to FmPcd is different from the handle provided at node initialization time"));
31680 +
31681 + p_FmPcd = (t_FmPcd *)p_CcNode->h_FmPcd;
31682 +
31683 + INIT_LIST(&h_OldPointersLst);
31684 + INIT_LIST(&h_NewPointersLst);
31685 +
31686 + p_ModifyKeyParams = ModifyNodeCommonPart(p_CcNode, keyIndex,
31687 + e_MODIFY_STATE_REMOVE, TRUE, TRUE,
31688 + FALSE);
31689 + if (!p_ModifyKeyParams)
31690 + RETURN_ERROR(MAJOR, E_INVALID_STATE, NO_MSG);
31691 +
31692 + if (p_CcNode->maxNumOfKeys)
31693 + {
31694 + if (!TRY_LOCK(p_FmPcd->h_ShadowSpinlock, &p_FmPcd->shadowLock))
31695 + {
31696 + XX_Free(p_ModifyKeyParams);
31697 + return ERROR_CODE(E_BUSY);
31698 + }
31699 +
31700 + useShadowStructs = TRUE;
31701 + }
31702 +
31703 + err = BuildNewNodeRemoveKey(p_CcNode, keyIndex, p_ModifyKeyParams);
31704 + if (err)
31705 + {
31706 + XX_Free(p_ModifyKeyParams);
31707 + if (p_CcNode->maxNumOfKeys)
31708 + RELEASE_LOCK(p_FmPcd->shadowLock);
31709 + RETURN_ERROR(MAJOR, err, NO_MSG);
31710 + }
31711 +
31712 + err = UpdatePtrWhichPointOnCrntMdfNode(p_CcNode, p_ModifyKeyParams,
31713 + &h_OldPointersLst,
31714 + &h_NewPointersLst);
31715 + if (err)
31716 + {
31717 + ReleaseNewNodeCommonPart(p_ModifyKeyParams);
31718 + XX_Free(p_ModifyKeyParams);
31719 + if (p_CcNode->maxNumOfKeys)
31720 + RELEASE_LOCK(p_FmPcd->shadowLock);
31721 + RETURN_ERROR(MAJOR, err, NO_MSG);
31722 + }
31723 +
31724 + err = DoDynamicChange(p_FmPcd, &h_OldPointersLst, &h_NewPointersLst,
31725 + p_ModifyKeyParams, useShadowStructs);
31726 +
31727 + if (p_CcNode->maxNumOfKeys)
31728 + RELEASE_LOCK(p_FmPcd->shadowLock);
31729 +
31730 + ReleaseLst(&h_OldPointersLst);
31731 + ReleaseLst(&h_NewPointersLst);
31732 +
31733 + return err;
31734 +}
31735 +
31736 +t_Error FmPcdCcModifyKey(t_Handle h_FmPcd, t_Handle h_FmPcdCcNode,
31737 + uint16_t keyIndex, uint8_t keySize, uint8_t *p_Key,
31738 + uint8_t *p_Mask)
31739 +{
31740 + t_FmPcdCcNode *p_CcNode = (t_FmPcdCcNode *)h_FmPcdCcNode;
31741 + t_FmPcd *p_FmPcd;
31742 + t_List h_OldPointersLst, h_NewPointersLst;
31743 + t_FmPcdModifyCcKeyAdditionalParams *p_ModifyKeyParams;
31744 + uint16_t tmpKeyIndex;
31745 + bool useShadowStructs = FALSE;
31746 + t_Error err = E_OK;
31747 +
31748 + if (keyIndex >= p_CcNode->numOfKeys)
31749 + RETURN_ERROR(MAJOR, E_INVALID_STATE,
31750 + ("keyIndex > previously cleared last index + 1"));
31751 +
31752 + if (keySize != p_CcNode->userSizeOfExtraction)
31753 + RETURN_ERROR(
31754 + MAJOR,
31755 + E_INVALID_VALUE,
31756 + ("size for ModifyKey has to be the same as defined in SetNode"));
31757 +
31758 + if (p_CcNode->h_FmPcd != h_FmPcd)
31759 + RETURN_ERROR(
31760 + MAJOR,
31761 + E_INVALID_VALUE,
31762 + ("handler to FmPcd is different from the handle provided at node initialization time"));
31763 +
31764 + err = FindKeyIndex(h_FmPcdCcNode, keySize, p_Key, p_Mask, &tmpKeyIndex);
31765 + if (GET_ERROR_TYPE(err) != E_NOT_FOUND)
31766 + RETURN_ERROR(
31767 + MINOR,
31768 + E_ALREADY_EXISTS,
31769 + ("The received key and mask pair was already found in the match table of the provided node"));
31770 +
31771 + p_FmPcd = (t_FmPcd *)p_CcNode->h_FmPcd;
31772 +
31773 + INIT_LIST(&h_OldPointersLst);
31774 + INIT_LIST(&h_NewPointersLst);
31775 +
31776 + p_ModifyKeyParams = ModifyNodeCommonPart(p_CcNode, keyIndex,
31777 + e_MODIFY_STATE_CHANGE, TRUE, TRUE,
31778 + FALSE);
31779 + if (!p_ModifyKeyParams)
31780 + RETURN_ERROR(MAJOR, E_INVALID_STATE, NO_MSG);
31781 +
31782 + if (p_CcNode->maxNumOfKeys)
31783 + {
31784 + if (!TRY_LOCK(p_FmPcd->h_ShadowSpinlock, &p_FmPcd->shadowLock))
31785 + {
31786 + XX_Free(p_ModifyKeyParams);
31787 + return ERROR_CODE(E_BUSY);
31788 + }
31789 +
31790 + useShadowStructs = TRUE;
31791 + }
31792 +
31793 + err = BuildNewNodeModifyKey(p_CcNode, keyIndex, p_Key, p_Mask,
31794 + p_ModifyKeyParams);
31795 + if (err)
31796 + {
31797 + XX_Free(p_ModifyKeyParams);
31798 + if (p_CcNode->maxNumOfKeys)
31799 + RELEASE_LOCK(p_FmPcd->shadowLock);
31800 + RETURN_ERROR(MAJOR, err, NO_MSG);
31801 + }
31802 +
31803 + err = UpdatePtrWhichPointOnCrntMdfNode(p_CcNode, p_ModifyKeyParams,
31804 + &h_OldPointersLst,
31805 + &h_NewPointersLst);
31806 + if (err)
31807 + {
31808 + ReleaseNewNodeCommonPart(p_ModifyKeyParams);
31809 + XX_Free(p_ModifyKeyParams);
31810 + if (p_CcNode->maxNumOfKeys)
31811 + RELEASE_LOCK(p_FmPcd->shadowLock);
31812 + RETURN_ERROR(MAJOR, err, NO_MSG);
31813 + }
31814 +
31815 + err = DoDynamicChange(p_FmPcd, &h_OldPointersLst, &h_NewPointersLst,
31816 + p_ModifyKeyParams, useShadowStructs);
31817 +
31818 + if (p_CcNode->maxNumOfKeys)
31819 + RELEASE_LOCK(p_FmPcd->shadowLock);
31820 +
31821 + ReleaseLst(&h_OldPointersLst);
31822 + ReleaseLst(&h_NewPointersLst);
31823 +
31824 + return err;
31825 +}
31826 +
31827 +t_Error FmPcdCcModifyMissNextEngineParamNode(
31828 + t_Handle h_FmPcd, t_Handle h_FmPcdCcNode,
31829 + t_FmPcdCcNextEngineParams *p_FmPcdCcNextEngineParams)
31830 +{
31831 + t_FmPcdCcNode *p_CcNode = (t_FmPcdCcNode *)h_FmPcdCcNode;
31832 + t_FmPcd *p_FmPcd;
31833 + t_List h_OldPointersLst, h_NewPointersLst;
31834 + uint16_t keyIndex;
31835 + t_FmPcdModifyCcKeyAdditionalParams *p_ModifyKeyParams;
31836 + t_Error err = E_OK;
31837 +
31838 + SANITY_CHECK_RETURN_ERROR(p_CcNode, E_INVALID_VALUE);
31839 +
31840 + keyIndex = p_CcNode->numOfKeys;
31841 +
31842 + p_FmPcd = (t_FmPcd *)p_CcNode->h_FmPcd;
31843 +
31844 + INIT_LIST(&h_OldPointersLst);
31845 + INIT_LIST(&h_NewPointersLst);
31846 +
31847 + p_ModifyKeyParams = ModifyNodeCommonPart(p_CcNode, keyIndex,
31848 + e_MODIFY_STATE_CHANGE, FALSE, TRUE,
31849 + FALSE);
31850 + if (!p_ModifyKeyParams)
31851 + RETURN_ERROR(MAJOR, E_INVALID_STATE, NO_MSG);
31852 +
31853 + if (p_CcNode->maxNumOfKeys
31854 + && !TRY_LOCK(p_FmPcd->h_ShadowSpinlock, &p_FmPcd->shadowLock))
31855 + {
31856 + XX_Free(p_ModifyKeyParams);
31857 + return ERROR_CODE(E_BUSY);
31858 + }
31859 +
31860 + err = BuildNewNodeModifyNextEngine(h_FmPcd, p_CcNode, keyIndex,
31861 + p_FmPcdCcNextEngineParams,
31862 + &h_OldPointersLst, &h_NewPointersLst,
31863 + p_ModifyKeyParams);
31864 + if (err)
31865 + {
31866 + XX_Free(p_ModifyKeyParams);
31867 + if (p_CcNode->maxNumOfKeys)
31868 + RELEASE_LOCK(p_FmPcd->shadowLock);
31869 + RETURN_ERROR(MAJOR, err, NO_MSG);
31870 + }
31871 +
31872 + err = DoDynamicChange(p_FmPcd, &h_OldPointersLst, &h_NewPointersLst,
31873 + p_ModifyKeyParams, FALSE);
31874 +
31875 + if (p_CcNode->maxNumOfKeys)
31876 + RELEASE_LOCK(p_FmPcd->shadowLock);
31877 +
31878 + ReleaseLst(&h_OldPointersLst);
31879 + ReleaseLst(&h_NewPointersLst);
31880 +
31881 + return err;
31882 +}
31883 +
31884 +t_Error FmPcdCcAddKey(t_Handle h_FmPcd, t_Handle h_FmPcdCcNode,
31885 + uint16_t keyIndex, uint8_t keySize,
31886 + t_FmPcdCcKeyParams *p_FmPcdCcKeyParams)
31887 +{
31888 + t_FmPcdCcNode *p_CcNode = (t_FmPcdCcNode *)h_FmPcdCcNode;
31889 + t_FmPcd *p_FmPcd;
31890 + t_FmPcdModifyCcKeyAdditionalParams *p_ModifyKeyParams;
31891 + t_List h_OldPointersLst, h_NewPointersLst;
31892 + bool useShadowStructs = FALSE;
31893 + uint16_t tmpKeyIndex;
31894 + t_Error err = E_OK;
31895 +
31896 + if (keyIndex > p_CcNode->numOfKeys)
31897 + RETURN_ERROR(MAJOR, E_NOT_IN_RANGE,
31898 + ("keyIndex > previously cleared last index + 1"));
31899 +
31900 + if (keySize != p_CcNode->userSizeOfExtraction)
31901 + RETURN_ERROR(
31902 + MAJOR,
31903 + E_INVALID_VALUE,
31904 + ("keySize has to be defined as it was defined in initialization step"));
31905 +
31906 + if (p_CcNode->h_FmPcd != h_FmPcd)
31907 + RETURN_ERROR(
31908 + MAJOR,
31909 + E_INVALID_VALUE,
31910 + ("handler to FmPcd is different from the handle provided at node initialization time"));
31911 +
31912 + if (p_CcNode->maxNumOfKeys)
31913 + {
31914 + if (p_CcNode->numOfKeys == p_CcNode->maxNumOfKeys)
31915 + RETURN_ERROR(
31916 + MAJOR,
31917 + E_FULL,
31918 + ("number of keys exceeds the maximal number of keys provided at node initialization time"));
31919 + }
31920 + else
31921 + if (p_CcNode->numOfKeys == FM_PCD_MAX_NUM_OF_KEYS)
31922 + RETURN_ERROR(
31923 + MAJOR,
31924 + E_INVALID_VALUE,
31925 + ("number of keys can not be larger than %d", FM_PCD_MAX_NUM_OF_KEYS));
31926 +
31927 + err = FindKeyIndex(h_FmPcdCcNode, keySize, p_FmPcdCcKeyParams->p_Key,
31928 + p_FmPcdCcKeyParams->p_Mask, &tmpKeyIndex);
31929 + if (GET_ERROR_TYPE(err) != E_NOT_FOUND)
31930 + RETURN_ERROR(
31931 + MAJOR,
31932 + E_ALREADY_EXISTS,
31933 + ("The received key and mask pair was already found in the match table of the provided node"));
31934 +
31935 + p_FmPcd = (t_FmPcd *)p_CcNode->h_FmPcd;
31936 +
31937 + INIT_LIST(&h_OldPointersLst);
31938 + INIT_LIST(&h_NewPointersLst);
31939 +
31940 + p_ModifyKeyParams = ModifyNodeCommonPart(p_CcNode, keyIndex,
31941 + e_MODIFY_STATE_ADD, TRUE, TRUE,
31942 + FALSE);
31943 + if (!p_ModifyKeyParams)
31944 + RETURN_ERROR(MAJOR, E_INVALID_STATE, NO_MSG);
31945 +
31946 + if (p_CcNode->maxNumOfKeys)
31947 + {
31948 + if (!TRY_LOCK(p_FmPcd->h_ShadowSpinlock, &p_FmPcd->shadowLock))
31949 + {
31950 + XX_Free(p_ModifyKeyParams);
31951 + return ERROR_CODE(E_BUSY);
31952 + }
31953 +
31954 + useShadowStructs = TRUE;
31955 + }
31956 +
31957 + err = BuildNewNodeAddOrMdfyKeyAndNextEngine(h_FmPcd, p_CcNode, keyIndex,
31958 + p_FmPcdCcKeyParams,
31959 + p_ModifyKeyParams, TRUE);
31960 + if (err)
31961 + {
31962 + ReleaseNewNodeCommonPart(p_ModifyKeyParams);
31963 + XX_Free(p_ModifyKeyParams);
31964 + if (p_CcNode->maxNumOfKeys)
31965 + RELEASE_LOCK(p_FmPcd->shadowLock);
31966 + RETURN_ERROR(MAJOR, err, NO_MSG);
31967 + }
31968 +
31969 + err = UpdatePtrWhichPointOnCrntMdfNode(p_CcNode, p_ModifyKeyParams,
31970 + &h_OldPointersLst,
31971 + &h_NewPointersLst);
31972 + if (err)
31973 + {
31974 + ReleaseNewNodeCommonPart(p_ModifyKeyParams);
31975 + XX_Free(p_ModifyKeyParams);
31976 + if (p_CcNode->maxNumOfKeys)
31977 + RELEASE_LOCK(p_FmPcd->shadowLock);
31978 + RETURN_ERROR(MAJOR, err, NO_MSG);
31979 + }
31980 +
31981 + err = DoDynamicChange(p_FmPcd, &h_OldPointersLst, &h_NewPointersLst,
31982 + p_ModifyKeyParams, useShadowStructs);
31983 + if (p_CcNode->maxNumOfKeys)
31984 + RELEASE_LOCK(p_FmPcd->shadowLock);
31985 +
31986 + ReleaseLst(&h_OldPointersLst);
31987 + ReleaseLst(&h_NewPointersLst);
31988 +
31989 + return err;
31990 +}
31991 +
31992 +t_Error FmPcdCcModifyKeyAndNextEngine(t_Handle h_FmPcd, t_Handle h_FmPcdCcNode,
31993 + uint16_t keyIndex, uint8_t keySize,
31994 + t_FmPcdCcKeyParams *p_FmPcdCcKeyParams)
31995 +{
31996 + t_FmPcdCcNode *p_CcNode = (t_FmPcdCcNode *)h_FmPcdCcNode;
31997 + t_FmPcd *p_FmPcd;
31998 + t_List h_OldPointersLst, h_NewPointersLst;
31999 + t_FmPcdModifyCcKeyAdditionalParams *p_ModifyKeyParams;
32000 + uint16_t tmpKeyIndex;
32001 + bool useShadowStructs = FALSE;
32002 + t_Error err = E_OK;
32003 +
32004 + if (keyIndex > p_CcNode->numOfKeys)
32005 + RETURN_ERROR(MAJOR, E_INVALID_STATE,
32006 + ("keyIndex > previously cleared last index + 1"));
32007 +
32008 + if (keySize != p_CcNode->userSizeOfExtraction)
32009 + RETURN_ERROR(
32010 + MAJOR,
32011 + E_INVALID_VALUE,
32012 + ("keySize has to be defined as it was defined in initialization step"));
32013 +
32014 + if (p_CcNode->h_FmPcd != h_FmPcd)
32015 + RETURN_ERROR(
32016 + MAJOR,
32017 + E_INVALID_VALUE,
32018 + ("handler to FmPcd is different from the handle provided at node initialization time"));
32019 +
32020 + err = FindKeyIndex(h_FmPcdCcNode, keySize, p_FmPcdCcKeyParams->p_Key,
32021 + p_FmPcdCcKeyParams->p_Mask, &tmpKeyIndex);
32022 + if (GET_ERROR_TYPE(err) != E_NOT_FOUND)
32023 + RETURN_ERROR(
32024 + MINOR,
32025 + E_ALREADY_EXISTS,
32026 + ("The received key and mask pair was already found in the match table of the provided node"));
32027 +
32028 + p_FmPcd = (t_FmPcd *)p_CcNode->h_FmPcd;
32029 +
32030 + INIT_LIST(&h_OldPointersLst);
32031 + INIT_LIST(&h_NewPointersLst);
32032 +
32033 + p_ModifyKeyParams = ModifyNodeCommonPart(p_CcNode, keyIndex,
32034 + e_MODIFY_STATE_CHANGE, TRUE, TRUE,
32035 + FALSE);
32036 + if (!p_ModifyKeyParams)
32037 + RETURN_ERROR(MAJOR, E_INVALID_STATE, NO_MSG);
32038 +
32039 + if (p_CcNode->maxNumOfKeys)
32040 + {
32041 + if (!TRY_LOCK(p_FmPcd->h_ShadowSpinlock, &p_FmPcd->shadowLock))
32042 + {
32043 + XX_Free(p_ModifyKeyParams);
32044 + return ERROR_CODE(E_BUSY);
32045 + }
32046 +
32047 + useShadowStructs = TRUE;
32048 + }
32049 +
32050 + err = BuildNewNodeAddOrMdfyKeyAndNextEngine(h_FmPcd, p_CcNode, keyIndex,
32051 + p_FmPcdCcKeyParams,
32052 + p_ModifyKeyParams, FALSE);
32053 + if (err)
32054 + {
32055 + ReleaseNewNodeCommonPart(p_ModifyKeyParams);
32056 + XX_Free(p_ModifyKeyParams);
32057 + if (p_CcNode->maxNumOfKeys)
32058 + RELEASE_LOCK(p_FmPcd->shadowLock);
32059 + RETURN_ERROR(MAJOR, err, NO_MSG);
32060 + }
32061 +
32062 + err = UpdatePtrWhichPointOnCrntMdfNode(p_CcNode, p_ModifyKeyParams,
32063 + &h_OldPointersLst,
32064 + &h_NewPointersLst);
32065 + if (err)
32066 + {
32067 + ReleaseNewNodeCommonPart(p_ModifyKeyParams);
32068 + XX_Free(p_ModifyKeyParams);
32069 + if (p_CcNode->maxNumOfKeys)
32070 + RELEASE_LOCK(p_FmPcd->shadowLock);
32071 + RETURN_ERROR(MAJOR, err, NO_MSG);
32072 + }
32073 +
32074 + err = DoDynamicChange(p_FmPcd, &h_OldPointersLst, &h_NewPointersLst,
32075 + p_ModifyKeyParams, useShadowStructs);
32076 +
32077 + if (p_CcNode->maxNumOfKeys)
32078 + RELEASE_LOCK(p_FmPcd->shadowLock);
32079 +
32080 + ReleaseLst(&h_OldPointersLst);
32081 + ReleaseLst(&h_NewPointersLst);
32082 +
32083 + return err;
32084 +}
32085 +
32086 +uint32_t FmPcdCcGetNodeAddrOffsetFromNodeInfo(t_Handle h_FmPcd,
32087 + t_Handle h_Pointer)
32088 +{
32089 + t_FmPcd *p_FmPcd = (t_FmPcd *)h_FmPcd;
32090 + t_CcNodeInformation *p_CcNodeInfo;
32091 +
32092 + SANITY_CHECK_RETURN_VALUE(h_FmPcd, E_INVALID_HANDLE,
32093 + (uint32_t)ILLEGAL_BASE);
32094 +
32095 + p_CcNodeInfo = CC_NODE_F_OBJECT(h_Pointer);
32096 +
32097 + return (uint32_t)(XX_VirtToPhys(p_CcNodeInfo->h_CcNode)
32098 + - p_FmPcd->physicalMuramBase);
32099 +}
32100 +
32101 +t_Error FmPcdCcGetGrpParams(t_Handle h_FmPcdCcTree, uint8_t grpId,
32102 + uint32_t *p_GrpBits, uint8_t *p_GrpBase)
32103 +{
32104 + t_FmPcdCcTree *p_FmPcdCcTree = (t_FmPcdCcTree *)h_FmPcdCcTree;
32105 +
32106 + SANITY_CHECK_RETURN_ERROR(h_FmPcdCcTree, E_INVALID_HANDLE);
32107 +
32108 + if (grpId >= p_FmPcdCcTree->numOfGrps)
32109 + RETURN_ERROR(MAJOR, E_INVALID_HANDLE,
32110 + ("grpId you asked > numOfGroup of relevant tree"));
32111 +
32112 + *p_GrpBits = p_FmPcdCcTree->fmPcdGroupParam[grpId].totalBitsMask;
32113 + *p_GrpBase = p_FmPcdCcTree->fmPcdGroupParam[grpId].baseGroupEntry;
32114 +
32115 + return E_OK;
32116 +}
32117 +
32118 +t_Error FmPcdCcBindTree(t_Handle h_FmPcd, t_Handle h_PcdParams,
32119 + t_Handle h_FmPcdCcTree, uint32_t *p_Offset,
32120 + t_Handle h_FmPort)
32121 +{
32122 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
32123 + t_FmPcdCcTree *p_FmPcdCcTree = (t_FmPcdCcTree *)h_FmPcdCcTree;
32124 + t_Error err = E_OK;
32125 +
32126 + SANITY_CHECK_RETURN_ERROR(h_FmPcd, E_INVALID_HANDLE);
32127 + SANITY_CHECK_RETURN_ERROR(h_FmPcdCcTree, E_INVALID_HANDLE);
32128 +
32129 + /* this routine must be protected by the calling routine by locking all PCD modules! */
32130 +
32131 + err = CcUpdateParams(h_FmPcd, h_PcdParams, h_FmPort, h_FmPcdCcTree, TRUE);
32132 +
32133 + if (err == E_OK)
32134 + UpdateCcRootOwner(p_FmPcdCcTree, TRUE);
32135 +
32136 + *p_Offset = (uint32_t)(XX_VirtToPhys(
32137 + UINT_TO_PTR(p_FmPcdCcTree->ccTreeBaseAddr))
32138 + - p_FmPcd->physicalMuramBase);
32139 +
32140 + return err;
32141 +}
32142 +
32143 +t_Error FmPcdCcUnbindTree(t_Handle h_FmPcd, t_Handle h_FmPcdCcTree)
32144 +{
32145 + t_FmPcdCcTree *p_FmPcdCcTree = (t_FmPcdCcTree *)h_FmPcdCcTree;
32146 +
32147 + /* this routine must be protected by the calling routine by locking all PCD modules! */
32148 +
32149 + UNUSED(h_FmPcd);
32150 +
32151 + SANITY_CHECK_RETURN_ERROR(h_FmPcdCcTree, E_INVALID_HANDLE);
32152 +
32153 + UpdateCcRootOwner(p_FmPcdCcTree, FALSE);
32154 +
32155 + return E_OK;
32156 +}
32157 +
32158 +t_Error FmPcdCcNodeTreeTryLock(t_Handle h_FmPcd, t_Handle h_FmPcdCcNode,
32159 + t_List *p_List)
32160 +{
32161 + t_FmPcdCcNode *p_CcNode = (t_FmPcdCcNode *)h_FmPcdCcNode;
32162 + t_List *p_Pos, *p_Tmp;
32163 + t_CcNodeInformation *p_CcNodeInfo, nodeInfo;
32164 + uint32_t intFlags;
32165 + t_Error err = E_OK;
32166 +
32167 + intFlags = FmPcdLock(h_FmPcd);
32168 +
32169 + LIST_FOR_EACH(p_Pos, &p_CcNode->ccTreesLst)
32170 + {
32171 + p_CcNodeInfo = CC_NODE_F_OBJECT(p_Pos);
32172 + ASSERT_COND(p_CcNodeInfo->h_CcNode);
32173 +
32174 + err = CcRootTryLock(p_CcNodeInfo->h_CcNode);
32175 +
32176 + if (err)
32177 + {
32178 + LIST_FOR_EACH(p_Tmp, &p_CcNode->ccTreesLst)
32179 + {
32180 + if (p_Tmp == p_Pos)
32181 + break;
32182 +
32183 + CcRootReleaseLock(p_CcNodeInfo->h_CcNode);
32184 + }
32185 + break;
32186 + }
32187 +
32188 + memset(&nodeInfo, 0, sizeof(t_CcNodeInformation));
32189 + nodeInfo.h_CcNode = p_CcNodeInfo->h_CcNode;
32190 + EnqueueNodeInfoToRelevantLst(p_List, &nodeInfo, NULL);
32191 + }
32192 +
32193 + FmPcdUnlock(h_FmPcd, intFlags);
32194 + CORE_MemoryBarrier();
32195 +
32196 + return err;
32197 +}
32198 +
32199 +void FmPcdCcNodeTreeReleaseLock(t_Handle h_FmPcd, t_List *p_List)
32200 +{
32201 + t_List *p_Pos;
32202 + t_CcNodeInformation *p_CcNodeInfo;
32203 + t_Handle h_FmPcdCcTree;
32204 + uint32_t intFlags;
32205 +
32206 + intFlags = FmPcdLock(h_FmPcd);
32207 +
32208 + LIST_FOR_EACH(p_Pos, p_List)
32209 + {
32210 + p_CcNodeInfo = CC_NODE_F_OBJECT(p_Pos);
32211 + h_FmPcdCcTree = p_CcNodeInfo->h_CcNode;
32212 + CcRootReleaseLock(h_FmPcdCcTree);
32213 + }
32214 +
32215 + ReleaseLst(p_List);
32216 +
32217 + FmPcdUnlock(h_FmPcd, intFlags);
32218 + CORE_MemoryBarrier();
32219 +}
32220 +
32221 +t_Error FmPcdUpdateCcShadow(t_FmPcd *p_FmPcd, uint32_t size, uint32_t align)
32222 +{
32223 + uint32_t intFlags;
32224 + uint32_t newSize = 0, newAlign = 0;
32225 + bool allocFail = FALSE;
32226 +
32227 + ASSERT_COND(p_FmPcd);
32228 +
32229 + if (!size)
32230 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("size must be larger then 0"));
32231 +
32232 + if (!POWER_OF_2(align))
32233 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("alignment must be power of 2"));
32234 +
32235 + newSize = p_FmPcd->ccShadowSize;
32236 + newAlign = p_FmPcd->ccShadowAlign;
32237 +
32238 + /* Check if current shadow is large enough to hold the requested size */
32239 + if (size > p_FmPcd->ccShadowSize)
32240 + newSize = size;
32241 +
32242 + /* Check if current shadow matches the requested alignment */
32243 + if (align > p_FmPcd->ccShadowAlign)
32244 + newAlign = align;
32245 +
32246 + /* If a bigger shadow size or bigger shadow alignment are required,
32247 + a new shadow will be allocated */
32248 + if ((newSize != p_FmPcd->ccShadowSize)
32249 + || (newAlign != p_FmPcd->ccShadowAlign))
32250 + {
32251 + intFlags = FmPcdLock(p_FmPcd);
32252 +
32253 + if (p_FmPcd->p_CcShadow)
32254 + {
32255 + FM_MURAM_FreeMem(FmPcdGetMuramHandle(p_FmPcd), p_FmPcd->p_CcShadow);
32256 + p_FmPcd->ccShadowSize = 0;
32257 + p_FmPcd->ccShadowAlign = 0;
32258 + }
32259 +
32260 + p_FmPcd->p_CcShadow = FM_MURAM_AllocMem(FmPcdGetMuramHandle(p_FmPcd),
32261 + newSize, newAlign);
32262 + if (!p_FmPcd->p_CcShadow)
32263 + {
32264 + allocFail = TRUE;
32265 +
32266 + /* If new shadow size allocation failed,
32267 + re-allocate with previous parameters */
32268 + p_FmPcd->p_CcShadow = FM_MURAM_AllocMem(
32269 + FmPcdGetMuramHandle(p_FmPcd), p_FmPcd->ccShadowSize,
32270 + p_FmPcd->ccShadowAlign);
32271 + }
32272 +
32273 + FmPcdUnlock(p_FmPcd, intFlags);
32274 +
32275 + if (allocFail)
32276 + RETURN_ERROR(MAJOR, E_NO_MEMORY,
32277 + ("MURAM allocation for CC Shadow memory"));
32278 +
32279 + p_FmPcd->ccShadowSize = newSize;
32280 + p_FmPcd->ccShadowAlign = newAlign;
32281 + }
32282 +
32283 + return E_OK;
32284 +}
32285 +
32286 +#if (DPAA_VERSION >= 11)
32287 +void FmPcdCcGetAdTablesThatPointOnReplicGroup(t_Handle h_Node,
32288 + t_Handle h_ReplicGroup,
32289 + t_List *p_AdTables,
32290 + uint32_t *p_NumOfAdTables)
32291 +{
32292 + t_FmPcdCcNode *p_CurrentNode = (t_FmPcdCcNode *)h_Node;
32293 + int i = 0;
32294 + void * p_AdTable;
32295 + t_CcNodeInformation ccNodeInfo;
32296 +
32297 + ASSERT_COND(h_Node);
32298 + *p_NumOfAdTables = 0;
32299 +
32300 + /* search in the current node which exact index points on this current replicator group for getting AD */
32301 + for (i = 0; i < p_CurrentNode->numOfKeys + 1; i++)
32302 + {
32303 + if ((p_CurrentNode->keyAndNextEngineParams[i].nextEngineParams.nextEngine
32304 + == e_FM_PCD_FR)
32305 + && ((p_CurrentNode->keyAndNextEngineParams[i].nextEngineParams.params.frParams.h_FrmReplic
32306 + == (t_Handle)h_ReplicGroup)))
32307 + {
32308 + /* save the current ad table in the list */
32309 + /* this entry uses the input replicator group */
32310 + p_AdTable =
32311 + PTR_MOVE(p_CurrentNode->h_AdTable, i*FM_PCD_CC_AD_ENTRY_SIZE);
32312 + memset(&ccNodeInfo, 0, sizeof(t_CcNodeInformation));
32313 + ccNodeInfo.h_CcNode = p_AdTable;
32314 + EnqueueNodeInfoToRelevantLst(p_AdTables, &ccNodeInfo, NULL);
32315 + (*p_NumOfAdTables)++;
32316 + }
32317 + }
32318 +
32319 + ASSERT_COND(i != p_CurrentNode->numOfKeys);
32320 +}
32321 +#endif /* (DPAA_VERSION >= 11) */
32322 +/*********************** End of inter-module routines ************************/
32323 +
32324 +/****************************************/
32325 +/* API Init unit functions */
32326 +/****************************************/
32327 +
32328 +t_Handle FM_PCD_CcRootBuild(t_Handle h_FmPcd,
32329 + t_FmPcdCcTreeParams *p_PcdGroupsParam)
32330 +{
32331 + t_FmPcd *p_FmPcd = (t_FmPcd *)h_FmPcd;
32332 + t_Error err = E_OK;
32333 + int i = 0, j = 0, k = 0;
32334 + t_FmPcdCcTree *p_FmPcdCcTree;
32335 + uint8_t numOfEntries;
32336 + t_Handle p_CcTreeTmp;
32337 + t_FmPcdCcGrpParams *p_FmPcdCcGroupParams;
32338 + t_FmPcdCcKeyAndNextEngineParams *p_Params, *p_KeyAndNextEngineParams;
32339 + t_NetEnvParams netEnvParams;
32340 + uint8_t lastOne = 0;
32341 + uint32_t requiredAction = 0;
32342 + t_FmPcdCcNode *p_FmPcdCcNextNode;
32343 + t_CcNodeInformation ccNodeInfo, *p_CcInformation;
32344 +
32345 + SANITY_CHECK_RETURN_VALUE(h_FmPcd, E_INVALID_HANDLE, NULL);
32346 + SANITY_CHECK_RETURN_VALUE(p_PcdGroupsParam, E_INVALID_HANDLE, NULL);
32347 +
32348 + if (p_PcdGroupsParam->numOfGrps > FM_PCD_MAX_NUM_OF_CC_GROUPS)
32349 + {
32350 + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("numOfGrps should not exceed %d", FM_PCD_MAX_NUM_OF_CC_GROUPS));
32351 + return NULL;
32352 + }
32353 +
32354 + p_FmPcdCcTree = (t_FmPcdCcTree*)XX_Malloc(sizeof(t_FmPcdCcTree));
32355 + if (!p_FmPcdCcTree)
32356 + {
32357 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("PCD tree structure"));
32358 + return NULL;
32359 + }
32360 + memset(p_FmPcdCcTree, 0, sizeof(t_FmPcdCcTree));
32361 + p_FmPcdCcTree->h_FmPcd = h_FmPcd;
32362 +
32363 + p_Params = (t_FmPcdCcKeyAndNextEngineParams*)XX_Malloc(
32364 + FM_PCD_MAX_NUM_OF_CC_GROUPS
32365 + * sizeof(t_FmPcdCcKeyAndNextEngineParams));
32366 + memset(p_Params,
32367 + 0,
32368 + FM_PCD_MAX_NUM_OF_CC_GROUPS
32369 + * sizeof(t_FmPcdCcKeyAndNextEngineParams));
32370 +
32371 + INIT_LIST(&p_FmPcdCcTree->fmPortsLst);
32372 +
32373 +#ifdef FM_CAPWAP_SUPPORT
32374 + if ((p_PcdGroupsParam->numOfGrps == 1) &&
32375 + (p_PcdGroupsParam->ccGrpParams[0].numOfDistinctionUnits == 0) &&
32376 + (p_PcdGroupsParam->ccGrpParams[0].nextEnginePerEntriesInGrp[0].nextEngine == e_FM_PCD_CC) &&
32377 + p_PcdGroupsParam->ccGrpParams[0].nextEnginePerEntriesInGrp[0].params.ccParams.h_CcNode &&
32378 + IsCapwapApplSpecific(p_PcdGroupsParam->ccGrpParams[0].nextEnginePerEntriesInGrp[0].params.ccParams.h_CcNode))
32379 + {
32380 + p_PcdGroupsParam->ccGrpParams[0].nextEnginePerEntriesInGrp[0].h_Manip = FmPcdManipApplSpecificBuild();
32381 + if (!p_PcdGroupsParam->ccGrpParams[0].nextEnginePerEntriesInGrp[0].h_Manip)
32382 + {
32383 + DeleteTree(p_FmPcdCcTree,p_FmPcd);
32384 + XX_Free(p_Params);
32385 + REPORT_ERROR(MAJOR, E_INVALID_STATE, NO_MSG);
32386 + return NULL;
32387 + }
32388 + }
32389 +#endif /* FM_CAPWAP_SUPPORT */
32390 +
32391 + numOfEntries = 0;
32392 + p_FmPcdCcTree->netEnvId = FmPcdGetNetEnvId(p_PcdGroupsParam->h_NetEnv);
32393 +
32394 + for (i = 0; i < p_PcdGroupsParam->numOfGrps; i++)
32395 + {
32396 + p_FmPcdCcGroupParams = &p_PcdGroupsParam->ccGrpParams[i];
32397 +
32398 + if (p_FmPcdCcGroupParams->numOfDistinctionUnits
32399 + > FM_PCD_MAX_NUM_OF_CC_UNITS)
32400 + {
32401 + DeleteTree(p_FmPcdCcTree, p_FmPcd);
32402 + XX_Free(p_Params);
32403 + REPORT_ERROR(MAJOR, E_INVALID_VALUE,
32404 + ("numOfDistinctionUnits (group %d) should not exceed %d", i, FM_PCD_MAX_NUM_OF_CC_UNITS));
32405 + return NULL;
32406 + }
32407 +
32408 + p_FmPcdCcTree->fmPcdGroupParam[i].baseGroupEntry = numOfEntries;
32409 + p_FmPcdCcTree->fmPcdGroupParam[i].numOfEntriesInGroup = (uint8_t)(0x01
32410 + << p_FmPcdCcGroupParams->numOfDistinctionUnits);
32411 + numOfEntries += p_FmPcdCcTree->fmPcdGroupParam[i].numOfEntriesInGroup;
32412 + if (numOfEntries > FM_PCD_MAX_NUM_OF_CC_GROUPS)
32413 + {
32414 + DeleteTree(p_FmPcdCcTree, p_FmPcd);
32415 + XX_Free(p_Params);
32416 + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("numOfEntries can not be larger than %d", FM_PCD_MAX_NUM_OF_CC_GROUPS));
32417 + return NULL;
32418 + }
32419 +
32420 + if (lastOne)
32421 + {
32422 + if (p_FmPcdCcTree->fmPcdGroupParam[i].numOfEntriesInGroup > lastOne)
32423 + {
32424 + DeleteTree(p_FmPcdCcTree, p_FmPcd);
32425 + XX_Free(p_Params);
32426 + REPORT_ERROR(MAJOR, E_CONFLICT, ("numOfEntries per group must be set in descending order"));
32427 + return NULL;
32428 + }
32429 + }
32430 +
32431 + lastOne = p_FmPcdCcTree->fmPcdGroupParam[i].numOfEntriesInGroup;
32432 +
32433 + netEnvParams.netEnvId = p_FmPcdCcTree->netEnvId;
32434 + netEnvParams.numOfDistinctionUnits =
32435 + p_FmPcdCcGroupParams->numOfDistinctionUnits;
32436 +
32437 + memcpy(netEnvParams.unitIds, &p_FmPcdCcGroupParams->unitIds,
32438 + (sizeof(uint8_t)) * p_FmPcdCcGroupParams->numOfDistinctionUnits);
32439 +
32440 + err = PcdGetUnitsVector(p_FmPcd, &netEnvParams);
32441 + if (err)
32442 + {
32443 + DeleteTree(p_FmPcdCcTree, p_FmPcd);
32444 + XX_Free(p_Params);
32445 + REPORT_ERROR(MAJOR, err, NO_MSG);
32446 + return NULL;
32447 + }
32448 +
32449 + p_FmPcdCcTree->fmPcdGroupParam[i].totalBitsMask = netEnvParams.vector;
32450 + for (j = 0; j < p_FmPcdCcTree->fmPcdGroupParam[i].numOfEntriesInGroup;
32451 + j++)
32452 + {
32453 + err = ValidateNextEngineParams(
32454 + h_FmPcd,
32455 + &p_FmPcdCcGroupParams->nextEnginePerEntriesInGrp[j],
32456 + e_FM_PCD_CC_STATS_MODE_NONE);
32457 + if (err)
32458 + {
32459 + DeleteTree(p_FmPcdCcTree, p_FmPcd);
32460 + XX_Free(p_Params);
32461 + REPORT_ERROR(MAJOR, err, (NO_MSG));
32462 + return NULL;
32463 + }
32464 +
32465 + if (p_FmPcdCcGroupParams->nextEnginePerEntriesInGrp[j].h_Manip)
32466 + {
32467 + err = FmPcdManipCheckParamsForCcNextEngine(
32468 + &p_FmPcdCcGroupParams->nextEnginePerEntriesInGrp[j],
32469 + &requiredAction);
32470 + if (err)
32471 + {
32472 + DeleteTree(p_FmPcdCcTree, p_FmPcd);
32473 + XX_Free(p_Params);
32474 + REPORT_ERROR(MAJOR, E_INVALID_STATE, NO_MSG);
32475 + return NULL;
32476 + }
32477 + }
32478 + p_KeyAndNextEngineParams = p_Params + k;
32479 +
32480 + memcpy(&p_KeyAndNextEngineParams->nextEngineParams,
32481 + &p_FmPcdCcGroupParams->nextEnginePerEntriesInGrp[j],
32482 + sizeof(t_FmPcdCcNextEngineParams));
32483 +
32484 + if ((p_KeyAndNextEngineParams->nextEngineParams.nextEngine
32485 + == e_FM_PCD_CC)
32486 + && p_KeyAndNextEngineParams->nextEngineParams.h_Manip)
32487 + {
32488 + err =
32489 + AllocAndFillAdForContLookupManip(
32490 + p_KeyAndNextEngineParams->nextEngineParams.params.ccParams.h_CcNode);
32491 + if (err)
32492 + {
32493 + DeleteTree(p_FmPcdCcTree, p_FmPcd);
32494 + XX_Free(p_Params);
32495 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("MURAM allocation for CC Tree"));
32496 + return NULL;
32497 + }
32498 + }
32499 +
32500 + requiredAction |= UPDATE_CC_WITH_TREE;
32501 + p_KeyAndNextEngineParams->requiredAction = requiredAction;
32502 +
32503 + k++;
32504 + }
32505 + }
32506 +
32507 + p_FmPcdCcTree->numOfEntries = (uint8_t)k;
32508 + p_FmPcdCcTree->numOfGrps = p_PcdGroupsParam->numOfGrps;
32509 +
32510 + p_FmPcdCcTree->ccTreeBaseAddr =
32511 + PTR_TO_UINT(FM_MURAM_AllocMem(FmPcdGetMuramHandle(h_FmPcd),
32512 + (uint32_t)( FM_PCD_MAX_NUM_OF_CC_GROUPS * FM_PCD_CC_AD_ENTRY_SIZE),
32513 + FM_PCD_CC_TREE_ADDR_ALIGN));
32514 + if (!p_FmPcdCcTree->ccTreeBaseAddr)
32515 + {
32516 + DeleteTree(p_FmPcdCcTree, p_FmPcd);
32517 + XX_Free(p_Params);
32518 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("MURAM allocation for CC Tree"));
32519 + return NULL;
32520 + }
32521 + MemSet8(
32522 + UINT_TO_PTR(p_FmPcdCcTree->ccTreeBaseAddr), 0,
32523 + (uint32_t)(FM_PCD_MAX_NUM_OF_CC_GROUPS * FM_PCD_CC_AD_ENTRY_SIZE));
32524 +
32525 + p_CcTreeTmp = UINT_TO_PTR(p_FmPcdCcTree->ccTreeBaseAddr);
32526 +
32527 + for (i = 0; i < numOfEntries; i++)
32528 + {
32529 + p_KeyAndNextEngineParams = p_Params + i;
32530 +
32531 + NextStepAd(p_CcTreeTmp, NULL,
32532 + &p_KeyAndNextEngineParams->nextEngineParams, p_FmPcd);
32533 +
32534 + p_CcTreeTmp = PTR_MOVE(p_CcTreeTmp, FM_PCD_CC_AD_ENTRY_SIZE);
32535 +
32536 + memcpy(&p_FmPcdCcTree->keyAndNextEngineParams[i],
32537 + p_KeyAndNextEngineParams,
32538 + sizeof(t_FmPcdCcKeyAndNextEngineParams));
32539 +
32540 + if (p_FmPcdCcTree->keyAndNextEngineParams[i].nextEngineParams.nextEngine
32541 + == e_FM_PCD_CC)
32542 + {
32543 + p_FmPcdCcNextNode =
32544 + (t_FmPcdCcNode*)p_FmPcdCcTree->keyAndNextEngineParams[i].nextEngineParams.params.ccParams.h_CcNode;
32545 + p_CcInformation = FindNodeInfoInReleventLst(
32546 + &p_FmPcdCcNextNode->ccTreeIdLst, (t_Handle)p_FmPcdCcTree,
32547 + p_FmPcdCcNextNode->h_Spinlock);
32548 +
32549 + if (!p_CcInformation)
32550 + {
32551 + memset(&ccNodeInfo, 0, sizeof(t_CcNodeInformation));
32552 + ccNodeInfo.h_CcNode = (t_Handle)p_FmPcdCcTree;
32553 + ccNodeInfo.index = 1;
32554 + EnqueueNodeInfoToRelevantLst(&p_FmPcdCcNextNode->ccTreeIdLst,
32555 + &ccNodeInfo,
32556 + p_FmPcdCcNextNode->h_Spinlock);
32557 + }
32558 + else
32559 + p_CcInformation->index++;
32560 + }
32561 + }
32562 +
32563 + FmPcdIncNetEnvOwners(h_FmPcd, p_FmPcdCcTree->netEnvId);
32564 + p_CcTreeTmp = UINT_TO_PTR(p_FmPcdCcTree->ccTreeBaseAddr);
32565 +
32566 + if (!FmPcdLockTryLockAll(p_FmPcd))
32567 + {
32568 + FM_PCD_CcRootDelete(p_FmPcdCcTree);
32569 + XX_Free(p_Params);
32570 + DBG(TRACE, ("FmPcdLockTryLockAll failed"));
32571 + return NULL;
32572 + }
32573 +
32574 + for (i = 0; i < numOfEntries; i++)
32575 + {
32576 + if (p_FmPcdCcTree->keyAndNextEngineParams[i].requiredAction)
32577 + {
32578 + err = SetRequiredAction(
32579 + h_FmPcd,
32580 + p_FmPcdCcTree->keyAndNextEngineParams[i].requiredAction,
32581 + &p_FmPcdCcTree->keyAndNextEngineParams[i], p_CcTreeTmp, 1,
32582 + p_FmPcdCcTree);
32583 + if (err)
32584 + {
32585 + FmPcdLockUnlockAll(p_FmPcd);
32586 + FM_PCD_CcRootDelete(p_FmPcdCcTree);
32587 + XX_Free(p_Params);
32588 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("No memory"));
32589 + return NULL;
32590 + }
32591 + p_CcTreeTmp = PTR_MOVE(p_CcTreeTmp, FM_PCD_CC_AD_ENTRY_SIZE);
32592 + }
32593 + }
32594 +
32595 + FmPcdLockUnlockAll(p_FmPcd);
32596 + p_FmPcdCcTree->p_Lock = FmPcdAcquireLock(p_FmPcd);
32597 + if (!p_FmPcdCcTree->p_Lock)
32598 + {
32599 + FM_PCD_CcRootDelete(p_FmPcdCcTree);
32600 + XX_Free(p_Params);
32601 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FM CC lock"));
32602 + return NULL;
32603 + }
32604 +
32605 + XX_Free(p_Params);
32606 +
32607 + return p_FmPcdCcTree;
32608 +}
32609 +
32610 +t_Error FM_PCD_CcRootDelete(t_Handle h_CcTree)
32611 +{
32612 + t_FmPcd *p_FmPcd;
32613 + t_FmPcdCcTree *p_CcTree = (t_FmPcdCcTree *)h_CcTree;
32614 + int i = 0;
32615 +
32616 + SANITY_CHECK_RETURN_ERROR(p_CcTree, E_INVALID_STATE);
32617 + p_FmPcd = (t_FmPcd *)p_CcTree->h_FmPcd;
32618 + SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);
32619 +
32620 + FmPcdDecNetEnvOwners(p_FmPcd, p_CcTree->netEnvId);
32621 +
32622 + if (p_CcTree->owners)
32623 + RETURN_ERROR(
32624 + MAJOR,
32625 + E_INVALID_SELECTION,
32626 + ("the tree with this ID can not be removed because this tree is occupied, first - unbind this tree"));
32627 +
32628 + /* Delete ip-reassembly schemes if exist */
32629 + if (p_CcTree->h_IpReassemblyManip)
32630 + {
32631 + FmPcdManipDeleteIpReassmSchemes(p_CcTree->h_IpReassemblyManip);
32632 + FmPcdManipUpdateOwner(p_CcTree->h_IpReassemblyManip, FALSE);
32633 + }
32634 +
32635 + /* Delete capwap-reassembly schemes if exist */
32636 + if (p_CcTree->h_CapwapReassemblyManip)
32637 + {
32638 + FmPcdManipDeleteCapwapReassmSchemes(p_CcTree->h_CapwapReassemblyManip);
32639 + FmPcdManipUpdateOwner(p_CcTree->h_CapwapReassemblyManip, FALSE);
32640 + }
32641 +
32642 + for (i = 0; i < p_CcTree->numOfEntries; i++)
32643 + {
32644 + if (p_CcTree->keyAndNextEngineParams[i].nextEngineParams.nextEngine
32645 + == e_FM_PCD_CC)
32646 + UpdateNodeOwner(
32647 + p_CcTree->keyAndNextEngineParams[i].nextEngineParams.params.ccParams.h_CcNode,
32648 + FALSE);
32649 +
32650 + if (p_CcTree->keyAndNextEngineParams[i].nextEngineParams.h_Manip)
32651 + FmPcdManipUpdateOwner(
32652 + p_CcTree->keyAndNextEngineParams[i].nextEngineParams.h_Manip,
32653 + FALSE);
32654 +
32655 +#ifdef FM_CAPWAP_SUPPORT
32656 + if ((p_CcTree->numOfGrps == 1) &&
32657 + (p_CcTree->fmPcdGroupParam[0].numOfEntriesInGroup == 1) &&
32658 + (p_CcTree->keyAndNextEngineParams[0].nextEngineParams.nextEngine == e_FM_PCD_CC) &&
32659 + p_CcTree->keyAndNextEngineParams[0].nextEngineParams.params.ccParams.h_CcNode &&
32660 + IsCapwapApplSpecific(p_CcTree->keyAndNextEngineParams[0].nextEngineParams.params.ccParams.h_CcNode))
32661 + {
32662 + if (FM_PCD_ManipNodeDelete(p_CcTree->keyAndNextEngineParams[0].nextEngineParams.h_Manip) != E_OK)
32663 + return E_INVALID_STATE;
32664 + }
32665 +#endif /* FM_CAPWAP_SUPPORT */
32666 +
32667 +#if (DPAA_VERSION >= 11)
32668 + if ((p_CcTree->keyAndNextEngineParams[i].nextEngineParams.nextEngine
32669 + == e_FM_PCD_FR)
32670 + && (p_CcTree->keyAndNextEngineParams[i].nextEngineParams.params.frParams.h_FrmReplic))
32671 + FrmReplicGroupUpdateOwner(
32672 + p_CcTree->keyAndNextEngineParams[i].nextEngineParams.params.frParams.h_FrmReplic,
32673 + FALSE);
32674 +#endif /* (DPAA_VERSION >= 11) */
32675 + }
32676 +
32677 + if (p_CcTree->p_Lock)
32678 + FmPcdReleaseLock(p_CcTree->h_FmPcd, p_CcTree->p_Lock);
32679 +
32680 + DeleteTree(p_CcTree, p_FmPcd);
32681 +
32682 + return E_OK;
32683 +}
32684 +
32685 +t_Error FM_PCD_CcRootModifyNextEngine(
32686 + t_Handle h_CcTree, uint8_t grpId, uint8_t index,
32687 + t_FmPcdCcNextEngineParams *p_FmPcdCcNextEngineParams)
32688 +{
32689 + t_FmPcd *p_FmPcd;
32690 + t_FmPcdCcTree *p_CcTree = (t_FmPcdCcTree *)h_CcTree;
32691 + t_Error err = E_OK;
32692 +
32693 + SANITY_CHECK_RETURN_ERROR(p_FmPcdCcNextEngineParams, E_NULL_POINTER);
32694 + SANITY_CHECK_RETURN_ERROR(p_CcTree, E_INVALID_STATE);
32695 + p_FmPcd = (t_FmPcd *)p_CcTree->h_FmPcd;
32696 + SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);
32697 +
32698 + if (!FmPcdLockTryLockAll(p_FmPcd))
32699 + {
32700 + DBG(TRACE, ("FmPcdLockTryLockAll failed"));
32701 + return ERROR_CODE(E_BUSY);
32702 + }
32703 +
32704 + err = FmPcdCcModifyNextEngineParamTree(p_FmPcd, p_CcTree, grpId, index,
32705 + p_FmPcdCcNextEngineParams);
32706 + FmPcdLockUnlockAll(p_FmPcd);
32707 +
32708 + if (err)
32709 + {
32710 + RETURN_ERROR(MAJOR, err, NO_MSG);
32711 + }
32712 +
32713 + return E_OK;
32714 +}
32715 +
32716 +t_Handle FM_PCD_MatchTableSet(t_Handle h_FmPcd,
32717 + t_FmPcdCcNodeParams *p_CcNodeParam)
32718 +{
32719 + t_FmPcdCcNode *p_CcNode;
32720 + t_Error err;
32721 +
32722 + SANITY_CHECK_RETURN_VALUE(h_FmPcd, E_INVALID_HANDLE, NULL);
32723 + SANITY_CHECK_RETURN_VALUE(p_CcNodeParam, E_NULL_POINTER, NULL);
32724 +
32725 + p_CcNode = (t_FmPcdCcNode*)XX_Malloc(sizeof(t_FmPcdCcNode));
32726 + if (!p_CcNode)
32727 + {
32728 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("No memory"));
32729 + return NULL;
32730 + }
32731 + memset(p_CcNode, 0, sizeof(t_FmPcdCcNode));
32732 +
32733 + err = MatchTableSet(h_FmPcd, p_CcNode, p_CcNodeParam);
32734 +
32735 + switch(GET_ERROR_TYPE(err)
32736 +) {
32737 + case E_OK:
32738 + break;
32739 +
32740 + case E_BUSY:
32741 + DBG(TRACE, ("E_BUSY error"));
32742 + return NULL;
32743 +
32744 + default:
32745 + REPORT_ERROR(MAJOR, err, NO_MSG);
32746 + return NULL;
32747 + }
32748 +
32749 + return p_CcNode;
32750 +}
32751 +
32752 +t_Error FM_PCD_MatchTableDelete(t_Handle h_CcNode)
32753 +{
32754 + t_FmPcdCcNode *p_CcNode = (t_FmPcdCcNode *)h_CcNode;
32755 + int i = 0;
32756 +
32757 + SANITY_CHECK_RETURN_ERROR(p_CcNode, E_INVALID_HANDLE);
32758 + SANITY_CHECK_RETURN_ERROR(p_CcNode->h_FmPcd, E_INVALID_HANDLE);
32759 +
32760 + if (p_CcNode->owners)
32761 + RETURN_ERROR(
32762 + MAJOR,
32763 + E_INVALID_STATE,
32764 + ("This node cannot be removed because it is occupied; first unbind this node"));
32765 +
32766 + for (i = 0; i < p_CcNode->numOfKeys; i++)
32767 + if (p_CcNode->keyAndNextEngineParams[i].nextEngineParams.nextEngine
32768 + == e_FM_PCD_CC)
32769 + UpdateNodeOwner(
32770 + p_CcNode->keyAndNextEngineParams[i].nextEngineParams.params.ccParams.h_CcNode,
32771 + FALSE);
32772 +
32773 + if (p_CcNode->keyAndNextEngineParams[i].nextEngineParams.nextEngine
32774 + == e_FM_PCD_CC)
32775 + UpdateNodeOwner(
32776 + p_CcNode->keyAndNextEngineParams[i].nextEngineParams.params.ccParams.h_CcNode,
32777 + FALSE);
32778 +
32779 + /* Handle also Miss entry */
32780 + for (i = 0; i < p_CcNode->numOfKeys + 1; i++)
32781 + {
32782 + if (p_CcNode->keyAndNextEngineParams[i].nextEngineParams.h_Manip)
32783 + FmPcdManipUpdateOwner(
32784 + p_CcNode->keyAndNextEngineParams[i].nextEngineParams.h_Manip,
32785 + FALSE);
32786 +
32787 +#if (DPAA_VERSION >= 11)
32788 + if ((p_CcNode->keyAndNextEngineParams[i].nextEngineParams.nextEngine
32789 + == e_FM_PCD_FR)
32790 + && (p_CcNode->keyAndNextEngineParams[i].nextEngineParams.params.frParams.h_FrmReplic))
32791 + {
32792 + FrmReplicGroupUpdateOwner(
32793 + p_CcNode->keyAndNextEngineParams[i].nextEngineParams.params.frParams.h_FrmReplic,
32794 + FALSE);
32795 + }
32796 +#endif /* (DPAA_VERSION >= 11) */
32797 + }
32798 +
32799 + DeleteNode(p_CcNode);
32800 +
32801 + return E_OK;
32802 +}
32803 +
32804 +t_Error FM_PCD_MatchTableAddKey(t_Handle h_CcNode, uint16_t keyIndex,
32805 + uint8_t keySize,
32806 + t_FmPcdCcKeyParams *p_KeyParams)
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_KeyParams, E_NULL_POINTER);
32813 + SANITY_CHECK_RETURN_ERROR(p_CcNode, E_INVALID_HANDLE);
32814 + p_FmPcd = (t_FmPcd *)p_CcNode->h_FmPcd;
32815 + SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);
32816 + SANITY_CHECK_RETURN_ERROR(p_FmPcd->h_Hc, E_INVALID_HANDLE);
32817 +
32818 + if (keyIndex == FM_PCD_LAST_KEY_INDEX)
32819 + keyIndex = p_CcNode->numOfKeys;
32820 +
32821 + if (!FmPcdLockTryLockAll(p_FmPcd))
32822 + {
32823 + DBG(TRACE, ("FmPcdLockTryLockAll failed"));
32824 + return ERROR_CODE(E_BUSY);
32825 + }
32826 +
32827 + err = FmPcdCcAddKey(p_FmPcd, p_CcNode, keyIndex, keySize, p_KeyParams);
32828 +
32829 + FmPcdLockUnlockAll(p_FmPcd);
32830 +
32831 + switch(GET_ERROR_TYPE(err)
32832 +) {
32833 + case E_OK:
32834 + return E_OK;
32835 +
32836 + case E_BUSY:
32837 + DBG(TRACE, ("E_BUSY error"));
32838 + return ERROR_CODE(E_BUSY);
32839 +
32840 + default:
32841 + RETURN_ERROR(MAJOR, err, NO_MSG);
32842 + }
32843 +}
32844 +
32845 +t_Error FM_PCD_MatchTableRemoveKey(t_Handle h_CcNode, uint16_t keyIndex)
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 + p_FmPcd = (t_FmPcd *)p_CcNode->h_FmPcd;
32853 + SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);
32854 + SANITY_CHECK_RETURN_ERROR(p_FmPcd->h_Hc, E_INVALID_HANDLE);
32855 +
32856 + if (!FmPcdLockTryLockAll(p_FmPcd))
32857 + {
32858 + DBG(TRACE, ("FmPcdLockTryLockAll failed"));
32859 + return ERROR_CODE(E_BUSY);
32860 + }
32861 +
32862 + err = FmPcdCcRemoveKey(p_FmPcd, p_CcNode, keyIndex);
32863 +
32864 + FmPcdLockUnlockAll(p_FmPcd);
32865 +
32866 + switch(GET_ERROR_TYPE(err)
32867 +) {
32868 + case E_OK:
32869 + return E_OK;
32870 +
32871 + case E_BUSY:
32872 + DBG(TRACE, ("E_BUSY error"));
32873 + return ERROR_CODE(E_BUSY);
32874 +
32875 + default:
32876 + RETURN_ERROR(MAJOR, err, NO_MSG);
32877 + }
32878 +
32879 + return E_OK;
32880 +}
32881 +
32882 +t_Error FM_PCD_MatchTableModifyKey(t_Handle h_CcNode, uint16_t keyIndex,
32883 + uint8_t keySize, uint8_t *p_Key,
32884 + uint8_t *p_Mask)
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_CcNode, E_INVALID_HANDLE);
32891 + SANITY_CHECK_RETURN_ERROR(p_Key, E_NULL_POINTER);
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 +
32897 + if (!FmPcdLockTryLockAll(p_FmPcd))
32898 + {
32899 + DBG(TRACE, ("FmPcdLockTryLockAll failed"));
32900 + return ERROR_CODE(E_BUSY);
32901 + }
32902 +
32903 + err = FmPcdCcModifyKey(p_FmPcd, p_CcNode, keyIndex, keySize, p_Key, p_Mask);
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_MatchTableModifyNextEngine(
32922 + t_Handle h_CcNode, uint16_t keyIndex,
32923 + t_FmPcdCcNextEngineParams *p_FmPcdCcNextEngineParams)
32924 +{
32925 + t_FmPcd *p_FmPcd;
32926 + t_FmPcdCcNode *p_CcNode = (t_FmPcdCcNode *)h_CcNode;
32927 + t_Error err = E_OK;
32928 +
32929 + SANITY_CHECK_RETURN_ERROR(p_FmPcdCcNextEngineParams, E_NULL_POINTER);
32930 + SANITY_CHECK_RETURN_ERROR(p_CcNode, E_INVALID_HANDLE);
32931 + p_FmPcd = (t_FmPcd *)p_CcNode->h_FmPcd;
32932 + SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);
32933 + SANITY_CHECK_RETURN_ERROR(p_FmPcd->h_Hc, E_INVALID_HANDLE);
32934 +
32935 + if (!FmPcdLockTryLockAll(p_FmPcd))
32936 + {
32937 + DBG(TRACE, ("FmPcdLockTryLockAll failed"));
32938 + return ERROR_CODE(E_BUSY);
32939 + }
32940 +
32941 + err = ModifyNextEngineParamNode(p_FmPcd, p_CcNode, keyIndex,
32942 + p_FmPcdCcNextEngineParams);
32943 +
32944 + FmPcdLockUnlockAll(p_FmPcd);
32945 +
32946 + switch(GET_ERROR_TYPE(err)
32947 +) {
32948 + case E_OK:
32949 + return E_OK;
32950 +
32951 + case E_BUSY:
32952 + DBG(TRACE, ("E_BUSY error"));
32953 + return ERROR_CODE(E_BUSY);
32954 +
32955 + default:
32956 + RETURN_ERROR(MAJOR, err, NO_MSG);
32957 + }
32958 +}
32959 +
32960 +t_Error FM_PCD_MatchTableModifyMissNextEngine(
32961 + t_Handle h_CcNode, t_FmPcdCcNextEngineParams *p_FmPcdCcNextEngineParams)
32962 +{
32963 + t_FmPcd *p_FmPcd;
32964 + t_FmPcdCcNode *p_CcNode = (t_FmPcdCcNode *)h_CcNode;
32965 + t_Error err = E_OK;
32966 +
32967 + SANITY_CHECK_RETURN_ERROR(p_FmPcdCcNextEngineParams, E_NULL_POINTER);
32968 + SANITY_CHECK_RETURN_ERROR(p_CcNode, E_INVALID_HANDLE);
32969 + p_FmPcd = (t_FmPcd *)p_CcNode->h_FmPcd;
32970 + SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);
32971 + SANITY_CHECK_RETURN_ERROR(p_FmPcd->h_Hc, E_INVALID_HANDLE);
32972 +
32973 + if (!FmPcdLockTryLockAll(p_FmPcd))
32974 + {
32975 + DBG(TRACE, ("FmPcdLockTryLockAll failed"));
32976 + return ERROR_CODE(E_BUSY);
32977 + }
32978 +
32979 + err = FmPcdCcModifyMissNextEngineParamNode(p_FmPcd, p_CcNode,
32980 + p_FmPcdCcNextEngineParams);
32981 +
32982 + FmPcdLockUnlockAll(p_FmPcd);
32983 +
32984 + switch(GET_ERROR_TYPE(err)
32985 +) {
32986 + case E_OK:
32987 + return E_OK;
32988 +
32989 + case E_BUSY:
32990 + DBG(TRACE, ("E_BUSY error"));
32991 + return ERROR_CODE(E_BUSY);
32992 +
32993 + default:
32994 + RETURN_ERROR(MAJOR, err, NO_MSG);
32995 + }
32996 +}
32997 +
32998 +t_Error FM_PCD_MatchTableModifyKeyAndNextEngine(t_Handle h_CcNode,
32999 + uint16_t keyIndex,
33000 + uint8_t keySize,
33001 + t_FmPcdCcKeyParams *p_KeyParams)
33002 +{
33003 + t_FmPcd *p_FmPcd;
33004 + t_FmPcdCcNode *p_CcNode = (t_FmPcdCcNode *)h_CcNode;
33005 + t_Error err = E_OK;
33006 +
33007 + SANITY_CHECK_RETURN_ERROR(p_KeyParams, 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 = FmPcdCcModifyKeyAndNextEngine(p_FmPcd, p_CcNode, keyIndex, keySize,
33020 + p_KeyParams);
33021 +
33022 + FmPcdLockUnlockAll(p_FmPcd);
33023 +
33024 + switch(GET_ERROR_TYPE(err)
33025 +) {
33026 + case E_OK:
33027 + return E_OK;
33028 +
33029 + case E_BUSY:
33030 + DBG(TRACE, ("E_BUSY error"));
33031 + return ERROR_CODE(E_BUSY);
33032 +
33033 + default:
33034 + RETURN_ERROR(MAJOR, err, NO_MSG);
33035 + }
33036 +}
33037 +
33038 +t_Error FM_PCD_MatchTableFindNRemoveKey(t_Handle h_CcNode, uint8_t keySize,
33039 + uint8_t *p_Key, uint8_t *p_Mask)
33040 +{
33041 + t_FmPcd *p_FmPcd;
33042 + t_FmPcdCcNode *p_CcNode = (t_FmPcdCcNode *)h_CcNode;
33043 + uint16_t keyIndex;
33044 + t_Error err;
33045 +
33046 + SANITY_CHECK_RETURN_ERROR(p_Key, E_NULL_POINTER);
33047 + SANITY_CHECK_RETURN_ERROR(p_CcNode, E_INVALID_HANDLE);
33048 + p_FmPcd = (t_FmPcd *)p_CcNode->h_FmPcd;
33049 + SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);
33050 + SANITY_CHECK_RETURN_ERROR(p_FmPcd->h_Hc, E_INVALID_HANDLE);
33051 +
33052 + if (!FmPcdLockTryLockAll(p_FmPcd))
33053 + {
33054 + DBG(TRACE, ("FmPcdLockTryLockAll failed"));
33055 + return ERROR_CODE(E_BUSY);
33056 + }
33057 +
33058 + err = FindKeyIndex(p_CcNode, keySize, p_Key, p_Mask, &keyIndex);
33059 + if (GET_ERROR_TYPE(err) != E_OK)
33060 + {
33061 + FmPcdLockUnlockAll(p_FmPcd);
33062 + RETURN_ERROR(
33063 + MAJOR,
33064 + err,
33065 + ("The received key and mask pair was not found in the match table of the provided node"));
33066 + }
33067 +
33068 + err = FmPcdCcRemoveKey(p_FmPcd, p_CcNode, keyIndex);
33069 +
33070 + FmPcdLockUnlockAll(p_FmPcd);
33071 +
33072 + switch(GET_ERROR_TYPE(err)
33073 +) {
33074 + case E_OK:
33075 + return E_OK;
33076 +
33077 + case E_BUSY:
33078 + DBG(TRACE, ("E_BUSY error"));
33079 + return ERROR_CODE(E_BUSY);
33080 +
33081 + default:
33082 + RETURN_ERROR(MAJOR, err, NO_MSG);
33083 + }
33084 +}
33085 +
33086 +t_Error FM_PCD_MatchTableFindNModifyNextEngine(
33087 + t_Handle h_CcNode, uint8_t keySize, uint8_t *p_Key, uint8_t *p_Mask,
33088 + t_FmPcdCcNextEngineParams *p_FmPcdCcNextEngineParams)
33089 +{
33090 + t_FmPcd *p_FmPcd;
33091 + t_FmPcdCcNode *p_CcNode = (t_FmPcdCcNode *)h_CcNode;
33092 + uint16_t keyIndex;
33093 + t_Error err;
33094 +
33095 + SANITY_CHECK_RETURN_ERROR(p_Key, E_NULL_POINTER);
33096 + SANITY_CHECK_RETURN_ERROR(p_FmPcdCcNextEngineParams, E_NULL_POINTER);
33097 + SANITY_CHECK_RETURN_ERROR(p_CcNode, E_INVALID_HANDLE);
33098 + p_FmPcd = (t_FmPcd *)p_CcNode->h_FmPcd;
33099 + SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);
33100 + SANITY_CHECK_RETURN_ERROR(p_FmPcd->h_Hc, E_INVALID_HANDLE);
33101 +
33102 + if (!FmPcdLockTryLockAll(p_FmPcd))
33103 + {
33104 + DBG(TRACE, ("FmPcdLockTryLockAll failed"));
33105 + return ERROR_CODE(E_BUSY);
33106 + }
33107 +
33108 + err = FindKeyIndex(p_CcNode, keySize, p_Key, p_Mask, &keyIndex);
33109 + if (GET_ERROR_TYPE(err) != E_OK)
33110 + {
33111 + FmPcdLockUnlockAll(p_FmPcd);
33112 + RETURN_ERROR(
33113 + MAJOR,
33114 + err,
33115 + ("The received key and mask pair was not found in the match table of the provided node"));
33116 + }
33117 +
33118 + err = ModifyNextEngineParamNode(p_FmPcd, p_CcNode, keyIndex,
33119 + p_FmPcdCcNextEngineParams);
33120 +
33121 + FmPcdLockUnlockAll(p_FmPcd);
33122 +
33123 + switch(GET_ERROR_TYPE(err)
33124 +) {
33125 + case E_OK:
33126 + return E_OK;
33127 +
33128 + case E_BUSY:
33129 + DBG(TRACE, ("E_BUSY error"));
33130 + return ERROR_CODE(E_BUSY);
33131 +
33132 + default:
33133 + RETURN_ERROR(MAJOR, err, NO_MSG);
33134 + }
33135 +}
33136 +
33137 +t_Error FM_PCD_MatchTableFindNModifyKeyAndNextEngine(
33138 + t_Handle h_CcNode, uint8_t keySize, uint8_t *p_Key, uint8_t *p_Mask,
33139 + t_FmPcdCcKeyParams *p_KeyParams)
33140 +{
33141 + t_FmPcd *p_FmPcd;
33142 + t_FmPcdCcNode *p_CcNode = (t_FmPcdCcNode *)h_CcNode;
33143 + uint16_t keyIndex;
33144 + t_Error err;
33145 +
33146 + SANITY_CHECK_RETURN_ERROR(p_Key, E_NULL_POINTER);
33147 + SANITY_CHECK_RETURN_ERROR(p_KeyParams, E_NULL_POINTER);
33148 + SANITY_CHECK_RETURN_ERROR(p_CcNode, E_INVALID_HANDLE);
33149 + p_FmPcd = (t_FmPcd *)p_CcNode->h_FmPcd;
33150 + SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);
33151 + SANITY_CHECK_RETURN_ERROR(p_FmPcd->h_Hc, E_INVALID_HANDLE);
33152 +
33153 + if (!FmPcdLockTryLockAll(p_FmPcd))
33154 + {
33155 + DBG(TRACE, ("FmPcdLockTryLockAll failed"));
33156 + return ERROR_CODE(E_BUSY);
33157 + }
33158 +
33159 + err = FindKeyIndex(p_CcNode, keySize, p_Key, p_Mask, &keyIndex);
33160 + if (GET_ERROR_TYPE(err) != E_OK)
33161 + {
33162 + FmPcdLockUnlockAll(p_FmPcd);
33163 + RETURN_ERROR(
33164 + MAJOR,
33165 + err,
33166 + ("The received key and mask pair was not found in the match table of the provided node"));
33167 + }
33168 +
33169 + err = FmPcdCcModifyKeyAndNextEngine(p_FmPcd, h_CcNode, keyIndex, keySize,
33170 + p_KeyParams);
33171 +
33172 + FmPcdLockUnlockAll(p_FmPcd);
33173 +
33174 + switch(GET_ERROR_TYPE(err)
33175 +) {
33176 + case E_OK:
33177 + return E_OK;
33178 +
33179 + case E_BUSY:
33180 + DBG(TRACE, ("E_BUSY error"));
33181 + return ERROR_CODE(E_BUSY);
33182 +
33183 + default:
33184 + RETURN_ERROR(MAJOR, err, NO_MSG);
33185 + }
33186 +}
33187 +
33188 +t_Error FM_PCD_MatchTableFindNModifyKey(t_Handle h_CcNode, uint8_t keySize,
33189 + uint8_t *p_Key, uint8_t *p_Mask,
33190 + uint8_t *p_NewKey, uint8_t *p_NewMask)
33191 +{
33192 + t_FmPcd *p_FmPcd;
33193 + t_FmPcdCcNode *p_CcNode = (t_FmPcdCcNode *)h_CcNode;
33194 + t_List h_List;
33195 + uint16_t keyIndex;
33196 + t_Error err;
33197 +
33198 + SANITY_CHECK_RETURN_ERROR(p_Key, E_NULL_POINTER);
33199 + SANITY_CHECK_RETURN_ERROR(p_NewKey, E_NULL_POINTER);
33200 + SANITY_CHECK_RETURN_ERROR(p_CcNode, E_INVALID_HANDLE);
33201 + p_FmPcd = (t_FmPcd *)p_CcNode->h_FmPcd;
33202 + SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);
33203 + SANITY_CHECK_RETURN_ERROR(p_FmPcd->h_Hc, E_INVALID_HANDLE);
33204 +
33205 + INIT_LIST(&h_List);
33206 +
33207 + err = FmPcdCcNodeTreeTryLock(p_FmPcd, p_CcNode, &h_List);
33208 + if (err)
33209 + {
33210 + DBG(TRACE, ("Node's trees lock failed"));
33211 + return ERROR_CODE(E_BUSY);
33212 + }
33213 +
33214 + err = FindKeyIndex(p_CcNode, keySize, p_Key, p_Mask, &keyIndex);
33215 + if (GET_ERROR_TYPE(err) != E_OK)
33216 + {
33217 + FmPcdCcNodeTreeReleaseLock(p_FmPcd, &h_List);
33218 + RETURN_ERROR(MAJOR, err,
33219 + ("The received key and mask pair was not found in the "
33220 + "match table of the provided node"));
33221 + }
33222 +
33223 + err = FmPcdCcModifyKey(p_FmPcd, p_CcNode, keyIndex, keySize, p_NewKey,
33224 + p_NewMask);
33225 +
33226 + FmPcdCcNodeTreeReleaseLock(p_FmPcd, &h_List);
33227 +
33228 + switch(GET_ERROR_TYPE(err)
33229 +) {
33230 + case E_OK:
33231 + return E_OK;
33232 +
33233 + case E_BUSY:
33234 + DBG(TRACE, ("E_BUSY error"));
33235 + return ERROR_CODE(E_BUSY);
33236 +
33237 + default:
33238 + RETURN_ERROR(MAJOR, err, NO_MSG);
33239 + }
33240 +}
33241 +
33242 +t_Error FM_PCD_MatchTableGetNextEngine(
33243 + t_Handle h_CcNode, uint16_t keyIndex,
33244 + t_FmPcdCcNextEngineParams *p_FmPcdCcNextEngineParams)
33245 +{
33246 + t_FmPcdCcNode *p_CcNode = (t_FmPcdCcNode *)h_CcNode;
33247 +
33248 + SANITY_CHECK_RETURN_ERROR(p_CcNode, E_INVALID_HANDLE);
33249 + SANITY_CHECK_RETURN_ERROR(p_FmPcdCcNextEngineParams, E_NULL_POINTER);
33250 +
33251 + if (keyIndex >= p_CcNode->numOfKeys)
33252 + RETURN_ERROR(MAJOR, E_INVALID_STATE,
33253 + ("keyIndex exceeds current number of keys"));
33254 +
33255 + if (keyIndex > (FM_PCD_MAX_NUM_OF_KEYS - 1))
33256 + RETURN_ERROR(
33257 + MAJOR,
33258 + E_INVALID_VALUE,
33259 + ("keyIndex can not be larger than %d", (FM_PCD_MAX_NUM_OF_KEYS - 1)));
33260 +
33261 + memcpy(p_FmPcdCcNextEngineParams,
33262 + &p_CcNode->keyAndNextEngineParams[keyIndex].nextEngineParams,
33263 + sizeof(t_FmPcdCcNextEngineParams));
33264 +
33265 + return E_OK;
33266 +}
33267 +
33268 +
33269 +uint32_t FM_PCD_MatchTableGetKeyCounter(t_Handle h_CcNode, uint16_t keyIndex)
33270 +{
33271 + t_FmPcdCcNode *p_CcNode = (t_FmPcdCcNode *)h_CcNode;
33272 + uint32_t *p_StatsCounters, frameCount;
33273 + uint32_t intFlags;
33274 +
33275 + SANITY_CHECK_RETURN_VALUE(p_CcNode, E_INVALID_HANDLE, 0);
33276 +
33277 + if (p_CcNode->statisticsMode == e_FM_PCD_CC_STATS_MODE_NONE)
33278 + {
33279 + REPORT_ERROR(MAJOR, E_INVALID_STATE, ("Statistics were not enabled for this match table"));
33280 + return 0;
33281 + }
33282 +
33283 + if ((p_CcNode->statisticsMode != e_FM_PCD_CC_STATS_MODE_FRAME)
33284 + && (p_CcNode->statisticsMode
33285 + != e_FM_PCD_CC_STATS_MODE_BYTE_AND_FRAME))
33286 + {
33287 + REPORT_ERROR(MAJOR, E_INVALID_STATE, ("Frame count is not supported in the statistics mode of this match table"));
33288 + return 0;
33289 + }
33290 +
33291 + intFlags = XX_LockIntrSpinlock(p_CcNode->h_Spinlock);
33292 +
33293 + if (keyIndex >= p_CcNode->numOfKeys)
33294 + {
33295 + XX_UnlockIntrSpinlock(p_CcNode->h_Spinlock, intFlags);
33296 + REPORT_ERROR(MAJOR, E_INVALID_STATE, ("The provided keyIndex exceeds the number of keys in this match table"));
33297 + return 0;
33298 + }
33299 +
33300 + if (!p_CcNode->keyAndNextEngineParams[keyIndex].p_StatsObj)
33301 + {
33302 + XX_UnlockIntrSpinlock(p_CcNode->h_Spinlock, intFlags);
33303 + REPORT_ERROR(MAJOR, E_INVALID_STATE, ("Statistics were not enabled for this key"));
33304 + return 0;
33305 + }
33306 +
33307 + p_StatsCounters =
33308 + p_CcNode->keyAndNextEngineParams[keyIndex].p_StatsObj->h_StatsCounters;
33309 + ASSERT_COND(p_StatsCounters);
33310 +
33311 + /* The first counter is byte counter, so we need to advance to the next counter */
33312 + frameCount = GET_UINT32(*(uint32_t *)(PTR_MOVE(p_StatsCounters,
33313 + FM_PCD_CC_STATS_COUNTER_SIZE)));
33314 +
33315 + XX_UnlockIntrSpinlock(p_CcNode->h_Spinlock, intFlags);
33316 +
33317 + return frameCount;
33318 +}
33319 +
33320 +t_Error FM_PCD_MatchTableGetKeyStatistics(
33321 + t_Handle h_CcNode, uint16_t keyIndex,
33322 + t_FmPcdCcKeyStatistics *p_KeyStatistics)
33323 +{
33324 + t_FmPcdCcNode *p_CcNode = (t_FmPcdCcNode *)h_CcNode;
33325 + uint32_t intFlags;
33326 + t_Error err;
33327 +
33328 + SANITY_CHECK_RETURN_ERROR(h_CcNode, E_INVALID_HANDLE);
33329 + SANITY_CHECK_RETURN_ERROR(p_KeyStatistics, E_NULL_POINTER);
33330 +
33331 + intFlags = XX_LockIntrSpinlock(p_CcNode->h_Spinlock);
33332 +
33333 + if (keyIndex >= p_CcNode->numOfKeys)
33334 + RETURN_ERROR(
33335 + MAJOR,
33336 + E_INVALID_STATE,
33337 + ("The provided keyIndex exceeds the number of keys in this match table"));
33338 +
33339 + err = MatchTableGetKeyStatistics(p_CcNode, keyIndex, p_KeyStatistics);
33340 +
33341 + XX_UnlockIntrSpinlock(p_CcNode->h_Spinlock, intFlags);
33342 +
33343 + if (err != E_OK)
33344 + RETURN_ERROR(MAJOR, err, NO_MSG);
33345 +
33346 + return E_OK;
33347 +}
33348 +
33349 +t_Error FM_PCD_MatchTableGetMissStatistics(
33350 + t_Handle h_CcNode, t_FmPcdCcKeyStatistics *p_MissStatistics)
33351 +{
33352 + t_FmPcdCcNode *p_CcNode = (t_FmPcdCcNode *)h_CcNode;
33353 + uint32_t intFlags;
33354 + t_Error err;
33355 +
33356 + SANITY_CHECK_RETURN_ERROR(h_CcNode, E_INVALID_HANDLE);
33357 + SANITY_CHECK_RETURN_ERROR(p_MissStatistics, E_NULL_POINTER);
33358 +
33359 + intFlags = XX_LockIntrSpinlock(p_CcNode->h_Spinlock);
33360 +
33361 + err = MatchTableGetKeyStatistics(p_CcNode, p_CcNode->numOfKeys,
33362 + p_MissStatistics);
33363 +
33364 + XX_UnlockIntrSpinlock(p_CcNode->h_Spinlock, intFlags);
33365 +
33366 + if (err != E_OK)
33367 + RETURN_ERROR(MAJOR, err, NO_MSG);
33368 +
33369 + return E_OK;
33370 +}
33371 +
33372 +t_Error FM_PCD_MatchTableFindNGetKeyStatistics(
33373 + t_Handle h_CcNode, uint8_t keySize, uint8_t *p_Key, uint8_t *p_Mask,
33374 + t_FmPcdCcKeyStatistics *p_KeyStatistics)
33375 +{
33376 + t_FmPcdCcNode *p_CcNode = (t_FmPcdCcNode *)h_CcNode;
33377 + uint16_t keyIndex;
33378 + uint32_t intFlags;
33379 + t_Error err;
33380 +
33381 + SANITY_CHECK_RETURN_ERROR(p_Key, E_NULL_POINTER);
33382 + SANITY_CHECK_RETURN_ERROR(p_KeyStatistics, E_NULL_POINTER);
33383 +
33384 + intFlags = XX_LockIntrSpinlock(p_CcNode->h_Spinlock);
33385 +
33386 + err = FindKeyIndex(p_CcNode, keySize, p_Key, p_Mask, &keyIndex);
33387 + if (GET_ERROR_TYPE(err) != E_OK)
33388 + {
33389 + XX_UnlockIntrSpinlock(p_CcNode->h_Spinlock, intFlags);
33390 + RETURN_ERROR(MAJOR, err,
33391 + ("The received key and mask pair was not found in the "
33392 + "match table of the provided node"));
33393 + }
33394 +
33395 + ASSERT_COND(keyIndex < p_CcNode->numOfKeys);
33396 +
33397 + err = MatchTableGetKeyStatistics(p_CcNode, keyIndex, p_KeyStatistics);
33398 +
33399 + XX_UnlockIntrSpinlock(p_CcNode->h_Spinlock, intFlags);
33400 +
33401 + if (err != E_OK)
33402 + RETURN_ERROR(MAJOR, err, NO_MSG);
33403 +
33404 + return E_OK;
33405 +}
33406 +
33407 +t_Error FM_PCD_MatchTableGetIndexedHashBucket(t_Handle h_CcNode,
33408 + uint8_t keySize, uint8_t *p_Key,
33409 + uint8_t hashShift,
33410 + t_Handle *p_CcNodeBucketHandle,
33411 + uint8_t *p_BucketIndex,
33412 + uint16_t *p_LastIndex)
33413 +{
33414 + t_FmPcdCcNode *p_CcNode = (t_FmPcdCcNode *)h_CcNode;
33415 + uint16_t glblMask;
33416 + uint64_t crc64 = 0;
33417 +
33418 + SANITY_CHECK_RETURN_ERROR(h_CcNode, E_INVALID_HANDLE);
33419 + SANITY_CHECK_RETURN_ERROR(
33420 + p_CcNode->parseCode == CC_PC_GENERIC_IC_HASH_INDEXED,
33421 + E_INVALID_STATE);
33422 + SANITY_CHECK_RETURN_ERROR(p_Key, E_NULL_POINTER);
33423 + SANITY_CHECK_RETURN_ERROR(p_CcNodeBucketHandle, E_NULL_POINTER);
33424 +
33425 + memcpy(&glblMask, PTR_MOVE(p_CcNode->p_GlblMask, 2), 2);
33426 + be16_to_cpus(&glblMask);
33427 +
33428 + crc64 = crc64_init();
33429 + crc64 = crc64_compute(p_Key, keySize, crc64);
33430 + crc64 >>= hashShift;
33431 +
33432 + *p_BucketIndex = (uint8_t)(((crc64 >> (8 * (6 - p_CcNode->userOffset)))
33433 + & glblMask) >> 4);
33434 + if (*p_BucketIndex >= p_CcNode->numOfKeys)
33435 + RETURN_ERROR(MINOR, E_NOT_IN_RANGE, ("bucket index!"));
33436 +
33437 + *p_CcNodeBucketHandle =
33438 + p_CcNode->keyAndNextEngineParams[*p_BucketIndex].nextEngineParams.params.ccParams.h_CcNode;
33439 + if (!*p_CcNodeBucketHandle)
33440 + RETURN_ERROR(MINOR, E_NOT_FOUND, ("bucket!"));
33441 +
33442 + *p_LastIndex = ((t_FmPcdCcNode *)*p_CcNodeBucketHandle)->numOfKeys;
33443 +
33444 + return E_OK;
33445 +}
33446 +
33447 +t_Handle FM_PCD_HashTableSet(t_Handle h_FmPcd, t_FmPcdHashTableParams *p_Param)
33448 +{
33449 + t_FmPcdCcNode *p_CcNodeHashTbl;
33450 + t_FmPcdCcNodeParams *p_IndxHashCcNodeParam, *p_ExactMatchCcNodeParam;
33451 + t_FmPcdCcNode *p_CcNode;
33452 + t_Handle h_MissStatsCounters = NULL;
33453 + t_FmPcdCcKeyParams *p_HashKeyParams;
33454 + int i;
33455 + uint16_t numOfSets, numOfWays, countMask, onesCount = 0;
33456 + bool statsEnForMiss = FALSE;
33457 + t_Error err;
33458 +
33459 + SANITY_CHECK_RETURN_VALUE(h_FmPcd, E_INVALID_HANDLE, NULL);
33460 + SANITY_CHECK_RETURN_VALUE(p_Param, E_NULL_POINTER, NULL);
33461 +
33462 + if (p_Param->maxNumOfKeys == 0)
33463 + {
33464 + REPORT_ERROR(MINOR, E_INVALID_VALUE, ("Max number of keys must be higher then 0"));
33465 + return NULL;
33466 + }
33467 +
33468 + if (p_Param->hashResMask == 0)
33469 + {
33470 + REPORT_ERROR(MINOR, E_INVALID_VALUE, ("Hash result mask must differ from 0"));
33471 + return NULL;
33472 + }
33473 +
33474 + /*Fix: QorIQ SDK / QSDK-2131*/
33475 + if (p_Param->ccNextEngineParamsForMiss.nextEngine == e_FM_PCD_INVALID)
33476 + {
33477 + 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."));
33478 + return NULL;
33479 + }
33480 +
33481 +#if (DPAA_VERSION >= 11)
33482 + if (p_Param->statisticsMode == e_FM_PCD_CC_STATS_MODE_RMON)
33483 + {
33484 + REPORT_ERROR(MAJOR, E_INVALID_VALUE,
33485 + ("RMON statistics mode is not supported for hash table"));
33486 + return NULL;
33487 + }
33488 +#endif /* (DPAA_VERSION >= 11) */
33489 +
33490 + p_ExactMatchCcNodeParam = (t_FmPcdCcNodeParams*)XX_Malloc(
33491 + sizeof(t_FmPcdCcNodeParams));
33492 + if (!p_ExactMatchCcNodeParam)
33493 + {
33494 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("p_ExactMatchCcNodeParam"));
33495 + return NULL;
33496 + }
33497 + memset(p_ExactMatchCcNodeParam, 0, sizeof(t_FmPcdCcNodeParams));
33498 +
33499 + p_IndxHashCcNodeParam = (t_FmPcdCcNodeParams*)XX_Malloc(
33500 + sizeof(t_FmPcdCcNodeParams));
33501 + if (!p_IndxHashCcNodeParam)
33502 + {
33503 + XX_Free(p_ExactMatchCcNodeParam);
33504 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("p_IndxHashCcNodeParam"));
33505 + return NULL;
33506 + }
33507 + memset(p_IndxHashCcNodeParam, 0, sizeof(t_FmPcdCcNodeParams));
33508 +
33509 + /* Calculate number of sets and number of ways of the hash table */
33510 + countMask = (uint16_t)(p_Param->hashResMask >> 4);
33511 + while (countMask)
33512 + {
33513 + onesCount++;
33514 + countMask = (uint16_t)(countMask >> 1);
33515 + }
33516 +
33517 + numOfSets = (uint16_t)(1 << onesCount);
33518 + numOfWays = (uint16_t)DIV_CEIL(p_Param->maxNumOfKeys, numOfSets);
33519 +
33520 + if (p_Param->maxNumOfKeys % numOfSets)
33521 + DBG(INFO, ("'maxNumOfKeys' is not a multiple of hash number of ways, so number of ways will be rounded up"));
33522 +
33523 + if ((p_Param->statisticsMode == e_FM_PCD_CC_STATS_MODE_FRAME)
33524 + || (p_Param->statisticsMode == e_FM_PCD_CC_STATS_MODE_BYTE_AND_FRAME))
33525 + {
33526 + /* Allocating a statistics counters table that will be used by all
33527 + 'miss' entries of the hash table */
33528 + h_MissStatsCounters = (t_Handle)FM_MURAM_AllocMem(
33529 + FmPcdGetMuramHandle(h_FmPcd), 2 * FM_PCD_CC_STATS_COUNTER_SIZE,
33530 + FM_PCD_CC_AD_TABLE_ALIGN);
33531 + if (!h_MissStatsCounters)
33532 + {
33533 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("MURAM allocation for statistics table for hash miss"));
33534 + XX_Free(p_IndxHashCcNodeParam);
33535 + XX_Free(p_ExactMatchCcNodeParam);
33536 + return NULL;
33537 + }
33538 + memset(h_MissStatsCounters, 0, (2 * FM_PCD_CC_STATS_COUNTER_SIZE));
33539 +
33540 + /* Always enable statistics for 'miss', so that a statistics AD will be
33541 + initialized from the start. We'll store the requested 'statistics enable'
33542 + value and it will be used when statistics are read by the user. */
33543 + statsEnForMiss = p_Param->ccNextEngineParamsForMiss.statisticsEn;
33544 + p_Param->ccNextEngineParamsForMiss.statisticsEn = TRUE;
33545 + }
33546 +
33547 + /* Building exact-match node params, will be used to create the hash buckets */
33548 + p_ExactMatchCcNodeParam->extractCcParams.type = e_FM_PCD_EXTRACT_NON_HDR;
33549 +
33550 + p_ExactMatchCcNodeParam->extractCcParams.extractNonHdr.src =
33551 + e_FM_PCD_EXTRACT_FROM_KEY;
33552 + p_ExactMatchCcNodeParam->extractCcParams.extractNonHdr.action =
33553 + e_FM_PCD_ACTION_EXACT_MATCH;
33554 + p_ExactMatchCcNodeParam->extractCcParams.extractNonHdr.offset = 0;
33555 + p_ExactMatchCcNodeParam->extractCcParams.extractNonHdr.size =
33556 + p_Param->matchKeySize;
33557 +
33558 + p_ExactMatchCcNodeParam->keysParams.maxNumOfKeys = numOfWays;
33559 + p_ExactMatchCcNodeParam->keysParams.maskSupport = FALSE;
33560 + p_ExactMatchCcNodeParam->keysParams.statisticsMode =
33561 + p_Param->statisticsMode;
33562 + p_ExactMatchCcNodeParam->keysParams.numOfKeys = 0;
33563 + p_ExactMatchCcNodeParam->keysParams.keySize = p_Param->matchKeySize;
33564 + p_ExactMatchCcNodeParam->keysParams.ccNextEngineParamsForMiss =
33565 + p_Param->ccNextEngineParamsForMiss;
33566 +
33567 + p_HashKeyParams = p_IndxHashCcNodeParam->keysParams.keyParams;
33568 +
33569 + for (i = 0; i < numOfSets; i++)
33570 + {
33571 + /* Each exact-match node will be marked as a 'bucket' and provided with
33572 + a pointer to statistics counters, to be used for 'miss' entry
33573 + statistics */
33574 + p_CcNode = (t_FmPcdCcNode *)XX_Malloc(sizeof(t_FmPcdCcNode));
33575 + if (!p_CcNode)
33576 + break;
33577 + memset(p_CcNode, 0, sizeof(t_FmPcdCcNode));
33578 +
33579 + p_CcNode->isHashBucket = TRUE;
33580 + p_CcNode->h_MissStatsCounters = h_MissStatsCounters;
33581 +
33582 + err = MatchTableSet(h_FmPcd, p_CcNode, p_ExactMatchCcNodeParam);
33583 + if (err)
33584 + break;
33585 +
33586 + p_HashKeyParams[i].ccNextEngineParams.nextEngine = e_FM_PCD_CC;
33587 + p_HashKeyParams[i].ccNextEngineParams.statisticsEn = FALSE;
33588 + p_HashKeyParams[i].ccNextEngineParams.params.ccParams.h_CcNode =
33589 + p_CcNode;
33590 + }
33591 +
33592 + if (i < numOfSets)
33593 + {
33594 + for (i = i - 1; i >= 0; i--)
33595 + FM_PCD_MatchTableDelete(
33596 + p_HashKeyParams[i].ccNextEngineParams.params.ccParams.h_CcNode);
33597 +
33598 + FM_MURAM_FreeMem(FmPcdGetMuramHandle(h_FmPcd), h_MissStatsCounters);
33599 +
33600 + REPORT_ERROR(MAJOR, E_NULL_POINTER, NO_MSG);
33601 + XX_Free(p_IndxHashCcNodeParam);
33602 + XX_Free(p_ExactMatchCcNodeParam);
33603 + return NULL;
33604 + }
33605 +
33606 + /* Creating indexed-hash CC node */
33607 + p_IndxHashCcNodeParam->extractCcParams.type = e_FM_PCD_EXTRACT_NON_HDR;
33608 + p_IndxHashCcNodeParam->extractCcParams.extractNonHdr.src =
33609 + e_FM_PCD_EXTRACT_FROM_HASH;
33610 + p_IndxHashCcNodeParam->extractCcParams.extractNonHdr.action =
33611 + e_FM_PCD_ACTION_INDEXED_LOOKUP;
33612 + p_IndxHashCcNodeParam->extractCcParams.extractNonHdr.icIndxMask =
33613 + p_Param->hashResMask;
33614 + p_IndxHashCcNodeParam->extractCcParams.extractNonHdr.offset =
33615 + p_Param->hashShift;
33616 + p_IndxHashCcNodeParam->extractCcParams.extractNonHdr.size = 2;
33617 +
33618 + p_IndxHashCcNodeParam->keysParams.maxNumOfKeys = numOfSets;
33619 + p_IndxHashCcNodeParam->keysParams.maskSupport = FALSE;
33620 + p_IndxHashCcNodeParam->keysParams.statisticsMode =
33621 + e_FM_PCD_CC_STATS_MODE_NONE;
33622 + /* Number of keys of this node is number of sets of the hash */
33623 + p_IndxHashCcNodeParam->keysParams.numOfKeys = numOfSets;
33624 + p_IndxHashCcNodeParam->keysParams.keySize = 2;
33625 +
33626 + p_CcNodeHashTbl = FM_PCD_MatchTableSet(h_FmPcd, p_IndxHashCcNodeParam);
33627 +
33628 + if (p_CcNodeHashTbl)
33629 + {
33630 + p_CcNodeHashTbl->kgHashShift = p_Param->kgHashShift;
33631 +
33632 + /* Storing the allocated counters for buckets 'miss' in the hash table
33633 + and if statistics for miss were enabled. */
33634 + p_CcNodeHashTbl->h_MissStatsCounters = h_MissStatsCounters;
33635 + p_CcNodeHashTbl->statsEnForMiss = statsEnForMiss;
33636 + }
33637 +
33638 + XX_Free(p_IndxHashCcNodeParam);
33639 + XX_Free(p_ExactMatchCcNodeParam);
33640 +
33641 + return p_CcNodeHashTbl;
33642 +}
33643 +
33644 +t_Error FM_PCD_HashTableDelete(t_Handle h_HashTbl)
33645 +{
33646 + t_FmPcdCcNode *p_HashTbl = (t_FmPcdCcNode *)h_HashTbl;
33647 + t_Handle h_FmPcd;
33648 + t_Handle *p_HashBuckets, h_MissStatsCounters;
33649 + uint16_t i, numOfBuckets;
33650 + t_Error err;
33651 +
33652 + SANITY_CHECK_RETURN_ERROR(p_HashTbl, E_INVALID_HANDLE);
33653 +
33654 + /* Store all hash buckets before the hash is freed */
33655 + numOfBuckets = p_HashTbl->numOfKeys;
33656 +
33657 + p_HashBuckets = (t_Handle *)XX_Malloc(numOfBuckets * sizeof(t_Handle));
33658 + if (!p_HashBuckets)
33659 + RETURN_ERROR(MAJOR, E_NO_MEMORY, NO_MSG);
33660 +
33661 + for (i = 0; i < numOfBuckets; i++)
33662 + p_HashBuckets[i] =
33663 + p_HashTbl->keyAndNextEngineParams[i].nextEngineParams.params.ccParams.h_CcNode;
33664 +
33665 + h_FmPcd = p_HashTbl->h_FmPcd;
33666 + h_MissStatsCounters = p_HashTbl->h_MissStatsCounters;
33667 +
33668 + /* Free the hash */
33669 + err = FM_PCD_MatchTableDelete(p_HashTbl);
33670 +
33671 + /* Free each hash bucket */
33672 + for (i = 0; i < numOfBuckets; i++)
33673 + err |= FM_PCD_MatchTableDelete(p_HashBuckets[i]);
33674 +
33675 + XX_Free(p_HashBuckets);
33676 +
33677 + /* Free statistics counters for 'miss', if these were allocated */
33678 + if (h_MissStatsCounters)
33679 + FM_MURAM_FreeMem(FmPcdGetMuramHandle(h_FmPcd), h_MissStatsCounters);
33680 +
33681 + if (err)
33682 + RETURN_ERROR(MAJOR, err, NO_MSG);
33683 +
33684 + return E_OK;
33685 +}
33686 +
33687 +t_Error FM_PCD_HashTableAddKey(t_Handle h_HashTbl, uint8_t keySize,
33688 + t_FmPcdCcKeyParams *p_KeyParams)
33689 +{
33690 + t_FmPcdCcNode *p_HashTbl = (t_FmPcdCcNode *)h_HashTbl;
33691 + t_Handle h_HashBucket;
33692 + uint8_t bucketIndex;
33693 + uint16_t lastIndex;
33694 + t_Error err;
33695 +
33696 + SANITY_CHECK_RETURN_ERROR(p_HashTbl, E_INVALID_HANDLE);
33697 + SANITY_CHECK_RETURN_ERROR(p_KeyParams, E_NULL_POINTER);
33698 + SANITY_CHECK_RETURN_ERROR(p_KeyParams->p_Key, E_NULL_POINTER);
33699 +
33700 + if (p_KeyParams->p_Mask)
33701 + RETURN_ERROR(MAJOR, E_INVALID_VALUE,
33702 + ("Keys masks not supported for hash table"));
33703 +
33704 + err = FM_PCD_MatchTableGetIndexedHashBucket(p_HashTbl, keySize,
33705 + p_KeyParams->p_Key,
33706 + p_HashTbl->kgHashShift,
33707 + &h_HashBucket, &bucketIndex,
33708 + &lastIndex);
33709 + if (err)
33710 + RETURN_ERROR(MAJOR, err, NO_MSG);
33711 +
33712 + return FM_PCD_MatchTableAddKey(h_HashBucket, FM_PCD_LAST_KEY_INDEX, keySize,
33713 + p_KeyParams);
33714 +}
33715 +
33716 +t_Error FM_PCD_HashTableRemoveKey(t_Handle h_HashTbl, uint8_t keySize,
33717 + uint8_t *p_Key)
33718 +{
33719 + t_FmPcdCcNode *p_HashTbl = (t_FmPcdCcNode *)h_HashTbl;
33720 + t_Handle h_HashBucket;
33721 + uint8_t bucketIndex;
33722 + uint16_t lastIndex;
33723 + t_Error err;
33724 +
33725 + SANITY_CHECK_RETURN_ERROR(p_HashTbl, E_INVALID_HANDLE);
33726 + SANITY_CHECK_RETURN_ERROR(p_Key, E_NULL_POINTER);
33727 +
33728 + err = FM_PCD_MatchTableGetIndexedHashBucket(p_HashTbl, keySize, p_Key,
33729 + p_HashTbl->kgHashShift,
33730 + &h_HashBucket, &bucketIndex,
33731 + &lastIndex);
33732 + if (err)
33733 + RETURN_ERROR(MAJOR, err, NO_MSG);
33734 +
33735 + return FM_PCD_MatchTableFindNRemoveKey(h_HashBucket, keySize, p_Key, NULL);
33736 +}
33737 +
33738 +t_Error FM_PCD_HashTableModifyNextEngine(
33739 + t_Handle h_HashTbl, uint8_t keySize, uint8_t *p_Key,
33740 + t_FmPcdCcNextEngineParams *p_FmPcdCcNextEngineParams)
33741 +{
33742 + t_FmPcdCcNode *p_HashTbl = (t_FmPcdCcNode *)h_HashTbl;
33743 + t_Handle h_HashBucket;
33744 + uint8_t bucketIndex;
33745 + uint16_t lastIndex;
33746 + t_Error err;
33747 +
33748 + SANITY_CHECK_RETURN_ERROR(p_HashTbl, E_INVALID_HANDLE);
33749 + SANITY_CHECK_RETURN_ERROR(p_Key, E_NULL_POINTER);
33750 + SANITY_CHECK_RETURN_ERROR(p_FmPcdCcNextEngineParams, E_NULL_POINTER);
33751 +
33752 + err = FM_PCD_MatchTableGetIndexedHashBucket(p_HashTbl, keySize, p_Key,
33753 + p_HashTbl->kgHashShift,
33754 + &h_HashBucket, &bucketIndex,
33755 + &lastIndex);
33756 + if (err)
33757 + RETURN_ERROR(MAJOR, err, NO_MSG);
33758 +
33759 + return FM_PCD_MatchTableFindNModifyNextEngine(h_HashBucket, keySize, p_Key,
33760 + NULL,
33761 + p_FmPcdCcNextEngineParams);
33762 +}
33763 +
33764 +t_Error FM_PCD_HashTableModifyMissNextEngine(
33765 + t_Handle h_HashTbl,
33766 + t_FmPcdCcNextEngineParams *p_FmPcdCcNextEngineParams)
33767 +{
33768 + t_FmPcdCcNode *p_HashTbl = (t_FmPcdCcNode *)h_HashTbl;
33769 + t_Handle h_HashBucket;
33770 + uint8_t i;
33771 + bool nullifyMissStats = FALSE;
33772 + t_Error err;
33773 +
33774 + SANITY_CHECK_RETURN_ERROR(h_HashTbl, E_INVALID_HANDLE);
33775 + SANITY_CHECK_RETURN_ERROR(p_FmPcdCcNextEngineParams, E_NULL_POINTER);
33776 +
33777 + if ((!p_HashTbl->h_MissStatsCounters)
33778 + && (p_FmPcdCcNextEngineParams->statisticsEn))
33779 + RETURN_ERROR(
33780 + MAJOR,
33781 + E_CONFLICT,
33782 + ("Statistics are requested for a key, but statistics mode was set"
33783 + "to 'NONE' upon initialization"));
33784 +
33785 + if (p_HashTbl->h_MissStatsCounters)
33786 + {
33787 + if ((!p_HashTbl->statsEnForMiss)
33788 + && (p_FmPcdCcNextEngineParams->statisticsEn))
33789 + nullifyMissStats = TRUE;
33790 +
33791 + if ((p_HashTbl->statsEnForMiss)
33792 + && (!p_FmPcdCcNextEngineParams->statisticsEn))
33793 + {
33794 + p_HashTbl->statsEnForMiss = FALSE;
33795 + p_FmPcdCcNextEngineParams->statisticsEn = TRUE;
33796 + }
33797 + }
33798 +
33799 + for (i = 0; i < p_HashTbl->numOfKeys; i++)
33800 + {
33801 + h_HashBucket =
33802 + p_HashTbl->keyAndNextEngineParams[i].nextEngineParams.params.ccParams.h_CcNode;
33803 +
33804 + err = FM_PCD_MatchTableModifyMissNextEngine(h_HashBucket,
33805 + p_FmPcdCcNextEngineParams);
33806 + if (err)
33807 + RETURN_ERROR(MAJOR, err, NO_MSG);
33808 + }
33809 +
33810 + if (nullifyMissStats)
33811 + {
33812 + memset(p_HashTbl->h_MissStatsCounters, 0,
33813 + (2 * FM_PCD_CC_STATS_COUNTER_SIZE));
33814 + memset(p_HashTbl->h_MissStatsCounters, 0,
33815 + (2 * FM_PCD_CC_STATS_COUNTER_SIZE));
33816 + p_HashTbl->statsEnForMiss = TRUE;
33817 + }
33818 +
33819 + return E_OK;
33820 +}
33821 +
33822 +
33823 +t_Error FM_PCD_HashTableGetMissNextEngine(
33824 + t_Handle h_HashTbl,
33825 + t_FmPcdCcNextEngineParams *p_FmPcdCcNextEngineParams)
33826 +{
33827 + t_FmPcdCcNode *p_HashTbl = (t_FmPcdCcNode *)h_HashTbl;
33828 + t_FmPcdCcNode *p_HashBucket;
33829 +
33830 + SANITY_CHECK_RETURN_ERROR(p_HashTbl, E_INVALID_HANDLE);
33831 +
33832 + /* Miss next engine of each bucket was initialized with the next engine of the hash table */
33833 + p_HashBucket =
33834 + p_HashTbl->keyAndNextEngineParams[0].nextEngineParams.params.ccParams.h_CcNode;
33835 +
33836 + memcpy(p_FmPcdCcNextEngineParams,
33837 + &p_HashBucket->keyAndNextEngineParams[p_HashBucket->numOfKeys].nextEngineParams,
33838 + sizeof(t_FmPcdCcNextEngineParams));
33839 +
33840 + return E_OK;
33841 +}
33842 +
33843 +t_Error FM_PCD_HashTableFindNGetKeyStatistics(
33844 + t_Handle h_HashTbl, uint8_t keySize, uint8_t *p_Key,
33845 + t_FmPcdCcKeyStatistics *p_KeyStatistics)
33846 +{
33847 + t_FmPcdCcNode *p_HashTbl = (t_FmPcdCcNode *)h_HashTbl;
33848 + t_Handle h_HashBucket;
33849 + uint8_t bucketIndex;
33850 + uint16_t lastIndex;
33851 + t_Error err;
33852 +
33853 + SANITY_CHECK_RETURN_ERROR(p_HashTbl, E_INVALID_HANDLE);
33854 + SANITY_CHECK_RETURN_ERROR(p_Key, E_NULL_POINTER);
33855 + SANITY_CHECK_RETURN_ERROR(p_KeyStatistics, E_NULL_POINTER);
33856 +
33857 + err = FM_PCD_MatchTableGetIndexedHashBucket(p_HashTbl, keySize, p_Key,
33858 + p_HashTbl->kgHashShift,
33859 + &h_HashBucket, &bucketIndex,
33860 + &lastIndex);
33861 + if (err)
33862 + RETURN_ERROR(MAJOR, err, NO_MSG);
33863 +
33864 + return FM_PCD_MatchTableFindNGetKeyStatistics(h_HashBucket, keySize, p_Key,
33865 + NULL, p_KeyStatistics);
33866 +}
33867 +
33868 +t_Error FM_PCD_HashTableGetMissStatistics(
33869 + t_Handle h_HashTbl, t_FmPcdCcKeyStatistics *p_MissStatistics)
33870 +{
33871 + t_FmPcdCcNode *p_HashTbl = (t_FmPcdCcNode *)h_HashTbl;
33872 + t_Handle h_HashBucket;
33873 +
33874 + SANITY_CHECK_RETURN_ERROR(p_HashTbl, E_INVALID_HANDLE);
33875 + SANITY_CHECK_RETURN_ERROR(p_MissStatistics, E_NULL_POINTER);
33876 +
33877 + if (!p_HashTbl->statsEnForMiss)
33878 + RETURN_ERROR(MAJOR, E_INVALID_STATE,
33879 + ("Statistics were not enabled for miss"));
33880 +
33881 + h_HashBucket =
33882 + p_HashTbl->keyAndNextEngineParams[0].nextEngineParams.params.ccParams.h_CcNode;
33883 +
33884 + return FM_PCD_MatchTableGetMissStatistics(h_HashBucket, p_MissStatistics);
33885 +}
33886 --- /dev/null
33887 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/fm_cc.h
33888 @@ -0,0 +1,399 @@
33889 +/*
33890 + * Copyright 2008-2012 Freescale Semiconductor Inc.
33891 + *
33892 + * Redistribution and use in source and binary forms, with or without
33893 + * modification, are permitted provided that the following conditions are met:
33894 + * * Redistributions of source code must retain the above copyright
33895 + * notice, this list of conditions and the following disclaimer.
33896 + * * Redistributions in binary form must reproduce the above copyright
33897 + * notice, this list of conditions and the following disclaimer in the
33898 + * documentation and/or other materials provided with the distribution.
33899 + * * Neither the name of Freescale Semiconductor nor the
33900 + * names of its contributors may be used to endorse or promote products
33901 + * derived from this software without specific prior written permission.
33902 + *
33903 + *
33904 + * ALTERNATIVELY, this software may be distributed under the terms of the
33905 + * GNU General Public License ("GPL") as published by the Free Software
33906 + * Foundation, either version 2 of that License or (at your option) any
33907 + * later version.
33908 + *
33909 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
33910 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
33911 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
33912 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
33913 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
33914 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
33915 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
33916 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
33917 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
33918 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33919 + */
33920 +
33921 +
33922 +/******************************************************************************
33923 + @File fm_cc.h
33924 +
33925 + @Description FM PCD CC ...
33926 +*//***************************************************************************/
33927 +#ifndef __FM_CC_H
33928 +#define __FM_CC_H
33929 +
33930 +#include "std_ext.h"
33931 +#include "error_ext.h"
33932 +#include "list_ext.h"
33933 +
33934 +#include "fm_pcd.h"
33935 +
33936 +
33937 +/***********************************************************************/
33938 +/* Coarse classification defines */
33939 +/***********************************************************************/
33940 +
33941 +#define CC_MAX_NUM_OF_KEYS (FM_PCD_MAX_NUM_OF_KEYS + 1)
33942 +
33943 +#define CC_PC_FF_MACDST 0x00
33944 +#define CC_PC_FF_MACSRC 0x01
33945 +#define CC_PC_FF_ETYPE 0x02
33946 +
33947 +#define CC_PC_FF_TCI1 0x03
33948 +#define CC_PC_FF_TCI2 0x04
33949 +
33950 +#define CC_PC_FF_MPLS1 0x06
33951 +#define CC_PC_FF_MPLS_LAST 0x07
33952 +
33953 +#define CC_PC_FF_IPV4DST1 0x08
33954 +#define CC_PC_FF_IPV4DST2 0x16
33955 +#define CC_PC_FF_IPV4IPTOS_TC1 0x09
33956 +#define CC_PC_FF_IPV4IPTOS_TC2 0x17
33957 +#define CC_PC_FF_IPV4PTYPE1 0x0A
33958 +#define CC_PC_FF_IPV4PTYPE2 0x18
33959 +#define CC_PC_FF_IPV4SRC1 0x0b
33960 +#define CC_PC_FF_IPV4SRC2 0x19
33961 +#define CC_PC_FF_IPV4SRC1_IPV4DST1 0x0c
33962 +#define CC_PC_FF_IPV4SRC2_IPV4DST2 0x1a
33963 +#define CC_PC_FF_IPV4TTL 0x29
33964 +
33965 +
33966 +#define CC_PC_FF_IPTOS_IPV6TC1_IPV6FLOW1 0x0d /*TODO - CLASS - what is it? TOS*/
33967 +#define CC_PC_FF_IPTOS_IPV6TC2_IPV6FLOW2 0x1b
33968 +#define CC_PC_FF_IPV6PTYPE1 0x0e
33969 +#define CC_PC_FF_IPV6PTYPE2 0x1c
33970 +#define CC_PC_FF_IPV6DST1 0x0f
33971 +#define CC_PC_FF_IPV6DST2 0x1d
33972 +#define CC_PC_FF_IPV6SRC1 0x10
33973 +#define CC_PC_FF_IPV6SRC2 0x1e
33974 +#define CC_PC_FF_IPV6HOP_LIMIT 0x2a
33975 +#define CC_PC_FF_IPPID 0x24
33976 +#define CC_PC_FF_IPDSCP 0x76
33977 +
33978 +#define CC_PC_FF_GREPTYPE 0x11
33979 +
33980 +#define CC_PC_FF_MINENCAP_PTYPE 0x12
33981 +#define CC_PC_FF_MINENCAP_IPDST 0x13
33982 +#define CC_PC_FF_MINENCAP_IPSRC 0x14
33983 +#define CC_PC_FF_MINENCAP_IPSRC_IPDST 0x15
33984 +
33985 +#define CC_PC_FF_L4PSRC 0x1f
33986 +#define CC_PC_FF_L4PDST 0x20
33987 +#define CC_PC_FF_L4PSRC_L4PDST 0x21
33988 +
33989 +#define CC_PC_FF_PPPPID 0x05
33990 +
33991 +#define CC_PC_PR_SHIM1 0x22
33992 +#define CC_PC_PR_SHIM2 0x23
33993 +
33994 +#define CC_PC_GENERIC_WITHOUT_MASK 0x27
33995 +#define CC_PC_GENERIC_WITH_MASK 0x28
33996 +#define CC_PC_GENERIC_IC_GMASK 0x2B
33997 +#define CC_PC_GENERIC_IC_HASH_INDEXED 0x2C
33998 +#define CC_PC_GENERIC_IC_AGING_MASK 0x2D
33999 +
34000 +#define CC_PR_OFFSET 0x25
34001 +#define CC_PR_WITHOUT_OFFSET 0x26
34002 +
34003 +#define CC_PC_PR_ETH_OFFSET 19
34004 +#define CC_PC_PR_USER_DEFINED_SHIM1_OFFSET 16
34005 +#define CC_PC_PR_USER_DEFINED_SHIM2_OFFSET 17
34006 +#define CC_PC_PR_USER_LLC_SNAP_OFFSET 20
34007 +#define CC_PC_PR_VLAN1_OFFSET 21
34008 +#define CC_PC_PR_VLAN2_OFFSET 22
34009 +#define CC_PC_PR_PPPOE_OFFSET 24
34010 +#define CC_PC_PR_MPLS1_OFFSET 25
34011 +#define CC_PC_PR_MPLS_LAST_OFFSET 26
34012 +#define CC_PC_PR_IP1_OFFSET 27
34013 +#define CC_PC_PR_IP_LAST_OFFSET 28
34014 +#define CC_PC_PR_MINENC_OFFSET 28
34015 +#define CC_PC_PR_L4_OFFSET 30
34016 +#define CC_PC_PR_GRE_OFFSET 29
34017 +#define CC_PC_PR_ETYPE_LAST_OFFSET 23
34018 +#define CC_PC_PR_NEXT_HEADER_OFFSET 31
34019 +
34020 +#define CC_PC_ILLEGAL 0xff
34021 +#define CC_SIZE_ILLEGAL 0
34022 +
34023 +#define FM_PCD_CC_KEYS_MATCH_TABLE_ALIGN 16
34024 +#define FM_PCD_CC_AD_TABLE_ALIGN 16
34025 +#define FM_PCD_CC_AD_ENTRY_SIZE 16
34026 +#define FM_PCD_CC_NUM_OF_KEYS 255
34027 +#define FM_PCD_CC_TREE_ADDR_ALIGN 256
34028 +
34029 +#define FM_PCD_AD_RESULT_CONTRL_FLOW_TYPE 0x00000000
34030 +#define FM_PCD_AD_RESULT_DATA_FLOW_TYPE 0x80000000
34031 +#define FM_PCD_AD_RESULT_PLCR_DIS 0x20000000
34032 +#define FM_PCD_AD_RESULT_EXTENDED_MODE 0x80000000
34033 +#define FM_PCD_AD_RESULT_NADEN 0x20000000
34034 +#define FM_PCD_AD_RESULT_STATISTICS_EN 0x40000000
34035 +
34036 +#define FM_PCD_AD_CONT_LOOKUP_TYPE 0x40000000
34037 +#define FM_PCD_AD_CONT_LOOKUP_LCL_MASK 0x00800000
34038 +
34039 +#define FM_PCD_AD_STATS_TYPE 0x40000000
34040 +#define FM_PCD_AD_STATS_FLR_ADDR_MASK 0x00FFFFFF
34041 +#define FM_PCD_AD_STATS_COUNTERS_ADDR_MASK 0x00FFFFFF
34042 +#define FM_PCD_AD_STATS_NEXT_ACTION_MASK 0xFFFF0000
34043 +#define FM_PCD_AD_STATS_NEXT_ACTION_SHIFT 12
34044 +#define FM_PCD_AD_STATS_NAD_EN 0x00008000
34045 +#define FM_PCD_AD_STATS_OP_CODE 0x00000036
34046 +#define FM_PCD_AD_STATS_FLR_EN 0x00004000
34047 +#define FM_PCD_AD_STATS_COND_EN 0x00002000
34048 +
34049 +
34050 +
34051 +#define FM_PCD_AD_BYPASS_TYPE 0xc0000000
34052 +
34053 +#define FM_PCD_AD_TYPE_MASK 0xc0000000
34054 +#define FM_PCD_AD_OPCODE_MASK 0x0000000f
34055 +
34056 +#define FM_PCD_AD_PROFILEID_FOR_CNTRL_SHIFT 16
34057 +#if (DPAA_VERSION >= 11)
34058 +#define FM_PCD_AD_RESULT_VSP_SHIFT 24
34059 +#define FM_PCD_AD_RESULT_NO_OM_VSPE 0x02000000
34060 +#define FM_PCD_AD_RESULT_VSP_MASK 0x3f
34061 +#define FM_PCD_AD_NCSPFQIDM_MASK 0x80000000
34062 +#endif /* (DPAA_VERSION >= 11) */
34063 +
34064 +#define GLBL_MASK_FOR_HASH_INDEXED 0xfff00000
34065 +#define CC_GLBL_MASK_SIZE 4
34066 +#define CC_AGING_MASK_SIZE 4
34067 +
34068 +typedef uint32_t ccPrivateInfo_t; /**< private info of CC: */
34069 +
34070 +#define CC_PRIVATE_INFO_NONE 0
34071 +#define CC_PRIVATE_INFO_IC_HASH_INDEX_LOOKUP 0x80000000
34072 +#define CC_PRIVATE_INFO_IC_HASH_EXACT_MATCH 0x40000000
34073 +#define CC_PRIVATE_INFO_IC_KEY_EXACT_MATCH 0x20000000
34074 +#define CC_PRIVATE_INFO_IC_DEQ_FQID_INDEX_LOOKUP 0x10000000
34075 +
34076 +#define CC_BUILD_AGING_MASK(numOfKeys) ((((1LL << ((numOfKeys) + 1)) - 1)) << (31 - (numOfKeys)))
34077 +/***********************************************************************/
34078 +/* Memory map */
34079 +/***********************************************************************/
34080 +#if defined(__MWERKS__) && !defined(__GNUC__)
34081 +#pragma pack(push,1)
34082 +#endif /* defined(__MWERKS__) && ... */
34083 +
34084 +typedef struct
34085 +{
34086 + volatile uint32_t fqid;
34087 + volatile uint32_t plcrProfile;
34088 + volatile uint32_t nia;
34089 + volatile uint32_t res;
34090 +} t_AdOfTypeResult;
34091 +
34092 +typedef struct
34093 +{
34094 + volatile uint32_t ccAdBase;
34095 + volatile uint32_t matchTblPtr;
34096 + volatile uint32_t pcAndOffsets;
34097 + volatile uint32_t gmask;
34098 +} t_AdOfTypeContLookup;
34099 +
34100 +typedef struct
34101 +{
34102 + volatile uint32_t profileTableAddr;
34103 + volatile uint32_t reserved;
34104 + volatile uint32_t nextActionIndx;
34105 + volatile uint32_t statsTableAddr;
34106 +} t_AdOfTypeStats;
34107 +
34108 +typedef union
34109 +{
34110 + volatile t_AdOfTypeResult adResult;
34111 + volatile t_AdOfTypeContLookup adContLookup;
34112 +} t_Ad;
34113 +
34114 +#if defined(__MWERKS__) && !defined(__GNUC__)
34115 +#pragma pack(pop)
34116 +#endif /* defined(__MWERKS__) && ... */
34117 +
34118 +
34119 +/***********************************************************************/
34120 +/* Driver's internal structures */
34121 +/***********************************************************************/
34122 +
34123 +typedef struct t_FmPcdStatsObj
34124 +{
34125 + t_Handle h_StatsAd;
34126 + t_Handle h_StatsCounters;
34127 + t_List node;
34128 +} t_FmPcdStatsObj;
34129 +
34130 +typedef struct
34131 +{
34132 + uint8_t key[FM_PCD_MAX_SIZE_OF_KEY];
34133 + uint8_t mask[FM_PCD_MAX_SIZE_OF_KEY];
34134 +
34135 + t_FmPcdCcNextEngineParams nextEngineParams;
34136 + uint32_t requiredAction;
34137 + uint32_t shadowAction;
34138 +
34139 + t_FmPcdStatsObj *p_StatsObj;
34140 +
34141 +} t_FmPcdCcKeyAndNextEngineParams;
34142 +
34143 +typedef struct
34144 +{
34145 + t_Handle p_Ad;
34146 + e_FmPcdEngine fmPcdEngine;
34147 + bool adAllocated;
34148 + bool isTree;
34149 +
34150 + uint32_t myInfo;
34151 + t_List *h_CcNextNodesLst;
34152 + t_Handle h_AdditionalInfo;
34153 + t_Handle h_Node;
34154 +} t_FmPcdModifyCcAdditionalParams;
34155 +
34156 +typedef struct
34157 +{
34158 + t_Handle p_AdTableNew;
34159 + t_Handle p_KeysMatchTableNew;
34160 + t_Handle p_AdTableOld;
34161 + t_Handle p_KeysMatchTableOld;
34162 + uint16_t numOfKeys;
34163 + t_Handle h_CurrentNode;
34164 + uint16_t savedKeyIndex;
34165 + t_Handle h_NodeForAdd;
34166 + t_Handle h_NodeForRmv;
34167 + t_Handle h_ManipForRmv;
34168 + t_Handle h_ManipForAdd;
34169 + t_FmPcdStatsObj *p_StatsObjForRmv;
34170 +#if (DPAA_VERSION >= 11)
34171 + t_Handle h_FrmReplicForAdd;
34172 + t_Handle h_FrmReplicForRmv;
34173 +#endif /* (DPAA_VERSION >= 11) */
34174 + bool tree;
34175 +
34176 + t_FmPcdCcKeyAndNextEngineParams keyAndNextEngineParams[CC_MAX_NUM_OF_KEYS];
34177 +} t_FmPcdModifyCcKeyAdditionalParams;
34178 +
34179 +typedef struct
34180 +{
34181 + t_Handle h_Manip;
34182 + t_Handle h_CcNode;
34183 +} t_CcNextEngineInfo;
34184 +
34185 +typedef struct
34186 +{
34187 + uint16_t numOfKeys;
34188 + uint16_t maxNumOfKeys;
34189 +
34190 + bool maskSupport;
34191 + uint32_t keysMatchTableMaxSize;
34192 +
34193 + e_FmPcdCcStatsMode statisticsMode;
34194 + uint32_t numOfStatsFLRs;
34195 + uint32_t countersArraySize;
34196 +
34197 + bool isHashBucket; /**< Valid for match table node that is a bucket of a hash table only */
34198 + t_Handle h_MissStatsCounters; /**< Valid for hash table node and match table that is a bucket;
34199 + Holds the statistics counters allocated by the hash table and
34200 + are shared by all hash table buckets; */
34201 + t_Handle h_PrivMissStatsCounters; /**< Valid for match table node that is a bucket of a hash table only;
34202 + Holds the statistics counters that were allocated for this node
34203 + and replaced by the shared counters (allocated by the hash table); */
34204 + bool statsEnForMiss; /**< Valid for hash table node only; TRUE is statistics are currently
34205 + enabled for hash 'miss', FALSE otherwise; This parameter effects the
34206 + returned statistics count to user, statistics AD always present for 'miss'
34207 + for all hash buckets; */
34208 + bool glblMaskUpdated;
34209 + t_Handle p_GlblMask;
34210 + bool lclMask;
34211 + uint8_t parseCode;
34212 + uint8_t offset;
34213 + uint8_t prsArrayOffset;
34214 + bool ctrlFlow;
34215 + uint16_t owners;
34216 +
34217 + uint8_t ccKeySizeAccExtraction;
34218 + uint8_t sizeOfExtraction;
34219 + uint8_t glblMaskSize;
34220 +
34221 + t_Handle h_KeysMatchTable;
34222 + t_Handle h_AdTable;
34223 + t_Handle h_StatsAds;
34224 + t_Handle h_TmpAd;
34225 + t_Handle h_Ad;
34226 + t_Handle h_StatsFLRs;
34227 +
34228 + t_List availableStatsLst;
34229 +
34230 + t_List ccPrevNodesLst;
34231 +
34232 + t_List ccTreeIdLst;
34233 + t_List ccTreesLst;
34234 +
34235 + t_Handle h_FmPcd;
34236 + uint32_t shadowAction;
34237 + uint8_t userSizeOfExtraction;
34238 + uint8_t userOffset;
34239 + uint8_t kgHashShift; /* used in hash-table */
34240 +
34241 + t_Handle h_Spinlock;
34242 +
34243 + t_FmPcdCcKeyAndNextEngineParams keyAndNextEngineParams[CC_MAX_NUM_OF_KEYS];
34244 +} t_FmPcdCcNode;
34245 +
34246 +typedef struct
34247 +{
34248 + t_FmPcdCcNode *p_FmPcdCcNode;
34249 + bool occupied;
34250 + uint16_t owners;
34251 + volatile bool lock;
34252 +} t_FmPcdCcNodeArray;
34253 +
34254 +typedef struct
34255 +{
34256 + uint8_t numOfEntriesInGroup;
34257 + uint32_t totalBitsMask;
34258 + uint8_t baseGroupEntry;
34259 +} t_FmPcdCcGroupParam;
34260 +
34261 +typedef struct
34262 +{
34263 + t_Handle h_FmPcd;
34264 + uint8_t netEnvId;
34265 + uintptr_t ccTreeBaseAddr;
34266 + uint8_t numOfGrps;
34267 + t_FmPcdCcGroupParam fmPcdGroupParam[FM_PCD_MAX_NUM_OF_CC_GROUPS];
34268 + t_List fmPortsLst;
34269 + t_FmPcdLock *p_Lock;
34270 + uint8_t numOfEntries;
34271 + uint16_t owners;
34272 + t_Handle h_FmPcdCcSavedManipParams;
34273 + bool modifiedState;
34274 + uint32_t requiredAction;
34275 + t_Handle h_IpReassemblyManip;
34276 + t_Handle h_CapwapReassemblyManip;
34277 +
34278 + t_FmPcdCcKeyAndNextEngineParams keyAndNextEngineParams[FM_PCD_MAX_NUM_OF_CC_GROUPS];
34279 +} t_FmPcdCcTree;
34280 +
34281 +
34282 +t_Error FmPcdCcNodeTreeTryLock(t_Handle h_FmPcd,t_Handle h_FmPcdCcNode, t_List *p_List);
34283 +void FmPcdCcNodeTreeReleaseLock(t_Handle h_FmPcd, t_List *p_List);
34284 +t_Error FmPcdUpdateCcShadow (t_FmPcd *p_FmPcd, uint32_t size, uint32_t align);
34285 +
34286 +
34287 +#endif /* __FM_CC_H */
34288 --- /dev/null
34289 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/fm_kg.c
34290 @@ -0,0 +1,3242 @@
34291 +/*
34292 + * Copyright 2008-2012 Freescale Semiconductor Inc.
34293 + *
34294 + * Redistribution and use in source and binary forms, with or without
34295 + * modification, are permitted provided that the following conditions are met:
34296 + * * Redistributions of source code must retain the above copyright
34297 + * notice, this list of conditions and the following disclaimer.
34298 + * * Redistributions in binary form must reproduce the above copyright
34299 + * notice, this list of conditions and the following disclaimer in the
34300 + * documentation and/or other materials provided with the distribution.
34301 + * * Neither the name of Freescale Semiconductor nor the
34302 + * names of its contributors may be used to endorse or promote products
34303 + * derived from this software without specific prior written permission.
34304 + *
34305 + *
34306 + * ALTERNATIVELY, this software may be distributed under the terms of the
34307 + * GNU General Public License ("GPL") as published by the Free Software
34308 + * Foundation, either version 2 of that License or (at your option) any
34309 + * later version.
34310 + *
34311 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
34312 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
34313 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
34314 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
34315 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
34316 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
34317 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
34318 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
34319 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
34320 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34321 + */
34322 +
34323 +
34324 +/******************************************************************************
34325 + @File fm_kg.c
34326 +
34327 + @Description FM PCD ...
34328 +*//***************************************************************************/
34329 +#include "std_ext.h"
34330 +#include "error_ext.h"
34331 +#include "string_ext.h"
34332 +#include "debug_ext.h"
34333 +#include "net_ext.h"
34334 +#include "fm_port_ext.h"
34335 +
34336 +#include "fm_common.h"
34337 +#include "fm_pcd.h"
34338 +#include "fm_hc.h"
34339 +#include "fm_pcd_ipc.h"
34340 +#include "fm_kg.h"
34341 +#include "fsl_fman_kg.h"
34342 +
34343 +
34344 +/****************************************/
34345 +/* static functions */
34346 +/****************************************/
34347 +
34348 +static uint32_t KgHwLock(t_Handle h_FmPcdKg)
34349 +{
34350 + ASSERT_COND(h_FmPcdKg);
34351 + return XX_LockIntrSpinlock(((t_FmPcdKg *)h_FmPcdKg)->h_HwSpinlock);
34352 +}
34353 +
34354 +static void KgHwUnlock(t_Handle h_FmPcdKg, uint32_t intFlags)
34355 +{
34356 + ASSERT_COND(h_FmPcdKg);
34357 + XX_UnlockIntrSpinlock(((t_FmPcdKg *)h_FmPcdKg)->h_HwSpinlock, intFlags);
34358 +}
34359 +
34360 +static uint32_t KgSchemeLock(t_Handle h_Scheme)
34361 +{
34362 + ASSERT_COND(h_Scheme);
34363 + return FmPcdLockSpinlock(((t_FmPcdKgScheme *)h_Scheme)->p_Lock);
34364 +}
34365 +
34366 +static void KgSchemeUnlock(t_Handle h_Scheme, uint32_t intFlags)
34367 +{
34368 + ASSERT_COND(h_Scheme);
34369 + FmPcdUnlockSpinlock(((t_FmPcdKgScheme *)h_Scheme)->p_Lock, intFlags);
34370 +}
34371 +
34372 +static bool KgSchemeFlagTryLock(t_Handle h_Scheme)
34373 +{
34374 + ASSERT_COND(h_Scheme);
34375 + return FmPcdLockTryLock(((t_FmPcdKgScheme *)h_Scheme)->p_Lock);
34376 +}
34377 +
34378 +static void KgSchemeFlagUnlock(t_Handle h_Scheme)
34379 +{
34380 + ASSERT_COND(h_Scheme);
34381 + FmPcdLockUnlock(((t_FmPcdKgScheme *)h_Scheme)->p_Lock);
34382 +}
34383 +
34384 +static t_Error WriteKgarWait(t_FmPcd *p_FmPcd, uint32_t fmkg_ar)
34385 +{
34386 +
34387 + struct fman_kg_regs *regs = p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs;
34388 +
34389 + if (fman_kg_write_ar_wait(regs, fmkg_ar))
34390 + RETURN_ERROR(MINOR, E_INVALID_STATE, ("Keygen scheme access violation"));
34391 +
34392 + return E_OK;
34393 +}
34394 +
34395 +static e_FmPcdKgExtractDfltSelect GetGenericSwDefault(t_FmPcdKgExtractDflt swDefaults[], uint8_t numOfSwDefaults, uint8_t code)
34396 +{
34397 + int i;
34398 +
34399 + switch (code)
34400 + {
34401 + case (KG_SCH_GEN_PARSE_RESULT_N_FQID):
34402 + case (KG_SCH_GEN_DEFAULT):
34403 + case (KG_SCH_GEN_NEXTHDR):
34404 + for (i=0 ; i<numOfSwDefaults ; i++)
34405 + if (swDefaults[i].type == e_FM_PCD_KG_GENERIC_NOT_FROM_DATA)
34406 + return swDefaults[i].dfltSelect;
34407 + break;
34408 + case (KG_SCH_GEN_SHIM1):
34409 + case (KG_SCH_GEN_SHIM2):
34410 + case (KG_SCH_GEN_IP_PID_NO_V):
34411 + case (KG_SCH_GEN_ETH_NO_V):
34412 + case (KG_SCH_GEN_SNAP_NO_V):
34413 + case (KG_SCH_GEN_VLAN1_NO_V):
34414 + case (KG_SCH_GEN_VLAN2_NO_V):
34415 + case (KG_SCH_GEN_ETH_TYPE_NO_V):
34416 + case (KG_SCH_GEN_PPP_NO_V):
34417 + case (KG_SCH_GEN_MPLS1_NO_V):
34418 + case (KG_SCH_GEN_MPLS_LAST_NO_V):
34419 + case (KG_SCH_GEN_L3_NO_V):
34420 + case (KG_SCH_GEN_IP2_NO_V):
34421 + case (KG_SCH_GEN_GRE_NO_V):
34422 + case (KG_SCH_GEN_L4_NO_V):
34423 + for (i=0 ; i<numOfSwDefaults ; i++)
34424 + if (swDefaults[i].type == e_FM_PCD_KG_GENERIC_FROM_DATA_NO_V)
34425 + return swDefaults[i].dfltSelect;
34426 + break;
34427 + case (KG_SCH_GEN_START_OF_FRM):
34428 + case (KG_SCH_GEN_ETH):
34429 + case (KG_SCH_GEN_SNAP):
34430 + case (KG_SCH_GEN_VLAN1):
34431 + case (KG_SCH_GEN_VLAN2):
34432 + case (KG_SCH_GEN_ETH_TYPE):
34433 + case (KG_SCH_GEN_PPP):
34434 + case (KG_SCH_GEN_MPLS1):
34435 + case (KG_SCH_GEN_MPLS2):
34436 + case (KG_SCH_GEN_MPLS3):
34437 + case (KG_SCH_GEN_MPLS_LAST):
34438 + case (KG_SCH_GEN_IPV4):
34439 + case (KG_SCH_GEN_IPV6):
34440 + case (KG_SCH_GEN_IPV4_TUNNELED):
34441 + case (KG_SCH_GEN_IPV6_TUNNELED):
34442 + case (KG_SCH_GEN_MIN_ENCAP):
34443 + case (KG_SCH_GEN_GRE):
34444 + case (KG_SCH_GEN_TCP):
34445 + case (KG_SCH_GEN_UDP):
34446 + case (KG_SCH_GEN_IPSEC_AH):
34447 + case (KG_SCH_GEN_SCTP):
34448 + case (KG_SCH_GEN_DCCP):
34449 + case (KG_SCH_GEN_IPSEC_ESP):
34450 + for (i=0 ; i<numOfSwDefaults ; i++)
34451 + if (swDefaults[i].type == e_FM_PCD_KG_GENERIC_FROM_DATA)
34452 + return swDefaults[i].dfltSelect;
34453 + break;
34454 + default:
34455 + break;
34456 + }
34457 +
34458 + return e_FM_PCD_KG_DFLT_ILLEGAL;
34459 +}
34460 +
34461 +static uint8_t GetGenCode(e_FmPcdExtractFrom src, uint8_t *p_Offset)
34462 +{
34463 + *p_Offset = 0;
34464 +
34465 + switch (src)
34466 + {
34467 + case (e_FM_PCD_EXTRACT_FROM_FRAME_START):
34468 + return KG_SCH_GEN_START_OF_FRM;
34469 + case (e_FM_PCD_EXTRACT_FROM_DFLT_VALUE):
34470 + return KG_SCH_GEN_DEFAULT;
34471 + case (e_FM_PCD_EXTRACT_FROM_PARSE_RESULT):
34472 + return KG_SCH_GEN_PARSE_RESULT_N_FQID;
34473 + case (e_FM_PCD_EXTRACT_FROM_ENQ_FQID):
34474 + *p_Offset = 32;
34475 + return KG_SCH_GEN_PARSE_RESULT_N_FQID;
34476 + case (e_FM_PCD_EXTRACT_FROM_CURR_END_OF_PARSE):
34477 + return KG_SCH_GEN_NEXTHDR;
34478 + default:
34479 + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("Illegal 'extract from' src"));
34480 + return 0;
34481 + }
34482 +}
34483 +
34484 +static uint8_t GetGenHdrCode(e_NetHeaderType hdr, e_FmPcdHdrIndex hdrIndex, bool ignoreProtocolValidation)
34485 +{
34486 + if (!ignoreProtocolValidation)
34487 + switch (hdr)
34488 + {
34489 + case (HEADER_TYPE_NONE):
34490 + ASSERT_COND(FALSE);
34491 + case (HEADER_TYPE_ETH):
34492 + return KG_SCH_GEN_ETH;
34493 + case (HEADER_TYPE_LLC_SNAP):
34494 + return KG_SCH_GEN_SNAP;
34495 + case (HEADER_TYPE_PPPoE):
34496 + return KG_SCH_GEN_PPP;
34497 + case (HEADER_TYPE_MPLS):
34498 + if ((hdrIndex == e_FM_PCD_HDR_INDEX_NONE) || (hdrIndex == e_FM_PCD_HDR_INDEX_1))
34499 + return KG_SCH_GEN_MPLS1;
34500 + if (hdrIndex == e_FM_PCD_HDR_INDEX_2)
34501 + return KG_SCH_GEN_MPLS2;
34502 + if (hdrIndex == e_FM_PCD_HDR_INDEX_3)
34503 + return KG_SCH_GEN_MPLS3;
34504 + if (hdrIndex == e_FM_PCD_HDR_INDEX_LAST)
34505 + return KG_SCH_GEN_MPLS_LAST;
34506 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal MPLS header index"));
34507 + return 0;
34508 + case (HEADER_TYPE_IPv4):
34509 + if ((hdrIndex == e_FM_PCD_HDR_INDEX_NONE) || (hdrIndex == e_FM_PCD_HDR_INDEX_1))
34510 + return KG_SCH_GEN_IPV4;
34511 + if ((hdrIndex == e_FM_PCD_HDR_INDEX_2) || (hdrIndex == e_FM_PCD_HDR_INDEX_LAST))
34512 + return KG_SCH_GEN_IPV4_TUNNELED;
34513 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal IPv4 header index"));
34514 + return 0;
34515 + case (HEADER_TYPE_IPv6):
34516 + if ((hdrIndex == e_FM_PCD_HDR_INDEX_NONE) || (hdrIndex == e_FM_PCD_HDR_INDEX_1))
34517 + return KG_SCH_GEN_IPV6;
34518 + if ((hdrIndex == e_FM_PCD_HDR_INDEX_2) || (hdrIndex == e_FM_PCD_HDR_INDEX_LAST))
34519 + return KG_SCH_GEN_IPV6_TUNNELED;
34520 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal IPv6 header index"));
34521 + return 0;
34522 + case (HEADER_TYPE_GRE):
34523 + return KG_SCH_GEN_GRE;
34524 + case (HEADER_TYPE_TCP):
34525 + return KG_SCH_GEN_TCP;
34526 + case (HEADER_TYPE_UDP):
34527 + return KG_SCH_GEN_UDP;
34528 + case (HEADER_TYPE_IPSEC_AH):
34529 + return KG_SCH_GEN_IPSEC_AH;
34530 + case (HEADER_TYPE_IPSEC_ESP):
34531 + return KG_SCH_GEN_IPSEC_ESP;
34532 + case (HEADER_TYPE_SCTP):
34533 + return KG_SCH_GEN_SCTP;
34534 + case (HEADER_TYPE_DCCP):
34535 + return KG_SCH_GEN_DCCP;
34536 + default:
34537 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
34538 + return 0;
34539 + }
34540 + else
34541 + switch (hdr)
34542 + {
34543 + case (HEADER_TYPE_NONE):
34544 + ASSERT_COND(FALSE);
34545 + case (HEADER_TYPE_ETH):
34546 + return KG_SCH_GEN_ETH_NO_V;
34547 + case (HEADER_TYPE_LLC_SNAP):
34548 + return KG_SCH_GEN_SNAP_NO_V;
34549 + case (HEADER_TYPE_PPPoE):
34550 + return KG_SCH_GEN_PPP_NO_V;
34551 + case (HEADER_TYPE_MPLS):
34552 + if ((hdrIndex == e_FM_PCD_HDR_INDEX_NONE) || (hdrIndex == e_FM_PCD_HDR_INDEX_1))
34553 + return KG_SCH_GEN_MPLS1_NO_V;
34554 + if (hdrIndex == e_FM_PCD_HDR_INDEX_LAST)
34555 + return KG_SCH_GEN_MPLS_LAST_NO_V;
34556 + if ((hdrIndex == e_FM_PCD_HDR_INDEX_2) || (hdrIndex == e_FM_PCD_HDR_INDEX_3) )
34557 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Indexed MPLS Extraction not supported"));
34558 + else
34559 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal MPLS header index"));
34560 + return 0;
34561 + case (HEADER_TYPE_IPv4):
34562 + case (HEADER_TYPE_IPv6):
34563 + if ((hdrIndex == e_FM_PCD_HDR_INDEX_NONE) || (hdrIndex == e_FM_PCD_HDR_INDEX_1))
34564 + return KG_SCH_GEN_L3_NO_V;
34565 + if ((hdrIndex == e_FM_PCD_HDR_INDEX_2) || (hdrIndex == e_FM_PCD_HDR_INDEX_LAST))
34566 + return KG_SCH_GEN_IP2_NO_V;
34567 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal IP header index"));
34568 + case (HEADER_TYPE_MINENCAP):
34569 + return KG_SCH_GEN_IP2_NO_V;
34570 + case (HEADER_TYPE_USER_DEFINED_L3):
34571 + return KG_SCH_GEN_L3_NO_V;
34572 + case (HEADER_TYPE_GRE):
34573 + return KG_SCH_GEN_GRE_NO_V;
34574 + case (HEADER_TYPE_TCP):
34575 + case (HEADER_TYPE_UDP):
34576 + case (HEADER_TYPE_IPSEC_AH):
34577 + case (HEADER_TYPE_IPSEC_ESP):
34578 + case (HEADER_TYPE_SCTP):
34579 + case (HEADER_TYPE_DCCP):
34580 + return KG_SCH_GEN_L4_NO_V;
34581 + case (HEADER_TYPE_USER_DEFINED_SHIM1):
34582 + return KG_SCH_GEN_SHIM1;
34583 + case (HEADER_TYPE_USER_DEFINED_SHIM2):
34584 + return KG_SCH_GEN_SHIM2;
34585 + default:
34586 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
34587 + return 0;
34588 + }
34589 +}
34590 +static t_GenericCodes GetGenFieldCode(e_NetHeaderType hdr, t_FmPcdFields field, bool ignoreProtocolValidation, e_FmPcdHdrIndex hdrIndex)
34591 +{
34592 + if (!ignoreProtocolValidation)
34593 + switch (hdr)
34594 + {
34595 + case (HEADER_TYPE_NONE):
34596 + ASSERT_COND(FALSE);
34597 + break;
34598 + case (HEADER_TYPE_ETH):
34599 + switch (field.eth)
34600 + {
34601 + case (NET_HEADER_FIELD_ETH_TYPE):
34602 + return KG_SCH_GEN_ETH_TYPE;
34603 + default:
34604 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
34605 + return 0;
34606 + }
34607 + break;
34608 + case (HEADER_TYPE_VLAN):
34609 + switch (field.vlan)
34610 + {
34611 + case (NET_HEADER_FIELD_VLAN_TCI):
34612 + if ((hdrIndex == e_FM_PCD_HDR_INDEX_NONE) || (hdrIndex == e_FM_PCD_HDR_INDEX_1))
34613 + return KG_SCH_GEN_VLAN1;
34614 + if (hdrIndex == e_FM_PCD_HDR_INDEX_LAST)
34615 + return KG_SCH_GEN_VLAN2;
34616 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal VLAN header index"));
34617 + return 0;
34618 + }
34619 + break;
34620 + case (HEADER_TYPE_MPLS):
34621 + case (HEADER_TYPE_IPSEC_AH):
34622 + case (HEADER_TYPE_IPSEC_ESP):
34623 + case (HEADER_TYPE_LLC_SNAP):
34624 + case (HEADER_TYPE_PPPoE):
34625 + case (HEADER_TYPE_IPv4):
34626 + case (HEADER_TYPE_IPv6):
34627 + case (HEADER_TYPE_GRE):
34628 + case (HEADER_TYPE_MINENCAP):
34629 + case (HEADER_TYPE_USER_DEFINED_L3):
34630 + case (HEADER_TYPE_TCP):
34631 + case (HEADER_TYPE_UDP):
34632 + case (HEADER_TYPE_SCTP):
34633 + case (HEADER_TYPE_DCCP):
34634 + case (HEADER_TYPE_USER_DEFINED_L4):
34635 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
34636 + return 0;
34637 + default:
34638 + break;
34639 +
34640 + }
34641 + else
34642 + switch (hdr)
34643 + {
34644 + case (HEADER_TYPE_NONE):
34645 + ASSERT_COND(FALSE);
34646 + break;
34647 + case (HEADER_TYPE_ETH):
34648 + switch (field.eth)
34649 + {
34650 + case (NET_HEADER_FIELD_ETH_TYPE):
34651 + return KG_SCH_GEN_ETH_TYPE_NO_V;
34652 + default:
34653 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
34654 + return 0;
34655 + }
34656 + break;
34657 + case (HEADER_TYPE_VLAN):
34658 + switch (field.vlan)
34659 + {
34660 + case (NET_HEADER_FIELD_VLAN_TCI) :
34661 + if ((hdrIndex == e_FM_PCD_HDR_INDEX_NONE) || (hdrIndex == e_FM_PCD_HDR_INDEX_1))
34662 + return KG_SCH_GEN_VLAN1_NO_V;
34663 + if (hdrIndex == e_FM_PCD_HDR_INDEX_LAST)
34664 + return KG_SCH_GEN_VLAN2_NO_V;
34665 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal VLAN header index"));
34666 + return 0;
34667 + }
34668 + break;
34669 + case (HEADER_TYPE_IPv4):
34670 + switch (field.ipv4)
34671 + {
34672 + case (NET_HEADER_FIELD_IPv4_PROTO):
34673 + return KG_SCH_GEN_IP_PID_NO_V;
34674 + default:
34675 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
34676 + return 0;
34677 + }
34678 + break;
34679 + case (HEADER_TYPE_IPv6):
34680 + switch (field.ipv6)
34681 + {
34682 + case (NET_HEADER_FIELD_IPv6_NEXT_HDR):
34683 + return KG_SCH_GEN_IP_PID_NO_V;
34684 + default:
34685 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
34686 + return 0;
34687 + }
34688 + break;
34689 + case (HEADER_TYPE_MPLS):
34690 + case (HEADER_TYPE_LLC_SNAP):
34691 + case (HEADER_TYPE_PPPoE):
34692 + case (HEADER_TYPE_GRE):
34693 + case (HEADER_TYPE_MINENCAP):
34694 + case (HEADER_TYPE_USER_DEFINED_L3):
34695 + case (HEADER_TYPE_TCP):
34696 + case (HEADER_TYPE_UDP):
34697 + case (HEADER_TYPE_IPSEC_AH):
34698 + case (HEADER_TYPE_IPSEC_ESP):
34699 + case (HEADER_TYPE_SCTP):
34700 + case (HEADER_TYPE_DCCP):
34701 + case (HEADER_TYPE_USER_DEFINED_L4):
34702 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
34703 + return 0;
34704 + default:
34705 + break;
34706 + }
34707 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Header not supported"));
34708 + return 0;
34709 +}
34710 +
34711 +static t_KnownFieldsMasks GetKnownProtMask(t_FmPcd *p_FmPcd, e_NetHeaderType hdr, e_FmPcdHdrIndex index, t_FmPcdFields field)
34712 +{
34713 + UNUSED(p_FmPcd);
34714 +
34715 + switch (hdr)
34716 + {
34717 + case (HEADER_TYPE_NONE):
34718 + ASSERT_COND(FALSE);
34719 + break;
34720 + case (HEADER_TYPE_ETH):
34721 + switch (field.eth)
34722 + {
34723 + case (NET_HEADER_FIELD_ETH_DA):
34724 + return KG_SCH_KN_MACDST;
34725 + case (NET_HEADER_FIELD_ETH_SA):
34726 + return KG_SCH_KN_MACSRC;
34727 + case (NET_HEADER_FIELD_ETH_TYPE):
34728 + return KG_SCH_KN_ETYPE;
34729 + default:
34730 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
34731 + return 0;
34732 + }
34733 + case (HEADER_TYPE_LLC_SNAP):
34734 + switch (field.llcSnap)
34735 + {
34736 + case (NET_HEADER_FIELD_LLC_SNAP_TYPE):
34737 + return KG_SCH_KN_ETYPE;
34738 + default:
34739 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
34740 + return 0;
34741 + }
34742 + case (HEADER_TYPE_VLAN):
34743 + switch (field.vlan)
34744 + {
34745 + case (NET_HEADER_FIELD_VLAN_TCI):
34746 + if ((index == e_FM_PCD_HDR_INDEX_NONE) || (index == e_FM_PCD_HDR_INDEX_1))
34747 + return KG_SCH_KN_TCI1;
34748 + if (index == e_FM_PCD_HDR_INDEX_LAST)
34749 + return KG_SCH_KN_TCI2;
34750 + else
34751 + {
34752 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
34753 + return 0;
34754 + }
34755 + default:
34756 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
34757 + return 0;
34758 + }
34759 + case (HEADER_TYPE_MPLS):
34760 + switch (field.mpls)
34761 + {
34762 + case (NET_HEADER_FIELD_MPLS_LABEL_STACK):
34763 + if ((index == e_FM_PCD_HDR_INDEX_NONE) || (index == e_FM_PCD_HDR_INDEX_1))
34764 + return KG_SCH_KN_MPLS1;
34765 + if (index == e_FM_PCD_HDR_INDEX_2)
34766 + return KG_SCH_KN_MPLS2;
34767 + if (index == e_FM_PCD_HDR_INDEX_LAST)
34768 + return KG_SCH_KN_MPLS_LAST;
34769 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal MPLS index"));
34770 + return 0;
34771 + default:
34772 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
34773 + return 0;
34774 + }
34775 + case (HEADER_TYPE_IPv4):
34776 + switch (field.ipv4)
34777 + {
34778 + case (NET_HEADER_FIELD_IPv4_SRC_IP):
34779 + if ((index == e_FM_PCD_HDR_INDEX_NONE) || (index == e_FM_PCD_HDR_INDEX_1))
34780 + return KG_SCH_KN_IPSRC1;
34781 + if ((index == e_FM_PCD_HDR_INDEX_2) || (index == e_FM_PCD_HDR_INDEX_LAST))
34782 + return KG_SCH_KN_IPSRC2;
34783 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal IPv4 index"));
34784 + return 0;
34785 + case (NET_HEADER_FIELD_IPv4_DST_IP):
34786 + if ((index == e_FM_PCD_HDR_INDEX_NONE) || (index == e_FM_PCD_HDR_INDEX_1))
34787 + return KG_SCH_KN_IPDST1;
34788 + if ((index == e_FM_PCD_HDR_INDEX_2) || (index == e_FM_PCD_HDR_INDEX_LAST))
34789 + return KG_SCH_KN_IPDST2;
34790 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal IPv4 index"));
34791 + return 0;
34792 + case (NET_HEADER_FIELD_IPv4_PROTO):
34793 + if ((index == e_FM_PCD_HDR_INDEX_NONE) || (index == e_FM_PCD_HDR_INDEX_1))
34794 + return KG_SCH_KN_PTYPE1;
34795 + if ((index == e_FM_PCD_HDR_INDEX_2) || (index == e_FM_PCD_HDR_INDEX_LAST))
34796 + return KG_SCH_KN_PTYPE2;
34797 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal IPv4 index"));
34798 + return 0;
34799 + case (NET_HEADER_FIELD_IPv4_TOS):
34800 + if ((index == e_FM_PCD_HDR_INDEX_NONE) || (index == e_FM_PCD_HDR_INDEX_1))
34801 + return KG_SCH_KN_IPTOS_TC1;
34802 + if ((index == e_FM_PCD_HDR_INDEX_2) || (index == e_FM_PCD_HDR_INDEX_LAST))
34803 + return KG_SCH_KN_IPTOS_TC2;
34804 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal IPv4 index"));
34805 + return 0;
34806 + default:
34807 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
34808 + return 0;
34809 + }
34810 + case (HEADER_TYPE_IPv6):
34811 + switch (field.ipv6)
34812 + {
34813 + case (NET_HEADER_FIELD_IPv6_SRC_IP):
34814 + if ((index == e_FM_PCD_HDR_INDEX_NONE) || (index == e_FM_PCD_HDR_INDEX_1))
34815 + return KG_SCH_KN_IPSRC1;
34816 + if ((index == e_FM_PCD_HDR_INDEX_2) || (index == e_FM_PCD_HDR_INDEX_LAST))
34817 + return KG_SCH_KN_IPSRC2;
34818 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal IPv6 index"));
34819 + return 0;
34820 + case (NET_HEADER_FIELD_IPv6_DST_IP):
34821 + if ((index == e_FM_PCD_HDR_INDEX_NONE) || (index == e_FM_PCD_HDR_INDEX_1))
34822 + return KG_SCH_KN_IPDST1;
34823 + if ((index == e_FM_PCD_HDR_INDEX_2) || (index == e_FM_PCD_HDR_INDEX_LAST))
34824 + return KG_SCH_KN_IPDST2;
34825 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal IPv6 index"));
34826 + return 0;
34827 + case (NET_HEADER_FIELD_IPv6_NEXT_HDR):
34828 + if ((index == e_FM_PCD_HDR_INDEX_NONE) || (index == e_FM_PCD_HDR_INDEX_1))
34829 + return KG_SCH_KN_PTYPE1;
34830 + if (index == e_FM_PCD_HDR_INDEX_2)
34831 + return KG_SCH_KN_PTYPE2;
34832 + if (index == e_FM_PCD_HDR_INDEX_LAST)
34833 +#ifdef FM_KG_NO_IPPID_SUPPORT
34834 + if (p_FmPcd->fmRevInfo.majorRev < 6)
34835 + return KG_SCH_KN_PTYPE2;
34836 +#endif /* FM_KG_NO_IPPID_SUPPORT */
34837 + return KG_SCH_KN_IPPID;
34838 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal IPv6 index"));
34839 + return 0;
34840 + case (NET_HEADER_FIELD_IPv6_VER | NET_HEADER_FIELD_IPv6_FL | NET_HEADER_FIELD_IPv6_TC):
34841 + if ((index == e_FM_PCD_HDR_INDEX_NONE) || (index == e_FM_PCD_HDR_INDEX_1))
34842 + return (KG_SCH_KN_IPV6FL1 | KG_SCH_KN_IPTOS_TC1);
34843 + if ((index == e_FM_PCD_HDR_INDEX_2) || (index == e_FM_PCD_HDR_INDEX_LAST))
34844 + return (KG_SCH_KN_IPV6FL2 | KG_SCH_KN_IPTOS_TC2);
34845 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal IPv6 index"));
34846 + return 0;
34847 + case (NET_HEADER_FIELD_IPv6_VER | NET_HEADER_FIELD_IPv6_TC):
34848 + if ((index == e_FM_PCD_HDR_INDEX_NONE) || (index == e_FM_PCD_HDR_INDEX_1))
34849 + return KG_SCH_KN_IPTOS_TC1;
34850 + if ((index == e_FM_PCD_HDR_INDEX_2) || (index == e_FM_PCD_HDR_INDEX_LAST))
34851 + return KG_SCH_KN_IPTOS_TC2;
34852 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal IPv6 index"));
34853 + return 0;
34854 + case (NET_HEADER_FIELD_IPv6_FL):
34855 + if ((index == e_FM_PCD_HDR_INDEX_NONE) || (index == e_FM_PCD_HDR_INDEX_1))
34856 + return KG_SCH_KN_IPV6FL1;
34857 + if ((index == e_FM_PCD_HDR_INDEX_2) || (index == e_FM_PCD_HDR_INDEX_LAST))
34858 + return KG_SCH_KN_IPV6FL2;
34859 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal IPv6 index"));
34860 + return 0;
34861 + default:
34862 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
34863 + return 0;
34864 + }
34865 + case (HEADER_TYPE_GRE):
34866 + switch (field.gre)
34867 + {
34868 + case (NET_HEADER_FIELD_GRE_TYPE):
34869 + return KG_SCH_KN_GREPTYPE;
34870 + default:
34871 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
34872 + return 0;
34873 + }
34874 + case (HEADER_TYPE_MINENCAP):
34875 + switch (field.minencap)
34876 + {
34877 + case (NET_HEADER_FIELD_MINENCAP_SRC_IP):
34878 + return KG_SCH_KN_IPSRC2;
34879 + case (NET_HEADER_FIELD_MINENCAP_DST_IP):
34880 + return KG_SCH_KN_IPDST2;
34881 + case (NET_HEADER_FIELD_MINENCAP_TYPE):
34882 + return KG_SCH_KN_PTYPE2;
34883 + default:
34884 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
34885 + return 0;
34886 + }
34887 + case (HEADER_TYPE_TCP):
34888 + switch (field.tcp)
34889 + {
34890 + case (NET_HEADER_FIELD_TCP_PORT_SRC):
34891 + return KG_SCH_KN_L4PSRC;
34892 + case (NET_HEADER_FIELD_TCP_PORT_DST):
34893 + return KG_SCH_KN_L4PDST;
34894 + case (NET_HEADER_FIELD_TCP_FLAGS):
34895 + return KG_SCH_KN_TFLG;
34896 + default:
34897 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
34898 + return 0;
34899 + }
34900 + case (HEADER_TYPE_UDP):
34901 + switch (field.udp)
34902 + {
34903 + case (NET_HEADER_FIELD_UDP_PORT_SRC):
34904 + return KG_SCH_KN_L4PSRC;
34905 + case (NET_HEADER_FIELD_UDP_PORT_DST):
34906 + return KG_SCH_KN_L4PDST;
34907 + default:
34908 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
34909 + return 0;
34910 + }
34911 + case (HEADER_TYPE_IPSEC_AH):
34912 + switch (field.ipsecAh)
34913 + {
34914 + case (NET_HEADER_FIELD_IPSEC_AH_SPI):
34915 + return KG_SCH_KN_IPSEC_SPI;
34916 + case (NET_HEADER_FIELD_IPSEC_AH_NH):
34917 + return KG_SCH_KN_IPSEC_NH;
34918 + default:
34919 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
34920 + return 0;
34921 + }
34922 + case (HEADER_TYPE_IPSEC_ESP):
34923 + switch (field.ipsecEsp)
34924 + {
34925 + case (NET_HEADER_FIELD_IPSEC_ESP_SPI):
34926 + return KG_SCH_KN_IPSEC_SPI;
34927 + default:
34928 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
34929 + return 0;
34930 + }
34931 + case (HEADER_TYPE_SCTP):
34932 + switch (field.sctp)
34933 + {
34934 + case (NET_HEADER_FIELD_SCTP_PORT_SRC):
34935 + return KG_SCH_KN_L4PSRC;
34936 + case (NET_HEADER_FIELD_SCTP_PORT_DST):
34937 + return KG_SCH_KN_L4PDST;
34938 + default:
34939 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
34940 + return 0;
34941 + }
34942 + case (HEADER_TYPE_DCCP):
34943 + switch (field.dccp)
34944 + {
34945 + case (NET_HEADER_FIELD_DCCP_PORT_SRC):
34946 + return KG_SCH_KN_L4PSRC;
34947 + case (NET_HEADER_FIELD_DCCP_PORT_DST):
34948 + return KG_SCH_KN_L4PDST;
34949 + default:
34950 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
34951 + return 0;
34952 + }
34953 + case (HEADER_TYPE_PPPoE):
34954 + switch (field.pppoe)
34955 + {
34956 + case (NET_HEADER_FIELD_PPPoE_PID):
34957 + return KG_SCH_KN_PPPID;
34958 + case (NET_HEADER_FIELD_PPPoE_SID):
34959 + return KG_SCH_KN_PPPSID;
34960 + default:
34961 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
34962 + return 0;
34963 + }
34964 + default:
34965 + break;
34966 +
34967 + }
34968 +
34969 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
34970 + return 0;
34971 +}
34972 +
34973 +
34974 +static uint8_t GetKnownFieldId(uint32_t bitMask)
34975 +{
34976 + uint8_t cnt = 0;
34977 +
34978 + while (bitMask)
34979 + if (bitMask & 0x80000000)
34980 + break;
34981 + else
34982 + {
34983 + cnt++;
34984 + bitMask <<= 1;
34985 + }
34986 + return cnt;
34987 +
34988 +}
34989 +
34990 +static uint8_t GetExtractedOrMask(uint8_t bitOffset, bool fqid)
34991 +{
34992 + uint8_t i, mask, numOfOnesToClear, walking1Mask = 1;
34993 +
34994 + /* bitOffset 1-7 --> mask 0x1-0x7F */
34995 + if (bitOffset<8)
34996 + {
34997 + mask = 0;
34998 + for (i = 0 ; i < bitOffset ; i++, walking1Mask <<= 1)
34999 + mask |= walking1Mask;
35000 + }
35001 + else
35002 + {
35003 + mask = 0xFF;
35004 + numOfOnesToClear = 0;
35005 + if (fqid && bitOffset>24)
35006 + /* bitOffset 25-31 --> mask 0xFE-0x80 */
35007 + numOfOnesToClear = (uint8_t)(bitOffset-24);
35008 + else
35009 + /* bitOffset 9-15 --> mask 0xFE-0x80 */
35010 + if (!fqid && bitOffset>8)
35011 + numOfOnesToClear = (uint8_t)(bitOffset-8);
35012 + for (i = 0 ; i < numOfOnesToClear ; i++, walking1Mask <<= 1)
35013 + mask &= ~walking1Mask;
35014 + /* bitOffset 8-24 for FQID, 8 for PP --> no mask (0xFF)*/
35015 + }
35016 + return mask;
35017 +}
35018 +
35019 +static void IncSchemeOwners(t_FmPcd *p_FmPcd, t_FmPcdKgInterModuleBindPortToSchemes *p_BindPort)
35020 +{
35021 + t_FmPcdKg *p_FmPcdKg;
35022 + t_FmPcdKgScheme *p_Scheme;
35023 + uint32_t intFlags;
35024 + uint8_t relativeSchemeId;
35025 + int i;
35026 +
35027 + p_FmPcdKg = p_FmPcd->p_FmPcdKg;
35028 +
35029 + /* for each scheme - update owners counters */
35030 + for (i = 0; i < p_BindPort->numOfSchemes; i++)
35031 + {
35032 + relativeSchemeId = FmPcdKgGetRelativeSchemeId(p_FmPcd, p_BindPort->schemesIds[i]);
35033 + ASSERT_COND(relativeSchemeId < FM_PCD_KG_NUM_OF_SCHEMES);
35034 +
35035 + p_Scheme = &p_FmPcdKg->schemes[relativeSchemeId];
35036 +
35037 + /* increment owners number */
35038 + intFlags = KgSchemeLock(p_Scheme);
35039 + p_Scheme->owners++;
35040 + KgSchemeUnlock(p_Scheme, intFlags);
35041 + }
35042 +}
35043 +
35044 +static void DecSchemeOwners(t_FmPcd *p_FmPcd, t_FmPcdKgInterModuleBindPortToSchemes *p_BindPort)
35045 +{
35046 + t_FmPcdKg *p_FmPcdKg;
35047 + t_FmPcdKgScheme *p_Scheme;
35048 + uint32_t intFlags;
35049 + uint8_t relativeSchemeId;
35050 + int i;
35051 +
35052 + p_FmPcdKg = p_FmPcd->p_FmPcdKg;
35053 +
35054 + /* for each scheme - update owners counters */
35055 + for (i = 0; i < p_BindPort->numOfSchemes; i++)
35056 + {
35057 + relativeSchemeId = FmPcdKgGetRelativeSchemeId(p_FmPcd, p_BindPort->schemesIds[i]);
35058 + ASSERT_COND(relativeSchemeId < FM_PCD_KG_NUM_OF_SCHEMES);
35059 +
35060 + p_Scheme = &p_FmPcdKg->schemes[relativeSchemeId];
35061 +
35062 + /* increment owners number */
35063 + ASSERT_COND(p_Scheme->owners);
35064 + intFlags = KgSchemeLock(p_Scheme);
35065 + p_Scheme->owners--;
35066 + KgSchemeUnlock(p_Scheme, intFlags);
35067 + }
35068 +}
35069 +
35070 +static void UpdateRequiredActionFlag(t_FmPcdKgScheme *p_Scheme, bool set)
35071 +{
35072 + /* this routine is locked by the calling routine */
35073 + ASSERT_COND(p_Scheme);
35074 + ASSERT_COND(p_Scheme->valid);
35075 +
35076 + if (set)
35077 + p_Scheme->requiredActionFlag = TRUE;
35078 + else
35079 + {
35080 + p_Scheme->requiredAction = 0;
35081 + p_Scheme->requiredActionFlag = FALSE;
35082 + }
35083 +}
35084 +
35085 +static t_Error KgWriteSp(t_FmPcd *p_FmPcd, uint8_t hardwarePortId, uint32_t spReg, bool add)
35086 +{
35087 + struct fman_kg_regs *p_KgRegs;
35088 +
35089 + uint32_t tmpKgarReg = 0, intFlags;
35090 + t_Error err = E_OK;
35091 +
35092 + /* The calling routine had locked the port, so for each port only one core can access
35093 + * (so we don't need a lock here) */
35094 +
35095 + if (p_FmPcd->h_Hc)
35096 + return FmHcKgWriteSp(p_FmPcd->h_Hc, hardwarePortId, spReg, add);
35097 +
35098 + p_KgRegs = p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs;
35099 +
35100 + tmpKgarReg = FmPcdKgBuildReadPortSchemeBindActionReg(hardwarePortId);
35101 + /* lock a common KG reg */
35102 + intFlags = KgHwLock(p_FmPcd->p_FmPcdKg);
35103 + err = WriteKgarWait(p_FmPcd, tmpKgarReg);
35104 + if (err)
35105 + {
35106 + KgHwUnlock(p_FmPcd->p_FmPcdKg, intFlags);
35107 + RETURN_ERROR(MINOR, err, NO_MSG);
35108 + }
35109 +
35110 + fman_kg_write_sp(p_KgRegs, spReg, add);
35111 +
35112 + tmpKgarReg = FmPcdKgBuildWritePortSchemeBindActionReg(hardwarePortId);
35113 +
35114 + err = WriteKgarWait(p_FmPcd, tmpKgarReg);
35115 + KgHwUnlock(p_FmPcd->p_FmPcdKg, intFlags);
35116 + return err;
35117 +}
35118 +
35119 +static t_Error KgWriteCpp(t_FmPcd *p_FmPcd, uint8_t hardwarePortId, uint32_t cppReg)
35120 +{
35121 + struct fman_kg_regs *p_KgRegs;
35122 + uint32_t tmpKgarReg, intFlags;
35123 + t_Error err;
35124 +
35125 + p_KgRegs = p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs;
35126 +
35127 + if (p_FmPcd->h_Hc)
35128 + {
35129 + err = FmHcKgWriteCpp(p_FmPcd->h_Hc, hardwarePortId, cppReg);
35130 + return err;
35131 + }
35132 +
35133 + intFlags = KgHwLock(p_FmPcd->p_FmPcdKg);
35134 + fman_kg_write_cpp(p_KgRegs, cppReg);
35135 + tmpKgarReg = FmPcdKgBuildWritePortClsPlanBindActionReg(hardwarePortId);
35136 + err = WriteKgarWait(p_FmPcd, tmpKgarReg);
35137 + KgHwUnlock(p_FmPcd->p_FmPcdKg, intFlags);
35138 +
35139 + return err;
35140 +}
35141 +
35142 +static uint32_t BuildCppReg(t_FmPcd *p_FmPcd, uint8_t clsPlanGrpId)
35143 +{
35144 + uint32_t tmpKgpeCpp;
35145 +
35146 + tmpKgpeCpp = (uint32_t)(p_FmPcd->p_FmPcdKg->clsPlanGrps[clsPlanGrpId].baseEntry / 8);
35147 + tmpKgpeCpp |= (uint32_t)(((p_FmPcd->p_FmPcdKg->clsPlanGrps[clsPlanGrpId].sizeOfGrp / 8) - 1) << FM_KG_PE_CPP_MASK_SHIFT);
35148 +
35149 + return tmpKgpeCpp;
35150 +}
35151 +
35152 +static t_Error BindPortToClsPlanGrp(t_FmPcd *p_FmPcd, uint8_t hardwarePortId, uint8_t clsPlanGrpId)
35153 +{
35154 + uint32_t tmpKgpeCpp = 0;
35155 +
35156 + tmpKgpeCpp = BuildCppReg(p_FmPcd, clsPlanGrpId);
35157 + return KgWriteCpp(p_FmPcd, hardwarePortId, tmpKgpeCpp);
35158 +}
35159 +
35160 +static void UnbindPortToClsPlanGrp(t_FmPcd *p_FmPcd, uint8_t hardwarePortId)
35161 +{
35162 + KgWriteCpp(p_FmPcd, hardwarePortId, 0);
35163 +}
35164 +
35165 +#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
35166 +static uint32_t __attribute__((unused)) ReadClsPlanBlockActionReg(uint8_t grpId)
35167 +{
35168 + return (uint32_t)(FM_KG_KGAR_GO |
35169 + FM_KG_KGAR_READ |
35170 + FM_PCD_KG_KGAR_SEL_CLS_PLAN_ENTRY |
35171 + DUMMY_PORT_ID |
35172 + ((uint32_t)grpId << FM_PCD_KG_KGAR_NUM_SHIFT) |
35173 + FM_PCD_KG_KGAR_WSEL_MASK);
35174 +
35175 + /* if we ever want to write 1 by 1, use:
35176 + sel = (uint8_t)(0x01 << (7- (entryId % CLS_PLAN_NUM_PER_GRP)));
35177 + */
35178 +}
35179 +#endif /* (defined(DEBUG_ERRORS) && ... */
35180 +
35181 +static void PcdKgErrorException(t_Handle h_FmPcd)
35182 +{
35183 + t_FmPcd *p_FmPcd = (t_FmPcd *)h_FmPcd;
35184 + uint32_t event,schemeIndexes = 0, index = 0;
35185 + struct fman_kg_regs *p_KgRegs;
35186 +
35187 + ASSERT_COND(FmIsMaster(p_FmPcd->h_Fm));
35188 + p_KgRegs = p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs;
35189 + fman_kg_get_event(p_KgRegs, &event, &schemeIndexes);
35190 +
35191 + if (event & FM_EX_KG_DOUBLE_ECC)
35192 + p_FmPcd->f_Exception(p_FmPcd->h_App,e_FM_PCD_KG_EXCEPTION_DOUBLE_ECC);
35193 + if (event & FM_EX_KG_KEYSIZE_OVERFLOW)
35194 + {
35195 + if (schemeIndexes)
35196 + {
35197 + while (schemeIndexes)
35198 + {
35199 + if (schemeIndexes & 0x1)
35200 + p_FmPcd->f_FmPcdIndexedException(p_FmPcd->h_App,e_FM_PCD_KG_EXCEPTION_KEYSIZE_OVERFLOW, (uint16_t)(31 - index));
35201 + schemeIndexes >>= 1;
35202 + index+=1;
35203 + }
35204 + }
35205 + else /* this should happen only when interrupt is forced. */
35206 + p_FmPcd->f_Exception(p_FmPcd->h_App,e_FM_PCD_KG_EXCEPTION_KEYSIZE_OVERFLOW);
35207 + }
35208 +}
35209 +
35210 +static t_Error KgInitGuest(t_FmPcd *p_FmPcd)
35211 +{
35212 + t_Error err = E_OK;
35213 + t_FmPcdIpcKgSchemesParams kgAlloc;
35214 + uint32_t replyLength;
35215 + t_FmPcdIpcReply reply;
35216 + t_FmPcdIpcMsg msg;
35217 +
35218 + ASSERT_COND(p_FmPcd->guestId != NCSW_MASTER_ID);
35219 +
35220 + /* in GUEST_PARTITION, we use the IPC */
35221 + memset(&reply, 0, sizeof(reply));
35222 + memset(&msg, 0, sizeof(msg));
35223 + memset(&kgAlloc, 0, sizeof(t_FmPcdIpcKgSchemesParams));
35224 + kgAlloc.numOfSchemes = p_FmPcd->p_FmPcdKg->numOfSchemes;
35225 + kgAlloc.guestId = p_FmPcd->guestId;
35226 + msg.msgId = FM_PCD_ALLOC_KG_SCHEMES;
35227 + memcpy(msg.msgBody, &kgAlloc, sizeof(kgAlloc));
35228 + replyLength = sizeof(uint32_t) + p_FmPcd->p_FmPcdKg->numOfSchemes*sizeof(uint8_t);
35229 + if ((err = XX_IpcSendMessage(p_FmPcd->h_IpcSession,
35230 + (uint8_t*)&msg,
35231 + sizeof(msg.msgId) + sizeof(kgAlloc),
35232 + (uint8_t*)&reply,
35233 + &replyLength,
35234 + NULL,
35235 + NULL)) != E_OK)
35236 + RETURN_ERROR(MAJOR, err, NO_MSG);
35237 + if (replyLength != (sizeof(uint32_t) + p_FmPcd->p_FmPcdKg->numOfSchemes*sizeof(uint8_t)))
35238 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch"));
35239 + memcpy(p_FmPcd->p_FmPcdKg->schemesIds, (uint8_t*)(reply.replyBody),p_FmPcd->p_FmPcdKg->numOfSchemes*sizeof(uint8_t));
35240 +
35241 + return (t_Error)reply.error;
35242 +}
35243 +
35244 +static t_Error KgInitMaster(t_FmPcd *p_FmPcd)
35245 +{
35246 + t_Error err = E_OK;
35247 + struct fman_kg_regs *p_Regs = p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs;
35248 +
35249 + ASSERT_COND(p_FmPcd->guestId == NCSW_MASTER_ID);
35250 +
35251 + if (p_FmPcd->exceptions & FM_EX_KG_DOUBLE_ECC)
35252 + FmEnableRamsEcc(p_FmPcd->h_Fm);
35253 +
35254 + fman_kg_init(p_Regs, p_FmPcd->exceptions, GET_NIA_BMI_AC_ENQ_FRAME(p_FmPcd));
35255 +
35256 + /* register even if no interrupts enabled, to allow future enablement */
35257 + FmRegisterIntr(p_FmPcd->h_Fm,
35258 + e_FM_MOD_KG,
35259 + 0,
35260 + e_FM_INTR_TYPE_ERR,
35261 + PcdKgErrorException,
35262 + p_FmPcd);
35263 +
35264 + fman_kg_enable_scheme_interrupts(p_Regs);
35265 +
35266 + if (p_FmPcd->p_FmPcdKg->numOfSchemes)
35267 + {
35268 + err = FmPcdKgAllocSchemes(p_FmPcd,
35269 + p_FmPcd->p_FmPcdKg->numOfSchemes,
35270 + p_FmPcd->guestId,
35271 + p_FmPcd->p_FmPcdKg->schemesIds);
35272 + if (err)
35273 + RETURN_ERROR(MINOR, err, NO_MSG);
35274 + }
35275 +
35276 + return E_OK;
35277 +}
35278 +
35279 +static void ValidateSchemeSw(t_FmPcdKgScheme *p_Scheme)
35280 +{
35281 + ASSERT_COND(!p_Scheme->valid);
35282 + if (p_Scheme->netEnvId != ILLEGAL_NETENV)
35283 + FmPcdIncNetEnvOwners(p_Scheme->h_FmPcd, p_Scheme->netEnvId);
35284 + p_Scheme->valid = TRUE;
35285 +}
35286 +
35287 +static t_Error InvalidateSchemeSw(t_FmPcdKgScheme *p_Scheme)
35288 +{
35289 + if (p_Scheme->owners)
35290 + RETURN_ERROR(MINOR, E_INVALID_STATE, ("Trying to delete a scheme that has ports bound to"));
35291 +
35292 + if (p_Scheme->netEnvId != ILLEGAL_NETENV)
35293 + FmPcdDecNetEnvOwners(p_Scheme->h_FmPcd, p_Scheme->netEnvId);
35294 + p_Scheme->valid = FALSE;
35295 +
35296 + return E_OK;
35297 +}
35298 +
35299 +static t_Error BuildSchemeRegs(t_FmPcdKgScheme *p_Scheme,
35300 + t_FmPcdKgSchemeParams *p_SchemeParams,
35301 + struct fman_kg_scheme_regs *p_SchemeRegs)
35302 +{
35303 + t_FmPcd *p_FmPcd = (t_FmPcd *)(p_Scheme->h_FmPcd);
35304 + uint32_t grpBits = 0;
35305 + uint8_t grpBase;
35306 + bool direct=TRUE, absolute=FALSE;
35307 + uint16_t profileId=0, numOfProfiles=0, relativeProfileId;
35308 + t_Error err = E_OK;
35309 + int i = 0;
35310 + t_NetEnvParams netEnvParams;
35311 + uint32_t tmpReg, fqbTmp = 0, ppcTmp = 0, selectTmp, maskTmp, knownTmp, genTmp;
35312 + t_FmPcdKgKeyExtractAndHashParams *p_KeyAndHash = NULL;
35313 + uint8_t j, curr, idx;
35314 + uint8_t id, shift=0, code=0, offset=0, size=0;
35315 + t_FmPcdExtractEntry *p_Extract = NULL;
35316 + t_FmPcdKgExtractedOrParams *p_ExtractOr;
35317 + bool generic = FALSE;
35318 + t_KnownFieldsMasks bitMask;
35319 + e_FmPcdKgExtractDfltSelect swDefault = (e_FmPcdKgExtractDfltSelect)0;
35320 + t_FmPcdKgSchemesExtracts *p_LocalExtractsArray;
35321 + uint8_t numOfSwDefaults = 0;
35322 + t_FmPcdKgExtractDflt swDefaults[NUM_OF_SW_DEFAULTS];
35323 + uint8_t currGenId = 0;
35324 +
35325 + memset(swDefaults, 0, NUM_OF_SW_DEFAULTS*sizeof(t_FmPcdKgExtractDflt));
35326 + memset(p_SchemeRegs, 0, sizeof(struct fman_kg_scheme_regs));
35327 +
35328 + if (p_SchemeParams->netEnvParams.numOfDistinctionUnits > FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS)
35329 + RETURN_ERROR(MAJOR, E_INVALID_VALUE,
35330 + ("numOfDistinctionUnits should not exceed %d", FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS));
35331 +
35332 + /* by netEnv parameters, get match vector */
35333 + if (!p_SchemeParams->alwaysDirect)
35334 + {
35335 + p_Scheme->netEnvId = FmPcdGetNetEnvId(p_SchemeParams->netEnvParams.h_NetEnv);
35336 + netEnvParams.netEnvId = p_Scheme->netEnvId;
35337 + netEnvParams.numOfDistinctionUnits = p_SchemeParams->netEnvParams.numOfDistinctionUnits;
35338 + memcpy(netEnvParams.unitIds, p_SchemeParams->netEnvParams.unitIds, (sizeof(uint8_t))*p_SchemeParams->netEnvParams.numOfDistinctionUnits);
35339 + err = PcdGetUnitsVector(p_FmPcd, &netEnvParams);
35340 + if (err)
35341 + RETURN_ERROR(MAJOR, E_INVALID_STATE, NO_MSG);
35342 + p_Scheme->matchVector = netEnvParams.vector;
35343 + }
35344 + else
35345 + {
35346 + p_Scheme->matchVector = SCHEME_ALWAYS_DIRECT;
35347 + p_Scheme->netEnvId = ILLEGAL_NETENV;
35348 + }
35349 +
35350 + if (p_SchemeParams->nextEngine == e_FM_PCD_INVALID)
35351 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Next Engine of the scheme is not Valid"));
35352 +
35353 + if (p_SchemeParams->bypassFqidGeneration)
35354 + {
35355 +#ifdef FM_KG_NO_BYPASS_FQID_GEN
35356 + if ((p_FmPcd->fmRevInfo.majorRev != 4) && (p_FmPcd->fmRevInfo.majorRev < 6))
35357 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("bypassFqidGeneration."));
35358 +#endif /* FM_KG_NO_BYPASS_FQID_GEN */
35359 + if (p_SchemeParams->baseFqid)
35360 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("baseFqid set for a scheme that does not generate an FQID"));
35361 + }
35362 + else
35363 + if (!p_SchemeParams->baseFqid)
35364 + DBG(WARNING, ("baseFqid is 0."));
35365 +
35366 + if (p_SchemeParams->nextEngine == e_FM_PCD_PLCR)
35367 + {
35368 + direct = p_SchemeParams->kgNextEngineParams.plcrProfile.direct;
35369 + p_Scheme->directPlcr = direct;
35370 + absolute = (bool)(p_SchemeParams->kgNextEngineParams.plcrProfile.sharedProfile ? TRUE : FALSE);
35371 + if (!direct && absolute)
35372 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Indirect policing is not available when profile is shared."));
35373 +
35374 + if (direct)
35375 + {
35376 + profileId = p_SchemeParams->kgNextEngineParams.plcrProfile.profileSelect.directRelativeProfileId;
35377 + numOfProfiles = 1;
35378 + }
35379 + else
35380 + {
35381 + profileId = p_SchemeParams->kgNextEngineParams.plcrProfile.profileSelect.indirectProfile.fqidOffsetRelativeProfileIdBase;
35382 + shift = p_SchemeParams->kgNextEngineParams.plcrProfile.profileSelect.indirectProfile.fqidOffsetShift;
35383 + numOfProfiles = p_SchemeParams->kgNextEngineParams.plcrProfile.profileSelect.indirectProfile.numOfProfiles;
35384 + }
35385 + }
35386 +
35387 + if (p_SchemeParams->nextEngine == e_FM_PCD_CC)
35388 + {
35389 +#ifdef FM_KG_NO_BYPASS_PLCR_PROFILE_GEN
35390 + if ((p_SchemeParams->kgNextEngineParams.cc.plcrNext) && (p_SchemeParams->kgNextEngineParams.cc.bypassPlcrProfileGeneration))
35391 + {
35392 + if ((p_FmPcd->fmRevInfo.majorRev != 4) && (p_FmPcd->fmRevInfo.majorRev < 6))
35393 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("bypassPlcrProfileGeneration."));
35394 + }
35395 +#endif /* FM_KG_NO_BYPASS_PLCR_PROFILE_GEN */
35396 +
35397 + err = FmPcdCcGetGrpParams(p_SchemeParams->kgNextEngineParams.cc.h_CcTree,
35398 + p_SchemeParams->kgNextEngineParams.cc.grpId,
35399 + &grpBits,
35400 + &grpBase);
35401 + if (err)
35402 + RETURN_ERROR(MAJOR, err, NO_MSG);
35403 + p_Scheme->ccUnits = grpBits;
35404 +
35405 + if ((p_SchemeParams->kgNextEngineParams.cc.plcrNext) &&
35406 + (!p_SchemeParams->kgNextEngineParams.cc.bypassPlcrProfileGeneration))
35407 + {
35408 + if (p_SchemeParams->kgNextEngineParams.cc.plcrProfile.sharedProfile)
35409 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Shared profile may not be used after Coarse classification."));
35410 + absolute = FALSE;
35411 + direct = p_SchemeParams->kgNextEngineParams.cc.plcrProfile.direct;
35412 + if (direct)
35413 + {
35414 + profileId = p_SchemeParams->kgNextEngineParams.cc.plcrProfile.profileSelect.directRelativeProfileId;
35415 + numOfProfiles = 1;
35416 + }
35417 + else
35418 + {
35419 + profileId = p_SchemeParams->kgNextEngineParams.cc.plcrProfile.profileSelect.indirectProfile.fqidOffsetRelativeProfileIdBase;
35420 + shift = p_SchemeParams->kgNextEngineParams.cc.plcrProfile.profileSelect.indirectProfile.fqidOffsetShift;
35421 + numOfProfiles = p_SchemeParams->kgNextEngineParams.cc.plcrProfile.profileSelect.indirectProfile.numOfProfiles;
35422 + }
35423 + }
35424 + }
35425 +
35426 + /* if policer is used directly after KG, or after CC */
35427 + if ((p_SchemeParams->nextEngine == e_FM_PCD_PLCR) ||
35428 + ((p_SchemeParams->nextEngine == e_FM_PCD_CC) &&
35429 + (p_SchemeParams->kgNextEngineParams.cc.plcrNext) &&
35430 + (!p_SchemeParams->kgNextEngineParams.cc.bypassPlcrProfileGeneration)))
35431 + {
35432 + /* if private policer profile, it may be uninitialized yet, therefore no checks are done at this stage */
35433 + if (absolute)
35434 + {
35435 + /* for absolute direct policy only, */
35436 + relativeProfileId = profileId;
35437 + err = FmPcdPlcrGetAbsoluteIdByProfileParams((t_Handle)p_FmPcd,e_FM_PCD_PLCR_SHARED,NULL, relativeProfileId, &profileId);
35438 + if (err)
35439 + RETURN_ERROR(MAJOR, err, ("Shared profile not valid offset"));
35440 + if (!FmPcdPlcrIsProfileValid(p_FmPcd, profileId))
35441 + RETURN_ERROR(MINOR, E_INVALID_STATE, ("Shared profile not valid."));
35442 + p_Scheme->relativeProfileId = profileId;
35443 + }
35444 + else
35445 + {
35446 + /* save relative profile id's for later check */
35447 + p_Scheme->nextRelativePlcrProfile = TRUE;
35448 + p_Scheme->relativeProfileId = profileId;
35449 + p_Scheme->numOfProfiles = numOfProfiles;
35450 + }
35451 + }
35452 + else
35453 + {
35454 + /* if policer is NOT going to be used after KG at all than if bypassFqidGeneration
35455 + is set, we do not need numOfUsedExtractedOrs and hashDistributionNumOfFqids */
35456 + if (p_SchemeParams->bypassFqidGeneration && p_SchemeParams->numOfUsedExtractedOrs)
35457 + RETURN_ERROR(MAJOR, E_INVALID_STATE,
35458 + ("numOfUsedExtractedOrs is set in a scheme that does not generate FQID or policer profile ID"));
35459 + if (p_SchemeParams->bypassFqidGeneration &&
35460 + p_SchemeParams->useHash &&
35461 + p_SchemeParams->keyExtractAndHashParams.hashDistributionNumOfFqids)
35462 + RETURN_ERROR(MAJOR, E_INVALID_STATE,
35463 + ("hashDistributionNumOfFqids is set in a scheme that does not generate FQID or policer profile ID"));
35464 + }
35465 +
35466 + /* configure all 21 scheme registers */
35467 + tmpReg = KG_SCH_MODE_EN;
35468 + switch (p_SchemeParams->nextEngine)
35469 + {
35470 + case (e_FM_PCD_PLCR):
35471 + /* add to mode register - NIA */
35472 + tmpReg |= KG_SCH_MODE_NIA_PLCR;
35473 + tmpReg |= NIA_ENG_PLCR;
35474 + tmpReg |= (uint32_t)(p_SchemeParams->kgNextEngineParams.plcrProfile.sharedProfile ? NIA_PLCR_ABSOLUTE:0);
35475 + /* initialize policer profile command - */
35476 + /* configure kgse_ppc */
35477 + if (direct)
35478 + /* use profileId as base, other fields are 0 */
35479 + p_SchemeRegs->kgse_ppc = (uint32_t)profileId;
35480 + else
35481 + {
35482 + if (shift > MAX_PP_SHIFT)
35483 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("fqidOffsetShift may not be larger than %d", MAX_PP_SHIFT));
35484 +
35485 + if (!numOfProfiles || !POWER_OF_2(numOfProfiles))
35486 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("numOfProfiles must not be 0 and must be a power of 2"));
35487 +
35488 + ppcTmp = ((uint32_t)shift << KG_SCH_PP_SHIFT_HIGH_SHIFT) & KG_SCH_PP_SHIFT_HIGH;
35489 + ppcTmp |= ((uint32_t)shift << KG_SCH_PP_SHIFT_LOW_SHIFT) & KG_SCH_PP_SHIFT_LOW;
35490 + ppcTmp |= ((uint32_t)(numOfProfiles-1) << KG_SCH_PP_MASK_SHIFT);
35491 + ppcTmp |= (uint32_t)profileId;
35492 +
35493 + p_SchemeRegs->kgse_ppc = ppcTmp;
35494 + }
35495 + break;
35496 + case (e_FM_PCD_CC):
35497 + /* mode reg - define NIA */
35498 + tmpReg |= (NIA_ENG_FM_CTL | NIA_FM_CTL_AC_CC);
35499 +
35500 + p_SchemeRegs->kgse_ccbs = grpBits;
35501 + tmpReg |= (uint32_t)(grpBase << KG_SCH_MODE_CCOBASE_SHIFT);
35502 +
35503 + if (p_SchemeParams->kgNextEngineParams.cc.plcrNext)
35504 + {
35505 + if (!p_SchemeParams->kgNextEngineParams.cc.bypassPlcrProfileGeneration)
35506 + {
35507 + /* find out if absolute or relative */
35508 + if (absolute)
35509 + 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"));
35510 + if (direct)
35511 + {
35512 + /* mask = 0, base = directProfileId */
35513 + p_SchemeRegs->kgse_ppc = (uint32_t)profileId;
35514 + }
35515 + else
35516 + {
35517 + if (shift > MAX_PP_SHIFT)
35518 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("fqidOffsetShift may not be larger than %d", MAX_PP_SHIFT));
35519 + if (!numOfProfiles || !POWER_OF_2(numOfProfiles))
35520 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("numOfProfiles must not be 0 and must be a power of 2"));
35521 +
35522 + ppcTmp = ((uint32_t)shift << KG_SCH_PP_SHIFT_HIGH_SHIFT) & KG_SCH_PP_SHIFT_HIGH;
35523 + ppcTmp |= ((uint32_t)shift << KG_SCH_PP_SHIFT_LOW_SHIFT) & KG_SCH_PP_SHIFT_LOW;
35524 + ppcTmp |= ((uint32_t)(numOfProfiles-1) << KG_SCH_PP_MASK_SHIFT);
35525 + ppcTmp |= (uint32_t)profileId;
35526 +
35527 + p_SchemeRegs->kgse_ppc = ppcTmp;
35528 + }
35529 + }
35530 + }
35531 + break;
35532 + case (e_FM_PCD_DONE):
35533 + if (p_SchemeParams->kgNextEngineParams.doneAction == e_FM_PCD_DROP_FRAME)
35534 + tmpReg |= GET_NIA_BMI_AC_DISCARD_FRAME(p_FmPcd);
35535 + else
35536 + tmpReg |= GET_NIA_BMI_AC_ENQ_FRAME(p_FmPcd);
35537 + break;
35538 + default:
35539 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("Next engine not supported"));
35540 + }
35541 + p_SchemeRegs->kgse_mode = tmpReg;
35542 +
35543 + p_SchemeRegs->kgse_mv = p_Scheme->matchVector;
35544 +
35545 +#if (DPAA_VERSION >= 11)
35546 + if (p_SchemeParams->overrideStorageProfile)
35547 + {
35548 + p_SchemeRegs->kgse_om |= KG_SCH_OM_VSPE;
35549 +
35550 + if (p_SchemeParams->storageProfile.direct)
35551 + {
35552 + profileId = p_SchemeParams->storageProfile.profileSelect.directRelativeProfileId;
35553 + shift = 0;
35554 + numOfProfiles = 1;
35555 + }
35556 + else
35557 + {
35558 + profileId = p_SchemeParams->storageProfile.profileSelect.indirectProfile.fqidOffsetRelativeProfileIdBase;
35559 + shift = p_SchemeParams->storageProfile.profileSelect.indirectProfile.fqidOffsetShift;
35560 + numOfProfiles = p_SchemeParams->storageProfile.profileSelect.indirectProfile.numOfProfiles;
35561 + }
35562 + if (shift > MAX_SP_SHIFT)
35563 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("fqidOffsetShift may not be larger than %d", MAX_SP_SHIFT));
35564 +
35565 + if (!numOfProfiles || !POWER_OF_2(numOfProfiles))
35566 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("numOfProfiles must not be 0 and must be a power of 2"));
35567 +
35568 + tmpReg = (uint32_t)shift << KG_SCH_VSP_SHIFT;
35569 + tmpReg |= ((uint32_t)(numOfProfiles-1) << KG_SCH_VSP_MASK_SHIFT);
35570 + tmpReg |= (uint32_t)profileId;
35571 +
35572 +
35573 + p_SchemeRegs->kgse_vsp = tmpReg;
35574 +
35575 + p_Scheme->vspe = TRUE;
35576 +
35577 + }
35578 + else
35579 + p_SchemeRegs->kgse_vsp = KG_SCH_VSP_NO_KSP_EN;
35580 +#endif /* (DPAA_VERSION >= 11) */
35581 +
35582 + if (p_SchemeParams->useHash)
35583 + {
35584 + p_KeyAndHash = &p_SchemeParams->keyExtractAndHashParams;
35585 +
35586 + if (p_KeyAndHash->numOfUsedExtracts >= FM_PCD_KG_MAX_NUM_OF_EXTRACTS_PER_KEY)
35587 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("numOfUsedExtracts out of range"));
35588 +
35589 + /* configure kgse_dv0 */
35590 + p_SchemeRegs->kgse_dv0 = p_KeyAndHash->privateDflt0;
35591 +
35592 + /* configure kgse_dv1 */
35593 + p_SchemeRegs->kgse_dv1 = p_KeyAndHash->privateDflt1;
35594 +
35595 + if (!p_SchemeParams->bypassFqidGeneration)
35596 + {
35597 + if (!p_KeyAndHash->hashDistributionNumOfFqids || !POWER_OF_2(p_KeyAndHash->hashDistributionNumOfFqids))
35598 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("hashDistributionNumOfFqids must not be 0 and must be a power of 2"));
35599 + if ((p_KeyAndHash->hashDistributionNumOfFqids-1) & p_SchemeParams->baseFqid)
35600 + DBG(WARNING, ("baseFqid unaligned. Distribution may result in less than hashDistributionNumOfFqids queues."));
35601 + }
35602 +
35603 + /* configure kgse_ekdv */
35604 + tmpReg = 0;
35605 + for ( i=0 ;i<p_KeyAndHash->numOfUsedDflts ; i++)
35606 + {
35607 + switch (p_KeyAndHash->dflts[i].type)
35608 + {
35609 + case (e_FM_PCD_KG_MAC_ADDR):
35610 + tmpReg |= (p_KeyAndHash->dflts[i].dfltSelect << KG_SCH_DEF_MAC_ADDR_SHIFT);
35611 + break;
35612 + case (e_FM_PCD_KG_TCI):
35613 + tmpReg |= (p_KeyAndHash->dflts[i].dfltSelect << KG_SCH_DEF_TCI_SHIFT);
35614 + break;
35615 + case (e_FM_PCD_KG_ENET_TYPE):
35616 + tmpReg |= (p_KeyAndHash->dflts[i].dfltSelect << KG_SCH_DEF_ENET_TYPE_SHIFT);
35617 + break;
35618 + case (e_FM_PCD_KG_PPP_SESSION_ID):
35619 + tmpReg |= (p_KeyAndHash->dflts[i].dfltSelect << KG_SCH_DEF_PPP_SESSION_ID_SHIFT);
35620 + break;
35621 + case (e_FM_PCD_KG_PPP_PROTOCOL_ID):
35622 + tmpReg |= (p_KeyAndHash->dflts[i].dfltSelect << KG_SCH_DEF_PPP_PROTOCOL_ID_SHIFT);
35623 + break;
35624 + case (e_FM_PCD_KG_MPLS_LABEL):
35625 + tmpReg |= (p_KeyAndHash->dflts[i].dfltSelect << KG_SCH_DEF_MPLS_LABEL_SHIFT);
35626 + break;
35627 + case (e_FM_PCD_KG_IP_ADDR):
35628 + tmpReg |= (p_KeyAndHash->dflts[i].dfltSelect << KG_SCH_DEF_IP_ADDR_SHIFT);
35629 + break;
35630 + case (e_FM_PCD_KG_PROTOCOL_TYPE):
35631 + tmpReg |= (p_KeyAndHash->dflts[i].dfltSelect << KG_SCH_DEF_PROTOCOL_TYPE_SHIFT);
35632 + break;
35633 + case (e_FM_PCD_KG_IP_TOS_TC):
35634 + tmpReg |= (p_KeyAndHash->dflts[i].dfltSelect << KG_SCH_DEF_IP_TOS_TC_SHIFT);
35635 + break;
35636 + case (e_FM_PCD_KG_IPV6_FLOW_LABEL):
35637 + tmpReg |= (p_KeyAndHash->dflts[i].dfltSelect << KG_SCH_DEF_L4_PORT_SHIFT);
35638 + break;
35639 + case (e_FM_PCD_KG_IPSEC_SPI):
35640 + tmpReg |= (p_KeyAndHash->dflts[i].dfltSelect << KG_SCH_DEF_IPSEC_SPI_SHIFT);
35641 + break;
35642 + case (e_FM_PCD_KG_L4_PORT):
35643 + tmpReg |= (p_KeyAndHash->dflts[i].dfltSelect << KG_SCH_DEF_L4_PORT_SHIFT);
35644 + break;
35645 + case (e_FM_PCD_KG_TCP_FLAG):
35646 + tmpReg |= (p_KeyAndHash->dflts[i].dfltSelect << KG_SCH_DEF_TCP_FLAG_SHIFT);
35647 + break;
35648 + case (e_FM_PCD_KG_GENERIC_FROM_DATA):
35649 + swDefaults[numOfSwDefaults].type = e_FM_PCD_KG_GENERIC_FROM_DATA;
35650 + swDefaults[numOfSwDefaults].dfltSelect = p_KeyAndHash->dflts[i].dfltSelect;
35651 + numOfSwDefaults ++;
35652 + break;
35653 + case (e_FM_PCD_KG_GENERIC_FROM_DATA_NO_V):
35654 + swDefaults[numOfSwDefaults].type = e_FM_PCD_KG_GENERIC_FROM_DATA_NO_V;
35655 + swDefaults[numOfSwDefaults].dfltSelect = p_KeyAndHash->dflts[i].dfltSelect;
35656 + numOfSwDefaults ++;
35657 + break;
35658 + case (e_FM_PCD_KG_GENERIC_NOT_FROM_DATA):
35659 + swDefaults[numOfSwDefaults].type = e_FM_PCD_KG_GENERIC_NOT_FROM_DATA;
35660 + swDefaults[numOfSwDefaults].dfltSelect = p_KeyAndHash->dflts[i].dfltSelect;
35661 + numOfSwDefaults ++;
35662 + break;
35663 + default:
35664 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION, NO_MSG);
35665 + }
35666 + }
35667 + p_SchemeRegs->kgse_ekdv = tmpReg;
35668 +
35669 + p_LocalExtractsArray = (t_FmPcdKgSchemesExtracts *)XX_Malloc(sizeof(t_FmPcdKgSchemesExtracts));
35670 + if (!p_LocalExtractsArray)
35671 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("No memory"));
35672 +
35673 + /* configure kgse_ekfc and kgse_gec */
35674 + knownTmp = 0;
35675 + for ( i=0 ;i<p_KeyAndHash->numOfUsedExtracts ; i++)
35676 + {
35677 + p_Extract = &p_KeyAndHash->extractArray[i];
35678 + switch (p_Extract->type)
35679 + {
35680 + case (e_FM_PCD_KG_EXTRACT_PORT_PRIVATE_INFO):
35681 + knownTmp |= KG_SCH_KN_PORT_ID;
35682 + /* save in driver structure */
35683 + p_LocalExtractsArray->extractsArray[i].id = GetKnownFieldId(KG_SCH_KN_PORT_ID);
35684 + p_LocalExtractsArray->extractsArray[i].known = TRUE;
35685 + break;
35686 + case (e_FM_PCD_EXTRACT_BY_HDR):
35687 + switch (p_Extract->extractByHdr.hdr)
35688 + {
35689 +#if (DPAA_VERSION >= 11) || ((DPAA_VERSION == 10) && defined(FM_CAPWAP_SUPPORT))
35690 + case (HEADER_TYPE_UDP_LITE):
35691 + p_Extract->extractByHdr.hdr = HEADER_TYPE_UDP;
35692 + break;
35693 +#endif /* (DPAA_VERSION >= 11) || ((DPAA_VERSION == 10) && defined(FM_CAPWAP_SUPPORT)) */
35694 + case (HEADER_TYPE_UDP_ENCAP_ESP):
35695 + switch (p_Extract->extractByHdr.type)
35696 + {
35697 + case (e_FM_PCD_EXTRACT_FROM_HDR):
35698 + /* case where extraction from ESP only */
35699 + if (p_Extract->extractByHdr.extractByHdrType.fromHdr.offset >= UDP_HEADER_SIZE)
35700 + {
35701 + p_Extract->extractByHdr.hdr = FmPcdGetAliasHdr(p_FmPcd, p_Scheme->netEnvId, HEADER_TYPE_UDP_ENCAP_ESP);
35702 + p_Extract->extractByHdr.extractByHdrType.fromHdr.offset -= UDP_HEADER_SIZE;
35703 + p_Extract->extractByHdr.ignoreProtocolValidation = TRUE;
35704 + }
35705 + else
35706 + {
35707 + p_Extract->extractByHdr.hdr = HEADER_TYPE_UDP;
35708 + p_Extract->extractByHdr.ignoreProtocolValidation = FALSE;
35709 + }
35710 + break;
35711 + case (e_FM_PCD_EXTRACT_FROM_FIELD):
35712 + switch (p_Extract->extractByHdr.extractByHdrType.fromField.field.udpEncapEsp)
35713 + {
35714 + case (NET_HEADER_FIELD_UDP_ENCAP_ESP_PORT_SRC):
35715 + case (NET_HEADER_FIELD_UDP_ENCAP_ESP_PORT_DST):
35716 + case (NET_HEADER_FIELD_UDP_ENCAP_ESP_LEN):
35717 + case (NET_HEADER_FIELD_UDP_ENCAP_ESP_CKSUM):
35718 + p_Extract->extractByHdr.hdr = HEADER_TYPE_UDP;
35719 + break;
35720 + case (NET_HEADER_FIELD_UDP_ENCAP_ESP_SPI):
35721 + p_Extract->extractByHdr.type = e_FM_PCD_EXTRACT_FROM_HDR;
35722 + p_Extract->extractByHdr.hdr = FmPcdGetAliasHdr(p_FmPcd, p_Scheme->netEnvId, HEADER_TYPE_UDP_ENCAP_ESP);
35723 + /*p_Extract->extractByHdr.extractByHdrType.fromField.offset += ESP_SPI_OFFSET;*/
35724 + p_Extract->extractByHdr.ignoreProtocolValidation = TRUE;
35725 + break;
35726 + case (NET_HEADER_FIELD_UDP_ENCAP_ESP_SEQUENCE_NUM):
35727 + p_Extract->extractByHdr.type = e_FM_PCD_EXTRACT_FROM_HDR;
35728 + p_Extract->extractByHdr.hdr = FmPcdGetAliasHdr(p_FmPcd, p_Scheme->netEnvId, HEADER_TYPE_UDP_ENCAP_ESP);
35729 + p_Extract->extractByHdr.extractByHdrType.fromField.offset += ESP_SEQ_NUM_OFFSET;
35730 + p_Extract->extractByHdr.ignoreProtocolValidation = TRUE;
35731 + break;
35732 + }
35733 + break;
35734 + case (e_FM_PCD_EXTRACT_FULL_FIELD):
35735 + switch (p_Extract->extractByHdr.extractByHdrType.fullField.udpEncapEsp)
35736 + {
35737 + case (NET_HEADER_FIELD_UDP_ENCAP_ESP_PORT_SRC):
35738 + case (NET_HEADER_FIELD_UDP_ENCAP_ESP_PORT_DST):
35739 + case (NET_HEADER_FIELD_UDP_ENCAP_ESP_LEN):
35740 + case (NET_HEADER_FIELD_UDP_ENCAP_ESP_CKSUM):
35741 + p_Extract->extractByHdr.hdr = HEADER_TYPE_UDP;
35742 + break;
35743 + case (NET_HEADER_FIELD_UDP_ENCAP_ESP_SPI):
35744 + p_Extract->extractByHdr.type = e_FM_PCD_EXTRACT_FROM_HDR;
35745 + p_Extract->extractByHdr.hdr = FmPcdGetAliasHdr(p_FmPcd, p_Scheme->netEnvId, HEADER_TYPE_UDP_ENCAP_ESP);
35746 + p_Extract->extractByHdr.extractByHdrType.fromHdr.size = ESP_SPI_SIZE;
35747 + p_Extract->extractByHdr.extractByHdrType.fromHdr.offset = ESP_SPI_OFFSET;
35748 + p_Extract->extractByHdr.ignoreProtocolValidation = TRUE;
35749 + break;
35750 + case (NET_HEADER_FIELD_UDP_ENCAP_ESP_SEQUENCE_NUM):
35751 + p_Extract->extractByHdr.type = e_FM_PCD_EXTRACT_FROM_HDR;
35752 + p_Extract->extractByHdr.hdr = FmPcdGetAliasHdr(p_FmPcd, p_Scheme->netEnvId, HEADER_TYPE_UDP_ENCAP_ESP);
35753 + p_Extract->extractByHdr.extractByHdrType.fromHdr.size = ESP_SEQ_NUM_SIZE;
35754 + p_Extract->extractByHdr.extractByHdrType.fromHdr.offset = ESP_SEQ_NUM_OFFSET;
35755 + p_Extract->extractByHdr.ignoreProtocolValidation = TRUE;
35756 + break;
35757 + }
35758 + break;
35759 + }
35760 + break;
35761 + default:
35762 + break;
35763 + }
35764 + switch (p_Extract->extractByHdr.type)
35765 + {
35766 + case (e_FM_PCD_EXTRACT_FROM_HDR):
35767 + generic = TRUE;
35768 + /* get the header code for the generic extract */
35769 + code = GetGenHdrCode(p_Extract->extractByHdr.hdr, p_Extract->extractByHdr.hdrIndex, p_Extract->extractByHdr.ignoreProtocolValidation);
35770 + /* set generic register fields */
35771 + offset = p_Extract->extractByHdr.extractByHdrType.fromHdr.offset;
35772 + size = p_Extract->extractByHdr.extractByHdrType.fromHdr.size;
35773 + break;
35774 + case (e_FM_PCD_EXTRACT_FROM_FIELD):
35775 + generic = TRUE;
35776 + /* get the field code for the generic extract */
35777 + code = GetGenFieldCode(p_Extract->extractByHdr.hdr,
35778 + p_Extract->extractByHdr.extractByHdrType.fromField.field, p_Extract->extractByHdr.ignoreProtocolValidation,p_Extract->extractByHdr.hdrIndex);
35779 + offset = p_Extract->extractByHdr.extractByHdrType.fromField.offset;
35780 + size = p_Extract->extractByHdr.extractByHdrType.fromField.size;
35781 + break;
35782 + case (e_FM_PCD_EXTRACT_FULL_FIELD):
35783 + if (!p_Extract->extractByHdr.ignoreProtocolValidation)
35784 + {
35785 + /* if we have a known field for it - use it, otherwise use generic */
35786 + bitMask = GetKnownProtMask(p_FmPcd, p_Extract->extractByHdr.hdr, p_Extract->extractByHdr.hdrIndex,
35787 + p_Extract->extractByHdr.extractByHdrType.fullField);
35788 + if (bitMask)
35789 + {
35790 + knownTmp |= bitMask;
35791 + /* save in driver structure */
35792 + p_LocalExtractsArray->extractsArray[i].id = GetKnownFieldId(bitMask);
35793 + p_LocalExtractsArray->extractsArray[i].known = TRUE;
35794 + }
35795 + else
35796 + generic = TRUE;
35797 + }
35798 + else
35799 + generic = TRUE;
35800 + if (generic)
35801 + {
35802 + /* tmp - till we cover more headers under generic */
35803 + XX_Free(p_LocalExtractsArray);
35804 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("Full header selection not supported"));
35805 + }
35806 + break;
35807 + default:
35808 + XX_Free(p_LocalExtractsArray);
35809 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION, NO_MSG);
35810 + }
35811 + break;
35812 + case (e_FM_PCD_EXTRACT_NON_HDR):
35813 + /* use generic */
35814 + generic = TRUE;
35815 + offset = 0;
35816 + /* get the field code for the generic extract */
35817 + code = GetGenCode(p_Extract->extractNonHdr.src, &offset);
35818 + offset += p_Extract->extractNonHdr.offset;
35819 + size = p_Extract->extractNonHdr.size;
35820 + break;
35821 + default:
35822 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION, NO_MSG);
35823 + }
35824 +
35825 + if (generic)
35826 + {
35827 + /* set generic register fields */
35828 + if (currGenId >= FM_KG_NUM_OF_GENERIC_REGS)
35829 + {
35830 + XX_Free(p_LocalExtractsArray);
35831 + RETURN_ERROR(MAJOR, E_FULL, ("Generic registers are fully used"));
35832 + }
35833 + if (!code)
35834 + {
35835 + XX_Free(p_LocalExtractsArray);
35836 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, NO_MSG);
35837 + }
35838 +
35839 + genTmp = KG_SCH_GEN_VALID;
35840 + genTmp |= (uint32_t)(code << KG_SCH_GEN_HT_SHIFT);
35841 + genTmp |= offset;
35842 + if ((size > MAX_KG_SCH_SIZE) || (size < 1))
35843 + {
35844 + XX_Free(p_LocalExtractsArray);
35845 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal extraction (size out of range)"));
35846 + }
35847 + genTmp |= (uint32_t)((size - 1) << KG_SCH_GEN_SIZE_SHIFT);
35848 + swDefault = GetGenericSwDefault(swDefaults, numOfSwDefaults, code);
35849 + if (swDefault == e_FM_PCD_KG_DFLT_ILLEGAL)
35850 + DBG(WARNING, ("No sw default configured"));
35851 + else
35852 + genTmp |= swDefault << KG_SCH_GEN_DEF_SHIFT;
35853 +
35854 + genTmp |= KG_SCH_GEN_MASK;
35855 + p_SchemeRegs->kgse_gec[currGenId] = genTmp;
35856 + /* save in driver structure */
35857 + p_LocalExtractsArray->extractsArray[i].id = currGenId++;
35858 + p_LocalExtractsArray->extractsArray[i].known = FALSE;
35859 + generic = FALSE;
35860 + }
35861 + }
35862 + p_SchemeRegs->kgse_ekfc = knownTmp;
35863 +
35864 + selectTmp = 0;
35865 + maskTmp = 0xFFFFFFFF;
35866 + /* configure kgse_bmch, kgse_bmcl and kgse_fqb */
35867 +
35868 + if (p_KeyAndHash->numOfUsedMasks > FM_PCD_KG_NUM_OF_EXTRACT_MASKS)
35869 + {
35870 + XX_Free(p_LocalExtractsArray);
35871 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Only %d masks supported", FM_PCD_KG_NUM_OF_EXTRACT_MASKS));
35872 + }
35873 + for ( i=0 ;i<p_KeyAndHash->numOfUsedMasks ; i++)
35874 + {
35875 + /* Get the relative id of the extract (for known 0-0x1f, for generic 0-7) */
35876 + id = p_LocalExtractsArray->extractsArray[p_KeyAndHash->masks[i].extractArrayIndex].id;
35877 + /* Get the shift of the select field (depending on i) */
35878 + GET_MASK_SEL_SHIFT(shift,i);
35879 + if (p_LocalExtractsArray->extractsArray[p_KeyAndHash->masks[i].extractArrayIndex].known)
35880 + selectTmp |= id << shift;
35881 + else
35882 + selectTmp |= (id + MASK_FOR_GENERIC_BASE_ID) << shift;
35883 +
35884 + /* Get the shift of the offset field (depending on i) - may
35885 + be in kgse_bmch or in kgse_fqb (depending on i) */
35886 + GET_MASK_OFFSET_SHIFT(shift,i);
35887 + if (i<=1)
35888 + selectTmp |= p_KeyAndHash->masks[i].offset << shift;
35889 + else
35890 + fqbTmp |= p_KeyAndHash->masks[i].offset << shift;
35891 +
35892 + /* Get the shift of the mask field (depending on i) */
35893 + GET_MASK_SHIFT(shift,i);
35894 + /* pass all bits */
35895 + maskTmp |= KG_SCH_BITMASK_MASK << shift;
35896 + /* clear bits that need masking */
35897 + maskTmp &= ~(0xFF << shift) ;
35898 + /* set mask bits */
35899 + maskTmp |= (p_KeyAndHash->masks[i].mask << shift) ;
35900 + }
35901 + p_SchemeRegs->kgse_bmch = selectTmp;
35902 + p_SchemeRegs->kgse_bmcl = maskTmp;
35903 + /* kgse_fqb will be written t the end of the routine */
35904 +
35905 + /* configure kgse_hc */
35906 + if (p_KeyAndHash->hashShift > MAX_HASH_SHIFT)
35907 + {
35908 + XX_Free(p_LocalExtractsArray);
35909 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("hashShift must not be larger than %d", MAX_HASH_SHIFT));
35910 + }
35911 + if (p_KeyAndHash->hashDistributionFqidsShift > MAX_DIST_FQID_SHIFT)
35912 + {
35913 + XX_Free(p_LocalExtractsArray);
35914 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("hashDistributionFqidsShift must not be larger than %d", MAX_DIST_FQID_SHIFT));
35915 + }
35916 +
35917 + tmpReg = 0;
35918 +
35919 + tmpReg |= ((p_KeyAndHash->hashDistributionNumOfFqids - 1) << p_KeyAndHash->hashDistributionFqidsShift);
35920 + tmpReg |= p_KeyAndHash->hashShift << KG_SCH_HASH_CONFIG_SHIFT_SHIFT;
35921 +
35922 + if (p_KeyAndHash->symmetricHash)
35923 + {
35924 + if ((!!(p_SchemeRegs->kgse_ekfc & KG_SCH_KN_MACSRC) != !!(p_SchemeRegs->kgse_ekfc & KG_SCH_KN_MACDST)) ||
35925 + (!!(p_SchemeRegs->kgse_ekfc & KG_SCH_KN_IPSRC1) != !!(p_SchemeRegs->kgse_ekfc & KG_SCH_KN_IPDST1)) ||
35926 + (!!(p_SchemeRegs->kgse_ekfc & KG_SCH_KN_IPSRC2) != !!(p_SchemeRegs->kgse_ekfc & KG_SCH_KN_IPDST2)) ||
35927 + (!!(p_SchemeRegs->kgse_ekfc & KG_SCH_KN_L4PSRC) != !!(p_SchemeRegs->kgse_ekfc & KG_SCH_KN_L4PDST)))
35928 + {
35929 + XX_Free(p_LocalExtractsArray);
35930 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("symmetricHash set but src/dest extractions missing"));
35931 + }
35932 + tmpReg |= KG_SCH_HASH_CONFIG_SYM;
35933 + }
35934 + p_SchemeRegs->kgse_hc = tmpReg;
35935 +
35936 + /* build the return array describing the order of the extractions */
35937 +
35938 + /* the last currGenId places of the array
35939 + are for generic extracts that are always last.
35940 + We now sort for the calculation of the order of the known
35941 + extractions we sort the known extracts between orderedArray[0] and
35942 + orderedArray[p_KeyAndHash->numOfUsedExtracts - currGenId - 1].
35943 + for the calculation of the order of the generic extractions we use:
35944 + num_of_generic - currGenId
35945 + num_of_known - p_KeyAndHash->numOfUsedExtracts - currGenId
35946 + first_generic_index = num_of_known */
35947 + curr = 0;
35948 + for (i=0;i<p_KeyAndHash->numOfUsedExtracts ; i++)
35949 + {
35950 + if (p_LocalExtractsArray->extractsArray[i].known)
35951 + {
35952 + ASSERT_COND(curr<(p_KeyAndHash->numOfUsedExtracts - currGenId));
35953 + j = curr;
35954 + /* id is the extract id (port id = 0, mac src = 1 etc.). the value in the array is the original
35955 + index in the user's extractions array */
35956 + /* we compare the id of the current extract with the id of the extract in the orderedArray[j-1]
35957 + location */
35958 + while ((j > 0) && (p_LocalExtractsArray->extractsArray[i].id <
35959 + p_LocalExtractsArray->extractsArray[p_Scheme->orderedArray[j-1]].id))
35960 + {
35961 + p_Scheme->orderedArray[j] =
35962 + p_Scheme->orderedArray[j-1];
35963 + j--;
35964 + }
35965 + p_Scheme->orderedArray[j] = (uint8_t)i;
35966 + curr++;
35967 + }
35968 + else
35969 + {
35970 + /* index is first_generic_index + generic index (id) */
35971 + idx = (uint8_t)(p_KeyAndHash->numOfUsedExtracts - currGenId + p_LocalExtractsArray->extractsArray[i].id);
35972 + ASSERT_COND(idx < FM_PCD_KG_MAX_NUM_OF_EXTRACTS_PER_KEY);
35973 + p_Scheme->orderedArray[idx]= (uint8_t)i;
35974 + }
35975 + }
35976 + XX_Free(p_LocalExtractsArray);
35977 + }
35978 + else
35979 + {
35980 + /* clear all unused registers: */
35981 + p_SchemeRegs->kgse_ekfc = 0;
35982 + p_SchemeRegs->kgse_ekdv = 0;
35983 + p_SchemeRegs->kgse_bmch = 0;
35984 + p_SchemeRegs->kgse_bmcl = 0;
35985 + p_SchemeRegs->kgse_hc = 0;
35986 + p_SchemeRegs->kgse_dv0 = 0;
35987 + p_SchemeRegs->kgse_dv1 = 0;
35988 + }
35989 +
35990 + if (p_SchemeParams->bypassFqidGeneration)
35991 + p_SchemeRegs->kgse_hc |= KG_SCH_HASH_CONFIG_NO_FQID;
35992 +
35993 + /* configure kgse_spc */
35994 + if ( p_SchemeParams->schemeCounter.update)
35995 + p_SchemeRegs->kgse_spc = p_SchemeParams->schemeCounter.value;
35996 +
35997 +
35998 + /* check that are enough generic registers */
35999 + if (p_SchemeParams->numOfUsedExtractedOrs + currGenId > FM_KG_NUM_OF_GENERIC_REGS)
36000 + RETURN_ERROR(MAJOR, E_FULL, ("Generic registers are fully used"));
36001 +
36002 + /* extracted OR mask on Qid */
36003 + for ( i=0 ;i<p_SchemeParams->numOfUsedExtractedOrs ; i++)
36004 + {
36005 +
36006 + p_Scheme->extractedOrs = TRUE;
36007 + /* configure kgse_gec[i] */
36008 + p_ExtractOr = &p_SchemeParams->extractedOrs[i];
36009 + switch (p_ExtractOr->type)
36010 + {
36011 + case (e_FM_PCD_KG_EXTRACT_PORT_PRIVATE_INFO):
36012 + code = KG_SCH_GEN_PARSE_RESULT_N_FQID;
36013 + offset = 0;
36014 + break;
36015 + case (e_FM_PCD_EXTRACT_BY_HDR):
36016 + /* get the header code for the generic extract */
36017 + code = GetGenHdrCode(p_ExtractOr->extractByHdr.hdr, p_ExtractOr->extractByHdr.hdrIndex, p_ExtractOr->extractByHdr.ignoreProtocolValidation);
36018 + /* set generic register fields */
36019 + offset = p_ExtractOr->extractionOffset;
36020 + break;
36021 + case (e_FM_PCD_EXTRACT_NON_HDR):
36022 + /* get the field code for the generic extract */
36023 + offset = 0;
36024 + code = GetGenCode(p_ExtractOr->src, &offset);
36025 + offset += p_ExtractOr->extractionOffset;
36026 + break;
36027 + default:
36028 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION, NO_MSG);
36029 + }
36030 +
36031 + /* set generic register fields */
36032 + if (!code)
36033 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, NO_MSG);
36034 + genTmp = KG_SCH_GEN_EXTRACT_TYPE | KG_SCH_GEN_VALID;
36035 + genTmp |= (uint32_t)(code << KG_SCH_GEN_HT_SHIFT);
36036 + genTmp |= offset;
36037 + if (!!p_ExtractOr->bitOffsetInFqid == !!p_ExtractOr->bitOffsetInPlcrProfile)
36038 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, (" extracted byte must effect either FQID or Policer profile"));
36039 +
36040 + /************************************************************************************
36041 + bitOffsetInFqid and bitOffsetInPolicerProfile are translated to rotate parameter
36042 + in the following way:
36043 +
36044 + Driver API and implementation:
36045 + ==============================
36046 + FQID: extracted OR byte may be shifted right 1-31 bits to effect parts of the FQID.
36047 + if shifted less than 8 bits, or more than 24 bits a mask is set on the bits that
36048 + are not overlapping FQID.
36049 + ------------------------
36050 + | FQID (24) |
36051 + ------------------------
36052 + --------
36053 + | | extracted OR byte
36054 + --------
36055 +
36056 + Policer Profile: extracted OR byte may be shifted right 1-15 bits to effect parts of the
36057 + PP id. Unless shifted exactly 8 bits to overlap the PP id, a mask is set on the bits that
36058 + are not overlapping PP id.
36059 +
36060 + --------
36061 + | PP (8) |
36062 + --------
36063 + --------
36064 + | | extracted OR byte
36065 + --------
36066 +
36067 + HW implementation
36068 + =================
36069 + FQID and PP construct a 32 bit word in the way describe below. Extracted byte is located
36070 + as the highest byte of that word and may be rotated to effect any part os the FQID or
36071 + the PP.
36072 + ------------------------ --------
36073 + | FQID (24) || PP (8) |
36074 + ------------------------ --------
36075 + --------
36076 + | | extracted OR byte
36077 + --------
36078 +
36079 + ************************************************************************************/
36080 +
36081 + if (p_ExtractOr->bitOffsetInFqid)
36082 + {
36083 + if (p_ExtractOr->bitOffsetInFqid > MAX_KG_SCH_FQID_BIT_OFFSET )
36084 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Illegal extraction (bitOffsetInFqid out of range)"));
36085 + if (p_ExtractOr->bitOffsetInFqid<8)
36086 + genTmp |= (uint32_t)((p_ExtractOr->bitOffsetInFqid+24) << KG_SCH_GEN_SIZE_SHIFT);
36087 + else
36088 + genTmp |= (uint32_t)((p_ExtractOr->bitOffsetInFqid-8) << KG_SCH_GEN_SIZE_SHIFT);
36089 + p_ExtractOr->mask &= GetExtractedOrMask(p_ExtractOr->bitOffsetInFqid, TRUE);
36090 + }
36091 + else /* effect policer profile */
36092 + {
36093 + if (p_ExtractOr->bitOffsetInPlcrProfile > MAX_KG_SCH_PP_BIT_OFFSET )
36094 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Illegal extraction (bitOffsetInPlcrProfile out of range)"));
36095 + p_Scheme->bitOffsetInPlcrProfile = p_ExtractOr->bitOffsetInPlcrProfile;
36096 + genTmp |= (uint32_t)((p_ExtractOr->bitOffsetInPlcrProfile+16) << KG_SCH_GEN_SIZE_SHIFT);
36097 + p_ExtractOr->mask &= GetExtractedOrMask(p_ExtractOr->bitOffsetInPlcrProfile, FALSE);
36098 + }
36099 +
36100 + genTmp |= (uint32_t)(p_ExtractOr->extractionOffset << KG_SCH_GEN_DEF_SHIFT);
36101 + /* clear bits that need masking */
36102 + genTmp &= ~KG_SCH_GEN_MASK ;
36103 + /* set mask bits */
36104 + genTmp |= (uint32_t)(p_ExtractOr->mask << KG_SCH_GEN_MASK_SHIFT);
36105 + p_SchemeRegs->kgse_gec[currGenId++] = genTmp;
36106 +
36107 + }
36108 + /* clear all unused GEC registers */
36109 + for ( i=currGenId ;i<FM_KG_NUM_OF_GENERIC_REGS ; i++)
36110 + p_SchemeRegs->kgse_gec[i] = 0;
36111 +
36112 + /* add base Qid for this scheme */
36113 + /* add configuration for kgse_fqb */
36114 + if (p_SchemeParams->baseFqid & ~0x00FFFFFF)
36115 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("baseFqid must be between 1 and 2^24-1"));
36116 +
36117 + fqbTmp |= p_SchemeParams->baseFqid;
36118 + p_SchemeRegs->kgse_fqb = fqbTmp;
36119 +
36120 + p_Scheme->nextEngine = p_SchemeParams->nextEngine;
36121 + p_Scheme->doneAction = p_SchemeParams->kgNextEngineParams.doneAction;
36122 +
36123 + return E_OK;
36124 +}
36125 +
36126 +
36127 +/*****************************************************************************/
36128 +/* Inter-module API routines */
36129 +/*****************************************************************************/
36130 +
36131 +t_Error FmPcdKgBuildClsPlanGrp(t_Handle h_FmPcd, t_FmPcdKgInterModuleClsPlanGrpParams *p_Grp, t_FmPcdKgInterModuleClsPlanSet *p_ClsPlanSet)
36132 +{
36133 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
36134 + t_FmPcdKgClsPlanGrp *p_ClsPlanGrp;
36135 + t_FmPcdIpcKgClsPlanParams kgAlloc;
36136 + t_Error err = E_OK;
36137 + uint32_t oredVectors = 0;
36138 + int i, j;
36139 +
36140 + /* this routine is protected by the calling routine ! */
36141 + if (p_Grp->numOfOptions >= FM_PCD_MAX_NUM_OF_OPTIONS(FM_PCD_MAX_NUM_OF_CLS_PLANS))
36142 + RETURN_ERROR(MAJOR, E_INVALID_VALUE,("Too many classification plan basic options selected."));
36143 +
36144 + /* find a new clsPlan group */
36145 + for (i = 0; i < FM_MAX_NUM_OF_PORTS; i++)
36146 + if (!p_FmPcd->p_FmPcdKg->clsPlanGrps[i].used)
36147 + break;
36148 + if (i == FM_MAX_NUM_OF_PORTS)
36149 + RETURN_ERROR(MAJOR, E_FULL,("No classification plan groups available."));
36150 +
36151 + p_FmPcd->p_FmPcdKg->clsPlanGrps[i].used = TRUE;
36152 +
36153 + p_Grp->clsPlanGrpId = (uint8_t)i;
36154 +
36155 + if (p_Grp->numOfOptions == 0)
36156 + p_FmPcd->p_FmPcdKg->emptyClsPlanGrpId = (uint8_t)i;
36157 +
36158 + p_ClsPlanGrp = &p_FmPcd->p_FmPcdKg->clsPlanGrps[i];
36159 + p_ClsPlanGrp->netEnvId = p_Grp->netEnvId;
36160 + p_ClsPlanGrp->owners = 0;
36161 + FmPcdSetClsPlanGrpId(p_FmPcd, p_Grp->netEnvId, p_Grp->clsPlanGrpId);
36162 + if (p_Grp->numOfOptions != 0)
36163 + FmPcdIncNetEnvOwners(p_FmPcd, p_Grp->netEnvId);
36164 +
36165 + p_ClsPlanGrp->sizeOfGrp = (uint16_t)(1 << p_Grp->numOfOptions);
36166 + /* a minimal group of 8 is required */
36167 + if (p_ClsPlanGrp->sizeOfGrp < CLS_PLAN_NUM_PER_GRP)
36168 + p_ClsPlanGrp->sizeOfGrp = CLS_PLAN_NUM_PER_GRP;
36169 + if (p_FmPcd->guestId == NCSW_MASTER_ID)
36170 + {
36171 + err = KgAllocClsPlanEntries(h_FmPcd, p_ClsPlanGrp->sizeOfGrp, p_FmPcd->guestId, &p_ClsPlanGrp->baseEntry);
36172 +
36173 + if (err)
36174 + RETURN_ERROR(MINOR, E_INVALID_STATE, NO_MSG);
36175 + }
36176 + else
36177 + {
36178 + t_FmPcdIpcMsg msg;
36179 + uint32_t replyLength;
36180 + t_FmPcdIpcReply reply;
36181 +
36182 + /* in GUEST_PARTITION, we use the IPC, to also set a private driver group if required */
36183 + memset(&reply, 0, sizeof(reply));
36184 + memset(&msg, 0, sizeof(msg));
36185 + memset(&kgAlloc, 0, sizeof(kgAlloc));
36186 + kgAlloc.guestId = p_FmPcd->guestId;
36187 + kgAlloc.numOfClsPlanEntries = p_ClsPlanGrp->sizeOfGrp;
36188 + msg.msgId = FM_PCD_ALLOC_KG_CLSPLAN;
36189 + memcpy(msg.msgBody, &kgAlloc, sizeof(kgAlloc));
36190 + replyLength = (sizeof(uint32_t) + sizeof(p_ClsPlanGrp->baseEntry));
36191 + if ((err = XX_IpcSendMessage(p_FmPcd->h_IpcSession,
36192 + (uint8_t*)&msg,
36193 + sizeof(msg.msgId) + sizeof(kgAlloc),
36194 + (uint8_t*)&reply,
36195 + &replyLength,
36196 + NULL,
36197 + NULL)) != E_OK)
36198 + RETURN_ERROR(MAJOR, err, NO_MSG);
36199 +
36200 + if (replyLength != (sizeof(uint32_t) + sizeof(p_ClsPlanGrp->baseEntry)))
36201 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch"));
36202 + if ((t_Error)reply.error != E_OK)
36203 + RETURN_ERROR(MINOR, (t_Error)reply.error, NO_MSG);
36204 +
36205 + p_ClsPlanGrp->baseEntry = *(uint8_t*)(reply.replyBody);
36206 + }
36207 +
36208 + /* build classification plan entries parameters */
36209 + p_ClsPlanSet->baseEntry = p_ClsPlanGrp->baseEntry;
36210 + p_ClsPlanSet->numOfClsPlanEntries = p_ClsPlanGrp->sizeOfGrp;
36211 +
36212 + oredVectors = 0;
36213 + for (i = 0; i<p_Grp->numOfOptions; i++)
36214 + {
36215 + oredVectors |= p_Grp->optVectors[i];
36216 + /* save an array of used options - the indexes represent the power of 2 index */
36217 + p_ClsPlanGrp->optArray[i] = p_Grp->options[i];
36218 + }
36219 + /* set the classification plan relevant entries so that all bits
36220 + * relevant to the list of options is cleared
36221 + */
36222 + for (j = 0; j<p_ClsPlanGrp->sizeOfGrp; j++)
36223 + p_ClsPlanSet->vectors[j] = ~oredVectors;
36224 +
36225 + for (i = 0; i<p_Grp->numOfOptions; i++)
36226 + {
36227 + /* option i got the place 2^i in the clsPlan array. all entries that
36228 + * have bit i set, should have the vector bit cleared. So each option
36229 + * has one location that it is exclusive (1,2,4,8...) and represent the
36230 + * presence of that option only, and other locations that represent a
36231 + * combination of options.
36232 + * e.g:
36233 + * If ethernet-BC is option 1 it gets entry 2 in the table. Entry 2
36234 + * now represents a frame with ethernet-BC header - so the bit
36235 + * representing ethernet-BC should be set and all other option bits
36236 + * should be cleared.
36237 + * Entries 2,3,6,7,10... also have ethernet-BC and therefore have bit
36238 + * vector[1] set, but they also have other bits set:
36239 + * 3=1+2, options 0 and 1
36240 + * 6=2+4, options 1 and 2
36241 + * 7=1+2+4, options 0,1,and 2
36242 + * 10=2+8, options 1 and 3
36243 + * etc.
36244 + * */
36245 +
36246 + /* now for each option (i), we set their bits in all entries (j)
36247 + * that contain bit 2^i.
36248 + */
36249 + for (j = 0; j<p_ClsPlanGrp->sizeOfGrp; j++)
36250 + {
36251 + if (j & (1<<i))
36252 + p_ClsPlanSet->vectors[j] |= p_Grp->optVectors[i];
36253 + }
36254 + }
36255 +
36256 + return E_OK;
36257 +}
36258 +
36259 +void FmPcdKgDestroyClsPlanGrp(t_Handle h_FmPcd, uint8_t grpId)
36260 +{
36261 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
36262 + t_FmPcdIpcKgClsPlanParams kgAlloc;
36263 + t_Error err;
36264 + t_FmPcdIpcMsg msg;
36265 + uint32_t replyLength;
36266 + t_FmPcdIpcReply reply;
36267 +
36268 + /* check that no port is bound to this clsPlan */
36269 + if (p_FmPcd->p_FmPcdKg->clsPlanGrps[grpId].owners)
36270 + {
36271 + REPORT_ERROR(MINOR, E_INVALID_STATE, ("Trying to delete a clsPlan grp that has ports bound to"));
36272 + return;
36273 + }
36274 +
36275 + FmPcdSetClsPlanGrpId(p_FmPcd, p_FmPcd->p_FmPcdKg->clsPlanGrps[grpId].netEnvId, ILLEGAL_CLS_PLAN);
36276 +
36277 + if (grpId == p_FmPcd->p_FmPcdKg->emptyClsPlanGrpId)
36278 + p_FmPcd->p_FmPcdKg->emptyClsPlanGrpId = ILLEGAL_CLS_PLAN;
36279 + else
36280 + FmPcdDecNetEnvOwners(p_FmPcd, p_FmPcd->p_FmPcdKg->clsPlanGrps[grpId].netEnvId);
36281 +
36282 + /* free blocks */
36283 + if (p_FmPcd->guestId == NCSW_MASTER_ID)
36284 + KgFreeClsPlanEntries(h_FmPcd,
36285 + p_FmPcd->p_FmPcdKg->clsPlanGrps[grpId].sizeOfGrp,
36286 + p_FmPcd->guestId,
36287 + p_FmPcd->p_FmPcdKg->clsPlanGrps[grpId].baseEntry);
36288 + else /* in GUEST_PARTITION, we use the IPC, to also set a private driver group if required */
36289 + {
36290 + memset(&reply, 0, sizeof(reply));
36291 + memset(&msg, 0, sizeof(msg));
36292 + kgAlloc.guestId = p_FmPcd->guestId;
36293 + kgAlloc.numOfClsPlanEntries = p_FmPcd->p_FmPcdKg->clsPlanGrps[grpId].sizeOfGrp;
36294 + kgAlloc.clsPlanBase = p_FmPcd->p_FmPcdKg->clsPlanGrps[grpId].baseEntry;
36295 + msg.msgId = FM_PCD_FREE_KG_CLSPLAN;
36296 + memcpy(msg.msgBody, &kgAlloc, sizeof(kgAlloc));
36297 + replyLength = sizeof(uint32_t);
36298 + err = XX_IpcSendMessage(p_FmPcd->h_IpcSession,
36299 + (uint8_t*)&msg,
36300 + sizeof(msg.msgId) + sizeof(kgAlloc),
36301 + (uint8_t*)&reply,
36302 + &replyLength,
36303 + NULL,
36304 + NULL);
36305 + if (err != E_OK)
36306 + {
36307 + REPORT_ERROR(MINOR, err, NO_MSG);
36308 + return;
36309 + }
36310 + if (replyLength != sizeof(uint32_t))
36311 + {
36312 + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch"));
36313 + return;
36314 + }
36315 + if ((t_Error)reply.error != E_OK)
36316 + {
36317 + REPORT_ERROR(MAJOR, E_INVALID_STATE, ("Free KG clsPlan failed"));
36318 + return;
36319 + }
36320 + }
36321 +
36322 + /* clear clsPlan driver structure */
36323 + memset(&p_FmPcd->p_FmPcdKg->clsPlanGrps[grpId], 0, sizeof(t_FmPcdKgClsPlanGrp));
36324 +}
36325 +
36326 +t_Error FmPcdKgBuildBindPortToSchemes(t_Handle h_FmPcd, t_FmPcdKgInterModuleBindPortToSchemes *p_BindPort, uint32_t *p_SpReg, bool add)
36327 +{
36328 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
36329 + uint32_t j, schemesPerPortVector = 0;
36330 + t_FmPcdKgScheme *p_Scheme;
36331 + uint8_t i, relativeSchemeId;
36332 + uint32_t tmp, walking1Mask;
36333 + uint8_t swPortIndex = 0;
36334 +
36335 + SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);
36336 + SANITY_CHECK_RETURN_ERROR(p_FmPcd->p_FmPcdKg, E_INVALID_HANDLE);
36337 + SANITY_CHECK_RETURN_ERROR(!p_FmPcd->p_FmPcdDriverParam, E_INVALID_STATE);
36338 +
36339 + /* for each scheme */
36340 + for (i = 0; i<p_BindPort->numOfSchemes; i++)
36341 + {
36342 + relativeSchemeId = FmPcdKgGetRelativeSchemeId(p_FmPcd, p_BindPort->schemesIds[i]);
36343 + if (relativeSchemeId >= FM_PCD_KG_NUM_OF_SCHEMES)
36344 + RETURN_ERROR(MAJOR, E_NOT_IN_RANGE, NO_MSG);
36345 +
36346 + if (add)
36347 + {
36348 + p_Scheme = &p_FmPcd->p_FmPcdKg->schemes[relativeSchemeId];
36349 + if (!FmPcdKgIsSchemeValidSw(p_Scheme))
36350 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Requested scheme is invalid."));
36351 + /* check netEnvId of the port against the scheme netEnvId */
36352 + if ((p_Scheme->netEnvId != p_BindPort->netEnvId) && (p_Scheme->netEnvId != ILLEGAL_NETENV))
36353 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Port may not be bound to requested scheme - differ in netEnvId"));
36354 +
36355 + /* if next engine is private port policer profile, we need to check that it is valid */
36356 + HW_PORT_ID_TO_SW_PORT_INDX(swPortIndex, p_BindPort->hardwarePortId);
36357 + if (p_Scheme->nextRelativePlcrProfile)
36358 + {
36359 + for (j = 0;j<p_Scheme->numOfProfiles;j++)
36360 + {
36361 + ASSERT_COND(p_FmPcd->p_FmPcdPlcr->portsMapping[swPortIndex].h_FmPort);
36362 + if (p_Scheme->relativeProfileId+j >= p_FmPcd->p_FmPcdPlcr->portsMapping[swPortIndex].numOfProfiles)
36363 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Relative profile not in range"));
36364 + if (!FmPcdPlcrIsProfileValid(p_FmPcd, (uint16_t)(p_FmPcd->p_FmPcdPlcr->portsMapping[swPortIndex].profilesBase + p_Scheme->relativeProfileId + j)))
36365 + RETURN_ERROR(MINOR, E_INVALID_STATE, ("Relative profile not valid."));
36366 + }
36367 + }
36368 + if (!p_BindPort->useClsPlan)
36369 + {
36370 + /* This check may be redundant as port is a assigned to the whole NetEnv */
36371 +
36372 + /* if this port does not use clsPlan, it may not be bound to schemes with units that contain
36373 + cls plan options. Schemes that are used only directly, should not be checked.
36374 + it also may not be bound to schemes that go to CC with units that are options - so we OR
36375 + the match vector and the grpBits (= ccUnits) */
36376 + if ((p_Scheme->matchVector != SCHEME_ALWAYS_DIRECT) || p_Scheme->ccUnits)
36377 + {
36378 + uint8_t netEnvId;
36379 + walking1Mask = 0x80000000;
36380 + netEnvId = (p_Scheme->netEnvId == ILLEGAL_NETENV)? p_BindPort->netEnvId:p_Scheme->netEnvId;
36381 + tmp = (p_Scheme->matchVector == SCHEME_ALWAYS_DIRECT)? 0:p_Scheme->matchVector;
36382 + tmp |= p_Scheme->ccUnits;
36383 + while (tmp)
36384 + {
36385 + if (tmp & walking1Mask)
36386 + {
36387 + tmp &= ~walking1Mask;
36388 + if (!PcdNetEnvIsUnitWithoutOpts(p_FmPcd, netEnvId, walking1Mask))
36389 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Port (without clsPlan) may not be bound to requested scheme - uses clsPlan options"));
36390 + }
36391 + walking1Mask >>= 1;
36392 + }
36393 + }
36394 + }
36395 + }
36396 + /* build vector */
36397 + schemesPerPortVector |= 1 << (31 - p_BindPort->schemesIds[i]);
36398 + }
36399 +
36400 + *p_SpReg = schemesPerPortVector;
36401 +
36402 + return E_OK;
36403 +}
36404 +
36405 +t_Error FmPcdKgBindPortToSchemes(t_Handle h_FmPcd , t_FmPcdKgInterModuleBindPortToSchemes *p_SchemeBind)
36406 +{
36407 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
36408 + uint32_t spReg;
36409 + t_Error err = E_OK;
36410 +
36411 + err = FmPcdKgBuildBindPortToSchemes(h_FmPcd, p_SchemeBind, &spReg, TRUE);
36412 + if (err)
36413 + RETURN_ERROR(MAJOR, err, NO_MSG);
36414 +
36415 + err = KgWriteSp(p_FmPcd, p_SchemeBind->hardwarePortId, spReg, TRUE);
36416 + if (err)
36417 + RETURN_ERROR(MAJOR, err, NO_MSG);
36418 +
36419 + IncSchemeOwners(p_FmPcd, p_SchemeBind);
36420 +
36421 + return E_OK;
36422 +}
36423 +
36424 +t_Error FmPcdKgUnbindPortToSchemes(t_Handle h_FmPcd, t_FmPcdKgInterModuleBindPortToSchemes *p_SchemeBind)
36425 +{
36426 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
36427 + uint32_t spReg;
36428 + t_Error err = E_OK;
36429 +
36430 + err = FmPcdKgBuildBindPortToSchemes(p_FmPcd, p_SchemeBind, &spReg, FALSE);
36431 + if (err)
36432 + RETURN_ERROR(MAJOR, err, NO_MSG);
36433 +
36434 + err = KgWriteSp(p_FmPcd, p_SchemeBind->hardwarePortId, spReg, FALSE);
36435 + if (err)
36436 + RETURN_ERROR(MAJOR, err, NO_MSG);
36437 +
36438 + DecSchemeOwners(p_FmPcd, p_SchemeBind);
36439 +
36440 + return E_OK;
36441 +}
36442 +
36443 +bool FmPcdKgIsSchemeValidSw(t_Handle h_Scheme)
36444 +{
36445 + t_FmPcdKgScheme *p_Scheme = (t_FmPcdKgScheme*)h_Scheme;
36446 +
36447 + return p_Scheme->valid;
36448 +}
36449 +
36450 +bool KgIsSchemeAlwaysDirect(t_Handle h_FmPcd, uint8_t schemeId)
36451 +{
36452 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
36453 +
36454 + if (p_FmPcd->p_FmPcdKg->schemes[schemeId].matchVector == SCHEME_ALWAYS_DIRECT)
36455 + return TRUE;
36456 + else
36457 + return FALSE;
36458 +}
36459 +
36460 +t_Error FmPcdKgAllocSchemes(t_Handle h_FmPcd, uint8_t numOfSchemes, uint8_t guestId, uint8_t *p_SchemesIds)
36461 +{
36462 + t_FmPcd *p_FmPcd = (t_FmPcd *)h_FmPcd;
36463 + uint8_t i, j;
36464 +
36465 + SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);
36466 + SANITY_CHECK_RETURN_ERROR(p_FmPcd->p_FmPcdKg, E_INVALID_HANDLE);
36467 +
36468 + /* This routine is issued only on master core of master partition -
36469 + either directly or through IPC, so no need for lock */
36470 +
36471 + for (j = 0, i = 0; i < FM_PCD_KG_NUM_OF_SCHEMES && j < numOfSchemes; i++)
36472 + {
36473 + if (!p_FmPcd->p_FmPcdKg->schemesMng[i].allocated)
36474 + {
36475 + p_FmPcd->p_FmPcdKg->schemesMng[i].allocated = TRUE;
36476 + p_FmPcd->p_FmPcdKg->schemesMng[i].ownerId = guestId;
36477 + p_SchemesIds[j] = i;
36478 + j++;
36479 + }
36480 + }
36481 +
36482 + if (j != numOfSchemes)
36483 + {
36484 + /* roll back */
36485 + for (j--; j; j--)
36486 + {
36487 + p_FmPcd->p_FmPcdKg->schemesMng[p_SchemesIds[j]].allocated = FALSE;
36488 + p_FmPcd->p_FmPcdKg->schemesMng[p_SchemesIds[j]].ownerId = 0;
36489 + p_SchemesIds[j] = 0;
36490 + }
36491 +
36492 + RETURN_ERROR(MAJOR, E_NOT_AVAILABLE, ("No schemes found"));
36493 + }
36494 +
36495 + return E_OK;
36496 +}
36497 +
36498 +t_Error FmPcdKgFreeSchemes(t_Handle h_FmPcd, uint8_t numOfSchemes, uint8_t guestId, uint8_t *p_SchemesIds)
36499 +{
36500 + t_FmPcd *p_FmPcd = (t_FmPcd *)h_FmPcd;
36501 + uint8_t i;
36502 +
36503 + SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);
36504 + SANITY_CHECK_RETURN_ERROR(p_FmPcd->p_FmPcdKg, E_INVALID_HANDLE);
36505 +
36506 + /* This routine is issued only on master core of master partition -
36507 + either directly or through IPC */
36508 +
36509 + for (i = 0; i < numOfSchemes; i++)
36510 + {
36511 + if (!p_FmPcd->p_FmPcdKg->schemesMng[p_SchemesIds[i]].allocated)
36512 + {
36513 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Scheme was not previously allocated"));
36514 + }
36515 + if (p_FmPcd->p_FmPcdKg->schemesMng[p_SchemesIds[i]].ownerId != guestId)
36516 + {
36517 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Scheme is not owned by caller. "));
36518 + }
36519 + p_FmPcd->p_FmPcdKg->schemesMng[p_SchemesIds[i]].allocated = FALSE;
36520 + p_FmPcd->p_FmPcdKg->schemesMng[p_SchemesIds[i]].ownerId = 0;
36521 + }
36522 +
36523 + return E_OK;
36524 +}
36525 +
36526 +t_Error KgAllocClsPlanEntries(t_Handle h_FmPcd, uint16_t numOfClsPlanEntries, uint8_t guestId, uint8_t *p_First)
36527 +{
36528 + t_FmPcd *p_FmPcd = (t_FmPcd *)h_FmPcd;
36529 + uint8_t numOfBlocks, blocksFound=0, first=0;
36530 + uint8_t i, j;
36531 +
36532 + /* This routine is issued only on master core of master partition -
36533 + either directly or through IPC, so no need for lock */
36534 +
36535 + if (!numOfClsPlanEntries)
36536 + return E_OK;
36537 +
36538 + if ((numOfClsPlanEntries % CLS_PLAN_NUM_PER_GRP) || (!POWER_OF_2(numOfClsPlanEntries)))
36539 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("numOfClsPlanEntries must be a power of 2 and divisible by 8"));
36540 +
36541 + numOfBlocks = (uint8_t)(numOfClsPlanEntries/CLS_PLAN_NUM_PER_GRP);
36542 +
36543 + /* try to find consequent blocks */
36544 + first = 0;
36545 + for (i = 0; i < FM_PCD_MAX_NUM_OF_CLS_PLANS/CLS_PLAN_NUM_PER_GRP;)
36546 + {
36547 + if (!p_FmPcd->p_FmPcdKg->clsPlanBlocksMng[i].allocated)
36548 + {
36549 + blocksFound++;
36550 + i++;
36551 + if (blocksFound == numOfBlocks)
36552 + break;
36553 + }
36554 + else
36555 + {
36556 + blocksFound = 0;
36557 + /* advance i to the next aligned address */
36558 + first = i = (uint8_t)(first + numOfBlocks);
36559 + }
36560 + }
36561 +
36562 + if (blocksFound == numOfBlocks)
36563 + {
36564 + *p_First = (uint8_t)(first * CLS_PLAN_NUM_PER_GRP);
36565 + for (j = first; j < (first + numOfBlocks); j++)
36566 + {
36567 + p_FmPcd->p_FmPcdKg->clsPlanBlocksMng[j].allocated = TRUE;
36568 + p_FmPcd->p_FmPcdKg->clsPlanBlocksMng[j].ownerId = guestId;
36569 + }
36570 + return E_OK;
36571 + }
36572 + else
36573 + RETURN_ERROR(MINOR, E_FULL, ("No resources for clsPlan"));
36574 +}
36575 +
36576 +void KgFreeClsPlanEntries(t_Handle h_FmPcd, uint16_t numOfClsPlanEntries, uint8_t guestId, uint8_t base)
36577 +{
36578 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
36579 + uint8_t numOfBlocks;
36580 + uint8_t i, baseBlock;
36581 +
36582 +#ifdef DISABLE_ASSERTIONS
36583 +UNUSED(guestId);
36584 +#endif /* DISABLE_ASSERTIONS */
36585 +
36586 + /* This routine is issued only on master core of master partition -
36587 + either directly or through IPC, so no need for lock */
36588 +
36589 + numOfBlocks = (uint8_t)(numOfClsPlanEntries/CLS_PLAN_NUM_PER_GRP);
36590 + ASSERT_COND(!(base%CLS_PLAN_NUM_PER_GRP));
36591 +
36592 + baseBlock = (uint8_t)(base/CLS_PLAN_NUM_PER_GRP);
36593 + for (i=baseBlock;i<baseBlock+numOfBlocks;i++)
36594 + {
36595 + ASSERT_COND(p_FmPcd->p_FmPcdKg->clsPlanBlocksMng[i].allocated);
36596 + ASSERT_COND(guestId == p_FmPcd->p_FmPcdKg->clsPlanBlocksMng[i].ownerId);
36597 + p_FmPcd->p_FmPcdKg->clsPlanBlocksMng[i].allocated = FALSE;
36598 + p_FmPcd->p_FmPcdKg->clsPlanBlocksMng[i].ownerId = 0;
36599 + }
36600 +}
36601 +
36602 +void KgEnable(t_FmPcd *p_FmPcd)
36603 +{
36604 + struct fman_kg_regs *p_Regs = p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs;
36605 +
36606 + ASSERT_COND(FmIsMaster(p_FmPcd->h_Fm));
36607 + fman_kg_enable(p_Regs);
36608 +}
36609 +
36610 +void KgDisable(t_FmPcd *p_FmPcd)
36611 +{
36612 + struct fman_kg_regs *p_Regs = p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs;
36613 +
36614 + ASSERT_COND(FmIsMaster(p_FmPcd->h_Fm));
36615 + fman_kg_disable(p_Regs);
36616 +}
36617 +
36618 +void KgSetClsPlan(t_Handle h_FmPcd, t_FmPcdKgInterModuleClsPlanSet *p_Set)
36619 +{
36620 + t_FmPcd *p_FmPcd = (t_FmPcd *)h_FmPcd;
36621 + struct fman_kg_cp_regs *p_FmPcdKgPortRegs;
36622 + uint32_t tmpKgarReg = 0, intFlags;
36623 + uint16_t i, j;
36624 +
36625 + /* This routine is protected by the calling routine ! */
36626 + ASSERT_COND(FmIsMaster(p_FmPcd->h_Fm));
36627 + p_FmPcdKgPortRegs = &p_FmPcd->p_FmPcdKg->p_IndirectAccessRegs->clsPlanRegs;
36628 +
36629 + intFlags = KgHwLock(p_FmPcd->p_FmPcdKg);
36630 + for (i=p_Set->baseEntry;i<p_Set->baseEntry+p_Set->numOfClsPlanEntries;i+=8)
36631 + {
36632 + tmpKgarReg = FmPcdKgBuildWriteClsPlanBlockActionReg((uint8_t)(i / CLS_PLAN_NUM_PER_GRP));
36633 +
36634 + for (j = i; j < i+8; j++)
36635 + {
36636 + ASSERT_COND(IN_RANGE(0, (j - p_Set->baseEntry), FM_PCD_MAX_NUM_OF_CLS_PLANS-1));
36637 + WRITE_UINT32(p_FmPcdKgPortRegs->kgcpe[j % CLS_PLAN_NUM_PER_GRP],p_Set->vectors[j - p_Set->baseEntry]);
36638 + }
36639 +
36640 + if (WriteKgarWait(p_FmPcd, tmpKgarReg) != E_OK)
36641 + {
36642 + REPORT_ERROR(MAJOR, E_INVALID_STATE, ("WriteKgarWait FAILED"));
36643 + KgHwUnlock(p_FmPcd->p_FmPcdKg, intFlags);
36644 + return;
36645 + }
36646 + }
36647 + KgHwUnlock(p_FmPcd->p_FmPcdKg, intFlags);
36648 +}
36649 +
36650 +t_Handle KgConfig( t_FmPcd *p_FmPcd, t_FmPcdParams *p_FmPcdParams)
36651 +{
36652 + t_FmPcdKg *p_FmPcdKg;
36653 +
36654 + UNUSED(p_FmPcd);
36655 +
36656 + if (p_FmPcdParams->numOfSchemes > FM_PCD_KG_NUM_OF_SCHEMES)
36657 + {
36658 + REPORT_ERROR(MAJOR, E_INVALID_VALUE,
36659 + ("numOfSchemes should not exceed %d", FM_PCD_KG_NUM_OF_SCHEMES));
36660 + return NULL;
36661 + }
36662 +
36663 + p_FmPcdKg = (t_FmPcdKg *)XX_Malloc(sizeof(t_FmPcdKg));
36664 + if (!p_FmPcdKg)
36665 + {
36666 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FM Keygen allocation FAILED"));
36667 + return NULL;
36668 + }
36669 + memset(p_FmPcdKg, 0, sizeof(t_FmPcdKg));
36670 +
36671 +
36672 + if (FmIsMaster(p_FmPcd->h_Fm))
36673 + {
36674 + p_FmPcdKg->p_FmPcdKgRegs = (struct fman_kg_regs *)UINT_TO_PTR(FmGetPcdKgBaseAddr(p_FmPcdParams->h_Fm));
36675 + p_FmPcd->exceptions |= DEFAULT_fmPcdKgErrorExceptions;
36676 + p_FmPcdKg->p_IndirectAccessRegs = (u_FmPcdKgIndirectAccessRegs *)&p_FmPcdKg->p_FmPcdKgRegs->fmkg_indirect[0];
36677 + }
36678 +
36679 + p_FmPcdKg->numOfSchemes = p_FmPcdParams->numOfSchemes;
36680 + if ((p_FmPcd->guestId == NCSW_MASTER_ID) && !p_FmPcdKg->numOfSchemes)
36681 + {
36682 + p_FmPcdKg->numOfSchemes = FM_PCD_KG_NUM_OF_SCHEMES;
36683 + DBG(WARNING, ("numOfSchemes was defined 0 by user, re-defined by driver to FM_PCD_KG_NUM_OF_SCHEMES"));
36684 + }
36685 +
36686 + p_FmPcdKg->emptyClsPlanGrpId = ILLEGAL_CLS_PLAN;
36687 +
36688 + return p_FmPcdKg;
36689 +}
36690 +
36691 +t_Error KgInit(t_FmPcd *p_FmPcd)
36692 +{
36693 + t_Error err = E_OK;
36694 +
36695 + p_FmPcd->p_FmPcdKg->h_HwSpinlock = XX_InitSpinlock();
36696 + if (!p_FmPcd->p_FmPcdKg->h_HwSpinlock)
36697 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("FM KG HW spinlock"));
36698 +
36699 + if (p_FmPcd->guestId == NCSW_MASTER_ID)
36700 + err = KgInitMaster(p_FmPcd);
36701 + else
36702 + err = KgInitGuest(p_FmPcd);
36703 +
36704 + if (err != E_OK)
36705 + {
36706 + if (p_FmPcd->p_FmPcdKg->h_HwSpinlock)
36707 + XX_FreeSpinlock(p_FmPcd->p_FmPcdKg->h_HwSpinlock);
36708 + }
36709 +
36710 + return err;
36711 +}
36712 +
36713 +t_Error KgFree(t_FmPcd *p_FmPcd)
36714 +{
36715 + t_FmPcdIpcKgSchemesParams kgAlloc;
36716 + t_Error err = E_OK;
36717 + t_FmPcdIpcMsg msg;
36718 + uint32_t replyLength;
36719 + t_FmPcdIpcReply reply;
36720 +
36721 + FmUnregisterIntr(p_FmPcd->h_Fm, e_FM_MOD_KG, 0, e_FM_INTR_TYPE_ERR);
36722 +
36723 + if (p_FmPcd->guestId == NCSW_MASTER_ID)
36724 + {
36725 + err = FmPcdKgFreeSchemes(p_FmPcd,
36726 + p_FmPcd->p_FmPcdKg->numOfSchemes,
36727 + p_FmPcd->guestId,
36728 + p_FmPcd->p_FmPcdKg->schemesIds);
36729 + if (err)
36730 + RETURN_ERROR(MAJOR, err, NO_MSG);
36731 +
36732 + if (p_FmPcd->p_FmPcdKg->h_HwSpinlock)
36733 + XX_FreeSpinlock(p_FmPcd->p_FmPcdKg->h_HwSpinlock);
36734 +
36735 + return E_OK;
36736 + }
36737 +
36738 + /* guest */
36739 + memset(&reply, 0, sizeof(reply));
36740 + memset(&msg, 0, sizeof(msg));
36741 + kgAlloc.numOfSchemes = p_FmPcd->p_FmPcdKg->numOfSchemes;
36742 + kgAlloc.guestId = p_FmPcd->guestId;
36743 + ASSERT_COND(kgAlloc.numOfSchemes < FM_PCD_KG_NUM_OF_SCHEMES);
36744 + memcpy(kgAlloc.schemesIds, p_FmPcd->p_FmPcdKg->schemesIds, (sizeof(uint8_t))*kgAlloc.numOfSchemes);
36745 + msg.msgId = FM_PCD_FREE_KG_SCHEMES;
36746 + memcpy(msg.msgBody, &kgAlloc, sizeof(kgAlloc));
36747 + replyLength = sizeof(uint32_t);
36748 + if ((err = XX_IpcSendMessage(p_FmPcd->h_IpcSession,
36749 + (uint8_t*)&msg,
36750 + sizeof(msg.msgId) + sizeof(kgAlloc),
36751 + (uint8_t*)&reply,
36752 + &replyLength,
36753 + NULL,
36754 + NULL)) != E_OK)
36755 + RETURN_ERROR(MAJOR, err, NO_MSG);
36756 + if (replyLength != sizeof(uint32_t))
36757 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch"));
36758 +
36759 + if (p_FmPcd->p_FmPcdKg->h_HwSpinlock)
36760 + XX_FreeSpinlock(p_FmPcd->p_FmPcdKg->h_HwSpinlock);
36761 +
36762 + return (t_Error)reply.error;
36763 +}
36764 +
36765 +t_Error FmPcdKgSetOrBindToClsPlanGrp(t_Handle h_FmPcd, uint8_t hardwarePortId, uint8_t netEnvId, protocolOpt_t *p_OptArray, uint8_t *p_ClsPlanGrpId, bool *p_IsEmptyClsPlanGrp)
36766 +{
36767 + t_FmPcd *p_FmPcd = (t_FmPcd *)h_FmPcd;
36768 + t_FmPcdKgInterModuleClsPlanGrpParams grpParams, *p_GrpParams;
36769 + t_FmPcdKgClsPlanGrp *p_ClsPlanGrp;
36770 + t_FmPcdKgInterModuleClsPlanSet *p_ClsPlanSet;
36771 + t_Error err;
36772 +
36773 + /* This function is issued only from FM_PORT_SetPcd which locked all PCD modules,
36774 + so no need for lock here */
36775 +
36776 + memset(&grpParams, 0, sizeof(grpParams));
36777 + grpParams.clsPlanGrpId = ILLEGAL_CLS_PLAN;
36778 + p_GrpParams = &grpParams;
36779 +
36780 + p_GrpParams->netEnvId = netEnvId;
36781 +
36782 + /* Get from the NetEnv the information of the clsPlan (can be already created,
36783 + * or needs to build) */
36784 + err = PcdGetClsPlanGrpParams(h_FmPcd, p_GrpParams);
36785 + if (err)
36786 + RETURN_ERROR(MINOR,err,NO_MSG);
36787 +
36788 + if (p_GrpParams->grpExists)
36789 + {
36790 + /* this group was already updated (at least) in SW */
36791 + *p_ClsPlanGrpId = p_GrpParams->clsPlanGrpId;
36792 + }
36793 + else
36794 + {
36795 + p_ClsPlanSet = (t_FmPcdKgInterModuleClsPlanSet *)XX_Malloc(sizeof(t_FmPcdKgInterModuleClsPlanSet));
36796 + if (!p_ClsPlanSet)
36797 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("Classification plan set"));
36798 + memset(p_ClsPlanSet, 0, sizeof(t_FmPcdKgInterModuleClsPlanSet));
36799 + /* Build (in SW) the clsPlan parameters, including the vectors to be written to HW */
36800 + err = FmPcdKgBuildClsPlanGrp(h_FmPcd, p_GrpParams, p_ClsPlanSet);
36801 + if (err)
36802 + {
36803 + XX_Free(p_ClsPlanSet);
36804 + RETURN_ERROR(MINOR, err, NO_MSG);
36805 + }
36806 + *p_ClsPlanGrpId = p_GrpParams->clsPlanGrpId;
36807 +
36808 + if (p_FmPcd->h_Hc)
36809 + {
36810 + /* write clsPlan entries to memory */
36811 + err = FmHcPcdKgSetClsPlan(p_FmPcd->h_Hc, p_ClsPlanSet);
36812 + if (err)
36813 + {
36814 + XX_Free(p_ClsPlanSet);
36815 + RETURN_ERROR(MAJOR, err, NO_MSG);
36816 + }
36817 + }
36818 + else
36819 + /* write clsPlan entries to memory */
36820 + KgSetClsPlan(p_FmPcd, p_ClsPlanSet);
36821 +
36822 + XX_Free(p_ClsPlanSet);
36823 + }
36824 +
36825 + /* Set caller parameters */
36826 +
36827 + /* mark if this is an empty classification group */
36828 + if (*p_ClsPlanGrpId == p_FmPcd->p_FmPcdKg->emptyClsPlanGrpId)
36829 + *p_IsEmptyClsPlanGrp = TRUE;
36830 + else
36831 + *p_IsEmptyClsPlanGrp = FALSE;
36832 +
36833 + p_ClsPlanGrp = &p_FmPcd->p_FmPcdKg->clsPlanGrps[*p_ClsPlanGrpId];
36834 +
36835 + /* increment owners number */
36836 + p_ClsPlanGrp->owners++;
36837 +
36838 + /* copy options array for port */
36839 + 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));
36840 +
36841 + /* bind port to the new or existing group */
36842 + err = BindPortToClsPlanGrp(p_FmPcd, hardwarePortId, p_GrpParams->clsPlanGrpId);
36843 + if (err)
36844 + RETURN_ERROR(MINOR, err, NO_MSG);
36845 +
36846 + return E_OK;
36847 +}
36848 +
36849 +t_Error FmPcdKgDeleteOrUnbindPortToClsPlanGrp(t_Handle h_FmPcd, uint8_t hardwarePortId, uint8_t clsPlanGrpId)
36850 +{
36851 + t_FmPcd *p_FmPcd = (t_FmPcd *)h_FmPcd;
36852 + t_FmPcdKgClsPlanGrp *p_ClsPlanGrp = &p_FmPcd->p_FmPcdKg->clsPlanGrps[clsPlanGrpId];
36853 + t_FmPcdKgInterModuleClsPlanSet *p_ClsPlanSet;
36854 + t_Error err;
36855 +
36856 + /* This function is issued only from FM_PORT_DeletePcd which locked all PCD modules,
36857 + so no need for lock here */
36858 +
36859 + UnbindPortToClsPlanGrp(p_FmPcd, hardwarePortId);
36860 +
36861 + /* decrement owners number */
36862 + ASSERT_COND(p_ClsPlanGrp->owners);
36863 + p_ClsPlanGrp->owners--;
36864 +
36865 + if (!p_ClsPlanGrp->owners)
36866 + {
36867 + if (p_FmPcd->h_Hc)
36868 + {
36869 + err = FmHcPcdKgDeleteClsPlan(p_FmPcd->h_Hc, clsPlanGrpId);
36870 + return err;
36871 + }
36872 + else
36873 + {
36874 + /* clear clsPlan entries in memory */
36875 + p_ClsPlanSet = (t_FmPcdKgInterModuleClsPlanSet *)XX_Malloc(sizeof(t_FmPcdKgInterModuleClsPlanSet));
36876 + if (!p_ClsPlanSet)
36877 + {
36878 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("Classification plan set"));
36879 + }
36880 + memset(p_ClsPlanSet, 0, sizeof(t_FmPcdKgInterModuleClsPlanSet));
36881 +
36882 + p_ClsPlanSet->baseEntry = p_FmPcd->p_FmPcdKg->clsPlanGrps[clsPlanGrpId].baseEntry;
36883 + p_ClsPlanSet->numOfClsPlanEntries = p_FmPcd->p_FmPcdKg->clsPlanGrps[clsPlanGrpId].sizeOfGrp;
36884 + KgSetClsPlan(p_FmPcd, p_ClsPlanSet);
36885 + XX_Free(p_ClsPlanSet);
36886 +
36887 + FmPcdKgDestroyClsPlanGrp(h_FmPcd, clsPlanGrpId);
36888 + }
36889 + }
36890 + return E_OK;
36891 +}
36892 +
36893 +uint32_t FmPcdKgGetRequiredAction(t_Handle h_FmPcd, uint8_t schemeId)
36894 +{
36895 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
36896 + ASSERT_COND(p_FmPcd->p_FmPcdKg->schemes[schemeId].valid);
36897 +
36898 + return p_FmPcd->p_FmPcdKg->schemes[schemeId].requiredAction;
36899 +}
36900 +
36901 +uint32_t FmPcdKgGetRequiredActionFlag(t_Handle h_FmPcd, uint8_t schemeId)
36902 +{
36903 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
36904 +
36905 + ASSERT_COND(p_FmPcd->p_FmPcdKg->schemes[schemeId].valid);
36906 +
36907 + return p_FmPcd->p_FmPcdKg->schemes[schemeId].requiredActionFlag;
36908 +}
36909 +
36910 +bool FmPcdKgIsDirectPlcr(t_Handle h_FmPcd, uint8_t schemeId)
36911 +{
36912 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
36913 +
36914 + ASSERT_COND(p_FmPcd->p_FmPcdKg->schemes[schemeId].valid);
36915 +
36916 + return p_FmPcd->p_FmPcdKg->schemes[schemeId].directPlcr;
36917 +}
36918 +
36919 +
36920 +uint16_t FmPcdKgGetRelativeProfileId(t_Handle h_FmPcd, uint8_t schemeId)
36921 +{
36922 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
36923 +
36924 + ASSERT_COND(p_FmPcd->p_FmPcdKg->schemes[schemeId].valid);
36925 +
36926 + return p_FmPcd->p_FmPcdKg->schemes[schemeId].relativeProfileId;
36927 +}
36928 +
36929 +bool FmPcdKgIsDistrOnPlcrProfile(t_Handle h_FmPcd, uint8_t schemeId)
36930 +{
36931 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
36932 +
36933 + ASSERT_COND(p_FmPcd->p_FmPcdKg->schemes[schemeId].valid);
36934 +
36935 + if ((p_FmPcd->p_FmPcdKg->schemes[schemeId].extractedOrs &&
36936 + p_FmPcd->p_FmPcdKg->schemes[schemeId].bitOffsetInPlcrProfile) ||
36937 + p_FmPcd->p_FmPcdKg->schemes[schemeId].nextRelativePlcrProfile)
36938 + return TRUE;
36939 + else
36940 + return FALSE;
36941 +
36942 +}
36943 +
36944 +e_FmPcdEngine FmPcdKgGetNextEngine(t_Handle h_FmPcd, uint8_t relativeSchemeId)
36945 +{
36946 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
36947 +
36948 + ASSERT_COND(p_FmPcd->p_FmPcdKg->schemes[relativeSchemeId].valid);
36949 +
36950 + return p_FmPcd->p_FmPcdKg->schemes[relativeSchemeId].nextEngine;
36951 +}
36952 +
36953 +e_FmPcdDoneAction FmPcdKgGetDoneAction(t_Handle h_FmPcd, uint8_t schemeId)
36954 +{
36955 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
36956 +
36957 + ASSERT_COND(p_FmPcd->p_FmPcdKg->schemes[schemeId].valid);
36958 +
36959 + return p_FmPcd->p_FmPcdKg->schemes[schemeId].doneAction;
36960 +}
36961 +
36962 +void FmPcdKgUpdateRequiredAction(t_Handle h_Scheme, uint32_t requiredAction)
36963 +{
36964 + t_FmPcdKgScheme *p_Scheme = (t_FmPcdKgScheme *)h_Scheme;
36965 +
36966 + /* this routine is protected by calling routine */
36967 +
36968 + ASSERT_COND(p_Scheme->valid);
36969 +
36970 + p_Scheme->requiredAction |= requiredAction;
36971 +}
36972 +
36973 +bool FmPcdKgHwSchemeIsValid(uint32_t schemeModeReg)
36974 +{
36975 + return (bool)!!(schemeModeReg & KG_SCH_MODE_EN);
36976 +}
36977 +
36978 +uint32_t FmPcdKgBuildWriteSchemeActionReg(uint8_t schemeId, bool updateCounter)
36979 +{
36980 + return (uint32_t)(((uint32_t)schemeId << FM_PCD_KG_KGAR_NUM_SHIFT) |
36981 + FM_KG_KGAR_GO |
36982 + FM_KG_KGAR_WRITE |
36983 + FM_KG_KGAR_SEL_SCHEME_ENTRY |
36984 + DUMMY_PORT_ID |
36985 + (updateCounter ? FM_KG_KGAR_SCM_WSEL_UPDATE_CNT:0));
36986 +}
36987 +
36988 +uint32_t FmPcdKgBuildReadSchemeActionReg(uint8_t schemeId)
36989 +{
36990 + return (uint32_t)(((uint32_t)schemeId << FM_PCD_KG_KGAR_NUM_SHIFT) |
36991 + FM_KG_KGAR_GO |
36992 + FM_KG_KGAR_READ |
36993 + FM_KG_KGAR_SEL_SCHEME_ENTRY |
36994 + DUMMY_PORT_ID |
36995 + FM_KG_KGAR_SCM_WSEL_UPDATE_CNT);
36996 +
36997 +}
36998 +
36999 +uint32_t FmPcdKgBuildWriteClsPlanBlockActionReg(uint8_t grpId)
37000 +{
37001 + return (uint32_t)(FM_KG_KGAR_GO |
37002 + FM_KG_KGAR_WRITE |
37003 + FM_PCD_KG_KGAR_SEL_CLS_PLAN_ENTRY |
37004 + DUMMY_PORT_ID |
37005 + ((uint32_t)grpId << FM_PCD_KG_KGAR_NUM_SHIFT) |
37006 + FM_PCD_KG_KGAR_WSEL_MASK);
37007 +
37008 + /* if we ever want to write 1 by 1, use:
37009 + sel = (uint8_t)(0x01 << (7- (entryId % CLS_PLAN_NUM_PER_GRP)));
37010 + */
37011 +}
37012 +
37013 +uint32_t FmPcdKgBuildWritePortSchemeBindActionReg(uint8_t hardwarePortId)
37014 +{
37015 +
37016 + return (uint32_t)(FM_KG_KGAR_GO |
37017 + FM_KG_KGAR_WRITE |
37018 + FM_PCD_KG_KGAR_SEL_PORT_ENTRY |
37019 + hardwarePortId |
37020 + FM_PCD_KG_KGAR_SEL_PORT_WSEL_SP);
37021 +}
37022 +
37023 +uint32_t FmPcdKgBuildReadPortSchemeBindActionReg(uint8_t hardwarePortId)
37024 +{
37025 +
37026 + return (uint32_t)(FM_KG_KGAR_GO |
37027 + FM_KG_KGAR_READ |
37028 + FM_PCD_KG_KGAR_SEL_PORT_ENTRY |
37029 + hardwarePortId |
37030 + FM_PCD_KG_KGAR_SEL_PORT_WSEL_SP);
37031 +}
37032 +
37033 +uint32_t FmPcdKgBuildWritePortClsPlanBindActionReg(uint8_t hardwarePortId)
37034 +{
37035 +
37036 + return (uint32_t)(FM_KG_KGAR_GO |
37037 + FM_KG_KGAR_WRITE |
37038 + FM_PCD_KG_KGAR_SEL_PORT_ENTRY |
37039 + hardwarePortId |
37040 + FM_PCD_KG_KGAR_SEL_PORT_WSEL_CPP);
37041 +}
37042 +
37043 +uint8_t FmPcdKgGetClsPlanGrpBase(t_Handle h_FmPcd, uint8_t clsPlanGrp)
37044 +{
37045 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
37046 +
37047 + return p_FmPcd->p_FmPcdKg->clsPlanGrps[clsPlanGrp].baseEntry;
37048 +}
37049 +
37050 +uint16_t FmPcdKgGetClsPlanGrpSize(t_Handle h_FmPcd, uint8_t clsPlanGrp)
37051 +{
37052 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
37053 +
37054 + return p_FmPcd->p_FmPcdKg->clsPlanGrps[clsPlanGrp].sizeOfGrp;
37055 +}
37056 +
37057 +
37058 +uint8_t FmPcdKgGetSchemeId(t_Handle h_Scheme)
37059 +{
37060 + return ((t_FmPcdKgScheme*)h_Scheme)->schemeId;
37061 +
37062 +}
37063 +
37064 +#if (DPAA_VERSION >= 11)
37065 +bool FmPcdKgGetVspe(t_Handle h_Scheme)
37066 +{
37067 + return ((t_FmPcdKgScheme*)h_Scheme)->vspe;
37068 +
37069 +}
37070 +#endif /* (DPAA_VERSION >= 11) */
37071 +
37072 +uint8_t FmPcdKgGetRelativeSchemeId(t_Handle h_FmPcd, uint8_t schemeId)
37073 +{
37074 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
37075 + uint8_t i;
37076 +
37077 + for (i = 0;i<p_FmPcd->p_FmPcdKg->numOfSchemes;i++)
37078 + if (p_FmPcd->p_FmPcdKg->schemesIds[i] == schemeId)
37079 + return i;
37080 +
37081 + if (i == p_FmPcd->p_FmPcdKg->numOfSchemes)
37082 + REPORT_ERROR(MAJOR, E_NOT_IN_RANGE, ("Scheme is out of partition range"));
37083 +
37084 + return FM_PCD_KG_NUM_OF_SCHEMES;
37085 +}
37086 +
37087 +t_Handle FmPcdKgGetSchemeHandle(t_Handle h_FmPcd, uint8_t relativeSchemeId)
37088 +{
37089 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
37090 +
37091 + ASSERT_COND(p_FmPcd);
37092 +
37093 + /* check that schemeId is in range */
37094 + if (relativeSchemeId >= p_FmPcd->p_FmPcdKg->numOfSchemes)
37095 + {
37096 + REPORT_ERROR(MAJOR, E_NOT_IN_RANGE, ("relative-scheme-id %d!", relativeSchemeId));
37097 + return NULL;
37098 + }
37099 +
37100 + if (!FmPcdKgIsSchemeValidSw(&p_FmPcd->p_FmPcdKg->schemes[relativeSchemeId]))
37101 + return NULL;
37102 +
37103 + return &p_FmPcd->p_FmPcdKg->schemes[relativeSchemeId];
37104 +}
37105 +
37106 +bool FmPcdKgIsSchemeHasOwners(t_Handle h_Scheme)
37107 +{
37108 + return (((t_FmPcdKgScheme*)h_Scheme)->owners == 0)?FALSE:TRUE;
37109 +}
37110 +
37111 +t_Error FmPcdKgCcGetSetParams(t_Handle h_FmPcd, t_Handle h_Scheme, uint32_t requiredAction, uint32_t value)
37112 +{
37113 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
37114 + uint8_t relativeSchemeId, physicalSchemeId;
37115 + uint32_t tmpKgarReg, tmpReg32 = 0, intFlags;
37116 + t_Error err;
37117 + t_FmPcdKgScheme *p_Scheme = (t_FmPcdKgScheme*)h_Scheme;
37118 +
37119 + SANITY_CHECK_RETURN_VALUE(h_FmPcd, E_INVALID_HANDLE, 0);
37120 + SANITY_CHECK_RETURN_VALUE(p_FmPcd->p_FmPcdKg, E_INVALID_HANDLE, 0);
37121 + SANITY_CHECK_RETURN_VALUE(!p_FmPcd->p_FmPcdDriverParam, E_INVALID_STATE, 0);
37122 +
37123 + /* Calling function locked all PCD modules, so no need to lock here */
37124 +
37125 + if (!FmPcdKgIsSchemeValidSw(h_Scheme))
37126 + RETURN_ERROR(MAJOR, E_ALREADY_EXISTS, ("Scheme is Invalid"));
37127 +
37128 + if (p_FmPcd->h_Hc)
37129 + {
37130 + err = FmHcPcdKgCcGetSetParams(p_FmPcd->h_Hc, h_Scheme, requiredAction, value);
37131 +
37132 + UpdateRequiredActionFlag(h_Scheme,TRUE);
37133 + FmPcdKgUpdateRequiredAction(h_Scheme,requiredAction);
37134 + return err;
37135 + }
37136 +
37137 + physicalSchemeId = p_Scheme->schemeId;
37138 +
37139 + relativeSchemeId = FmPcdKgGetRelativeSchemeId(p_FmPcd, physicalSchemeId);
37140 + if (relativeSchemeId >= FM_PCD_KG_NUM_OF_SCHEMES)
37141 + RETURN_ERROR(MAJOR, E_NOT_IN_RANGE, NO_MSG);
37142 +
37143 + if (!p_FmPcd->p_FmPcdKg->schemes[relativeSchemeId].requiredActionFlag ||
37144 + !(p_FmPcd->p_FmPcdKg->schemes[relativeSchemeId].requiredAction & requiredAction))
37145 + {
37146 + if (requiredAction & UPDATE_NIA_ENQ_WITHOUT_DMA)
37147 + {
37148 + switch (p_FmPcd->p_FmPcdKg->schemes[relativeSchemeId].nextEngine)
37149 + {
37150 + case (e_FM_PCD_DONE):
37151 + if (p_FmPcd->p_FmPcdKg->schemes[relativeSchemeId].doneAction == e_FM_PCD_ENQ_FRAME)
37152 + {
37153 + tmpKgarReg = FmPcdKgBuildReadSchemeActionReg(physicalSchemeId);
37154 + intFlags = KgHwLock(p_FmPcd->p_FmPcdKg);
37155 + WriteKgarWait(p_FmPcd, tmpKgarReg);
37156 + tmpReg32 = GET_UINT32(p_FmPcd->p_FmPcdKg->p_IndirectAccessRegs->schemeRegs.kgse_mode);
37157 + ASSERT_COND(tmpReg32 & (NIA_ENG_BMI | NIA_BMI_AC_ENQ_FRAME));
37158 + WRITE_UINT32(p_FmPcd->p_FmPcdKg->p_IndirectAccessRegs->schemeRegs.kgse_mode, tmpReg32 | NIA_BMI_AC_ENQ_FRAME_WITHOUT_DMA);
37159 + /* call indirect command for scheme write */
37160 + tmpKgarReg = FmPcdKgBuildWriteSchemeActionReg(physicalSchemeId, FALSE);
37161 + WriteKgarWait(p_FmPcd, tmpKgarReg);
37162 + KgHwUnlock(p_FmPcd->p_FmPcdKg, intFlags);
37163 + }
37164 + break;
37165 + case (e_FM_PCD_PLCR):
37166 + if (!p_FmPcd->p_FmPcdKg->schemes[relativeSchemeId].directPlcr ||
37167 + (p_FmPcd->p_FmPcdKg->schemes[relativeSchemeId].extractedOrs &&
37168 + p_FmPcd->p_FmPcdKg->schemes[relativeSchemeId].bitOffsetInPlcrProfile) ||
37169 + p_FmPcd->p_FmPcdKg->schemes[relativeSchemeId].nextRelativePlcrProfile)
37170 + {
37171 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("In this situation PP can not be with distribution and has to be shared"));
37172 + }
37173 + err = FmPcdPlcrCcGetSetParams(h_FmPcd, p_FmPcd->p_FmPcdKg->schemes[relativeSchemeId].relativeProfileId, requiredAction);
37174 + if (err)
37175 + {
37176 + RETURN_ERROR(MAJOR, err, NO_MSG);
37177 + }
37178 + break;
37179 + default:
37180 + RETURN_ERROR(MAJOR, E_INVALID_VALUE,("in this situation the next engine after scheme can be or PLCR or ENQ_FRAME"));
37181 + }
37182 + }
37183 + if (requiredAction & UPDATE_KG_NIA_CC_WA)
37184 + {
37185 + if (p_FmPcd->p_FmPcdKg->schemes[relativeSchemeId].nextEngine == e_FM_PCD_CC)
37186 + {
37187 + tmpKgarReg = FmPcdKgBuildReadSchemeActionReg(physicalSchemeId);
37188 + intFlags = KgHwLock(p_FmPcd->p_FmPcdKg);
37189 + WriteKgarWait(p_FmPcd, tmpKgarReg);
37190 + tmpReg32 = GET_UINT32(p_FmPcd->p_FmPcdKg->p_IndirectAccessRegs->schemeRegs.kgse_mode);
37191 + ASSERT_COND(tmpReg32 & (NIA_ENG_FM_CTL | NIA_FM_CTL_AC_CC));
37192 + tmpReg32 &= ~NIA_FM_CTL_AC_CC;
37193 + WRITE_UINT32(p_FmPcd->p_FmPcdKg->p_IndirectAccessRegs->schemeRegs.kgse_mode, tmpReg32 | NIA_FM_CTL_AC_PRE_CC);
37194 + /* call indirect command for scheme write */
37195 + tmpKgarReg = FmPcdKgBuildWriteSchemeActionReg(physicalSchemeId, FALSE);
37196 + WriteKgarWait(p_FmPcd, tmpKgarReg);
37197 + KgHwUnlock(p_FmPcd->p_FmPcdKg, intFlags);
37198 + }
37199 + }
37200 + if (requiredAction & UPDATE_KG_OPT_MODE)
37201 + {
37202 + tmpKgarReg = FmPcdKgBuildReadSchemeActionReg(physicalSchemeId);
37203 + intFlags = KgHwLock(p_FmPcd->p_FmPcdKg);
37204 + WriteKgarWait(p_FmPcd, tmpKgarReg);
37205 + WRITE_UINT32(p_FmPcd->p_FmPcdKg->p_IndirectAccessRegs->schemeRegs.kgse_om, value);
37206 + /* call indirect command for scheme write */
37207 + tmpKgarReg = FmPcdKgBuildWriteSchemeActionReg(physicalSchemeId, FALSE);
37208 + WriteKgarWait(p_FmPcd, tmpKgarReg);
37209 + KgHwUnlock(p_FmPcd->p_FmPcdKg, intFlags);
37210 + }
37211 + if (requiredAction & UPDATE_KG_NIA)
37212 + {
37213 + tmpKgarReg = FmPcdKgBuildReadSchemeActionReg(physicalSchemeId);
37214 + intFlags = KgHwLock(p_FmPcd->p_FmPcdKg);
37215 + WriteKgarWait(p_FmPcd, tmpKgarReg);
37216 + tmpReg32 = GET_UINT32(p_FmPcd->p_FmPcdKg->p_IndirectAccessRegs->schemeRegs.kgse_mode);
37217 + tmpReg32 &= ~(NIA_ENG_MASK | NIA_AC_MASK);
37218 + tmpReg32 |= value;
37219 + WRITE_UINT32(p_FmPcd->p_FmPcdKg->p_IndirectAccessRegs->schemeRegs.kgse_mode, tmpReg32);
37220 + /* call indirect command for scheme write */
37221 + tmpKgarReg = FmPcdKgBuildWriteSchemeActionReg(physicalSchemeId, FALSE);
37222 + WriteKgarWait(p_FmPcd, tmpKgarReg);
37223 + KgHwUnlock(p_FmPcd->p_FmPcdKg, intFlags);
37224 + }
37225 + }
37226 +
37227 + UpdateRequiredActionFlag(h_Scheme, TRUE);
37228 + FmPcdKgUpdateRequiredAction(h_Scheme, requiredAction);
37229 +
37230 + return E_OK;
37231 +}
37232 +/*********************** End of inter-module routines ************************/
37233 +
37234 +
37235 +/****************************************/
37236 +/* API routines */
37237 +/****************************************/
37238 +
37239 +t_Handle FM_PCD_KgSchemeSet(t_Handle h_FmPcd, t_FmPcdKgSchemeParams *p_SchemeParams)
37240 +{
37241 + t_FmPcd *p_FmPcd;
37242 + struct fman_kg_scheme_regs schemeRegs;
37243 + struct fman_kg_scheme_regs *p_MemRegs;
37244 + uint8_t i;
37245 + t_Error err = E_OK;
37246 + uint32_t tmpKgarReg;
37247 + uint32_t intFlags;
37248 + uint8_t physicalSchemeId, relativeSchemeId = 0;
37249 + t_FmPcdKgScheme *p_Scheme;
37250 +
37251 + if (p_SchemeParams->modify)
37252 + {
37253 + p_Scheme = (t_FmPcdKgScheme *)p_SchemeParams->id.h_Scheme;
37254 + p_FmPcd = p_Scheme->h_FmPcd;
37255 +
37256 + SANITY_CHECK_RETURN_VALUE(p_FmPcd, E_INVALID_HANDLE, NULL);
37257 + SANITY_CHECK_RETURN_VALUE(p_FmPcd->p_FmPcdKg, E_INVALID_HANDLE, NULL);
37258 +
37259 + if (!FmPcdKgIsSchemeValidSw(p_Scheme))
37260 + {
37261 + REPORT_ERROR(MAJOR, E_ALREADY_EXISTS,
37262 + ("Scheme is invalid"));
37263 + return NULL;
37264 + }
37265 +
37266 + if (!KgSchemeFlagTryLock(p_Scheme))
37267 + {
37268 + DBG(TRACE, ("Scheme Try Lock - BUSY"));
37269 + /* Signal to caller BUSY condition */
37270 + p_SchemeParams->id.h_Scheme = NULL;
37271 + return NULL;
37272 + }
37273 + }
37274 + else
37275 + {
37276 + p_FmPcd = (t_FmPcd*)h_FmPcd;
37277 +
37278 + SANITY_CHECK_RETURN_VALUE(p_FmPcd, E_INVALID_HANDLE, NULL);
37279 + SANITY_CHECK_RETURN_VALUE(p_FmPcd->p_FmPcdKg, E_INVALID_HANDLE, NULL);
37280 +
37281 + relativeSchemeId = p_SchemeParams->id.relativeSchemeId;
37282 + /* check that schemeId is in range */
37283 + if (relativeSchemeId >= p_FmPcd->p_FmPcdKg->numOfSchemes)
37284 + {
37285 + REPORT_ERROR(MAJOR, E_NOT_IN_RANGE, ("relative-scheme-id %d!", relativeSchemeId));
37286 + return NULL;
37287 + }
37288 +
37289 + p_Scheme = &p_FmPcd->p_FmPcdKg->schemes[relativeSchemeId];
37290 + if (FmPcdKgIsSchemeValidSw(p_Scheme))
37291 + {
37292 + REPORT_ERROR(MAJOR, E_ALREADY_EXISTS,
37293 + ("Scheme id (%d)!", relativeSchemeId));
37294 + return NULL;
37295 + }
37296 + /* Clear all fields, scheme may have beed previously used */
37297 + memset(p_Scheme, 0, sizeof(t_FmPcdKgScheme));
37298 +
37299 + p_Scheme->schemeId = p_FmPcd->p_FmPcdKg->schemesIds[relativeSchemeId];
37300 + p_Scheme->h_FmPcd = p_FmPcd;
37301 +
37302 + p_Scheme->p_Lock = FmPcdAcquireLock(p_FmPcd);
37303 + if (!p_Scheme->p_Lock)
37304 + REPORT_ERROR(MAJOR, E_NOT_AVAILABLE, ("FM KG Scheme lock obj!"));
37305 + }
37306 +
37307 + err = BuildSchemeRegs((t_Handle)p_Scheme, p_SchemeParams, &schemeRegs);
37308 + if (err)
37309 + {
37310 + REPORT_ERROR(MAJOR, err, NO_MSG);
37311 + if (p_SchemeParams->modify)
37312 + KgSchemeFlagUnlock(p_Scheme);
37313 + if (!p_SchemeParams->modify &&
37314 + p_Scheme->p_Lock)
37315 + FmPcdReleaseLock(p_FmPcd, p_Scheme->p_Lock);
37316 + return NULL;
37317 + }
37318 +
37319 + if (p_FmPcd->h_Hc)
37320 + {
37321 + err = FmHcPcdKgSetScheme(p_FmPcd->h_Hc,
37322 + (t_Handle)p_Scheme,
37323 + &schemeRegs,
37324 + p_SchemeParams->schemeCounter.update);
37325 + if (p_SchemeParams->modify)
37326 + KgSchemeFlagUnlock(p_Scheme);
37327 + if (err)
37328 + {
37329 + if (!p_SchemeParams->modify &&
37330 + p_Scheme->p_Lock)
37331 + FmPcdReleaseLock(p_FmPcd, p_Scheme->p_Lock);
37332 + return NULL;
37333 + }
37334 + if (!p_SchemeParams->modify)
37335 + ValidateSchemeSw(p_Scheme);
37336 + return (t_Handle)p_Scheme;
37337 + }
37338 +
37339 + physicalSchemeId = p_Scheme->schemeId;
37340 +
37341 + /* configure all 21 scheme registers */
37342 + p_MemRegs = &p_FmPcd->p_FmPcdKg->p_IndirectAccessRegs->schemeRegs;
37343 + intFlags = KgHwLock(p_FmPcd->p_FmPcdKg);
37344 + WRITE_UINT32(p_MemRegs->kgse_ppc, schemeRegs.kgse_ppc);
37345 + WRITE_UINT32(p_MemRegs->kgse_ccbs, schemeRegs.kgse_ccbs);
37346 + WRITE_UINT32(p_MemRegs->kgse_mode, schemeRegs.kgse_mode);
37347 + WRITE_UINT32(p_MemRegs->kgse_mv, schemeRegs.kgse_mv);
37348 + WRITE_UINT32(p_MemRegs->kgse_dv0, schemeRegs.kgse_dv0);
37349 + WRITE_UINT32(p_MemRegs->kgse_dv1, schemeRegs.kgse_dv1);
37350 + WRITE_UINT32(p_MemRegs->kgse_ekdv, schemeRegs.kgse_ekdv);
37351 + WRITE_UINT32(p_MemRegs->kgse_ekfc, schemeRegs.kgse_ekfc);
37352 + WRITE_UINT32(p_MemRegs->kgse_bmch, schemeRegs.kgse_bmch);
37353 + WRITE_UINT32(p_MemRegs->kgse_bmcl, schemeRegs.kgse_bmcl);
37354 + WRITE_UINT32(p_MemRegs->kgse_hc, schemeRegs.kgse_hc);
37355 + WRITE_UINT32(p_MemRegs->kgse_spc, schemeRegs.kgse_spc);
37356 + WRITE_UINT32(p_MemRegs->kgse_fqb, schemeRegs.kgse_fqb);
37357 + WRITE_UINT32(p_MemRegs->kgse_om, schemeRegs.kgse_om);
37358 + WRITE_UINT32(p_MemRegs->kgse_vsp, schemeRegs.kgse_vsp);
37359 + for (i=0 ; i<FM_KG_NUM_OF_GENERIC_REGS ; i++)
37360 + WRITE_UINT32(p_MemRegs->kgse_gec[i], schemeRegs.kgse_gec[i]);
37361 +
37362 + /* call indirect command for scheme write */
37363 + tmpKgarReg = FmPcdKgBuildWriteSchemeActionReg(physicalSchemeId, p_SchemeParams->schemeCounter.update);
37364 +
37365 + WriteKgarWait(p_FmPcd, tmpKgarReg);
37366 + KgHwUnlock(p_FmPcd->p_FmPcdKg, intFlags);
37367 +
37368 + if (!p_SchemeParams->modify)
37369 + ValidateSchemeSw(p_Scheme);
37370 + else
37371 + KgSchemeFlagUnlock(p_Scheme);
37372 +
37373 + return (t_Handle)p_Scheme;
37374 +}
37375 +
37376 +t_Error FM_PCD_KgSchemeDelete(t_Handle h_Scheme)
37377 +{
37378 + t_FmPcd *p_FmPcd;
37379 + uint8_t physicalSchemeId;
37380 + uint32_t tmpKgarReg, intFlags;
37381 + t_Error err = E_OK;
37382 + t_FmPcdKgScheme *p_Scheme = (t_FmPcdKgScheme *)h_Scheme;
37383 +
37384 + SANITY_CHECK_RETURN_ERROR(h_Scheme, E_INVALID_HANDLE);
37385 +
37386 + p_FmPcd = (t_FmPcd*)(p_Scheme->h_FmPcd);
37387 +
37388 + UpdateRequiredActionFlag(h_Scheme, FALSE);
37389 +
37390 + /* check that no port is bound to this scheme */
37391 + err = InvalidateSchemeSw(h_Scheme);
37392 + if (err)
37393 + RETURN_ERROR(MINOR, err, NO_MSG);
37394 +
37395 + if (p_FmPcd->h_Hc)
37396 + {
37397 + err = FmHcPcdKgDeleteScheme(p_FmPcd->h_Hc, h_Scheme);
37398 + if (p_Scheme->p_Lock)
37399 + FmPcdReleaseLock(p_FmPcd, p_Scheme->p_Lock);
37400 + return err;
37401 + }
37402 +
37403 + physicalSchemeId = ((t_FmPcdKgScheme *)h_Scheme)->schemeId;
37404 +
37405 + intFlags = KgHwLock(p_FmPcd->p_FmPcdKg);
37406 + /* clear mode register, including enable bit */
37407 + WRITE_UINT32(p_FmPcd->p_FmPcdKg->p_IndirectAccessRegs->schemeRegs.kgse_mode, 0);
37408 +
37409 + /* call indirect command for scheme write */
37410 + tmpKgarReg = FmPcdKgBuildWriteSchemeActionReg(physicalSchemeId, FALSE);
37411 +
37412 + WriteKgarWait(p_FmPcd, tmpKgarReg);
37413 + KgHwUnlock(p_FmPcd->p_FmPcdKg, intFlags);
37414 +
37415 + if (p_Scheme->p_Lock)
37416 + FmPcdReleaseLock(p_FmPcd, p_Scheme->p_Lock);
37417 +
37418 + return E_OK;
37419 +}
37420 +
37421 +uint32_t FM_PCD_KgSchemeGetCounter(t_Handle h_Scheme)
37422 +{
37423 + t_FmPcd *p_FmPcd;
37424 + uint32_t tmpKgarReg, spc, intFlags;
37425 + uint8_t physicalSchemeId;
37426 +
37427 + SANITY_CHECK_RETURN_VALUE(h_Scheme, E_INVALID_HANDLE, 0);
37428 +
37429 + p_FmPcd = (t_FmPcd*)(((t_FmPcdKgScheme *)h_Scheme)->h_FmPcd);
37430 + if (p_FmPcd->h_Hc)
37431 + return FmHcPcdKgGetSchemeCounter(p_FmPcd->h_Hc, h_Scheme);
37432 +
37433 + physicalSchemeId = ((t_FmPcdKgScheme *)h_Scheme)->schemeId;
37434 +
37435 + if (FmPcdKgGetRelativeSchemeId(p_FmPcd, physicalSchemeId) == FM_PCD_KG_NUM_OF_SCHEMES)
37436 + REPORT_ERROR(MAJOR, E_NOT_IN_RANGE, NO_MSG);
37437 +
37438 + tmpKgarReg = FmPcdKgBuildReadSchemeActionReg(physicalSchemeId);
37439 + intFlags = KgHwLock(p_FmPcd->p_FmPcdKg);
37440 + WriteKgarWait(p_FmPcd, tmpKgarReg);
37441 + if (!(GET_UINT32(p_FmPcd->p_FmPcdKg->p_IndirectAccessRegs->schemeRegs.kgse_mode) & KG_SCH_MODE_EN))
37442 + REPORT_ERROR(MAJOR, E_ALREADY_EXISTS, ("Scheme is Invalid"));
37443 + spc = GET_UINT32(p_FmPcd->p_FmPcdKg->p_IndirectAccessRegs->schemeRegs.kgse_spc);
37444 + KgHwUnlock(p_FmPcd->p_FmPcdKg, intFlags);
37445 +
37446 + return spc;
37447 +}
37448 +
37449 +t_Error FM_PCD_KgSchemeSetCounter(t_Handle h_Scheme, uint32_t value)
37450 +{
37451 + t_FmPcd *p_FmPcd;
37452 + uint32_t tmpKgarReg, intFlags;
37453 + uint8_t physicalSchemeId;
37454 +
37455 + SANITY_CHECK_RETURN_VALUE(h_Scheme, E_INVALID_HANDLE, 0);
37456 +
37457 + p_FmPcd = (t_FmPcd*)(((t_FmPcdKgScheme *)h_Scheme)->h_FmPcd);
37458 +
37459 + if (!FmPcdKgIsSchemeValidSw(h_Scheme))
37460 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Requested scheme is invalid."));
37461 +
37462 + if (p_FmPcd->h_Hc)
37463 + return FmHcPcdKgSetSchemeCounter(p_FmPcd->h_Hc, h_Scheme, value);
37464 +
37465 + physicalSchemeId = ((t_FmPcdKgScheme *)h_Scheme)->schemeId;
37466 + /* check that schemeId is in range */
37467 + if (FmPcdKgGetRelativeSchemeId(p_FmPcd, physicalSchemeId) == FM_PCD_KG_NUM_OF_SCHEMES)
37468 + REPORT_ERROR(MAJOR, E_NOT_IN_RANGE, NO_MSG);
37469 +
37470 + /* read specified scheme into scheme registers */
37471 + tmpKgarReg = FmPcdKgBuildReadSchemeActionReg(physicalSchemeId);
37472 + intFlags = KgHwLock(p_FmPcd->p_FmPcdKg);
37473 + WriteKgarWait(p_FmPcd, tmpKgarReg);
37474 + if (!(GET_UINT32(p_FmPcd->p_FmPcdKg->p_IndirectAccessRegs->schemeRegs.kgse_mode) & KG_SCH_MODE_EN))
37475 + {
37476 + KgHwUnlock(p_FmPcd->p_FmPcdKg, intFlags);
37477 + RETURN_ERROR(MAJOR, E_ALREADY_EXISTS, ("Scheme is Invalid"));
37478 + }
37479 +
37480 + /* change counter value */
37481 + WRITE_UINT32(p_FmPcd->p_FmPcdKg->p_IndirectAccessRegs->schemeRegs.kgse_spc, value);
37482 +
37483 + /* call indirect command for scheme write */
37484 + tmpKgarReg = FmPcdKgBuildWriteSchemeActionReg(physicalSchemeId, TRUE);
37485 +
37486 + WriteKgarWait(p_FmPcd, tmpKgarReg);
37487 + KgHwUnlock(p_FmPcd->p_FmPcdKg, intFlags);
37488 +
37489 + return E_OK;
37490 +}
37491 +
37492 +t_Error FM_PCD_KgSetAdditionalDataAfterParsing(t_Handle h_FmPcd, uint8_t payloadOffset)
37493 +{
37494 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
37495 + struct fman_kg_regs *p_Regs;
37496 +
37497 + SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);
37498 + SANITY_CHECK_RETURN_ERROR(!p_FmPcd->p_FmPcdDriverParam, E_NULL_POINTER);
37499 + SANITY_CHECK_RETURN_ERROR(p_FmPcd->p_FmPcdKg, E_NULL_POINTER);
37500 + SANITY_CHECK_RETURN_ERROR(p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs, E_NULL_POINTER);
37501 +
37502 + p_Regs = p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs;
37503 + if (!FmIsMaster(p_FmPcd->h_Fm))
37504 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("FM_PCD_KgSetAdditionalDataAfterParsing - guest mode!"));
37505 +
37506 + WRITE_UINT32(p_Regs->fmkg_fdor,payloadOffset);
37507 +
37508 + return E_OK;
37509 +}
37510 +
37511 +t_Error FM_PCD_KgSetDfltValue(t_Handle h_FmPcd, uint8_t valueId, uint32_t value)
37512 +{
37513 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
37514 + struct fman_kg_regs *p_Regs;
37515 +
37516 + SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);
37517 + SANITY_CHECK_RETURN_ERROR(((valueId == 0) || (valueId == 1)), E_INVALID_VALUE);
37518 + SANITY_CHECK_RETURN_ERROR(!p_FmPcd->p_FmPcdDriverParam, E_NULL_POINTER);
37519 + SANITY_CHECK_RETURN_ERROR(p_FmPcd->p_FmPcdKg, E_NULL_POINTER);
37520 + SANITY_CHECK_RETURN_ERROR(p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs, E_NULL_POINTER);
37521 +
37522 + p_Regs = p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs;
37523 +
37524 + if (!FmIsMaster(p_FmPcd->h_Fm))
37525 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("FM_PCD_KgSetDfltValue - guest mode!"));
37526 +
37527 + if (valueId == 0)
37528 + WRITE_UINT32(p_Regs->fmkg_gdv0r,value);
37529 + else
37530 + WRITE_UINT32(p_Regs->fmkg_gdv1r,value);
37531 + return E_OK;
37532 +}
37533 --- /dev/null
37534 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/fm_kg.h
37535 @@ -0,0 +1,206 @@
37536 +/*
37537 + * Copyright 2008-2012 Freescale Semiconductor Inc.
37538 + *
37539 + * Redistribution and use in source and binary forms, with or without
37540 + * modification, are permitted provided that the following conditions are met:
37541 + * * Redistributions of source code must retain the above copyright
37542 + * notice, this list of conditions and the following disclaimer.
37543 + * * Redistributions in binary form must reproduce the above copyright
37544 + * notice, this list of conditions and the following disclaimer in the
37545 + * documentation and/or other materials provided with the distribution.
37546 + * * Neither the name of Freescale Semiconductor nor the
37547 + * names of its contributors may be used to endorse or promote products
37548 + * derived from this software without specific prior written permission.
37549 + *
37550 + *
37551 + * ALTERNATIVELY, this software may be distributed under the terms of the
37552 + * GNU General Public License ("GPL") as published by the Free Software
37553 + * Foundation, either version 2 of that License or (at your option) any
37554 + * later version.
37555 + *
37556 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
37557 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
37558 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
37559 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
37560 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
37561 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
37562 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
37563 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
37564 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
37565 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
37566 + */
37567 +
37568 +
37569 +/******************************************************************************
37570 + @File fm_kg.h
37571 +
37572 + @Description FM KG private header
37573 +*//***************************************************************************/
37574 +#ifndef __FM_KG_H
37575 +#define __FM_KG_H
37576 +
37577 +#include "std_ext.h"
37578 +
37579 +/***********************************************************************/
37580 +/* Keygen defines */
37581 +/***********************************************************************/
37582 +/* maskes */
37583 +#if (DPAA_VERSION >= 11)
37584 +#define KG_SCH_VSP_SHIFT_MASK 0x0003f000
37585 +#define KG_SCH_OM_VSPE 0x00000001
37586 +#define KG_SCH_VSP_NO_KSP_EN 0x80000000
37587 +
37588 +#define MAX_SP_SHIFT 23
37589 +#define KG_SCH_VSP_MASK_SHIFT 12
37590 +#define KG_SCH_VSP_SHIFT 24
37591 +#endif /* (DPAA_VERSION >= 11) */
37592 +
37593 +typedef uint32_t t_KnownFieldsMasks;
37594 +#define KG_SCH_KN_PORT_ID 0x80000000
37595 +#define KG_SCH_KN_MACDST 0x40000000
37596 +#define KG_SCH_KN_MACSRC 0x20000000
37597 +#define KG_SCH_KN_TCI1 0x10000000
37598 +#define KG_SCH_KN_TCI2 0x08000000
37599 +#define KG_SCH_KN_ETYPE 0x04000000
37600 +#define KG_SCH_KN_PPPSID 0x02000000
37601 +#define KG_SCH_KN_PPPID 0x01000000
37602 +#define KG_SCH_KN_MPLS1 0x00800000
37603 +#define KG_SCH_KN_MPLS2 0x00400000
37604 +#define KG_SCH_KN_MPLS_LAST 0x00200000
37605 +#define KG_SCH_KN_IPSRC1 0x00100000
37606 +#define KG_SCH_KN_IPDST1 0x00080000
37607 +#define KG_SCH_KN_PTYPE1 0x00040000
37608 +#define KG_SCH_KN_IPTOS_TC1 0x00020000
37609 +#define KG_SCH_KN_IPV6FL1 0x00010000
37610 +#define KG_SCH_KN_IPSRC2 0x00008000
37611 +#define KG_SCH_KN_IPDST2 0x00004000
37612 +#define KG_SCH_KN_PTYPE2 0x00002000
37613 +#define KG_SCH_KN_IPTOS_TC2 0x00001000
37614 +#define KG_SCH_KN_IPV6FL2 0x00000800
37615 +#define KG_SCH_KN_GREPTYPE 0x00000400
37616 +#define KG_SCH_KN_IPSEC_SPI 0x00000200
37617 +#define KG_SCH_KN_IPSEC_NH 0x00000100
37618 +#define KG_SCH_KN_IPPID 0x00000080
37619 +#define KG_SCH_KN_L4PSRC 0x00000004
37620 +#define KG_SCH_KN_L4PDST 0x00000002
37621 +#define KG_SCH_KN_TFLG 0x00000001
37622 +
37623 +typedef uint8_t t_GenericCodes;
37624 +#define KG_SCH_GEN_SHIM1 0x70
37625 +#define KG_SCH_GEN_DEFAULT 0x10
37626 +#define KG_SCH_GEN_PARSE_RESULT_N_FQID 0x20
37627 +#define KG_SCH_GEN_START_OF_FRM 0x40
37628 +#define KG_SCH_GEN_SHIM2 0x71
37629 +#define KG_SCH_GEN_IP_PID_NO_V 0x72
37630 +#define KG_SCH_GEN_ETH 0x03
37631 +#define KG_SCH_GEN_ETH_NO_V 0x73
37632 +#define KG_SCH_GEN_SNAP 0x04
37633 +#define KG_SCH_GEN_SNAP_NO_V 0x74
37634 +#define KG_SCH_GEN_VLAN1 0x05
37635 +#define KG_SCH_GEN_VLAN1_NO_V 0x75
37636 +#define KG_SCH_GEN_VLAN2 0x06
37637 +#define KG_SCH_GEN_VLAN2_NO_V 0x76
37638 +#define KG_SCH_GEN_ETH_TYPE 0x07
37639 +#define KG_SCH_GEN_ETH_TYPE_NO_V 0x77
37640 +#define KG_SCH_GEN_PPP 0x08
37641 +#define KG_SCH_GEN_PPP_NO_V 0x78
37642 +#define KG_SCH_GEN_MPLS1 0x09
37643 +#define KG_SCH_GEN_MPLS2 0x19
37644 +#define KG_SCH_GEN_MPLS3 0x29
37645 +#define KG_SCH_GEN_MPLS1_NO_V 0x79
37646 +#define KG_SCH_GEN_MPLS_LAST 0x0a
37647 +#define KG_SCH_GEN_MPLS_LAST_NO_V 0x7a
37648 +#define KG_SCH_GEN_IPV4 0x0b
37649 +#define KG_SCH_GEN_IPV6 0x1b
37650 +#define KG_SCH_GEN_L3_NO_V 0x7b
37651 +#define KG_SCH_GEN_IPV4_TUNNELED 0x0c
37652 +#define KG_SCH_GEN_IPV6_TUNNELED 0x1c
37653 +#define KG_SCH_GEN_MIN_ENCAP 0x2c
37654 +#define KG_SCH_GEN_IP2_NO_V 0x7c
37655 +#define KG_SCH_GEN_GRE 0x0d
37656 +#define KG_SCH_GEN_GRE_NO_V 0x7d
37657 +#define KG_SCH_GEN_TCP 0x0e
37658 +#define KG_SCH_GEN_UDP 0x1e
37659 +#define KG_SCH_GEN_IPSEC_AH 0x2e
37660 +#define KG_SCH_GEN_SCTP 0x3e
37661 +#define KG_SCH_GEN_DCCP 0x4e
37662 +#define KG_SCH_GEN_IPSEC_ESP 0x6e
37663 +#define KG_SCH_GEN_L4_NO_V 0x7e
37664 +#define KG_SCH_GEN_NEXTHDR 0x7f
37665 +/* shifts */
37666 +#define KG_SCH_PP_SHIFT_HIGH_SHIFT 27
37667 +#define KG_SCH_PP_SHIFT_LOW_SHIFT 12
37668 +#define KG_SCH_PP_MASK_SHIFT 16
37669 +#define KG_SCH_MODE_CCOBASE_SHIFT 24
37670 +#define KG_SCH_DEF_MAC_ADDR_SHIFT 30
37671 +#define KG_SCH_DEF_TCI_SHIFT 28
37672 +#define KG_SCH_DEF_ENET_TYPE_SHIFT 26
37673 +#define KG_SCH_DEF_PPP_SESSION_ID_SHIFT 24
37674 +#define KG_SCH_DEF_PPP_PROTOCOL_ID_SHIFT 22
37675 +#define KG_SCH_DEF_MPLS_LABEL_SHIFT 20
37676 +#define KG_SCH_DEF_IP_ADDR_SHIFT 18
37677 +#define KG_SCH_DEF_PROTOCOL_TYPE_SHIFT 16
37678 +#define KG_SCH_DEF_IP_TOS_TC_SHIFT 14
37679 +#define KG_SCH_DEF_IPV6_FLOW_LABEL_SHIFT 12
37680 +#define KG_SCH_DEF_IPSEC_SPI_SHIFT 10
37681 +#define KG_SCH_DEF_L4_PORT_SHIFT 8
37682 +#define KG_SCH_DEF_TCP_FLAG_SHIFT 6
37683 +#define KG_SCH_HASH_CONFIG_SHIFT_SHIFT 24
37684 +#define KG_SCH_GEN_MASK_SHIFT 16
37685 +#define KG_SCH_GEN_HT_SHIFT 8
37686 +#define KG_SCH_GEN_SIZE_SHIFT 24
37687 +#define KG_SCH_GEN_DEF_SHIFT 29
37688 +#define FM_PCD_KG_KGAR_NUM_SHIFT 16
37689 +
37690 +/* others */
37691 +#define NUM_OF_SW_DEFAULTS 3
37692 +#define MAX_PP_SHIFT 23
37693 +#define MAX_KG_SCH_SIZE 16
37694 +#define MASK_FOR_GENERIC_BASE_ID 0x20
37695 +#define MAX_HASH_SHIFT 40
37696 +#define MAX_KG_SCH_FQID_BIT_OFFSET 31
37697 +#define MAX_KG_SCH_PP_BIT_OFFSET 15
37698 +#define MAX_DIST_FQID_SHIFT 23
37699 +
37700 +#define GET_MASK_SEL_SHIFT(shift,i) \
37701 +switch (i) { \
37702 + case (0):shift = 26;break; \
37703 + case (1):shift = 20;break; \
37704 + case (2):shift = 10;break; \
37705 + case (3):shift = 4;break; \
37706 + default: \
37707 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, NO_MSG); \
37708 +}
37709 +
37710 +#define GET_MASK_OFFSET_SHIFT(shift,i) \
37711 +switch (i) { \
37712 + case (0):shift = 16;break; \
37713 + case (1):shift = 0;break; \
37714 + case (2):shift = 28;break; \
37715 + case (3):shift = 24;break; \
37716 + default: \
37717 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, NO_MSG); \
37718 +}
37719 +
37720 +#define GET_MASK_SHIFT(shift,i) \
37721 +switch (i) { \
37722 + case (0):shift = 24;break; \
37723 + case (1):shift = 16;break; \
37724 + case (2):shift = 8;break; \
37725 + case (3):shift = 0;break; \
37726 + default: \
37727 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, NO_MSG); \
37728 +}
37729 +
37730 +/***********************************************************************/
37731 +/* Keygen defines */
37732 +/***********************************************************************/
37733 +
37734 +#define KG_DOUBLE_MEANING_REGS_OFFSET 0x100
37735 +#define NO_VALIDATION 0x70
37736 +#define KG_ACTION_REG_TO 1024
37737 +#define KG_MAX_PROFILE 255
37738 +#define SCHEME_ALWAYS_DIRECT 0xFFFFFFFF
37739 +
37740 +
37741 +#endif /* __FM_KG_H */
37742 --- /dev/null
37743 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/fm_manip.c
37744 @@ -0,0 +1,5571 @@
37745 +/*
37746 + * Copyright 2008-2012 Freescale Semiconductor Inc.
37747 + *
37748 + * Redistribution and use in source and binary forms, with or without
37749 + * modification, are permitted provided that the following conditions are met:
37750 + * * Redistributions of source code must retain the above copyright
37751 + * notice, this list of conditions and the following disclaimer.
37752 + * * Redistributions in binary form must reproduce the above copyright
37753 + * notice, this list of conditions and the following disclaimer in the
37754 + * documentation and/or other materials provided with the distribution.
37755 + * * Neither the name of Freescale Semiconductor nor the
37756 + * names of its contributors may be used to endorse or promote products
37757 + * derived from this software without specific prior written permission.
37758 + *
37759 + *
37760 + * ALTERNATIVELY, this software may be distributed under the terms of the
37761 + * GNU General Public License ("GPL") as published by the Free Software
37762 + * Foundation, either version 2 of that License or (at your option) any
37763 + * later version.
37764 + *
37765 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
37766 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
37767 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
37768 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
37769 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
37770 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
37771 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
37772 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
37773 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
37774 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
37775 + */
37776 +
37777 +
37778 +/******************************************************************************
37779 + @File fm_manip.c
37780 +
37781 + @Description FM PCD manip ...
37782 + *//***************************************************************************/
37783 +#include "std_ext.h"
37784 +#include "error_ext.h"
37785 +#include "string_ext.h"
37786 +#include "debug_ext.h"
37787 +#include "fm_pcd_ext.h"
37788 +#include "fm_port_ext.h"
37789 +#include "fm_muram_ext.h"
37790 +#include "memcpy_ext.h"
37791 +
37792 +#include "fm_common.h"
37793 +#include "fm_hc.h"
37794 +#include "fm_manip.h"
37795 +
37796 +/****************************************/
37797 +/* static functions */
37798 +/****************************************/
37799 +static t_Handle GetManipInfo(t_FmPcdManip *p_Manip, e_ManipInfo manipInfo)
37800 +{
37801 + t_FmPcdManip *p_CurManip = p_Manip;
37802 +
37803 + if (!MANIP_IS_UNIFIED(p_Manip))
37804 + p_CurManip = p_Manip;
37805 + else
37806 + {
37807 + /* go to first unified */
37808 + while (MANIP_IS_UNIFIED_NON_FIRST(p_CurManip))
37809 + p_CurManip = p_CurManip->h_PrevManip;
37810 + }
37811 +
37812 + switch (manipInfo)
37813 + {
37814 + case (e_MANIP_HMCT):
37815 + return p_CurManip->p_Hmct;
37816 + case (e_MANIP_HMTD):
37817 + return p_CurManip->h_Ad;
37818 + case (e_MANIP_HANDLER_TABLE_OWNER):
37819 + return (t_Handle)p_CurManip;
37820 + default:
37821 + return NULL;
37822 + }
37823 +}
37824 +
37825 +static uint16_t GetHmctSize(t_FmPcdManip *p_Manip)
37826 +{
37827 + uint16_t size = 0;
37828 + t_FmPcdManip *p_CurManip = p_Manip;
37829 +
37830 + if (!MANIP_IS_UNIFIED(p_Manip))
37831 + return p_Manip->tableSize;
37832 +
37833 + /* accumulate sizes, starting with the first node */
37834 + while (MANIP_IS_UNIFIED_NON_FIRST(p_CurManip))
37835 + p_CurManip = p_CurManip->h_PrevManip;
37836 +
37837 + while (MANIP_IS_UNIFIED_NON_LAST(p_CurManip))
37838 + {
37839 + size += p_CurManip->tableSize;
37840 + p_CurManip = (t_FmPcdManip *)p_CurManip->h_NextManip;
37841 + }
37842 + size += p_CurManip->tableSize; /* add last size */
37843 +
37844 + return (size);
37845 +}
37846 +
37847 +static uint16_t GetDataSize(t_FmPcdManip *p_Manip)
37848 +{
37849 + uint16_t size = 0;
37850 + t_FmPcdManip *p_CurManip = p_Manip;
37851 +
37852 + if (!MANIP_IS_UNIFIED(p_Manip))
37853 + return p_Manip->dataSize;
37854 +
37855 + /* accumulate sizes, starting with the first node */
37856 + while (MANIP_IS_UNIFIED_NON_FIRST(p_CurManip))
37857 + p_CurManip = p_CurManip->h_PrevManip;
37858 +
37859 + while (MANIP_IS_UNIFIED_NON_LAST(p_CurManip))
37860 + {
37861 + size += p_CurManip->dataSize;
37862 + p_CurManip = (t_FmPcdManip *)p_CurManip->h_NextManip;
37863 + }
37864 + size += p_CurManip->dataSize; /* add last size */
37865 +
37866 + return (size);
37867 +}
37868 +
37869 +static t_Error CalculateTableSize(t_FmPcdManipParams *p_FmPcdManipParams,
37870 + uint16_t *p_TableSize, uint8_t *p_DataSize)
37871 +{
37872 + uint8_t localDataSize, remain, tableSize = 0, dataSize = 0;
37873 +
37874 + if (p_FmPcdManipParams->u.hdr.rmv)
37875 + {
37876 + switch (p_FmPcdManipParams->u.hdr.rmvParams.type)
37877 + {
37878 + case (e_FM_PCD_MANIP_RMV_GENERIC):
37879 + tableSize += HMCD_BASIC_SIZE;
37880 + break;
37881 + case (e_FM_PCD_MANIP_RMV_BY_HDR):
37882 + switch (p_FmPcdManipParams->u.hdr.rmvParams.u.byHdr.type)
37883 + {
37884 + case (e_FM_PCD_MANIP_RMV_BY_HDR_SPECIFIC_L2):
37885 +#if (DPAA_VERSION >= 11)
37886 + case (e_FM_PCD_MANIP_RMV_BY_HDR_CAPWAP):
37887 + case (e_FM_PCD_MANIP_RMV_BY_HDR_FROM_START):
37888 +#endif /* (DPAA_VERSION >= 11) */
37889 + tableSize += HMCD_BASIC_SIZE;
37890 + break;
37891 + default:
37892 + RETURN_ERROR(MINOR, E_INVALID_SELECTION,
37893 + ("Unknown byHdr.type"));
37894 + }
37895 + break;
37896 + default:
37897 + RETURN_ERROR(MINOR, E_INVALID_SELECTION,
37898 + ("Unknown rmvParams.type"));
37899 + }
37900 + }
37901 +
37902 + if (p_FmPcdManipParams->u.hdr.insrt)
37903 + {
37904 + switch (p_FmPcdManipParams->u.hdr.insrtParams.type)
37905 + {
37906 + case (e_FM_PCD_MANIP_INSRT_GENERIC):
37907 + remain =
37908 + (uint8_t)(p_FmPcdManipParams->u.hdr.insrtParams.u.generic.size
37909 + % 4);
37910 + if (remain)
37911 + localDataSize =
37912 + (uint8_t)(p_FmPcdManipParams->u.hdr.insrtParams.u.generic.size
37913 + + 4 - remain);
37914 + else
37915 + localDataSize =
37916 + p_FmPcdManipParams->u.hdr.insrtParams.u.generic.size;
37917 + tableSize += (uint8_t)(HMCD_BASIC_SIZE + localDataSize);
37918 + break;
37919 + case (e_FM_PCD_MANIP_INSRT_BY_HDR):
37920 + {
37921 + switch (p_FmPcdManipParams->u.hdr.insrtParams.u.byHdr.type)
37922 + {
37923 +
37924 + case (e_FM_PCD_MANIP_INSRT_BY_HDR_SPECIFIC_L2):
37925 + tableSize += HMCD_BASIC_SIZE + HMCD_PTR_SIZE;
37926 + switch (p_FmPcdManipParams->u.hdr.insrtParams.u.byHdr.u.specificL2Params.specificL2)
37927 + {
37928 + case (e_FM_PCD_MANIP_HDR_INSRT_MPLS):
37929 + case (e_FM_PCD_MANIP_HDR_INSRT_PPPOE):
37930 + dataSize +=
37931 + p_FmPcdManipParams->u.hdr.insrtParams.u.byHdr.u.specificL2Params.size;
37932 + break;
37933 + default:
37934 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
37935 + }
37936 + break;
37937 +#if (DPAA_VERSION >= 11)
37938 + case (e_FM_PCD_MANIP_INSRT_BY_HDR_IP):
37939 + tableSize +=
37940 + (HMCD_BASIC_SIZE + HMCD_PTR_SIZE
37941 + + HMCD_PARAM_SIZE
37942 + + p_FmPcdManipParams->u.hdr.insrtParams.u.byHdr.u.ipParams.insrt.size);
37943 + dataSize += 2;
37944 + break;
37945 +
37946 + case (e_FM_PCD_MANIP_INSRT_BY_HDR_UDP):
37947 + case (e_FM_PCD_MANIP_INSRT_BY_HDR_UDP_LITE):
37948 + tableSize += (HMCD_BASIC_SIZE + HMCD_L4_HDR_SIZE);
37949 +
37950 + break;
37951 +
37952 + case (e_FM_PCD_MANIP_INSRT_BY_HDR_CAPWAP):
37953 + tableSize +=
37954 + (HMCD_BASIC_SIZE
37955 + + p_FmPcdManipParams->u.hdr.insrtParams.u.byHdr.u.insrt.size);
37956 + break;
37957 +#endif /* (DPAA_VERSION >= 11) */
37958 + default:
37959 + RETURN_ERROR(MINOR, E_INVALID_SELECTION,
37960 + ("Unknown byHdr.type"));
37961 + }
37962 + }
37963 + break;
37964 + default:
37965 + RETURN_ERROR(MINOR, E_INVALID_SELECTION,
37966 + ("Unknown insrtParams.type"));
37967 + }
37968 + }
37969 +
37970 + if (p_FmPcdManipParams->u.hdr.fieldUpdate)
37971 + {
37972 + switch (p_FmPcdManipParams->u.hdr.fieldUpdateParams.type)
37973 + {
37974 + case (e_FM_PCD_MANIP_HDR_FIELD_UPDATE_VLAN):
37975 + tableSize += HMCD_BASIC_SIZE;
37976 + if (p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.vlan.updateType
37977 + == e_FM_PCD_MANIP_HDR_FIELD_UPDATE_DSCP_TO_VLAN)
37978 + {
37979 + tableSize += HMCD_PTR_SIZE;
37980 + dataSize += DSCP_TO_VLAN_TABLE_SIZE;
37981 + }
37982 + break;
37983 + case (e_FM_PCD_MANIP_HDR_FIELD_UPDATE_IPV4):
37984 + tableSize += HMCD_BASIC_SIZE;
37985 + if (p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.ipv4.validUpdates
37986 + & HDR_MANIP_IPV4_ID)
37987 + {
37988 + tableSize += HMCD_PARAM_SIZE;
37989 + dataSize += 2;
37990 + }
37991 + if (p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.ipv4.validUpdates
37992 + & HDR_MANIP_IPV4_SRC)
37993 + tableSize += HMCD_IPV4_ADDR_SIZE;
37994 + if (p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.ipv4.validUpdates
37995 + & HDR_MANIP_IPV4_DST)
37996 + tableSize += HMCD_IPV4_ADDR_SIZE;
37997 + break;
37998 + case (e_FM_PCD_MANIP_HDR_FIELD_UPDATE_IPV6):
37999 + tableSize += HMCD_BASIC_SIZE;
38000 + if (p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.ipv4.validUpdates
38001 + & HDR_MANIP_IPV6_SRC)
38002 + tableSize += HMCD_IPV6_ADDR_SIZE;
38003 + if (p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.ipv4.validUpdates
38004 + & HDR_MANIP_IPV6_DST)
38005 + tableSize += HMCD_IPV6_ADDR_SIZE;
38006 + break;
38007 + case (e_FM_PCD_MANIP_HDR_FIELD_UPDATE_TCP_UDP):
38008 + if (p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.tcpUdp.validUpdates
38009 + == HDR_MANIP_TCP_UDP_CHECKSUM)
38010 + /* we implement this case with the update-checksum descriptor */
38011 + tableSize += HMCD_BASIC_SIZE;
38012 + else
38013 + /* we implement this case with the TCP/UDP-update descriptor */
38014 + tableSize += HMCD_BASIC_SIZE + HMCD_PARAM_SIZE;
38015 + break;
38016 + default:
38017 + RETURN_ERROR(MINOR, E_INVALID_SELECTION,
38018 + ("Unknown fieldUpdateParams.type"));
38019 + }
38020 + }
38021 +
38022 + if (p_FmPcdManipParams->u.hdr.custom)
38023 + {
38024 + switch (p_FmPcdManipParams->u.hdr.customParams.type)
38025 + {
38026 + case (e_FM_PCD_MANIP_HDR_CUSTOM_IP_REPLACE):
38027 + {
38028 + tableSize += HMCD_BASIC_SIZE + HMCD_PARAM_SIZE + HMCD_PARAM_SIZE;
38029 + dataSize +=
38030 + p_FmPcdManipParams->u.hdr.customParams.u.ipHdrReplace.hdrSize;
38031 + if ((p_FmPcdManipParams->u.hdr.customParams.u.ipHdrReplace.replaceType
38032 + == e_FM_PCD_MANIP_HDR_CUSTOM_REPLACE_IPV6_BY_IPV4)
38033 + && (p_FmPcdManipParams->u.hdr.customParams.u.ipHdrReplace.updateIpv4Id))
38034 + dataSize += 2;
38035 + }
38036 + break;
38037 + case (e_FM_PCD_MANIP_HDR_CUSTOM_GEN_FIELD_REPLACE):
38038 + tableSize += HMCD_BASIC_SIZE + HMCD_PARAM_SIZE;
38039 + break;
38040 + default:
38041 + RETURN_ERROR(MINOR, E_INVALID_SELECTION,
38042 + ("Unknown customParams.type"));
38043 + }
38044 + }
38045 +
38046 + *p_TableSize = tableSize;
38047 + *p_DataSize = dataSize;
38048 +
38049 + return E_OK;
38050 +}
38051 +
38052 +static t_Error GetPrOffsetByHeaderOrField(t_FmManipHdrInfo *p_HdrInfo,
38053 + uint8_t *parseArrayOffset)
38054 +{
38055 + e_NetHeaderType hdr = p_HdrInfo->hdr;
38056 + e_FmPcdHdrIndex hdrIndex = p_HdrInfo->hdrIndex;
38057 + bool byField = p_HdrInfo->byField;
38058 + t_FmPcdFields field;
38059 +
38060 + if (byField)
38061 + field = p_HdrInfo->fullField;
38062 +
38063 + if (byField)
38064 + {
38065 + switch (hdr)
38066 + {
38067 + case (HEADER_TYPE_ETH):
38068 + switch (field.eth)
38069 + {
38070 + case (NET_HEADER_FIELD_ETH_TYPE):
38071 + *parseArrayOffset = CC_PC_PR_ETYPE_LAST_OFFSET;
38072 + break;
38073 + default:
38074 + RETURN_ERROR(
38075 + MAJOR,
38076 + E_NOT_SUPPORTED,
38077 + ("Header manipulation of the type Ethernet with this field not supported"));
38078 + }
38079 + break;
38080 + case (HEADER_TYPE_VLAN):
38081 + switch (field.vlan)
38082 + {
38083 + case (NET_HEADER_FIELD_VLAN_TCI):
38084 + if ((hdrIndex == e_FM_PCD_HDR_INDEX_NONE)
38085 + || (hdrIndex == e_FM_PCD_HDR_INDEX_1))
38086 + *parseArrayOffset = CC_PC_PR_VLAN1_OFFSET;
38087 + else
38088 + if (hdrIndex == e_FM_PCD_HDR_INDEX_LAST)
38089 + *parseArrayOffset = CC_PC_PR_VLAN2_OFFSET;
38090 + break;
38091 + default:
38092 + RETURN_ERROR(
38093 + MAJOR,
38094 + E_NOT_SUPPORTED,
38095 + ("Header manipulation of the type VLAN with this field not supported"));
38096 + }
38097 + break;
38098 + default:
38099 + RETURN_ERROR(
38100 + MAJOR,
38101 + E_NOT_SUPPORTED,
38102 + ("Header manipulation of this header by field not supported"));
38103 + }
38104 + }
38105 + else
38106 + {
38107 + switch (hdr)
38108 + {
38109 + case (HEADER_TYPE_ETH):
38110 + *parseArrayOffset = (uint8_t)CC_PC_PR_ETH_OFFSET;
38111 + break;
38112 + case (HEADER_TYPE_USER_DEFINED_SHIM1):
38113 + *parseArrayOffset = (uint8_t)CC_PC_PR_USER_DEFINED_SHIM1_OFFSET;
38114 + break;
38115 + case (HEADER_TYPE_USER_DEFINED_SHIM2):
38116 + *parseArrayOffset = (uint8_t)CC_PC_PR_USER_DEFINED_SHIM2_OFFSET;
38117 + break;
38118 + case (HEADER_TYPE_LLC_SNAP):
38119 + *parseArrayOffset = CC_PC_PR_USER_LLC_SNAP_OFFSET;
38120 + break;
38121 + case (HEADER_TYPE_PPPoE):
38122 + *parseArrayOffset = CC_PC_PR_PPPOE_OFFSET;
38123 + break;
38124 + case (HEADER_TYPE_MPLS):
38125 + if ((hdrIndex == e_FM_PCD_HDR_INDEX_NONE)
38126 + || (hdrIndex == e_FM_PCD_HDR_INDEX_1))
38127 + *parseArrayOffset = CC_PC_PR_MPLS1_OFFSET;
38128 + else
38129 + if (hdrIndex == e_FM_PCD_HDR_INDEX_LAST)
38130 + *parseArrayOffset = CC_PC_PR_MPLS_LAST_OFFSET;
38131 + break;
38132 + case (HEADER_TYPE_IPv4):
38133 + case (HEADER_TYPE_IPv6):
38134 + if ((hdrIndex == e_FM_PCD_HDR_INDEX_NONE)
38135 + || (hdrIndex == e_FM_PCD_HDR_INDEX_1))
38136 + *parseArrayOffset = CC_PC_PR_IP1_OFFSET;
38137 + else
38138 + if (hdrIndex == e_FM_PCD_HDR_INDEX_2)
38139 + *parseArrayOffset = CC_PC_PR_IP_LAST_OFFSET;
38140 + break;
38141 + case (HEADER_TYPE_MINENCAP):
38142 + *parseArrayOffset = CC_PC_PR_MINENC_OFFSET;
38143 + break;
38144 + case (HEADER_TYPE_GRE):
38145 + *parseArrayOffset = CC_PC_PR_GRE_OFFSET;
38146 + break;
38147 + case (HEADER_TYPE_TCP):
38148 + case (HEADER_TYPE_UDP):
38149 + case (HEADER_TYPE_IPSEC_AH):
38150 + case (HEADER_TYPE_IPSEC_ESP):
38151 + case (HEADER_TYPE_DCCP):
38152 + case (HEADER_TYPE_SCTP):
38153 + *parseArrayOffset = CC_PC_PR_L4_OFFSET;
38154 + break;
38155 + case (HEADER_TYPE_CAPWAP):
38156 + case (HEADER_TYPE_CAPWAP_DTLS):
38157 + *parseArrayOffset = CC_PC_PR_NEXT_HEADER_OFFSET;
38158 + break;
38159 + default:
38160 + RETURN_ERROR(
38161 + MAJOR,
38162 + E_NOT_SUPPORTED,
38163 + ("Header manipulation of this header is not supported"));
38164 + }
38165 + }
38166 + return E_OK;
38167 +}
38168 +
38169 +static t_Error BuildHmct(t_FmPcdManip *p_Manip,
38170 + t_FmPcdManipParams *p_FmPcdManipParams,
38171 + uint8_t *p_DestHmct, uint8_t *p_DestData, bool new)
38172 +{
38173 + uint32_t *p_TmpHmct = (uint32_t*)p_DestHmct, *p_LocalData;
38174 + uint32_t tmpReg = 0, *p_Last = NULL, tmp_ipv6_addr;
38175 + uint8_t remain, i, size = 0, origSize, *p_UsrData = NULL, *p_TmpData =
38176 + p_DestData;
38177 + t_Handle h_FmPcd = p_Manip->h_FmPcd;
38178 + uint8_t j = 0;
38179 +
38180 + if (p_FmPcdManipParams->u.hdr.rmv)
38181 + {
38182 + if (p_FmPcdManipParams->u.hdr.rmvParams.type
38183 + == e_FM_PCD_MANIP_RMV_GENERIC)
38184 + {
38185 + /* initialize HMCD */
38186 + tmpReg = (uint32_t)(HMCD_OPCODE_GENERIC_RMV) << HMCD_OC_SHIFT;
38187 + /* tmp, should be conditional */
38188 + tmpReg |= p_FmPcdManipParams->u.hdr.rmvParams.u.generic.offset
38189 + << HMCD_RMV_OFFSET_SHIFT;
38190 + tmpReg |= p_FmPcdManipParams->u.hdr.rmvParams.u.generic.size
38191 + << HMCD_RMV_SIZE_SHIFT;
38192 + }
38193 + else
38194 + if (p_FmPcdManipParams->u.hdr.rmvParams.type
38195 + == e_FM_PCD_MANIP_RMV_BY_HDR)
38196 + {
38197 + switch (p_FmPcdManipParams->u.hdr.rmvParams.u.byHdr.type)
38198 + {
38199 + case (e_FM_PCD_MANIP_RMV_BY_HDR_SPECIFIC_L2):
38200 + {
38201 + uint8_t hmcdOpt;
38202 +
38203 + /* initialize HMCD */
38204 + tmpReg = (uint32_t)(HMCD_OPCODE_L2_RMV) << HMCD_OC_SHIFT;
38205 +
38206 + switch (p_FmPcdManipParams->u.hdr.rmvParams.u.byHdr.u.specificL2)
38207 + {
38208 + case (e_FM_PCD_MANIP_HDR_RMV_ETHERNET):
38209 + hmcdOpt = HMCD_RMV_L2_ETHERNET;
38210 + break;
38211 + case (e_FM_PCD_MANIP_HDR_RMV_STACKED_QTAGS):
38212 + hmcdOpt = HMCD_RMV_L2_STACKED_QTAGS;
38213 + break;
38214 + case (e_FM_PCD_MANIP_HDR_RMV_ETHERNET_AND_MPLS):
38215 + hmcdOpt = HMCD_RMV_L2_ETHERNET_AND_MPLS;
38216 + break;
38217 + case (e_FM_PCD_MANIP_HDR_RMV_MPLS):
38218 + hmcdOpt = HMCD_RMV_L2_MPLS;
38219 + break;
38220 + case (e_FM_PCD_MANIP_HDR_RMV_PPPOE):
38221 + hmcdOpt = HMCD_RMV_L2_PPPOE;
38222 + break;
38223 + default:
38224 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
38225 + }
38226 + tmpReg |= hmcdOpt << HMCD_L2_MODE_SHIFT;
38227 + break;
38228 + }
38229 +#if (DPAA_VERSION >= 11)
38230 + case (e_FM_PCD_MANIP_RMV_BY_HDR_CAPWAP):
38231 + tmpReg = (uint32_t)(HMCD_OPCODE_CAPWAP_RMV)
38232 + << HMCD_OC_SHIFT;
38233 + break;
38234 + case (e_FM_PCD_MANIP_RMV_BY_HDR_FROM_START):
38235 + {
38236 + uint8_t prsArrayOffset;
38237 + t_Error err = E_OK;
38238 +
38239 + tmpReg = (uint32_t)(HMCD_OPCODE_RMV_TILL)
38240 + << HMCD_OC_SHIFT;
38241 +
38242 + err =
38243 + GetPrOffsetByHeaderOrField(
38244 + &p_FmPcdManipParams->u.hdr.rmvParams.u.byHdr.u.hdrInfo,
38245 + &prsArrayOffset);
38246 + ASSERT_COND(!err);
38247 + /* was previously checked */
38248 +
38249 + tmpReg |= ((uint32_t)prsArrayOffset << 16);
38250 + }
38251 + break;
38252 +#endif /* (DPAA_VERSION >= 11) */
38253 + default:
38254 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED,
38255 + ("manip header remove by hdr type!"));
38256 + }
38257 + }
38258 +
38259 + WRITE_UINT32(*p_TmpHmct, tmpReg);
38260 + /* save a pointer to the "last" indication word */
38261 + p_Last = p_TmpHmct;
38262 + /* advance to next command */
38263 + p_TmpHmct += HMCD_BASIC_SIZE / 4;
38264 + }
38265 +
38266 + if (p_FmPcdManipParams->u.hdr.insrt)
38267 + {
38268 + if (p_FmPcdManipParams->u.hdr.insrtParams.type
38269 + == e_FM_PCD_MANIP_INSRT_GENERIC)
38270 + {
38271 + /* initialize HMCD */
38272 + if (p_FmPcdManipParams->u.hdr.insrtParams.u.generic.replace)
38273 + tmpReg = (uint32_t)(HMCD_OPCODE_GENERIC_REPLACE)
38274 + << HMCD_OC_SHIFT;
38275 + else
38276 + tmpReg = (uint32_t)(HMCD_OPCODE_GENERIC_INSRT) << HMCD_OC_SHIFT;
38277 +
38278 + tmpReg |= p_FmPcdManipParams->u.hdr.insrtParams.u.generic.offset
38279 + << HMCD_INSRT_OFFSET_SHIFT;
38280 + tmpReg |= p_FmPcdManipParams->u.hdr.insrtParams.u.generic.size
38281 + << HMCD_INSRT_SIZE_SHIFT;
38282 +
38283 + size = p_FmPcdManipParams->u.hdr.insrtParams.u.generic.size;
38284 + p_UsrData = p_FmPcdManipParams->u.hdr.insrtParams.u.generic.p_Data;
38285 +
38286 + WRITE_UINT32(*p_TmpHmct, tmpReg);
38287 + /* save a pointer to the "last" indication word */
38288 + p_Last = p_TmpHmct;
38289 +
38290 + p_TmpHmct += HMCD_BASIC_SIZE / 4;
38291 +
38292 + /* initialize data to be inserted */
38293 + /* if size is not a multiple of 4, padd with 0's */
38294 + origSize = size;
38295 + remain = (uint8_t)(size % 4);
38296 + if (remain)
38297 + {
38298 + size += (uint8_t)(4 - remain);
38299 + p_LocalData = (uint32_t *)XX_Malloc(size);
38300 + memset((uint8_t *)p_LocalData, 0, size);
38301 + memcpy((uint8_t *)p_LocalData, p_UsrData, origSize);
38302 + }
38303 + else
38304 + p_LocalData = (uint32_t*)p_UsrData;
38305 +
38306 + /* initialize data and advance pointer to next command */
38307 + MemCpy8(p_TmpHmct, p_LocalData, size);
38308 + p_TmpHmct += size / sizeof(uint32_t);
38309 +
38310 + if (remain)
38311 + XX_Free(p_LocalData);
38312 + }
38313 +
38314 + else
38315 + if (p_FmPcdManipParams->u.hdr.insrtParams.type
38316 + == e_FM_PCD_MANIP_INSRT_BY_HDR)
38317 + {
38318 + switch (p_FmPcdManipParams->u.hdr.insrtParams.u.byHdr.type)
38319 + {
38320 + case (e_FM_PCD_MANIP_INSRT_BY_HDR_SPECIFIC_L2):
38321 + {
38322 + uint8_t hmcdOpt;
38323 +
38324 + /* initialize HMCD */
38325 + tmpReg = (uint32_t)(HMCD_OPCODE_L2_INSRT)
38326 + << HMCD_OC_SHIFT;
38327 +
38328 + switch (p_FmPcdManipParams->u.hdr.insrtParams.u.byHdr.u.specificL2Params.specificL2)
38329 + {
38330 + case (e_FM_PCD_MANIP_HDR_INSRT_MPLS):
38331 + if (p_FmPcdManipParams->u.hdr.insrtParams.u.byHdr.u.specificL2Params.update)
38332 + hmcdOpt = HMCD_INSRT_N_UPDATE_L2_MPLS;
38333 + else
38334 + hmcdOpt = HMCD_INSRT_L2_MPLS;
38335 + break;
38336 + case (e_FM_PCD_MANIP_HDR_INSRT_PPPOE):
38337 + hmcdOpt = HMCD_INSRT_L2_PPPOE;
38338 + break;
38339 + default:
38340 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
38341 + }
38342 + tmpReg |= hmcdOpt << HMCD_L2_MODE_SHIFT;
38343 +
38344 + WRITE_UINT32(*p_TmpHmct, tmpReg);
38345 + /* save a pointer to the "last" indication word */
38346 + p_Last = p_TmpHmct;
38347 +
38348 + p_TmpHmct += HMCD_BASIC_SIZE / 4;
38349 +
38350 + /* set size and pointer of user's data */
38351 + size =
38352 + (uint8_t)p_FmPcdManipParams->u.hdr.insrtParams.u.byHdr.u.specificL2Params.size;
38353 +
38354 + ASSERT_COND(p_TmpData);
38355 + MemCpy8(
38356 + p_TmpData,
38357 + p_FmPcdManipParams->u.hdr.insrtParams.u.byHdr.u.specificL2Params.p_Data,
38358 + size);
38359 + tmpReg =
38360 + (size << HMCD_INSRT_L2_SIZE_SHIFT)
38361 + | (uint32_t)(XX_VirtToPhys(p_TmpData)
38362 + - (((t_FmPcd*)h_FmPcd)->physicalMuramBase));
38363 + WRITE_UINT32(*p_TmpHmct, tmpReg);
38364 + p_TmpHmct += HMCD_PTR_SIZE / 4;
38365 + p_TmpData += size;
38366 + }
38367 + break;
38368 +#if (DPAA_VERSION >= 11)
38369 + case (e_FM_PCD_MANIP_INSRT_BY_HDR_IP):
38370 + tmpReg = (uint32_t)(HMCD_OPCODE_IP_INSRT)
38371 + << HMCD_OC_SHIFT;
38372 + if (p_FmPcdManipParams->u.hdr.insrtParams.u.byHdr.u.ipParams.calcL4Checksum)
38373 + tmpReg |= HMCD_IP_L4_CS_CALC;
38374 + if (p_FmPcdManipParams->u.hdr.insrtParams.u.byHdr.u.ipParams.mappingMode
38375 + == e_FM_PCD_MANIP_HDR_QOS_MAPPING_AS_IS)
38376 + tmpReg |= HMCD_IP_OR_QOS;
38377 + tmpReg |=
38378 + p_FmPcdManipParams->u.hdr.insrtParams.u.byHdr.u.ipParams.lastPidOffset
38379 + & HMCD_IP_LAST_PID_MASK;
38380 + tmpReg |=
38381 + ((p_FmPcdManipParams->u.hdr.insrtParams.u.byHdr.u.ipParams.insrt.size
38382 + << HMCD_IP_SIZE_SHIFT)
38383 + & HMCD_IP_SIZE_MASK);
38384 + if (p_FmPcdManipParams->u.hdr.insrtParams.u.byHdr.u.ipParams.dontFragOverwrite)
38385 + tmpReg |= HMCD_IP_DF_MODE;
38386 +
38387 + WRITE_UINT32(*p_TmpHmct, tmpReg);
38388 +
38389 + /* save a pointer to the "last" indication word */
38390 + p_Last = p_TmpHmct;
38391 +
38392 + p_TmpHmct += HMCD_BASIC_SIZE / 4;
38393 +
38394 + /* set IP id */
38395 + ASSERT_COND(p_TmpData);
38396 + WRITE_UINT16(
38397 + *(uint16_t*)p_TmpData,
38398 + p_FmPcdManipParams->u.hdr.insrtParams.u.byHdr.u.ipParams.id);
38399 + WRITE_UINT32(
38400 + *p_TmpHmct,
38401 + (uint32_t)(XX_VirtToPhys(p_TmpData) - (((t_FmPcd*)p_Manip->h_FmPcd)->physicalMuramBase)));
38402 + p_TmpData += 2;
38403 + p_TmpHmct += HMCD_PTR_SIZE / 4;
38404 +
38405 + WRITE_UINT8(*p_TmpHmct, p_FmPcdManipParams->u.hdr.insrtParams.u.byHdr.u.ipParams.lastDstOffset);
38406 + p_TmpHmct += HMCD_PARAM_SIZE / 4;
38407 +
38408 + MemCpy8(
38409 + p_TmpHmct,
38410 + p_FmPcdManipParams->u.hdr.insrtParams.u.byHdr.u.ipParams.insrt.p_Data,
38411 + p_FmPcdManipParams->u.hdr.insrtParams.u.byHdr.u.ipParams.insrt.size);
38412 + p_TmpHmct +=
38413 + p_FmPcdManipParams->u.hdr.insrtParams.u.byHdr.u.ipParams.insrt.size
38414 + / 4;
38415 + break;
38416 + case (e_FM_PCD_MANIP_INSRT_BY_HDR_UDP_LITE):
38417 + tmpReg = HMCD_INSRT_UDP_LITE;
38418 + case (e_FM_PCD_MANIP_INSRT_BY_HDR_UDP):
38419 + tmpReg |= (uint32_t)(HMCD_OPCODE_UDP_INSRT)
38420 + << HMCD_OC_SHIFT;
38421 +
38422 + WRITE_UINT32(*p_TmpHmct, tmpReg);
38423 +
38424 + /* save a pointer to the "last" indication word */
38425 + p_Last = p_TmpHmct;
38426 +
38427 + p_TmpHmct += HMCD_BASIC_SIZE / 4;
38428 +
38429 + MemCpy8(
38430 + p_TmpHmct,
38431 + p_FmPcdManipParams->u.hdr.insrtParams.u.byHdr.u.insrt.p_Data,
38432 + p_FmPcdManipParams->u.hdr.insrtParams.u.byHdr.u.insrt.size);
38433 + p_TmpHmct +=
38434 + p_FmPcdManipParams->u.hdr.insrtParams.u.byHdr.u.insrt.size
38435 + / 4;
38436 + break;
38437 + case (e_FM_PCD_MANIP_INSRT_BY_HDR_CAPWAP):
38438 + tmpReg = (uint32_t)(HMCD_OPCODE_CAPWAP_INSRT)
38439 + << HMCD_OC_SHIFT;
38440 + tmpReg |= HMCD_CAPWAP_INSRT;
38441 +
38442 + WRITE_UINT32(*p_TmpHmct, tmpReg);
38443 +
38444 + /* save a pointer to the "last" indication word */
38445 + p_Last = p_TmpHmct;
38446 +
38447 + p_TmpHmct += HMCD_BASIC_SIZE / 4;
38448 +
38449 + MemCpy8(
38450 + p_TmpHmct,
38451 + p_FmPcdManipParams->u.hdr.insrtParams.u.byHdr.u.insrt.p_Data,
38452 + p_FmPcdManipParams->u.hdr.insrtParams.u.byHdr.u.insrt.size);
38453 + p_TmpHmct +=
38454 + p_FmPcdManipParams->u.hdr.insrtParams.u.byHdr.u.insrt.size
38455 + / 4;
38456 + break;
38457 +#endif /* (DPAA_VERSION >= 11) */
38458 + default:
38459 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED,
38460 + ("manip header insert by header type!"));
38461 +
38462 + }
38463 + }
38464 + }
38465 +
38466 + if (p_FmPcdManipParams->u.hdr.fieldUpdate)
38467 + {
38468 + switch (p_FmPcdManipParams->u.hdr.fieldUpdateParams.type)
38469 + {
38470 + case (e_FM_PCD_MANIP_HDR_FIELD_UPDATE_VLAN):
38471 + /* set opcode */
38472 + tmpReg = (uint32_t)(HMCD_OPCODE_VLAN_PRI_UPDATE)
38473 + << HMCD_OC_SHIFT;
38474 +
38475 + /* set mode & table pointer */
38476 + if (p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.vlan.updateType
38477 + == e_FM_PCD_MANIP_HDR_FIELD_UPDATE_DSCP_TO_VLAN)
38478 + {
38479 + /* set Mode */
38480 + tmpReg |= (uint32_t)(HMCD_VLAN_PRI_UPDATE_DSCP_TO_VPRI)
38481 + << HMCD_VLAN_PRI_REP_MODE_SHIFT;
38482 + /* set VPRI default */
38483 + tmpReg |=
38484 + p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.vlan.u.dscpToVpri.vpriDefVal;
38485 + WRITE_UINT32(*p_TmpHmct, tmpReg);
38486 + /* save a pointer to the "last" indication word */
38487 + p_Last = p_TmpHmct;
38488 + /* write the table pointer into the Manip descriptor */
38489 + p_TmpHmct += HMCD_BASIC_SIZE / 4;
38490 +
38491 + tmpReg = 0;
38492 + ASSERT_COND(p_TmpData);
38493 + for (i = 0; i < HMCD_DSCP_VALUES; i++)
38494 + {
38495 + /* first we build from each 8 values a 32bit register */
38496 + tmpReg |=
38497 + (p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.vlan.u.dscpToVpri.dscpToVpriTable[i])
38498 + << (32 - 4 * (j + 1));
38499 + j++;
38500 + /* Than we write this register to the next table word
38501 + * (i=7-->word 0, i=15-->word 1,... i=63-->word 7) */
38502 + if ((i % 8) == 7)
38503 + {
38504 + WRITE_UINT32(*((uint32_t*)p_TmpData + (i+1)/8-1),
38505 + tmpReg);
38506 + tmpReg = 0;
38507 + j = 0;
38508 + }
38509 + }
38510 +
38511 + WRITE_UINT32(
38512 + *p_TmpHmct,
38513 + (uint32_t)(XX_VirtToPhys(p_TmpData) - (((t_FmPcd*)h_FmPcd)->physicalMuramBase)));
38514 + p_TmpHmct += HMCD_PTR_SIZE / 4;
38515 +
38516 + p_TmpData += DSCP_TO_VLAN_TABLE_SIZE;
38517 + }
38518 + else
38519 + if (p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.vlan.updateType
38520 + == e_FM_PCD_MANIP_HDR_FIELD_UPDATE_VLAN_VPRI)
38521 + {
38522 + /* set Mode */
38523 + /* line commented out as it has no-side-effect ('0' value). */
38524 + /*tmpReg |= HMCD_VLAN_PRI_UPDATE << HMCD_VLAN_PRI_REP_MODE_SHIFT*/;
38525 + /* set VPRI parameter */
38526 + tmpReg |=
38527 + p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.vlan.u.vpri;
38528 + WRITE_UINT32(*p_TmpHmct, tmpReg);
38529 + /* save a pointer to the "last" indication word */
38530 + p_Last = p_TmpHmct;
38531 + p_TmpHmct += HMCD_BASIC_SIZE / 4;
38532 + }
38533 + break;
38534 +
38535 + case (e_FM_PCD_MANIP_HDR_FIELD_UPDATE_IPV4):
38536 + /* set opcode */
38537 + tmpReg = (uint32_t)(HMCD_OPCODE_IPV4_UPDATE) << HMCD_OC_SHIFT;
38538 + if (p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.ipv4.validUpdates
38539 + & HDR_MANIP_IPV4_TTL)
38540 + tmpReg |= HMCD_IPV4_UPDATE_TTL;
38541 + if (p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.ipv4.validUpdates
38542 + & HDR_MANIP_IPV4_TOS)
38543 + {
38544 + tmpReg |= HMCD_IPV4_UPDATE_TOS;
38545 + tmpReg |=
38546 + p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.ipv4.tos
38547 + << HMCD_IPV4_UPDATE_TOS_SHIFT;
38548 + }
38549 + if (p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.ipv4.validUpdates
38550 + & HDR_MANIP_IPV4_ID)
38551 + tmpReg |= HMCD_IPV4_UPDATE_ID;
38552 + if (p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.ipv4.validUpdates
38553 + & HDR_MANIP_IPV4_SRC)
38554 + tmpReg |= HMCD_IPV4_UPDATE_SRC;
38555 + if (p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.ipv4.validUpdates
38556 + & HDR_MANIP_IPV4_DST)
38557 + tmpReg |= HMCD_IPV4_UPDATE_DST;
38558 + /* write the first 4 bytes of the descriptor */
38559 + WRITE_UINT32(*p_TmpHmct, tmpReg);
38560 + /* save a pointer to the "last" indication word */
38561 + p_Last = p_TmpHmct;
38562 +
38563 + p_TmpHmct += HMCD_BASIC_SIZE / 4;
38564 +
38565 + if (p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.ipv4.validUpdates
38566 + & HDR_MANIP_IPV4_ID)
38567 + {
38568 + ASSERT_COND(p_TmpData);
38569 + WRITE_UINT16(
38570 + *(uint16_t*)p_TmpData,
38571 + p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.ipv4.id);
38572 + WRITE_UINT32(
38573 + *p_TmpHmct,
38574 + (uint32_t)(XX_VirtToPhys(p_TmpData) - (((t_FmPcd*)p_Manip->h_FmPcd)->physicalMuramBase)));
38575 + p_TmpData += 2;
38576 + p_TmpHmct += HMCD_PTR_SIZE / 4;
38577 + }
38578 +
38579 + if (p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.ipv4.validUpdates
38580 + & HDR_MANIP_IPV4_SRC)
38581 + {
38582 + WRITE_UINT32(
38583 + *p_TmpHmct,
38584 + p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.ipv4.src);
38585 + p_TmpHmct += HMCD_IPV4_ADDR_SIZE / 4;
38586 + }
38587 +
38588 + if (p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.ipv4.validUpdates
38589 + & HDR_MANIP_IPV4_DST)
38590 + {
38591 + WRITE_UINT32(
38592 + *p_TmpHmct,
38593 + p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.ipv4.dst);
38594 + p_TmpHmct += HMCD_IPV4_ADDR_SIZE / 4;
38595 + }
38596 + break;
38597 +
38598 + case (e_FM_PCD_MANIP_HDR_FIELD_UPDATE_IPV6):
38599 + /* set opcode */
38600 + tmpReg = (uint32_t)(HMCD_OPCODE_IPV6_UPDATE) << HMCD_OC_SHIFT;
38601 + if (p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.ipv6.validUpdates
38602 + & HDR_MANIP_IPV6_HL)
38603 + tmpReg |= HMCD_IPV6_UPDATE_HL;
38604 + if (p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.ipv6.validUpdates
38605 + & HDR_MANIP_IPV6_TC)
38606 + {
38607 + tmpReg |= HMCD_IPV6_UPDATE_TC;
38608 + tmpReg |=
38609 + p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.ipv6.trafficClass
38610 + << HMCD_IPV6_UPDATE_TC_SHIFT;
38611 + }
38612 + if (p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.ipv6.validUpdates
38613 + & HDR_MANIP_IPV6_SRC)
38614 + tmpReg |= HMCD_IPV6_UPDATE_SRC;
38615 + if (p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.ipv6.validUpdates
38616 + & HDR_MANIP_IPV6_DST)
38617 + tmpReg |= HMCD_IPV6_UPDATE_DST;
38618 + /* write the first 4 bytes of the descriptor */
38619 + WRITE_UINT32(*p_TmpHmct, tmpReg);
38620 + /* save a pointer to the "last" indication word */
38621 + p_Last = p_TmpHmct;
38622 +
38623 + p_TmpHmct += HMCD_BASIC_SIZE / 4;
38624 + if (p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.ipv6.validUpdates
38625 + & HDR_MANIP_IPV6_SRC)
38626 + {
38627 + for (i = 0; i < NET_HEADER_FIELD_IPv6_ADDR_SIZE; i += 4)
38628 + {
38629 + memcpy(&tmp_ipv6_addr,
38630 + &p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.ipv6.src[i],
38631 + sizeof(uint32_t));
38632 + WRITE_UINT32(*p_TmpHmct, tmp_ipv6_addr);
38633 + p_TmpHmct += HMCD_PTR_SIZE / 4;
38634 + }
38635 + }
38636 + if (p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.ipv6.validUpdates
38637 + & HDR_MANIP_IPV6_DST)
38638 + {
38639 + for (i = 0; i < NET_HEADER_FIELD_IPv6_ADDR_SIZE; i += 4)
38640 + {
38641 + memcpy(&tmp_ipv6_addr,
38642 + &p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.ipv6.dst[i],
38643 + sizeof(uint32_t));
38644 + WRITE_UINT32(*p_TmpHmct, tmp_ipv6_addr);
38645 + p_TmpHmct += HMCD_PTR_SIZE / 4;
38646 + }
38647 + }
38648 + break;
38649 +
38650 + case (e_FM_PCD_MANIP_HDR_FIELD_UPDATE_TCP_UDP):
38651 + if (p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.tcpUdp.validUpdates
38652 + == HDR_MANIP_TCP_UDP_CHECKSUM)
38653 + {
38654 + /* we implement this case with the update-checksum descriptor */
38655 + /* set opcode */
38656 + tmpReg = (uint32_t)(HMCD_OPCODE_TCP_UDP_CHECKSUM)
38657 + << HMCD_OC_SHIFT;
38658 + /* write the first 4 bytes of the descriptor */
38659 + WRITE_UINT32(*p_TmpHmct, tmpReg);
38660 + /* save a pointer to the "last" indication word */
38661 + p_Last = p_TmpHmct;
38662 +
38663 + p_TmpHmct += HMCD_BASIC_SIZE / 4;
38664 + }
38665 + else
38666 + {
38667 + /* we implement this case with the TCP/UDP update descriptor */
38668 + /* set opcode */
38669 + tmpReg = (uint32_t)(HMCD_OPCODE_TCP_UDP_UPDATE)
38670 + << HMCD_OC_SHIFT;
38671 + if (p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.tcpUdp.validUpdates
38672 + & HDR_MANIP_TCP_UDP_DST)
38673 + tmpReg |= HMCD_TCP_UDP_UPDATE_DST;
38674 + if (p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.tcpUdp.validUpdates
38675 + & HDR_MANIP_TCP_UDP_SRC)
38676 + tmpReg |= HMCD_TCP_UDP_UPDATE_SRC;
38677 + /* write the first 4 bytes of the descriptor */
38678 + WRITE_UINT32(*p_TmpHmct, tmpReg);
38679 + /* save a pointer to the "last" indication word */
38680 + p_Last = p_TmpHmct;
38681 +
38682 + p_TmpHmct += HMCD_BASIC_SIZE / 4;
38683 +
38684 + tmpReg = 0;
38685 + if (p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.tcpUdp.validUpdates
38686 + & HDR_MANIP_TCP_UDP_SRC)
38687 + tmpReg |=
38688 + ((uint32_t)p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.tcpUdp.src)
38689 + << HMCD_TCP_UDP_UPDATE_SRC_SHIFT;
38690 + if (p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.tcpUdp.validUpdates
38691 + & HDR_MANIP_TCP_UDP_DST)
38692 + tmpReg |=
38693 + ((uint32_t)p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.tcpUdp.dst);
38694 + WRITE_UINT32(*p_TmpHmct, tmpReg);
38695 + p_TmpHmct += HMCD_PTR_SIZE / 4;
38696 + }
38697 + break;
38698 +
38699 + default:
38700 + RETURN_ERROR(MINOR, E_INVALID_SELECTION,
38701 + ("Unknown fieldUpdateParams.type"));
38702 + }
38703 + }
38704 +
38705 + if (p_FmPcdManipParams->u.hdr.custom)
38706 + {
38707 + switch (p_FmPcdManipParams->u.hdr.customParams.type)
38708 + {
38709 + case (e_FM_PCD_MANIP_HDR_CUSTOM_IP_REPLACE):
38710 + /* set opcode */
38711 + tmpReg = (uint32_t)(HMCD_OPCODE_REPLACE_IP) << HMCD_OC_SHIFT;
38712 +
38713 + if (p_FmPcdManipParams->u.hdr.customParams.u.ipHdrReplace.decTtlHl)
38714 + tmpReg |= HMCD_IP_REPLACE_TTL_HL;
38715 + if (p_FmPcdManipParams->u.hdr.customParams.u.ipHdrReplace.replaceType
38716 + == e_FM_PCD_MANIP_HDR_CUSTOM_REPLACE_IPV4_BY_IPV6)
38717 + /* line commented out as it has no-side-effect ('0' value). */
38718 + /*tmpReg |= HMCD_IP_REPLACE_REPLACE_IPV4*/;
38719 + else
38720 + if (p_FmPcdManipParams->u.hdr.customParams.u.ipHdrReplace.replaceType
38721 + == e_FM_PCD_MANIP_HDR_CUSTOM_REPLACE_IPV6_BY_IPV4)
38722 + {
38723 + tmpReg |= HMCD_IP_REPLACE_REPLACE_IPV6;
38724 + if (p_FmPcdManipParams->u.hdr.customParams.u.ipHdrReplace.updateIpv4Id)
38725 + tmpReg |= HMCD_IP_REPLACE_ID;
38726 + }
38727 + else
38728 + RETURN_ERROR(
38729 + MINOR,
38730 + E_NOT_SUPPORTED,
38731 + ("One flag out of HDR_MANIP_IP_REPLACE_IPV4, HDR_MANIP_IP_REPLACE_IPV6 - must be set."));
38732 +
38733 + /* write the first 4 bytes of the descriptor */
38734 + WRITE_UINT32(*p_TmpHmct, tmpReg);
38735 + /* save a pointer to the "last" indication word */
38736 + p_Last = p_TmpHmct;
38737 +
38738 + p_TmpHmct += HMCD_BASIC_SIZE / 4;
38739 +
38740 + size =
38741 + p_FmPcdManipParams->u.hdr.customParams.u.ipHdrReplace.hdrSize;
38742 + ASSERT_COND(p_TmpData);
38743 + MemCpy8(
38744 + p_TmpData,
38745 + p_FmPcdManipParams->u.hdr.customParams.u.ipHdrReplace.hdr,
38746 + size);
38747 + tmpReg = (uint32_t)(size << HMCD_IP_REPLACE_L3HDRSIZE_SHIFT);
38748 + tmpReg |= (uint32_t)(XX_VirtToPhys(p_TmpData)
38749 + - (((t_FmPcd*)h_FmPcd)->physicalMuramBase));
38750 + WRITE_UINT32(*p_TmpHmct, tmpReg);
38751 + p_TmpHmct += HMCD_PTR_SIZE / 4;
38752 + p_TmpData += size;
38753 +
38754 + if ((p_FmPcdManipParams->u.hdr.customParams.u.ipHdrReplace.replaceType
38755 + == e_FM_PCD_MANIP_HDR_CUSTOM_REPLACE_IPV6_BY_IPV4)
38756 + && (p_FmPcdManipParams->u.hdr.customParams.u.ipHdrReplace.updateIpv4Id))
38757 + {
38758 + WRITE_UINT16(
38759 + *(uint16_t*)p_TmpData,
38760 + p_FmPcdManipParams->u.hdr.customParams.u.ipHdrReplace.id);
38761 + WRITE_UINT32(
38762 + *p_TmpHmct,
38763 + (uint32_t)(XX_VirtToPhys(p_TmpData) - (((t_FmPcd*)h_FmPcd)->physicalMuramBase)));
38764 + p_TmpData += 2;
38765 + }
38766 + p_TmpHmct += HMCD_PTR_SIZE / 4;
38767 + break;
38768 + case (e_FM_PCD_MANIP_HDR_CUSTOM_GEN_FIELD_REPLACE):
38769 + /* set opcode */
38770 + tmpReg = (uint32_t)(HMCD_OPCODE_GEN_FIELD_REPLACE) << HMCD_OC_SHIFT;
38771 + tmpReg |= p_FmPcdManipParams->u.hdr.customParams.u.genFieldReplace.size << HMCD_GEN_FIELD_SIZE_SHIFT;
38772 + tmpReg |= p_FmPcdManipParams->u.hdr.customParams.u.genFieldReplace.srcOffset << HMCD_GEN_FIELD_SRC_OFF_SHIFT;
38773 + tmpReg |= p_FmPcdManipParams->u.hdr.customParams.u.genFieldReplace.dstOffset << HMCD_GEN_FIELD_DST_OFF_SHIFT;
38774 + if (p_FmPcdManipParams->u.hdr.customParams.u.genFieldReplace.mask)
38775 + tmpReg |= HMCD_GEN_FIELD_MASK_EN;
38776 +
38777 + /* write the first 4 bytes of the descriptor */
38778 + WRITE_UINT32(*p_TmpHmct, tmpReg);
38779 + /* save a pointer to the "last" indication word */
38780 + p_Last = p_TmpHmct;
38781 +
38782 + p_TmpHmct += HMCD_BASIC_SIZE/4;
38783 +
38784 + if (p_FmPcdManipParams->u.hdr.customParams.u.genFieldReplace.mask)
38785 + {
38786 + tmpReg = p_FmPcdManipParams->u.hdr.customParams.u.genFieldReplace.mask << HMCD_GEN_FIELD_MASK_SHIFT;
38787 + tmpReg |= p_FmPcdManipParams->u.hdr.customParams.u.genFieldReplace.maskOffset << HMCD_GEN_FIELD_MASK_OFF_SHIFT;
38788 + /* write the next 4 bytes of the descriptor */
38789 + WRITE_UINT32(*p_TmpHmct, tmpReg);
38790 + }
38791 + p_TmpHmct += HMCD_PARAM_SIZE/4;
38792 + break;
38793 + default:
38794 + RETURN_ERROR(MINOR, E_INVALID_SELECTION,
38795 + ("Unknown customParams.type"));
38796 + }
38797 + }
38798 +
38799 + /* If this node has a nextManip, and no parsing is required, the old table must be copied to the new table
38800 + the old table and should be freed */
38801 + if (p_FmPcdManipParams->h_NextManip
38802 + && (p_Manip->nextManipType == e_FM_PCD_MANIP_HDR)
38803 + && (MANIP_DONT_REPARSE(p_Manip)))
38804 + {
38805 + if (new)
38806 + {
38807 + /* If this is the first time this manip is created we need to free unused memory. If it
38808 + * is a dynamic changes case, the memory used is either the CC shadow or the existing
38809 + * table - no allocation, no free */
38810 + MANIP_UPDATE_UNIFIED_POSITION(p_FmPcdManipParams->h_NextManip);
38811 +
38812 + p_Manip->unifiedPosition = e_MANIP_UNIFIED_FIRST;
38813 + }
38814 + }
38815 + else
38816 + {
38817 + ASSERT_COND(p_Last);
38818 + /* set the "last" indication on the last command of the current table */
38819 + WRITE_UINT32(*p_Last, GET_UINT32(*p_Last) | HMCD_LAST);
38820 + }
38821 +
38822 + return E_OK;
38823 +}
38824 +
38825 +static t_Error CreateManipActionNew(t_FmPcdManip *p_Manip,
38826 + t_FmPcdManipParams *p_FmPcdManipParams)
38827 +{
38828 + t_FmPcdManip *p_CurManip;
38829 + t_Error err;
38830 + uint32_t nextSize = 0, totalSize;
38831 + uint16_t tmpReg;
38832 + uint8_t *p_OldHmct, *p_TmpHmctPtr, *p_TmpDataPtr;
38833 +
38834 + /* set Manip structure */
38835 +
38836 + p_Manip->dontParseAfterManip =
38837 + p_FmPcdManipParams->u.hdr.dontParseAfterManip;
38838 +
38839 + if (p_FmPcdManipParams->h_NextManip)
38840 + { /* Next Header manipulation exists */
38841 + p_Manip->nextManipType = MANIP_GET_TYPE(p_FmPcdManipParams->h_NextManip);
38842 +
38843 + if ((p_Manip->nextManipType == e_FM_PCD_MANIP_HDR) && p_Manip->dontParseAfterManip)
38844 + nextSize = (uint32_t)(GetHmctSize(p_FmPcdManipParams->h_NextManip)
38845 + + GetDataSize(p_FmPcdManipParams->h_NextManip));
38846 + else /* either parsing is required or next manip is Frag; no table merging. */
38847 + p_Manip->cascaded = TRUE;
38848 + /* pass up the "cascaded" attribute. The whole chain is cascaded
38849 + * if something is cascaded along the way. */
38850 + if (MANIP_IS_CASCADED(p_FmPcdManipParams->h_NextManip))
38851 + p_Manip->cascaded = TRUE;
38852 + }
38853 +
38854 + /* Allocate new table */
38855 + /* calculate table size according to manip parameters */
38856 + err = CalculateTableSize(p_FmPcdManipParams, &p_Manip->tableSize,
38857 + &p_Manip->dataSize);
38858 + if (err)
38859 + RETURN_ERROR(MINOR, err, NO_MSG);
38860 +
38861 + totalSize = (uint16_t)(p_Manip->tableSize + p_Manip->dataSize + nextSize);
38862 +
38863 + p_Manip->p_Hmct = (uint8_t*)FM_MURAM_AllocMem(
38864 + ((t_FmPcd *)p_Manip->h_FmPcd)->h_FmMuram, totalSize, 4);
38865 + if (!p_Manip->p_Hmct)
38866 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("MURAM alloc failed"));
38867 +
38868 + if (p_Manip->dataSize)
38869 + p_Manip->p_Data =
38870 + (uint8_t*)PTR_MOVE(p_Manip->p_Hmct, (p_Manip->tableSize + nextSize));
38871 +
38872 + /* update shadow size to allow runtime replacement of Header manipulation */
38873 + /* The allocated shadow is divided as follows:
38874 + 0 . . . 16 . . .
38875 + --------------------------------
38876 + | Shadow | Shadow HMTD |
38877 + | HMTD | Match Table |
38878 + | (16 bytes) | (maximal size) |
38879 + --------------------------------
38880 + */
38881 +
38882 + err = FmPcdUpdateCcShadow(p_Manip->h_FmPcd, (uint32_t)(totalSize + 16),
38883 + (uint16_t)FM_PCD_CC_AD_TABLE_ALIGN);
38884 + if (err != E_OK)
38885 + {
38886 + FM_MURAM_FreeMem(p_Manip->h_FmPcd, p_Manip->p_Hmct);
38887 + RETURN_ERROR(MAJOR, E_NO_MEMORY,
38888 + ("MURAM allocation for HdrManip node shadow"));
38889 + }
38890 +
38891 + if (p_FmPcdManipParams->h_NextManip
38892 + && (p_Manip->nextManipType == e_FM_PCD_MANIP_HDR)
38893 + && (MANIP_DONT_REPARSE(p_Manip)))
38894 + {
38895 + p_OldHmct = (uint8_t *)GetManipInfo(p_FmPcdManipParams->h_NextManip,
38896 + e_MANIP_HMCT);
38897 + p_CurManip = p_FmPcdManipParams->h_NextManip;
38898 + /* Run till the last Manip (which is the first to configure) */
38899 + while (MANIP_IS_UNIFIED_NON_LAST(p_CurManip))
38900 + p_CurManip = p_CurManip->h_NextManip;
38901 +
38902 + while (p_CurManip)
38903 + {
38904 + /* If this is a unified table, point to the part of the table
38905 + * which is the relative offset in HMCT.
38906 + */
38907 + p_TmpHmctPtr = (uint8_t*)PTR_MOVE(p_Manip->p_Hmct,
38908 + (p_Manip->tableSize +
38909 + (PTR_TO_UINT(p_CurManip->p_Hmct) -
38910 + PTR_TO_UINT(p_OldHmct))));
38911 + if (p_CurManip->p_Data)
38912 + p_TmpDataPtr = (uint8_t*)PTR_MOVE(p_Manip->p_Hmct,
38913 + (p_Manip->tableSize +
38914 + (PTR_TO_UINT(p_CurManip->p_Data) -
38915 + PTR_TO_UINT(p_OldHmct))));
38916 + else
38917 + p_TmpDataPtr = NULL;
38918 +
38919 + BuildHmct(p_CurManip, &p_CurManip->manipParams, p_TmpHmctPtr,
38920 + p_TmpDataPtr, FALSE);
38921 + /* update old manip table pointer */
38922 + MANIP_SET_HMCT_PTR(p_CurManip, p_TmpHmctPtr);
38923 + MANIP_SET_DATA_PTR(p_CurManip, p_TmpDataPtr);
38924 +
38925 + p_CurManip = p_CurManip->h_PrevManip;
38926 + }
38927 + /* We copied the HMCT to create a new large HMCT so we can free the old one */
38928 + FM_MURAM_FreeMem(MANIP_GET_MURAM(p_FmPcdManipParams->h_NextManip),
38929 + p_OldHmct);
38930 + }
38931 +
38932 + /* Fill table */
38933 + err = BuildHmct(p_Manip, p_FmPcdManipParams, p_Manip->p_Hmct,
38934 + p_Manip->p_Data, TRUE);
38935 + if (err)
38936 + {
38937 + FM_MURAM_FreeMem(p_Manip->h_FmPcd, p_Manip->p_Hmct);
38938 + RETURN_ERROR(MINOR, err, NO_MSG);
38939 + }
38940 +
38941 + /* Build HMTD (table descriptor) */
38942 + tmpReg = HMTD_CFG_TYPE; /* NADEN = 0 */
38943 +
38944 + /* add parseAfterManip */
38945 + if (!p_Manip->dontParseAfterManip)
38946 + tmpReg |= HMTD_CFG_PRS_AFTER_HM;
38947 +
38948 + /* create cascade */
38949 + /*if (p_FmPcdManipParams->h_NextManip
38950 + && (!MANIP_DONT_REPARSE(p_Manip) || (p_Manip->nextManipType != e_FM_PCD_MANIP_HDR)))*/
38951 + if (p_Manip->cascaded)
38952 + {
38953 + uint16_t nextAd;
38954 + /* indicate that there's another HM table descriptor */
38955 + tmpReg |= HMTD_CFG_NEXT_AD_EN;
38956 + /* get address of next HMTD (table descriptor; h_Ad).
38957 + * If the next HMTD was removed due to table unifing, get the address
38958 + * of the "next next" as written in the h_Ad of the next h_Manip node.
38959 + */
38960 + if (p_Manip->unifiedPosition != e_MANIP_UNIFIED_FIRST)
38961 + nextAd = (uint16_t)((uint32_t)(XX_VirtToPhys(MANIP_GET_HMTD_PTR(p_FmPcdManipParams->h_NextManip)) - (((t_FmPcd*)p_Manip->h_FmPcd)->physicalMuramBase)) >> 4);
38962 + else
38963 + nextAd = ((t_Hmtd *)((t_FmPcdManip *)p_FmPcdManipParams->h_NextManip)->h_Ad)->nextAdIdx;
38964 +
38965 + WRITE_UINT16(((t_Hmtd *)p_Manip->h_Ad)->nextAdIdx, nextAd);
38966 + }
38967 +
38968 + WRITE_UINT16(((t_Hmtd *)p_Manip->h_Ad)->cfg, tmpReg);
38969 + WRITE_UINT32(
38970 + ((t_Hmtd *)p_Manip->h_Ad)->hmcdBasePtr,
38971 + (uint32_t)(XX_VirtToPhys(p_Manip->p_Hmct) - (((t_FmPcd*)p_Manip->h_FmPcd)->physicalMuramBase)));
38972 +
38973 + WRITE_UINT8(((t_Hmtd *)p_Manip->h_Ad)->opCode, HMAN_OC);
38974 +
38975 + if (p_Manip->unifiedPosition == e_MANIP_UNIFIED_FIRST)
38976 + {
38977 + /* The HMTD of the next Manip is never going to be used */
38978 + if (((t_FmPcdManip *)p_FmPcdManipParams->h_NextManip)->muramAllocate)
38979 + FM_MURAM_FreeMem(
38980 + ((t_FmPcd *)((t_FmPcdManip *)p_FmPcdManipParams->h_NextManip)->h_FmPcd)->h_FmMuram,
38981 + ((t_FmPcdManip *)p_FmPcdManipParams->h_NextManip)->h_Ad);
38982 + else
38983 + XX_Free(((t_FmPcdManip *)p_FmPcdManipParams->h_NextManip)->h_Ad);
38984 + ((t_FmPcdManip *)p_FmPcdManipParams->h_NextManip)->h_Ad = NULL;
38985 + }
38986 +
38987 + return E_OK;
38988 +}
38989 +
38990 +static t_Error CreateManipActionShadow(t_FmPcdManip *p_Manip,
38991 + t_FmPcdManipParams *p_FmPcdManipParams)
38992 +{
38993 + uint8_t *p_WholeHmct, *p_TmpHmctPtr, newDataSize, *p_TmpDataPtr = NULL;
38994 + uint16_t newSize;
38995 + t_FmPcd *p_FmPcd = (t_FmPcd *)p_Manip->h_FmPcd;
38996 + t_Error err;
38997 + t_FmPcdManip *p_CurManip = p_Manip;
38998 +
38999 + err = CalculateTableSize(p_FmPcdManipParams, &newSize, &newDataSize);
39000 + if (err)
39001 + RETURN_ERROR(MINOR, err, NO_MSG);
39002 +
39003 + /* check coherency of new table parameters */
39004 + if (newSize > p_Manip->tableSize)
39005 + RETURN_ERROR(
39006 + MINOR,
39007 + E_INVALID_VALUE,
39008 + ("New Hdr Manip configuration requires larger size than current one (command table)."));
39009 + if (newDataSize > p_Manip->dataSize)
39010 + RETURN_ERROR(
39011 + MINOR,
39012 + E_INVALID_VALUE,
39013 + ("New Hdr Manip configuration requires larger size than current one (data)."));
39014 + if (p_FmPcdManipParams->h_NextManip)
39015 + RETURN_ERROR(
39016 + MINOR, E_INVALID_VALUE,
39017 + ("New Hdr Manip configuration can not contain h_NextManip."));
39018 + if (MANIP_IS_UNIFIED(p_Manip) && (newSize != p_Manip->tableSize))
39019 + RETURN_ERROR(
39020 + MINOR,
39021 + E_INVALID_VALUE,
39022 + ("New Hdr Manip configuration in a chained manipulation requires different size than current one."));
39023 + if (p_Manip->dontParseAfterManip
39024 + != p_FmPcdManipParams->u.hdr.dontParseAfterManip)
39025 + RETURN_ERROR(
39026 + MINOR,
39027 + E_INVALID_VALUE,
39028 + ("New Hdr Manip configuration differs in dontParseAfterManip value."));
39029 +
39030 + p_Manip->tableSize = newSize;
39031 + p_Manip->dataSize = newDataSize;
39032 +
39033 + /* Build the new table in the shadow */
39034 + if (!MANIP_IS_UNIFIED(p_Manip))
39035 + {
39036 + p_TmpHmctPtr = (uint8_t*)PTR_MOVE(p_FmPcd->p_CcShadow, 16);
39037 + if (p_Manip->p_Data)
39038 + p_TmpDataPtr =
39039 + (uint8_t*)PTR_MOVE(p_TmpHmctPtr,
39040 + (PTR_TO_UINT(p_Manip->p_Data) - PTR_TO_UINT(p_Manip->p_Hmct)));
39041 +
39042 + BuildHmct(p_Manip, p_FmPcdManipParams, p_TmpHmctPtr, p_Manip->p_Data,
39043 + FALSE);
39044 + }
39045 + else
39046 + {
39047 + p_WholeHmct = (uint8_t *)GetManipInfo(p_Manip, e_MANIP_HMCT);
39048 + ASSERT_COND(p_WholeHmct);
39049 +
39050 + /* Run till the last Manip (which is the first to configure) */
39051 + while (MANIP_IS_UNIFIED_NON_LAST(p_CurManip))
39052 + p_CurManip = p_CurManip->h_NextManip;
39053 +
39054 + while (p_CurManip)
39055 + {
39056 + /* If this is a non-head node in a unified table, point to the part of the shadow
39057 + * which is the relative offset in HMCT.
39058 + * else, point to the beginning of the
39059 + * shadow table (we save 16 for the HMTD.
39060 + */
39061 + p_TmpHmctPtr =
39062 + (uint8_t*)PTR_MOVE(p_FmPcd->p_CcShadow,
39063 + (16 + PTR_TO_UINT(p_CurManip->p_Hmct) - PTR_TO_UINT(p_WholeHmct)));
39064 + if (p_CurManip->p_Data)
39065 + p_TmpDataPtr =
39066 + (uint8_t*)PTR_MOVE(p_FmPcd->p_CcShadow,
39067 + (16 + PTR_TO_UINT(p_CurManip->p_Data) - PTR_TO_UINT(p_WholeHmct)));
39068 +
39069 + BuildHmct(p_CurManip, &p_CurManip->manipParams, p_TmpHmctPtr,
39070 + p_TmpDataPtr, FALSE);
39071 + p_CurManip = p_CurManip->h_PrevManip;
39072 + }
39073 + }
39074 +
39075 + return E_OK;
39076 +}
39077 +
39078 +static t_Error CreateManipActionBackToOrig(
39079 + t_FmPcdManip *p_Manip, t_FmPcdManipParams *p_FmPcdManipParams)
39080 +{
39081 + uint8_t *p_WholeHmct = NULL, *p_TmpHmctPtr, *p_TmpDataPtr;
39082 + t_FmPcdManip *p_CurManip = p_Manip;
39083 +
39084 + /* Build the new table in the shadow */
39085 + if (!MANIP_IS_UNIFIED(p_Manip))
39086 + BuildHmct(p_Manip, p_FmPcdManipParams, p_Manip->p_Hmct, p_Manip->p_Data,
39087 + FALSE);
39088 + else
39089 + {
39090 + p_WholeHmct = (uint8_t *)GetManipInfo(p_Manip, e_MANIP_HMCT);
39091 + ASSERT_COND(p_WholeHmct);
39092 +
39093 + /* Run till the last Manip (which is the first to configure) */
39094 + while (MANIP_IS_UNIFIED_NON_LAST(p_CurManip))
39095 + p_CurManip = p_CurManip->h_NextManip;
39096 +
39097 + while (p_CurManip)
39098 + {
39099 + /* If this is a unified table, point to the part of the table
39100 + * which is the relative offset in HMCT.
39101 + */
39102 + p_TmpHmctPtr = p_CurManip->p_Hmct; /*- (uint32_t)p_WholeHmct*/
39103 + p_TmpDataPtr = p_CurManip->p_Data; /*- (uint32_t)p_WholeHmct*/
39104 +
39105 + BuildHmct(p_CurManip, &p_CurManip->manipParams, p_TmpHmctPtr,
39106 + p_TmpDataPtr, FALSE);
39107 +
39108 + p_CurManip = p_CurManip->h_PrevManip;
39109 + }
39110 + }
39111 +
39112 + return E_OK;
39113 +}
39114 +
39115 +#if (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10))
39116 +static t_Error UpdateManipIc(t_Handle h_Manip, uint8_t icOffset)
39117 +{
39118 + t_FmPcdManip *p_Manip = (t_FmPcdManip *)h_Manip;
39119 + t_Handle p_Ad;
39120 + uint32_t tmpReg32 = 0;
39121 + SANITY_CHECK_RETURN_ERROR(h_Manip, E_INVALID_HANDLE);
39122 + SANITY_CHECK_RETURN_ERROR(p_Manip->h_Ad, E_INVALID_HANDLE);
39123 +
39124 + switch (p_Manip->opcode)
39125 + {
39126 + case (HMAN_OC_MV_INT_FRAME_HDR_FROM_FRM_TO_BUFFER_PREFFIX):
39127 + p_Ad = (t_AdOfTypeContLookup *)p_Manip->h_Ad;
39128 + if (p_Manip->updateParams & INTERNAL_CONTEXT_OFFSET)
39129 + {
39130 + tmpReg32 =
39131 + *(uint32_t *)&((t_AdOfTypeContLookup *)p_Ad)->pcAndOffsets;
39132 + tmpReg32 |= (uint32_t)((uint32_t)icOffset << 16);
39133 + *(uint32_t *)&((t_AdOfTypeContLookup *)p_Ad)->pcAndOffsets =
39134 + tmpReg32;
39135 + p_Manip->updateParams &= ~INTERNAL_CONTEXT_OFFSET;
39136 + p_Manip->icOffset = icOffset;
39137 + }
39138 + else
39139 + {
39140 + if (p_Manip->icOffset != icOffset)
39141 + RETURN_ERROR(
39142 + MAJOR,
39143 + E_INVALID_VALUE,
39144 + ("this manipulation was updated previously by different value"););
39145 + }
39146 + break;
39147 + case (HMAN_OC_CAPWAP_RMV_DTLS_IF_EXIST):
39148 + if (p_Manip->h_Frag)
39149 + {
39150 + if (p_Manip->updateParams & INTERNAL_CONTEXT_OFFSET)
39151 + {
39152 + p_Ad = (t_AdOfTypeContLookup *)p_Manip->h_Ad;
39153 + tmpReg32 |= GET_UINT32(((t_AdOfTypeContLookup *)p_Ad)->pcAndOffsets);
39154 + tmpReg32 |= (uint32_t)((uint32_t)icOffset << 16);
39155 + WRITE_UINT32(((t_AdOfTypeContLookup *)p_Ad)->pcAndOffsets, tmpReg32);
39156 + p_Manip->updateParams &= ~INTERNAL_CONTEXT_OFFSET;
39157 + p_Manip->icOffset = icOffset;
39158 + }
39159 + else
39160 + {
39161 + if (p_Manip->icOffset != icOffset)
39162 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("this manipulation was updated previousely by different value"););
39163 + }
39164 + }
39165 + break;
39166 + }
39167 +
39168 + return E_OK;
39169 +}
39170 +
39171 +static t_Error UpdateInitMvIntFrameHeaderFromFrameToBufferPrefix(
39172 + t_Handle h_FmPort, t_FmPcdManip *p_Manip, t_Handle h_Ad, bool validate)
39173 +{
39174 +
39175 + t_AdOfTypeContLookup *p_Ad = (t_AdOfTypeContLookup *)h_Ad;
39176 + t_FmPortGetSetCcParams fmPortGetSetCcParams;
39177 + t_Error err;
39178 + uint32_t tmpReg32;
39179 +
39180 + memset(&fmPortGetSetCcParams, 0, sizeof(t_FmPortGetSetCcParams));
39181 +
39182 + SANITY_CHECK_RETURN_ERROR(p_Manip, E_INVALID_HANDLE);
39183 + SANITY_CHECK_RETURN_ERROR(
39184 + (p_Manip->opcode & HMAN_OC_MV_INT_FRAME_HDR_FROM_FRM_TO_BUFFER_PREFFIX),
39185 + E_INVALID_STATE);
39186 + SANITY_CHECK_RETURN_ERROR(!p_Manip->muramAllocate, E_INVALID_STATE);
39187 +
39188 + if (p_Manip->updateParams)
39189 + {
39190 + if ((!(p_Manip->updateParams & OFFSET_OF_PR))
39191 + || (p_Manip->shadowUpdateParams & OFFSET_OF_PR))
39192 + RETURN_ERROR(
39193 + MAJOR, E_INVALID_STATE,
39194 + ("in this stage parameters from Port has not be updated"));
39195 +
39196 + fmPortGetSetCcParams.getCcParams.type = p_Manip->updateParams;
39197 + fmPortGetSetCcParams.setCcParams.type = UPDATE_PSO;
39198 + fmPortGetSetCcParams.setCcParams.psoSize = 16;
39199 +
39200 + err = FmPortGetSetCcParams(h_FmPort, &fmPortGetSetCcParams);
39201 + if (err)
39202 + RETURN_ERROR(MAJOR, err, NO_MSG);
39203 + if (fmPortGetSetCcParams.getCcParams.type & OFFSET_OF_PR)
39204 + RETURN_ERROR(
39205 + MAJOR, E_INVALID_STATE,
39206 + ("Parser result offset wasn't configured previousely"));
39207 +#ifdef FM_LOCKUP_ALIGNMENT_ERRATA_FMAN_SW004
39208 + ASSERT_COND(!(fmPortGetSetCcParams.getCcParams.prOffset % 16));
39209 +#endif
39210 + }
39211 + else
39212 + if (validate)
39213 + {
39214 + if ((!(p_Manip->shadowUpdateParams & OFFSET_OF_PR))
39215 + || (p_Manip->updateParams & OFFSET_OF_PR))
39216 + RETURN_ERROR(
39217 + MAJOR, E_INVALID_STATE,
39218 + ("in this stage parameters from Port has be updated"));
39219 + fmPortGetSetCcParams.getCcParams.type = p_Manip->shadowUpdateParams;
39220 + fmPortGetSetCcParams.setCcParams.type = UPDATE_PSO;
39221 + fmPortGetSetCcParams.setCcParams.psoSize = 16;
39222 +
39223 + err = FmPortGetSetCcParams(h_FmPort, &fmPortGetSetCcParams);
39224 + if (err)
39225 + RETURN_ERROR(MAJOR, err, NO_MSG);
39226 + if (fmPortGetSetCcParams.getCcParams.type & OFFSET_OF_PR)
39227 + RETURN_ERROR(
39228 + MAJOR, E_INVALID_STATE,
39229 + ("Parser result offset wasn't configured previousely"));
39230 +
39231 + }
39232 +
39233 + ASSERT_COND(p_Ad);
39234 +
39235 + if (p_Manip->updateParams & OFFSET_OF_PR)
39236 + {
39237 + tmpReg32 = 0;
39238 + tmpReg32 |= fmPortGetSetCcParams.getCcParams.prOffset;
39239 + WRITE_UINT32(p_Ad->matchTblPtr,
39240 + (GET_UINT32(p_Ad->matchTblPtr) | tmpReg32));
39241 + p_Manip->updateParams &= ~OFFSET_OF_PR;
39242 + p_Manip->shadowUpdateParams |= OFFSET_OF_PR;
39243 + }
39244 + else
39245 + if (validate)
39246 + {
39247 + tmpReg32 = GET_UINT32(p_Ad->matchTblPtr);
39248 + if ((uint8_t)tmpReg32 != fmPortGetSetCcParams.getCcParams.prOffset)
39249 + RETURN_ERROR(
39250 + MAJOR,
39251 + E_INVALID_STATE,
39252 + ("this manipulation was updated previousely by different value"););
39253 + }
39254 +
39255 + return E_OK;
39256 +}
39257 +
39258 +static t_Error UpdateModifyCapwapFragmenation(t_FmPcdManip *p_Manip, t_Handle h_Ad, bool validate,t_Handle h_FmTree)
39259 +{
39260 + t_AdOfTypeContLookup *p_Ad = (t_AdOfTypeContLookup *)h_Ad;
39261 + t_FmPcdCcSavedManipParams *p_SavedManipParams = NULL;
39262 + uint32_t tmpReg32 = 0;
39263 +
39264 + SANITY_CHECK_RETURN_ERROR(p_Manip,E_INVALID_HANDLE);
39265 + SANITY_CHECK_RETURN_ERROR(p_Manip->h_Frag,E_INVALID_HANDLE);
39266 + SANITY_CHECK_RETURN_ERROR(p_Manip->frag,E_INVALID_HANDLE);
39267 + 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);
39268 +
39269 + p_Ad = (t_AdOfTypeContLookup *)p_Manip->h_Frag;
39270 +
39271 + if (p_Manip->updateParams)
39272 + {
39273 +
39274 + if ((!(p_Manip->updateParams & OFFSET_OF_DATA)) ||
39275 + ((p_Manip->shadowUpdateParams & OFFSET_OF_DATA)))
39276 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("in this stage parameters from Port has not be updated"));
39277 + p_SavedManipParams = FmPcdCcTreeGetSavedManipParams(h_FmTree);
39278 + if (!p_SavedManipParams)
39279 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("for this manipulation tree has to be configured previosely with this type"));
39280 + p_Manip->capwapFragParams.dataOffset = p_SavedManipParams->capwapParams.dataOffset;
39281 +
39282 + tmpReg32 = GET_UINT32(p_Ad->pcAndOffsets);
39283 + tmpReg32 |= ((uint32_t)p_Manip->capwapFragParams.dataOffset<< 16);
39284 + WRITE_UINT32(p_Ad->pcAndOffsets,tmpReg32);
39285 +
39286 + p_Manip->updateParams &= ~OFFSET_OF_DATA;
39287 + p_Manip->shadowUpdateParams |= OFFSET_OF_DATA;
39288 + }
39289 + else if (validate)
39290 + {
39291 +
39292 + p_SavedManipParams = FmPcdCcTreeGetSavedManipParams(h_FmTree);
39293 + if (!p_SavedManipParams)
39294 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("for this manipulation tree has to be configured previosely with this type"));
39295 + if (p_Manip->capwapFragParams.dataOffset != p_SavedManipParams->capwapParams.dataOffset)
39296 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("this manipulation was updated previousely by different value"));
39297 + }
39298 +
39299 + return E_OK;
39300 +}
39301 +
39302 +static t_Error UpdateInitCapwapFragmentation(t_Handle h_FmPort,
39303 + t_FmPcdManip *p_Manip,
39304 + t_Handle h_Ad,
39305 + bool validate,
39306 + t_Handle h_FmTree)
39307 +{
39308 + t_AdOfTypeContLookup *p_Ad;
39309 + t_FmPortGetSetCcParams fmPortGetSetCcParams;
39310 + t_Error err;
39311 + uint32_t tmpReg32 = 0;
39312 + t_FmPcdCcSavedManipParams *p_SavedManipParams;
39313 +
39314 + UNUSED(h_Ad);
39315 +
39316 + SANITY_CHECK_RETURN_ERROR(p_Manip,E_INVALID_HANDLE);
39317 + SANITY_CHECK_RETURN_ERROR(p_Manip->h_Frag,E_INVALID_HANDLE);
39318 + SANITY_CHECK_RETURN_ERROR(p_Manip->frag,E_INVALID_HANDLE);
39319 + SANITY_CHECK_RETURN_ERROR(((p_Manip->opcode == HMAN_OC_CAPWAP_FRAGMENTATION) ||
39320 + (p_Manip->opcode == HMAN_OC_INSRT_HDR_BY_TEMPL_N_OR_FRAG_AFTER)), E_INVALID_STATE);
39321 +
39322 + p_Ad = (t_AdOfTypeContLookup *)p_Manip->h_Frag;
39323 +
39324 + if (p_Manip->updateParams)
39325 + {
39326 + if ((!(p_Manip->updateParams & OFFSET_OF_DATA)) ||
39327 + ((p_Manip->shadowUpdateParams & OFFSET_OF_DATA)))
39328 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("in this stage parameters from Port has not be updated"));
39329 + fmPortGetSetCcParams.getCcParams.type = p_Manip->updateParams;
39330 + fmPortGetSetCcParams.setCcParams.type = UPDATE_NIA_PNEN | UPDATE_FMFP_PRC_WITH_ONE_RISC_ONLY;
39331 + fmPortGetSetCcParams.setCcParams.nia = NIA_FM_CTL_AC_POP_TO_N_STEP | NIA_ENG_FM_CTL;
39332 + /* For CAPWAP Rassembly used FMAN_CTRL2 hardcoded - so for fragmentation its better to use FMAN_CTRL1 */
39333 + fmPortGetSetCcParams.setCcParams.orFmanCtrl = FPM_PORT_FM_CTL1;
39334 +
39335 + err = FmPortGetSetCcParams(h_FmPort, &fmPortGetSetCcParams);
39336 + if (err)
39337 + RETURN_ERROR(MAJOR, err, NO_MSG);
39338 +
39339 + if (fmPortGetSetCcParams.getCcParams.type & OFFSET_OF_DATA)
39340 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Data offset wasn't configured previousely"));
39341 +
39342 + p_SavedManipParams = (t_FmPcdCcSavedManipParams *)XX_Malloc(sizeof(t_FmPcdCcSavedManipParams));
39343 + p_SavedManipParams->capwapParams.dataOffset = fmPortGetSetCcParams.getCcParams.dataOffset;
39344 +
39345 +#ifdef FM_LOCKUP_ALIGNMENT_ERRATA_FMAN_SW004
39346 + ASSERT_COND(!(p_SavedManipParams->capwapParams.dataOffset % 16));
39347 +#endif /* FM_LOCKUP_ALIGNMENT_ERRATA_FMAN_SW004 */
39348 +
39349 + FmPcdCcTreeSetSavedManipParams(h_FmTree, (t_Handle)p_SavedManipParams);
39350 + }
39351 + else if (validate)
39352 + {
39353 + if ((!(p_Manip->shadowUpdateParams & OFFSET_OF_DATA)) ||
39354 + ((p_Manip->updateParams & OFFSET_OF_DATA)))
39355 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("in this stage parameters from Port has be updated"));
39356 + fmPortGetSetCcParams.getCcParams.type = p_Manip->shadowUpdateParams;
39357 + fmPortGetSetCcParams.setCcParams.type = UPDATE_NIA_PNEN | UPDATE_FMFP_PRC_WITH_ONE_RISC_ONLY;
39358 + fmPortGetSetCcParams.setCcParams.nia = NIA_FM_CTL_AC_POP_TO_N_STEP | NIA_ENG_FM_CTL;
39359 + err = FmPortGetSetCcParams(h_FmPort, &fmPortGetSetCcParams);
39360 + if (err)
39361 + RETURN_ERROR(MAJOR, err, NO_MSG);
39362 +
39363 + if (fmPortGetSetCcParams.getCcParams.type & OFFSET_OF_DATA)
39364 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Data offset wasn't configured previousely"));
39365 + }
39366 +
39367 + if (p_Manip->updateParams)
39368 + {
39369 + tmpReg32 = GET_UINT32(p_Ad->pcAndOffsets);
39370 + tmpReg32 |= ((uint32_t)fmPortGetSetCcParams.getCcParams.dataOffset<< 16);
39371 + WRITE_UINT32(p_Ad->pcAndOffsets,tmpReg32);
39372 +
39373 + p_Manip->updateParams &= ~OFFSET_OF_DATA;
39374 + p_Manip->shadowUpdateParams |= OFFSET_OF_DATA;
39375 + p_Manip->capwapFragParams.dataOffset = fmPortGetSetCcParams.getCcParams.dataOffset;
39376 + }
39377 + else if (validate)
39378 + {
39379 + if (p_Manip->capwapFragParams.dataOffset != fmPortGetSetCcParams.getCcParams.dataOffset)
39380 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("this manipulation was updated previousely by different value"));
39381 + }
39382 +
39383 + return E_OK;
39384 +}
39385 +
39386 +static t_Error UpdateInitCapwapReasm(t_Handle h_FmPcd,
39387 + t_Handle h_FmPort,
39388 + t_FmPcdManip *p_Manip,
39389 + t_Handle h_Ad,
39390 + bool validate)
39391 +{
39392 + t_CapwapReasmPram *p_ReassmTbl;
39393 + t_Error err;
39394 + t_FmPortGetSetCcParams fmPortGetSetCcParams;
39395 + uint8_t i = 0;
39396 + uint16_t size;
39397 + uint32_t tmpReg32;
39398 + t_FmPcd *p_FmPcd = (t_FmPcd *)h_FmPcd;
39399 + t_FmPcdCcCapwapReassmTimeoutParams ccCapwapReassmTimeoutParams;
39400 +
39401 + SANITY_CHECK_RETURN_ERROR(p_Manip,E_INVALID_HANDLE);
39402 + SANITY_CHECK_RETURN_ERROR(p_Manip->h_Frag,E_INVALID_HANDLE);
39403 + SANITY_CHECK_RETURN_ERROR(!p_Manip->frag,E_INVALID_HANDLE);
39404 + SANITY_CHECK_RETURN_ERROR((p_Manip->opcode == HMAN_OC_CAPWAP_RMV_DTLS_IF_EXIST), E_INVALID_STATE);
39405 + SANITY_CHECK_RETURN_ERROR(h_FmPcd,E_INVALID_HANDLE);
39406 + SANITY_CHECK_RETURN_ERROR(p_FmPcd->h_Hc,E_INVALID_HANDLE);
39407 +
39408 + if (p_Manip->h_FmPcd != h_FmPcd)
39409 + RETURN_ERROR(MAJOR, E_INVALID_STATE,
39410 + ("handler of PCD previously was initiated by different value"));
39411 +
39412 + UNUSED(h_Ad);
39413 +
39414 + memset(&fmPortGetSetCcParams, 0, sizeof(t_FmPortGetSetCcParams));
39415 + p_ReassmTbl = (t_CapwapReasmPram *)p_Manip->h_Frag;
39416 +
39417 + if (p_Manip->updateParams)
39418 + {
39419 + if ((!(p_Manip->updateParams & NUM_OF_TASKS) &&
39420 + !(p_Manip->updateParams & OFFSET_OF_DATA) &&
39421 + !(p_Manip->updateParams & OFFSET_OF_PR) &&
39422 + !(p_Manip->updateParams & HW_PORT_ID)) ||
39423 + ((p_Manip->shadowUpdateParams & NUM_OF_TASKS) ||
39424 + (p_Manip->shadowUpdateParams & OFFSET_OF_DATA) || (p_Manip->shadowUpdateParams & OFFSET_OF_PR) ||
39425 + (p_Manip->shadowUpdateParams & HW_PORT_ID)))
39426 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("in this stage parameters from Port has not be updated"));
39427 +
39428 + fmPortGetSetCcParams.getCcParams.type = p_Manip->updateParams;
39429 + fmPortGetSetCcParams.setCcParams.type = UPDATE_NIA_PNEN;
39430 + fmPortGetSetCcParams.setCcParams.nia = NIA_FM_CTL_AC_POP_TO_N_STEP | NIA_ENG_FM_CTL;
39431 +
39432 + err = FmPortGetSetCcParams(h_FmPort, &fmPortGetSetCcParams);
39433 + if (err)
39434 + RETURN_ERROR(MAJOR, err, NO_MSG);
39435 +
39436 + if (fmPortGetSetCcParams.getCcParams.type & NUM_OF_TASKS)
39437 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Num of tasks wasn't configured previousely"));
39438 + if (fmPortGetSetCcParams.getCcParams.type & OFFSET_OF_DATA)
39439 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("offset of the data wasn't configured previousely"));
39440 + if (fmPortGetSetCcParams.getCcParams.type & HW_PORT_ID)
39441 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("hwPortId wasn't updated"));
39442 +#ifdef FM_LOCKUP_ALIGNMENT_ERRATA_FMAN_SW004
39443 + ASSERT_COND((fmPortGetSetCcParams.getCcParams.dataOffset % 16) == 0);
39444 +#endif /* FM_LOCKUP_ALIGNMENT_ERRATA_FMAN_SW004 */
39445 + }
39446 + else if (validate)
39447 + {
39448 + if ((!(p_Manip->shadowUpdateParams & NUM_OF_TASKS) &&
39449 + !(p_Manip->shadowUpdateParams & OFFSET_OF_DATA) &&
39450 + !(p_Manip->shadowUpdateParams & OFFSET_OF_PR) &&
39451 + !(p_Manip->shadowUpdateParams & HW_PORT_ID)) &&
39452 + ((p_Manip->updateParams & NUM_OF_TASKS) ||
39453 + (p_Manip->updateParams & OFFSET_OF_DATA) || (p_Manip->updateParams & OFFSET_OF_PR) ||
39454 + (p_Manip->updateParams & HW_PORT_ID)))
39455 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("in this stage parameters from Port has be updated"));
39456 +
39457 + fmPortGetSetCcParams.getCcParams.type = p_Manip->shadowUpdateParams;
39458 + fmPortGetSetCcParams.setCcParams.type = UPDATE_NIA_PNEN;
39459 + fmPortGetSetCcParams.setCcParams.nia = NIA_FM_CTL_AC_POP_TO_N_STEP | NIA_ENG_FM_CTL;
39460 +
39461 + err = FmPortGetSetCcParams(h_FmPort, &fmPortGetSetCcParams);
39462 + if (err)
39463 + RETURN_ERROR(MAJOR, err, NO_MSG);
39464 +
39465 + if (fmPortGetSetCcParams.getCcParams.type & NUM_OF_TASKS)
39466 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("NumOfTasks wasn't configured previously"));
39467 + if (fmPortGetSetCcParams.getCcParams.type & OFFSET_OF_DATA)
39468 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("offset of the data wasn't configured previously"));
39469 + if (fmPortGetSetCcParams.getCcParams.type & HW_PORT_ID)
39470 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("hwPortId wasn't updated"));
39471 + }
39472 +
39473 + if (p_Manip->updateParams)
39474 + {
39475 + if (p_Manip->updateParams & NUM_OF_TASKS)
39476 + {
39477 + /*recommendation of Microcode team - (maxNumFramesInProcess * 2) */
39478 + size = (uint16_t)(p_Manip->capwapFragParams.maxNumFramesInProcess*2 + fmPortGetSetCcParams.getCcParams.numOfTasks);
39479 + if (size > 255)
39480 + RETURN_ERROR(MAJOR,E_INVALID_VALUE, ("numOfOpenReassmEntries + numOfTasks per port can not be greater than 256"));
39481 +
39482 + p_Manip->capwapFragParams.numOfTasks = fmPortGetSetCcParams.getCcParams.numOfTasks;
39483 +
39484 + /*p_ReassmFrmDescrIndxPoolTbl*/
39485 + p_Manip->capwapFragParams.p_ReassmFrmDescrIndxPoolTbl =
39486 + (t_Handle)FM_MURAM_AllocMem(p_FmPcd->h_FmMuram,
39487 + (uint32_t)(size + 1),
39488 + 4);
39489 + if (!p_Manip->capwapFragParams.p_ReassmFrmDescrIndxPoolTbl)
39490 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("MURAM alloc for CAPWAP Reassembly frame buffer index pool table"));
39491 +
39492 + MemSet8(p_Manip->capwapFragParams.p_ReassmFrmDescrIndxPoolTbl, 0, (uint32_t)(size + 1));
39493 +
39494 + for ( i = 0; i < size; i++)
39495 + WRITE_UINT8(*(uint8_t *)PTR_MOVE(p_Manip->capwapFragParams.p_ReassmFrmDescrIndxPoolTbl, i), (uint8_t)(i+1));
39496 +
39497 + tmpReg32 = (uint32_t)(XX_VirtToPhys(p_Manip->capwapFragParams.p_ReassmFrmDescrIndxPoolTbl) - p_FmPcd->physicalMuramBase);
39498 +
39499 + WRITE_UINT32(p_ReassmTbl->reasmFrmDescIndexPoolTblPtr, tmpReg32);
39500 +
39501 + /*p_ReassmFrmDescrPoolTbl*/
39502 + p_Manip->capwapFragParams.p_ReassmFrmDescrPoolTbl =
39503 + (t_Handle)FM_MURAM_AllocMem(p_FmPcd->h_FmMuram,
39504 + (uint32_t)((size + 1) * FM_PCD_MANIP_CAPWAP_REASM_RFD_SIZE),
39505 + 4);
39506 +
39507 + if (!p_Manip->capwapFragParams.p_ReassmFrmDescrPoolTbl)
39508 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("MURAM alloc for CAPWAP Reassembly frame buffer pool table"));
39509 +
39510 + MemSet8(p_Manip->capwapFragParams.p_ReassmFrmDescrPoolTbl, 0, (uint32_t)((size +1)* FM_PCD_MANIP_CAPWAP_REASM_RFD_SIZE));
39511 +
39512 + tmpReg32 = (uint32_t)(XX_VirtToPhys(p_Manip->capwapFragParams.p_ReassmFrmDescrPoolTbl) - p_FmPcd->physicalMuramBase);
39513 +
39514 + WRITE_UINT32(p_ReassmTbl->reasmFrmDescPoolTblPtr, tmpReg32);
39515 +
39516 + /*p_TimeOutTbl*/
39517 +
39518 + p_Manip->capwapFragParams.p_TimeOutTbl =
39519 + (t_Handle)FM_MURAM_AllocMem(p_FmPcd->h_FmMuram,
39520 + (uint32_t)((size + 1)* FM_PCD_MANIP_CAPWAP_REASM_TIME_OUT_ENTRY_SIZE),
39521 + 4);
39522 +
39523 + if (!p_Manip->capwapFragParams.p_TimeOutTbl)
39524 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("MURAM alloc for CAPWAP Reassembly timeout table"));
39525 +
39526 + MemSet8(p_Manip->capwapFragParams.p_TimeOutTbl, 0, (uint16_t)((size + 1)*FM_PCD_MANIP_CAPWAP_REASM_TIME_OUT_ENTRY_SIZE));
39527 +
39528 + tmpReg32 = (uint32_t)(XX_VirtToPhys(p_Manip->capwapFragParams.p_TimeOutTbl) - p_FmPcd->physicalMuramBase);
39529 + WRITE_UINT32(p_ReassmTbl->timeOutTblPtr, tmpReg32);
39530 +
39531 + p_Manip->updateParams &= ~NUM_OF_TASKS;
39532 + p_Manip->shadowUpdateParams |= NUM_OF_TASKS;
39533 + }
39534 +
39535 + if (p_Manip->updateParams & OFFSET_OF_DATA)
39536 + {
39537 + p_Manip->capwapFragParams.dataOffset = fmPortGetSetCcParams.getCcParams.dataOffset;
39538 + tmpReg32 = GET_UINT32(p_ReassmTbl->mode);
39539 + tmpReg32|= p_Manip->capwapFragParams.dataOffset;
39540 + WRITE_UINT32(p_ReassmTbl->mode, tmpReg32);
39541 + p_Manip->updateParams &= ~OFFSET_OF_DATA;
39542 + p_Manip->shadowUpdateParams |= OFFSET_OF_DATA;
39543 + }
39544 +
39545 + if (!(fmPortGetSetCcParams.getCcParams.type & OFFSET_OF_PR))
39546 + {
39547 + p_Manip->capwapFragParams.prOffset = fmPortGetSetCcParams.getCcParams.prOffset;
39548 +
39549 + tmpReg32 = GET_UINT32(p_ReassmTbl->mode);
39550 + tmpReg32|= FM_PCD_MANIP_CAPWAP_REASM_PR_COPY;
39551 + WRITE_UINT32(p_ReassmTbl->mode, tmpReg32);
39552 +
39553 + tmpReg32 = GET_UINT32(p_ReassmTbl->intStatsTblPtr);
39554 + tmpReg32 |= (uint32_t)p_Manip->capwapFragParams.prOffset << 24;
39555 + WRITE_UINT32(p_ReassmTbl->intStatsTblPtr, tmpReg32);
39556 + p_Manip->updateParams &= ~OFFSET_OF_PR;
39557 + p_Manip->shadowUpdateParams |= OFFSET_OF_PR;
39558 + }
39559 + else
39560 + {
39561 + p_Manip->capwapFragParams.prOffset = 0xff;
39562 + p_Manip->updateParams &= ~OFFSET_OF_PR;
39563 + p_Manip->shadowUpdateParams |= OFFSET_OF_PR;
39564 + }
39565 +
39566 + p_Manip->capwapFragParams.hwPortId = fmPortGetSetCcParams.getCcParams.hardwarePortId;
39567 + p_Manip->updateParams &= ~HW_PORT_ID;
39568 + p_Manip->shadowUpdateParams |= HW_PORT_ID;
39569 +
39570 + /*timeout hc */
39571 + ccCapwapReassmTimeoutParams.fqidForTimeOutFrames = p_Manip->capwapFragParams.fqidForTimeOutFrames;
39572 + ccCapwapReassmTimeoutParams.portIdAndCapwapReassmTbl = (uint32_t)p_Manip->capwapFragParams.hwPortId << 24;
39573 + ccCapwapReassmTimeoutParams.portIdAndCapwapReassmTbl |= (uint32_t)((XX_VirtToPhys(p_ReassmTbl) - p_FmPcd->physicalMuramBase));
39574 + ccCapwapReassmTimeoutParams.timeoutRequestTime = (((uint32_t)1<<p_Manip->capwapFragParams.bitFor1Micro) * p_Manip->capwapFragParams.timeoutRoutineRequestTime)/2;
39575 + return FmHcPcdCcCapwapTimeoutReassm(p_FmPcd->h_Hc,&ccCapwapReassmTimeoutParams);
39576 + }
39577 +
39578 + else if (validate)
39579 + {
39580 + if (fmPortGetSetCcParams.getCcParams.hardwarePortId != p_Manip->capwapFragParams.hwPortId)
39581 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Reassembly manipulation previously was assigned to another port"));
39582 + if (fmPortGetSetCcParams.getCcParams.numOfTasks != p_Manip->capwapFragParams.numOfTasks)
39583 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("numOfTasks for this manipulation previously was defined by another value "));
39584 +
39585 + if (!(fmPortGetSetCcParams.getCcParams.type & OFFSET_OF_PR))
39586 + {
39587 + if (p_Manip->capwapFragParams.prOffset != fmPortGetSetCcParams.getCcParams.prOffset)
39588 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Parse result offset previously was defined by another value "));
39589 + }
39590 + else
39591 + {
39592 + if (p_Manip->capwapFragParams.prOffset != 0xff)
39593 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Parse result offset previously was defined by another value "));
39594 + }
39595 + if (fmPortGetSetCcParams.getCcParams.dataOffset != p_Manip->capwapFragParams.dataOffset)
39596 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Data offset previously was defined by another value "));
39597 + }
39598 +
39599 + return E_OK;
39600 +}
39601 +#endif /* (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10)) */
39602 +
39603 +t_Error FmPcdRegisterReassmPort(t_Handle h_FmPcd, t_Handle h_ReasmCommonPramTbl)
39604 +{
39605 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
39606 + t_FmPcdCcReassmTimeoutParams ccReassmTimeoutParams = { 0 };
39607 + t_Error err = E_OK;
39608 + uint8_t result;
39609 + uint32_t bitFor1Micro, tsbs, log2num;
39610 +
39611 + ASSERT_COND(p_FmPcd);
39612 + ASSERT_COND(h_ReasmCommonPramTbl);
39613 +
39614 + bitFor1Micro = FmGetTimeStampScale(p_FmPcd->h_Fm);
39615 + if (bitFor1Micro == 0)
39616 + RETURN_ERROR(MAJOR, E_NOT_AVAILABLE, ("Timestamp scale"));
39617 +
39618 + bitFor1Micro = 32 - bitFor1Micro;
39619 + LOG2(FM_PCD_MANIP_REASM_TIMEOUT_THREAD_THRESH, log2num);
39620 + tsbs = bitFor1Micro - log2num;
39621 +
39622 + ccReassmTimeoutParams.iprcpt = (uint32_t)(XX_VirtToPhys(
39623 + h_ReasmCommonPramTbl) - p_FmPcd->physicalMuramBase);
39624 + ccReassmTimeoutParams.tsbs = (uint8_t)tsbs;
39625 + ccReassmTimeoutParams.activate = TRUE;
39626 + if ((err = FmHcPcdCcTimeoutReassm(p_FmPcd->h_Hc, &ccReassmTimeoutParams,
39627 + &result)) != E_OK)
39628 + RETURN_ERROR(MAJOR, err, NO_MSG);
39629 +
39630 + switch (result)
39631 + {
39632 + case (0):
39633 + return E_OK;
39634 + case (1):
39635 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("failed to allocate TNUM"));
39636 + case (2):
39637 + RETURN_ERROR(
39638 + MAJOR, E_NO_MEMORY,
39639 + ("failed to allocate internal buffer from the HC-Port"));
39640 + case (3):
39641 + RETURN_ERROR(MAJOR, E_INVALID_VALUE,
39642 + ("'Disable Timeout Task' with invalid IPRCPT"));
39643 + case (4):
39644 + RETURN_ERROR(MAJOR, E_FULL, ("too many timeout tasks"));
39645 + case (5):
39646 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION, ("invalid sub command"));
39647 + default:
39648 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, NO_MSG);
39649 + }
39650 + return E_OK;
39651 +}
39652 +
39653 +static t_Error CreateReassCommonTable(t_FmPcdManip *p_Manip)
39654 +{
39655 + uint32_t tmpReg32 = 0, i, bitFor1Micro;
39656 + uint64_t tmpReg64, size;
39657 + t_FmPcd *p_FmPcd = (t_FmPcd *)p_Manip->h_FmPcd;
39658 + t_Error err = E_OK;
39659 +
39660 + bitFor1Micro = FmGetTimeStampScale(p_FmPcd->h_Fm);
39661 + if (bitFor1Micro == 0)
39662 + RETURN_ERROR(MAJOR, E_NOT_AVAILABLE, ("Timestamp scale"));
39663 +
39664 + /* Allocation of the Reassembly Common Parameters table. This table is located in the
39665 + MURAM. Its size is 64 bytes and its base address should be 8-byte aligned. */
39666 + p_Manip->reassmParams.p_ReassCommonTbl =
39667 + (t_ReassCommonTbl *)FM_MURAM_AllocMem(
39668 + p_FmPcd->h_FmMuram,
39669 + FM_PCD_MANIP_REASM_COMMON_PARAM_TABLE_SIZE,
39670 + FM_PCD_MANIP_REASM_COMMON_PARAM_TABLE_ALIGN);
39671 +
39672 + if (!p_Manip->reassmParams.p_ReassCommonTbl)
39673 + RETURN_ERROR(MAJOR, E_NO_MEMORY,
39674 + ("MURAM alloc for Reassembly common parameters table"));
39675 +
39676 + MemSet8(p_Manip->reassmParams.p_ReassCommonTbl, 0,
39677 + FM_PCD_MANIP_REASM_COMMON_PARAM_TABLE_SIZE);
39678 +
39679 + /* Setting the TimeOut Mode.*/
39680 + tmpReg32 = 0;
39681 + if (p_Manip->reassmParams.timeOutMode
39682 + == e_FM_PCD_MANIP_TIME_OUT_BETWEEN_FRAMES)
39683 + tmpReg32 |= FM_PCD_MANIP_REASM_TIME_OUT_BETWEEN_FRAMES;
39684 +
39685 + /* Setting TimeOut FQID - Frames that time out are enqueued to this FQID.
39686 + In order to cause TimeOut frames to be discarded, this queue should be configured accordingly*/
39687 + tmpReg32 |= p_Manip->reassmParams.fqidForTimeOutFrames;
39688 + WRITE_UINT32(p_Manip->reassmParams.p_ReassCommonTbl->timeoutModeAndFqid,
39689 + tmpReg32);
39690 +
39691 + /* Calculation the size of IP Reassembly Frame Descriptor - number of frames that are allowed to be reassembled simultaneously + 129.*/
39692 + size = p_Manip->reassmParams.maxNumFramesInProcess + 129;
39693 +
39694 + /*Allocation of IP Reassembly Frame Descriptor Indexes Pool - This pool resides in the MURAM */
39695 + p_Manip->reassmParams.reassFrmDescrIndxPoolTblAddr =
39696 + PTR_TO_UINT(FM_MURAM_AllocMem(p_FmPcd->h_FmMuram,
39697 + (uint32_t)(size * 2),
39698 + 256));
39699 + if (!p_Manip->reassmParams.reassFrmDescrIndxPoolTblAddr)
39700 + RETURN_ERROR(
39701 + MAJOR, E_NO_MEMORY,
39702 + ("MURAM alloc for Reassembly frame descriptor indexes pool"));
39703 +
39704 + MemSet8(UINT_TO_PTR(p_Manip->reassmParams.reassFrmDescrIndxPoolTblAddr),
39705 + 0, (uint32_t)(size * 2));
39706 +
39707 + /* The entries in IP Reassembly Frame Descriptor Indexes Pool contains indexes starting with 1 up to
39708 + the maximum number of frames that are allowed to be reassembled simultaneously + 128.
39709 + The last entry in this pool must contain the index zero*/
39710 + for (i = 0; i < (size - 1); i++)
39711 + WRITE_UINT16(
39712 + *(uint16_t *)PTR_MOVE(UINT_TO_PTR(p_Manip->reassmParams.reassFrmDescrIndxPoolTblAddr), (i<<1)),
39713 + (uint16_t)(i+1));
39714 +
39715 + /* Sets the IP Reassembly Frame Descriptor Indexes Pool offset from MURAM */
39716 + tmpReg32 = (uint32_t)(XX_VirtToPhys(
39717 + UINT_TO_PTR(p_Manip->reassmParams.reassFrmDescrIndxPoolTblAddr))
39718 + - p_FmPcd->physicalMuramBase);
39719 + WRITE_UINT32(
39720 + p_Manip->reassmParams.p_ReassCommonTbl->reassFrmDescIndexPoolTblPtr,
39721 + tmpReg32);
39722 +
39723 + /* Allocation of the Reassembly Frame Descriptors Pool - This pool resides in external memory.
39724 + The number of entries in this pool should be equal to the number of entries in IP Reassembly Frame Descriptor Indexes Pool.*/
39725 + p_Manip->reassmParams.reassFrmDescrPoolTblAddr =
39726 + PTR_TO_UINT(XX_MallocSmart((uint32_t)(size * 64), p_Manip->reassmParams.dataMemId, 64));
39727 +
39728 + if (!p_Manip->reassmParams.reassFrmDescrPoolTblAddr)
39729 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("Memory allocation FAILED"));
39730 +
39731 + MemSet8(UINT_TO_PTR(p_Manip->reassmParams.reassFrmDescrPoolTblAddr), 0,
39732 + (uint32_t)(size * 64));
39733 +
39734 + /* Sets the Reassembly Frame Descriptors Pool and liodn offset*/
39735 + tmpReg64 = (uint64_t)(XX_VirtToPhys(
39736 + UINT_TO_PTR(p_Manip->reassmParams.reassFrmDescrPoolTblAddr)));
39737 + tmpReg64 |= ((uint64_t)(p_Manip->reassmParams.dataLiodnOffset
39738 + & FM_PCD_MANIP_REASM_LIODN_MASK)
39739 + << (uint64_t)FM_PCD_MANIP_REASM_LIODN_SHIFT);
39740 + tmpReg64 |= ((uint64_t)(p_Manip->reassmParams.dataLiodnOffset
39741 + & FM_PCD_MANIP_REASM_ELIODN_MASK)
39742 + << (uint64_t)FM_PCD_MANIP_REASM_ELIODN_SHIFT);
39743 + WRITE_UINT32(
39744 + p_Manip->reassmParams.p_ReassCommonTbl->liodnAndReassFrmDescPoolPtrHi,
39745 + (uint32_t)(tmpReg64 >> 32));
39746 + WRITE_UINT32(
39747 + p_Manip->reassmParams.p_ReassCommonTbl->reassFrmDescPoolPtrLow,
39748 + (uint32_t)tmpReg64);
39749 +
39750 + /*Allocation of the TimeOut table - This table resides in the MURAM.
39751 + The number of entries in this table is identical to the number of entries in the Reassembly Frame Descriptors Pool*/
39752 + p_Manip->reassmParams.timeOutTblAddr =
39753 + PTR_TO_UINT(FM_MURAM_AllocMem(p_FmPcd->h_FmMuram, (uint32_t)(size * 8),8));
39754 +
39755 + if (!p_Manip->reassmParams.timeOutTblAddr)
39756 + RETURN_ERROR(MAJOR, E_NO_MEMORY,
39757 + ("MURAM alloc for Reassembly timeout table"));
39758 +
39759 + MemSet8(UINT_TO_PTR(p_Manip->reassmParams.timeOutTblAddr), 0,
39760 + (uint16_t)(size * 8));
39761 +
39762 + /* Sets the TimeOut table offset from MURAM */
39763 + tmpReg32 = (uint32_t)(XX_VirtToPhys(
39764 + UINT_TO_PTR(p_Manip->reassmParams.timeOutTblAddr))
39765 + - p_FmPcd->physicalMuramBase);
39766 + WRITE_UINT32(p_Manip->reassmParams.p_ReassCommonTbl->timeOutTblPtr,
39767 + tmpReg32);
39768 +
39769 + /* Sets the Expiration Delay */
39770 + tmpReg32 = 0;
39771 + tmpReg32 |= (((uint32_t)(1 << bitFor1Micro))
39772 + * p_Manip->reassmParams.timeoutThresholdForReassmProcess);
39773 + WRITE_UINT32(p_Manip->reassmParams.p_ReassCommonTbl->expirationDelay,
39774 + tmpReg32);
39775 +
39776 + err = FmPcdRegisterReassmPort(p_FmPcd,
39777 + p_Manip->reassmParams.p_ReassCommonTbl);
39778 + if (err != E_OK)
39779 + {
39780 + FM_MURAM_FreeMem(p_FmPcd->h_FmMuram,
39781 + p_Manip->reassmParams.p_ReassCommonTbl);
39782 + RETURN_ERROR(MAJOR, err, ("port registration"));
39783 + }
39784 +
39785 + return err;
39786 +}
39787 +
39788 +static t_Error CreateReassTable(t_FmPcdManip *p_Manip, e_NetHeaderType hdr)
39789 +{
39790 + t_FmPcd *p_FmPcd = p_Manip->h_FmPcd;
39791 + uint32_t tmpReg32, autoLearnHashTblSize;
39792 + uint32_t numOfWays, setSize, setSizeCode, keySize;
39793 + uint32_t waySize, numOfSets, numOfEntries;
39794 + uint64_t tmpReg64;
39795 + uint16_t minFragSize;
39796 + uint16_t maxReassemSize;
39797 + uintptr_t *p_AutoLearnHashTblAddr, *p_AutoLearnSetLockTblAddr;
39798 + t_ReassTbl **p_ReassTbl;
39799 +
39800 + switch (hdr)
39801 + {
39802 + case HEADER_TYPE_IPv4:
39803 + p_ReassTbl = &p_Manip->reassmParams.ip.p_Ipv4ReassTbl;
39804 + p_AutoLearnHashTblAddr =
39805 + &p_Manip->reassmParams.ip.ipv4AutoLearnHashTblAddr;
39806 + p_AutoLearnSetLockTblAddr =
39807 + &p_Manip->reassmParams.ip.ipv4AutoLearnSetLockTblAddr;
39808 + minFragSize = p_Manip->reassmParams.ip.minFragSize[0];
39809 + maxReassemSize = 0;
39810 + numOfWays = p_Manip->reassmParams.ip.numOfFramesPerHashEntry[0];
39811 + keySize = 4 + 4 + 1 + 2; /* 3-tuple + IP-Id */
39812 + break;
39813 + case HEADER_TYPE_IPv6:
39814 + p_ReassTbl = &p_Manip->reassmParams.ip.p_Ipv6ReassTbl;
39815 + p_AutoLearnHashTblAddr =
39816 + &p_Manip->reassmParams.ip.ipv6AutoLearnHashTblAddr;
39817 + p_AutoLearnSetLockTblAddr =
39818 + &p_Manip->reassmParams.ip.ipv6AutoLearnSetLockTblAddr;
39819 + minFragSize = p_Manip->reassmParams.ip.minFragSize[1];
39820 + maxReassemSize = 0;
39821 + numOfWays = p_Manip->reassmParams.ip.numOfFramesPerHashEntry[1];
39822 + keySize = 16 + 16 + 4; /* 2-tuple + IP-Id */
39823 + if (numOfWays > e_FM_PCD_MANIP_SIX_WAYS_HASH)
39824 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("num of ways"));
39825 + break;
39826 + case HEADER_TYPE_CAPWAP:
39827 + p_ReassTbl = &p_Manip->reassmParams.capwap.p_ReassTbl;
39828 + p_AutoLearnHashTblAddr =
39829 + &p_Manip->reassmParams.capwap.autoLearnHashTblAddr;
39830 + p_AutoLearnSetLockTblAddr =
39831 + &p_Manip->reassmParams.capwap.autoLearnSetLockTblAddr;
39832 + minFragSize = 0;
39833 + maxReassemSize = p_Manip->reassmParams.capwap.maxRessembledsSize;
39834 + numOfWays = p_Manip->reassmParams.capwap.numOfFramesPerHashEntry;
39835 + keySize = 4;
39836 + break;
39837 + default:
39838 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("header type"));
39839 + }
39840 + keySize += 2; /* 2 bytes reserved for RFDIndex */
39841 +#if (DPAA_VERSION >= 11)
39842 + keySize += 2; /* 2 bytes reserved */
39843 +#endif /* (DPAA_VERSION >= 11) */
39844 + waySize = ROUND_UP(keySize, 8);
39845 +
39846 + /* Allocates the Reassembly Parameters Table - This table is located in the MURAM.*/
39847 + *p_ReassTbl = (t_ReassTbl *)FM_MURAM_AllocMem(
39848 + p_FmPcd->h_FmMuram, FM_PCD_MANIP_REASM_TABLE_SIZE,
39849 + FM_PCD_MANIP_REASM_TABLE_ALIGN);
39850 + if (!*p_ReassTbl)
39851 + RETURN_ERROR( MAJOR, E_NO_MEMORY,
39852 + ("MURAM alloc for Reassembly specific parameters table"));
39853 + memset(*p_ReassTbl, 0, sizeof(t_ReassTbl));
39854 +
39855 + /* Sets the Reassembly common Parameters table offset from MURAM in the Reassembly Table descriptor*/
39856 + tmpReg32 = (uint32_t)(XX_VirtToPhys(p_Manip->reassmParams.p_ReassCommonTbl)
39857 + - p_FmPcd->physicalMuramBase);
39858 + WRITE_UINT32((*p_ReassTbl)->reassCommonPrmTblPtr, tmpReg32);
39859 +
39860 + /* Calculate set size (set size is rounded-up to next power of 2) */
39861 + NEXT_POWER_OF_2(numOfWays * waySize, setSize);
39862 +
39863 + /* Get set size code */
39864 + LOG2(setSize, setSizeCode);
39865 +
39866 + /* Sets ways number and set size code */
39867 + WRITE_UINT16((*p_ReassTbl)->waysNumAndSetSize,
39868 + (uint16_t)((numOfWays << 8) | setSizeCode));
39869 +
39870 + /* It is recommended that the total number of entries in this table
39871 + (number of sets * number of ways) will be twice the number of frames that
39872 + are expected to be reassembled simultaneously.*/
39873 + numOfEntries = (uint32_t)(p_Manip->reassmParams.maxNumFramesInProcess * 2);
39874 +
39875 + /* sets number calculation - number of entries = number of sets * number of ways */
39876 + numOfSets = numOfEntries / numOfWays;
39877 +
39878 + /* Sets AutoLearnHashKeyMask*/
39879 + NEXT_POWER_OF_2(numOfSets, numOfSets);
39880 +
39881 + WRITE_UINT16((*p_ReassTbl)->autoLearnHashKeyMask,
39882 + (uint16_t)(numOfSets - 1));
39883 +
39884 + /* Allocation of Reassembly Automatic Learning Hash Table - This table resides in external memory.
39885 + The size of this table is determined by the number of sets and the set size.
39886 + Table size = set size * number of sets
39887 + This table base address should be aligned to SetSize.*/
39888 + autoLearnHashTblSize = numOfSets * setSize;
39889 +
39890 + *p_AutoLearnHashTblAddr =
39891 + PTR_TO_UINT(XX_MallocSmart(autoLearnHashTblSize, p_Manip->reassmParams.dataMemId, setSize));
39892 + if (!*p_AutoLearnHashTblAddr)
39893 + {
39894 + FM_MURAM_FreeMem(p_FmPcd->h_FmMuram, *p_ReassTbl);
39895 + *p_ReassTbl = NULL;
39896 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("Memory allocation FAILED"));
39897 + }
39898 + MemSet8(UINT_TO_PTR(*p_AutoLearnHashTblAddr), 0, autoLearnHashTblSize);
39899 +
39900 + /* Sets the Reassembly Automatic Learning Hash Table and liodn offset */
39901 + tmpReg64 = ((uint64_t)(p_Manip->reassmParams.dataLiodnOffset
39902 + & FM_PCD_MANIP_REASM_LIODN_MASK)
39903 + << (uint64_t)FM_PCD_MANIP_REASM_LIODN_SHIFT);
39904 + tmpReg64 |= ((uint64_t)(p_Manip->reassmParams.dataLiodnOffset
39905 + & FM_PCD_MANIP_REASM_ELIODN_MASK)
39906 + << (uint64_t)FM_PCD_MANIP_REASM_ELIODN_SHIFT);
39907 + tmpReg64 |= XX_VirtToPhys(UINT_TO_PTR(*p_AutoLearnHashTblAddr));
39908 + WRITE_UINT32( (*p_ReassTbl)->liodnAlAndAutoLearnHashTblPtrHi,
39909 + (uint32_t)(tmpReg64 >> 32));
39910 + WRITE_UINT32((*p_ReassTbl)->autoLearnHashTblPtrLow, (uint32_t)tmpReg64);
39911 +
39912 + /* Allocation of the Set Lock table - This table resides in external memory
39913 + The size of this table is (number of sets in the Reassembly Automatic Learning Hash table)*4 bytes.
39914 + This table resides in external memory and its base address should be 4-byte aligned */
39915 + *p_AutoLearnSetLockTblAddr =
39916 + PTR_TO_UINT(XX_MallocSmart((uint32_t)(numOfSets * 4), p_Manip->reassmParams.dataMemId, 4));
39917 + if (!*p_AutoLearnSetLockTblAddr)
39918 + {
39919 + FM_MURAM_FreeMem(p_FmPcd->h_FmMuram, *p_ReassTbl);
39920 + *p_ReassTbl = NULL;
39921 + XX_FreeSmart(UINT_TO_PTR(*p_AutoLearnHashTblAddr));
39922 + *p_AutoLearnHashTblAddr = 0;
39923 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("Memory allocation FAILED"));
39924 + }
39925 + MemSet8(UINT_TO_PTR(*p_AutoLearnSetLockTblAddr), 0, (numOfSets * 4));
39926 +
39927 + /* sets Set Lock table pointer and liodn offset*/
39928 + tmpReg64 = ((uint64_t)(p_Manip->reassmParams.dataLiodnOffset
39929 + & FM_PCD_MANIP_REASM_LIODN_MASK)
39930 + << (uint64_t)FM_PCD_MANIP_REASM_LIODN_SHIFT);
39931 + tmpReg64 |= ((uint64_t)(p_Manip->reassmParams.dataLiodnOffset
39932 + & FM_PCD_MANIP_REASM_ELIODN_MASK)
39933 + << (uint64_t)FM_PCD_MANIP_REASM_ELIODN_SHIFT);
39934 + tmpReg64 |= XX_VirtToPhys(UINT_TO_PTR(*p_AutoLearnSetLockTblAddr));
39935 + WRITE_UINT32( (*p_ReassTbl)->liodnSlAndAutoLearnSetLockTblPtrHi,
39936 + (uint32_t)(tmpReg64 >> 32));
39937 + WRITE_UINT32((*p_ReassTbl)->autoLearnSetLockTblPtrLow, (uint32_t)tmpReg64);
39938 +
39939 + /* Sets user's requested minimum fragment size (in Bytes) for First/Middle fragment */
39940 + WRITE_UINT16((*p_ReassTbl)->minFragSize, minFragSize);
39941 +
39942 + WRITE_UINT16((*p_ReassTbl)->maxReassemblySize, maxReassemSize);
39943 +
39944 + return E_OK;
39945 +}
39946 +
39947 +static t_Error UpdateInitReasm(t_Handle h_FmPcd, t_Handle h_PcdParams,
39948 + t_Handle h_FmPort, t_FmPcdManip *p_Manip,
39949 + t_Handle h_Ad, bool validate)
39950 +{
39951 + t_FmPortGetSetCcParams fmPortGetSetCcParams;
39952 + uint32_t tmpReg32;
39953 + t_Error err;
39954 + t_FmPortPcdParams *p_PcdParams = (t_FmPortPcdParams *)h_PcdParams;
39955 +#if (DPAA_VERSION >= 11)
39956 + t_FmPcdCtrlParamsPage *p_ParamsPage;
39957 +#endif /* (DPAA_VERSION >= 11) */
39958 +
39959 + SANITY_CHECK_RETURN_ERROR(p_Manip, E_INVALID_HANDLE);
39960 + SANITY_CHECK_RETURN_ERROR(!p_Manip->frag, E_INVALID_HANDLE);
39961 + SANITY_CHECK_RETURN_ERROR(
39962 + (p_Manip->opcode == HMAN_OC_IP_REASSEMBLY) || (p_Manip->opcode == HMAN_OC_CAPWAP_REASSEMBLY),
39963 + E_INVALID_STATE);
39964 + SANITY_CHECK_RETURN_ERROR(h_FmPcd, E_INVALID_HANDLE);
39965 + SANITY_CHECK_RETURN_ERROR(!p_Manip->updateParams || h_PcdParams,
39966 + E_INVALID_HANDLE);
39967 +
39968 + UNUSED(h_Ad);
39969 +
39970 + if (!p_Manip->updateParams)
39971 + return E_OK;
39972 +
39973 + if (p_Manip->h_FmPcd != h_FmPcd)
39974 + RETURN_ERROR(
39975 + MAJOR, E_INVALID_STATE,
39976 + ("handler of PCD previously was initiated by different value"));
39977 +
39978 + if (p_Manip->updateParams)
39979 + {
39980 + if ((!(p_Manip->updateParams
39981 + & (NUM_OF_TASKS | NUM_OF_EXTRA_TASKS | DISCARD_MASK)))
39982 + || ((p_Manip->shadowUpdateParams
39983 + & (NUM_OF_TASKS | NUM_OF_EXTRA_TASKS | DISCARD_MASK))))
39984 + RETURN_ERROR(
39985 + MAJOR, E_INVALID_STATE,
39986 + ("in this stage parameters from Port has not be updated"));
39987 +
39988 + fmPortGetSetCcParams.setCcParams.type = 0;
39989 + if (p_Manip->opcode == HMAN_OC_CAPWAP_REASSEMBLY)
39990 + {
39991 + fmPortGetSetCcParams.setCcParams.type |= UPDATE_OFP_DPTE;
39992 + fmPortGetSetCcParams.setCcParams.ofpDpde = 0xF;
39993 + }
39994 + fmPortGetSetCcParams.getCcParams.type = p_Manip->updateParams | FM_REV;
39995 + if ((err = FmPortGetSetCcParams(h_FmPort, &fmPortGetSetCcParams))
39996 + != E_OK)
39997 + RETURN_ERROR(MAJOR, err, NO_MSG);
39998 + if (fmPortGetSetCcParams.getCcParams.type
39999 + & (NUM_OF_TASKS | NUM_OF_EXTRA_TASKS | DISCARD_MASK | FM_REV))
40000 + RETURN_ERROR(MAJOR, E_INVALID_STATE,
40001 + ("offset of the data wasn't configured previously"));
40002 + if (p_Manip->updateParams
40003 + & (NUM_OF_TASKS | NUM_OF_EXTRA_TASKS | DISCARD_MASK))
40004 + {
40005 + t_FmPcd *p_FmPcd = (t_FmPcd *)h_FmPcd;
40006 + uint8_t *p_Ptr, i, totalNumOfTnums;
40007 +
40008 + totalNumOfTnums =
40009 + (uint8_t)(fmPortGetSetCcParams.getCcParams.numOfTasks
40010 + + fmPortGetSetCcParams.getCcParams.numOfExtraTasks);
40011 +
40012 + p_Manip->reassmParams.internalBufferPoolAddr =
40013 + PTR_TO_UINT(FM_MURAM_AllocMem(p_FmPcd->h_FmMuram,
40014 + (uint32_t)(totalNumOfTnums * BMI_FIFO_UNITS),
40015 + BMI_FIFO_UNITS));
40016 + if (!p_Manip->reassmParams.internalBufferPoolAddr)
40017 + RETURN_ERROR(
40018 + MAJOR, E_NO_MEMORY,
40019 + ("MURAM alloc for Reassembly internal buffers pool"));
40020 + MemSet8(
40021 + UINT_TO_PTR(p_Manip->reassmParams.internalBufferPoolAddr),
40022 + 0, (uint32_t)(totalNumOfTnums * BMI_FIFO_UNITS));
40023 +
40024 + p_Manip->reassmParams.internalBufferPoolManagementIndexAddr =
40025 + PTR_TO_UINT(FM_MURAM_AllocMem(p_FmPcd->h_FmMuram,
40026 + (uint32_t)(5 + totalNumOfTnums),
40027 + 4));
40028 + if (!p_Manip->reassmParams.internalBufferPoolManagementIndexAddr)
40029 + RETURN_ERROR(
40030 + MAJOR,
40031 + E_NO_MEMORY,
40032 + ("MURAM alloc for Reassembly internal buffers management"));
40033 +
40034 + p_Ptr =
40035 + (uint8_t*)UINT_TO_PTR(p_Manip->reassmParams.internalBufferPoolManagementIndexAddr);
40036 + WRITE_UINT32(
40037 + *(uint32_t*)p_Ptr,
40038 + (uint32_t)(XX_VirtToPhys(UINT_TO_PTR(p_Manip->reassmParams.internalBufferPoolAddr)) - p_FmPcd->physicalMuramBase));
40039 + for (i = 0, p_Ptr += 4; i < totalNumOfTnums; i++, p_Ptr++)
40040 + WRITE_UINT8(*p_Ptr, i);
40041 + WRITE_UINT8(*p_Ptr, 0xFF);
40042 +
40043 + tmpReg32 =
40044 + (4 << FM_PCD_MANIP_REASM_COMMON_INT_BUFFER_IDX_SHIFT)
40045 + | ((uint32_t)(XX_VirtToPhys(
40046 + UINT_TO_PTR(p_Manip->reassmParams.internalBufferPoolManagementIndexAddr))
40047 + - p_FmPcd->physicalMuramBase));
40048 + WRITE_UINT32(
40049 + p_Manip->reassmParams.p_ReassCommonTbl->internalBufferManagement,
40050 + tmpReg32);
40051 +
40052 + p_Manip->updateParams &= ~(NUM_OF_TASKS | NUM_OF_EXTRA_TASKS
40053 + | DISCARD_MASK);
40054 + p_Manip->shadowUpdateParams |= (NUM_OF_TASKS | NUM_OF_EXTRA_TASKS
40055 + | DISCARD_MASK);
40056 + }
40057 + }
40058 +
40059 + if (p_Manip->opcode == HMAN_OC_CAPWAP_REASSEMBLY)
40060 + {
40061 + if (p_Manip->reassmParams.capwap.h_Scheme)
40062 + {
40063 + p_PcdParams->p_KgParams->h_Schemes[p_PcdParams->p_KgParams->numOfSchemes] =
40064 + p_Manip->reassmParams.capwap.h_Scheme;
40065 + p_PcdParams->p_KgParams->numOfSchemes++;
40066 + }
40067 +
40068 + }
40069 + else
40070 + {
40071 + if (p_Manip->reassmParams.ip.h_Ipv4Scheme)
40072 + {
40073 + p_PcdParams->p_KgParams->h_Schemes[p_PcdParams->p_KgParams->numOfSchemes] =
40074 + p_Manip->reassmParams.ip.h_Ipv4Scheme;
40075 + p_PcdParams->p_KgParams->numOfSchemes++;
40076 + }
40077 + if (p_Manip->reassmParams.ip.h_Ipv6Scheme)
40078 + {
40079 + p_PcdParams->p_KgParams->h_Schemes[p_PcdParams->p_KgParams->numOfSchemes] =
40080 + p_Manip->reassmParams.ip.h_Ipv6Scheme;
40081 + p_PcdParams->p_KgParams->numOfSchemes++;
40082 + }
40083 +#if (DPAA_VERSION >= 11)
40084 + if (fmPortGetSetCcParams.getCcParams.revInfo.majorRev >= 6)
40085 + {
40086 + if ((err = FmPortSetGprFunc(h_FmPort, e_FM_PORT_GPR_MURAM_PAGE,
40087 + (void**)&p_ParamsPage)) != E_OK)
40088 + RETURN_ERROR(MAJOR, err, NO_MSG);
40089 +
40090 + tmpReg32 = NIA_ENG_KG;
40091 + if (p_Manip->reassmParams.ip.h_Ipv4Scheme)
40092 + {
40093 + tmpReg32 |= NIA_KG_DIRECT;
40094 + tmpReg32 |= NIA_KG_CC_EN;
40095 + tmpReg32 |= FmPcdKgGetSchemeId(
40096 + p_Manip->reassmParams.ip.h_Ipv4Scheme);
40097 + WRITE_UINT32(p_ParamsPage->iprIpv4Nia, tmpReg32);
40098 + }
40099 + if (p_Manip->reassmParams.ip.h_Ipv6Scheme)
40100 + {
40101 + tmpReg32 &= ~NIA_AC_MASK;
40102 + tmpReg32 |= NIA_KG_DIRECT;
40103 + tmpReg32 |= NIA_KG_CC_EN;
40104 + tmpReg32 |= FmPcdKgGetSchemeId(
40105 + p_Manip->reassmParams.ip.h_Ipv6Scheme);
40106 + WRITE_UINT32(p_ParamsPage->iprIpv6Nia, tmpReg32);
40107 + }
40108 + }
40109 +#else
40110 + if (fmPortGetSetCcParams.getCcParams.revInfo.majorRev < 6)
40111 + {
40112 + WRITE_UINT32(p_Manip->reassmParams.p_ReassCommonTbl->discardMask,
40113 + fmPortGetSetCcParams.getCcParams.discardMask);
40114 + }
40115 +#endif /* (DPAA_VERSION >= 11) */
40116 + }
40117 + return E_OK;
40118 +}
40119 +
40120 +#if (DPAA_VERSION == 10)
40121 +static t_Error FmPcdFragHcScratchPoolFill(t_Handle h_FmPcd, uint8_t scratchBpid)
40122 +{
40123 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
40124 + t_FmPcdCcFragScratchPoolCmdParams fmPcdCcFragScratchPoolCmdParams;
40125 + t_Error err;
40126 +
40127 + SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);
40128 +
40129 + memset(&fmPcdCcFragScratchPoolCmdParams, 0, sizeof(t_FmPcdCcFragScratchPoolCmdParams));
40130 +
40131 + fmPcdCcFragScratchPoolCmdParams.numOfBuffers = NUM_OF_SCRATCH_POOL_BUFFERS;
40132 + fmPcdCcFragScratchPoolCmdParams.bufferPoolId = scratchBpid;
40133 + if ((err = FmHcPcdCcIpFragScratchPollCmd(p_FmPcd->h_Hc, TRUE, &fmPcdCcFragScratchPoolCmdParams)) != E_OK)
40134 + RETURN_ERROR(MAJOR, err, NO_MSG);
40135 +
40136 + if (fmPcdCcFragScratchPoolCmdParams.numOfBuffers != 0)
40137 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Fill scratch pool failed,"
40138 + "Failed to release %d buffers to the BM (missing FBPRs)",
40139 + fmPcdCcFragScratchPoolCmdParams.numOfBuffers));
40140 +
40141 + return E_OK;
40142 +}
40143 +
40144 +static t_Error FmPcdFragHcScratchPoolEmpty(t_Handle h_FmPcd, uint8_t scratchBpid)
40145 +{
40146 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
40147 + t_FmPcdCcFragScratchPoolCmdParams fmPcdCcFragScratchPoolCmdParams;
40148 + t_Error err;
40149 +
40150 + SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);
40151 +
40152 + memset(&fmPcdCcFragScratchPoolCmdParams, 0, sizeof(t_FmPcdCcFragScratchPoolCmdParams));
40153 +
40154 + fmPcdCcFragScratchPoolCmdParams.bufferPoolId = scratchBpid;
40155 + if ((err = FmHcPcdCcIpFragScratchPollCmd(p_FmPcd->h_Hc, FALSE, &fmPcdCcFragScratchPoolCmdParams)) != E_OK)
40156 + RETURN_ERROR(MAJOR, err, NO_MSG);
40157 +
40158 + return E_OK;
40159 +}
40160 +#endif /* (DPAA_VERSION == 10) */
40161 +
40162 +static void ReleaseManipHandler(t_FmPcdManip *p_Manip, t_FmPcd *p_FmPcd)
40163 +{
40164 + if (p_Manip->h_Ad)
40165 + {
40166 + if (p_Manip->muramAllocate)
40167 + FM_MURAM_FreeMem(p_FmPcd->h_FmMuram, p_Manip->h_Ad);
40168 + else
40169 + XX_Free(p_Manip->h_Ad);
40170 + p_Manip->h_Ad = NULL;
40171 + }
40172 + if (p_Manip->p_Template)
40173 + {
40174 + FM_MURAM_FreeMem(p_FmPcd->h_FmMuram, p_Manip->p_Template);
40175 + p_Manip->p_Template = NULL;
40176 + }
40177 +#if (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10))
40178 + if (p_Manip->h_Frag)
40179 + {
40180 + if (p_Manip->capwapFragParams.p_AutoLearnHashTbl)
40181 + FM_MURAM_FreeMem(p_FmPcd->h_FmMuram,
40182 + p_Manip->capwapFragParams.p_AutoLearnHashTbl);
40183 + if (p_Manip->capwapFragParams.p_ReassmFrmDescrPoolTbl)
40184 + FM_MURAM_FreeMem(p_FmPcd->h_FmMuram,
40185 + p_Manip->capwapFragParams.p_ReassmFrmDescrPoolTbl);
40186 + if (p_Manip->capwapFragParams.p_ReassmFrmDescrIndxPoolTbl)
40187 + FM_MURAM_FreeMem(p_FmPcd->h_FmMuram,
40188 + p_Manip->capwapFragParams.p_ReassmFrmDescrIndxPoolTbl);
40189 + if (p_Manip->capwapFragParams.p_TimeOutTbl)
40190 + FM_MURAM_FreeMem(p_FmPcd->h_FmMuram,
40191 + p_Manip->capwapFragParams.p_TimeOutTbl);
40192 + FM_MURAM_FreeMem(p_FmPcd->h_FmMuram, p_Manip->h_Frag);
40193 +
40194 + }
40195 +#endif /* (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10)) */
40196 + if (p_Manip->frag)
40197 + {
40198 + if (p_Manip->fragParams.p_Frag)
40199 + {
40200 +#if (DPAA_VERSION == 10)
40201 + FmPcdFragHcScratchPoolEmpty((t_Handle)p_FmPcd, p_Manip->fragParams.scratchBpid);
40202 +#endif /* (DPAA_VERSION == 10) */
40203 +
40204 + FM_MURAM_FreeMem(p_FmPcd->h_FmMuram, p_Manip->fragParams.p_Frag);
40205 + }
40206 + }
40207 + else
40208 + if (p_Manip->reassm)
40209 + {
40210 + FmPcdUnregisterReassmPort(p_FmPcd,
40211 + p_Manip->reassmParams.p_ReassCommonTbl);
40212 +
40213 + if (p_Manip->reassmParams.timeOutTblAddr)
40214 + FM_MURAM_FreeMem(
40215 + p_FmPcd->h_FmMuram,
40216 + UINT_TO_PTR(p_Manip->reassmParams.timeOutTblAddr));
40217 + if (p_Manip->reassmParams.reassFrmDescrPoolTblAddr)
40218 + XX_FreeSmart(
40219 + UINT_TO_PTR(p_Manip->reassmParams.reassFrmDescrPoolTblAddr));
40220 + if (p_Manip->reassmParams.p_ReassCommonTbl)
40221 + FM_MURAM_FreeMem(p_FmPcd->h_FmMuram,
40222 + p_Manip->reassmParams.p_ReassCommonTbl);
40223 + if (p_Manip->reassmParams.reassFrmDescrIndxPoolTblAddr)
40224 + FM_MURAM_FreeMem(
40225 + p_FmPcd->h_FmMuram,
40226 + UINT_TO_PTR(p_Manip->reassmParams.reassFrmDescrIndxPoolTblAddr));
40227 + if (p_Manip->reassmParams.internalBufferPoolManagementIndexAddr)
40228 + FM_MURAM_FreeMem(
40229 + p_FmPcd->h_FmMuram,
40230 + UINT_TO_PTR(p_Manip->reassmParams.internalBufferPoolManagementIndexAddr));
40231 + if (p_Manip->reassmParams.internalBufferPoolAddr)
40232 + FM_MURAM_FreeMem(
40233 + p_FmPcd->h_FmMuram,
40234 + UINT_TO_PTR(p_Manip->reassmParams.internalBufferPoolAddr));
40235 + if (p_Manip->reassmParams.hdr == HEADER_TYPE_CAPWAP)
40236 + {
40237 +
40238 + }
40239 + else
40240 + {
40241 + if (p_Manip->reassmParams.ip.ipv4AutoLearnHashTblAddr)
40242 + XX_FreeSmart(
40243 + UINT_TO_PTR(p_Manip->reassmParams.ip.ipv4AutoLearnHashTblAddr));
40244 + if (p_Manip->reassmParams.ip.ipv6AutoLearnHashTblAddr)
40245 + XX_FreeSmart(
40246 + UINT_TO_PTR(p_Manip->reassmParams.ip.ipv6AutoLearnHashTblAddr));
40247 + if (p_Manip->reassmParams.ip.ipv4AutoLearnSetLockTblAddr)
40248 + XX_FreeSmart(
40249 + UINT_TO_PTR(p_Manip->reassmParams.ip.ipv4AutoLearnSetLockTblAddr));
40250 + if (p_Manip->reassmParams.ip.ipv6AutoLearnSetLockTblAddr)
40251 + XX_FreeSmart(
40252 + UINT_TO_PTR(p_Manip->reassmParams.ip.ipv6AutoLearnSetLockTblAddr));
40253 + if (p_Manip->reassmParams.ip.p_Ipv4ReassTbl)
40254 + FM_MURAM_FreeMem(p_FmPcd->h_FmMuram,
40255 + p_Manip->reassmParams.ip.p_Ipv4ReassTbl);
40256 + if (p_Manip->reassmParams.ip.p_Ipv6ReassTbl)
40257 + FM_MURAM_FreeMem(p_FmPcd->h_FmMuram,
40258 + p_Manip->reassmParams.ip.p_Ipv6ReassTbl);
40259 + if (p_Manip->reassmParams.ip.h_Ipv6Ad)
40260 + XX_FreeSmart(p_Manip->reassmParams.ip.h_Ipv6Ad);
40261 + if (p_Manip->reassmParams.ip.h_Ipv4Ad)
40262 + XX_FreeSmart(p_Manip->reassmParams.ip.h_Ipv4Ad);
40263 + }
40264 + }
40265 +
40266 + if (p_Manip->p_StatsTbl)
40267 + FM_MURAM_FreeMem(p_FmPcd->h_FmMuram, p_Manip->p_StatsTbl);
40268 +}
40269 +
40270 +#if (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10))
40271 +static t_Error CheckManipParamsAndSetType(t_FmPcdManip *p_Manip, t_FmPcdManipParams *p_ManipParams)
40272 +{
40273 + if (p_ManipParams->u.hdr.rmv)
40274 + {
40275 + switch (p_ManipParams->u.hdr.rmvParams.type)
40276 + {
40277 + case (e_FM_PCD_MANIP_RMV_BY_HDR):
40278 + switch (p_ManipParams->u.hdr.rmvParams.u.byHdr.type)
40279 + {
40280 + case (e_FM_PCD_MANIP_RMV_BY_HDR_FROM_START) :
40281 + if (p_ManipParams->u.hdr.rmvParams.u.byHdr.u.fromStartByHdr.include)
40282 + {
40283 + switch (p_ManipParams->u.hdr.rmvParams.u.byHdr.u.fromStartByHdr.hdrInfo.hdr)
40284 + {
40285 + case (HEADER_TYPE_CAPWAP_DTLS) :
40286 + p_Manip->opcode = HMAN_OC_CAPWAP_RMV_DTLS_IF_EXIST;
40287 + p_Manip->muramAllocate = TRUE;
40288 + if (p_ManipParams->u.hdr.insrt)
40289 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("for CAPWAP_DTLS_HDR remove can not be insrt manipualtion after"));
40290 + if (p_ManipParams->fragOrReasm)
40291 + {
40292 + if (!p_ManipParams->fragOrReasmParams.frag)
40293 + {
40294 + switch (p_ManipParams->fragOrReasmParams.hdr)
40295 + {
40296 + case (HEADER_TYPE_CAPWAP):
40297 + p_Manip->opcode = HMAN_OC_CAPWAP_REASSEMBLY;
40298 + break;
40299 + default:
40300 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("unsupported header for Reassembly"));
40301 + }
40302 + }
40303 + else
40304 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("for this type of manipulation frag can not be TRUE"));
40305 + }
40306 + break;
40307 + default:
40308 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("non valid net header of remove location"));
40309 + }
40310 + }
40311 + else
40312 + {
40313 + switch (p_ManipParams->u.hdr.rmvParams.u.byHdr.u.fromStartByHdr.hdrInfo.hdr)
40314 + {
40315 + case (HEADER_TYPE_CAPWAP_DTLS) :
40316 + case (HEADER_TYPE_CAPWAP) :
40317 + if (p_ManipParams->fragOrReasm || p_ManipParams->u.hdr.insrt)
40318 + 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"));
40319 + p_Manip->opcode = HMAN_OC_RMV_N_OR_INSRT_INT_FRM_HDR;
40320 + p_Manip->muramAllocate = TRUE;
40321 + p_ManipParams->u.hdr.insrt = TRUE; //internal frame header
40322 + break;
40323 + default :
40324 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("invalid type of remove manipulation"));
40325 + }
40326 + }
40327 + break;
40328 + default :
40329 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("invalid type of remove manipulation"));
40330 + }
40331 + break;
40332 + default:
40333 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("invalid type of remove manipulation"));
40334 + }
40335 + }
40336 + else if (p_ManipParams->u.hdr.insrt)
40337 + {
40338 + switch (p_ManipParams->u.hdr.insrtParams.type)
40339 + {
40340 + case (e_FM_PCD_MANIP_INSRT_BY_TEMPLATE) :
40341 +
40342 + p_Manip->opcode = HMAN_OC_INSRT_HDR_BY_TEMPL_N_OR_FRAG_AFTER;
40343 + p_Manip->muramAllocate = FALSE;
40344 + if (p_ManipParams->fragOrReasm)
40345 + {
40346 + if (p_ManipParams->fragOrReasmParams.frag)
40347 + {
40348 + switch (p_ManipParams->fragOrReasmParams.hdr)
40349 + {
40350 + case (HEADER_TYPE_CAPWAP):
40351 + p_Manip->opcode = HMAN_OC_CAPWAP_FRAGMENTATION;
40352 + break;
40353 + default:
40354 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Invalid header for fragmentation"));
40355 + }
40356 + }
40357 + else
40358 + RETURN_ERROR(MAJOR, E_INVALID_STATE,("can not reach this point"));
40359 + }
40360 + break;
40361 +
40362 + default:
40363 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("for only isert manipulation unsupported type"));
40364 + }
40365 + }
40366 + else if (p_ManipParams->fragOrReasm)
40367 + {
40368 + if (p_ManipParams->fragOrReasmParams.frag)
40369 + {
40370 + switch (p_ManipParams->fragOrReasmParams.hdr)
40371 + {
40372 + case (HEADER_TYPE_CAPWAP):
40373 + p_Manip->opcode = HMAN_OC_CAPWAP_FRAGMENTATION;
40374 + p_Manip->muramAllocate = FALSE;
40375 + break;
40376 + default:
40377 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Unsupported header for fragmentation"));
40378 + }
40379 + }
40380 + else
40381 + {
40382 + switch (p_ManipParams->fragOrReasmParams.hdr)
40383 + {
40384 + case (HEADER_TYPE_CAPWAP):
40385 + 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"));
40386 + default:
40387 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Unsupported header for reassembly"));
40388 + }
40389 + }
40390 +
40391 + }
40392 + else
40393 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("User didn't ask for any manipulation"));
40394 +
40395 + p_Manip->insrt = p_ManipParams->u.hdr.insrt;
40396 + p_Manip->rmv = p_ManipParams->u.hdr.rmv;
40397 +
40398 + return E_OK;
40399 +}
40400 +
40401 +#else /* not (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10)) */
40402 +static t_Error CheckManipParamsAndSetType(t_FmPcdManip *p_Manip,
40403 + t_FmPcdManipParams *p_ManipParams)
40404 +{
40405 + switch (p_ManipParams->type)
40406 + {
40407 + case e_FM_PCD_MANIP_HDR:
40408 + /* Check that next-manip is not already used */
40409 + if (p_ManipParams->h_NextManip)
40410 + {
40411 + if (!MANIP_IS_FIRST(p_ManipParams->h_NextManip))
40412 + RETURN_ERROR(
40413 + MAJOR, E_INVALID_STATE,
40414 + ("h_NextManip is already a part of another chain"));
40415 + if ((MANIP_GET_TYPE(p_ManipParams->h_NextManip)
40416 + != e_FM_PCD_MANIP_HDR) &&
40417 + (MANIP_GET_TYPE(p_ManipParams->h_NextManip)
40418 + != e_FM_PCD_MANIP_FRAG))
40419 + RETURN_ERROR(
40420 + MAJOR,
40421 + E_NOT_SUPPORTED,
40422 + ("For a Header Manipulation node - no support of h_NextManip of type other than Header Manipulation or Fragmentation."));
40423 + }
40424 +
40425 + if (p_ManipParams->u.hdr.rmv)
40426 + {
40427 + switch (p_ManipParams->u.hdr.rmvParams.type)
40428 + {
40429 + case (e_FM_PCD_MANIP_RMV_BY_HDR):
40430 + switch (p_ManipParams->u.hdr.rmvParams.u.byHdr.type)
40431 + {
40432 + case (e_FM_PCD_MANIP_RMV_BY_HDR_SPECIFIC_L2):
40433 + break;
40434 +#if (DPAA_VERSION >= 11)
40435 + case (e_FM_PCD_MANIP_RMV_BY_HDR_CAPWAP):
40436 + break;
40437 + case (e_FM_PCD_MANIP_RMV_BY_HDR_FROM_START):
40438 + {
40439 + t_Error err;
40440 + uint8_t prsArrayOffset;
40441 +
40442 + err =
40443 + GetPrOffsetByHeaderOrField(
40444 + &p_ManipParams->u.hdr.rmvParams.u.byHdr.u.hdrInfo,
40445 + &prsArrayOffset);
40446 + if (err)
40447 + RETURN_ERROR(MAJOR, err, NO_MSG);
40448 + break;
40449 + }
40450 +#endif /* (DPAA_VERSION >= 11) */
40451 + default:
40452 + RETURN_ERROR(
40453 + MAJOR,
40454 + E_INVALID_STATE,
40455 + ("invalid type of remove manipulation"));
40456 + }
40457 + break;
40458 + case (e_FM_PCD_MANIP_RMV_GENERIC):
40459 + break;
40460 + default:
40461 + RETURN_ERROR(MAJOR, E_INVALID_STATE,
40462 + ("invalid type of remove manipulation"));
40463 + }
40464 + p_Manip->opcode = HMAN_OC;
40465 + p_Manip->muramAllocate = TRUE;
40466 + p_Manip->rmv = TRUE;
40467 + }
40468 + else
40469 + if (p_ManipParams->u.hdr.insrt)
40470 + {
40471 + switch (p_ManipParams->u.hdr.insrtParams.type)
40472 + {
40473 + case (e_FM_PCD_MANIP_INSRT_BY_HDR):
40474 + {
40475 + switch (p_ManipParams->u.hdr.insrtParams.u.byHdr.type)
40476 + {
40477 + case (e_FM_PCD_MANIP_INSRT_BY_HDR_SPECIFIC_L2):
40478 + /* nothing to check */
40479 + break;
40480 +#if (DPAA_VERSION >= 11)
40481 + case (e_FM_PCD_MANIP_INSRT_BY_HDR_IP):
40482 + if (p_ManipParams->u.hdr.insrtParams.u.byHdr.u.ipParams.insrt.size
40483 + % 4)
40484 + RETURN_ERROR(
40485 + MAJOR,
40486 + E_INVALID_VALUE,
40487 + ("IP inserted header must be of size which is a multiple of four bytes"));
40488 + break;
40489 + case (e_FM_PCD_MANIP_INSRT_BY_HDR_CAPWAP):
40490 + if (p_ManipParams->u.hdr.insrtParams.u.byHdr.u.insrt.size
40491 + % 4)
40492 + RETURN_ERROR(
40493 + MAJOR,
40494 + E_INVALID_VALUE,
40495 + ("CAPWAP inserted header must be of size which is a multiple of four bytes"));
40496 + break;
40497 + case (e_FM_PCD_MANIP_INSRT_BY_HDR_UDP):
40498 + case (e_FM_PCD_MANIP_INSRT_BY_HDR_UDP_LITE):
40499 + if (p_ManipParams->u.hdr.insrtParams.u.byHdr.u.insrt.size
40500 + != 8)
40501 + RETURN_ERROR(
40502 + MAJOR,
40503 + E_INVALID_VALUE,
40504 + ("Inserted header must be of size 8"));
40505 + break;
40506 +#endif /* (DPAA_VERSION >= 11) */
40507 + default:
40508 + RETURN_ERROR(
40509 + MAJOR,
40510 + E_INVALID_STATE,
40511 + ("unsupported insert by header type"));
40512 + }
40513 + }
40514 + case (e_FM_PCD_MANIP_INSRT_GENERIC):
40515 + break;
40516 + default:
40517 + RETURN_ERROR(
40518 + MAJOR,
40519 + E_INVALID_STATE,
40520 + ("for only insert manipulation unsupported type"));
40521 + }
40522 + p_Manip->opcode = HMAN_OC;
40523 + p_Manip->muramAllocate = TRUE;
40524 + p_Manip->insrt = TRUE;
40525 + }
40526 + else
40527 + if (p_ManipParams->u.hdr.fieldUpdate)
40528 + {
40529 + /* Check parameters */
40530 + if (p_ManipParams->u.hdr.fieldUpdateParams.type
40531 + == e_FM_PCD_MANIP_HDR_FIELD_UPDATE_VLAN)
40532 + {
40533 + if ((p_ManipParams->u.hdr.fieldUpdateParams.u.vlan.updateType
40534 + == e_FM_PCD_MANIP_HDR_FIELD_UPDATE_VLAN_VPRI)
40535 + && (p_ManipParams->u.hdr.fieldUpdateParams.u.vlan.u.vpri
40536 + > 7))
40537 + RETURN_ERROR(
40538 + MAJOR, E_INVALID_VALUE,
40539 + ("vpri should get values of 0-7 "));
40540 + if (p_ManipParams->u.hdr.fieldUpdateParams.u.vlan.updateType
40541 + == e_FM_PCD_MANIP_HDR_FIELD_UPDATE_DSCP_TO_VLAN)
40542 + {
40543 + int i;
40544 +
40545 + if (p_ManipParams->u.hdr.fieldUpdateParams.u.vlan.u.dscpToVpri.vpriDefVal
40546 + > 7)
40547 + RETURN_ERROR(
40548 + MAJOR,
40549 + E_INVALID_VALUE,
40550 + ("vpriDefVal should get values of 0-7 "));
40551 + for (i = 0; i < FM_PCD_MANIP_DSCP_TO_VLAN_TRANS;
40552 + i++)
40553 + if (p_ManipParams->u.hdr.fieldUpdateParams.u.vlan.u.dscpToVpri.dscpToVpriTable[i]
40554 + & 0xf0)
40555 + RETURN_ERROR(
40556 + MAJOR,
40557 + E_INVALID_VALUE,
40558 + ("dscpToVpriTabl value out of range (0-15)"));
40559 + }
40560 +
40561 + }
40562 +
40563 + p_Manip->opcode = HMAN_OC;
40564 + p_Manip->muramAllocate = TRUE;
40565 + p_Manip->fieldUpdate = TRUE;
40566 + }
40567 + else
40568 + if (p_ManipParams->u.hdr.custom)
40569 + {
40570 + if (p_ManipParams->u.hdr.customParams.type == e_FM_PCD_MANIP_HDR_CUSTOM_GEN_FIELD_REPLACE)
40571 + {
40572 +
40573 + if ((p_ManipParams->u.hdr.customParams.u.genFieldReplace.size == 0) ||
40574 + (p_ManipParams->u.hdr.customParams.u.genFieldReplace.size > 8))
40575 + RETURN_ERROR(
40576 + MAJOR, E_INVALID_VALUE,
40577 + ("size should get values of 1-8 "));
40578 +
40579 + if (p_ManipParams->u.hdr.customParams.u.genFieldReplace.srcOffset > 7)
40580 + RETURN_ERROR(
40581 + MAJOR, E_INVALID_VALUE,
40582 + ("srcOffset should be <= 7"));
40583 +
40584 + if ((p_ManipParams->u.hdr.customParams.u.genFieldReplace.srcOffset +
40585 + p_ManipParams->u.hdr.customParams.u.genFieldReplace.size) > 8)
40586 + RETURN_ERROR(
40587 + MAJOR, E_INVALID_VALUE,
40588 + ("(srcOffset + size) should be <= 8"));
40589 +
40590 + if ((p_ManipParams->u.hdr.customParams.u.genFieldReplace.dstOffset +
40591 + p_ManipParams->u.hdr.customParams.u.genFieldReplace.size) > 256)
40592 + RETURN_ERROR(
40593 + MAJOR, E_INVALID_VALUE,
40594 + ("(dstOffset + size) should be <= 256"));
40595 +
40596 + }
40597 +
40598 + p_Manip->opcode = HMAN_OC;
40599 + p_Manip->muramAllocate = TRUE;
40600 + p_Manip->custom = TRUE;
40601 + }
40602 + break;
40603 + case e_FM_PCD_MANIP_REASSEM:
40604 + if (p_ManipParams->h_NextManip)
40605 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED,
40606 + ("next manip with reassembly"));
40607 + switch (p_ManipParams->u.reassem.hdr)
40608 + {
40609 + case (HEADER_TYPE_IPv4):
40610 + p_Manip->reassmParams.hdr = HEADER_TYPE_IPv4;
40611 + p_Manip->opcode = HMAN_OC_IP_REASSEMBLY;
40612 + break;
40613 + case (HEADER_TYPE_IPv6):
40614 + p_Manip->reassmParams.hdr = HEADER_TYPE_IPv6;
40615 + p_Manip->opcode = HMAN_OC_IP_REASSEMBLY;
40616 + break;
40617 +#if (DPAA_VERSION >= 11)
40618 + case (HEADER_TYPE_CAPWAP):
40619 + p_Manip->reassmParams.hdr = HEADER_TYPE_CAPWAP;
40620 + p_Manip->opcode = HMAN_OC_CAPWAP_REASSEMBLY;
40621 + break;
40622 +#endif /* (DPAA_VERSION >= 11) */
40623 + default:
40624 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED,
40625 + ("header for reassembly"));
40626 + }
40627 + break;
40628 + case e_FM_PCD_MANIP_FRAG:
40629 + if (p_ManipParams->h_NextManip)
40630 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED,
40631 + ("next manip with fragmentation"));
40632 + switch (p_ManipParams->u.frag.hdr)
40633 + {
40634 + case (HEADER_TYPE_IPv4):
40635 + case (HEADER_TYPE_IPv6):
40636 + p_Manip->opcode = HMAN_OC_IP_FRAGMENTATION;
40637 + break;
40638 +#if (DPAA_VERSION >= 11)
40639 + case (HEADER_TYPE_CAPWAP):
40640 + p_Manip->opcode = HMAN_OC_CAPWAP_FRAGMENTATION;
40641 + break;
40642 +#endif /* (DPAA_VERSION >= 11) */
40643 + default:
40644 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED,
40645 + ("header for fragmentation"));
40646 + }
40647 + p_Manip->muramAllocate = TRUE;
40648 + break;
40649 + case e_FM_PCD_MANIP_SPECIAL_OFFLOAD:
40650 + switch (p_ManipParams->u.specialOffload.type)
40651 + {
40652 + case (e_FM_PCD_MANIP_SPECIAL_OFFLOAD_IPSEC):
40653 + p_Manip->opcode = HMAN_OC_IPSEC_MANIP;
40654 + p_Manip->muramAllocate = TRUE;
40655 + break;
40656 +#if (DPAA_VERSION >= 11)
40657 + case (e_FM_PCD_MANIP_SPECIAL_OFFLOAD_CAPWAP):
40658 + p_Manip->opcode = HMAN_OC_CAPWAP_MANIP;
40659 + p_Manip->muramAllocate = TRUE;
40660 + break;
40661 +#endif /* (DPAA_VERSION >= 11) */
40662 + default:
40663 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED,
40664 + ("special offload type"));
40665 + }
40666 + break;
40667 + default:
40668 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("manip type"));
40669 + }
40670 +
40671 + return E_OK;
40672 +}
40673 +#endif /* not (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10)) */
40674 +
40675 +#if (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10))
40676 +
40677 +static t_Error UpdateIndxStats(t_Handle h_FmPcd,
40678 + t_Handle h_FmPort,
40679 + t_FmPcdManip *p_Manip)
40680 +{
40681 + t_FmPcd *p_FmPcd = (t_FmPcd *)h_FmPcd;
40682 + uint32_t tmpReg32 = 0;
40683 + t_AdOfTypeContLookup *p_Ad;
40684 + t_FmPortGetSetCcParams fmPortGetSetCcParams;
40685 + t_Error err;
40686 +
40687 + SANITY_CHECK_RETURN_ERROR(p_Manip,E_INVALID_HANDLE);
40688 + SANITY_CHECK_RETURN_ERROR(p_Manip->h_Ad,E_INVALID_HANDLE);
40689 +
40690 + p_Ad = (t_AdOfTypeContLookup *)p_Manip->h_Ad;
40691 + if (p_Manip->h_FmPcd != h_FmPcd)
40692 + RETURN_ERROR(MAJOR, E_INVALID_STATE,
40693 + ("handler of PCD previously was initiated by different value"));
40694 +
40695 + memset(&fmPortGetSetCcParams, 0, sizeof(t_FmPortGetSetCcParams));
40696 +
40697 + if (!p_Manip->p_StatsTbl)
40698 + {
40699 +
40700 + fmPortGetSetCcParams.setCcParams.type = UPDATE_NIA_PNDN;
40701 + fmPortGetSetCcParams.setCcParams.nia = NIA_FM_CTL_AC_CC;
40702 + err = FmPortGetSetCcParams(h_FmPort, &fmPortGetSetCcParams);
40703 + if (err)
40704 + RETURN_ERROR(MAJOR, err, NO_MSG);
40705 +
40706 + tmpReg32 = GET_UINT32(p_Ad->ccAdBase);
40707 +
40708 + p_Manip->p_StatsTbl =
40709 + (t_Handle)FM_MURAM_AllocMem(p_FmPcd->h_FmMuram,
40710 + (uint32_t)p_Manip->owner * FM_PCD_MANIP_INDEXED_STATS_ENTRY_SIZE,
40711 + 4);
40712 + if (!p_Manip->p_StatsTbl)
40713 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("MURAM alloc for Manipulation indexed statistics table"));
40714 +
40715 + MemSet8(p_Manip->p_StatsTbl, 0, (uint32_t)(p_Manip->owner * 4));
40716 +
40717 + tmpReg32 |= (uint32_t)(XX_VirtToPhys(p_Manip->p_StatsTbl) - p_FmPcd->physicalMuramBase);
40718 +
40719 + if (p_Manip->cnia)
40720 + tmpReg32 |= FM_PCD_MANIP_INDEXED_STATS_CNIA;
40721 +
40722 + tmpReg32 |= FM_PCD_MANIP_INDEXED_STATS_DPD;
40723 + WRITE_UINT32(p_Ad->ccAdBase, tmpReg32);
40724 + }
40725 + else
40726 + {
40727 + fmPortGetSetCcParams.setCcParams.type = UPDATE_NIA_PNDN;
40728 + fmPortGetSetCcParams.setCcParams.nia = NIA_FM_CTL_AC_CC;
40729 + err = FmPortGetSetCcParams(h_FmPort, &fmPortGetSetCcParams);
40730 + if (err)
40731 + RETURN_ERROR(MAJOR, err, NO_MSG);
40732 + }
40733 +
40734 + return E_OK;
40735 +}
40736 +
40737 +static t_Error RmvHdrTillSpecLocNOrInsrtIntFrmHdr(t_FmPcdManipHdrRmvParams *p_ManipParams, t_FmPcdManip *p_Manip)
40738 +{
40739 + t_AdOfTypeContLookup *p_Ad;
40740 + uint32_t tmpReg32 = 0;
40741 + uint8_t prsArrayOffset = 0;
40742 + t_Error err;
40743 +
40744 + SANITY_CHECK_RETURN_ERROR(p_Manip,E_NULL_POINTER);
40745 + SANITY_CHECK_RETURN_ERROR(p_ManipParams,E_NULL_POINTER);
40746 + SANITY_CHECK_RETURN_ERROR(p_Manip->h_Ad,E_INVALID_HANDLE);
40747 +
40748 + p_Ad = (t_AdOfTypeContLookup *)p_Manip->h_Ad;
40749 + if (p_Manip->rmv)
40750 + {
40751 + err = GetPrOffsetByHeaderOrField(&p_ManipParams->u.byHdr.u.fromStartByHdr.hdrInfo, &prsArrayOffset);
40752 + if (err)
40753 + RETURN_ERROR(MAJOR, err, NO_MSG);
40754 +
40755 + tmpReg32 |= (uint32_t)prsArrayOffset << 24;
40756 + tmpReg32 |= HMAN_RMV_HDR;
40757 + }
40758 +
40759 + if (p_Manip->insrt)
40760 + tmpReg32 |= HMAN_INSRT_INT_FRM_HDR;
40761 +
40762 + tmpReg32 |= (uint32_t)HMAN_OC_RMV_N_OR_INSRT_INT_FRM_HDR;
40763 +
40764 + WRITE_UINT32(p_Ad->pcAndOffsets, tmpReg32);
40765 +
40766 + tmpReg32 = 0;
40767 + tmpReg32 |= FM_PCD_AD_CONT_LOOKUP_TYPE;
40768 + WRITE_UINT32(p_Ad->ccAdBase, tmpReg32);
40769 +
40770 + return E_OK;
40771 +}
40772 +
40773 +static t_Error MvIntFrameHeaderFromFrameToBufferPrefix(t_FmPcdManip *p_Manip,
40774 + bool caamUsed)
40775 +{
40776 + t_AdOfTypeContLookup *p_Ad = (t_AdOfTypeContLookup *)p_Manip->h_Ad;
40777 + uint32_t tmpReg32 = 0;
40778 +
40779 + SANITY_CHECK_RETURN_ERROR(p_Ad, E_INVALID_HANDLE);
40780 +
40781 + p_Manip->updateParams |= OFFSET_OF_PR | INTERNAL_CONTEXT_OFFSET;
40782 +
40783 + tmpReg32 = 0;
40784 + tmpReg32 |= FM_PCD_AD_CONT_LOOKUP_TYPE;
40785 + *(uint32_t *)&p_Ad->ccAdBase = tmpReg32;
40786 +
40787 + tmpReg32 = 0;
40788 + tmpReg32 |= HMAN_OC_MV_INT_FRAME_HDR_FROM_FRM_TO_BUFFER_PREFFIX;
40789 + tmpReg32 |= (uint32_t)0x16 << 16;
40790 + *(uint32_t *)&p_Ad->pcAndOffsets = tmpReg32;
40791 +
40792 + if (caamUsed)
40793 + *(uint32_t *)&p_Ad->gmask = 0xf0000000;
40794 +
40795 + return E_OK;
40796 +}
40797 +
40798 +static t_Error CapwapRmvDtlsHdr(t_FmPcd *p_FmPcd, t_FmPcdManip *p_Manip)
40799 +{
40800 + t_AdOfTypeContLookup *p_Ad;
40801 + uint32_t tmpReg32 = 0;
40802 + t_Error err = E_OK;
40803 +
40804 + SANITY_CHECK_RETURN_ERROR(p_Manip->h_Ad,E_INVALID_HANDLE);
40805 +
40806 + p_Ad = (t_AdOfTypeContLookup *)p_Manip->h_Ad;
40807 +
40808 + tmpReg32 = 0;
40809 + tmpReg32 |= (uint32_t)HMAN_OC_CAPWAP_RMV_DTLS_IF_EXIST;
40810 + WRITE_UINT32(p_Ad->pcAndOffsets, tmpReg32);
40811 +
40812 + tmpReg32 = 0;
40813 + tmpReg32 |= FM_PCD_AD_CONT_LOOKUP_TYPE;
40814 +
40815 +
40816 + if (p_Manip->h_Frag)
40817 + {
40818 + p_Manip->updateParams |= INTERNAL_CONTEXT_OFFSET;
40819 + tmpReg32 |= (uint32_t)(XX_VirtToPhys(p_Manip->h_Frag) - (p_FmPcd->physicalMuramBase));
40820 + }
40821 +
40822 + WRITE_UINT32(p_Ad->ccAdBase, tmpReg32);
40823 +
40824 + return err;
40825 +}
40826 +
40827 +static t_Error CapwapReassembly(t_CapwapReassemblyParams *p_ManipParams,
40828 + t_FmPcdManip *p_Manip,
40829 + t_FmPcd *p_FmPcd,
40830 + uint8_t poolId)
40831 +{
40832 + t_Handle p_Table;
40833 + uint32_t tmpReg32 = 0;
40834 + int i = 0;
40835 + uint8_t log2Num;
40836 + uint8_t numOfSets;
40837 + uint32_t j = 0;
40838 + uint32_t bitFor1Micro;
40839 +
40840 + SANITY_CHECK_RETURN_ERROR(p_Manip->h_Ad, E_INVALID_HANDLE);
40841 + SANITY_CHECK_RETURN_ERROR(p_FmPcd->h_Hc, E_INVALID_HANDLE);
40842 +
40843 + if (!p_FmPcd->h_Hc)
40844 + RETURN_ERROR(MAJOR, E_INVALID_VALUE,("hc port has to be initialized in this mode"));
40845 + if (!POWER_OF_2(p_ManipParams->timeoutRoutineRequestTime))
40846 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("timeoutRoutineRequestTime has to be power of 2"));
40847 + if (!POWER_OF_2(p_ManipParams->maxNumFramesInProcess))
40848 + RETURN_ERROR(MAJOR, E_INVALID_VALUE,("maxNumFramesInProcess has to be power of 2"));
40849 + if (!p_ManipParams->timeoutRoutineRequestTime && p_ManipParams->timeoutThresholdForReassmProcess)
40850 + DBG(WARNING, ("if timeoutRoutineRequestTime 0, timeoutThresholdForReassmProcess is uselessly"));
40851 + if (p_ManipParams->numOfFramesPerHashEntry == e_FM_PCD_MANIP_FOUR_WAYS_HASH)
40852 + {
40853 + if ((p_ManipParams->maxNumFramesInProcess < 4) ||
40854 + (p_ManipParams->maxNumFramesInProcess > 512))
40855 + 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"));
40856 + }
40857 + else
40858 + {
40859 + if ((p_ManipParams->maxNumFramesInProcess < 8) ||
40860 + (p_ManipParams->maxNumFramesInProcess > 2048))
40861 + 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"));
40862 + }
40863 +
40864 + bitFor1Micro = FmGetTimeStampScale(p_FmPcd->h_Fm);
40865 + if (bitFor1Micro == 0)
40866 + RETURN_ERROR(MAJOR, E_NOT_AVAILABLE, ("Timestamp scale"));
40867 +
40868 + p_Manip->updateParams |= (NUM_OF_TASKS | OFFSET_OF_PR | OFFSET_OF_DATA | HW_PORT_ID);
40869 +
40870 + p_Manip->h_Frag = (t_Handle)FM_MURAM_AllocMem(p_FmPcd->h_FmMuram,
40871 + FM_PCD_MANIP_CAPWAP_REASM_TABLE_SIZE,
40872 + FM_PCD_MANIP_CAPWAP_REASM_TABLE_ALIGN);
40873 + if (!p_Manip->h_Frag)
40874 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("MURAM alloc CAPWAP reassembly parameters table"));
40875 +
40876 + MemSet8(p_Manip->h_Frag, 0, FM_PCD_MANIP_CAPWAP_REASM_TABLE_SIZE);
40877 +
40878 + p_Table = (t_CapwapReasmPram *)p_Manip->h_Frag;
40879 +
40880 + p_Manip->capwapFragParams.p_AutoLearnHashTbl =
40881 + (t_Handle)FM_MURAM_AllocMem(p_FmPcd->h_FmMuram,
40882 + (uint32_t)(p_ManipParams->maxNumFramesInProcess * 2 * FM_PCD_MANIP_CAPWAP_REASM_AUTO_LEARNING_HASH_ENTRY_SIZE),
40883 + FM_PCD_MANIP_CAPWAP_REASM_TABLE_ALIGN);
40884 +
40885 + if (!p_Manip->capwapFragParams.p_AutoLearnHashTbl)
40886 + RETURN_ERROR(MAJOR, E_NO_MEMORY,("MURAM alloc for CAPWAP automatic learning hash table"));
40887 +
40888 + MemSet8(p_Manip->capwapFragParams.p_AutoLearnHashTbl, 0, (uint32_t)(p_ManipParams->maxNumFramesInProcess * 2 * FM_PCD_MANIP_CAPWAP_REASM_AUTO_LEARNING_HASH_ENTRY_SIZE));
40889 +
40890 + tmpReg32 = (uint32_t)(XX_VirtToPhys(p_Manip->capwapFragParams.p_AutoLearnHashTbl) - p_FmPcd->physicalMuramBase);
40891 +
40892 + WRITE_UINT32(((t_CapwapReasmPram *)p_Table)->autoLearnHashTblPtr, tmpReg32);
40893 +
40894 + tmpReg32 = 0;
40895 + if (p_ManipParams->timeOutMode == e_FM_PCD_MANIP_TIME_OUT_BETWEEN_FRAMES)
40896 + tmpReg32 |= FM_PCD_MANIP_CAPWAP_REASM_TIME_OUT_BETWEEN_FRAMES;
40897 + if (p_ManipParams->haltOnDuplicationFrag)
40898 + tmpReg32 |= FM_PCD_MANIP_CAPWAP_REASM_HALT_ON_DUPLICATE_FRAG;
40899 + if (p_ManipParams->numOfFramesPerHashEntry == e_FM_PCD_MANIP_EIGHT_WAYS_HASH)
40900 + {
40901 + i = 8;
40902 + tmpReg32 |= FM_PCD_MANIP_CAPWAP_REASM_AUTOMATIC_LEARNIN_HASH_8_WAYS;
40903 + }
40904 + else
40905 + i = 4;
40906 +
40907 + numOfSets = (uint8_t)((p_ManipParams->maxNumFramesInProcess * 2) / i);
40908 + LOG2(numOfSets, log2Num);
40909 + tmpReg32 |= (uint32_t)(log2Num - 1) << 24;
40910 +
40911 + WRITE_UINT32(((t_CapwapReasmPram *)p_Table)->mode, tmpReg32);
40912 +
40913 + for (j=0; j<p_ManipParams->maxNumFramesInProcess*2; j++)
40914 + if (((j / i) % 2)== 0)
40915 + WRITE_UINT32(*(uint32_t *)PTR_MOVE(p_Manip->capwapFragParams.p_AutoLearnHashTbl, j * FM_PCD_MANIP_CAPWAP_REASM_AUTO_LEARNING_HASH_ENTRY_SIZE), 0x80000000);
40916 +
40917 + tmpReg32 = 0x00008000;
40918 + tmpReg32 |= (uint32_t)poolId << 16;
40919 + WRITE_UINT32(((t_CapwapReasmPram *)p_Table)->bufferPoolIdAndRisc1SetIndexes, tmpReg32);
40920 + WRITE_UINT32(((t_CapwapReasmPram *)p_Table)->risc23SetIndexes, 0x80008000);
40921 + WRITE_UINT32(((t_CapwapReasmPram *)p_Table)->risc4SetIndexesAndExtendedStatsTblPtr, 0x80000000);
40922 +
40923 + p_Manip->capwapFragParams.maxNumFramesInProcess = p_ManipParams->maxNumFramesInProcess;
40924 +
40925 + p_Manip->capwapFragParams.sgBpid = poolId;
40926 +
40927 + p_Manip->capwapFragParams.fqidForTimeOutFrames = p_ManipParams->fqidForTimeOutFrames;
40928 + p_Manip->capwapFragParams.timeoutRoutineRequestTime = p_ManipParams->timeoutRoutineRequestTime;
40929 + p_Manip->capwapFragParams.bitFor1Micro = bitFor1Micro;
40930 +
40931 + tmpReg32 = 0;
40932 + tmpReg32 |= (((uint32_t)1<<p_Manip->capwapFragParams.bitFor1Micro) * p_ManipParams->timeoutThresholdForReassmProcess);
40933 + WRITE_UINT32(((t_CapwapReasmPram *)p_Table)->expirationDelay, tmpReg32);
40934 +
40935 + return E_OK;
40936 +}
40937 +
40938 +static t_Error CapwapFragmentation(t_CapwapFragmentationParams *p_ManipParams,
40939 + t_FmPcdManip *p_Manip,
40940 + t_FmPcd *p_FmPcd,
40941 + uint8_t poolId)
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 + p_Manip->updateParams |= OFFSET_OF_DATA;
40949 +
40950 + p_Manip->frag = TRUE;
40951 +
40952 + p_Manip->h_Frag = (t_Handle)FM_MURAM_AllocMem(p_FmPcd->h_FmMuram,
40953 + FM_PCD_CC_AD_ENTRY_SIZE,
40954 + FM_PCD_CC_AD_TABLE_ALIGN);
40955 + if (!p_Manip->h_Frag)
40956 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("MURAM alloc for CAPWAP fragmentation table descriptor"));
40957 +
40958 + MemSet8(p_Manip->h_Frag, 0, FM_PCD_CC_AD_ENTRY_SIZE);
40959 +
40960 + p_Ad = (t_AdOfTypeContLookup *)p_Manip->h_Frag;
40961 +
40962 + tmpReg32 = 0;
40963 + tmpReg32 |= (uint32_t)HMAN_OC_CAPWAP_FRAGMENTATION;
40964 +
40965 + if (p_ManipParams->headerOptionsCompr)
40966 + tmpReg32 |= FM_PCD_MANIP_CAPWAP_FRAG_COMPR_OPTION_FIELD_EN;
40967 + tmpReg32 |= ((uint32_t)poolId << 8);
40968 + WRITE_UINT32(p_Ad->pcAndOffsets, tmpReg32);
40969 +
40970 + tmpReg32 = 0;
40971 + tmpReg32 |= FM_PCD_AD_CONT_LOOKUP_TYPE;
40972 + WRITE_UINT32(p_Ad->ccAdBase, tmpReg32);
40973 +
40974 + p_Manip->sizeForFragmentation = p_ManipParams->sizeForFragmentation;
40975 + p_Manip->capwapFragParams.sgBpid = poolId;
40976 +
40977 + return E_OK;
40978 +}
40979 +
40980 +static t_Error IndxStats(t_FmPcdStatsParams *p_StatsParams,t_FmPcdManip *p_Manip,t_FmPcd *p_FmPcd)
40981 +{
40982 + t_AdOfTypeContLookup *p_Ad;
40983 + uint32_t tmpReg32 = 0;
40984 +
40985 + SANITY_CHECK_RETURN_ERROR(p_Manip->h_Ad,E_INVALID_HANDLE);
40986 +
40987 + UNUSED(p_FmPcd);
40988 +
40989 + p_Ad = (t_AdOfTypeContLookup *)p_Manip->h_Ad;
40990 +
40991 + tmpReg32 = 0;
40992 + tmpReg32 |= (uint32_t)HMAN_OC_CAPWAP_INDEXED_STATS;
40993 + if (p_StatsParams->type == e_FM_PCD_STATS_PER_FLOWID)
40994 + tmpReg32 |= (uint32_t)0x16 << 16;
40995 + WRITE_UINT32(p_Ad->pcAndOffsets, tmpReg32);
40996 +
40997 + tmpReg32 = 0;
40998 + tmpReg32 |= FM_PCD_AD_CONT_LOOKUP_TYPE;
40999 + WRITE_UINT32(p_Ad->ccAdBase, tmpReg32);
41000 +
41001 + return E_OK;
41002 +}
41003 +
41004 +static t_Error InsrtHdrByTempl(t_FmPcdManipHdrInsrtParams *p_ManipParams, t_FmPcdManip *p_Manip, t_FmPcd *p_FmPcd)
41005 +{
41006 + t_FmPcdManipHdrInsrtByTemplateParams *p_InsrtByTemplate = &p_ManipParams->u.byTemplate;
41007 + uint8_t tmpReg8 = 0xff;
41008 + t_AdOfTypeContLookup *p_Ad;
41009 + bool ipModify = FALSE;
41010 + uint32_t tmpReg32 = 0, tmpRegNia = 0;
41011 + uint16_t tmpReg16 = 0;
41012 + t_Error err = E_OK;
41013 + uint8_t extraAddedBytes = 0, blockSize = 0, extraAddedBytesAlignedToBlockSize = 0, log2Num = 0;
41014 + uint8_t *p_Template = NULL;
41015 +
41016 + SANITY_CHECK_RETURN_ERROR(p_ManipParams,E_NULL_POINTER);
41017 + SANITY_CHECK_RETURN_ERROR(p_Manip,E_NULL_POINTER);
41018 + SANITY_CHECK_RETURN_ERROR(p_Manip->h_Ad,E_INVALID_HANDLE);
41019 + SANITY_CHECK_RETURN_ERROR(p_FmPcd,E_NULL_POINTER);
41020 +
41021 + p_Ad = (t_AdOfTypeContLookup *)p_Manip->h_Ad;
41022 + if (p_Manip->insrt)
41023 + {
41024 + if ((!p_InsrtByTemplate->size && p_InsrtByTemplate->modifyOuterIp) ||
41025 + (!p_InsrtByTemplate->size && p_InsrtByTemplate->modifyOuterVlan))
41026 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Inconsistent parameters : asking for header template modifications with no template for insertion (template size)"));
41027 +
41028 + if (p_InsrtByTemplate->size && p_InsrtByTemplate->modifyOuterIp && (p_InsrtByTemplate->size <= p_InsrtByTemplate->modifyOuterIpParams.ipOuterOffset))
41029 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Inconsistent parameters : size of template < ipOuterOffset"));
41030 +
41031 + if (p_InsrtByTemplate->size > 128)
41032 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Size of header template for insertion can not be more than 128"));
41033 +
41034 + if (p_InsrtByTemplate->size)
41035 + {
41036 + p_Manip->p_Template = (uint8_t *)FM_MURAM_AllocMem(p_FmPcd->h_FmMuram,
41037 + p_InsrtByTemplate->size,
41038 + FM_PCD_CC_AD_TABLE_ALIGN);
41039 + if(!p_Manip->p_Template)
41040 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("Memory allocation in MURAM FAILED"));
41041 +
41042 + tmpReg32 = (uint32_t)(XX_VirtToPhys(p_Manip->p_Template) - (p_FmPcd->physicalMuramBase));
41043 + tmpReg32 |= (uint32_t)p_InsrtByTemplate->size << 24;
41044 + *(uint32_t *)&p_Ad->matchTblPtr = tmpReg32;
41045 + }
41046 +
41047 + tmpReg32 = 0;
41048 +
41049 + p_Template = (uint8_t *)XX_Malloc(p_InsrtByTemplate->size * sizeof(uint8_t));
41050 +
41051 + if (!p_Template)
41052 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("XX_Malloc allocation FAILED"));
41053 +
41054 + memcpy(p_Template, p_InsrtByTemplate->hdrTemplate, p_InsrtByTemplate->size * sizeof(uint8_t));
41055 +
41056 + if (p_InsrtByTemplate->modifyOuterIp)
41057 + {
41058 + ipModify = TRUE;
41059 +
41060 + tmpReg8 = (uint8_t)p_Template[p_InsrtByTemplate->modifyOuterIpParams.ipOuterOffset];
41061 +
41062 + if((tmpReg8 & 0xf0) == 0x40)
41063 + tmpReg8 = 4;
41064 + else if((tmpReg8 & 0xf0) == 0x60)
41065 + tmpReg8 = 6;
41066 + else
41067 + tmpReg8 = 0xff;
41068 +
41069 + if (tmpReg8 != 0xff)
41070 + {
41071 + if(p_InsrtByTemplate->modifyOuterIpParams.dscpEcn & 0xff00)
41072 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Inconsistent parameters : IPV4 present in header template, dscpEcn has to be only 1 byte"));
41073 + if(p_InsrtByTemplate->modifyOuterIpParams.recalculateLength)
41074 + {
41075 +
41076 + if((p_InsrtByTemplate->modifyOuterIpParams.recalculateLengthParams.extraBytesAddedAlignedToBlockSize + p_InsrtByTemplate->modifyOuterIpParams.recalculateLengthParams.extraBytesAddedNotAlignedToBlockSize) > 255)
41077 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("extra Byte added can not be more than 256 bytes"));
41078 + extraAddedBytes = (uint8_t) (p_InsrtByTemplate->modifyOuterIpParams.recalculateLengthParams.extraBytesAddedAlignedToBlockSize + p_InsrtByTemplate->modifyOuterIpParams.recalculateLengthParams.extraBytesAddedNotAlignedToBlockSize);
41079 + blockSize = p_InsrtByTemplate->modifyOuterIpParams.recalculateLengthParams.blockSize;
41080 + extraAddedBytesAlignedToBlockSize = p_InsrtByTemplate->modifyOuterIpParams.recalculateLengthParams.extraBytesAddedAlignedToBlockSize;
41081 + /*IP header template - IP totalLength -
41082 + (1 byte) extraByteForIp = headerTemplateSize - ipOffset + insertedBytesAfterThisStage ,
41083 + in the case of SEC insertedBytesAfterThisStage - SEC trailer (21/31) + header(13)
41084 + second byte - extraByteForIp = headerTemplate - ipOffset + insertedBytesAfterThisStage*/
41085 + }
41086 + if (blockSize)
41087 + {
41088 + if (!POWER_OF_2(blockSize))
41089 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("inputFrmPaddingUpToBlockSize has to be power of 2"));
41090 + }
41091 +
41092 + }
41093 + if (tmpReg8 == 4)
41094 + {
41095 + if ((IPv4_HDRCHECKSUM_FIELD_OFFSET_FROM_IP + p_InsrtByTemplate->modifyOuterIpParams.ipOuterOffset) > p_InsrtByTemplate->size)
41096 + 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"));
41097 +
41098 + p_Template[p_InsrtByTemplate->modifyOuterIpParams.ipOuterOffset + IPv4_DSCECN_FIELD_OFFSET_FROM_IP] = (uint8_t)p_InsrtByTemplate->modifyOuterIpParams.dscpEcn;
41099 +
41100 + if (blockSize)
41101 + blockSize -= 1;
41102 +
41103 + if ((p_InsrtByTemplate->size - p_InsrtByTemplate->modifyOuterIpParams.ipOuterOffset + extraAddedBytes) > 255)
41104 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("p_InsrtByTemplate->size - p_InsrtByTemplate->modifyOuterIpParams.ipOuterOffset + extraAddedBytes has to be less than 255"));
41105 +
41106 + p_Template[p_InsrtByTemplate->modifyOuterIpParams.ipOuterOffset + IPv4_TOTALLENGTH_FIELD_OFFSET_FROM_IP + 1] = blockSize; // IPV6 - in AD instead of SEQ IND
41107 + 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
41108 +
41109 + p_Template[p_InsrtByTemplate->modifyOuterIpParams.ipOuterOffset + IPv4_ID_FIELD_OFFSET_FROM_IP] = 0x00;
41110 + p_Template[p_InsrtByTemplate->modifyOuterIpParams.ipOuterOffset + IPv4_ID_FIELD_OFFSET_FROM_IP + 1] = extraAddedBytesAlignedToBlockSize;
41111 +
41112 + /*IP header template - relevant only for ipv4 CheckSum = 0*/
41113 + p_Template[p_InsrtByTemplate->modifyOuterIpParams.ipOuterOffset + IPv4_HDRCHECKSUM_FIELD_OFFSET_FROM_IP] = 0x00;
41114 + p_Template[p_InsrtByTemplate->modifyOuterIpParams.ipOuterOffset + IPv4_HDRCHECKSUM_FIELD_OFFSET_FROM_IP + 1] = 0x00;
41115 +
41116 + /*UDP checksum has to be 0*/
41117 + if (p_InsrtByTemplate->modifyOuterIpParams.udpPresent)
41118 + {
41119 + if ((p_InsrtByTemplate->modifyOuterIpParams.udpOffset + UDP_CHECKSUM_FIELD_OFFSET_FROM_UDP + UDP_CHECKSUM_FIELD_SIZE) > p_InsrtByTemplate->size)
41120 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Inconsistent parameters : UDP present according to user but (UDP offset + UDP header size) < size of header template"));
41121 +
41122 + p_Template[p_InsrtByTemplate->modifyOuterIpParams.udpOffset + UDP_CHECKSUM_FIELD_OFFSET_FROM_UDP ] = 0x00;
41123 + p_Template[p_InsrtByTemplate->modifyOuterIpParams.udpOffset + UDP_CHECKSUM_FIELD_OFFSET_FROM_UDP + 1] = 0x00;
41124 +
41125 + }
41126 +
41127 + if (p_InsrtByTemplate->modifyOuterIpParams.ipIdentGenId > 7)
41128 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("ipIdentGenId has to be one out of 8 sequence number generators (0 - 7) for IP identification field"));
41129 +
41130 + tmpRegNia |= (uint32_t)p_InsrtByTemplate->modifyOuterIpParams.ipIdentGenId<<24;
41131 + }
41132 + else if (tmpReg8 == 6)
41133 + {
41134 + /*TODO - add check for maximum value of blockSize;*/
41135 + if (blockSize)
41136 + LOG2(blockSize, log2Num);
41137 + tmpRegNia |= (uint32_t)log2Num << 24;
41138 +
41139 + // for IPV6 decrement additional 40 bytes of IPV6 heade size - because IPV6 header size is not included in payloadLength
41140 + p_Template[p_InsrtByTemplate->modifyOuterIpParams.ipOuterOffset + IPv6_PAYLOAD_LENGTH_OFFSET_FROM_IP] = (uint8_t)(p_InsrtByTemplate->size - p_InsrtByTemplate->modifyOuterIpParams.ipOuterOffset + extraAddedBytes - 40);
41141 + p_Template[p_InsrtByTemplate->modifyOuterIpParams.ipOuterOffset + IPv6_PAYLOAD_LENGTH_OFFSET_FROM_IP + 1] = extraAddedBytesAlignedToBlockSize;
41142 + if (p_InsrtByTemplate->modifyOuterIpParams.udpPresent)
41143 + {
41144 + if ((p_InsrtByTemplate->modifyOuterIpParams.udpOffset + UDP_CHECKSUM_FIELD_OFFSET_FROM_UDP + UDP_CHECKSUM_FIELD_SIZE) > p_InsrtByTemplate->size)
41145 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Inconsistent parameters : UDP present according to user but (UDP offset + UDP header size) < size of header template"));
41146 + if (p_Template[p_InsrtByTemplate->modifyOuterIpParams.ipOuterOffset + IPv6_NEXT_HEADER_OFFSET_FROM_IP] != 0x88)
41147 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("OUr suppport is only IPv6/UDPLite"));
41148 + p_Template[p_InsrtByTemplate->modifyOuterIpParams.udpOffset + UDP_LENGTH_FIELD_OFFSET_FROM_UDP] = 0x00;
41149 + p_Template[p_InsrtByTemplate->modifyOuterIpParams.udpOffset + UDP_LENGTH_FIELD_OFFSET_FROM_UDP + 1] = 0x08;
41150 + p_Template[p_InsrtByTemplate->modifyOuterIpParams.udpOffset + UDP_CHECKSUM_FIELD_OFFSET_FROM_UDP] = 0x00;
41151 + p_Template[p_InsrtByTemplate->modifyOuterIpParams.udpOffset + UDP_CHECKSUM_FIELD_OFFSET_FROM_UDP + 1] = 0x00;
41152 + }
41153 + }
41154 + else
41155 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("IP version supported only IPV4"));
41156 + }
41157 +
41158 + tmpReg32 = tmpReg16 = tmpReg8 = 0;
41159 + /*TODO - check it*/
41160 + if (p_InsrtByTemplate->modifyOuterVlan)
41161 + {
41162 + if (p_InsrtByTemplate->modifyOuterVlanParams.vpri & ~0x07)
41163 + RETURN_ERROR(MAJOR, E_INVALID_STATE,("Inconsistent parameters : user asked for VLAN modifications but VPRI more than 3 bits"));
41164 +
41165 + memcpy(&tmpReg16, &p_Template[VLAN_TAG_FIELD_OFFSET_FROM_ETH], 2*(sizeof(uint8_t)));
41166 + if ((tmpReg16 != 0x9100) && (tmpReg16!= 0x9200) && (tmpReg16 != 0x8100))
41167 + RETURN_ERROR(MAJOR, E_INVALID_STATE,("Inconsistent parameters : user asked for VLAN modifications but Tag Protocol identifier is not VLAN "));
41168 +
41169 + memcpy(&tmpReg8, &p_Template[14],1*(sizeof(uint8_t)));
41170 + tmpReg8 &= 0x1f;
41171 + tmpReg8 |= (uint8_t)(p_InsrtByTemplate->modifyOuterVlanParams.vpri << 5);
41172 +
41173 + p_Template[14] = tmpReg8;
41174 + }
41175 +
41176 + MemCpy8(p_Manip->p_Template, p_Template, p_InsrtByTemplate->size);
41177 +
41178 + XX_Free(p_Template);
41179 + }
41180 +
41181 + tmpReg32 = 0;
41182 + if (p_Manip->h_Frag)
41183 + {
41184 + tmpRegNia |= (uint32_t)(XX_VirtToPhys(p_Manip->h_Frag) - (p_FmPcd->physicalMuramBase));
41185 + tmpReg32 |= (uint32_t)p_Manip->sizeForFragmentation << 16;
41186 + }
41187 + else
41188 + tmpReg32 = 0xffff0000;
41189 +
41190 + if (ipModify)
41191 + tmpReg32 |= (uint32_t)p_InsrtByTemplate->modifyOuterIpParams.ipOuterOffset << 8;
41192 + else
41193 + tmpReg32 |= (uint32_t)0x0000ff00;
41194 +
41195 + tmpReg32 |= (uint32_t)HMAN_OC_INSRT_HDR_BY_TEMPL_N_OR_FRAG_AFTER;
41196 + *(uint32_t *)&p_Ad->pcAndOffsets = tmpReg32;
41197 +
41198 + tmpRegNia |= FM_PCD_AD_CONT_LOOKUP_TYPE;
41199 + *(uint32_t *)&p_Ad->ccAdBase = tmpRegNia;
41200 +
41201 + return err;
41202 +}
41203 +
41204 +static t_Error CheckStatsParamsAndSetType(t_FmPcdManip *p_Manip, t_FmPcdStatsParams *p_StatsParams)
41205 +{
41206 +
41207 + switch (p_StatsParams->type)
41208 + {
41209 + case (e_FM_PCD_STATS_PER_FLOWID):
41210 + p_Manip->opcode = HMAN_OC_CAPWAP_INDEXED_STATS;
41211 + p_Manip->muramAllocate = TRUE;
41212 + break;
41213 + default:
41214 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Unsupported statistics type"));
41215 + }
41216 +
41217 + return E_OK;
41218 +}
41219 +#endif /* (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10)) */
41220 +
41221 +static t_Error FillReassmManipParams(t_FmPcdManip *p_Manip, e_NetHeaderType hdr)
41222 +{
41223 + t_AdOfTypeContLookup *p_Ad;
41224 + t_FmPcd *p_FmPcd = (t_FmPcd *)p_Manip->h_FmPcd;
41225 + uint32_t tmpReg32;
41226 + t_Error err = E_OK;
41227 +
41228 + /* Creates the Reassembly Parameters table. It contains parameters that are specific to either the IPv4 reassembly
41229 + function or to the IPv6 reassembly function. If both IPv4 reassembly and IPv6 reassembly are required, then
41230 + two separate IP Reassembly Parameter tables are required.*/
41231 + if ((err = CreateReassTable(p_Manip, hdr)) != E_OK)
41232 + RETURN_ERROR(MAJOR, err, NO_MSG);
41233 +
41234 + /* Sets the first Ad register (ccAdBase) - Action Descriptor Type and Pointer to the Reassembly Parameters Table offset from MURAM*/
41235 + tmpReg32 = 0;
41236 + tmpReg32 |= FM_PCD_AD_CONT_LOOKUP_TYPE;
41237 +
41238 + /* Gets the required Action descriptor table pointer */
41239 + switch (hdr)
41240 + {
41241 + case HEADER_TYPE_IPv4:
41242 + p_Ad = (t_AdOfTypeContLookup *)p_Manip->reassmParams.ip.h_Ipv4Ad;
41243 + tmpReg32 |= (uint32_t)(XX_VirtToPhys(
41244 + p_Manip->reassmParams.ip.p_Ipv4ReassTbl)
41245 + - (p_FmPcd->physicalMuramBase));
41246 + break;
41247 + case HEADER_TYPE_IPv6:
41248 + p_Ad = (t_AdOfTypeContLookup *)p_Manip->reassmParams.ip.h_Ipv6Ad;
41249 + tmpReg32 |= (uint32_t)(XX_VirtToPhys(
41250 + p_Manip->reassmParams.ip.p_Ipv6ReassTbl)
41251 + - (p_FmPcd->physicalMuramBase));
41252 + break;
41253 + case HEADER_TYPE_CAPWAP:
41254 + p_Ad = (t_AdOfTypeContLookup *)p_Manip->reassmParams.capwap.h_Ad;
41255 + tmpReg32 |= (uint32_t)(XX_VirtToPhys(
41256 + p_Manip->reassmParams.capwap.p_ReassTbl)
41257 + - (p_FmPcd->physicalMuramBase));
41258 + break;
41259 + default:
41260 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("header type"));
41261 + }
41262 +
41263 + WRITE_UINT32(p_Ad->ccAdBase, tmpReg32);
41264 +
41265 + /* Sets the second Ad register (matchTblPtr) - Buffer pool ID (BPID for V2) and Scatter/Gather table offset*/
41266 + /* mark the Scatter/Gather table offset to be set later on when the port will be known */
41267 + p_Manip->updateParams = (NUM_OF_TASKS | NUM_OF_EXTRA_TASKS | DISCARD_MASK);
41268 +
41269 + if ((hdr == HEADER_TYPE_IPv6) || (hdr == HEADER_TYPE_IPv4))
41270 + {
41271 +#if (DPAA_VERSION == 10)
41272 + tmpReg32 = (uint32_t)(p_Manip->reassmParams.sgBpid << 8);
41273 + WRITE_UINT32(p_Ad->matchTblPtr, tmpReg32);
41274 +#endif /* (DPAA_VERSION == 10) */
41275 +#if (DPAA_VERSION >= 11)
41276 + if (p_Manip->reassmParams.ip.nonConsistentSpFqid != 0)
41277 + {
41278 + tmpReg32 = FM_PCD_AD_NCSPFQIDM_MASK
41279 + | (uint32_t)(p_Manip->reassmParams.ip.nonConsistentSpFqid);
41280 + WRITE_UINT32(p_Ad->gmask, tmpReg32);
41281 + }
41282 +#endif /* (DPAA_VERSION >= 11) */
41283 + /* Sets the third Ad register (pcAndOffsets)- IP Reassemble Operation Code*/
41284 + tmpReg32 = 0;
41285 + tmpReg32 |= (uint32_t)HMAN_OC_IP_REASSEMBLY;
41286 + }
41287 +#if (DPAA_VERSION >= 11)
41288 + else
41289 + if (hdr == HEADER_TYPE_CAPWAP)
41290 + {
41291 + tmpReg32 = 0;
41292 + tmpReg32 |= (uint32_t)HMAN_OC_CAPWAP_REASSEMBLY;
41293 + }
41294 +#endif /* (DPAA_VERSION >= 11) */
41295 +
41296 + WRITE_UINT32(p_Ad->pcAndOffsets, tmpReg32);
41297 +
41298 + p_Manip->reassm = TRUE;
41299 +
41300 + return E_OK;
41301 +}
41302 +
41303 +static t_Error SetIpv4ReassmManip(t_FmPcdManip *p_Manip)
41304 +{
41305 + t_FmPcd *p_FmPcd = (t_FmPcd *)p_Manip->h_FmPcd;
41306 +
41307 + /* Allocation if IPv4 Action descriptor */
41308 + p_Manip->reassmParams.ip.h_Ipv4Ad = (t_Handle)XX_MallocSmart(
41309 + FM_PCD_CC_AD_ENTRY_SIZE, p_Manip->reassmParams.dataMemId,
41310 + FM_PCD_CC_AD_TABLE_ALIGN);
41311 + if (!p_Manip->reassmParams.ip.h_Ipv4Ad)
41312 + {
41313 + ReleaseManipHandler(p_Manip, p_FmPcd);
41314 + RETURN_ERROR(MAJOR, E_NO_MEMORY,
41315 + ("Allocation of IPv4 table descriptor"));
41316 + }
41317 +
41318 + memset(p_Manip->reassmParams.ip.h_Ipv4Ad, 0, FM_PCD_CC_AD_ENTRY_SIZE);
41319 +
41320 + /* Fill reassembly manipulation parameter in the IP Reassembly Action Descriptor */
41321 + return FillReassmManipParams(p_Manip, HEADER_TYPE_IPv4);
41322 +}
41323 +
41324 +static t_Error SetIpv6ReassmManip(t_FmPcdManip *p_Manip)
41325 +{
41326 + t_FmPcd *p_FmPcd = (t_FmPcd *)p_Manip->h_FmPcd;
41327 +
41328 + /* Allocation if IPv6 Action descriptor */
41329 + p_Manip->reassmParams.ip.h_Ipv6Ad = (t_Handle)XX_MallocSmart(
41330 + FM_PCD_CC_AD_ENTRY_SIZE, p_Manip->reassmParams.dataMemId,
41331 + FM_PCD_CC_AD_TABLE_ALIGN);
41332 + if (!p_Manip->reassmParams.ip.h_Ipv6Ad)
41333 + {
41334 + ReleaseManipHandler(p_Manip, p_FmPcd);
41335 + RETURN_ERROR(MAJOR, E_NO_MEMORY,
41336 + ("Allocation of IPv6 table descriptor"));
41337 + }
41338 +
41339 + memset(p_Manip->reassmParams.ip.h_Ipv6Ad, 0, FM_PCD_CC_AD_ENTRY_SIZE);
41340 +
41341 + /* Fill reassembly manipulation parameter in the IP Reassembly Action Descriptor */
41342 + return FillReassmManipParams(p_Manip, HEADER_TYPE_IPv6);
41343 +}
41344 +
41345 +static t_Error IpReassembly(t_FmPcdManipReassemParams *p_ManipReassmParams,
41346 + t_FmPcdManip *p_Manip)
41347 +{
41348 + uint32_t maxSetNumber = 10000;
41349 + t_FmPcdManipReassemIpParams reassmManipParams =
41350 + p_ManipReassmParams->u.ipReassem;
41351 + t_Error res;
41352 +
41353 + SANITY_CHECK_RETURN_ERROR(p_Manip->h_FmPcd, E_INVALID_HANDLE);
41354 + SANITY_CHECK_RETURN_ERROR(((t_FmPcd *)p_Manip->h_FmPcd)->h_Hc,
41355 + E_INVALID_HANDLE);
41356 +
41357 + /* Check validation of user's parameter.*/
41358 + if ((reassmManipParams.timeoutThresholdForReassmProcess < 1000)
41359 + || (reassmManipParams.timeoutThresholdForReassmProcess > 8000000))
41360 + RETURN_ERROR(
41361 + MAJOR, E_INVALID_VALUE,
41362 + ("timeoutThresholdForReassmProcess should be 1msec - 8sec"));
41363 + /* It is recommended that the total number of entries in this table (number of sets * number of ways)
41364 + will be twice the number of frames that are expected to be reassembled simultaneously.*/
41365 + if (reassmManipParams.maxNumFramesInProcess
41366 + > (reassmManipParams.maxNumFramesInProcess * maxSetNumber / 2))
41367 + RETURN_ERROR(
41368 + MAJOR,
41369 + E_INVALID_VALUE,
41370 + ("maxNumFramesInProcess has to be less than (maximun set number * number of ways / 2)"));
41371 +
41372 + if ((p_ManipReassmParams->hdr == HEADER_TYPE_IPv6)
41373 + && (reassmManipParams.minFragSize[1] < 256))
41374 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("minFragSize[1] must be >= 256"));
41375 +
41376 + /* Saves user's reassembly manipulation parameters */
41377 + p_Manip->reassmParams.ip.relativeSchemeId[0] =
41378 + reassmManipParams.relativeSchemeId[0];
41379 + p_Manip->reassmParams.ip.relativeSchemeId[1] =
41380 + reassmManipParams.relativeSchemeId[1];
41381 + p_Manip->reassmParams.ip.numOfFramesPerHashEntry[0] =
41382 + reassmManipParams.numOfFramesPerHashEntry[0];
41383 + p_Manip->reassmParams.ip.numOfFramesPerHashEntry[1] =
41384 + reassmManipParams.numOfFramesPerHashEntry[1];
41385 + p_Manip->reassmParams.ip.minFragSize[0] = reassmManipParams.minFragSize[0];
41386 + p_Manip->reassmParams.ip.minFragSize[1] = reassmManipParams.minFragSize[1];
41387 + p_Manip->reassmParams.maxNumFramesInProcess =
41388 + reassmManipParams.maxNumFramesInProcess;
41389 + p_Manip->reassmParams.timeOutMode = reassmManipParams.timeOutMode;
41390 + p_Manip->reassmParams.fqidForTimeOutFrames =
41391 + reassmManipParams.fqidForTimeOutFrames;
41392 + p_Manip->reassmParams.timeoutThresholdForReassmProcess =
41393 + reassmManipParams.timeoutThresholdForReassmProcess;
41394 + p_Manip->reassmParams.dataMemId = reassmManipParams.dataMemId;
41395 + p_Manip->reassmParams.dataLiodnOffset = reassmManipParams.dataLiodnOffset;
41396 +#if (DPAA_VERSION == 10)
41397 + p_Manip->reassmParams.sgBpid = reassmManipParams.sgBpid;
41398 +#endif /* (DPAA_VERSION == 10) */
41399 +#if (DPAA_VERSION >= 11)
41400 + if (reassmManipParams.nonConsistentSpFqid != 0)
41401 + {
41402 + p_Manip->reassmParams.ip.nonConsistentSpFqid =
41403 + reassmManipParams.nonConsistentSpFqid;
41404 + }
41405 +#endif /* (DPAA_VERSION >= 11) */
41406 +
41407 + /* Creates and initializes the IP Reassembly common parameter table */
41408 + CreateReassCommonTable(p_Manip);
41409 +
41410 + /* Creation of IPv4 reassembly manipulation */
41411 + if ((p_Manip->reassmParams.hdr == HEADER_TYPE_IPv6)
41412 + || (p_Manip->reassmParams.hdr == HEADER_TYPE_IPv4))
41413 + {
41414 + res = SetIpv4ReassmManip(p_Manip);
41415 + if (res != E_OK)
41416 + return res;
41417 + }
41418 +
41419 + /* Creation of IPv6 reassembly manipulation */
41420 + if (p_Manip->reassmParams.hdr == HEADER_TYPE_IPv6)
41421 + {
41422 + res = SetIpv6ReassmManip(p_Manip);
41423 + if (res != E_OK)
41424 + return res;
41425 + }
41426 +
41427 + return E_OK;
41428 +}
41429 +
41430 +static void setIpReassmSchemeParams(t_FmPcd* p_FmPcd,
41431 + t_FmPcdKgSchemeParams *p_Scheme,
41432 + t_Handle h_CcTree, bool ipv4,
41433 + uint8_t groupId)
41434 +{
41435 + uint32_t j;
41436 + uint8_t res;
41437 +
41438 + /* Configures scheme's network environment parameters */
41439 + p_Scheme->netEnvParams.numOfDistinctionUnits = 2;
41440 + if (ipv4)
41441 + res = FmPcdNetEnvGetUnitId(
41442 + p_FmPcd, FmPcdGetNetEnvId(p_Scheme->netEnvParams.h_NetEnv),
41443 + HEADER_TYPE_IPv4, FALSE, 0);
41444 + else
41445 + res = FmPcdNetEnvGetUnitId(
41446 + p_FmPcd, FmPcdGetNetEnvId(p_Scheme->netEnvParams.h_NetEnv),
41447 + HEADER_TYPE_IPv6, FALSE, 0);
41448 + ASSERT_COND(res != FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS);
41449 + p_Scheme->netEnvParams.unitIds[0] = res;
41450 +
41451 + res = FmPcdNetEnvGetUnitId(
41452 + p_FmPcd, FmPcdGetNetEnvId(p_Scheme->netEnvParams.h_NetEnv),
41453 + HEADER_TYPE_USER_DEFINED_SHIM2, FALSE, 0);
41454 + ASSERT_COND(res != FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS);
41455 + p_Scheme->netEnvParams.unitIds[1] = res;
41456 +
41457 + /* Configures scheme's next engine parameters*/
41458 + p_Scheme->nextEngine = e_FM_PCD_CC;
41459 + p_Scheme->kgNextEngineParams.cc.h_CcTree = h_CcTree;
41460 + p_Scheme->kgNextEngineParams.cc.grpId = groupId;
41461 + p_Scheme->useHash = TRUE;
41462 +
41463 + /* Configures scheme's key*/
41464 + if (ipv4 == TRUE)
41465 + {
41466 + p_Scheme->keyExtractAndHashParams.numOfUsedExtracts = 4;
41467 + p_Scheme->keyExtractAndHashParams.extractArray[0].type =
41468 + e_FM_PCD_EXTRACT_BY_HDR;
41469 + p_Scheme->keyExtractAndHashParams.extractArray[0].extractByHdr.type =
41470 + e_FM_PCD_EXTRACT_FULL_FIELD;
41471 + p_Scheme->keyExtractAndHashParams.extractArray[0].extractByHdr.hdr =
41472 + HEADER_TYPE_IPv4;
41473 + p_Scheme->keyExtractAndHashParams.extractArray[0].extractByHdr.extractByHdrType.fullField.ipv4 =
41474 + NET_HEADER_FIELD_IPv4_DST_IP;
41475 + p_Scheme->keyExtractAndHashParams.extractArray[1].type =
41476 + e_FM_PCD_EXTRACT_BY_HDR;
41477 + p_Scheme->keyExtractAndHashParams.extractArray[1].extractByHdr.type =
41478 + e_FM_PCD_EXTRACT_FULL_FIELD;
41479 + p_Scheme->keyExtractAndHashParams.extractArray[1].extractByHdr.hdr =
41480 + HEADER_TYPE_IPv4;
41481 + p_Scheme->keyExtractAndHashParams.extractArray[1].extractByHdr.extractByHdrType.fullField.ipv4 =
41482 + NET_HEADER_FIELD_IPv4_SRC_IP;
41483 + p_Scheme->keyExtractAndHashParams.extractArray[2].type =
41484 + e_FM_PCD_EXTRACT_BY_HDR;
41485 + p_Scheme->keyExtractAndHashParams.extractArray[2].extractByHdr.type =
41486 + e_FM_PCD_EXTRACT_FULL_FIELD;
41487 + p_Scheme->keyExtractAndHashParams.extractArray[2].extractByHdr.hdr =
41488 + HEADER_TYPE_IPv4;
41489 + p_Scheme->keyExtractAndHashParams.extractArray[2].extractByHdr.extractByHdrType.fullField.ipv4 =
41490 + NET_HEADER_FIELD_IPv4_PROTO;
41491 + p_Scheme->keyExtractAndHashParams.extractArray[3].type =
41492 + e_FM_PCD_EXTRACT_BY_HDR;
41493 + p_Scheme->keyExtractAndHashParams.extractArray[3].extractByHdr.hdr =
41494 + HEADER_TYPE_IPv4;
41495 + p_Scheme->keyExtractAndHashParams.extractArray[3].extractByHdr.type =
41496 + e_FM_PCD_EXTRACT_FROM_HDR;
41497 + p_Scheme->keyExtractAndHashParams.extractArray[3].extractByHdr.ignoreProtocolValidation =
41498 + FALSE;
41499 + p_Scheme->keyExtractAndHashParams.extractArray[3].extractByHdr.extractByHdrType.fromHdr.size =
41500 + 2;
41501 + p_Scheme->keyExtractAndHashParams.extractArray[3].extractByHdr.extractByHdrType.fromHdr.offset =
41502 + 4;
41503 + }
41504 + else /* IPv6 */
41505 + {
41506 + p_Scheme->keyExtractAndHashParams.numOfUsedExtracts = 3;
41507 + p_Scheme->keyExtractAndHashParams.extractArray[0].type =
41508 + e_FM_PCD_EXTRACT_BY_HDR;
41509 + p_Scheme->keyExtractAndHashParams.extractArray[0].extractByHdr.type =
41510 + e_FM_PCD_EXTRACT_FULL_FIELD;
41511 + p_Scheme->keyExtractAndHashParams.extractArray[0].extractByHdr.hdr =
41512 + HEADER_TYPE_IPv6;
41513 + p_Scheme->keyExtractAndHashParams.extractArray[0].extractByHdr.extractByHdrType.fullField.ipv6 =
41514 + NET_HEADER_FIELD_IPv6_DST_IP;
41515 + p_Scheme->keyExtractAndHashParams.extractArray[1].type =
41516 + e_FM_PCD_EXTRACT_BY_HDR;
41517 + p_Scheme->keyExtractAndHashParams.extractArray[1].extractByHdr.type =
41518 + e_FM_PCD_EXTRACT_FULL_FIELD;
41519 + p_Scheme->keyExtractAndHashParams.extractArray[1].extractByHdr.hdr =
41520 + HEADER_TYPE_IPv6;
41521 + p_Scheme->keyExtractAndHashParams.extractArray[1].extractByHdr.extractByHdrType.fullField.ipv6 =
41522 + NET_HEADER_FIELD_IPv6_SRC_IP;
41523 + p_Scheme->keyExtractAndHashParams.extractArray[2].type =
41524 + e_FM_PCD_EXTRACT_BY_HDR;
41525 + p_Scheme->keyExtractAndHashParams.extractArray[2].extractByHdr.hdr =
41526 + HEADER_TYPE_USER_DEFINED_SHIM2;
41527 + p_Scheme->keyExtractAndHashParams.extractArray[2].extractByHdr.type =
41528 + e_FM_PCD_EXTRACT_FROM_HDR;
41529 + p_Scheme->keyExtractAndHashParams.extractArray[2].extractByHdr.extractByHdrType.fromHdr.size =
41530 + 4;
41531 + p_Scheme->keyExtractAndHashParams.extractArray[2].extractByHdr.extractByHdrType.fromHdr.offset =
41532 + 4;
41533 + p_Scheme->keyExtractAndHashParams.extractArray[2].extractByHdr.ignoreProtocolValidation =
41534 + TRUE;
41535 + }
41536 +
41537 + p_Scheme->keyExtractAndHashParams.privateDflt0 = 0x01020304;
41538 + p_Scheme->keyExtractAndHashParams.privateDflt1 = 0x11121314;
41539 + p_Scheme->keyExtractAndHashParams.numOfUsedDflts =
41540 + FM_PCD_KG_NUM_OF_DEFAULT_GROUPS;
41541 + for (j = 0; j < FM_PCD_KG_NUM_OF_DEFAULT_GROUPS; j++)
41542 + {
41543 + p_Scheme->keyExtractAndHashParams.dflts[j].type =
41544 + (e_FmPcdKgKnownFieldsDfltTypes)j; /* all types */
41545 + p_Scheme->keyExtractAndHashParams.dflts[j].dfltSelect =
41546 + e_FM_PCD_KG_DFLT_GBL_0;
41547 + }
41548 +}
41549 +
41550 +static t_Error IpReassemblyStats(t_FmPcdManip *p_Manip,
41551 + t_FmPcdManipReassemIpStats *p_Stats)
41552 +{
41553 + ASSERT_COND(p_Manip);
41554 + ASSERT_COND(p_Stats);
41555 + ASSERT_COND(p_Manip->reassmParams.p_ReassCommonTbl);
41556 +
41557 + p_Stats->timeout =
41558 + GET_UINT32(p_Manip->reassmParams.p_ReassCommonTbl->totalTimeOutCounter);
41559 + p_Stats->rfdPoolBusy =
41560 + GET_UINT32(p_Manip->reassmParams.p_ReassCommonTbl->totalRfdPoolBusyCounter);
41561 + p_Stats->internalBufferBusy =
41562 + GET_UINT32(p_Manip->reassmParams.p_ReassCommonTbl->totalInternalBufferBusy);
41563 + p_Stats->externalBufferBusy =
41564 + GET_UINT32(p_Manip->reassmParams.p_ReassCommonTbl->totalExternalBufferBusy);
41565 + p_Stats->sgFragments =
41566 + GET_UINT32(p_Manip->reassmParams.p_ReassCommonTbl->totalSgFragmentCounter);
41567 + p_Stats->dmaSemaphoreDepletion =
41568 + GET_UINT32(p_Manip->reassmParams.p_ReassCommonTbl->totalDmaSemaphoreDepletionCounter);
41569 +#if (DPAA_VERSION >= 11)
41570 + p_Stats->nonConsistentSp =
41571 + GET_UINT32(p_Manip->reassmParams.p_ReassCommonTbl->totalNCSPCounter);
41572 +#endif /* (DPAA_VERSION >= 11) */
41573 +
41574 + if (p_Manip->reassmParams.ip.p_Ipv4ReassTbl)
41575 + {
41576 + p_Stats->specificHdrStatistics[0].successfullyReassembled =
41577 + GET_UINT32(p_Manip->reassmParams.ip.p_Ipv4ReassTbl->totalSuccessfullyReasmFramesCounter);
41578 + p_Stats->specificHdrStatistics[0].validFragments =
41579 + GET_UINT32(p_Manip->reassmParams.ip.p_Ipv4ReassTbl->totalValidFragmentCounter);
41580 + p_Stats->specificHdrStatistics[0].processedFragments =
41581 + GET_UINT32(p_Manip->reassmParams.ip.p_Ipv4ReassTbl->totalProcessedFragCounter);
41582 + p_Stats->specificHdrStatistics[0].malformedFragments =
41583 + GET_UINT32(p_Manip->reassmParams.ip.p_Ipv4ReassTbl->totalMalformdFragCounter);
41584 + p_Stats->specificHdrStatistics[0].autoLearnBusy =
41585 + GET_UINT32(p_Manip->reassmParams.ip.p_Ipv4ReassTbl->totalSetBusyCounter);
41586 + p_Stats->specificHdrStatistics[0].discardedFragments =
41587 + GET_UINT32(p_Manip->reassmParams.ip.p_Ipv4ReassTbl->totalDiscardedFragsCounter);
41588 + p_Stats->specificHdrStatistics[0].moreThan16Fragments =
41589 + GET_UINT32(p_Manip->reassmParams.ip.p_Ipv4ReassTbl->totalMoreThan16FramesCounter);
41590 + }
41591 + if (p_Manip->reassmParams.ip.p_Ipv6ReassTbl)
41592 + {
41593 + p_Stats->specificHdrStatistics[1].successfullyReassembled =
41594 + GET_UINT32(p_Manip->reassmParams.ip.p_Ipv6ReassTbl->totalSuccessfullyReasmFramesCounter);
41595 + p_Stats->specificHdrStatistics[1].validFragments =
41596 + GET_UINT32(p_Manip->reassmParams.ip.p_Ipv6ReassTbl->totalValidFragmentCounter);
41597 + p_Stats->specificHdrStatistics[1].processedFragments =
41598 + GET_UINT32(p_Manip->reassmParams.ip.p_Ipv6ReassTbl->totalProcessedFragCounter);
41599 + p_Stats->specificHdrStatistics[1].malformedFragments =
41600 + GET_UINT32(p_Manip->reassmParams.ip.p_Ipv6ReassTbl->totalMalformdFragCounter);
41601 + p_Stats->specificHdrStatistics[1].autoLearnBusy =
41602 + GET_UINT32(p_Manip->reassmParams.ip.p_Ipv6ReassTbl->totalSetBusyCounter);
41603 + p_Stats->specificHdrStatistics[1].discardedFragments =
41604 + GET_UINT32(p_Manip->reassmParams.ip.p_Ipv6ReassTbl->totalDiscardedFragsCounter);
41605 + p_Stats->specificHdrStatistics[1].moreThan16Fragments =
41606 + GET_UINT32(p_Manip->reassmParams.ip.p_Ipv6ReassTbl->totalMoreThan16FramesCounter);
41607 + }
41608 + return E_OK;
41609 +}
41610 +
41611 +static t_Error IpFragmentationStats(t_FmPcdManip *p_Manip,
41612 + t_FmPcdManipFragIpStats *p_Stats)
41613 +{
41614 + t_AdOfTypeContLookup *p_Ad;
41615 +
41616 + ASSERT_COND(p_Manip);
41617 + ASSERT_COND(p_Stats);
41618 + ASSERT_COND(p_Manip->h_Ad);
41619 + ASSERT_COND(p_Manip->fragParams.p_Frag);
41620 +
41621 + p_Ad = (t_AdOfTypeContLookup *)p_Manip->h_Ad;
41622 +
41623 + p_Stats->totalFrames = GET_UINT32(p_Ad->gmask);
41624 + p_Stats->fragmentedFrames = GET_UINT32(p_Manip->fragParams.p_Frag->ccAdBase)
41625 + & 0x00ffffff;
41626 + p_Stats->generatedFragments =
41627 + GET_UINT32(p_Manip->fragParams.p_Frag->matchTblPtr);
41628 +
41629 + return E_OK;
41630 +}
41631 +
41632 +static t_Error IpFragmentation(t_FmPcdManipFragIpParams *p_ManipParams,
41633 + t_FmPcdManip *p_Manip)
41634 +{
41635 + uint32_t pcAndOffsetsReg = 0, ccAdBaseReg = 0, gmaskReg = 0;
41636 + t_FmPcd *p_FmPcd;
41637 +#if (DPAA_VERSION == 10)
41638 + t_Error err = E_OK;
41639 +#endif /* (DPAA_VERSION == 10) */
41640 +
41641 + SANITY_CHECK_RETURN_ERROR(p_Manip->h_Ad, E_INVALID_HANDLE);
41642 + SANITY_CHECK_RETURN_ERROR(p_ManipParams->sizeForFragmentation != 0xFFFF,
41643 + E_INVALID_VALUE);
41644 +
41645 + p_FmPcd = p_Manip->h_FmPcd;
41646 + /* Allocation of fragmentation Action Descriptor */
41647 + p_Manip->fragParams.p_Frag = (t_AdOfTypeContLookup *)FM_MURAM_AllocMem(
41648 + p_FmPcd->h_FmMuram, FM_PCD_CC_AD_ENTRY_SIZE,
41649 + FM_PCD_CC_AD_TABLE_ALIGN);
41650 + if (!p_Manip->fragParams.p_Frag)
41651 + RETURN_ERROR(MAJOR, E_NO_MEMORY,
41652 + ("MURAM alloc for Fragmentation table descriptor"));
41653 + MemSet8(p_Manip->fragParams.p_Frag, 0, FM_PCD_CC_AD_ENTRY_SIZE);
41654 +
41655 + /* Prepare the third Ad register (pcAndOffsets)- OperationCode */
41656 + pcAndOffsetsReg = (uint32_t)HMAN_OC_IP_FRAGMENTATION;
41657 +
41658 + /* Prepare the first Ad register (ccAdBase) - Don't frag action and Action descriptor type*/
41659 + ccAdBaseReg = FM_PCD_AD_CONT_LOOKUP_TYPE;
41660 + ccAdBaseReg |= (p_ManipParams->dontFragAction
41661 + << FM_PCD_MANIP_IP_FRAG_DF_SHIFT);
41662 +
41663 +
41664 + /* Set Scatter/Gather BPid */
41665 + if (p_ManipParams->sgBpidEn)
41666 + {
41667 + ccAdBaseReg |= FM_PCD_MANIP_IP_FRAG_SG_BDID_EN;
41668 + pcAndOffsetsReg |= ((p_ManipParams->sgBpid
41669 + << FM_PCD_MANIP_IP_FRAG_SG_BDID_SHIFT)
41670 + & FM_PCD_MANIP_IP_FRAG_SG_BDID_MASK);
41671 + }
41672 +
41673 + /* Prepare the first Ad register (gmask) - scratch buffer pool id and Pointer to fragment ID */
41674 + gmaskReg = (uint32_t)(XX_VirtToPhys(UINT_TO_PTR(p_FmPcd->ipv6FrameIdAddr))
41675 + - p_FmPcd->physicalMuramBase);
41676 +#if (DPAA_VERSION == 10)
41677 + gmaskReg |= p_ManipParams->scratchBpid << FM_PCD_MANIP_IP_FRAG_SCRATCH_BPID;
41678 +#else
41679 + gmaskReg |= (0xFF) << FM_PCD_MANIP_IP_FRAG_SCRATCH_BPID;
41680 +#endif /* (DPAA_VERSION == 10) */
41681 +
41682 + /* Set all Ad registers */
41683 + WRITE_UINT32(p_Manip->fragParams.p_Frag->pcAndOffsets, pcAndOffsetsReg);
41684 + WRITE_UINT32(p_Manip->fragParams.p_Frag->ccAdBase, ccAdBaseReg);
41685 + WRITE_UINT32(p_Manip->fragParams.p_Frag->gmask, gmaskReg);
41686 +
41687 + /* Saves user's fragmentation manipulation parameters */
41688 + p_Manip->frag = TRUE;
41689 + p_Manip->sizeForFragmentation = p_ManipParams->sizeForFragmentation;
41690 +
41691 +#if (DPAA_VERSION == 10)
41692 + p_Manip->fragParams.scratchBpid = p_ManipParams->scratchBpid;
41693 +
41694 + /* scratch buffer pool initialization */
41695 + if ((err = FmPcdFragHcScratchPoolFill((t_Handle)p_FmPcd, p_ManipParams->scratchBpid)) != E_OK)
41696 + {
41697 + FM_MURAM_FreeMem(p_FmPcd->h_FmMuram, p_Manip->fragParams.p_Frag);
41698 + p_Manip->fragParams.p_Frag = NULL;
41699 + RETURN_ERROR(MAJOR, err, NO_MSG);
41700 + }
41701 +#endif /* (DPAA_VERSION == 10) */
41702 +
41703 + return E_OK;
41704 +}
41705 +
41706 +static t_Error IPManip(t_FmPcdManip *p_Manip)
41707 +{
41708 + t_Error err = E_OK;
41709 + t_FmPcd *p_FmPcd;
41710 + t_AdOfTypeContLookup *p_Ad;
41711 + uint32_t tmpReg32 = 0, tmpRegNia = 0;
41712 +
41713 + SANITY_CHECK_RETURN_ERROR(p_Manip, E_INVALID_HANDLE);
41714 + p_FmPcd = p_Manip->h_FmPcd;
41715 + SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);
41716 +
41717 + p_Ad = (t_AdOfTypeContLookup *)p_Manip->h_Ad;
41718 +
41719 + tmpReg32 = FM_PCD_MANIP_IP_NO_FRAGMENTATION;
41720 + if (p_Manip->frag == TRUE)
41721 + {
41722 + tmpRegNia = (uint32_t)(XX_VirtToPhys(p_Manip->fragParams.p_Frag)
41723 + - (p_FmPcd->physicalMuramBase));
41724 + tmpReg32 = (uint32_t)p_Manip->sizeForFragmentation
41725 + << FM_PCD_MANIP_IP_MTU_SHIFT;
41726 + }
41727 +
41728 + tmpRegNia |= FM_PCD_AD_CONT_LOOKUP_TYPE;
41729 + tmpReg32 |= HMAN_OC_IP_MANIP;
41730 +
41731 +#if (DPAA_VERSION >= 11)
41732 + tmpRegNia |= FM_PCD_MANIP_IP_CNIA;
41733 +#endif /* (DPAA_VERSION >= 11) */
41734 +
41735 + WRITE_UINT32(p_Ad->pcAndOffsets, tmpReg32);
41736 + WRITE_UINT32(p_Ad->ccAdBase, tmpRegNia);
41737 + WRITE_UINT32(p_Ad->gmask, 0);
41738 + /* Total frame counter - MUST be initialized to zero.*/
41739 +
41740 + return err;
41741 +}
41742 +
41743 +static t_Error UpdateInitIpFrag(t_Handle h_FmPcd, t_Handle h_PcdParams,
41744 + t_Handle h_FmPort, t_FmPcdManip *p_Manip,
41745 + t_Handle h_Ad, bool validate)
41746 +{
41747 + t_FmPortGetSetCcParams fmPortGetSetCcParams;
41748 + t_Error err;
41749 +
41750 + SANITY_CHECK_RETURN_ERROR(p_Manip, E_INVALID_HANDLE);
41751 + SANITY_CHECK_RETURN_ERROR((p_Manip->opcode == HMAN_OC_IP_FRAGMENTATION),
41752 + E_INVALID_STATE);
41753 + SANITY_CHECK_RETURN_ERROR(h_FmPcd, E_INVALID_HANDLE);
41754 + SANITY_CHECK_RETURN_ERROR(h_FmPort, E_INVALID_HANDLE);
41755 +
41756 + UNUSED(h_FmPcd);
41757 + UNUSED(h_Ad);
41758 + UNUSED(h_PcdParams);
41759 + UNUSED(validate);
41760 + UNUSED(p_Manip);
41761 +
41762 + fmPortGetSetCcParams.setCcParams.type = 0;
41763 + fmPortGetSetCcParams.getCcParams.type = MANIP_EXTRA_SPACE;
41764 + if ((err = FmPortGetSetCcParams(h_FmPort, &fmPortGetSetCcParams)) != E_OK)
41765 + RETURN_ERROR(MAJOR, err, NO_MSG);
41766 +
41767 + if (!fmPortGetSetCcParams.getCcParams.internalBufferOffset)
41768 + DBG(WARNING, ("manipExtraSpace must be larger than '0'"));
41769 +
41770 + return E_OK;
41771 +}
41772 +
41773 +static t_Error IPSecManip(t_FmPcdManipParams *p_ManipParams,
41774 + t_FmPcdManip *p_Manip)
41775 +{
41776 + t_AdOfTypeContLookup *p_Ad;
41777 + t_FmPcdManipSpecialOffloadIPSecParams *p_IPSecParams;
41778 + t_Error err = E_OK;
41779 + uint32_t tmpReg32 = 0;
41780 + uint32_t power;
41781 +
41782 + SANITY_CHECK_RETURN_ERROR(p_Manip, E_INVALID_HANDLE);
41783 + SANITY_CHECK_RETURN_ERROR(p_ManipParams, E_INVALID_HANDLE);
41784 +
41785 + p_IPSecParams = &p_ManipParams->u.specialOffload.u.ipsec;
41786 +
41787 + SANITY_CHECK_RETURN_ERROR(
41788 + !p_IPSecParams->variableIpHdrLen || p_IPSecParams->decryption,
41789 + E_INVALID_VALUE);
41790 + SANITY_CHECK_RETURN_ERROR(
41791 + !p_IPSecParams->variableIpVersion || !p_IPSecParams->decryption,
41792 + E_INVALID_VALUE);
41793 + SANITY_CHECK_RETURN_ERROR(
41794 + !p_IPSecParams->variableIpVersion || p_IPSecParams->outerIPHdrLen,
41795 + E_INVALID_VALUE);
41796 + SANITY_CHECK_RETURN_ERROR(
41797 + !p_IPSecParams->arwSize || p_IPSecParams->arwAddr,
41798 + E_INVALID_VALUE);
41799 + SANITY_CHECK_RETURN_ERROR(
41800 + !p_IPSecParams->arwSize || p_IPSecParams->decryption,
41801 + E_INVALID_VALUE);
41802 + SANITY_CHECK_RETURN_ERROR((p_IPSecParams->arwSize % 16) == 0, E_INVALID_VALUE);
41803 +
41804 + p_Ad = (t_AdOfTypeContLookup *)p_Manip->h_Ad;
41805 +
41806 + tmpReg32 |= FM_PCD_AD_CONT_LOOKUP_TYPE;
41807 + tmpReg32 |= (p_IPSecParams->decryption) ? FM_PCD_MANIP_IPSEC_DEC : 0;
41808 + tmpReg32 |= (p_IPSecParams->ecnCopy) ? FM_PCD_MANIP_IPSEC_ECN_EN : 0;
41809 + tmpReg32 |= (p_IPSecParams->dscpCopy) ? FM_PCD_MANIP_IPSEC_DSCP_EN : 0;
41810 + tmpReg32 |=
41811 + (p_IPSecParams->variableIpHdrLen) ? FM_PCD_MANIP_IPSEC_VIPL_EN : 0;
41812 + tmpReg32 |=
41813 + (p_IPSecParams->variableIpVersion) ? FM_PCD_MANIP_IPSEC_VIPV_EN : 0;
41814 + if (p_IPSecParams->arwSize)
41815 + tmpReg32 |= (uint32_t)((XX_VirtToPhys(UINT_TO_PTR(p_IPSecParams->arwAddr))-FM_MM_MURAM)
41816 + & (FM_MURAM_SIZE-1));
41817 + WRITE_UINT32(p_Ad->ccAdBase, tmpReg32);
41818 +
41819 + tmpReg32 = 0;
41820 + if (p_IPSecParams->arwSize) {
41821 + NEXT_POWER_OF_2((p_IPSecParams->arwSize + 32), power);
41822 + LOG2(power, power);
41823 + tmpReg32 = (p_IPSecParams->arwSize | (power - 5)) << FM_PCD_MANIP_IPSEC_ARW_SIZE_SHIFT;
41824 + }
41825 +
41826 + if (p_ManipParams->h_NextManip)
41827 + tmpReg32 |=
41828 + (uint32_t)(XX_VirtToPhys(((t_FmPcdManip *)p_ManipParams->h_NextManip)->h_Ad)-
41829 + (((t_FmPcd *)p_Manip->h_FmPcd)->physicalMuramBase)) >> 4;
41830 + WRITE_UINT32(p_Ad->matchTblPtr, tmpReg32);
41831 +
41832 + tmpReg32 = HMAN_OC_IPSEC_MANIP;
41833 + tmpReg32 |= p_IPSecParams->outerIPHdrLen
41834 + << FM_PCD_MANIP_IPSEC_IP_HDR_LEN_SHIFT;
41835 + if (p_ManipParams->h_NextManip)
41836 + tmpReg32 |= FM_PCD_MANIP_IPSEC_NADEN;
41837 + WRITE_UINT32(p_Ad->pcAndOffsets, tmpReg32);
41838 +
41839 + return err;
41840 +}
41841 +
41842 +static t_Error SetCapwapReassmManip(t_FmPcdManip *p_Manip)
41843 +{
41844 + t_FmPcd *p_FmPcd = (t_FmPcd *)p_Manip->h_FmPcd;
41845 +
41846 + /* Allocation if CAPWAP Action descriptor */
41847 + p_Manip->reassmParams.capwap.h_Ad = (t_Handle)XX_MallocSmart(
41848 + FM_PCD_CC_AD_ENTRY_SIZE, p_Manip->reassmParams.dataMemId,
41849 + FM_PCD_CC_AD_TABLE_ALIGN);
41850 + if (!p_Manip->reassmParams.capwap.h_Ad)
41851 + {
41852 + ReleaseManipHandler(p_Manip, p_FmPcd);
41853 + RETURN_ERROR(MAJOR, E_NO_MEMORY,
41854 + ("Allocation of CAPWAP table descriptor"));
41855 + }
41856 +
41857 + memset(p_Manip->reassmParams.capwap.h_Ad, 0, FM_PCD_CC_AD_ENTRY_SIZE);
41858 +
41859 + /* Fill reassembly manipulation parameter in the Reassembly Action Descriptor */
41860 + return FillReassmManipParams(p_Manip, HEADER_TYPE_CAPWAP);
41861 +}
41862 +
41863 +static void setCapwapReassmSchemeParams(t_FmPcd* p_FmPcd,
41864 + t_FmPcdKgSchemeParams *p_Scheme,
41865 + t_Handle h_CcTree, uint8_t groupId)
41866 +{
41867 + uint8_t res;
41868 +
41869 + /* Configures scheme's network environment parameters */
41870 + p_Scheme->netEnvParams.numOfDistinctionUnits = 1;
41871 + res = FmPcdNetEnvGetUnitId(
41872 + p_FmPcd, FmPcdGetNetEnvId(p_Scheme->netEnvParams.h_NetEnv),
41873 + HEADER_TYPE_USER_DEFINED_SHIM2, FALSE, 0);
41874 + ASSERT_COND(res != FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS);
41875 + p_Scheme->netEnvParams.unitIds[0] = res;
41876 +
41877 + /* Configures scheme's next engine parameters*/
41878 + p_Scheme->nextEngine = e_FM_PCD_CC;
41879 + p_Scheme->kgNextEngineParams.cc.h_CcTree = h_CcTree;
41880 + p_Scheme->kgNextEngineParams.cc.grpId = groupId;
41881 + p_Scheme->useHash = TRUE;
41882 +
41883 + /* Configures scheme's key*/
41884 + p_Scheme->keyExtractAndHashParams.numOfUsedExtracts = 2;
41885 + p_Scheme->keyExtractAndHashParams.extractArray[0].type =
41886 + e_FM_PCD_EXTRACT_NON_HDR;
41887 + p_Scheme->keyExtractAndHashParams.extractArray[0].extractNonHdr.src =
41888 + e_FM_PCD_EXTRACT_FROM_PARSE_RESULT;
41889 + p_Scheme->keyExtractAndHashParams.extractArray[0].extractNonHdr.action =
41890 + e_FM_PCD_ACTION_NONE;
41891 + p_Scheme->keyExtractAndHashParams.extractArray[0].extractNonHdr.offset = 20;
41892 + p_Scheme->keyExtractAndHashParams.extractArray[0].extractNonHdr.size = 4;
41893 + p_Scheme->keyExtractAndHashParams.extractArray[1].type =
41894 + e_FM_PCD_EXTRACT_NON_HDR;
41895 + p_Scheme->keyExtractAndHashParams.extractArray[1].extractNonHdr.src =
41896 + e_FM_PCD_EXTRACT_FROM_DFLT_VALUE;
41897 + p_Scheme->keyExtractAndHashParams.extractArray[1].extractNonHdr.action =
41898 + e_FM_PCD_ACTION_NONE;
41899 + p_Scheme->keyExtractAndHashParams.extractArray[1].extractNonHdr.offset = 0;
41900 + p_Scheme->keyExtractAndHashParams.extractArray[1].extractNonHdr.size = 1;
41901 +
41902 + p_Scheme->keyExtractAndHashParams.privateDflt0 = 0x0;
41903 + p_Scheme->keyExtractAndHashParams.privateDflt1 = 0x0;
41904 + p_Scheme->keyExtractAndHashParams.numOfUsedDflts = 1;
41905 + p_Scheme->keyExtractAndHashParams.dflts[0].type = e_FM_PCD_KG_GENERIC_NOT_FROM_DATA;
41906 + p_Scheme->keyExtractAndHashParams.dflts[0].dfltSelect = e_FM_PCD_KG_DFLT_PRIVATE_0;
41907 +}
41908 +
41909 +#if (DPAA_VERSION >= 11)
41910 +static t_Error CapwapReassemblyStats(t_FmPcdManip *p_Manip,
41911 + t_FmPcdManipReassemCapwapStats *p_Stats)
41912 +{
41913 + ASSERT_COND(p_Manip);
41914 + ASSERT_COND(p_Stats);
41915 + ASSERT_COND(p_Manip->reassmParams.p_ReassCommonTbl);
41916 +
41917 + p_Stats->timeout =
41918 + GET_UINT32(p_Manip->reassmParams.p_ReassCommonTbl->totalTimeOutCounter);
41919 + p_Stats->rfdPoolBusy =
41920 + GET_UINT32(p_Manip->reassmParams.p_ReassCommonTbl->totalRfdPoolBusyCounter);
41921 + p_Stats->internalBufferBusy =
41922 + GET_UINT32(p_Manip->reassmParams.p_ReassCommonTbl->totalInternalBufferBusy);
41923 + p_Stats->externalBufferBusy =
41924 + GET_UINT32(p_Manip->reassmParams.p_ReassCommonTbl->totalExternalBufferBusy);
41925 + p_Stats->sgFragments =
41926 + GET_UINT32(p_Manip->reassmParams.p_ReassCommonTbl->totalSgFragmentCounter);
41927 + p_Stats->dmaSemaphoreDepletion =
41928 + GET_UINT32(p_Manip->reassmParams.p_ReassCommonTbl->totalDmaSemaphoreDepletionCounter);
41929 + p_Stats->exceedMaxReassemblyFrameLen =
41930 + GET_UINT32(p_Manip->reassmParams.p_ReassCommonTbl->totalNCSPCounter);
41931 +
41932 + p_Stats->successfullyReassembled =
41933 + GET_UINT32(p_Manip->reassmParams.capwap.p_ReassTbl->totalSuccessfullyReasmFramesCounter);
41934 + p_Stats->validFragments =
41935 + GET_UINT32(p_Manip->reassmParams.capwap.p_ReassTbl->totalValidFragmentCounter);
41936 + p_Stats->processedFragments =
41937 + GET_UINT32(p_Manip->reassmParams.capwap.p_ReassTbl->totalProcessedFragCounter);
41938 + p_Stats->malformedFragments =
41939 + GET_UINT32(p_Manip->reassmParams.capwap.p_ReassTbl->totalMalformdFragCounter);
41940 + p_Stats->autoLearnBusy =
41941 + GET_UINT32(p_Manip->reassmParams.capwap.p_ReassTbl->totalSetBusyCounter);
41942 + p_Stats->discardedFragments =
41943 + GET_UINT32(p_Manip->reassmParams.capwap.p_ReassTbl->totalDiscardedFragsCounter);
41944 + p_Stats->moreThan16Fragments =
41945 + GET_UINT32(p_Manip->reassmParams.capwap.p_ReassTbl->totalMoreThan16FramesCounter);
41946 +
41947 + return E_OK;
41948 +}
41949 +
41950 +static t_Error CapwapFragmentationStats(t_FmPcdManip *p_Manip,
41951 + t_FmPcdManipFragCapwapStats *p_Stats)
41952 +{
41953 + t_AdOfTypeContLookup *p_Ad;
41954 +
41955 + ASSERT_COND(p_Manip);
41956 + ASSERT_COND(p_Stats);
41957 + ASSERT_COND(p_Manip->h_Ad);
41958 + ASSERT_COND(p_Manip->fragParams.p_Frag);
41959 +
41960 + p_Ad = (t_AdOfTypeContLookup *)p_Manip->h_Ad;
41961 +
41962 + p_Stats->totalFrames = GET_UINT32(p_Ad->gmask);
41963 +
41964 + return E_OK;
41965 +}
41966 +
41967 +static t_Error CapwapReassembly(t_FmPcdManipReassemParams *p_ManipReassmParams,
41968 + t_FmPcdManip *p_Manip)
41969 +{
41970 + uint32_t maxSetNumber = 10000;
41971 + t_FmPcdManipReassemCapwapParams reassmManipParams =
41972 + p_ManipReassmParams->u.capwapReassem;
41973 + t_Error res;
41974 +
41975 + SANITY_CHECK_RETURN_ERROR(p_Manip->h_FmPcd, E_INVALID_HANDLE);
41976 + SANITY_CHECK_RETURN_ERROR(((t_FmPcd *)p_Manip->h_FmPcd)->h_Hc,
41977 + E_INVALID_HANDLE);
41978 +
41979 + /* Check validation of user's parameter.*/
41980 + if ((reassmManipParams.timeoutThresholdForReassmProcess < 1000)
41981 + || (reassmManipParams.timeoutThresholdForReassmProcess > 8000000))
41982 + RETURN_ERROR(
41983 + MAJOR, E_INVALID_VALUE,
41984 + ("timeoutThresholdForReassmProcess should be 1msec - 8sec"));
41985 + /* It is recommended that the total number of entries in this table (number of sets * number of ways)
41986 + will be twice the number of frames that are expected to be reassembled simultaneously.*/
41987 + if (reassmManipParams.maxNumFramesInProcess
41988 + > (reassmManipParams.maxNumFramesInProcess * maxSetNumber / 2))
41989 + RETURN_ERROR(
41990 + MAJOR,
41991 + E_INVALID_VALUE,
41992 + ("maxNumFramesInProcess has to be less than (maximun set number * number of ways / 2)"));
41993 +
41994 + /* Saves user's reassembly manipulation parameters */
41995 + p_Manip->reassmParams.capwap.relativeSchemeId =
41996 + reassmManipParams.relativeSchemeId;
41997 + p_Manip->reassmParams.capwap.numOfFramesPerHashEntry =
41998 + reassmManipParams.numOfFramesPerHashEntry;
41999 + p_Manip->reassmParams.capwap.maxRessembledsSize =
42000 + reassmManipParams.maxReassembledFrameLength;
42001 + p_Manip->reassmParams.maxNumFramesInProcess =
42002 + reassmManipParams.maxNumFramesInProcess;
42003 + p_Manip->reassmParams.timeOutMode = reassmManipParams.timeOutMode;
42004 + p_Manip->reassmParams.fqidForTimeOutFrames =
42005 + reassmManipParams.fqidForTimeOutFrames;
42006 + p_Manip->reassmParams.timeoutThresholdForReassmProcess =
42007 + reassmManipParams.timeoutThresholdForReassmProcess;
42008 + p_Manip->reassmParams.dataMemId = reassmManipParams.dataMemId;
42009 + p_Manip->reassmParams.dataLiodnOffset = reassmManipParams.dataLiodnOffset;
42010 +
42011 + /* Creates and initializes the Reassembly common parameter table */
42012 + CreateReassCommonTable(p_Manip);
42013 +
42014 + res = SetCapwapReassmManip(p_Manip);
42015 + if (res != E_OK)
42016 + return res;
42017 +
42018 + return E_OK;
42019 +}
42020 +
42021 +static t_Error CapwapFragmentation(t_FmPcdManipFragCapwapParams *p_ManipParams,
42022 + t_FmPcdManip *p_Manip)
42023 +{
42024 + t_FmPcd *p_FmPcd;
42025 + t_AdOfTypeContLookup *p_Ad;
42026 + uint32_t pcAndOffsetsReg = 0, ccAdBaseReg = 0, gmaskReg = 0;
42027 + uint32_t tmpReg32 = 0, tmpRegNia = 0;
42028 +
42029 + SANITY_CHECK_RETURN_ERROR(p_Manip->h_Ad, E_INVALID_HANDLE);
42030 + SANITY_CHECK_RETURN_ERROR(p_ManipParams->sizeForFragmentation != 0xFFFF,
42031 + E_INVALID_VALUE);
42032 + p_FmPcd = p_Manip->h_FmPcd;
42033 + SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);
42034 +
42035 + /* Allocation of fragmentation Action Descriptor */
42036 + p_Manip->fragParams.p_Frag = (t_AdOfTypeContLookup *)FM_MURAM_AllocMem(
42037 + p_FmPcd->h_FmMuram, FM_PCD_CC_AD_ENTRY_SIZE,
42038 + FM_PCD_CC_AD_TABLE_ALIGN);
42039 + if (!p_Manip->fragParams.p_Frag)
42040 + RETURN_ERROR(MAJOR, E_NO_MEMORY,
42041 + ("MURAM alloc for Fragmentation table descriptor"));
42042 + MemSet8(p_Manip->fragParams.p_Frag, 0, FM_PCD_CC_AD_ENTRY_SIZE);
42043 +
42044 + /* Prepare the third Ad register (pcAndOffsets)- OperationCode */
42045 + pcAndOffsetsReg = (uint32_t)HMAN_OC_CAPWAP_FRAGMENTATION;
42046 +
42047 + /* Prepare the first Ad register (ccAdBase) - Don't frag action and Action descriptor type*/
42048 + ccAdBaseReg = FM_PCD_AD_CONT_LOOKUP_TYPE;
42049 + ccAdBaseReg |=
42050 + (p_ManipParams->compressModeEn) ? FM_PCD_MANIP_CAPWAP_FRAG_COMPRESS_EN :
42051 + 0;
42052 +
42053 + /* Set Scatter/Gather BPid */
42054 + if (p_ManipParams->sgBpidEn)
42055 + {
42056 + ccAdBaseReg |= FM_PCD_MANIP_CAPWAP_FRAG_SG_BDID_EN;
42057 + pcAndOffsetsReg |= ((p_ManipParams->sgBpid
42058 + << FM_PCD_MANIP_CAPWAP_FRAG_SG_BDID_SHIFT)
42059 + & FM_PCD_MANIP_CAPWAP_FRAG_SG_BDID_MASK);
42060 + }
42061 +
42062 + /* Prepare the first Ad register (gmask) - scratch buffer pool id and Pointer to fragment ID */
42063 + gmaskReg = (uint32_t)(XX_VirtToPhys(UINT_TO_PTR(p_FmPcd->capwapFrameIdAddr))
42064 + - p_FmPcd->physicalMuramBase);
42065 + gmaskReg |= (0xFF) << FM_PCD_MANIP_IP_FRAG_SCRATCH_BPID;
42066 +
42067 + /* Set all Ad registers */
42068 + WRITE_UINT32(p_Manip->fragParams.p_Frag->pcAndOffsets, pcAndOffsetsReg);
42069 + WRITE_UINT32(p_Manip->fragParams.p_Frag->ccAdBase, ccAdBaseReg);
42070 + WRITE_UINT32(p_Manip->fragParams.p_Frag->gmask, gmaskReg);
42071 +
42072 + /* Saves user's fragmentation manipulation parameters */
42073 + p_Manip->frag = TRUE;
42074 + p_Manip->sizeForFragmentation = p_ManipParams->sizeForFragmentation;
42075 +
42076 + p_Ad = (t_AdOfTypeContLookup *)p_Manip->h_Ad;
42077 +
42078 + tmpRegNia = (uint32_t)(XX_VirtToPhys(p_Manip->fragParams.p_Frag)
42079 + - (p_FmPcd->physicalMuramBase));
42080 + tmpReg32 = (uint32_t)p_Manip->sizeForFragmentation
42081 + << FM_PCD_MANIP_CAPWAP_FRAG_CHECK_MTU_SHIFT;
42082 +
42083 + tmpRegNia |= FM_PCD_AD_CONT_LOOKUP_TYPE;
42084 + tmpReg32 |= HMAN_OC_CAPWAP_FRAG_CHECK;
42085 +
42086 + tmpRegNia |= FM_PCD_MANIP_CAPWAP_FRAG_CHECK_CNIA;
42087 +
42088 + WRITE_UINT32(p_Ad->pcAndOffsets, tmpReg32);
42089 + WRITE_UINT32(p_Ad->ccAdBase, tmpRegNia);
42090 + WRITE_UINT32(p_Ad->gmask, 0);
42091 + /* Total frame counter - MUST be initialized to zero.*/
42092 +
42093 + return E_OK;
42094 +}
42095 +
42096 +static t_Error UpdateInitCapwapFrag(t_Handle h_FmPcd, t_Handle h_PcdParams,
42097 + t_Handle h_FmPort, t_FmPcdManip *p_Manip,
42098 + t_Handle h_Ad, bool validate)
42099 +{
42100 + t_FmPortGetSetCcParams fmPortGetSetCcParams;
42101 + t_Error err;
42102 +
42103 + SANITY_CHECK_RETURN_ERROR(p_Manip, E_INVALID_HANDLE);
42104 + SANITY_CHECK_RETURN_ERROR((p_Manip->opcode == HMAN_OC_CAPWAP_FRAGMENTATION),
42105 + E_INVALID_STATE);
42106 + SANITY_CHECK_RETURN_ERROR(h_FmPcd, E_INVALID_HANDLE);
42107 + SANITY_CHECK_RETURN_ERROR(h_FmPort, E_INVALID_HANDLE);
42108 +
42109 + UNUSED(h_FmPcd);
42110 + UNUSED(h_Ad);
42111 + UNUSED(h_PcdParams);
42112 + UNUSED(validate);
42113 + UNUSED(p_Manip);
42114 +
42115 + fmPortGetSetCcParams.setCcParams.type = 0;
42116 + fmPortGetSetCcParams.getCcParams.type = MANIP_EXTRA_SPACE;
42117 + if ((err = FmPortGetSetCcParams(h_FmPort, &fmPortGetSetCcParams)) != E_OK)
42118 + RETURN_ERROR(MAJOR, err, NO_MSG);
42119 +
42120 + if (!fmPortGetSetCcParams.getCcParams.internalBufferOffset)
42121 + DBG(WARNING, ("manipExtraSpace must be larger than '0'"));
42122 +
42123 + return E_OK;
42124 +}
42125 +
42126 +static t_Error CapwapManip(t_FmPcdManipParams *p_ManipParams,
42127 + t_FmPcdManip *p_Manip)
42128 +{
42129 + t_AdOfTypeContLookup *p_Ad;
42130 + t_FmPcdManipSpecialOffloadCapwapParams *p_Params;
42131 + t_Error err = E_OK;
42132 + uint32_t tmpReg32 = 0;
42133 +
42134 + SANITY_CHECK_RETURN_ERROR(p_Manip, E_INVALID_HANDLE);
42135 + SANITY_CHECK_RETURN_ERROR(p_ManipParams, E_INVALID_HANDLE);
42136 +
42137 + p_Params = &p_ManipParams->u.specialOffload.u.capwap;
42138 +
42139 + p_Ad = (t_AdOfTypeContLookup *)p_Manip->h_Ad;
42140 + tmpReg32 |= FM_PCD_AD_CONT_LOOKUP_TYPE;
42141 + tmpReg32 |= (p_Params->dtls) ? FM_PCD_MANIP_CAPWAP_DTLS : 0;
42142 + /* TODO - add 'qosSrc' */
42143 + WRITE_UINT32(p_Ad->ccAdBase, tmpReg32);
42144 +
42145 + tmpReg32 = HMAN_OC_CAPWAP_MANIP;
42146 + if (p_ManipParams->h_NextManip)
42147 + {
42148 + WRITE_UINT32(
42149 + p_Ad->matchTblPtr,
42150 + (uint32_t)(XX_VirtToPhys(((t_FmPcdManip *)p_ManipParams->h_NextManip)->h_Ad)- (((t_FmPcd *)p_Manip->h_FmPcd)->physicalMuramBase)) >> 4);
42151 +
42152 + tmpReg32 |= FM_PCD_MANIP_CAPWAP_NADEN;
42153 + }
42154 +
42155 + WRITE_UINT32(p_Ad->pcAndOffsets, tmpReg32);
42156 +
42157 + return err;
42158 +}
42159 +#endif /* (DPAA_VERSION >= 11) */
42160 +
42161 +static t_Handle ManipOrStatsSetNode(t_Handle h_FmPcd, t_Handle *p_Params,
42162 + bool stats)
42163 +{
42164 + t_FmPcdManip *p_Manip;
42165 + t_Error err;
42166 + t_FmPcd *p_FmPcd = (t_FmPcd *)h_FmPcd;
42167 +
42168 + p_Manip = (t_FmPcdManip*)XX_Malloc(sizeof(t_FmPcdManip));
42169 + if (!p_Manip)
42170 + {
42171 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("No memory"));
42172 + return NULL;
42173 + }
42174 + memset(p_Manip, 0, sizeof(t_FmPcdManip));
42175 +
42176 + p_Manip->type = ((t_FmPcdManipParams *)p_Params)->type;
42177 + memcpy((uint8_t*)&p_Manip->manipParams, p_Params,
42178 + sizeof(p_Manip->manipParams));
42179 +
42180 + if (!stats)
42181 + err = CheckManipParamsAndSetType(p_Manip,
42182 + (t_FmPcdManipParams *)p_Params);
42183 +#if (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10))
42184 + else
42185 + err = CheckStatsParamsAndSetType(p_Manip, (t_FmPcdStatsParams *)p_Params);
42186 +#else /* not (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10)) */
42187 + else
42188 + {
42189 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Statistics node!"));
42190 + XX_Free(p_Manip);
42191 + return NULL;
42192 + }
42193 +#endif /* (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10)) */
42194 + if (err)
42195 + {
42196 + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("Invalid header manipulation type"));
42197 + XX_Free(p_Manip);
42198 + return NULL;
42199 + }
42200 +
42201 + if ((p_Manip->opcode != HMAN_OC_IP_REASSEMBLY) && (p_Manip->opcode != HMAN_OC_CAPWAP_REASSEMBLY))
42202 + {
42203 + /* In Case of reassembly manipulation the reassembly action descriptor will
42204 + be defines later on */
42205 + if (p_Manip->muramAllocate)
42206 + {
42207 + p_Manip->h_Ad = (t_Handle)FM_MURAM_AllocMem(
42208 + p_FmPcd->h_FmMuram, FM_PCD_CC_AD_ENTRY_SIZE,
42209 + FM_PCD_CC_AD_TABLE_ALIGN);
42210 + if (!p_Manip->h_Ad)
42211 + {
42212 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("MURAM alloc for Manipulation action descriptor"));
42213 + ReleaseManipHandler(p_Manip, p_FmPcd);
42214 + XX_Free(p_Manip);
42215 + return NULL;
42216 + }
42217 +
42218 + MemSet8(p_Manip->h_Ad, 0, FM_PCD_CC_AD_ENTRY_SIZE);
42219 + }
42220 + else
42221 + {
42222 + p_Manip->h_Ad = (t_Handle)XX_Malloc(
42223 + FM_PCD_CC_AD_ENTRY_SIZE * sizeof(uint8_t));
42224 + if (!p_Manip->h_Ad)
42225 + {
42226 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("Allocation of Manipulation action descriptor"));
42227 + ReleaseManipHandler(p_Manip, p_FmPcd);
42228 + XX_Free(p_Manip);
42229 + return NULL;
42230 + }
42231 +
42232 + memset(p_Manip->h_Ad, 0, FM_PCD_CC_AD_ENTRY_SIZE * sizeof(uint8_t));
42233 + }
42234 + }
42235 +
42236 + p_Manip->h_FmPcd = h_FmPcd;
42237 +
42238 + return p_Manip;
42239 +}
42240 +
42241 +static void UpdateAdPtrOfNodesWhichPointsOnCrntMdfManip(
42242 + t_FmPcdManip *p_CrntMdfManip, t_List *h_NodesLst)
42243 +{
42244 + t_CcNodeInformation *p_CcNodeInformation;
42245 + t_FmPcdCcNode *p_NodePtrOnCurrentMdfManip = NULL;
42246 + t_List *p_Pos;
42247 + int i = 0;
42248 + t_Handle p_AdTablePtOnCrntCurrentMdfNode/*, p_AdTableNewModified*/;
42249 + t_CcNodeInformation ccNodeInfo;
42250 +
42251 + LIST_FOR_EACH(p_Pos, &p_CrntMdfManip->nodesLst)
42252 + {
42253 + p_CcNodeInformation = CC_NODE_F_OBJECT(p_Pos);
42254 + p_NodePtrOnCurrentMdfManip =
42255 + (t_FmPcdCcNode *)p_CcNodeInformation->h_CcNode;
42256 +
42257 + ASSERT_COND(p_NodePtrOnCurrentMdfManip);
42258 +
42259 + /* Search in the previous node which exact index points on this current modified node for getting AD */
42260 + for (i = 0; i < p_NodePtrOnCurrentMdfManip->numOfKeys + 1; i++)
42261 + {
42262 + if (p_NodePtrOnCurrentMdfManip->keyAndNextEngineParams[i].nextEngineParams.nextEngine
42263 + == e_FM_PCD_CC)
42264 + {
42265 + if (p_NodePtrOnCurrentMdfManip->keyAndNextEngineParams[i].nextEngineParams.h_Manip
42266 + == (t_Handle)p_CrntMdfManip)
42267 + {
42268 + if (p_NodePtrOnCurrentMdfManip->keyAndNextEngineParams[i].p_StatsObj)
42269 + p_AdTablePtOnCrntCurrentMdfNode =
42270 + p_NodePtrOnCurrentMdfManip->keyAndNextEngineParams[i].p_StatsObj->h_StatsAd;
42271 + else
42272 + p_AdTablePtOnCrntCurrentMdfNode =
42273 + PTR_MOVE(p_NodePtrOnCurrentMdfManip->h_AdTable, i*FM_PCD_CC_AD_ENTRY_SIZE);
42274 +
42275 + memset(&ccNodeInfo, 0, sizeof(t_CcNodeInformation));
42276 + ccNodeInfo.h_CcNode = p_AdTablePtOnCrntCurrentMdfNode;
42277 + EnqueueNodeInfoToRelevantLst(h_NodesLst, &ccNodeInfo, NULL);
42278 + }
42279 + }
42280 + }
42281 +
42282 + ASSERT_COND(i != p_NodePtrOnCurrentMdfManip->numOfKeys);
42283 + }
42284 +}
42285 +
42286 +static void BuildHmtd(uint8_t *p_Dest, uint8_t *p_Src, uint8_t *p_Hmcd,
42287 + t_FmPcd *p_FmPcd)
42288 +{
42289 + t_Error err;
42290 +
42291 + /* Copy the HMTD */
42292 + MemCpy8(p_Dest, (uint8_t*)p_Src, 16);
42293 + /* Replace the HMCT table pointer */
42294 + WRITE_UINT32(
42295 + ((t_Hmtd *)p_Dest)->hmcdBasePtr,
42296 + (uint32_t)(XX_VirtToPhys(p_Hmcd) - ((t_FmPcd*)p_FmPcd)->physicalMuramBase));
42297 + /* Call Host Command to replace HMTD by a new HMTD */
42298 + err = FmHcPcdCcDoDynamicChange(
42299 + p_FmPcd->h_Hc,
42300 + (uint32_t)(XX_VirtToPhys(p_Src) - p_FmPcd->physicalMuramBase),
42301 + (uint32_t)(XX_VirtToPhys(p_Dest) - p_FmPcd->physicalMuramBase));
42302 + if (err)
42303 + REPORT_ERROR(MINOR, err, ("Failed in dynamic manip change, continued to the rest of the owners."));
42304 +}
42305 +
42306 +static t_Error FmPcdManipInitUpdate(t_Handle h_FmPcd, t_Handle h_PcdParams,
42307 + t_Handle h_FmPort, t_Handle h_Manip,
42308 + t_Handle h_Ad, bool validate, int level,
42309 + t_Handle h_FmTree)
42310 +{
42311 + t_FmPcdManip *p_Manip = (t_FmPcdManip *)h_Manip;
42312 + t_Error err = E_OK;
42313 +
42314 + SANITY_CHECK_RETURN_ERROR(h_Manip, E_INVALID_HANDLE);
42315 +
42316 + UNUSED(level);
42317 + UNUSED(h_FmTree);
42318 +
42319 + switch (p_Manip->opcode)
42320 + {
42321 +#if (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10))
42322 + case (HMAN_OC_MV_INT_FRAME_HDR_FROM_FRM_TO_BUFFER_PREFFIX):
42323 + err = UpdateInitMvIntFrameHeaderFromFrameToBufferPrefix(h_FmPort,
42324 + p_Manip,
42325 + h_Ad,
42326 + validate);
42327 + break;
42328 + case (HMAN_OC_INSRT_HDR_BY_TEMPL_N_OR_FRAG_AFTER):
42329 + if (!p_Manip->h_Frag)
42330 + break;
42331 + case (HMAN_OC_CAPWAP_FRAGMENTATION):
42332 + err = UpdateInitCapwapFragmentation(h_FmPort, p_Manip, h_Ad, validate, h_FmTree);
42333 + break;
42334 + case (HMAN_OC_CAPWAP_RMV_DTLS_IF_EXIST):
42335 + if (p_Manip->h_Frag)
42336 + err = UpdateInitCapwapReasm(h_FmPcd, h_FmPort, p_Manip, h_Ad, validate);
42337 + break;
42338 + case (HMAN_OC_CAPWAP_INDEXED_STATS):
42339 + err = UpdateIndxStats(h_FmPcd, h_FmPort, p_Manip);
42340 + break;
42341 +#endif /* (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10)) */
42342 + case (HMAN_OC_IP_REASSEMBLY):
42343 + err = UpdateInitReasm(h_FmPcd, h_PcdParams, h_FmPort, p_Manip, h_Ad,
42344 + validate);
42345 + break;
42346 + case (HMAN_OC_IP_FRAGMENTATION):
42347 + err = UpdateInitIpFrag(h_FmPcd, h_PcdParams, h_FmPort, p_Manip,
42348 + h_Ad, validate);
42349 + break;
42350 +#if (DPAA_VERSION >= 11)
42351 + case (HMAN_OC_CAPWAP_FRAGMENTATION):
42352 + err = UpdateInitCapwapFrag(h_FmPcd, h_PcdParams, h_FmPort, p_Manip,
42353 + h_Ad, validate);
42354 + break;
42355 + case (HMAN_OC_CAPWAP_REASSEMBLY):
42356 + err = UpdateInitReasm(h_FmPcd, h_PcdParams, h_FmPort, p_Manip, h_Ad,
42357 + validate);
42358 + break;
42359 +#endif /* (DPAA_VERSION >= 11) */
42360 + default:
42361 + return E_OK;
42362 + }
42363 +
42364 + return err;
42365 +}
42366 +
42367 +static t_Error FmPcdManipModifyUpdate(t_Handle h_Manip, t_Handle h_Ad,
42368 + bool validate, int level,
42369 + t_Handle h_FmTree)
42370 +{
42371 +
42372 + t_FmPcdManip *p_Manip = (t_FmPcdManip *)h_Manip;
42373 + t_Error err = E_OK;
42374 +
42375 + UNUSED(level);
42376 +
42377 + switch (p_Manip->opcode)
42378 + {
42379 +#if (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10))
42380 + case (HMAN_OC_MV_INT_FRAME_HDR_FROM_FRM_TO_BUFFER_PREFFIX):
42381 + RETURN_ERROR(
42382 + MAJOR,
42383 + E_INVALID_STATE,
42384 + ("modify node with this type of manipulation is not suppported"));
42385 + case (HMAN_OC_CAPWAP_RMV_DTLS_IF_EXIST):
42386 +
42387 + if (p_Manip->h_Frag)
42388 + {
42389 + if (!(p_Manip->shadowUpdateParams & NUM_OF_TASKS)
42390 + && !(p_Manip->shadowUpdateParams & OFFSET_OF_DATA)
42391 + && !(p_Manip->shadowUpdateParams & OFFSET_OF_PR))
42392 + RETURN_ERROR(
42393 + MAJOR,
42394 + E_INVALID_STATE,
42395 + ("modify node with this type of manipulation requires manipulation be updated previously in SetPcd function"));
42396 + }
42397 + break;
42398 + case (HMAN_OC_INSRT_HDR_BY_TEMPL_N_OR_FRAG_AFTER):
42399 + if (p_Manip->h_Frag)
42400 + err = UpdateModifyCapwapFragmenation(p_Manip, h_Ad, validate, h_FmTree);
42401 + break;
42402 +#endif /* (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10)) */
42403 + default:
42404 + return E_OK;
42405 + }
42406 +
42407 + return err;
42408 +}
42409 +
42410 +/*****************************************************************************/
42411 +/* Inter-module API routines */
42412 +/*****************************************************************************/
42413 +
42414 +t_Error FmPcdManipUpdate(t_Handle h_FmPcd, t_Handle h_PcdParams,
42415 + t_Handle h_FmPort, t_Handle h_Manip, t_Handle h_Ad,
42416 + bool validate, int level, t_Handle h_FmTree,
42417 + bool modify)
42418 +{
42419 + t_Error err;
42420 +
42421 + if (!modify)
42422 + err = FmPcdManipInitUpdate(h_FmPcd, h_PcdParams, h_FmPort, h_Manip,
42423 + h_Ad, validate, level, h_FmTree);
42424 + else
42425 + err = FmPcdManipModifyUpdate(h_Manip, h_Ad, validate, level, h_FmTree);
42426 +
42427 + return err;
42428 +}
42429 +
42430 +void FmPcdManipUpdateOwner(t_Handle h_Manip, bool add)
42431 +{
42432 +
42433 + uint32_t intFlags;
42434 +
42435 + intFlags = XX_LockIntrSpinlock(((t_FmPcdManip *)h_Manip)->h_Spinlock);
42436 + if (add)
42437 + ((t_FmPcdManip *)h_Manip)->owner++;
42438 + else
42439 + {
42440 + ASSERT_COND(((t_FmPcdManip *)h_Manip)->owner);
42441 + ((t_FmPcdManip *)h_Manip)->owner--;
42442 + }
42443 + XX_UnlockIntrSpinlock(((t_FmPcdManip *)h_Manip)->h_Spinlock, intFlags);
42444 +}
42445 +
42446 +t_List *FmPcdManipGetNodeLstPointedOnThisManip(t_Handle h_Manip)
42447 +{
42448 + ASSERT_COND(h_Manip);
42449 + return &((t_FmPcdManip *)h_Manip)->nodesLst;
42450 +}
42451 +
42452 +t_List *FmPcdManipGetSpinlock(t_Handle h_Manip)
42453 +{
42454 + ASSERT_COND(h_Manip);
42455 + return ((t_FmPcdManip *)h_Manip)->h_Spinlock;
42456 +}
42457 +
42458 +t_Error FmPcdManipCheckParamsForCcNextEngine(
42459 + t_FmPcdCcNextEngineParams *p_FmPcdCcNextEngineParams,
42460 + uint32_t *requiredAction)
42461 +{
42462 + t_FmPcdManip *p_Manip;
42463 +#if (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10))
42464 + t_Error err = E_OK;
42465 +#endif /* (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10))*/
42466 + bool pointFromCc = TRUE;
42467 +
42468 + SANITY_CHECK_RETURN_ERROR(p_FmPcdCcNextEngineParams, E_NULL_POINTER);
42469 + SANITY_CHECK_RETURN_ERROR(p_FmPcdCcNextEngineParams->h_Manip,
42470 + E_NULL_POINTER);
42471 +
42472 + p_Manip = (t_FmPcdManip *)(p_FmPcdCcNextEngineParams->h_Manip);
42473 + *requiredAction = 0;
42474 +
42475 + while (p_Manip)
42476 + {
42477 + switch (p_Manip->opcode)
42478 + {
42479 +#if (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10))
42480 + case (HMAN_OC_CAPWAP_INDEXED_STATS):
42481 + if (p_FmPcdCcNextEngineParams->nextEngine != e_FM_PCD_DONE)
42482 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("For this type of header manipulation has to be nextEngine e_FM_PCD_DONE"));
42483 + if (p_FmPcdCcNextEngineParams->params.enqueueParams.overrideFqid)
42484 + p_Manip->cnia = TRUE;
42485 + case (HMAN_OC_CAPWAP_RMV_DTLS_IF_EXIST):
42486 + *requiredAction = UPDATE_NIA_ENQ_WITHOUT_DMA;
42487 + case (HMAN_OC_RMV_N_OR_INSRT_INT_FRM_HDR):
42488 + p_Manip->ownerTmp++;
42489 + break;
42490 + case (HMAN_OC_INSRT_HDR_BY_TEMPL_N_OR_FRAG_AFTER):
42491 + if ((p_FmPcdCcNextEngineParams->nextEngine != e_FM_PCD_DONE)
42492 + && !p_FmPcdCcNextEngineParams->params.enqueueParams.overrideFqid)
42493 + RETURN_ERROR(
42494 + MAJOR,
42495 + E_INVALID_STATE,
42496 + ("For this type of header manipulation has to be nextEngine e_FM_PCD_DONE with fqidForCtrlFlow FALSE"));
42497 + p_Manip->ownerTmp++;
42498 + break;
42499 + case (HMAN_OC_MV_INT_FRAME_HDR_FROM_FRM_TO_BUFFER_PREFFIX):
42500 + if ((p_FmPcdCcNextEngineParams->nextEngine != e_FM_PCD_CC)
42501 + && (FmPcdCcGetParseCode(p_FmPcdCcNextEngineParams->params.ccParams.h_CcNode)
42502 + != CC_PC_GENERIC_IC_HASH_INDEXED))
42503 + 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"));
42504 + err = UpdateManipIc(p_FmPcdCcNextEngineParams->h_Manip,
42505 + FmPcdCcGetOffset(p_FmPcdCcNextEngineParams->params.ccParams.h_CcNode));
42506 + if (err)
42507 + RETURN_ERROR(MAJOR, err, NO_MSG);
42508 + *requiredAction = UPDATE_NIA_ENQ_WITHOUT_DMA;
42509 + break;
42510 + #endif /* (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10)) */
42511 + case (HMAN_OC_IP_FRAGMENTATION):
42512 + case (HMAN_OC_IP_REASSEMBLY):
42513 +#if (DPAA_VERSION >= 11)
42514 + case (HMAN_OC_CAPWAP_REASSEMBLY):
42515 + case (HMAN_OC_CAPWAP_FRAGMENTATION):
42516 +#endif /* (DPAA_VERSION >= 11) */
42517 + if (p_FmPcdCcNextEngineParams->nextEngine != e_FM_PCD_DONE)
42518 + RETURN_ERROR(
42519 + MAJOR,
42520 + E_INVALID_STATE,
42521 + ("For this type of header manipulation has to be nextEngine e_FM_PCD_DONE"));
42522 + p_Manip->ownerTmp++;
42523 + break;
42524 + case (HMAN_OC_IPSEC_MANIP):
42525 +#if (DPAA_VERSION >= 11)
42526 + case (HMAN_OC_CAPWAP_MANIP):
42527 +#endif /* (DPAA_VERSION >= 11) */
42528 + p_Manip->ownerTmp++;
42529 + break;
42530 + case (HMAN_OC):
42531 + if ((p_FmPcdCcNextEngineParams->nextEngine == e_FM_PCD_CC)
42532 + && MANIP_IS_CASCADED(p_Manip))
42533 + RETURN_ERROR(
42534 + MINOR,
42535 + E_INVALID_STATE,
42536 + ("Can't have a cascaded manipulation when and Next Engine is CC"));
42537 + if (!MANIP_IS_FIRST(p_Manip) && pointFromCc)
42538 + RETURN_ERROR(
42539 + MAJOR,
42540 + E_INVALID_STATE,
42541 + ("h_Manip is already used and may not be shared (no sharing of non-head manip nodes)"));
42542 + break;
42543 + default:
42544 + RETURN_ERROR(
42545 + MAJOR, E_INVALID_STATE,
42546 + ("invalid type of header manipulation for this state"));
42547 + }
42548 + p_Manip = p_Manip->h_NextManip;
42549 + pointFromCc = FALSE;
42550 + }
42551 + return E_OK;
42552 +}
42553 +
42554 +
42555 +t_Error FmPcdManipCheckParamsWithCcNodeParams(t_Handle h_Manip,
42556 + t_Handle h_FmPcdCcNode)
42557 +{
42558 + t_FmPcdManip *p_Manip = (t_FmPcdManip *)h_Manip;
42559 + t_Error err = E_OK;
42560 +
42561 + SANITY_CHECK_RETURN_ERROR(h_Manip, E_INVALID_HANDLE);
42562 + SANITY_CHECK_RETURN_ERROR(h_FmPcdCcNode, E_INVALID_HANDLE);
42563 +
42564 + switch (p_Manip->opcode)
42565 + {
42566 +#if (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10))
42567 + case (HMAN_OC_CAPWAP_INDEXED_STATS):
42568 + if (p_Manip->ownerTmp != FmPcdCcGetNumOfKeys(h_FmPcdCcNode))
42569 + RETURN_ERROR(
42570 + MAJOR,
42571 + E_INVALID_VALUE,
42572 + ("The manipulation of the type statistics flowId if exist has to be pointed by all numOfKeys"));
42573 + break;
42574 + case (HMAN_OC_CAPWAP_RMV_DTLS_IF_EXIST):
42575 + if (p_Manip->h_Frag)
42576 + {
42577 + if (p_Manip->ownerTmp != FmPcdCcGetNumOfKeys(h_FmPcdCcNode))
42578 + RETURN_ERROR(
42579 + MAJOR,
42580 + E_INVALID_VALUE,
42581 + ("The manipulation of the type remove DTLS if exist has to be pointed by all numOfKeys"));
42582 + err = UpdateManipIc(h_Manip, FmPcdCcGetOffset(h_FmPcdCcNode));
42583 + if (err)
42584 + RETURN_ERROR(MAJOR, err, NO_MSG);
42585 + }
42586 + break;
42587 +#endif /* (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10)) */
42588 + default:
42589 + break;
42590 + }
42591 +
42592 + return err;
42593 +}
42594 +
42595 +void FmPcdManipUpdateAdResultForCc(
42596 + t_Handle h_Manip, t_FmPcdCcNextEngineParams *p_CcNextEngineParams,
42597 + t_Handle p_Ad, t_Handle *p_AdNewPtr)
42598 +{
42599 + t_FmPcdManip *p_Manip = (t_FmPcdManip *)h_Manip;
42600 +
42601 + /* This routine creates a Manip AD and can return in "p_AdNewPtr"
42602 + * either the new descriptor or NULL if it writes the Manip AD into p_AD (into the match table) */
42603 +
42604 + ASSERT_COND(p_Manip);
42605 + ASSERT_COND(p_CcNextEngineParams);
42606 + ASSERT_COND(p_Ad);
42607 + ASSERT_COND(p_AdNewPtr);
42608 +
42609 + FmPcdManipUpdateOwner(h_Manip, TRUE);
42610 +
42611 + /* According to "type", either build & initialize a new AD (p_AdNew) or initialize
42612 + * p_Ad ( the AD in the match table) and set p_AdNew = NULL. */
42613 + switch (p_Manip->opcode)
42614 + {
42615 +#if (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10))
42616 + case (HMAN_OC_RMV_N_OR_INSRT_INT_FRM_HDR):
42617 + case (HMAN_OC_CAPWAP_RMV_DTLS_IF_EXIST):
42618 + case (HMAN_OC_CAPWAP_INDEXED_STATS):
42619 + *p_AdNewPtr = p_Manip->h_Ad;
42620 + break;
42621 + case (HMAN_OC_INSRT_HDR_BY_TEMPL_N_OR_FRAG_AFTER):
42622 + case (HMAN_OC_CAPWAP_FRAGMENTATION):
42623 + WRITE_UINT32(((t_AdOfTypeResult *)p_Ad)->fqid,
42624 + ((t_AdOfTypeResult *)(p_Manip->h_Ad))->fqid);
42625 + WRITE_UINT32(((t_AdOfTypeResult *)p_Ad)->plcrProfile,
42626 + ((t_AdOfTypeResult *)(p_Manip->h_Ad))->plcrProfile);
42627 + WRITE_UINT32(((t_AdOfTypeResult *)p_Ad)->nia,
42628 + ((t_AdOfTypeResult *)(p_Manip->h_Ad))->nia);
42629 + *p_AdNewPtr = NULL;
42630 + break;
42631 +#endif /* (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10)) */
42632 + case (HMAN_OC_IPSEC_MANIP):
42633 +#if (DPAA_VERSION >= 11)
42634 + case (HMAN_OC_CAPWAP_MANIP):
42635 +#endif /* (DPAA_VERSION >= 11) */
42636 + *p_AdNewPtr = p_Manip->h_Ad;
42637 + break;
42638 + case (HMAN_OC_IP_FRAGMENTATION):
42639 +#if (DPAA_VERSION >= 11)
42640 + case (HMAN_OC_CAPWAP_FRAGMENTATION):
42641 +#endif /* (DPAA_VERSION >= 11) */
42642 + if ((p_CcNextEngineParams->nextEngine == e_FM_PCD_DONE)
42643 + && (!p_CcNextEngineParams->params.enqueueParams.overrideFqid))
42644 + {
42645 + memcpy((uint8_t *)p_Ad, (uint8_t *)p_Manip->h_Ad,
42646 + sizeof(t_AdOfTypeContLookup));
42647 +#if (DPAA_VERSION >= 11)
42648 + WRITE_UINT32(
42649 + ((t_AdOfTypeContLookup *)p_Ad)->ccAdBase,
42650 + GET_UINT32(((t_AdOfTypeContLookup *)p_Ad)->ccAdBase) & ~FM_PCD_MANIP_IP_CNIA);
42651 +#endif /* (DPAA_VERSION >= 11) */
42652 + *p_AdNewPtr = NULL;
42653 + }
42654 + else
42655 + *p_AdNewPtr = p_Manip->h_Ad;
42656 + break;
42657 + case (HMAN_OC_IP_REASSEMBLY):
42658 + if (FmPcdManipIpReassmIsIpv6Hdr(p_Manip))
42659 + {
42660 + if (!p_Manip->reassmParams.ip.ipv6Assigned)
42661 + {
42662 + *p_AdNewPtr = p_Manip->reassmParams.ip.h_Ipv6Ad;
42663 + p_Manip->reassmParams.ip.ipv6Assigned = TRUE;
42664 + FmPcdManipUpdateOwner(h_Manip, FALSE);
42665 + }
42666 + else
42667 + {
42668 + *p_AdNewPtr = p_Manip->reassmParams.ip.h_Ipv4Ad;
42669 + p_Manip->reassmParams.ip.ipv6Assigned = FALSE;
42670 + }
42671 + }
42672 + else
42673 + *p_AdNewPtr = p_Manip->reassmParams.ip.h_Ipv4Ad;
42674 + memcpy((uint8_t *)p_Ad, (uint8_t *)*p_AdNewPtr,
42675 + sizeof(t_AdOfTypeContLookup));
42676 + *p_AdNewPtr = NULL;
42677 + break;
42678 +#if (DPAA_VERSION >= 11)
42679 + case (HMAN_OC_CAPWAP_REASSEMBLY):
42680 + *p_AdNewPtr = p_Manip->reassmParams.capwap.h_Ad;
42681 + memcpy((uint8_t *)p_Ad, (uint8_t *)*p_AdNewPtr,
42682 + sizeof(t_AdOfTypeContLookup));
42683 + *p_AdNewPtr = NULL;
42684 + break;
42685 +#endif /* (DPAA_VERSION >= 11) */
42686 + case (HMAN_OC):
42687 + /* Allocate and initialize HMTD */
42688 + *p_AdNewPtr = p_Manip->h_Ad;
42689 + break;
42690 + default:
42691 + break;
42692 + }
42693 +}
42694 +
42695 +void FmPcdManipUpdateAdContLookupForCc(t_Handle h_Manip, t_Handle p_Ad,
42696 + t_Handle *p_AdNewPtr,
42697 + uint32_t adTableOffset)
42698 +{
42699 + t_FmPcdManip *p_Manip = (t_FmPcdManip *)h_Manip;
42700 +
42701 + /* This routine creates a Manip AD and can return in "p_AdNewPtr"
42702 + * either the new descriptor or NULL if it writes the Manip AD into p_AD (into the match table) */
42703 + ASSERT_COND(p_Manip);
42704 +
42705 + FmPcdManipUpdateOwner(h_Manip, TRUE);
42706 +
42707 + switch (p_Manip->opcode)
42708 + {
42709 +#if (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10))
42710 + case (HMAN_OC_MV_INT_FRAME_HDR_FROM_FRM_TO_BUFFER_PREFFIX):
42711 + WRITE_UINT32(((t_AdOfTypeContLookup *)p_Ad)->ccAdBase,
42712 + ((t_AdOfTypeContLookup *)(p_Manip->h_Ad))->ccAdBase);
42713 + WRITE_UINT32(
42714 + ((t_AdOfTypeContLookup *)p_Ad)->matchTblPtr,
42715 + ((t_AdOfTypeContLookup *)(p_Manip->h_Ad))->matchTblPtr);
42716 + WRITE_UINT32(
42717 + ((t_AdOfTypeContLookup *)p_Ad)->pcAndOffsets,
42718 + ((t_AdOfTypeContLookup *)(p_Manip->h_Ad))->pcAndOffsets);
42719 + WRITE_UINT32(((t_AdOfTypeContLookup *)p_Ad)->gmask,
42720 + ((t_AdOfTypeContLookup *)(p_Manip->h_Ad))->gmask);
42721 + WRITE_UINT32(
42722 + ((t_AdOfTypeContLookup *)p_Ad)->ccAdBase,
42723 + (GET_UINT32(((t_AdOfTypeContLookup *)p_Ad)->ccAdBase) | adTableOffset));
42724 + *p_AdNewPtr = NULL;
42725 + break;
42726 +#endif /* (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10)) */
42727 + case (HMAN_OC):
42728 + /* Initialize HMTD within the match table*/
42729 + MemSet8(p_Ad, 0, FM_PCD_CC_AD_ENTRY_SIZE);
42730 + /* copy the existing HMTD *//* ask Alla - memcpy??? */
42731 + memcpy((uint8_t*)p_Ad, p_Manip->h_Ad, sizeof(t_Hmtd));
42732 + /* update NADEN to be "1"*/
42733 + WRITE_UINT16(
42734 + ((t_Hmtd *)p_Ad)->cfg,
42735 + (uint16_t)(GET_UINT16(((t_Hmtd *)p_Ad)->cfg) | HMTD_CFG_NEXT_AD_EN));
42736 + /* update next action descriptor */
42737 + WRITE_UINT16(((t_Hmtd *)p_Ad)->nextAdIdx,
42738 + (uint16_t)(adTableOffset >> 4));
42739 + /* mark that Manip's HMTD is not used */
42740 + *p_AdNewPtr = NULL;
42741 + break;
42742 +
42743 + default:
42744 + break;
42745 + }
42746 +}
42747 +
42748 +t_Error FmPcdManipBuildIpReassmScheme(t_FmPcd *p_FmPcd, t_Handle h_NetEnv,
42749 + t_Handle h_CcTree, t_Handle h_Manip,
42750 + bool isIpv4, uint8_t groupId)
42751 +{
42752 + t_FmPcdManip *p_Manip = (t_FmPcdManip *)h_Manip;
42753 + t_FmPcdKgSchemeParams *p_SchemeParams = NULL;
42754 + t_Handle h_Scheme;
42755 +
42756 + ASSERT_COND(p_FmPcd);
42757 + ASSERT_COND(h_NetEnv);
42758 + ASSERT_COND(p_Manip);
42759 +
42760 + /* scheme was already build, no need to check for IPv6 */
42761 + if (p_Manip->reassmParams.ip.h_Ipv4Scheme)
42762 + return E_OK;
42763 +
42764 + if (isIpv4) {
42765 + h_Scheme = FmPcdKgGetSchemeHandle(p_FmPcd, p_Manip->reassmParams.ip.relativeSchemeId[0]);
42766 + if (h_Scheme) {
42767 + /* scheme was found */
42768 + p_Manip->reassmParams.ip.h_Ipv4Scheme = h_Scheme;
42769 + return E_OK;
42770 + }
42771 + } else {
42772 + h_Scheme = FmPcdKgGetSchemeHandle(p_FmPcd, p_Manip->reassmParams.ip.relativeSchemeId[1]);
42773 + if (h_Scheme) {
42774 + /* scheme was found */
42775 + p_Manip->reassmParams.ip.h_Ipv6Scheme = h_Scheme;
42776 + return E_OK;
42777 + }
42778 + }
42779 +
42780 + p_SchemeParams = XX_Malloc(sizeof(t_FmPcdKgSchemeParams));
42781 + if (!p_SchemeParams)
42782 + RETURN_ERROR(MAJOR, E_NO_MEMORY,
42783 + ("Memory allocation failed for scheme"));
42784 +
42785 + /* Configures the IPv4 or IPv6 scheme*/
42786 + memset(p_SchemeParams, 0, sizeof(t_FmPcdKgSchemeParams));
42787 + p_SchemeParams->netEnvParams.h_NetEnv = h_NetEnv;
42788 + p_SchemeParams->id.relativeSchemeId = (uint8_t)(
42789 + (isIpv4 == TRUE) ? p_Manip->reassmParams.ip.relativeSchemeId[0] :
42790 + p_Manip->reassmParams.ip.relativeSchemeId[1]);
42791 + p_SchemeParams->schemeCounter.update = TRUE;
42792 +#if (DPAA_VERSION >= 11)
42793 + p_SchemeParams->alwaysDirect = TRUE;
42794 + p_SchemeParams->bypassFqidGeneration = TRUE;
42795 +#else
42796 + p_SchemeParams->keyExtractAndHashParams.hashDistributionNumOfFqids = 1;
42797 + p_SchemeParams->baseFqid = 0xFFFFFF; /*TODO- baseFqid*/
42798 +#endif /* (DPAA_VERSION >= 11) */
42799 +
42800 + setIpReassmSchemeParams(p_FmPcd, p_SchemeParams, h_CcTree, isIpv4, groupId);
42801 +
42802 + /* Sets the new scheme */
42803 + if (isIpv4)
42804 + p_Manip->reassmParams.ip.h_Ipv4Scheme = FM_PCD_KgSchemeSet(
42805 + p_FmPcd, p_SchemeParams);
42806 + else
42807 + p_Manip->reassmParams.ip.h_Ipv6Scheme = FM_PCD_KgSchemeSet(
42808 + p_FmPcd, p_SchemeParams);
42809 +
42810 + XX_Free(p_SchemeParams);
42811 +
42812 + return E_OK;
42813 +}
42814 +
42815 +t_Error FmPcdManipDeleteIpReassmSchemes(t_Handle h_Manip)
42816 +{
42817 + t_FmPcdManip *p_Manip = (t_FmPcdManip *)h_Manip;
42818 +
42819 + ASSERT_COND(p_Manip);
42820 +
42821 + if ((p_Manip->reassmParams.ip.h_Ipv4Scheme) &&
42822 + !FmPcdKgIsSchemeHasOwners(p_Manip->reassmParams.ip.h_Ipv4Scheme))
42823 + FM_PCD_KgSchemeDelete(p_Manip->reassmParams.ip.h_Ipv4Scheme);
42824 +
42825 + if ((p_Manip->reassmParams.ip.h_Ipv6Scheme) &&
42826 + !FmPcdKgIsSchemeHasOwners(p_Manip->reassmParams.ip.h_Ipv6Scheme))
42827 + FM_PCD_KgSchemeDelete(p_Manip->reassmParams.ip.h_Ipv6Scheme);
42828 +
42829 + return E_OK;
42830 +}
42831 +
42832 +bool FmPcdManipIpReassmIsIpv6Hdr(t_Handle h_Manip)
42833 +{
42834 + t_FmPcdManip *p_Manip = (t_FmPcdManip *)h_Manip;
42835 +
42836 + ASSERT_COND(p_Manip);
42837 +
42838 + return (p_Manip->reassmParams.hdr == HEADER_TYPE_IPv6);
42839 +}
42840 +
42841 +t_Error FmPcdManipBuildCapwapReassmScheme(t_FmPcd *p_FmPcd, t_Handle h_NetEnv,
42842 + t_Handle h_CcTree, t_Handle h_Manip,
42843 + uint8_t groupId)
42844 +{
42845 + t_FmPcdManip *p_Manip = (t_FmPcdManip *)h_Manip;
42846 + t_FmPcdKgSchemeParams *p_SchemeParams = NULL;
42847 +
42848 + ASSERT_COND(p_FmPcd);
42849 + ASSERT_COND(h_NetEnv);
42850 + ASSERT_COND(p_Manip);
42851 +
42852 + /* scheme was already build, no need to check for IPv6 */
42853 + if (p_Manip->reassmParams.capwap.h_Scheme)
42854 + return E_OK;
42855 +
42856 + p_SchemeParams = XX_Malloc(sizeof(t_FmPcdKgSchemeParams));
42857 + if (!p_SchemeParams)
42858 + RETURN_ERROR(MAJOR, E_NO_MEMORY,
42859 + ("Memory allocation failed for scheme"));
42860 +
42861 + memset(p_SchemeParams, 0, sizeof(t_FmPcdKgSchemeParams));
42862 + p_SchemeParams->netEnvParams.h_NetEnv = h_NetEnv;
42863 + p_SchemeParams->id.relativeSchemeId =
42864 + (uint8_t)p_Manip->reassmParams.capwap.relativeSchemeId;
42865 + p_SchemeParams->schemeCounter.update = TRUE;
42866 + p_SchemeParams->bypassFqidGeneration = TRUE;
42867 +
42868 + setCapwapReassmSchemeParams(p_FmPcd, p_SchemeParams, h_CcTree, groupId);
42869 +
42870 + p_Manip->reassmParams.capwap.h_Scheme = FM_PCD_KgSchemeSet(p_FmPcd,
42871 + p_SchemeParams);
42872 +
42873 + XX_Free(p_SchemeParams);
42874 +
42875 + return E_OK;
42876 +}
42877 +
42878 +t_Error FmPcdManipDeleteCapwapReassmSchemes(t_Handle h_Manip)
42879 +{
42880 + t_FmPcdManip *p_Manip = (t_FmPcdManip *)h_Manip;
42881 +
42882 + ASSERT_COND(p_Manip);
42883 +
42884 + if (p_Manip->reassmParams.capwap.h_Scheme)
42885 + FM_PCD_KgSchemeDelete(p_Manip->reassmParams.capwap.h_Scheme);
42886 +
42887 + return E_OK;
42888 +}
42889 +
42890 +#if (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10))
42891 +t_Handle FmPcdManipApplSpecificBuild(void)
42892 +{
42893 + t_FmPcdManip *p_Manip;
42894 +
42895 + p_Manip = (t_FmPcdManip*)XX_Malloc(sizeof(t_FmPcdManip));
42896 + if (!p_Manip)
42897 + {
42898 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("No memory"));
42899 + return NULL;
42900 + }
42901 + memset(p_Manip, 0, sizeof(t_FmPcdManip));
42902 +
42903 + p_Manip->opcode = HMAN_OC_MV_INT_FRAME_HDR_FROM_FRM_TO_BUFFER_PREFFIX;
42904 + p_Manip->muramAllocate = FALSE;
42905 +
42906 + p_Manip->h_Ad = (t_Handle)XX_Malloc(FM_PCD_CC_AD_ENTRY_SIZE * sizeof(uint8_t));
42907 + if (!p_Manip->h_Ad)
42908 + {
42909 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("Allocation of Manipulation action descriptor"));
42910 + XX_Free(p_Manip);
42911 + return NULL;
42912 + }
42913 +
42914 + memset(p_Manip->h_Ad, 0, FM_PCD_CC_AD_ENTRY_SIZE * sizeof(uint8_t));
42915 +
42916 + /*treatFdStatusFieldsAsErrors = TRUE hardcoded - assumption its always come after CAAM*/
42917 + /*Application specific = type of flowId index, move internal frame header from data to IC,
42918 + SEC errors check*/
42919 + if (MvIntFrameHeaderFromFrameToBufferPrefix(p_Manip, TRUE)!= E_OK)
42920 + {
42921 + XX_Free(p_Manip->h_Ad);
42922 + XX_Free(p_Manip);
42923 + return NULL;
42924 + }
42925 + return p_Manip;
42926 +}
42927 +
42928 +bool FmPcdManipIsCapwapApplSpecific(t_Handle h_Manip)
42929 +{
42930 + t_FmPcdManip *p_Manip = (t_FmPcdManip *)h_Manip;
42931 + ASSERT_COND(h_Manip);
42932 +
42933 + return (bool)((p_Manip->opcode == HMAN_OC_CAPWAP_RMV_DTLS_IF_EXIST) ? TRUE : FALSE);
42934 +}
42935 +#endif /* (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10)) */
42936 +/*********************** End of inter-module routines ************************/
42937 +
42938 +/****************************************/
42939 +/* API Init unit functions */
42940 +/****************************************/
42941 +
42942 +t_Handle FM_PCD_ManipNodeSet(t_Handle h_FmPcd,
42943 + t_FmPcdManipParams *p_ManipParams)
42944 +{
42945 + t_FmPcd *p_FmPcd = (t_FmPcd *)h_FmPcd;
42946 + t_FmPcdManip *p_Manip;
42947 + t_Error err;
42948 +
42949 + SANITY_CHECK_RETURN_VALUE(h_FmPcd, E_INVALID_HANDLE, NULL);
42950 + SANITY_CHECK_RETURN_VALUE(p_ManipParams, E_INVALID_HANDLE, NULL);
42951 +
42952 + p_Manip = ManipOrStatsSetNode(h_FmPcd, (t_Handle)p_ManipParams, FALSE);
42953 + if (!p_Manip)
42954 + return NULL;
42955 +
42956 + if (((p_Manip->opcode == HMAN_OC_IP_REASSEMBLY)
42957 + || (p_Manip->opcode == HMAN_OC_IP_FRAGMENTATION)
42958 + || (p_Manip->opcode == HMAN_OC)
42959 + || (p_Manip->opcode == HMAN_OC_IPSEC_MANIP)
42960 +#if (DPAA_VERSION >= 11)
42961 + || (p_Manip->opcode == HMAN_OC_CAPWAP_MANIP)
42962 + || (p_Manip->opcode == HMAN_OC_CAPWAP_FRAGMENTATION)
42963 + || (p_Manip->opcode == HMAN_OC_CAPWAP_REASSEMBLY)
42964 +#endif /* (DPAA_VERSION >= 11) */
42965 + ) && (!FmPcdIsAdvancedOffloadSupported(p_FmPcd)))
42966 + {
42967 + REPORT_ERROR(MAJOR, E_INVALID_STATE, ("Advanced-offload must be enabled"));
42968 + XX_Free(p_Manip);
42969 + return NULL;
42970 + }
42971 + p_Manip->h_Spinlock = XX_InitSpinlock();
42972 + if (!p_Manip->h_Spinlock)
42973 + {
42974 + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("UNSUPPORTED HEADER MANIPULATION TYPE"));
42975 + ReleaseManipHandler(p_Manip, p_FmPcd);
42976 + XX_Free(p_Manip);
42977 + return NULL;
42978 + }INIT_LIST(&p_Manip->nodesLst);
42979 +
42980 + switch (p_Manip->opcode)
42981 + {
42982 + case (HMAN_OC_IP_REASSEMBLY):
42983 + /* IpReassembly */
42984 + err = IpReassembly(&p_ManipParams->u.reassem, p_Manip);
42985 + break;
42986 + case (HMAN_OC_IP_FRAGMENTATION):
42987 + /* IpFragmentation */
42988 + err = IpFragmentation(&p_ManipParams->u.frag.u.ipFrag, p_Manip);
42989 + if (err)
42990 + break;
42991 + err = IPManip(p_Manip);
42992 + break;
42993 + case (HMAN_OC_IPSEC_MANIP):
42994 + err = IPSecManip(p_ManipParams, p_Manip);
42995 + break;
42996 +#if (DPAA_VERSION >= 11)
42997 + case (HMAN_OC_CAPWAP_REASSEMBLY):
42998 + /* CapwapReassembly */
42999 + err = CapwapReassembly(&p_ManipParams->u.reassem, p_Manip);
43000 + break;
43001 + case (HMAN_OC_CAPWAP_FRAGMENTATION):
43002 + /* CapwapFragmentation */
43003 + err = CapwapFragmentation(&p_ManipParams->u.frag.u.capwapFrag,
43004 + p_Manip);
43005 + break;
43006 + case (HMAN_OC_CAPWAP_MANIP):
43007 + err = CapwapManip(p_ManipParams, p_Manip);
43008 + break;
43009 +#endif /* (DPAA_VERSION >= 11) */
43010 +#if (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10))
43011 + case (HMAN_OC_RMV_N_OR_INSRT_INT_FRM_HDR):
43012 + /* HmanType1 */
43013 + err = RmvHdrTillSpecLocNOrInsrtIntFrmHdr(&p_ManipParams->u.hdr.rmvParams, p_Manip);
43014 + break;
43015 + case (HMAN_OC_CAPWAP_FRAGMENTATION):
43016 + err = CapwapFragmentation(&p_ManipParams->fragOrReasmParams.u.capwapFragParams,
43017 + p_Manip,
43018 + p_FmPcd,
43019 + p_ManipParams->fragOrReasmParams.sgBpid);
43020 + if (err)
43021 + {
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 + if (p_Manip->insrt)
43028 + p_Manip->opcode = HMAN_OC_INSRT_HDR_BY_TEMPL_N_OR_FRAG_AFTER;
43029 + case (HMAN_OC_INSRT_HDR_BY_TEMPL_N_OR_FRAG_AFTER):
43030 + /* HmanType2 + if user asked only for fragmentation still need to allocate HmanType2 */
43031 + err = InsrtHdrByTempl(&p_ManipParams->u.hdr.insrtParams, p_Manip, p_FmPcd);
43032 + break;
43033 + case (HMAN_OC_CAPWAP_REASSEMBLY):
43034 + err = CapwapReassembly(&p_ManipParams->fragOrReasmParams.u.capwapReasmParams,
43035 + p_Manip,
43036 + p_FmPcd,
43037 + p_ManipParams->fragOrReasmParams.sgBpid);
43038 + if (err)
43039 + {
43040 + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("UNSUPPORTED HEADER MANIPULATION TYPE"));
43041 + ReleaseManipHandler(p_Manip, p_FmPcd);
43042 + XX_Free(p_Manip);
43043 + return NULL;
43044 + }
43045 + if (p_Manip->rmv)
43046 + p_Manip->opcode = HMAN_OC_CAPWAP_RMV_DTLS_IF_EXIST;
43047 + case (HMAN_OC_CAPWAP_RMV_DTLS_IF_EXIST):
43048 + /*CAPWAP decapsulation + if user asked only for reassembly still need to allocate CAPWAP decapsulation*/
43049 + err = CapwapRmvDtlsHdr(p_FmPcd, p_Manip);
43050 + break;
43051 + case (HMAN_OC_MV_INT_FRAME_HDR_FROM_FRM_TO_BUFFER_PREFFIX):
43052 + /*Application Specific type 1*/
43053 + err = MvIntFrameHeaderFromFrameToBufferPrefix(p_Manip, TRUE);
43054 + break;
43055 +#endif /* (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10)) */
43056 + case (HMAN_OC):
43057 + /* New Manip */
43058 + err = CreateManipActionNew(p_Manip, p_ManipParams);
43059 + break;
43060 + default:
43061 + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("UNSUPPORTED HEADER MANIPULATION TYPE"));
43062 + ReleaseManipHandler(p_Manip, p_FmPcd);
43063 + XX_Free(p_Manip);
43064 + return NULL;
43065 + }
43066 +
43067 + if (err)
43068 + {
43069 + REPORT_ERROR(MAJOR, err, NO_MSG);
43070 + ReleaseManipHandler(p_Manip, p_FmPcd);
43071 + XX_Free(p_Manip);
43072 + return NULL;
43073 + }
43074 +
43075 + if (p_ManipParams->h_NextManip)
43076 + {
43077 + /* in the check routine we've verified that h_NextManip has no owners
43078 + * and that only supported types are allowed. */
43079 + p_Manip->h_NextManip = p_ManipParams->h_NextManip;
43080 + /* save a "prev" pointer in h_NextManip */
43081 + MANIP_SET_PREV(p_Manip->h_NextManip, p_Manip);
43082 + FmPcdManipUpdateOwner(p_Manip->h_NextManip, TRUE);
43083 + }
43084 +
43085 + return p_Manip;
43086 +}
43087 +
43088 +t_Error FM_PCD_ManipNodeReplace(t_Handle h_Manip,
43089 + t_FmPcdManipParams *p_ManipParams)
43090 +{
43091 + t_FmPcdManip *p_Manip = (t_FmPcdManip *)h_Manip, *p_FirstManip;
43092 + t_FmPcd *p_FmPcd = (t_FmPcd *)(p_Manip->h_FmPcd);
43093 + t_Error err;
43094 + uint8_t *p_WholeHmct = NULL, *p_ShadowHmct = NULL, *p_Hmtd = NULL;
43095 + t_List lstOfNodeshichPointsOnCrntMdfManip, *p_Pos;
43096 + t_CcNodeInformation *p_CcNodeInfo;
43097 + SANITY_CHECK_RETURN_ERROR(h_Manip, E_INVALID_HANDLE);
43098 + SANITY_CHECK_RETURN_ERROR(p_ManipParams, E_INVALID_HANDLE);
43099 +
43100 + INIT_LIST(&lstOfNodeshichPointsOnCrntMdfManip);
43101 +
43102 + if ((p_ManipParams->type != e_FM_PCD_MANIP_HDR)
43103 + || (p_Manip->type != e_FM_PCD_MANIP_HDR))
43104 + RETURN_ERROR(
43105 + MINOR,
43106 + E_NOT_SUPPORTED,
43107 + ("FM_PCD_ManipNodeReplace Functionality supported only for Header Manipulation."));
43108 +
43109 + ASSERT_COND(p_Manip->opcode == HMAN_OC);
43110 + ASSERT_COND(p_Manip->manipParams.h_NextManip == p_Manip->h_NextManip);
43111 + memcpy((uint8_t*)&p_Manip->manipParams, p_ManipParams,
43112 + sizeof(p_Manip->manipParams));
43113 + p_Manip->manipParams.h_NextManip = p_Manip->h_NextManip;
43114 +
43115 + /* The replacement of the HdrManip depends on the node type.*/
43116 + /*
43117 + * (1) If this is an independent node, all its owners should be updated.
43118 + *
43119 + * (2) If it is the head of a cascaded chain (it does not have a "prev" but
43120 + * it has a "next" and it has a "cascaded" indication), the next
43121 + * node remains unchanged, and the behavior is as in (1).
43122 + *
43123 + * (3) If it is not the head, but a part of a cascaded chain, in can be
43124 + * also replaced as a regular node with just one owner.
43125 + *
43126 + * (4) If it is a part of a chain implemented as a unified table, the
43127 + * whole table is replaced and the owners of the head node must be updated.
43128 + *
43129 + */
43130 + /* lock shadow */
43131 + if (!p_FmPcd->p_CcShadow)
43132 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("CC Shadow not allocated"));
43133 +
43134 + if (!TRY_LOCK(p_FmPcd->h_ShadowSpinlock, &p_FmPcd->shadowLock))
43135 + return ERROR_CODE(E_BUSY);
43136 +
43137 + /* this routine creates a new manip action in the CC Shadow. */
43138 + err = CreateManipActionShadow(p_Manip, p_ManipParams);
43139 + if (err)
43140 + RETURN_ERROR(MINOR, err, NO_MSG);
43141 +
43142 + /* If the owners list is empty (these are NOT the "owners" counter, but pointers from CC)
43143 + * replace only HMTD and no lcok is required. Otherwise
43144 + * lock the whole PCD
43145 + * In case 4 MANIP_IS_UNIFIED_NON_FIRST(p_Manip) - Use the head node instead. */
43146 + if (!FmPcdLockTryLockAll(p_FmPcd))
43147 + {
43148 + DBG(TRACE, ("FmPcdLockTryLockAll failed"));
43149 + return ERROR_CODE(E_BUSY);
43150 + }
43151 +
43152 + p_ShadowHmct = (uint8_t*)PTR_MOVE(p_FmPcd->p_CcShadow, 16);
43153 +
43154 + p_FirstManip = (t_FmPcdManip*)GetManipInfo(p_Manip,
43155 + e_MANIP_HANDLER_TABLE_OWNER);
43156 + ASSERT_COND(p_FirstManip);
43157 +
43158 + if (!LIST_IsEmpty(&p_FirstManip->nodesLst))
43159 + UpdateAdPtrOfNodesWhichPointsOnCrntMdfManip(
43160 + p_FirstManip, &lstOfNodeshichPointsOnCrntMdfManip);
43161 +
43162 + p_Hmtd = (uint8_t *)GetManipInfo(p_Manip, e_MANIP_HMTD);
43163 + ASSERT_COND(p_Hmtd);
43164 + BuildHmtd(p_FmPcd->p_CcShadow, (uint8_t *)p_Hmtd, p_ShadowHmct,
43165 + ((t_FmPcd*)(p_Manip->h_FmPcd)));
43166 +
43167 + LIST_FOR_EACH(p_Pos, &lstOfNodeshichPointsOnCrntMdfManip)
43168 + {
43169 + p_CcNodeInfo = CC_NODE_F_OBJECT(p_Pos);
43170 + BuildHmtd(p_FmPcd->p_CcShadow, (uint8_t *)p_CcNodeInfo->h_CcNode,
43171 + p_ShadowHmct, ((t_FmPcd*)(p_Manip->h_FmPcd)));
43172 + }
43173 +
43174 + p_WholeHmct = (uint8_t *)GetManipInfo(p_Manip, e_MANIP_HMCT);
43175 + ASSERT_COND(p_WholeHmct);
43176 +
43177 + /* re-build the HMCT n the original location */
43178 + err = CreateManipActionBackToOrig(p_Manip, p_ManipParams);
43179 + if (err)
43180 + {
43181 + RELEASE_LOCK(p_FmPcd->shadowLock);
43182 + RETURN_ERROR(MINOR, err, NO_MSG);
43183 + }
43184 +
43185 + p_Hmtd = (uint8_t *)GetManipInfo(p_Manip, e_MANIP_HMTD);
43186 + ASSERT_COND(p_Hmtd);
43187 + BuildHmtd(p_FmPcd->p_CcShadow, (uint8_t *)p_Hmtd, p_WholeHmct,
43188 + ((t_FmPcd*)p_Manip->h_FmPcd));
43189 +
43190 + /* If LIST > 0, create a list of p_Ad's that point to the HMCT. Join also t_HMTD to this list.
43191 + * For each p_Hmct (from list+fixed):
43192 + * call Host Command to replace HMTD by a new one */LIST_FOR_EACH(p_Pos, &lstOfNodeshichPointsOnCrntMdfManip)
43193 + {
43194 + p_CcNodeInfo = CC_NODE_F_OBJECT(p_Pos);
43195 + BuildHmtd(p_FmPcd->p_CcShadow, (uint8_t *)p_CcNodeInfo->h_CcNode,
43196 + p_WholeHmct, ((t_FmPcd*)(p_Manip->h_FmPcd)));
43197 + }
43198 +
43199 +
43200 + ReleaseLst(&lstOfNodeshichPointsOnCrntMdfManip);
43201 +
43202 + FmPcdLockUnlockAll(p_FmPcd);
43203 +
43204 + /* unlock shadow */
43205 + RELEASE_LOCK(p_FmPcd->shadowLock);
43206 +
43207 + return E_OK;
43208 +}
43209 +
43210 +t_Error FM_PCD_ManipNodeDelete(t_Handle h_ManipNode)
43211 +{
43212 + t_FmPcdManip *p_Manip = (t_FmPcdManip *)h_ManipNode;
43213 +
43214 + SANITY_CHECK_RETURN_ERROR(p_Manip, E_INVALID_HANDLE);
43215 +
43216 + if (p_Manip->owner)
43217 + RETURN_ERROR(
43218 + MAJOR,
43219 + E_INVALID_STATE,
43220 + ("This manipulation node not be removed because this node is occupied, first - unbind this node "));
43221 +
43222 + if (p_Manip->h_NextManip)
43223 + {
43224 + MANIP_SET_PREV(p_Manip->h_NextManip, NULL);
43225 + FmPcdManipUpdateOwner(p_Manip->h_NextManip, FALSE);
43226 + }
43227 +
43228 + if (p_Manip->p_Hmct
43229 + && (MANIP_IS_UNIFIED_FIRST(p_Manip) || !MANIP_IS_UNIFIED(p_Manip)))
43230 + FM_MURAM_FreeMem(((t_FmPcd *)p_Manip->h_FmPcd)->h_FmMuram,
43231 + p_Manip->p_Hmct);
43232 +
43233 + if (p_Manip->h_Spinlock)
43234 + {
43235 + XX_FreeSpinlock(p_Manip->h_Spinlock);
43236 + p_Manip->h_Spinlock = NULL;
43237 + }
43238 +
43239 + ReleaseManipHandler(p_Manip, p_Manip->h_FmPcd);
43240 +
43241 + XX_Free(h_ManipNode);
43242 +
43243 + return E_OK;
43244 +}
43245 +
43246 +t_Error FM_PCD_ManipGetStatistics(t_Handle h_ManipNode,
43247 + t_FmPcdManipStats *p_FmPcdManipStats)
43248 +{
43249 + t_FmPcdManip *p_Manip = (t_FmPcdManip *)h_ManipNode;
43250 +
43251 + SANITY_CHECK_RETURN_ERROR(p_Manip, E_INVALID_HANDLE);
43252 + SANITY_CHECK_RETURN_ERROR(p_FmPcdManipStats, E_NULL_POINTER);
43253 +
43254 + switch (p_Manip->opcode)
43255 + {
43256 + case (HMAN_OC_IP_REASSEMBLY):
43257 + return IpReassemblyStats(p_Manip,
43258 + &p_FmPcdManipStats->u.reassem.u.ipReassem);
43259 + case (HMAN_OC_IP_FRAGMENTATION):
43260 + return IpFragmentationStats(p_Manip,
43261 + &p_FmPcdManipStats->u.frag.u.ipFrag);
43262 +#if (DPAA_VERSION >= 11)
43263 + case (HMAN_OC_CAPWAP_REASSEMBLY):
43264 + return CapwapReassemblyStats(
43265 + p_Manip, &p_FmPcdManipStats->u.reassem.u.capwapReassem);
43266 + case (HMAN_OC_CAPWAP_FRAGMENTATION):
43267 + return CapwapFragmentationStats(
43268 + p_Manip, &p_FmPcdManipStats->u.frag.u.capwapFrag);
43269 +#endif /* (DPAA_VERSION >= 11) */
43270 + default:
43271 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED,
43272 + ("no statistics to this type of manip"));
43273 + }
43274 +
43275 + return E_OK;
43276 +}
43277 +
43278 +#if (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10))
43279 +t_Handle FM_PCD_StatisticsSetNode(t_Handle h_FmPcd, t_FmPcdStatsParams *p_StatsParams)
43280 +{
43281 + t_FmPcd *p_FmPcd = (t_FmPcd *)h_FmPcd;
43282 + t_FmPcdManip *p_Manip;
43283 + t_Error err;
43284 +
43285 + SANITY_CHECK_RETURN_VALUE(h_FmPcd,E_INVALID_HANDLE,NULL);
43286 + SANITY_CHECK_RETURN_VALUE(p_StatsParams,E_INVALID_HANDLE,NULL);
43287 +
43288 + p_Manip = ManipOrStatsSetNode(h_FmPcd, (t_Handle)p_StatsParams, TRUE);
43289 + if (!p_Manip)
43290 + return NULL;
43291 +
43292 + switch (p_Manip->opcode)
43293 + {
43294 + case (HMAN_OC_CAPWAP_INDEXED_STATS):
43295 + /* Indexed statistics */
43296 + err = IndxStats(p_StatsParams, p_Manip, p_FmPcd);
43297 + break;
43298 + default:
43299 + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("UNSUPPORTED Statistics type"));
43300 + ReleaseManipHandler(p_Manip, p_FmPcd);
43301 + XX_Free(p_Manip);
43302 + return NULL;
43303 + }
43304 +
43305 + if (err)
43306 + {
43307 + REPORT_ERROR(MAJOR, err, NO_MSG);
43308 + ReleaseManipHandler(p_Manip, p_FmPcd);
43309 + XX_Free(p_Manip);
43310 + return NULL;
43311 + }
43312 +
43313 + return p_Manip;
43314 +}
43315 +#endif /* (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10)) */
43316 --- /dev/null
43317 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/fm_manip.h
43318 @@ -0,0 +1,555 @@
43319 +/*
43320 + * Copyright 2008-2012 Freescale Semiconductor Inc.
43321 + *
43322 + * Redistribution and use in source and binary forms, with or without
43323 + * modification, are permitted provided that the following conditions are met:
43324 + * * Redistributions of source code must retain the above copyright
43325 + * notice, this list of conditions and the following disclaimer.
43326 + * * Redistributions in binary form must reproduce the above copyright
43327 + * notice, this list of conditions and the following disclaimer in the
43328 + * documentation and/or other materials provided with the distribution.
43329 + * * Neither the name of Freescale Semiconductor nor the
43330 + * names of its contributors may be used to endorse or promote products
43331 + * derived from this software without specific prior written permission.
43332 + *
43333 + *
43334 + * ALTERNATIVELY, this software may be distributed under the terms of the
43335 + * GNU General Public License ("GPL") as published by the Free Software
43336 + * Foundation, either version 2 of that License or (at your option) any
43337 + * later version.
43338 + *
43339 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
43340 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
43341 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
43342 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
43343 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
43344 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
43345 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
43346 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
43347 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
43348 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
43349 + */
43350 +
43351 +
43352 +/******************************************************************************
43353 + @File fm_manip.h
43354 +
43355 + @Description FM PCD manip...
43356 +*//***************************************************************************/
43357 +#ifndef __FM_MANIP_H
43358 +#define __FM_MANIP_H
43359 +
43360 +#include "std_ext.h"
43361 +#include "error_ext.h"
43362 +#include "list_ext.h"
43363 +
43364 +#include "fm_cc.h"
43365 +
43366 +
43367 +/***********************************************************************/
43368 +/* Header manipulations defines */
43369 +/***********************************************************************/
43370 +
43371 +#define NUM_OF_SCRATCH_POOL_BUFFERS 1000 /*TODO - Change it!!*/
43372 +
43373 +#if (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10))
43374 +#define HMAN_OC_RMV_N_OR_INSRT_INT_FRM_HDR 0x2e
43375 +#define HMAN_OC_INSRT_HDR_BY_TEMPL_N_OR_FRAG_AFTER 0x31
43376 +#define HMAN_OC_MV_INT_FRAME_HDR_FROM_FRM_TO_BUFFER_PREFFIX 0x2f
43377 +#define HMAN_OC_CAPWAP_RMV_DTLS_IF_EXIST 0x30
43378 +#define HMAN_OC_CAPWAP_REASSEMBLY 0x11 /* dummy */
43379 +#define HMAN_OC_CAPWAP_INDEXED_STATS 0x32 /* dummy */
43380 +#define HMAN_OC_CAPWAP_FRAGMENTATION 0x33
43381 +#else
43382 +#define HMAN_OC_CAPWAP_MANIP 0x2F
43383 +#define HMAN_OC_CAPWAP_FRAG_CHECK 0x2E
43384 +#define HMAN_OC_CAPWAP_FRAGMENTATION 0x33
43385 +#define HMAN_OC_CAPWAP_REASSEMBLY 0x30
43386 +#endif /* (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10)) */
43387 +#define HMAN_OC_IP_MANIP 0x34
43388 +#define HMAN_OC_IP_FRAGMENTATION 0x74
43389 +#define HMAN_OC_IP_REASSEMBLY 0xB4
43390 +#define HMAN_OC_IPSEC_MANIP 0xF4
43391 +#define HMAN_OC 0x35
43392 +
43393 +#if (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10))
43394 +#define HMAN_RMV_HDR 0x80000000
43395 +#define HMAN_INSRT_INT_FRM_HDR 0x40000000
43396 +
43397 +#define UDP_CHECKSUM_FIELD_OFFSET_FROM_UDP 6
43398 +#define UDP_CHECKSUM_FIELD_SIZE 2
43399 +#define UDP_LENGTH_FIELD_OFFSET_FROM_UDP 4
43400 +
43401 +#define IPv4_DSCECN_FIELD_OFFSET_FROM_IP 1
43402 +#define IPv4_TOTALLENGTH_FIELD_OFFSET_FROM_IP 2
43403 +#define IPv4_HDRCHECKSUM_FIELD_OFFSET_FROM_IP 10
43404 +#define VLAN_TAG_FIELD_OFFSET_FROM_ETH 12
43405 +#define IPv4_ID_FIELD_OFFSET_FROM_IP 4
43406 +
43407 +#define IPv6_PAYLOAD_LENGTH_OFFSET_FROM_IP 4
43408 +#define IPv6_NEXT_HEADER_OFFSET_FROM_IP 6
43409 +
43410 +#define FM_PCD_MANIP_CAPWAP_REASM_TABLE_SIZE 0x80
43411 +#define FM_PCD_MANIP_CAPWAP_REASM_TABLE_ALIGN 8
43412 +#define FM_PCD_MANIP_CAPWAP_REASM_RFD_SIZE 32
43413 +#define FM_PCD_MANIP_CAPWAP_REASM_AUTO_LEARNING_HASH_ENTRY_SIZE 4
43414 +#define FM_PCD_MANIP_CAPWAP_REASM_TIME_OUT_ENTRY_SIZE 8
43415 +
43416 +
43417 +#define FM_PCD_MANIP_CAPWAP_REASM_TIME_OUT_BETWEEN_FRAMES 0x40000000
43418 +#define FM_PCD_MANIP_CAPWAP_REASM_HALT_ON_DUPLICATE_FRAG 0x10000000
43419 +#define FM_PCD_MANIP_CAPWAP_REASM_AUTOMATIC_LEARNIN_HASH_8_WAYS 0x08000000
43420 +#define FM_PCD_MANIP_CAPWAP_REASM_PR_COPY 0x00800000
43421 +
43422 +#define FM_PCD_MANIP_CAPWAP_FRAG_COMPR_OPTION_FIELD_EN 0x80000000
43423 +
43424 +#define FM_PCD_MANIP_INDEXED_STATS_ENTRY_SIZE 4
43425 +#define FM_PCD_MANIP_INDEXED_STATS_CNIA 0x20000000
43426 +#define FM_PCD_MANIP_INDEXED_STATS_DPD 0x10000000
43427 +#endif /* (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10)) */
43428 +
43429 +#if (DPAA_VERSION >= 11)
43430 +#define FM_PCD_MANIP_CAPWAP_DTLS 0x00040000
43431 +#define FM_PCD_MANIP_CAPWAP_NADEN 0x20000000
43432 +
43433 +#define FM_PCD_MANIP_CAPWAP_FRAG_CHECK_MTU_SHIFT 16
43434 +#define FM_PCD_MANIP_CAPWAP_FRAG_CHECK_NO_FRAGMENTATION 0xFFFF0000
43435 +#define FM_PCD_MANIP_CAPWAP_FRAG_CHECK_CNIA 0x20000000
43436 +
43437 +#define FM_PCD_MANIP_CAPWAP_FRAG_COMPRESS_EN 0x04000000
43438 +#define FM_PCD_MANIP_CAPWAP_FRAG_SCRATCH_BPID 24
43439 +#define FM_PCD_MANIP_CAPWAP_FRAG_SG_BDID_EN 0x08000000
43440 +#define FM_PCD_MANIP_CAPWAP_FRAG_SG_BDID_MASK 0xFF000000
43441 +#define FM_PCD_MANIP_CAPWAP_FRAG_SG_BDID_SHIFT 24
43442 +#endif /* (DPAA_VERSION >= 11) */
43443 +
43444 +#define FM_PCD_MANIP_REASM_TABLE_SIZE 0x40
43445 +#define FM_PCD_MANIP_REASM_TABLE_ALIGN 8
43446 +
43447 +#define FM_PCD_MANIP_REASM_COMMON_PARAM_TABLE_SIZE 64
43448 +#define FM_PCD_MANIP_REASM_COMMON_PARAM_TABLE_ALIGN 8
43449 +#define FM_PCD_MANIP_REASM_TIME_OUT_BETWEEN_FRAMES 0x80000000
43450 +#define FM_PCD_MANIP_REASM_COUPLING_ENABLE 0x40000000
43451 +#define FM_PCD_MANIP_REASM_COUPLING_MASK 0xFF000000
43452 +#define FM_PCD_MANIP_REASM_COUPLING_SHIFT 24
43453 +#define FM_PCD_MANIP_REASM_LIODN_MASK 0x0000003F
43454 +#define FM_PCD_MANIP_REASM_LIODN_SHIFT 56
43455 +#define FM_PCD_MANIP_REASM_ELIODN_MASK 0x000003c0
43456 +#define FM_PCD_MANIP_REASM_ELIODN_SHIFT 38
43457 +#define FM_PCD_MANIP_REASM_COMMON_INT_BUFFER_IDX_MASK 0x000000FF
43458 +#define FM_PCD_MANIP_REASM_COMMON_INT_BUFFER_IDX_SHIFT 24
43459 +#define FM_PCD_MANIP_REASM_TIMEOUT_THREAD_THRESH 1024
43460 +
43461 +#define FM_PCD_MANIP_IP_MTU_SHIFT 16
43462 +#define FM_PCD_MANIP_IP_NO_FRAGMENTATION 0xFFFF0000
43463 +#define FM_PCD_MANIP_IP_CNIA 0x20000000
43464 +
43465 +#define FM_PCD_MANIP_IP_FRAG_DF_SHIFT 28
43466 +#define FM_PCD_MANIP_IP_FRAG_SCRATCH_BPID 24
43467 +#define FM_PCD_MANIP_IP_FRAG_SG_BDID_EN 0x08000000
43468 +#define FM_PCD_MANIP_IP_FRAG_SG_BDID_MASK 0xFF000000
43469 +#define FM_PCD_MANIP_IP_FRAG_SG_BDID_SHIFT 24
43470 +
43471 +#define FM_PCD_MANIP_IPSEC_DEC 0x10000000
43472 +#define FM_PCD_MANIP_IPSEC_VIPV_EN 0x08000000
43473 +#define FM_PCD_MANIP_IPSEC_ECN_EN 0x04000000
43474 +#define FM_PCD_MANIP_IPSEC_DSCP_EN 0x02000000
43475 +#define FM_PCD_MANIP_IPSEC_VIPL_EN 0x01000000
43476 +#define FM_PCD_MANIP_IPSEC_NADEN 0x20000000
43477 +
43478 +#define FM_PCD_MANIP_IPSEC_IP_HDR_LEN_MASK 0x00FF0000
43479 +#define FM_PCD_MANIP_IPSEC_IP_HDR_LEN_SHIFT 16
43480 +
43481 +#define FM_PCD_MANIP_IPSEC_ARW_SIZE_MASK 0xFFFF0000
43482 +#define FM_PCD_MANIP_IPSEC_ARW_SIZE_SHIFT 16
43483 +
43484 +#define e_FM_MANIP_IP_INDX 1
43485 +
43486 +#define HMCD_OPCODE_GENERIC_RMV 0x01
43487 +#define HMCD_OPCODE_GENERIC_INSRT 0x02
43488 +#define HMCD_OPCODE_GENERIC_REPLACE 0x05
43489 +#define HMCD_OPCODE_L2_RMV 0x08
43490 +#define HMCD_OPCODE_L2_INSRT 0x09
43491 +#define HMCD_OPCODE_VLAN_PRI_UPDATE 0x0B
43492 +#define HMCD_OPCODE_IPV4_UPDATE 0x0C
43493 +#define HMCD_OPCODE_IPV6_UPDATE 0x10
43494 +#define HMCD_OPCODE_TCP_UDP_UPDATE 0x0E
43495 +#define HMCD_OPCODE_TCP_UDP_CHECKSUM 0x14
43496 +#define HMCD_OPCODE_REPLACE_IP 0x12
43497 +#define HMCD_OPCODE_RMV_TILL 0x15
43498 +#define HMCD_OPCODE_UDP_INSRT 0x16
43499 +#define HMCD_OPCODE_IP_INSRT 0x17
43500 +#define HMCD_OPCODE_CAPWAP_RMV 0x18
43501 +#define HMCD_OPCODE_CAPWAP_INSRT 0x18
43502 +#define HMCD_OPCODE_GEN_FIELD_REPLACE 0x19
43503 +
43504 +#define HMCD_LAST 0x00800000
43505 +
43506 +#define HMCD_DSCP_VALUES 64
43507 +
43508 +#define HMCD_BASIC_SIZE 4
43509 +#define HMCD_PTR_SIZE 4
43510 +#define HMCD_PARAM_SIZE 4
43511 +#define HMCD_IPV4_ADDR_SIZE 4
43512 +#define HMCD_IPV6_ADDR_SIZE 0x10
43513 +#define HMCD_L4_HDR_SIZE 8
43514 +
43515 +#define HMCD_CAPWAP_INSRT 0x00010000
43516 +#define HMCD_INSRT_UDP_LITE 0x00010000
43517 +#define HMCD_IP_ID_MASK 0x0000FFFF
43518 +#define HMCD_IP_SIZE_MASK 0x0000FF00
43519 +#define HMCD_IP_SIZE_SHIFT 8
43520 +#define HMCD_IP_LAST_PID_MASK 0x000000FF
43521 +#define HMCD_IP_OR_QOS 0x00010000
43522 +#define HMCD_IP_L4_CS_CALC 0x00040000
43523 +#define HMCD_IP_DF_MODE 0x00400000
43524 +
43525 +
43526 +#define HMCD_OC_SHIFT 24
43527 +
43528 +#define HMCD_RMV_OFFSET_SHIFT 0
43529 +#define HMCD_RMV_SIZE_SHIFT 8
43530 +
43531 +#define HMCD_INSRT_OFFSET_SHIFT 0
43532 +#define HMCD_INSRT_SIZE_SHIFT 8
43533 +
43534 +#define HMTD_CFG_TYPE 0x4000
43535 +#define HMTD_CFG_EXT_HMCT 0x0080
43536 +#define HMTD_CFG_PRS_AFTER_HM 0x0040
43537 +#define HMTD_CFG_NEXT_AD_EN 0x0020
43538 +
43539 +#define HMCD_RMV_L2_ETHERNET 0
43540 +#define HMCD_RMV_L2_STACKED_QTAGS 1
43541 +#define HMCD_RMV_L2_ETHERNET_AND_MPLS 2
43542 +#define HMCD_RMV_L2_MPLS 3
43543 +#define HMCD_RMV_L2_PPPOE 4
43544 +
43545 +#define HMCD_INSRT_L2_MPLS 0
43546 +#define HMCD_INSRT_N_UPDATE_L2_MPLS 1
43547 +#define HMCD_INSRT_L2_PPPOE 2
43548 +#define HMCD_INSRT_L2_SIZE_SHIFT 24
43549 +
43550 +#define HMCD_L2_MODE_SHIFT 16
43551 +
43552 +#define HMCD_VLAN_PRI_REP_MODE_SHIFT 16
43553 +#define HMCD_VLAN_PRI_UPDATE 0
43554 +#define HMCD_VLAN_PRI_UPDATE_DSCP_TO_VPRI 1
43555 +
43556 +#define HMCD_IPV4_UPDATE_TTL 0x00000001
43557 +#define HMCD_IPV4_UPDATE_TOS 0x00000002
43558 +#define HMCD_IPV4_UPDATE_DST 0x00000020
43559 +#define HMCD_IPV4_UPDATE_SRC 0x00000040
43560 +#define HMCD_IPV4_UPDATE_ID 0x00000080
43561 +#define HMCD_IPV4_UPDATE_TOS_SHIFT 8
43562 +
43563 +#define HMCD_IPV6_UPDATE_HL 0x00000001
43564 +#define HMCD_IPV6_UPDATE_TC 0x00000002
43565 +#define HMCD_IPV6_UPDATE_DST 0x00000040
43566 +#define HMCD_IPV6_UPDATE_SRC 0x00000080
43567 +#define HMCD_IPV6_UPDATE_TC_SHIFT 8
43568 +
43569 +#define HMCD_TCP_UDP_UPDATE_DST 0x00004000
43570 +#define HMCD_TCP_UDP_UPDATE_SRC 0x00008000
43571 +#define HMCD_TCP_UDP_UPDATE_SRC_SHIFT 16
43572 +
43573 +#define HMCD_IP_REPLACE_REPLACE_IPV4 0x00000000
43574 +#define HMCD_IP_REPLACE_REPLACE_IPV6 0x00010000
43575 +#define HMCD_IP_REPLACE_TTL_HL 0x00200000
43576 +#define HMCD_IP_REPLACE_ID 0x00400000
43577 +
43578 +#define HMCD_IP_REPLACE_L3HDRSIZE_SHIFT 24
43579 +
43580 +#define HMCD_GEN_FIELD_SIZE_SHIFT 16
43581 +#define HMCD_GEN_FIELD_SRC_OFF_SHIFT 8
43582 +#define HMCD_GEN_FIELD_DST_OFF_SHIFT 0
43583 +#define HMCD_GEN_FIELD_MASK_EN 0x00400000
43584 +
43585 +#define HMCD_GEN_FIELD_MASK_OFF_SHIFT 16
43586 +#define HMCD_GEN_FIELD_MASK_SHIFT 24
43587 +
43588 +#define DSCP_TO_VLAN_TABLE_SIZE 32
43589 +
43590 +#define MANIP_GET_HMCT_SIZE(h_Manip) (((t_FmPcdManip *)h_Manip)->tableSize)
43591 +#define MANIP_GET_DATA_SIZE(h_Manip) (((t_FmPcdManip *)h_Manip)->dataSize)
43592 +
43593 +#define MANIP_GET_HMCT_PTR(h_Manip) (((t_FmPcdManip *)h_Manip)->p_Hmct)
43594 +#define MANIP_GET_DATA_PTR(h_Manip) (((t_FmPcdManip *)h_Manip)->p_Data)
43595 +
43596 +#define MANIP_SET_HMCT_PTR(h_Manip, h_NewPtr) (((t_FmPcdManip *)h_Manip)->p_Hmct = h_NewPtr)
43597 +#define MANIP_SET_DATA_PTR(h_Manip, h_NewPtr) (((t_FmPcdManip *)h_Manip)->p_Data = h_NewPtr)
43598 +
43599 +#define MANIP_GET_HMTD_PTR(h_Manip) (((t_FmPcdManip *)h_Manip)->h_Ad)
43600 +#define MANIP_DONT_REPARSE(h_Manip) (((t_FmPcdManip *)h_Manip)->dontParseAfterManip)
43601 +#define MANIP_SET_PREV(h_Manip, h_Prev) (((t_FmPcdManip *)h_Manip)->h_PrevManip = h_Prev)
43602 +#define MANIP_GET_OWNERS(h_Manip) (((t_FmPcdManip *)h_Manip)->owner)
43603 +#define MANIP_GET_TYPE(h_Manip) (((t_FmPcdManip *)h_Manip)->type)
43604 +#define MANIP_SET_UNIFIED_TBL_PTR_INDICATION(h_Manip) (((t_FmPcdManip *)h_Manip)->unifiedTablePtr = TRUE)
43605 +#define MANIP_GET_MURAM(h_Manip) (((t_FmPcd *)((t_FmPcdManip *)h_Manip)->h_FmPcd)->h_FmMuram)
43606 +#define MANIP_FREE_HMTD(h_Manip) \
43607 + {if (((t_FmPcdManip *)h_Manip)->muramAllocate) \
43608 + FM_MURAM_FreeMem(((t_FmPcd *)((t_FmPcdManip *)h_Manip)->h_FmPcd)->h_FmMuram, ((t_FmPcdManip *)h_Manip)->h_Ad);\
43609 + else \
43610 + XX_Free(((t_FmPcdManip *)h_Manip)->h_Ad); \
43611 + ((t_FmPcdManip *)h_Manip)->h_Ad = NULL; \
43612 + }
43613 +/* position regarding Manip SW structure */
43614 +#define MANIP_IS_FIRST(h_Manip) (!(((t_FmPcdManip *)h_Manip)->h_PrevManip))
43615 +#define MANIP_IS_CASCADED(h_Manip) (((t_FmPcdManip *)h_Manip)->cascaded)
43616 +#define MANIP_IS_UNIFIED(h_Manip) (!(((t_FmPcdManip *)h_Manip)->unifiedPosition == e_MANIP_UNIFIED_NONE))
43617 +#define MANIP_IS_UNIFIED_NON_FIRST(h_Manip) ((((t_FmPcdManip *)h_Manip)->unifiedPosition == e_MANIP_UNIFIED_MID) || \
43618 + (((t_FmPcdManip *)h_Manip)->unifiedPosition == e_MANIP_UNIFIED_LAST))
43619 +#define MANIP_IS_UNIFIED_NON_LAST(h_Manip) ((((t_FmPcdManip *)h_Manip)->unifiedPosition == e_MANIP_UNIFIED_FIRST) ||\
43620 + (((t_FmPcdManip *)h_Manip)->unifiedPosition == e_MANIP_UNIFIED_MID))
43621 +#define MANIP_IS_UNIFIED_FIRST(h_Manip) (((t_FmPcdManip *)h_Manip)->unifiedPosition == e_MANIP_UNIFIED_FIRST)
43622 +#define MANIP_IS_UNIFIED_LAST(h_Manip) (((t_FmPcdManip *)h_Manip)->unifiedPosition == e_MANIP_UNIFIED_LAST)
43623 +
43624 +#define MANIP_UPDATE_UNIFIED_POSITION(h_Manip) (((t_FmPcdManip *)h_Manip)->unifiedPosition = \
43625 + (((t_FmPcdManip *)h_Manip)->unifiedPosition == e_MANIP_UNIFIED_NONE)? \
43626 + e_MANIP_UNIFIED_LAST : e_MANIP_UNIFIED_MID)
43627 +
43628 +typedef enum e_ManipUnifiedPosition {
43629 + e_MANIP_UNIFIED_NONE = 0,
43630 + e_MANIP_UNIFIED_FIRST,
43631 + e_MANIP_UNIFIED_MID,
43632 + e_MANIP_UNIFIED_LAST
43633 +} e_ManipUnifiedPosition;
43634 +
43635 +typedef enum e_ManipInfo {
43636 + e_MANIP_HMTD,
43637 + e_MANIP_HMCT,
43638 + e_MANIP_HANDLER_TABLE_OWNER
43639 +}e_ManipInfo;
43640 +/***********************************************************************/
43641 +/* Memory map */
43642 +/***********************************************************************/
43643 +#if defined(__MWERKS__) && !defined(__GNUC__)
43644 +#pragma pack(push,1)
43645 +#endif /* defined(__MWERKS__) && ... */
43646 +
43647 +#if (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10))
43648 +typedef struct t_CapwapReasmPram {
43649 + volatile uint32_t mode;
43650 + volatile uint32_t autoLearnHashTblPtr;
43651 + volatile uint32_t intStatsTblPtr;
43652 + volatile uint32_t reasmFrmDescPoolTblPtr;
43653 + volatile uint32_t reasmFrmDescIndexPoolTblPtr;
43654 + volatile uint32_t timeOutTblPtr;
43655 + volatile uint32_t bufferPoolIdAndRisc1SetIndexes;
43656 + volatile uint32_t risc23SetIndexes;
43657 + volatile uint32_t risc4SetIndexesAndExtendedStatsTblPtr;
43658 + volatile uint32_t extendedStatsTblPtr;
43659 + volatile uint32_t expirationDelay;
43660 + volatile uint32_t totalProcessedFragCounter;
43661 + volatile uint32_t totalUnsuccessfulReasmFramesCounter;
43662 + volatile uint32_t totalDuplicatedFragCounter;
43663 + volatile uint32_t totalMalformdFragCounter;
43664 + volatile uint32_t totalTimeOutCounter;
43665 + volatile uint32_t totalSetBusyCounter;
43666 + volatile uint32_t totalRfdPoolBusyCounter;
43667 + volatile uint32_t totalDiscardedFragsCounter;
43668 + volatile uint32_t totalMoreThan16FramesCounter;
43669 + volatile uint32_t internalBufferBusy;
43670 + volatile uint32_t externalBufferBusy;
43671 + volatile uint32_t reserved1[4];
43672 +} t_CapwapReasmPram;
43673 +#endif /* (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10)) */
43674 +
43675 +typedef _Packed struct t_ReassTbl {
43676 + volatile uint16_t waysNumAndSetSize;
43677 + volatile uint16_t autoLearnHashKeyMask;
43678 + volatile uint32_t reassCommonPrmTblPtr;
43679 + volatile uint32_t liodnAlAndAutoLearnHashTblPtrHi;
43680 + volatile uint32_t autoLearnHashTblPtrLow;
43681 + volatile uint32_t liodnSlAndAutoLearnSetLockTblPtrHi;
43682 + volatile uint32_t autoLearnSetLockTblPtrLow;
43683 + volatile uint16_t minFragSize; /* Not relevant for CAPWAP*/
43684 + volatile uint16_t maxReassemblySize; /* Only relevant for CAPWAP*/
43685 + volatile uint32_t totalSuccessfullyReasmFramesCounter;
43686 + volatile uint32_t totalValidFragmentCounter;
43687 + volatile uint32_t totalProcessedFragCounter;
43688 + volatile uint32_t totalMalformdFragCounter;
43689 + volatile uint32_t totalSetBusyCounter;
43690 + volatile uint32_t totalDiscardedFragsCounter;
43691 + volatile uint32_t totalMoreThan16FramesCounter;
43692 + volatile uint32_t reserved2[2];
43693 +} _PackedType t_ReassTbl;
43694 +
43695 +typedef struct t_ReassCommonTbl {
43696 + volatile uint32_t timeoutModeAndFqid;
43697 + volatile uint32_t reassFrmDescIndexPoolTblPtr;
43698 + volatile uint32_t liodnAndReassFrmDescPoolPtrHi;
43699 + volatile uint32_t reassFrmDescPoolPtrLow;
43700 + volatile uint32_t timeOutTblPtr;
43701 + volatile uint32_t expirationDelay;
43702 + volatile uint32_t internalBufferManagement;
43703 + volatile uint32_t reserved2;
43704 + volatile uint32_t totalTimeOutCounter;
43705 + volatile uint32_t totalRfdPoolBusyCounter;
43706 + volatile uint32_t totalInternalBufferBusy;
43707 + volatile uint32_t totalExternalBufferBusy;
43708 + volatile uint32_t totalSgFragmentCounter;
43709 + volatile uint32_t totalDmaSemaphoreDepletionCounter;
43710 + volatile uint32_t totalNCSPCounter;
43711 + volatile uint32_t discardMask;
43712 +} t_ReassCommonTbl;
43713 +
43714 +typedef _Packed struct t_Hmtd {
43715 + volatile uint16_t cfg;
43716 + volatile uint8_t eliodnOffset;
43717 + volatile uint8_t extHmcdBasePtrHi;
43718 + volatile uint32_t hmcdBasePtr;
43719 + volatile uint16_t nextAdIdx;
43720 + volatile uint8_t res1;
43721 + volatile uint8_t opCode;
43722 + volatile uint32_t res2;
43723 +} _PackedType t_Hmtd;
43724 +
43725 +#if defined(__MWERKS__) && !defined(__GNUC__)
43726 +#pragma pack(pop)
43727 +#endif /* defined(__MWERKS__) && ... */
43728 +
43729 +
43730 +/***********************************************************************/
43731 +/* Driver's internal structures */
43732 +/***********************************************************************/
43733 +#if (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10))
43734 +typedef struct
43735 +{
43736 + t_Handle p_AutoLearnHashTbl;
43737 + t_Handle p_ReassmFrmDescrPoolTbl;
43738 + t_Handle p_ReassmFrmDescrIndxPoolTbl;
43739 + t_Handle p_TimeOutTbl;
43740 + uint16_t maxNumFramesInProcess;
43741 + uint8_t numOfTasks;
43742 + //uint8_t poolId;
43743 + uint8_t prOffset;
43744 + uint16_t dataOffset;
43745 + uint8_t sgBpid;
43746 + uint8_t hwPortId;
43747 + uint32_t fqidForTimeOutFrames;
43748 + uint32_t timeoutRoutineRequestTime;
43749 + uint32_t bitFor1Micro;
43750 +} t_CapwapFragParams;
43751 +#endif /* (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10)) */
43752 +
43753 +typedef struct
43754 +{
43755 + t_AdOfTypeContLookup *p_Frag;
43756 +#if (DPAA_VERSION == 10)
43757 + uint8_t scratchBpid;
43758 +#endif /* (DPAA_VERSION == 10) */
43759 +} t_FragParams;
43760 +
43761 +typedef struct t_ReassmParams
43762 +{
43763 + e_NetHeaderType hdr; /* Header selection */
43764 + t_ReassCommonTbl *p_ReassCommonTbl;
43765 + uintptr_t reassFrmDescrIndxPoolTblAddr;
43766 + uintptr_t reassFrmDescrPoolTblAddr;
43767 + uintptr_t timeOutTblAddr;
43768 + uintptr_t internalBufferPoolManagementIndexAddr;
43769 + uintptr_t internalBufferPoolAddr;
43770 + uint32_t maxNumFramesInProcess;
43771 + uint8_t sgBpid;
43772 + uint8_t dataMemId;
43773 + uint16_t dataLiodnOffset;
43774 + uint32_t fqidForTimeOutFrames;
43775 + e_FmPcdManipReassemTimeOutMode timeOutMode;
43776 + uint32_t timeoutThresholdForReassmProcess;
43777 + union {
43778 + struct {
43779 + t_Handle h_Ipv4Ad;
43780 + t_Handle h_Ipv6Ad;
43781 + bool ipv6Assigned;
43782 + t_ReassTbl *p_Ipv4ReassTbl;
43783 + t_ReassTbl *p_Ipv6ReassTbl;
43784 + uintptr_t ipv4AutoLearnHashTblAddr;
43785 + uintptr_t ipv6AutoLearnHashTblAddr;
43786 + uintptr_t ipv4AutoLearnSetLockTblAddr;
43787 + uintptr_t ipv6AutoLearnSetLockTblAddr;
43788 + uint16_t minFragSize[2];
43789 + e_FmPcdManipReassemWaysNumber numOfFramesPerHashEntry[2];
43790 + uint8_t relativeSchemeId[2];
43791 + t_Handle h_Ipv4Scheme;
43792 + t_Handle h_Ipv6Scheme;
43793 + uint32_t nonConsistentSpFqid;
43794 + } ip;
43795 + struct {
43796 + t_Handle h_Ad;
43797 + t_ReassTbl *p_ReassTbl;
43798 + uintptr_t autoLearnHashTblAddr;
43799 + uintptr_t autoLearnSetLockTblAddr;
43800 + uint16_t maxRessembledsSize;
43801 + e_FmPcdManipReassemWaysNumber numOfFramesPerHashEntry;
43802 + uint8_t relativeSchemeId;
43803 + t_Handle h_Scheme;
43804 + } capwap;
43805 + };
43806 +} t_ReassmParams;
43807 +
43808 +typedef struct{
43809 + e_FmPcdManipType type;
43810 + t_FmPcdManipParams manipParams;
43811 + bool muramAllocate;
43812 + t_Handle h_Ad;
43813 + uint32_t opcode;
43814 + bool rmv;
43815 + bool insrt;
43816 + t_Handle h_NextManip;
43817 + t_Handle h_PrevManip;
43818 + e_FmPcdManipType nextManipType;
43819 + /* HdrManip parameters*/
43820 + uint8_t *p_Hmct;
43821 + uint8_t *p_Data;
43822 + bool dontParseAfterManip;
43823 + bool fieldUpdate;
43824 + bool custom;
43825 + uint16_t tableSize;
43826 + uint8_t dataSize;
43827 + bool cascaded;
43828 + e_ManipUnifiedPosition unifiedPosition;
43829 + /* end HdrManip */
43830 + uint8_t *p_Template;
43831 + uint16_t owner;
43832 + uint32_t updateParams;
43833 + uint32_t shadowUpdateParams;
43834 + bool frag;
43835 + bool reassm;
43836 + uint16_t sizeForFragmentation;
43837 +#if (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10))
43838 + t_Handle h_Frag;
43839 + t_CapwapFragParams capwapFragParams;
43840 +#endif /* (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10)) */
43841 + union {
43842 + t_ReassmParams reassmParams;
43843 + t_FragParams fragParams;
43844 + };
43845 + uint8_t icOffset;
43846 + uint16_t ownerTmp;
43847 + bool cnia;
43848 + t_Handle p_StatsTbl;
43849 + t_Handle h_FmPcd;
43850 + t_List nodesLst;
43851 + t_Handle h_Spinlock;
43852 +} t_FmPcdManip;
43853 +
43854 +typedef struct t_FmPcdCcSavedManipParams
43855 +{
43856 + union
43857 + {
43858 + struct
43859 + {
43860 + uint16_t dataOffset;
43861 + //uint8_t poolId;
43862 + }capwapParams;
43863 + struct
43864 + {
43865 + uint16_t dataOffset;
43866 + uint8_t poolId;
43867 + }ipParams;
43868 + };
43869 +
43870 +} t_FmPcdCcSavedManipParams;
43871 +
43872 +
43873 +#endif /* __FM_MANIP_H */
43874 --- /dev/null
43875 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/fm_pcd.c
43876 @@ -0,0 +1,2095 @@
43877 +/*
43878 + * Copyright 2008-2012 Freescale Semiconductor Inc.
43879 + *
43880 + * Redistribution and use in source and binary forms, with or without
43881 + * modification, are permitted provided that the following conditions are met:
43882 + * * Redistributions of source code must retain the above copyright
43883 + * notice, this list of conditions and the following disclaimer.
43884 + * * Redistributions in binary form must reproduce the above copyright
43885 + * notice, this list of conditions and the following disclaimer in the
43886 + * documentation and/or other materials provided with the distribution.
43887 + * * Neither the name of Freescale Semiconductor nor the
43888 + * names of its contributors may be used to endorse or promote products
43889 + * derived from this software without specific prior written permission.
43890 + *
43891 + *
43892 + * ALTERNATIVELY, this software may be distributed under the terms of the
43893 + * GNU General Public License ("GPL") as published by the Free Software
43894 + * Foundation, either version 2 of that License or (at your option) any
43895 + * later version.
43896 + *
43897 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
43898 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
43899 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
43900 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
43901 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
43902 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
43903 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
43904 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
43905 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
43906 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
43907 + */
43908 +
43909 +
43910 +/******************************************************************************
43911 + @File fm_pcd.c
43912 +
43913 + @Description FM PCD ...
43914 +*//***************************************************************************/
43915 +#include "std_ext.h"
43916 +#include "error_ext.h"
43917 +#include "string_ext.h"
43918 +#include "xx_ext.h"
43919 +#include "sprint_ext.h"
43920 +#include "debug_ext.h"
43921 +#include "net_ext.h"
43922 +#include "fm_ext.h"
43923 +#include "fm_pcd_ext.h"
43924 +
43925 +#include "fm_common.h"
43926 +#include "fm_pcd.h"
43927 +#include "fm_pcd_ipc.h"
43928 +#include "fm_hc.h"
43929 +#include "fm_muram_ext.h"
43930 +
43931 +
43932 +/****************************************/
43933 +/* static functions */
43934 +/****************************************/
43935 +
43936 +static t_Error CheckFmPcdParameters(t_FmPcd *p_FmPcd)
43937 +{
43938 + if (!p_FmPcd->h_Fm)
43939 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("h_Fm has to be initialized"));
43940 +
43941 + if (p_FmPcd->guestId == NCSW_MASTER_ID)
43942 + {
43943 + if (p_FmPcd->p_FmPcdKg && !p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs)
43944 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Something WRONG"));
43945 +
43946 + if (p_FmPcd->p_FmPcdPlcr && !p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs)
43947 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Something WRONG"));
43948 +
43949 + if (!p_FmPcd->f_Exception)
43950 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("f_FmPcdExceptions has to be initialized"));
43951 +
43952 + if ((!p_FmPcd->f_FmPcdIndexedException) && (p_FmPcd->p_FmPcdPlcr || p_FmPcd->p_FmPcdKg))
43953 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("f_FmPcdIndexedException has to be initialized"));
43954 +
43955 + if (p_FmPcd->p_FmPcdDriverParam->prsMaxParseCycleLimit > PRS_MAX_CYCLE_LIMIT)
43956 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("prsMaxParseCycleLimit has to be less than 8191"));
43957 + }
43958 +
43959 + return E_OK;
43960 +}
43961 +
43962 +static volatile bool blockingFlag = FALSE;
43963 +static void IpcMsgCompletionCB(t_Handle h_FmPcd,
43964 + uint8_t *p_Msg,
43965 + uint8_t *p_Reply,
43966 + uint32_t replyLength,
43967 + t_Error status)
43968 +{
43969 + UNUSED(h_FmPcd);UNUSED(p_Msg);UNUSED(p_Reply);UNUSED(replyLength);UNUSED(status);
43970 + blockingFlag = FALSE;
43971 +}
43972 +
43973 +static t_Error IpcMsgHandlerCB(t_Handle h_FmPcd,
43974 + uint8_t *p_Msg,
43975 + uint32_t msgLength,
43976 + uint8_t *p_Reply,
43977 + uint32_t *p_ReplyLength)
43978 +{
43979 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
43980 + t_Error err = E_OK;
43981 + t_FmPcdIpcMsg *p_IpcMsg = (t_FmPcdIpcMsg*)p_Msg;
43982 + t_FmPcdIpcReply *p_IpcReply = (t_FmPcdIpcReply*)p_Reply;
43983 +
43984 + SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);
43985 + SANITY_CHECK_RETURN_ERROR((msgLength >= sizeof(uint32_t)), E_INVALID_VALUE);
43986 +
43987 +#ifdef DISABLE_SANITY_CHECKS
43988 + UNUSED(msgLength);
43989 +#endif /* DISABLE_SANITY_CHECKS */
43990 +
43991 + ASSERT_COND(p_Msg);
43992 +
43993 + memset(p_IpcReply, 0, (sizeof(uint8_t) * FM_PCD_MAX_REPLY_SIZE));
43994 + *p_ReplyLength = 0;
43995 +
43996 + switch (p_IpcMsg->msgId)
43997 + {
43998 + case (FM_PCD_MASTER_IS_ALIVE):
43999 + *(uint8_t*)(p_IpcReply->replyBody) = 1;
44000 + p_IpcReply->error = E_OK;
44001 + *p_ReplyLength = sizeof(uint32_t) + sizeof(uint8_t);
44002 + break;
44003 + case (FM_PCD_MASTER_IS_ENABLED):
44004 + /* count partitions registrations */
44005 + if (p_FmPcd->enabled)
44006 + p_FmPcd->numOfEnabledGuestPartitionsPcds++;
44007 + *(uint8_t*)(p_IpcReply->replyBody) = (uint8_t)p_FmPcd->enabled;
44008 + p_IpcReply->error = E_OK;
44009 + *p_ReplyLength = sizeof(uint32_t) + sizeof(uint8_t);
44010 + break;
44011 + case (FM_PCD_GUEST_DISABLE):
44012 + if (p_FmPcd->numOfEnabledGuestPartitionsPcds)
44013 + {
44014 + p_FmPcd->numOfEnabledGuestPartitionsPcds--;
44015 + p_IpcReply->error = E_OK;
44016 + }
44017 + else
44018 + {
44019 + REPORT_ERROR(MINOR, E_INVALID_STATE,("Trying to disable an unregistered partition"));
44020 + p_IpcReply->error = E_INVALID_STATE;
44021 + }
44022 + *p_ReplyLength = sizeof(uint32_t);
44023 + break;
44024 + case (FM_PCD_GET_COUNTER):
44025 + {
44026 + e_FmPcdCounters inCounter;
44027 + uint32_t outCounter;
44028 +
44029 + memcpy((uint8_t*)&inCounter, p_IpcMsg->msgBody, sizeof(uint32_t));
44030 + outCounter = FM_PCD_GetCounter(h_FmPcd, inCounter);
44031 + memcpy(p_IpcReply->replyBody, (uint8_t*)&outCounter, sizeof(uint32_t));
44032 + p_IpcReply->error = E_OK;
44033 + *p_ReplyLength = sizeof(uint32_t) + sizeof(uint32_t);
44034 + break;
44035 + }
44036 + case (FM_PCD_ALLOC_KG_SCHEMES):
44037 + {
44038 + t_FmPcdIpcKgSchemesParams ipcSchemesParams;
44039 +
44040 + memcpy((uint8_t*)&ipcSchemesParams, p_IpcMsg->msgBody, sizeof(t_FmPcdIpcKgSchemesParams));
44041 + err = FmPcdKgAllocSchemes(h_FmPcd,
44042 + ipcSchemesParams.numOfSchemes,
44043 + ipcSchemesParams.guestId,
44044 + p_IpcReply->replyBody);
44045 + p_IpcReply->error = err;
44046 + *p_ReplyLength = sizeof(uint32_t) + ipcSchemesParams.numOfSchemes*sizeof(uint8_t);
44047 + break;
44048 + }
44049 + case (FM_PCD_FREE_KG_SCHEMES):
44050 + {
44051 + t_FmPcdIpcKgSchemesParams ipcSchemesParams;
44052 +
44053 + memcpy((uint8_t*)&ipcSchemesParams, p_IpcMsg->msgBody, sizeof(t_FmPcdIpcKgSchemesParams));
44054 + err = FmPcdKgFreeSchemes(h_FmPcd,
44055 + ipcSchemesParams.numOfSchemes,
44056 + ipcSchemesParams.guestId,
44057 + ipcSchemesParams.schemesIds);
44058 + p_IpcReply->error = err;
44059 + *p_ReplyLength = sizeof(uint32_t);
44060 + break;
44061 + }
44062 + case (FM_PCD_ALLOC_KG_CLSPLAN):
44063 + {
44064 + t_FmPcdIpcKgClsPlanParams ipcKgClsPlanParams;
44065 +
44066 + memcpy((uint8_t*)&ipcKgClsPlanParams, p_IpcMsg->msgBody, sizeof(t_FmPcdIpcKgClsPlanParams));
44067 + err = KgAllocClsPlanEntries(h_FmPcd,
44068 + ipcKgClsPlanParams.numOfClsPlanEntries,
44069 + ipcKgClsPlanParams.guestId,
44070 + p_IpcReply->replyBody);
44071 + p_IpcReply->error = err;
44072 + *p_ReplyLength = sizeof(uint32_t) + sizeof(uint8_t);
44073 + break;
44074 + }
44075 + case (FM_PCD_FREE_KG_CLSPLAN):
44076 + {
44077 + t_FmPcdIpcKgClsPlanParams ipcKgClsPlanParams;
44078 +
44079 + memcpy((uint8_t*)&ipcKgClsPlanParams, p_IpcMsg->msgBody, sizeof(t_FmPcdIpcKgClsPlanParams));
44080 + KgFreeClsPlanEntries(h_FmPcd,
44081 + ipcKgClsPlanParams.numOfClsPlanEntries,
44082 + ipcKgClsPlanParams.guestId,
44083 + ipcKgClsPlanParams.clsPlanBase);
44084 + *p_ReplyLength = sizeof(uint32_t);
44085 + break;
44086 + }
44087 + case (FM_PCD_ALLOC_PROFILES):
44088 + {
44089 + t_FmIpcResourceAllocParams ipcAllocParams;
44090 + uint16_t base;
44091 + memcpy(&ipcAllocParams, p_IpcMsg->msgBody, sizeof(t_FmIpcResourceAllocParams));
44092 + base = PlcrAllocProfilesForPartition(h_FmPcd,
44093 + ipcAllocParams.base,
44094 + ipcAllocParams.num,
44095 + ipcAllocParams.guestId);
44096 + memcpy(p_IpcReply->replyBody, (uint16_t*)&base, sizeof(uint16_t));
44097 + *p_ReplyLength = sizeof(uint32_t) + sizeof(uint16_t);
44098 + break;
44099 + }
44100 + case (FM_PCD_FREE_PROFILES):
44101 + {
44102 + t_FmIpcResourceAllocParams ipcAllocParams;
44103 + memcpy(&ipcAllocParams, p_IpcMsg->msgBody, sizeof(t_FmIpcResourceAllocParams));
44104 + PlcrFreeProfilesForPartition(h_FmPcd,
44105 + ipcAllocParams.base,
44106 + ipcAllocParams.num,
44107 + ipcAllocParams.guestId);
44108 + break;
44109 + }
44110 + case (FM_PCD_SET_PORT_PROFILES):
44111 + {
44112 + t_FmIpcResourceAllocParams ipcAllocParams;
44113 + memcpy(&ipcAllocParams, p_IpcMsg->msgBody, sizeof(t_FmIpcResourceAllocParams));
44114 + PlcrSetPortProfiles(h_FmPcd,
44115 + ipcAllocParams.guestId,
44116 + ipcAllocParams.num,
44117 + ipcAllocParams.base);
44118 + break;
44119 + }
44120 + case (FM_PCD_CLEAR_PORT_PROFILES):
44121 + {
44122 + t_FmIpcResourceAllocParams ipcAllocParams;
44123 + memcpy(&ipcAllocParams, p_IpcMsg->msgBody, sizeof(t_FmIpcResourceAllocParams));
44124 + PlcrClearPortProfiles(h_FmPcd,
44125 + ipcAllocParams.guestId);
44126 + break;
44127 + }
44128 + case (FM_PCD_GET_SW_PRS_OFFSET):
44129 + {
44130 + t_FmPcdIpcSwPrsLable ipcSwPrsLable;
44131 + uint32_t swPrsOffset;
44132 +
44133 + memcpy((uint8_t*)&ipcSwPrsLable, p_IpcMsg->msgBody, sizeof(t_FmPcdIpcSwPrsLable));
44134 + swPrsOffset =
44135 + FmPcdGetSwPrsOffset(h_FmPcd,
44136 + (e_NetHeaderType)ipcSwPrsLable.enumHdr,
44137 + ipcSwPrsLable.indexPerHdr);
44138 + memcpy(p_IpcReply->replyBody, (uint8_t*)&swPrsOffset, sizeof(uint32_t));
44139 + *p_ReplyLength = sizeof(uint32_t) + sizeof(uint32_t);
44140 + break;
44141 + }
44142 + case (FM_PCD_PRS_INC_PORT_STATS):
44143 + {
44144 + t_FmPcdIpcPrsIncludePort ipcPrsIncludePort;
44145 +
44146 + memcpy((uint8_t*)&ipcPrsIncludePort, p_IpcMsg->msgBody, sizeof(t_FmPcdIpcPrsIncludePort));
44147 + PrsIncludePortInStatistics(h_FmPcd,
44148 + ipcPrsIncludePort.hardwarePortId,
44149 + ipcPrsIncludePort.include);
44150 + break;
44151 + }
44152 + default:
44153 + *p_ReplyLength = 0;
44154 + RETURN_ERROR(MINOR, E_INVALID_SELECTION, ("command not found!!!"));
44155 + }
44156 + return E_OK;
44157 +}
44158 +
44159 +static uint32_t NetEnvLock(t_Handle h_NetEnv)
44160 +{
44161 + ASSERT_COND(h_NetEnv);
44162 + return XX_LockIntrSpinlock(((t_FmPcdNetEnv*)h_NetEnv)->h_Spinlock);
44163 +}
44164 +
44165 +static void NetEnvUnlock(t_Handle h_NetEnv, uint32_t intFlags)
44166 +{
44167 + ASSERT_COND(h_NetEnv);
44168 + XX_UnlockIntrSpinlock(((t_FmPcdNetEnv*)h_NetEnv)->h_Spinlock, intFlags);
44169 +}
44170 +
44171 +static void EnqueueLockToFreeLst(t_FmPcd *p_FmPcd, t_FmPcdLock *p_Lock)
44172 +{
44173 + uint32_t intFlags;
44174 +
44175 + intFlags = XX_LockIntrSpinlock(p_FmPcd->h_Spinlock);
44176 + LIST_AddToTail(&p_Lock->node, &p_FmPcd->freeLocksLst);
44177 + XX_UnlockIntrSpinlock(p_FmPcd->h_Spinlock, intFlags);
44178 +}
44179 +
44180 +static t_FmPcdLock * DequeueLockFromFreeLst(t_FmPcd *p_FmPcd)
44181 +{
44182 + t_FmPcdLock *p_Lock = NULL;
44183 + uint32_t intFlags;
44184 +
44185 + intFlags = XX_LockIntrSpinlock(p_FmPcd->h_Spinlock);
44186 + if (!LIST_IsEmpty(&p_FmPcd->freeLocksLst))
44187 + {
44188 + p_Lock = FM_PCD_LOCK_OBJ(p_FmPcd->freeLocksLst.p_Next);
44189 + LIST_DelAndInit(&p_Lock->node);
44190 + }
44191 + if (p_FmPcd->h_Spinlock)
44192 + XX_UnlockIntrSpinlock(p_FmPcd->h_Spinlock, intFlags);
44193 +
44194 + return p_Lock;
44195 +}
44196 +
44197 +static void EnqueueLockToAcquiredLst(t_FmPcd *p_FmPcd, t_FmPcdLock *p_Lock)
44198 +{
44199 + uint32_t intFlags;
44200 +
44201 + intFlags = XX_LockIntrSpinlock(p_FmPcd->h_Spinlock);
44202 + LIST_AddToTail(&p_Lock->node, &p_FmPcd->acquiredLocksLst);
44203 + XX_UnlockIntrSpinlock(p_FmPcd->h_Spinlock, intFlags);
44204 +}
44205 +
44206 +static t_Error FillFreeLocksLst(t_FmPcd *p_FmPcd)
44207 +{
44208 + t_FmPcdLock *p_Lock;
44209 + int i;
44210 +
44211 + for (i=0; i<10; i++)
44212 + {
44213 + p_Lock = (t_FmPcdLock *)XX_Malloc(sizeof(t_FmPcdLock));
44214 + if (!p_Lock)
44215 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("FM-PCD lock obj!"));
44216 + memset(p_Lock, 0, sizeof(t_FmPcdLock));
44217 + INIT_LIST(&p_Lock->node);
44218 + p_Lock->h_Spinlock = XX_InitSpinlock();
44219 + if (!p_Lock->h_Spinlock)
44220 + {
44221 + XX_Free(p_Lock);
44222 + RETURN_ERROR(MINOR, E_INVALID_STATE, ("FM-PCD spinlock obj!"));
44223 + }
44224 + EnqueueLockToFreeLst(p_FmPcd, p_Lock);
44225 + }
44226 +
44227 + return E_OK;
44228 +}
44229 +
44230 +static void ReleaseFreeLocksLst(t_FmPcd *p_FmPcd)
44231 +{
44232 + t_FmPcdLock *p_Lock;
44233 +
44234 + p_Lock = DequeueLockFromFreeLst(p_FmPcd);
44235 + while (p_Lock)
44236 + {
44237 + XX_FreeSpinlock(p_Lock->h_Spinlock);
44238 + XX_Free(p_Lock);
44239 + p_Lock = DequeueLockFromFreeLst(p_FmPcd);
44240 + }
44241 +}
44242 +
44243 +
44244 +
44245 +/*****************************************************************************/
44246 +/* Inter-module API routines */
44247 +/*****************************************************************************/
44248 +
44249 +void FmPcdSetClsPlanGrpId(t_FmPcd *p_FmPcd, uint8_t netEnvId, uint8_t clsPlanGrpId)
44250 +{
44251 + ASSERT_COND(p_FmPcd);
44252 + p_FmPcd->netEnvs[netEnvId].clsPlanGrpId = clsPlanGrpId;
44253 +}
44254 +
44255 +t_Error PcdGetClsPlanGrpParams(t_FmPcd *p_FmPcd, t_FmPcdKgInterModuleClsPlanGrpParams *p_GrpParams)
44256 +{
44257 + uint8_t netEnvId = p_GrpParams->netEnvId;
44258 + int i, k, j;
44259 +
44260 + ASSERT_COND(p_FmPcd);
44261 + if (p_FmPcd->netEnvs[netEnvId].clsPlanGrpId != ILLEGAL_CLS_PLAN)
44262 + {
44263 + p_GrpParams->grpExists = TRUE;
44264 + p_GrpParams->clsPlanGrpId = p_FmPcd->netEnvs[netEnvId].clsPlanGrpId;
44265 + return E_OK;
44266 + }
44267 +
44268 + for (i=0; ((i < FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS) &&
44269 + (p_FmPcd->netEnvs[netEnvId].units[i].hdrs[0].hdr != HEADER_TYPE_NONE)); i++)
44270 + {
44271 + for (k=0; ((k < FM_PCD_MAX_NUM_OF_INTERCHANGEABLE_HDRS) &&
44272 + (p_FmPcd->netEnvs[netEnvId].units[i].hdrs[k].hdr != HEADER_TYPE_NONE)); k++)
44273 + {
44274 + /* if an option exists, add it to the opts list */
44275 + if (p_FmPcd->netEnvs[netEnvId].units[i].hdrs[k].opt)
44276 + {
44277 + /* check if this option already exists, add if it doesn't */
44278 + for (j = 0;j<p_GrpParams->numOfOptions;j++)
44279 + {
44280 + if (p_GrpParams->options[j] == p_FmPcd->netEnvs[netEnvId].units[i].hdrs[k].opt)
44281 + break;
44282 + }
44283 + p_GrpParams->optVectors[j] |= p_FmPcd->netEnvs[netEnvId].unitsVectors[i];
44284 + if (j == p_GrpParams->numOfOptions)
44285 + {
44286 + p_GrpParams->options[p_GrpParams->numOfOptions] = p_FmPcd->netEnvs[netEnvId].units[i].hdrs[k].opt;
44287 + p_GrpParams->numOfOptions++;
44288 + }
44289 + }
44290 + }
44291 + }
44292 +
44293 + if (p_GrpParams->numOfOptions == 0)
44294 + {
44295 + if (p_FmPcd->p_FmPcdKg->emptyClsPlanGrpId != ILLEGAL_CLS_PLAN)
44296 + {
44297 + p_GrpParams->grpExists = TRUE;
44298 + p_GrpParams->clsPlanGrpId = p_FmPcd->p_FmPcdKg->emptyClsPlanGrpId;
44299 + }
44300 + }
44301 +
44302 + return E_OK;
44303 +
44304 +}
44305 +
44306 +t_Error PcdGetVectorForOpt(t_FmPcd *p_FmPcd, uint8_t netEnvId, protocolOpt_t opt, uint32_t *p_Vector)
44307 +{
44308 + uint8_t j,k;
44309 +
44310 + *p_Vector = 0;
44311 +
44312 + ASSERT_COND(p_FmPcd);
44313 + for (j=0; ((j < FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS) &&
44314 + (p_FmPcd->netEnvs[netEnvId].units[j].hdrs[0].hdr != HEADER_TYPE_NONE)); j++)
44315 + {
44316 + for (k=0; ((k < FM_PCD_MAX_NUM_OF_INTERCHANGEABLE_HDRS) &&
44317 + (p_FmPcd->netEnvs[netEnvId].units[j].hdrs[k].hdr != HEADER_TYPE_NONE)); k++)
44318 + {
44319 + if (p_FmPcd->netEnvs[netEnvId].units[j].hdrs[k].opt == opt)
44320 + *p_Vector |= p_FmPcd->netEnvs[netEnvId].unitsVectors[j];
44321 + }
44322 + }
44323 +
44324 + if (!*p_Vector)
44325 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Requested option was not defined for this Network Environment Characteristics module"));
44326 + else
44327 + return E_OK;
44328 +}
44329 +
44330 +t_Error PcdGetUnitsVector(t_FmPcd *p_FmPcd, t_NetEnvParams *p_Params)
44331 +{
44332 + int i;
44333 +
44334 + ASSERT_COND(p_FmPcd);
44335 + ASSERT_COND(p_Params->netEnvId < FM_MAX_NUM_OF_PORTS);
44336 +
44337 + p_Params->vector = 0;
44338 + for (i=0; i<p_Params->numOfDistinctionUnits ;i++)
44339 + {
44340 + if (p_FmPcd->netEnvs[p_Params->netEnvId].units[p_Params->unitIds[i]].hdrs[0].hdr == HEADER_TYPE_NONE)
44341 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Requested unit was not defined for this Network Environment Characteristics module"));
44342 + ASSERT_COND(p_FmPcd->netEnvs[p_Params->netEnvId].unitsVectors[p_Params->unitIds[i]]);
44343 + p_Params->vector |= p_FmPcd->netEnvs[p_Params->netEnvId].unitsVectors[p_Params->unitIds[i]];
44344 + }
44345 +
44346 + return E_OK;
44347 +}
44348 +
44349 +bool PcdNetEnvIsUnitWithoutOpts(t_FmPcd *p_FmPcd, uint8_t netEnvId, uint32_t unitVector)
44350 +{
44351 + int i=0, k;
44352 +
44353 + ASSERT_COND(p_FmPcd);
44354 + /* check whether a given unit may be used by non-clsPlan users. */
44355 + /* first, recognize the unit by its vector */
44356 + while (p_FmPcd->netEnvs[netEnvId].units[i].hdrs[0].hdr != HEADER_TYPE_NONE)
44357 + {
44358 + if (p_FmPcd->netEnvs[netEnvId].unitsVectors[i] == unitVector)
44359 + {
44360 + for (k=0;
44361 + ((k < FM_PCD_MAX_NUM_OF_INTERCHANGEABLE_HDRS) &&
44362 + (p_FmPcd->netEnvs[netEnvId].units[i].hdrs[k].hdr != HEADER_TYPE_NONE));
44363 + k++)
44364 + /* check that no option exists */
44365 + if ((protocolOpt_t)p_FmPcd->netEnvs[netEnvId].units[i].hdrs[k].opt)
44366 + return FALSE;
44367 + break;
44368 + }
44369 + i++;
44370 + }
44371 + /* assert that a unit was found to mach the vector */
44372 + ASSERT_COND(p_FmPcd->netEnvs[netEnvId].units[i].hdrs[0].hdr != HEADER_TYPE_NONE);
44373 +
44374 + return TRUE;
44375 +}
44376 +bool FmPcdNetEnvIsHdrExist(t_Handle h_FmPcd, uint8_t netEnvId, e_NetHeaderType hdr)
44377 +{
44378 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
44379 + int i, k;
44380 +
44381 + ASSERT_COND(p_FmPcd);
44382 +
44383 + for (i=0; ((i < FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS) &&
44384 + (p_FmPcd->netEnvs[netEnvId].units[i].hdrs[0].hdr != HEADER_TYPE_NONE)); i++)
44385 + {
44386 + for (k=0; ((k < FM_PCD_MAX_NUM_OF_INTERCHANGEABLE_HDRS) &&
44387 + (p_FmPcd->netEnvs[netEnvId].units[i].hdrs[k].hdr != HEADER_TYPE_NONE)); k++)
44388 + if (p_FmPcd->netEnvs[netEnvId].units[i].hdrs[k].hdr == hdr)
44389 + return TRUE;
44390 + }
44391 + for (i=0; ((i < FM_PCD_MAX_NUM_OF_ALIAS_HDRS) &&
44392 + (p_FmPcd->netEnvs[netEnvId].aliasHdrs[i].hdr != HEADER_TYPE_NONE)); i++)
44393 + {
44394 + if (p_FmPcd->netEnvs[netEnvId].aliasHdrs[i].hdr == hdr)
44395 + return TRUE;
44396 + }
44397 +
44398 + return FALSE;
44399 +}
44400 +
44401 +uint8_t FmPcdNetEnvGetUnitId(t_FmPcd *p_FmPcd, uint8_t netEnvId, e_NetHeaderType hdr, bool interchangeable, protocolOpt_t opt)
44402 +{
44403 + uint8_t i, k;
44404 +
44405 + ASSERT_COND(p_FmPcd);
44406 +
44407 + if (interchangeable)
44408 + {
44409 + for (i=0; (i < FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS) &&
44410 + (p_FmPcd->netEnvs[netEnvId].units[i].hdrs[0].hdr != HEADER_TYPE_NONE); i++)
44411 + {
44412 + for (k=0; (k < FM_PCD_MAX_NUM_OF_INTERCHANGEABLE_HDRS) &&
44413 + (p_FmPcd->netEnvs[netEnvId].units[i].hdrs[k].hdr != HEADER_TYPE_NONE); k++)
44414 + {
44415 + if ((p_FmPcd->netEnvs[netEnvId].units[i].hdrs[k].hdr == hdr) &&
44416 + (p_FmPcd->netEnvs[netEnvId].units[i].hdrs[k].opt == opt))
44417 +
44418 + return i;
44419 + }
44420 + }
44421 + }
44422 + else
44423 + {
44424 + for (i=0; (i < FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS) &&
44425 + (p_FmPcd->netEnvs[netEnvId].units[i].hdrs[0].hdr != HEADER_TYPE_NONE); i++)
44426 + if ((p_FmPcd->netEnvs[netEnvId].units[i].hdrs[0].hdr == hdr) &&
44427 + (p_FmPcd->netEnvs[netEnvId].units[i].hdrs[0].opt == opt) &&
44428 + (p_FmPcd->netEnvs[netEnvId].units[i].hdrs[1].hdr == HEADER_TYPE_NONE))
44429 + return i;
44430 +
44431 + for (i=0; (i < FM_PCD_MAX_NUM_OF_ALIAS_HDRS) &&
44432 + (p_FmPcd->netEnvs[netEnvId].aliasHdrs[i].hdr != HEADER_TYPE_NONE); i++)
44433 + if ((p_FmPcd->netEnvs[netEnvId].aliasHdrs[i].hdr == hdr) &&
44434 + (p_FmPcd->netEnvs[netEnvId].aliasHdrs[i].opt == opt))
44435 + return p_FmPcd->netEnvs[netEnvId].aliasHdrs[i].aliasHdr;
44436 + }
44437 +
44438 + return FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS;
44439 +}
44440 +
44441 +t_Error FmPcdUnregisterReassmPort(t_Handle h_FmPcd, t_Handle h_ReasmCommonPramTbl)
44442 +{
44443 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
44444 + t_FmPcdCcReassmTimeoutParams ccReassmTimeoutParams = {0};
44445 + uint8_t result;
44446 + t_Error err = E_OK;
44447 +
44448 + ASSERT_COND(p_FmPcd);
44449 + ASSERT_COND(h_ReasmCommonPramTbl);
44450 +
44451 + ccReassmTimeoutParams.iprcpt = (uint32_t)(XX_VirtToPhys(h_ReasmCommonPramTbl) - p_FmPcd->physicalMuramBase);
44452 + ccReassmTimeoutParams.activate = FALSE; /*Disable Timeout Task*/
44453 +
44454 + if ((err = FmHcPcdCcTimeoutReassm(p_FmPcd->h_Hc, &ccReassmTimeoutParams, &result)) != E_OK)
44455 + RETURN_ERROR(MAJOR, err, NO_MSG);
44456 +
44457 + switch (result)
44458 + {
44459 + case (0):
44460 + return E_OK;
44461 + case (1):
44462 + RETURN_ERROR(MAJOR, E_INVALID_STATE, (""));
44463 + case (2):
44464 + RETURN_ERROR(MAJOR, E_INVALID_STATE, (""));
44465 + case (3):
44466 + RETURN_ERROR(MAJOR, E_INVALID_HANDLE, ("Disable Timeout Task with invalid IPRCPT"));
44467 + default:
44468 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, NO_MSG);
44469 + }
44470 +
44471 + return E_OK;
44472 +}
44473 +
44474 +e_NetHeaderType FmPcdGetAliasHdr(t_FmPcd *p_FmPcd, uint8_t netEnvId, e_NetHeaderType hdr)
44475 +{
44476 + int i;
44477 +
44478 + ASSERT_COND(p_FmPcd);
44479 + ASSERT_COND(netEnvId < FM_MAX_NUM_OF_PORTS);
44480 +
44481 + for (i=0; (i < FM_PCD_MAX_NUM_OF_ALIAS_HDRS)
44482 + && (p_FmPcd->netEnvs[netEnvId].aliasHdrs[i].hdr != HEADER_TYPE_NONE); i++)
44483 + {
44484 + if (p_FmPcd->netEnvs[netEnvId].aliasHdrs[i].hdr == hdr)
44485 + return p_FmPcd->netEnvs[netEnvId].aliasHdrs[i].aliasHdr;
44486 + }
44487 +
44488 + return HEADER_TYPE_NONE;
44489 +}
44490 +
44491 +void FmPcdPortRegister(t_Handle h_FmPcd, t_Handle h_FmPort, uint8_t hardwarePortId)
44492 +{
44493 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
44494 + uint16_t swPortIndex = 0;
44495 +
44496 + ASSERT_COND(h_FmPcd);
44497 + HW_PORT_ID_TO_SW_PORT_INDX(swPortIndex, hardwarePortId);
44498 + p_FmPcd->p_FmPcdPlcr->portsMapping[swPortIndex].h_FmPort = h_FmPort;
44499 +}
44500 +
44501 +uint32_t FmPcdGetLcv(t_Handle h_FmPcd, uint32_t netEnvId, uint8_t hdrNum)
44502 +{
44503 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
44504 +
44505 + ASSERT_COND(h_FmPcd);
44506 + return p_FmPcd->netEnvs[netEnvId].lcvs[hdrNum];
44507 +}
44508 +
44509 +uint32_t FmPcdGetMacsecLcv(t_Handle h_FmPcd, uint32_t netEnvId)
44510 +{
44511 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
44512 +
44513 + ASSERT_COND(h_FmPcd);
44514 + return p_FmPcd->netEnvs[netEnvId].macsecVector;
44515 +}
44516 +
44517 +uint8_t FmPcdGetNetEnvId(t_Handle h_NetEnv)
44518 +{
44519 + return ((t_FmPcdNetEnv*)h_NetEnv)->netEnvId;
44520 +}
44521 +
44522 +void FmPcdIncNetEnvOwners(t_Handle h_FmPcd, uint8_t netEnvId)
44523 +{
44524 + uint32_t intFlags;
44525 +
44526 + ASSERT_COND(h_FmPcd);
44527 +
44528 + intFlags = NetEnvLock(&((t_FmPcd*)h_FmPcd)->netEnvs[netEnvId]);
44529 + ((t_FmPcd*)h_FmPcd)->netEnvs[netEnvId].owners++;
44530 + NetEnvUnlock(&((t_FmPcd*)h_FmPcd)->netEnvs[netEnvId], intFlags);
44531 +}
44532 +
44533 +void FmPcdDecNetEnvOwners(t_Handle h_FmPcd, uint8_t netEnvId)
44534 +{
44535 + uint32_t intFlags;
44536 +
44537 + ASSERT_COND(h_FmPcd);
44538 + ASSERT_COND(((t_FmPcd*)h_FmPcd)->netEnvs[netEnvId].owners);
44539 +
44540 + intFlags = NetEnvLock(&((t_FmPcd*)h_FmPcd)->netEnvs[netEnvId]);
44541 + ((t_FmPcd*)h_FmPcd)->netEnvs[netEnvId].owners--;
44542 + NetEnvUnlock(&((t_FmPcd*)h_FmPcd)->netEnvs[netEnvId], intFlags);
44543 +}
44544 +
44545 +uint32_t FmPcdLock(t_Handle h_FmPcd)
44546 +{
44547 + ASSERT_COND(h_FmPcd);
44548 + return XX_LockIntrSpinlock(((t_FmPcd*)h_FmPcd)->h_Spinlock);
44549 +}
44550 +
44551 +void FmPcdUnlock(t_Handle h_FmPcd, uint32_t intFlags)
44552 +{
44553 + ASSERT_COND(h_FmPcd);
44554 + XX_UnlockIntrSpinlock(((t_FmPcd*)h_FmPcd)->h_Spinlock, intFlags);
44555 +}
44556 +
44557 +t_FmPcdLock * FmPcdAcquireLock(t_Handle h_FmPcd)
44558 +{
44559 + t_FmPcdLock *p_Lock;
44560 + ASSERT_COND(h_FmPcd);
44561 + p_Lock = DequeueLockFromFreeLst((t_FmPcd*)h_FmPcd);
44562 + if (!p_Lock)
44563 + {
44564 + FillFreeLocksLst(h_FmPcd);
44565 + p_Lock = DequeueLockFromFreeLst((t_FmPcd*)h_FmPcd);
44566 + }
44567 +
44568 + if (p_Lock)
44569 + EnqueueLockToAcquiredLst((t_FmPcd*)h_FmPcd, p_Lock);
44570 + return p_Lock;
44571 +}
44572 +
44573 +void FmPcdReleaseLock(t_Handle h_FmPcd, t_FmPcdLock *p_Lock)
44574 +{
44575 + uint32_t intFlags;
44576 + ASSERT_COND(h_FmPcd);
44577 + intFlags = FmPcdLock(h_FmPcd);
44578 + LIST_DelAndInit(&p_Lock->node);
44579 + FmPcdUnlock(h_FmPcd, intFlags);
44580 + EnqueueLockToFreeLst((t_FmPcd*)h_FmPcd, p_Lock);
44581 +}
44582 +
44583 +bool FmPcdLockTryLockAll(t_Handle h_FmPcd)
44584 +{
44585 + uint32_t intFlags;
44586 + t_List *p_Pos, *p_SavedPos=NULL;
44587 +
44588 + ASSERT_COND(h_FmPcd);
44589 + intFlags = FmPcdLock(h_FmPcd);
44590 + LIST_FOR_EACH(p_Pos, &((t_FmPcd*)h_FmPcd)->acquiredLocksLst)
44591 + {
44592 + t_FmPcdLock *p_Lock = FM_PCD_LOCK_OBJ(p_Pos);
44593 + if (!FmPcdLockTryLock(p_Lock))
44594 + {
44595 + p_SavedPos = p_Pos;
44596 + break;
44597 + }
44598 + }
44599 + if (p_SavedPos)
44600 + {
44601 + LIST_FOR_EACH(p_Pos, &((t_FmPcd*)h_FmPcd)->acquiredLocksLst)
44602 + {
44603 + t_FmPcdLock *p_Lock = FM_PCD_LOCK_OBJ(p_Pos);
44604 + if (p_Pos == p_SavedPos)
44605 + break;
44606 + FmPcdLockUnlock(p_Lock);
44607 + }
44608 + }
44609 + FmPcdUnlock(h_FmPcd, intFlags);
44610 +
44611 + CORE_MemoryBarrier();
44612 +
44613 + if (p_SavedPos)
44614 + return FALSE;
44615 +
44616 + return TRUE;
44617 +}
44618 +
44619 +void FmPcdLockUnlockAll(t_Handle h_FmPcd)
44620 +{
44621 + uint32_t intFlags;
44622 + t_List *p_Pos;
44623 +
44624 + ASSERT_COND(h_FmPcd);
44625 + intFlags = FmPcdLock(h_FmPcd);
44626 + LIST_FOR_EACH(p_Pos, &((t_FmPcd*)h_FmPcd)->acquiredLocksLst)
44627 + {
44628 + t_FmPcdLock *p_Lock = FM_PCD_LOCK_OBJ(p_Pos);
44629 + p_Lock->flag = FALSE;
44630 + }
44631 + FmPcdUnlock(h_FmPcd, intFlags);
44632 +
44633 + CORE_MemoryBarrier();
44634 +}
44635 +
44636 +t_Error FmPcdHcSync(t_Handle h_FmPcd)
44637 +{
44638 + ASSERT_COND(h_FmPcd);
44639 + ASSERT_COND(((t_FmPcd*)h_FmPcd)->h_Hc);
44640 +
44641 + return FmHcPcdSync(((t_FmPcd*)h_FmPcd)->h_Hc);
44642 +}
44643 +
44644 +t_Handle FmPcdGetHcHandle(t_Handle h_FmPcd)
44645 +{
44646 + ASSERT_COND(h_FmPcd);
44647 + return ((t_FmPcd*)h_FmPcd)->h_Hc;
44648 +}
44649 +
44650 +bool FmPcdIsAdvancedOffloadSupported(t_Handle h_FmPcd)
44651 +{
44652 + ASSERT_COND(h_FmPcd);
44653 + return ((t_FmPcd*)h_FmPcd)->advancedOffloadSupport;
44654 +}
44655 +/*********************** End of inter-module routines ************************/
44656 +
44657 +
44658 +/****************************************/
44659 +/* API Init unit functions */
44660 +/****************************************/
44661 +
44662 +t_Handle FM_PCD_Config(t_FmPcdParams *p_FmPcdParams)
44663 +{
44664 + t_FmPcd *p_FmPcd = NULL;
44665 + t_FmPhysAddr physicalMuramBase;
44666 + uint8_t i;
44667 +
44668 + SANITY_CHECK_RETURN_VALUE(p_FmPcdParams, E_INVALID_HANDLE,NULL);
44669 +
44670 + p_FmPcd = (t_FmPcd *) XX_Malloc(sizeof(t_FmPcd));
44671 + if (!p_FmPcd)
44672 + {
44673 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FM PCD"));
44674 + return NULL;
44675 + }
44676 + memset(p_FmPcd, 0, sizeof(t_FmPcd));
44677 +
44678 + p_FmPcd->p_FmPcdDriverParam = (t_FmPcdDriverParam *) XX_Malloc(sizeof(t_FmPcdDriverParam));
44679 + if (!p_FmPcd->p_FmPcdDriverParam)
44680 + {
44681 + XX_Free(p_FmPcd);
44682 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FM PCD Driver Param"));
44683 + return NULL;
44684 + }
44685 + memset(p_FmPcd->p_FmPcdDriverParam, 0, sizeof(t_FmPcdDriverParam));
44686 +
44687 + p_FmPcd->h_Fm = p_FmPcdParams->h_Fm;
44688 + p_FmPcd->guestId = FmGetGuestId(p_FmPcd->h_Fm);
44689 + p_FmPcd->h_FmMuram = FmGetMuramHandle(p_FmPcd->h_Fm);
44690 + if (p_FmPcd->h_FmMuram)
44691 + {
44692 + FmGetPhysicalMuramBase(p_FmPcdParams->h_Fm, &physicalMuramBase);
44693 + p_FmPcd->physicalMuramBase = (uint64_t)((uint64_t)(&physicalMuramBase)->low | ((uint64_t)(&physicalMuramBase)->high << 32));
44694 + }
44695 +
44696 + for (i = 0; i<FM_MAX_NUM_OF_PORTS; i++)
44697 + p_FmPcd->netEnvs[i].clsPlanGrpId = ILLEGAL_CLS_PLAN;
44698 +
44699 + if (p_FmPcdParams->useHostCommand)
44700 + {
44701 + t_FmHcParams hcParams;
44702 +
44703 + memset(&hcParams, 0, sizeof(hcParams));
44704 + hcParams.h_Fm = p_FmPcd->h_Fm;
44705 + hcParams.h_FmPcd = (t_Handle)p_FmPcd;
44706 + memcpy((uint8_t*)&hcParams.params, (uint8_t*)&p_FmPcdParams->hc, sizeof(t_FmPcdHcParams));
44707 + p_FmPcd->h_Hc = FmHcConfigAndInit(&hcParams);
44708 + if (!p_FmPcd->h_Hc)
44709 + {
44710 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FM PCD HC"));
44711 + FM_PCD_Free(p_FmPcd);
44712 + return NULL;
44713 + }
44714 + }
44715 + else if (p_FmPcd->guestId != NCSW_MASTER_ID)
44716 + REPORT_ERROR(MAJOR, E_INVALID_STATE, ("No Host Command defined for a guest partition."));
44717 +
44718 + if (p_FmPcdParams->kgSupport)
44719 + {
44720 + p_FmPcd->p_FmPcdKg = (t_FmPcdKg *)KgConfig(p_FmPcd, p_FmPcdParams);
44721 + if (!p_FmPcd->p_FmPcdKg)
44722 + {
44723 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FM PCD Keygen"));
44724 + FM_PCD_Free(p_FmPcd);
44725 + return NULL;
44726 + }
44727 + }
44728 +
44729 + if (p_FmPcdParams->plcrSupport)
44730 + {
44731 + p_FmPcd->p_FmPcdPlcr = (t_FmPcdPlcr *)PlcrConfig(p_FmPcd, p_FmPcdParams);
44732 + if (!p_FmPcd->p_FmPcdPlcr)
44733 + {
44734 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FM PCD Policer"));
44735 + FM_PCD_Free(p_FmPcd);
44736 + return NULL;
44737 + }
44738 + }
44739 +
44740 + if (p_FmPcdParams->prsSupport)
44741 + {
44742 + p_FmPcd->p_FmPcdPrs = (t_FmPcdPrs *)PrsConfig(p_FmPcd, p_FmPcdParams);
44743 + if (!p_FmPcd->p_FmPcdPrs)
44744 + {
44745 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FM PCD Parser"));
44746 + FM_PCD_Free(p_FmPcd);
44747 + return NULL;
44748 + }
44749 + }
44750 +
44751 + p_FmPcd->h_Spinlock = XX_InitSpinlock();
44752 + if (!p_FmPcd->h_Spinlock)
44753 + {
44754 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FM PCD spinlock"));
44755 + FM_PCD_Free(p_FmPcd);
44756 + return NULL;
44757 + }
44758 + INIT_LIST(&p_FmPcd->freeLocksLst);
44759 + INIT_LIST(&p_FmPcd->acquiredLocksLst);
44760 +
44761 + p_FmPcd->numOfEnabledGuestPartitionsPcds = 0;
44762 +
44763 + p_FmPcd->f_Exception = p_FmPcdParams->f_Exception;
44764 + p_FmPcd->f_FmPcdIndexedException = p_FmPcdParams->f_ExceptionId;
44765 + p_FmPcd->h_App = p_FmPcdParams->h_App;
44766 +
44767 + p_FmPcd->p_CcShadow = NULL;
44768 + p_FmPcd->ccShadowSize = 0;
44769 + p_FmPcd->ccShadowAlign = 0;
44770 +
44771 + p_FmPcd->h_ShadowSpinlock = XX_InitSpinlock();
44772 + if (!p_FmPcd->h_ShadowSpinlock)
44773 + {
44774 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FM PCD shadow spinlock"));
44775 + FM_PCD_Free(p_FmPcd);
44776 + return NULL;
44777 + }
44778 +
44779 + return p_FmPcd;
44780 +}
44781 +
44782 +t_Error FM_PCD_Init(t_Handle h_FmPcd)
44783 +{
44784 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
44785 + t_Error err = E_OK;
44786 + t_FmPcdIpcMsg msg;
44787 +
44788 + SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);
44789 + SANITY_CHECK_RETURN_ERROR(p_FmPcd->p_FmPcdDriverParam, E_INVALID_HANDLE);
44790 +
44791 + FM_GetRevision(p_FmPcd->h_Fm, &p_FmPcd->fmRevInfo);
44792 +
44793 + if (p_FmPcd->guestId != NCSW_MASTER_ID)
44794 + {
44795 + memset(p_FmPcd->fmPcdIpcHandlerModuleName, 0, (sizeof(char)) * MODULE_NAME_SIZE);
44796 + if (Sprint (p_FmPcd->fmPcdIpcHandlerModuleName, "FM_PCD_%d_%d", FmGetId(p_FmPcd->h_Fm), NCSW_MASTER_ID) != 10)
44797 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Sprint failed"));
44798 + memset(p_FmPcd->fmPcdModuleName, 0, (sizeof(char)) * MODULE_NAME_SIZE);
44799 + if (Sprint (p_FmPcd->fmPcdModuleName, "FM_PCD_%d_%d",FmGetId(p_FmPcd->h_Fm), p_FmPcd->guestId) != (p_FmPcd->guestId<10 ? 10:11))
44800 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Sprint failed"));
44801 +
44802 + p_FmPcd->h_IpcSession = XX_IpcInitSession(p_FmPcd->fmPcdIpcHandlerModuleName, p_FmPcd->fmPcdModuleName);
44803 + if (p_FmPcd->h_IpcSession)
44804 + {
44805 + t_FmPcdIpcReply reply;
44806 + uint32_t replyLength;
44807 + uint8_t isMasterAlive = 0;
44808 +
44809 + memset(&msg, 0, sizeof(msg));
44810 + memset(&reply, 0, sizeof(reply));
44811 + msg.msgId = FM_PCD_MASTER_IS_ALIVE;
44812 + msg.msgBody[0] = p_FmPcd->guestId;
44813 + blockingFlag = TRUE;
44814 +
44815 + do
44816 + {
44817 + replyLength = sizeof(uint32_t) + sizeof(isMasterAlive);
44818 + if ((err = XX_IpcSendMessage(p_FmPcd->h_IpcSession,
44819 + (uint8_t*)&msg,
44820 + sizeof(msg.msgId)+sizeof(p_FmPcd->guestId),
44821 + (uint8_t*)&reply,
44822 + &replyLength,
44823 + IpcMsgCompletionCB,
44824 + h_FmPcd)) != E_OK)
44825 + REPORT_ERROR(MAJOR, err, NO_MSG);
44826 + while (blockingFlag) ;
44827 + if (replyLength != (sizeof(uint32_t) + sizeof(isMasterAlive)))
44828 + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch"));
44829 + isMasterAlive = *(uint8_t*)(reply.replyBody);
44830 + } while (!isMasterAlive);
44831 + }
44832 + }
44833 +
44834 + CHECK_INIT_PARAMETERS(p_FmPcd, CheckFmPcdParameters);
44835 +
44836 + if (p_FmPcd->p_FmPcdKg)
44837 + {
44838 + err = KgInit(p_FmPcd);
44839 + if (err)
44840 + RETURN_ERROR(MAJOR, err, NO_MSG);
44841 + }
44842 +
44843 + if (p_FmPcd->p_FmPcdPlcr)
44844 + {
44845 + err = PlcrInit(p_FmPcd);
44846 + if (err)
44847 + RETURN_ERROR(MAJOR, err, NO_MSG);
44848 + }
44849 +
44850 + if (p_FmPcd->p_FmPcdPrs)
44851 + {
44852 + err = PrsInit(p_FmPcd);
44853 + if (err)
44854 + RETURN_ERROR(MAJOR, err, NO_MSG);
44855 + }
44856 +
44857 + if (p_FmPcd->guestId == NCSW_MASTER_ID)
44858 + {
44859 + /* register to inter-core messaging mechanism */
44860 + memset(p_FmPcd->fmPcdModuleName, 0, (sizeof(char)) * MODULE_NAME_SIZE);
44861 + if (Sprint (p_FmPcd->fmPcdModuleName, "FM_PCD_%d_%d",FmGetId(p_FmPcd->h_Fm),NCSW_MASTER_ID) != 10)
44862 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Sprint failed"));
44863 + err = XX_IpcRegisterMsgHandler(p_FmPcd->fmPcdModuleName, IpcMsgHandlerCB, p_FmPcd, FM_PCD_MAX_REPLY_SIZE);
44864 + if (err)
44865 + RETURN_ERROR(MAJOR, err, NO_MSG);
44866 + }
44867 +
44868 + /* IPv6 Frame-Id used for fragmentation */
44869 + p_FmPcd->ipv6FrameIdAddr = PTR_TO_UINT(FM_MURAM_AllocMem(p_FmPcd->h_FmMuram, 4, 4));
44870 + if (!p_FmPcd->ipv6FrameIdAddr)
44871 + {
44872 + FM_PCD_Free(p_FmPcd);
44873 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("MURAM allocation for IPv6 Frame-Id"));
44874 + }
44875 + IOMemSet32(UINT_TO_PTR(p_FmPcd->ipv6FrameIdAddr), 0, 4);
44876 +
44877 + /* CAPWAP Frame-Id used for fragmentation */
44878 + p_FmPcd->capwapFrameIdAddr = PTR_TO_UINT(FM_MURAM_AllocMem(p_FmPcd->h_FmMuram, 2, 4));
44879 + if (!p_FmPcd->capwapFrameIdAddr)
44880 + {
44881 + FM_PCD_Free(p_FmPcd);
44882 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("MURAM allocation for CAPWAP Frame-Id"));
44883 + }
44884 + IOMemSet32(UINT_TO_PTR(p_FmPcd->capwapFrameIdAddr), 0, 2);
44885 +
44886 + XX_Free(p_FmPcd->p_FmPcdDriverParam);
44887 + p_FmPcd->p_FmPcdDriverParam = NULL;
44888 +
44889 + FmRegisterPcd(p_FmPcd->h_Fm, p_FmPcd);
44890 +
44891 + return E_OK;
44892 +}
44893 +
44894 +t_Error FM_PCD_Free(t_Handle h_FmPcd)
44895 +{
44896 + t_FmPcd *p_FmPcd =(t_FmPcd *)h_FmPcd;
44897 + t_Error err = E_OK;
44898 +
44899 + if (p_FmPcd->ipv6FrameIdAddr)
44900 + FM_MURAM_FreeMem(p_FmPcd->h_FmMuram, UINT_TO_PTR(p_FmPcd->ipv6FrameIdAddr));
44901 +
44902 + if (p_FmPcd->capwapFrameIdAddr)
44903 + FM_MURAM_FreeMem(p_FmPcd->h_FmMuram, UINT_TO_PTR(p_FmPcd->capwapFrameIdAddr));
44904 +
44905 + if (p_FmPcd->enabled)
44906 + FM_PCD_Disable(p_FmPcd);
44907 +
44908 + if (p_FmPcd->p_FmPcdDriverParam)
44909 + {
44910 + XX_Free(p_FmPcd->p_FmPcdDriverParam);
44911 + p_FmPcd->p_FmPcdDriverParam = NULL;
44912 + }
44913 +
44914 + if (p_FmPcd->p_FmPcdKg)
44915 + {
44916 + if ((err = KgFree(p_FmPcd)) != E_OK)
44917 + RETURN_ERROR(MINOR, err, NO_MSG);
44918 + XX_Free(p_FmPcd->p_FmPcdKg);
44919 + p_FmPcd->p_FmPcdKg = NULL;
44920 + }
44921 +
44922 + if (p_FmPcd->p_FmPcdPlcr)
44923 + {
44924 + PlcrFree(p_FmPcd);
44925 + XX_Free(p_FmPcd->p_FmPcdPlcr);
44926 + p_FmPcd->p_FmPcdPlcr = NULL;
44927 + }
44928 +
44929 + if (p_FmPcd->p_FmPcdPrs)
44930 + {
44931 + if (p_FmPcd->guestId == NCSW_MASTER_ID)
44932 + PrsFree(p_FmPcd);
44933 + XX_Free(p_FmPcd->p_FmPcdPrs);
44934 + p_FmPcd->p_FmPcdPrs = NULL;
44935 + }
44936 +
44937 + if (p_FmPcd->h_Hc)
44938 + {
44939 + FmHcFree(p_FmPcd->h_Hc);
44940 + p_FmPcd->h_Hc = NULL;
44941 + }
44942 +
44943 + XX_IpcUnregisterMsgHandler(p_FmPcd->fmPcdModuleName);
44944 +
44945 + FmUnregisterPcd(p_FmPcd->h_Fm);
44946 +
44947 + ReleaseFreeLocksLst(p_FmPcd);
44948 +
44949 + if (p_FmPcd->h_Spinlock)
44950 + XX_FreeSpinlock(p_FmPcd->h_Spinlock);
44951 +
44952 + if (p_FmPcd->h_ShadowSpinlock)
44953 + XX_FreeSpinlock(p_FmPcd->h_ShadowSpinlock);
44954 +
44955 + XX_Free(p_FmPcd);
44956 +
44957 + return E_OK;
44958 +}
44959 +
44960 +t_Error FM_PCD_ConfigException(t_Handle h_FmPcd, e_FmPcdExceptions exception, bool enable)
44961 +{
44962 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
44963 + uint32_t bitMask = 0;
44964 +
44965 + SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);
44966 +
44967 + if (p_FmPcd->guestId != NCSW_MASTER_ID)
44968 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("FM_PCD_ConfigException - guest mode!"));
44969 +
44970 + GET_FM_PCD_EXCEPTION_FLAG(bitMask, exception);
44971 + if (bitMask)
44972 + {
44973 + if (enable)
44974 + p_FmPcd->exceptions |= bitMask;
44975 + else
44976 + p_FmPcd->exceptions &= ~bitMask;
44977 + }
44978 + else
44979 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Undefined exception"));
44980 +
44981 + return E_OK;
44982 +}
44983 +
44984 +t_Error FM_PCD_ConfigHcFramesDataMemory(t_Handle h_FmPcd, uint8_t memId)
44985 +{
44986 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
44987 +
44988 + SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);
44989 + SANITY_CHECK_RETURN_ERROR(p_FmPcd->h_Hc, E_INVALID_HANDLE);
44990 +
44991 + return FmHcSetFramesDataMemory(p_FmPcd->h_Hc, memId);
44992 +}
44993 +
44994 +t_Error FM_PCD_Enable(t_Handle h_FmPcd)
44995 +{
44996 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
44997 + t_Error err = E_OK;
44998 +
44999 + SANITY_CHECK_RETURN_ERROR(h_FmPcd, E_INVALID_HANDLE);
45000 +
45001 + if (p_FmPcd->enabled)
45002 + return E_OK;
45003 +
45004 + if ((p_FmPcd->guestId != NCSW_MASTER_ID) &&
45005 + p_FmPcd->h_IpcSession)
45006 + {
45007 + uint8_t enabled;
45008 + t_FmPcdIpcMsg msg;
45009 + t_FmPcdIpcReply reply;
45010 + uint32_t replyLength;
45011 +
45012 + memset(&reply, 0, sizeof(reply));
45013 + memset(&msg, 0, sizeof(msg));
45014 + msg.msgId = FM_PCD_MASTER_IS_ENABLED;
45015 + replyLength = sizeof(uint32_t) + sizeof(enabled);
45016 + if ((err = XX_IpcSendMessage(p_FmPcd->h_IpcSession,
45017 + (uint8_t*)&msg,
45018 + sizeof(msg.msgId),
45019 + (uint8_t*)&reply,
45020 + &replyLength,
45021 + NULL,
45022 + NULL)) != E_OK)
45023 + RETURN_ERROR(MAJOR, err, NO_MSG);
45024 + if (replyLength != sizeof(uint32_t) + sizeof(enabled))
45025 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch"));
45026 + p_FmPcd->enabled = (bool)!!(*(uint8_t*)(reply.replyBody));
45027 + if (!p_FmPcd->enabled)
45028 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("FM-PCD master should be enabled first!"));
45029 +
45030 + return E_OK;
45031 + }
45032 + else if (p_FmPcd->guestId != NCSW_MASTER_ID)
45033 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED,
45034 + ("running in guest-mode without IPC!"));
45035 +
45036 + if (p_FmPcd->p_FmPcdKg)
45037 + KgEnable(p_FmPcd);
45038 +
45039 + if (p_FmPcd->p_FmPcdPlcr)
45040 + PlcrEnable(p_FmPcd);
45041 +
45042 + if (p_FmPcd->p_FmPcdPrs)
45043 + PrsEnable(p_FmPcd);
45044 +
45045 + p_FmPcd->enabled = TRUE;
45046 +
45047 + return E_OK;
45048 +}
45049 +
45050 +t_Error FM_PCD_Disable(t_Handle h_FmPcd)
45051 +{
45052 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
45053 + t_Error err = E_OK;
45054 +
45055 + SANITY_CHECK_RETURN_ERROR(h_FmPcd, E_INVALID_HANDLE);
45056 +
45057 + if (!p_FmPcd->enabled)
45058 + return E_OK;
45059 +
45060 + if ((p_FmPcd->guestId != NCSW_MASTER_ID) &&
45061 + p_FmPcd->h_IpcSession)
45062 + {
45063 + t_FmPcdIpcMsg msg;
45064 + t_FmPcdIpcReply reply;
45065 + uint32_t replyLength;
45066 +
45067 + memset(&reply, 0, sizeof(reply));
45068 + memset(&msg, 0, sizeof(msg));
45069 + msg.msgId = FM_PCD_GUEST_DISABLE;
45070 + replyLength = sizeof(uint32_t);
45071 + if ((err = XX_IpcSendMessage(p_FmPcd->h_IpcSession,
45072 + (uint8_t*)&msg,
45073 + sizeof(msg.msgId),
45074 + (uint8_t*)&reply,
45075 + &replyLength,
45076 + NULL,
45077 + NULL)) != E_OK)
45078 + RETURN_ERROR(MAJOR, err, NO_MSG);
45079 + if (replyLength != sizeof(uint32_t))
45080 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch"));
45081 + if (reply.error == E_OK)
45082 + p_FmPcd->enabled = FALSE;
45083 +
45084 + return (t_Error)(reply.error);
45085 + }
45086 + else if (p_FmPcd->guestId != NCSW_MASTER_ID)
45087 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED,
45088 + ("running in guest-mode without IPC!"));
45089 +
45090 + if (p_FmPcd->numOfEnabledGuestPartitionsPcds != 0)
45091 + RETURN_ERROR(MAJOR, E_INVALID_STATE,
45092 + ("Trying to disable a master partition PCD while"
45093 + "guest partitions are still enabled!"));
45094 +
45095 + if (p_FmPcd->p_FmPcdKg)
45096 + KgDisable(p_FmPcd);
45097 +
45098 + if (p_FmPcd->p_FmPcdPlcr)
45099 + PlcrDisable(p_FmPcd);
45100 +
45101 + if (p_FmPcd->p_FmPcdPrs)
45102 + PrsDisable(p_FmPcd);
45103 +
45104 + p_FmPcd->enabled = FALSE;
45105 +
45106 + return E_OK;
45107 +}
45108 +
45109 +t_Handle FM_PCD_NetEnvCharacteristicsSet(t_Handle h_FmPcd, t_FmPcdNetEnvParams *p_NetEnvParams)
45110 +{
45111 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
45112 + uint32_t intFlags, specialUnits = 0;
45113 + uint8_t bitId = 0;
45114 + uint8_t i, j, k;
45115 + uint8_t netEnvCurrId;
45116 + uint8_t ipsecAhUnit = 0,ipsecEspUnit = 0;
45117 + bool ipsecAhExists = FALSE, ipsecEspExists = FALSE, shim1Selected = FALSE;
45118 + uint8_t hdrNum;
45119 + t_FmPcdNetEnvParams *p_ModifiedNetEnvParams;
45120 +
45121 + SANITY_CHECK_RETURN_VALUE(h_FmPcd, E_INVALID_STATE, NULL);
45122 + SANITY_CHECK_RETURN_VALUE(!p_FmPcd->p_FmPcdDriverParam, E_INVALID_STATE, NULL);
45123 + SANITY_CHECK_RETURN_VALUE(p_NetEnvParams, E_NULL_POINTER, NULL);
45124 +
45125 + intFlags = FmPcdLock(p_FmPcd);
45126 +
45127 + /* find a new netEnv */
45128 + for (i = 0; i < FM_MAX_NUM_OF_PORTS; i++)
45129 + if (!p_FmPcd->netEnvs[i].used)
45130 + break;
45131 +
45132 + if (i== FM_MAX_NUM_OF_PORTS)
45133 + {
45134 + REPORT_ERROR(MAJOR, E_FULL,("No more than %d netEnv's allowed.", FM_MAX_NUM_OF_PORTS));
45135 + FmPcdUnlock(p_FmPcd, intFlags);
45136 + return NULL;
45137 + }
45138 +
45139 + p_FmPcd->netEnvs[i].used = TRUE;
45140 + FmPcdUnlock(p_FmPcd, intFlags);
45141 +
45142 + /* As anyone doesn't have handle of this netEnv yet, no need
45143 + to protect it with spinlocks */
45144 +
45145 + p_ModifiedNetEnvParams = (t_FmPcdNetEnvParams *)XX_Malloc(sizeof(t_FmPcdNetEnvParams));
45146 + if (!p_ModifiedNetEnvParams)
45147 + {
45148 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FmPcdNetEnvParams"));
45149 + return NULL;
45150 + }
45151 +
45152 + memcpy(p_ModifiedNetEnvParams, p_NetEnvParams, sizeof(t_FmPcdNetEnvParams));
45153 + p_NetEnvParams = p_ModifiedNetEnvParams;
45154 +
45155 + netEnvCurrId = (uint8_t)i;
45156 +
45157 + /* clear from previous use */
45158 + memset(&p_FmPcd->netEnvs[netEnvCurrId].units, 0, FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS * sizeof(t_FmPcdIntDistinctionUnit));
45159 + memset(&p_FmPcd->netEnvs[netEnvCurrId].aliasHdrs, 0, FM_PCD_MAX_NUM_OF_ALIAS_HDRS * sizeof(t_FmPcdNetEnvAliases));
45160 + memcpy(&p_FmPcd->netEnvs[netEnvCurrId].units, p_NetEnvParams->units, p_NetEnvParams->numOfDistinctionUnits*sizeof(t_FmPcdIntDistinctionUnit));
45161 +
45162 + p_FmPcd->netEnvs[netEnvCurrId].netEnvId = netEnvCurrId;
45163 + p_FmPcd->netEnvs[netEnvCurrId].h_FmPcd = p_FmPcd;
45164 +
45165 + p_FmPcd->netEnvs[netEnvCurrId].clsPlanGrpId = ILLEGAL_CLS_PLAN;
45166 +
45167 + /* check that header with opt is not interchanged with the same header */
45168 + for (i = 0; (i < FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS)
45169 + && (p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[0].hdr != HEADER_TYPE_NONE); i++)
45170 + {
45171 + for (k = 0; (k < FM_PCD_MAX_NUM_OF_INTERCHANGEABLE_HDRS)
45172 + && (p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[k].hdr != HEADER_TYPE_NONE); k++)
45173 + {
45174 + /* if an option exists, check that other headers are not the same header
45175 + without option */
45176 + if (p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[k].opt)
45177 + {
45178 + for (j = 0; (j < FM_PCD_MAX_NUM_OF_INTERCHANGEABLE_HDRS)
45179 + && (p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[j].hdr != HEADER_TYPE_NONE); j++)
45180 + {
45181 + if ((p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[j].hdr == p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[k].hdr) &&
45182 + !p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[j].opt)
45183 + {
45184 + REPORT_ERROR(MINOR, E_FULL,
45185 + ("Illegal unit - header with opt may not be interchangeable with the same header without opt"));
45186 + XX_Free(p_ModifiedNetEnvParams);
45187 + return NULL;
45188 + }
45189 + }
45190 + }
45191 + }
45192 + }
45193 +
45194 + /* Specific headers checking */
45195 + for (i = 0; (i < FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS)
45196 + && (p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[0].hdr != HEADER_TYPE_NONE); i++)
45197 + {
45198 + for (k = 0; (k < FM_PCD_MAX_NUM_OF_INTERCHANGEABLE_HDRS)
45199 + && (p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[k].hdr != HEADER_TYPE_NONE); k++)
45200 + {
45201 + /* Some headers pairs may not be defined on different units as the parser
45202 + doesn't distinguish */
45203 + /* IPSEC_AH and IPSEC_SPI can't be 2 units, */
45204 + /* check that header with opt is not interchanged with the same header */
45205 + if (p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[k].hdr == HEADER_TYPE_IPSEC_AH)
45206 + {
45207 + if (ipsecEspExists && (ipsecEspUnit != i))
45208 + {
45209 + REPORT_ERROR(MINOR, E_INVALID_STATE, ("HEADER_TYPE_IPSEC_AH and HEADER_TYPE_IPSEC_ESP may not be defined in separate units"));
45210 + XX_Free(p_ModifiedNetEnvParams);
45211 + return NULL;
45212 + }
45213 + else
45214 + {
45215 + ipsecAhUnit = i;
45216 + ipsecAhExists = TRUE;
45217 + }
45218 + }
45219 + if (p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[k].hdr == HEADER_TYPE_IPSEC_ESP)
45220 + {
45221 + if (ipsecAhExists && (ipsecAhUnit != i))
45222 + {
45223 + REPORT_ERROR(MINOR, E_INVALID_STATE, ("HEADER_TYPE_IPSEC_AH and HEADER_TYPE_IPSEC_ESP may not be defined in separate units"));
45224 + XX_Free(p_ModifiedNetEnvParams);
45225 + return NULL;
45226 + }
45227 + else
45228 + {
45229 + ipsecEspUnit = i;
45230 + ipsecEspExists = TRUE;
45231 + }
45232 + }
45233 + /* ENCAP_ESP */
45234 + if (p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[k].hdr == HEADER_TYPE_UDP_ENCAP_ESP)
45235 + {
45236 + /* IPSec UDP encapsulation is currently set to use SHIM1 */
45237 + p_FmPcd->netEnvs[netEnvCurrId].aliasHdrs[specialUnits].hdr = HEADER_TYPE_UDP_ENCAP_ESP;
45238 + p_FmPcd->netEnvs[netEnvCurrId].aliasHdrs[specialUnits++].aliasHdr = HEADER_TYPE_USER_DEFINED_SHIM1;
45239 + p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[k].hdr = HEADER_TYPE_USER_DEFINED_SHIM1;
45240 + p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[k].opt = 0;
45241 + }
45242 +#if (DPAA_VERSION >= 11) || ((DPAA_VERSION == 10) && defined(FM_CAPWAP_SUPPORT))
45243 + /* UDP_LITE */
45244 + if (p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[k].hdr == HEADER_TYPE_UDP_LITE)
45245 + {
45246 + p_FmPcd->netEnvs[netEnvCurrId].aliasHdrs[specialUnits].hdr = HEADER_TYPE_UDP_LITE;
45247 + p_FmPcd->netEnvs[netEnvCurrId].aliasHdrs[specialUnits++].aliasHdr = HEADER_TYPE_UDP;
45248 + p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[k].hdr = HEADER_TYPE_UDP;
45249 + p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[k].opt = 0;
45250 + }
45251 +#endif /* (DPAA_VERSION >= 11) || ((DPAA_VERSION == 10) && defined(FM_CAPWAP_SUPPORT)) */
45252 +
45253 + /* IP FRAG */
45254 + if ((p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[k].hdr == HEADER_TYPE_IPv4) &&
45255 + (p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[k].opt == IPV4_FRAG_1))
45256 + {
45257 + /* If IPv4+Frag, we need to set 2 units - SHIM 2 and IPv4. We first set SHIM2, and than check if
45258 + * IPv4 exists. If so we don't need to set an extra unit
45259 + * We consider as "having IPv4" any IPv4 without interchangable headers
45260 + * but including any options. */
45261 + p_FmPcd->netEnvs[netEnvCurrId].aliasHdrs[specialUnits].hdr = HEADER_TYPE_IPv4;
45262 + p_FmPcd->netEnvs[netEnvCurrId].aliasHdrs[specialUnits].opt = IPV4_FRAG_1;
45263 + p_FmPcd->netEnvs[netEnvCurrId].aliasHdrs[specialUnits++].aliasHdr = HEADER_TYPE_USER_DEFINED_SHIM2;
45264 + p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[k].hdr = HEADER_TYPE_USER_DEFINED_SHIM2;
45265 + p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[k].opt = 0;
45266 +
45267 + /* check if IPv4 header exists by itself */
45268 + if (FmPcdNetEnvGetUnitId(p_FmPcd, netEnvCurrId, HEADER_TYPE_IPv4, FALSE, 0) == FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS)
45269 + {
45270 + p_FmPcd->netEnvs[netEnvCurrId].units[p_NetEnvParams->numOfDistinctionUnits].hdrs[0].hdr = HEADER_TYPE_IPv4;
45271 + p_FmPcd->netEnvs[netEnvCurrId].units[p_NetEnvParams->numOfDistinctionUnits++].hdrs[0].opt = 0;
45272 + }
45273 + }
45274 + if ((p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[k].hdr == HEADER_TYPE_IPv6) &&
45275 + (p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[k].opt == IPV6_FRAG_1))
45276 + {
45277 + /* If IPv6+Frag, we need to set 2 units - SHIM 2 and IPv6. We first set SHIM2, and than check if
45278 + * IPv4 exists. If so we don't need to set an extra unit
45279 + * We consider as "having IPv6" any IPv6 without interchangable headers
45280 + * but including any options. */
45281 + p_FmPcd->netEnvs[netEnvCurrId].aliasHdrs[specialUnits].hdr = HEADER_TYPE_IPv6;
45282 + p_FmPcd->netEnvs[netEnvCurrId].aliasHdrs[specialUnits].opt = IPV6_FRAG_1;
45283 + p_FmPcd->netEnvs[netEnvCurrId].aliasHdrs[specialUnits++].aliasHdr = HEADER_TYPE_USER_DEFINED_SHIM2;
45284 + p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[k].hdr = HEADER_TYPE_USER_DEFINED_SHIM2;
45285 + p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[k].opt = 0;
45286 +
45287 + /* check if IPv6 header exists by itself */
45288 + if (FmPcdNetEnvGetUnitId(p_FmPcd, netEnvCurrId, HEADER_TYPE_IPv6, FALSE, 0) == FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS)
45289 + {
45290 + p_FmPcd->netEnvs[netEnvCurrId].units[p_NetEnvParams->numOfDistinctionUnits].hdrs[0].hdr = HEADER_TYPE_IPv6;
45291 + p_FmPcd->netEnvs[netEnvCurrId].units[p_NetEnvParams->numOfDistinctionUnits++].hdrs[0].opt = 0;
45292 + }
45293 + }
45294 +#if (DPAA_VERSION >= 11)
45295 + /* CAPWAP FRAG */
45296 + if ((p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[k].hdr == HEADER_TYPE_CAPWAP) &&
45297 + (p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[k].opt == CAPWAP_FRAG_1))
45298 + {
45299 + p_FmPcd->netEnvs[netEnvCurrId].aliasHdrs[specialUnits].hdr = HEADER_TYPE_CAPWAP;
45300 + p_FmPcd->netEnvs[netEnvCurrId].aliasHdrs[specialUnits].opt = CAPWAP_FRAG_1;
45301 + p_FmPcd->netEnvs[netEnvCurrId].aliasHdrs[specialUnits++].aliasHdr = HEADER_TYPE_USER_DEFINED_SHIM2;
45302 + p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[k].hdr = HEADER_TYPE_USER_DEFINED_SHIM2;
45303 + p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[k].opt = 0;
45304 + }
45305 +#endif /* (DPAA_VERSION >= 11) */
45306 + }
45307 + }
45308 +
45309 + /* if private header (shim), check that no other headers specified */
45310 + for (i = 0; (i < FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS)
45311 + && (p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[0].hdr != HEADER_TYPE_NONE); i++)
45312 + {
45313 + if (IS_PRIVATE_HEADER(p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[0].hdr))
45314 + if (p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[1].hdr != HEADER_TYPE_NONE)
45315 + {
45316 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("SHIM header may not be interchanged with other headers"));
45317 + XX_Free(p_ModifiedNetEnvParams);
45318 + return NULL;
45319 + }
45320 + }
45321 +
45322 + for (i = 0; i < p_NetEnvParams->numOfDistinctionUnits; i++)
45323 + {
45324 + if (IS_PRIVATE_HEADER(p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[0].hdr))
45325 + switch (p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[0].hdr)
45326 + {
45327 + case (HEADER_TYPE_USER_DEFINED_SHIM1):
45328 + if (shim1Selected)
45329 + {
45330 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("SHIM header cannot be selected with UDP_IPSEC_ESP"));
45331 + XX_Free(p_ModifiedNetEnvParams);
45332 + return NULL;
45333 + }
45334 + shim1Selected = TRUE;
45335 + p_FmPcd->netEnvs[netEnvCurrId].unitsVectors[i] = 0x00000001;
45336 + break;
45337 + case (HEADER_TYPE_USER_DEFINED_SHIM2):
45338 + p_FmPcd->netEnvs[netEnvCurrId].unitsVectors[i] = 0x00000002;
45339 + break;
45340 + default:
45341 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Requested SHIM not supported"));
45342 + }
45343 + else
45344 + {
45345 + p_FmPcd->netEnvs[netEnvCurrId].unitsVectors[i] = (uint32_t)(0x80000000 >> bitId++);
45346 +
45347 + if (IS_SPECIAL_HEADER(p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[0].hdr))
45348 + p_FmPcd->netEnvs[netEnvCurrId].macsecVector = p_FmPcd->netEnvs[netEnvCurrId].unitsVectors[i];
45349 + }
45350 + }
45351 +
45352 + /* define a set of hardware parser LCV's according to the defined netenv */
45353 +
45354 + /* set an array of LCV's for each header in the netEnv */
45355 + for (i = 0; (i < FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS)
45356 + && (p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[0].hdr != HEADER_TYPE_NONE); i++)
45357 + {
45358 + /* private headers have no LCV in the hard parser */
45359 + if (!IS_PRIVATE_HEADER(p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[0].hdr))
45360 + {
45361 + for (k = 0; (k < FM_PCD_MAX_NUM_OF_INTERCHANGEABLE_HDRS)
45362 + && (p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[k].hdr != HEADER_TYPE_NONE); k++)
45363 + {
45364 + hdrNum = GetPrsHdrNum(p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[k].hdr);
45365 + if ((hdrNum == ILLEGAL_HDR_NUM) || (hdrNum == NO_HDR_NUM))
45366 + {
45367 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, NO_MSG);
45368 + XX_Free(p_ModifiedNetEnvParams);
45369 + return NULL;
45370 + }
45371 + p_FmPcd->netEnvs[netEnvCurrId].lcvs[hdrNum] |= p_FmPcd->netEnvs[netEnvCurrId].unitsVectors[i];
45372 + }
45373 + }
45374 + }
45375 + XX_Free(p_ModifiedNetEnvParams);
45376 +
45377 + p_FmPcd->netEnvs[netEnvCurrId].h_Spinlock = XX_InitSpinlock();
45378 + if (!p_FmPcd->netEnvs[netEnvCurrId].h_Spinlock)
45379 + {
45380 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FM Pcd NetEnv spinlock"));
45381 + return NULL;
45382 + }
45383 + return &p_FmPcd->netEnvs[netEnvCurrId];
45384 +}
45385 +
45386 +t_Error FM_PCD_NetEnvCharacteristicsDelete(t_Handle h_NetEnv)
45387 +{
45388 + t_FmPcdNetEnv *p_NetEnv = (t_FmPcdNetEnv*)h_NetEnv;
45389 + t_FmPcd *p_FmPcd = p_NetEnv->h_FmPcd;
45390 + uint32_t intFlags;
45391 + uint8_t netEnvId = p_NetEnv->netEnvId;
45392 +
45393 + SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_STATE);
45394 + SANITY_CHECK_RETURN_ERROR(!p_FmPcd->p_FmPcdDriverParam, E_INVALID_STATE);
45395 +
45396 + /* check that no port is bound to this netEnv */
45397 + if (p_FmPcd->netEnvs[netEnvId].owners)
45398 + {
45399 + RETURN_ERROR(MINOR, E_INVALID_STATE,
45400 + ("Trying to delete a netEnv that has ports/schemes/trees/clsPlanGrps bound to"));
45401 + }
45402 +
45403 + intFlags = FmPcdLock(p_FmPcd);
45404 +
45405 + p_FmPcd->netEnvs[netEnvId].used = FALSE;
45406 + p_FmPcd->netEnvs[netEnvId].clsPlanGrpId = ILLEGAL_CLS_PLAN;
45407 +
45408 + memset(p_FmPcd->netEnvs[netEnvId].units, 0, sizeof(t_FmPcdIntDistinctionUnit)*FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS);
45409 + memset(p_FmPcd->netEnvs[netEnvId].unitsVectors, 0, sizeof(uint32_t)*FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS);
45410 + memset(p_FmPcd->netEnvs[netEnvId].lcvs, 0, sizeof(uint32_t)*FM_PCD_PRS_NUM_OF_HDRS);
45411 +
45412 + if (p_FmPcd->netEnvs[netEnvId].h_Spinlock)
45413 + XX_FreeSpinlock(p_FmPcd->netEnvs[netEnvId].h_Spinlock);
45414 +
45415 + FmPcdUnlock(p_FmPcd, intFlags);
45416 + return E_OK;
45417 +}
45418 +
45419 +void FM_PCD_HcTxConf(t_Handle h_FmPcd, t_DpaaFD *p_Fd)
45420 +{
45421 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
45422 +
45423 + SANITY_CHECK_RETURN(h_FmPcd, E_INVALID_STATE);
45424 +
45425 + FmHcTxConf(p_FmPcd->h_Hc, p_Fd);
45426 +}
45427 +
45428 +t_Error FM_PCD_SetAdvancedOffloadSupport(t_Handle h_FmPcd)
45429 +{
45430 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
45431 + t_FmCtrlCodeRevisionInfo revInfo;
45432 + t_Error err;
45433 +
45434 + SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);
45435 + SANITY_CHECK_RETURN_ERROR(!p_FmPcd->p_FmPcdDriverParam, E_INVALID_STATE);
45436 + SANITY_CHECK_RETURN_ERROR(!p_FmPcd->enabled, E_INVALID_STATE);
45437 +
45438 + if ((err = FM_GetFmanCtrlCodeRevision(p_FmPcd->h_Fm, &revInfo)) != E_OK)
45439 + {
45440 + DBG(WARNING, ("FM in guest-mode without IPC, can't validate firmware revision."));
45441 + revInfo.packageRev = IP_OFFLOAD_PACKAGE_NUMBER;
45442 + }
45443 + if (!IS_OFFLOAD_PACKAGE(revInfo.packageRev))
45444 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("Fman ctrl code package"));
45445 +
45446 + if (!p_FmPcd->h_Hc)
45447 + RETURN_ERROR(MAJOR, E_INVALID_HANDLE, ("HC must be initialized in this mode"));
45448 +
45449 + p_FmPcd->advancedOffloadSupport = TRUE;
45450 +
45451 + return E_OK;
45452 +}
45453 +
45454 +uint32_t FM_PCD_GetCounter(t_Handle h_FmPcd, e_FmPcdCounters counter)
45455 +{
45456 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
45457 + uint32_t outCounter = 0;
45458 + t_Error err;
45459 +
45460 + SANITY_CHECK_RETURN_VALUE(h_FmPcd, E_INVALID_HANDLE, 0);
45461 + SANITY_CHECK_RETURN_VALUE(!p_FmPcd->p_FmPcdDriverParam, E_INVALID_STATE, 0);
45462 +
45463 + switch (counter)
45464 + {
45465 + case (e_FM_PCD_KG_COUNTERS_TOTAL):
45466 + if (!p_FmPcd->p_FmPcdKg)
45467 + {
45468 + REPORT_ERROR(MAJOR, E_INVALID_STATE, ("KeyGen is not activated"));
45469 + return 0;
45470 + }
45471 + if ((p_FmPcd->guestId != NCSW_MASTER_ID) &&
45472 + !p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs &&
45473 + !p_FmPcd->h_IpcSession)
45474 + {
45475 + REPORT_ERROR(MINOR, E_NOT_SUPPORTED,
45476 + ("running in guest-mode without neither IPC nor mapped register!"));
45477 + return 0;
45478 + }
45479 + break;
45480 +
45481 + case (e_FM_PCD_PLCR_COUNTERS_YELLOW):
45482 + case (e_FM_PCD_PLCR_COUNTERS_RED):
45483 + case (e_FM_PCD_PLCR_COUNTERS_RECOLORED_TO_RED):
45484 + case (e_FM_PCD_PLCR_COUNTERS_RECOLORED_TO_YELLOW):
45485 + case (e_FM_PCD_PLCR_COUNTERS_TOTAL):
45486 + case (e_FM_PCD_PLCR_COUNTERS_LENGTH_MISMATCH):
45487 + if (!p_FmPcd->p_FmPcdPlcr)
45488 + {
45489 + REPORT_ERROR(MAJOR, E_INVALID_STATE, ("Policer is not activated"));
45490 + return 0;
45491 + }
45492 + if ((p_FmPcd->guestId != NCSW_MASTER_ID) &&
45493 + !p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs &&
45494 + !p_FmPcd->h_IpcSession)
45495 + {
45496 + REPORT_ERROR(MINOR, E_NOT_SUPPORTED,
45497 + ("running in \"guest-mode\" without neither IPC nor mapped register!"));
45498 + return 0;
45499 + }
45500 +
45501 + /* check that counters are enabled */
45502 + if (p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs &&
45503 + !(GET_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_gcr) & FM_PCD_PLCR_GCR_STEN))
45504 + {
45505 + REPORT_ERROR(MINOR, E_INVALID_STATE, ("Requested counter was not enabled"));
45506 + return 0;
45507 + }
45508 + ASSERT_COND(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs ||
45509 + ((p_FmPcd->guestId != NCSW_MASTER_ID) && p_FmPcd->h_IpcSession));
45510 + break;
45511 +
45512 + case (e_FM_PCD_PRS_COUNTERS_PARSE_DISPATCH):
45513 + case (e_FM_PCD_PRS_COUNTERS_L2_PARSE_RESULT_RETURNED):
45514 + case (e_FM_PCD_PRS_COUNTERS_L3_PARSE_RESULT_RETURNED):
45515 + case (e_FM_PCD_PRS_COUNTERS_L4_PARSE_RESULT_RETURNED):
45516 + case (e_FM_PCD_PRS_COUNTERS_SHIM_PARSE_RESULT_RETURNED):
45517 + case (e_FM_PCD_PRS_COUNTERS_L2_PARSE_RESULT_RETURNED_WITH_ERR):
45518 + case (e_FM_PCD_PRS_COUNTERS_L3_PARSE_RESULT_RETURNED_WITH_ERR):
45519 + case (e_FM_PCD_PRS_COUNTERS_L4_PARSE_RESULT_RETURNED_WITH_ERR):
45520 + case (e_FM_PCD_PRS_COUNTERS_SHIM_PARSE_RESULT_RETURNED_WITH_ERR):
45521 + case (e_FM_PCD_PRS_COUNTERS_SOFT_PRS_CYCLES):
45522 + case (e_FM_PCD_PRS_COUNTERS_SOFT_PRS_STALL_CYCLES):
45523 + case (e_FM_PCD_PRS_COUNTERS_HARD_PRS_CYCLE_INCL_STALL_CYCLES):
45524 + case (e_FM_PCD_PRS_COUNTERS_MURAM_READ_CYCLES):
45525 + case (e_FM_PCD_PRS_COUNTERS_MURAM_READ_STALL_CYCLES):
45526 + case (e_FM_PCD_PRS_COUNTERS_MURAM_WRITE_CYCLES):
45527 + case (e_FM_PCD_PRS_COUNTERS_MURAM_WRITE_STALL_CYCLES):
45528 + case (e_FM_PCD_PRS_COUNTERS_FPM_COMMAND_STALL_CYCLES):
45529 + if (!p_FmPcd->p_FmPcdPrs)
45530 + {
45531 + REPORT_ERROR(MAJOR, E_INVALID_STATE, ("Parser is not activated"));
45532 + return 0;
45533 + }
45534 + if ((p_FmPcd->guestId != NCSW_MASTER_ID) &&
45535 + !p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs &&
45536 + !p_FmPcd->h_IpcSession)
45537 + {
45538 + REPORT_ERROR(MINOR, E_NOT_SUPPORTED,
45539 + ("running in guest-mode without neither IPC nor mapped register!"));
45540 + return 0;
45541 + }
45542 + break;
45543 + default:
45544 + REPORT_ERROR(MAJOR, E_INVALID_STATE, ("Unsupported type of counter"));
45545 + return 0;
45546 + }
45547 +
45548 + if ((p_FmPcd->guestId != NCSW_MASTER_ID) &&
45549 + p_FmPcd->h_IpcSession)
45550 + {
45551 + t_FmPcdIpcMsg msg;
45552 + t_FmPcdIpcReply reply;
45553 + uint32_t replyLength;
45554 +
45555 + memset(&msg, 0, sizeof(msg));
45556 + memset(&reply, 0, sizeof(reply));
45557 + msg.msgId = FM_PCD_GET_COUNTER;
45558 + memcpy(msg.msgBody, (uint8_t *)&counter, sizeof(uint32_t));
45559 + replyLength = sizeof(uint32_t) + sizeof(uint32_t);
45560 + if ((err = XX_IpcSendMessage(p_FmPcd->h_IpcSession,
45561 + (uint8_t*)&msg,
45562 + sizeof(msg.msgId) +sizeof(uint32_t),
45563 + (uint8_t*)&reply,
45564 + &replyLength,
45565 + NULL,
45566 + NULL)) != E_OK)
45567 + RETURN_ERROR(MAJOR, err, NO_MSG);
45568 + if (replyLength != sizeof(uint32_t) + sizeof(uint32_t))
45569 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch"));
45570 +
45571 + memcpy((uint8_t*)&outCounter, reply.replyBody, sizeof(uint32_t));
45572 + return outCounter;
45573 + }
45574 +
45575 + switch (counter)
45576 + {
45577 + /* Parser statistics */
45578 + case (e_FM_PCD_PRS_COUNTERS_PARSE_DISPATCH):
45579 + return GET_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_pds);
45580 + case (e_FM_PCD_PRS_COUNTERS_L2_PARSE_RESULT_RETURNED):
45581 + return GET_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_l2rrs);
45582 + case (e_FM_PCD_PRS_COUNTERS_L3_PARSE_RESULT_RETURNED):
45583 + return GET_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_l3rrs);
45584 + case (e_FM_PCD_PRS_COUNTERS_L4_PARSE_RESULT_RETURNED):
45585 + return GET_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_l4rrs);
45586 + case (e_FM_PCD_PRS_COUNTERS_SHIM_PARSE_RESULT_RETURNED):
45587 + return GET_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_srrs);
45588 + case (e_FM_PCD_PRS_COUNTERS_L2_PARSE_RESULT_RETURNED_WITH_ERR):
45589 + return GET_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_l2rres);
45590 + case (e_FM_PCD_PRS_COUNTERS_L3_PARSE_RESULT_RETURNED_WITH_ERR):
45591 + return GET_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_l3rres);
45592 + case (e_FM_PCD_PRS_COUNTERS_L4_PARSE_RESULT_RETURNED_WITH_ERR):
45593 + return GET_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_l4rres);
45594 + case (e_FM_PCD_PRS_COUNTERS_SHIM_PARSE_RESULT_RETURNED_WITH_ERR):
45595 + return GET_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_srres);
45596 + case (e_FM_PCD_PRS_COUNTERS_SOFT_PRS_CYCLES):
45597 + return GET_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_spcs);
45598 + case (e_FM_PCD_PRS_COUNTERS_SOFT_PRS_STALL_CYCLES):
45599 + return GET_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_spscs);
45600 + case (e_FM_PCD_PRS_COUNTERS_HARD_PRS_CYCLE_INCL_STALL_CYCLES):
45601 + return GET_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_hxscs);
45602 + case (e_FM_PCD_PRS_COUNTERS_MURAM_READ_CYCLES):
45603 + return GET_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_mrcs);
45604 + case (e_FM_PCD_PRS_COUNTERS_MURAM_READ_STALL_CYCLES):
45605 + return GET_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_mrscs);
45606 + case (e_FM_PCD_PRS_COUNTERS_MURAM_WRITE_CYCLES):
45607 + return GET_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_mwcs);
45608 + case (e_FM_PCD_PRS_COUNTERS_MURAM_WRITE_STALL_CYCLES):
45609 + return GET_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_mwscs);
45610 + case (e_FM_PCD_PRS_COUNTERS_FPM_COMMAND_STALL_CYCLES):
45611 + return GET_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_fcscs);
45612 + case (e_FM_PCD_KG_COUNTERS_TOTAL):
45613 + return GET_UINT32(p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs->fmkg_tpc);
45614 +
45615 + /* Policer statistics */
45616 + case (e_FM_PCD_PLCR_COUNTERS_YELLOW):
45617 + return GET_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_ypcnt);
45618 + case (e_FM_PCD_PLCR_COUNTERS_RED):
45619 + return GET_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_rpcnt);
45620 + case (e_FM_PCD_PLCR_COUNTERS_RECOLORED_TO_RED):
45621 + return GET_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_rrpcnt);
45622 + case (e_FM_PCD_PLCR_COUNTERS_RECOLORED_TO_YELLOW):
45623 + return GET_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_rypcnt);
45624 + case (e_FM_PCD_PLCR_COUNTERS_TOTAL):
45625 + return GET_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_tpcnt);
45626 + case (e_FM_PCD_PLCR_COUNTERS_LENGTH_MISMATCH):
45627 + return GET_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_flmcnt);
45628 + }
45629 + return 0;
45630 +}
45631 +
45632 +t_Error FM_PCD_SetException(t_Handle h_FmPcd, e_FmPcdExceptions exception, bool enable)
45633 +{
45634 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
45635 + uint32_t bitMask = 0, tmpReg;
45636 +
45637 + SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);
45638 + SANITY_CHECK_RETURN_ERROR(!p_FmPcd->p_FmPcdDriverParam, E_INVALID_STATE);
45639 +
45640 + if (p_FmPcd->guestId != NCSW_MASTER_ID)
45641 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("FM_PCD_SetException - guest mode!"));
45642 +
45643 + GET_FM_PCD_EXCEPTION_FLAG(bitMask, exception);
45644 +
45645 + if (bitMask)
45646 + {
45647 + if (enable)
45648 + p_FmPcd->exceptions |= bitMask;
45649 + else
45650 + p_FmPcd->exceptions &= ~bitMask;
45651 +
45652 + switch (exception)
45653 + {
45654 + case (e_FM_PCD_KG_EXCEPTION_DOUBLE_ECC):
45655 + case (e_FM_PCD_KG_EXCEPTION_KEYSIZE_OVERFLOW):
45656 + if (!p_FmPcd->p_FmPcdKg)
45657 + RETURN_ERROR(MINOR, E_INVALID_STATE, ("Can't ask for this interrupt - keygen is not working"));
45658 + break;
45659 + case (e_FM_PCD_PLCR_EXCEPTION_DOUBLE_ECC):
45660 + case (e_FM_PCD_PLCR_EXCEPTION_INIT_ENTRY_ERROR):
45661 + case (e_FM_PCD_PLCR_EXCEPTION_PRAM_SELF_INIT_COMPLETE):
45662 + case (e_FM_PCD_PLCR_EXCEPTION_ATOMIC_ACTION_COMPLETE):
45663 + if (!p_FmPcd->p_FmPcdPlcr)
45664 + RETURN_ERROR(MINOR, E_INVALID_STATE, ("Can't ask for this interrupt - policer is not working"));
45665 + break;
45666 + case (e_FM_PCD_PRS_EXCEPTION_DOUBLE_ECC):
45667 + case (e_FM_PCD_PRS_EXCEPTION_SINGLE_ECC):
45668 + if (!p_FmPcd->p_FmPcdPrs)
45669 + RETURN_ERROR(MINOR, E_INVALID_STATE, ("Can't ask for this interrupt - parser is not working"));
45670 + break;
45671 + }
45672 +
45673 + switch (exception)
45674 + {
45675 + case (e_FM_PCD_KG_EXCEPTION_DOUBLE_ECC):
45676 + tmpReg = GET_UINT32(p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs->fmkg_eeer);
45677 + if (enable)
45678 + tmpReg |= FM_EX_KG_DOUBLE_ECC;
45679 + else
45680 + tmpReg &= ~FM_EX_KG_DOUBLE_ECC;
45681 + WRITE_UINT32(p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs->fmkg_eeer, tmpReg);
45682 + break;
45683 + case (e_FM_PCD_KG_EXCEPTION_KEYSIZE_OVERFLOW):
45684 + tmpReg = GET_UINT32(p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs->fmkg_eeer);
45685 + if (enable)
45686 + tmpReg |= FM_EX_KG_KEYSIZE_OVERFLOW;
45687 + else
45688 + tmpReg &= ~FM_EX_KG_KEYSIZE_OVERFLOW;
45689 + WRITE_UINT32(p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs->fmkg_eeer, tmpReg);
45690 + break;
45691 + case (e_FM_PCD_PRS_EXCEPTION_DOUBLE_ECC):
45692 + tmpReg = GET_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_perer);
45693 + if (enable)
45694 + tmpReg |= FM_PCD_PRS_DOUBLE_ECC;
45695 + else
45696 + tmpReg &= ~FM_PCD_PRS_DOUBLE_ECC;
45697 + WRITE_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_perer, tmpReg);
45698 + break;
45699 + case (e_FM_PCD_PRS_EXCEPTION_SINGLE_ECC):
45700 + tmpReg = GET_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_pever);
45701 + if (enable)
45702 + tmpReg |= FM_PCD_PRS_SINGLE_ECC;
45703 + else
45704 + tmpReg &= ~FM_PCD_PRS_SINGLE_ECC;
45705 + WRITE_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_pever, tmpReg);
45706 + break;
45707 + case (e_FM_PCD_PLCR_EXCEPTION_DOUBLE_ECC):
45708 + tmpReg = GET_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_eier);
45709 + if (enable)
45710 + tmpReg |= FM_PCD_PLCR_DOUBLE_ECC;
45711 + else
45712 + tmpReg &= ~FM_PCD_PLCR_DOUBLE_ECC;
45713 + WRITE_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_eier, tmpReg);
45714 + break;
45715 + case (e_FM_PCD_PLCR_EXCEPTION_INIT_ENTRY_ERROR):
45716 + tmpReg = GET_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_eier);
45717 + if (enable)
45718 + tmpReg |= FM_PCD_PLCR_INIT_ENTRY_ERROR;
45719 + else
45720 + tmpReg &= ~FM_PCD_PLCR_INIT_ENTRY_ERROR;
45721 + WRITE_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_eier, tmpReg);
45722 + break;
45723 + case (e_FM_PCD_PLCR_EXCEPTION_PRAM_SELF_INIT_COMPLETE):
45724 + tmpReg = GET_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_ier);
45725 + if (enable)
45726 + tmpReg |= FM_PCD_PLCR_PRAM_SELF_INIT_COMPLETE;
45727 + else
45728 + tmpReg &= ~FM_PCD_PLCR_PRAM_SELF_INIT_COMPLETE;
45729 + WRITE_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_ier, tmpReg);
45730 + break;
45731 + case (e_FM_PCD_PLCR_EXCEPTION_ATOMIC_ACTION_COMPLETE):
45732 + tmpReg = GET_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_ier);
45733 + if (enable)
45734 + tmpReg |= FM_PCD_PLCR_ATOMIC_ACTION_COMPLETE;
45735 + else
45736 + tmpReg &= ~FM_PCD_PLCR_ATOMIC_ACTION_COMPLETE;
45737 + WRITE_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_ier, tmpReg);
45738 + break;
45739 + }
45740 + /* for ECC exceptions driver automatically enables ECC mechanism, if disabled.
45741 + Driver may disable them automatically, depending on driver's status */
45742 + if (enable && ((exception == e_FM_PCD_KG_EXCEPTION_DOUBLE_ECC) |
45743 + (exception == e_FM_PCD_PLCR_EXCEPTION_DOUBLE_ECC) |
45744 + (exception == e_FM_PCD_PRS_EXCEPTION_DOUBLE_ECC) |
45745 + (exception == e_FM_PCD_PRS_EXCEPTION_SINGLE_ECC)))
45746 + FmEnableRamsEcc(p_FmPcd->h_Fm);
45747 + if (!enable && ((exception == e_FM_PCD_KG_EXCEPTION_DOUBLE_ECC) |
45748 + (exception == e_FM_PCD_PLCR_EXCEPTION_DOUBLE_ECC) |
45749 + (exception == e_FM_PCD_PRS_EXCEPTION_DOUBLE_ECC) |
45750 + (exception == e_FM_PCD_PRS_EXCEPTION_SINGLE_ECC)))
45751 + FmDisableRamsEcc(p_FmPcd->h_Fm);
45752 + }
45753 +
45754 + return E_OK;
45755 +}
45756 +
45757 +t_Error FM_PCD_ForceIntr (t_Handle h_FmPcd, e_FmPcdExceptions exception)
45758 +{
45759 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
45760 +
45761 + SANITY_CHECK_RETURN_ERROR(h_FmPcd, E_INVALID_HANDLE);
45762 + SANITY_CHECK_RETURN_ERROR(!p_FmPcd->p_FmPcdDriverParam, E_INVALID_STATE);
45763 +
45764 + if (p_FmPcd->guestId != NCSW_MASTER_ID)
45765 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("FM_PCD_ForceIntr - guest mode!"));
45766 +
45767 + switch (exception)
45768 + {
45769 + case (e_FM_PCD_KG_EXCEPTION_DOUBLE_ECC):
45770 + case (e_FM_PCD_KG_EXCEPTION_KEYSIZE_OVERFLOW):
45771 + if (!p_FmPcd->p_FmPcdKg)
45772 + RETURN_ERROR(MINOR, E_INVALID_STATE, ("Can't ask for this interrupt - keygen is not working"));
45773 + break;
45774 + case (e_FM_PCD_PLCR_EXCEPTION_DOUBLE_ECC):
45775 + case (e_FM_PCD_PLCR_EXCEPTION_INIT_ENTRY_ERROR):
45776 + case (e_FM_PCD_PLCR_EXCEPTION_PRAM_SELF_INIT_COMPLETE):
45777 + case (e_FM_PCD_PLCR_EXCEPTION_ATOMIC_ACTION_COMPLETE):
45778 + if (!p_FmPcd->p_FmPcdPlcr)
45779 + RETURN_ERROR(MINOR, E_INVALID_STATE, ("Can't ask for this interrupt - policer is not working"));
45780 + break;
45781 + case (e_FM_PCD_PRS_EXCEPTION_DOUBLE_ECC):
45782 + case (e_FM_PCD_PRS_EXCEPTION_SINGLE_ECC):
45783 + if (!p_FmPcd->p_FmPcdPrs)
45784 + RETURN_ERROR(MINOR, E_INVALID_STATE, ("Can't ask for this interrupt -parsrer is not working"));
45785 + break;
45786 + default:
45787 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Invalid interrupt requested"));
45788 + }
45789 + switch (exception)
45790 + {
45791 + case e_FM_PCD_PRS_EXCEPTION_DOUBLE_ECC:
45792 + if (!(p_FmPcd->exceptions & FM_PCD_EX_PRS_DOUBLE_ECC))
45793 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("The selected exception is masked"));
45794 + break;
45795 + case e_FM_PCD_PRS_EXCEPTION_SINGLE_ECC:
45796 + if (!(p_FmPcd->exceptions & FM_PCD_EX_PRS_SINGLE_ECC))
45797 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("The selected exception is masked"));
45798 + break;
45799 + case e_FM_PCD_KG_EXCEPTION_DOUBLE_ECC:
45800 + if (!(p_FmPcd->exceptions & FM_EX_KG_DOUBLE_ECC))
45801 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("The selected exception is masked"));
45802 + WRITE_UINT32(p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs->fmkg_feer, FM_EX_KG_DOUBLE_ECC);
45803 + break;
45804 + case e_FM_PCD_KG_EXCEPTION_KEYSIZE_OVERFLOW:
45805 + if (!(p_FmPcd->exceptions & FM_EX_KG_KEYSIZE_OVERFLOW))
45806 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("The selected exception is masked"));
45807 + WRITE_UINT32(p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs->fmkg_feer, FM_EX_KG_KEYSIZE_OVERFLOW);
45808 + break;
45809 + case e_FM_PCD_PLCR_EXCEPTION_DOUBLE_ECC:
45810 + if (!(p_FmPcd->exceptions & FM_PCD_EX_PLCR_DOUBLE_ECC))
45811 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("The selected exception is masked"));
45812 + WRITE_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_eifr, FM_PCD_PLCR_DOUBLE_ECC);
45813 + break;
45814 + case e_FM_PCD_PLCR_EXCEPTION_INIT_ENTRY_ERROR:
45815 + if (!(p_FmPcd->exceptions & FM_PCD_EX_PLCR_INIT_ENTRY_ERROR))
45816 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("The selected exception is masked"));
45817 + WRITE_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_eifr, FM_PCD_PLCR_INIT_ENTRY_ERROR);
45818 + break;
45819 + case e_FM_PCD_PLCR_EXCEPTION_PRAM_SELF_INIT_COMPLETE:
45820 + if (!(p_FmPcd->exceptions & FM_PCD_EX_PLCR_PRAM_SELF_INIT_COMPLETE))
45821 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("The selected exception is masked"));
45822 + WRITE_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_ifr, FM_PCD_PLCR_PRAM_SELF_INIT_COMPLETE);
45823 + break;
45824 + case e_FM_PCD_PLCR_EXCEPTION_ATOMIC_ACTION_COMPLETE:
45825 + if (!(p_FmPcd->exceptions & FM_PCD_EX_PLCR_ATOMIC_ACTION_COMPLETE))
45826 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("The selected exception is masked"));
45827 + WRITE_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_ifr, FM_PCD_PLCR_ATOMIC_ACTION_COMPLETE);
45828 + break;
45829 + }
45830 +
45831 + return E_OK;
45832 +}
45833 +
45834 +
45835 +t_Error FM_PCD_ModifyCounter(t_Handle h_FmPcd, e_FmPcdCounters counter, uint32_t value)
45836 +{
45837 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
45838 +
45839 + SANITY_CHECK_RETURN_ERROR(h_FmPcd, E_INVALID_HANDLE);
45840 + SANITY_CHECK_RETURN_ERROR(!p_FmPcd->p_FmPcdDriverParam, E_INVALID_STATE);
45841 +
45842 + if (p_FmPcd->guestId != NCSW_MASTER_ID)
45843 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("FM_PCD_ModifyCounter - guest mode!"));
45844 +
45845 + switch (counter)
45846 + {
45847 + case (e_FM_PCD_KG_COUNTERS_TOTAL):
45848 + if (!p_FmPcd->p_FmPcdKg)
45849 + RETURN_ERROR(MINOR, E_INVALID_STATE, ("Invalid counters - KeyGen is not working"));
45850 + break;
45851 + case (e_FM_PCD_PLCR_COUNTERS_YELLOW):
45852 + case (e_FM_PCD_PLCR_COUNTERS_RED):
45853 + case (e_FM_PCD_PLCR_COUNTERS_RECOLORED_TO_RED):
45854 + case (e_FM_PCD_PLCR_COUNTERS_RECOLORED_TO_YELLOW):
45855 + case (e_FM_PCD_PLCR_COUNTERS_TOTAL):
45856 + case (e_FM_PCD_PLCR_COUNTERS_LENGTH_MISMATCH):
45857 + if (!p_FmPcd->p_FmPcdPlcr)
45858 + RETURN_ERROR(MINOR, E_INVALID_STATE, ("Invalid counters - Policer is not working"));
45859 + if (!(GET_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_gcr) & FM_PCD_PLCR_GCR_STEN))
45860 + RETURN_ERROR(MINOR, E_INVALID_STATE, ("Requested counter was not enabled"));
45861 + break;
45862 + case (e_FM_PCD_PRS_COUNTERS_PARSE_DISPATCH):
45863 + case (e_FM_PCD_PRS_COUNTERS_L2_PARSE_RESULT_RETURNED):
45864 + case (e_FM_PCD_PRS_COUNTERS_L3_PARSE_RESULT_RETURNED):
45865 + case (e_FM_PCD_PRS_COUNTERS_L4_PARSE_RESULT_RETURNED):
45866 + case (e_FM_PCD_PRS_COUNTERS_SHIM_PARSE_RESULT_RETURNED):
45867 + case (e_FM_PCD_PRS_COUNTERS_L2_PARSE_RESULT_RETURNED_WITH_ERR):
45868 + case (e_FM_PCD_PRS_COUNTERS_L3_PARSE_RESULT_RETURNED_WITH_ERR):
45869 + case (e_FM_PCD_PRS_COUNTERS_L4_PARSE_RESULT_RETURNED_WITH_ERR):
45870 + case (e_FM_PCD_PRS_COUNTERS_SHIM_PARSE_RESULT_RETURNED_WITH_ERR):
45871 + case (e_FM_PCD_PRS_COUNTERS_SOFT_PRS_CYCLES):
45872 + case (e_FM_PCD_PRS_COUNTERS_SOFT_PRS_STALL_CYCLES):
45873 + case (e_FM_PCD_PRS_COUNTERS_HARD_PRS_CYCLE_INCL_STALL_CYCLES):
45874 + case (e_FM_PCD_PRS_COUNTERS_MURAM_READ_CYCLES):
45875 + case (e_FM_PCD_PRS_COUNTERS_MURAM_READ_STALL_CYCLES):
45876 + case (e_FM_PCD_PRS_COUNTERS_MURAM_WRITE_CYCLES):
45877 + case (e_FM_PCD_PRS_COUNTERS_MURAM_WRITE_STALL_CYCLES):
45878 + case (e_FM_PCD_PRS_COUNTERS_FPM_COMMAND_STALL_CYCLES):
45879 + if (!p_FmPcd->p_FmPcdPrs)
45880 + RETURN_ERROR(MINOR, E_INVALID_STATE, ("Unsupported type of counter"));
45881 + break;
45882 + default:
45883 + RETURN_ERROR(MINOR, E_INVALID_STATE, ("Unsupported type of counter"));
45884 + }
45885 + switch (counter)
45886 + {
45887 + case (e_FM_PCD_PRS_COUNTERS_PARSE_DISPATCH):
45888 + WRITE_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_pds, value);
45889 + break;
45890 + case (e_FM_PCD_PRS_COUNTERS_L2_PARSE_RESULT_RETURNED):
45891 + WRITE_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_l2rrs, value);
45892 + break;
45893 + case (e_FM_PCD_PRS_COUNTERS_L3_PARSE_RESULT_RETURNED):
45894 + WRITE_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_l3rrs, value);
45895 + break;
45896 + case (e_FM_PCD_PRS_COUNTERS_L4_PARSE_RESULT_RETURNED):
45897 + WRITE_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_l4rrs, value);
45898 + break;
45899 + case (e_FM_PCD_PRS_COUNTERS_SHIM_PARSE_RESULT_RETURNED):
45900 + WRITE_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_srrs, value);
45901 + break;
45902 + case (e_FM_PCD_PRS_COUNTERS_L2_PARSE_RESULT_RETURNED_WITH_ERR):
45903 + WRITE_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_l2rres, value);
45904 + break;
45905 + case (e_FM_PCD_PRS_COUNTERS_L3_PARSE_RESULT_RETURNED_WITH_ERR):
45906 + WRITE_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_l3rres, value);
45907 + break;
45908 + case (e_FM_PCD_PRS_COUNTERS_L4_PARSE_RESULT_RETURNED_WITH_ERR):
45909 + WRITE_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_l4rres, value);
45910 + break;
45911 + case (e_FM_PCD_PRS_COUNTERS_SHIM_PARSE_RESULT_RETURNED_WITH_ERR):
45912 + WRITE_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_srres, value);
45913 + break;
45914 + case (e_FM_PCD_PRS_COUNTERS_SOFT_PRS_CYCLES):
45915 + WRITE_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_spcs, value);
45916 + break;
45917 + case (e_FM_PCD_PRS_COUNTERS_SOFT_PRS_STALL_CYCLES):
45918 + WRITE_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_spscs, value);
45919 + break;
45920 + case (e_FM_PCD_PRS_COUNTERS_HARD_PRS_CYCLE_INCL_STALL_CYCLES):
45921 + WRITE_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_hxscs, value);
45922 + break;
45923 + case (e_FM_PCD_PRS_COUNTERS_MURAM_READ_CYCLES):
45924 + WRITE_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_mrcs, value);
45925 + break;
45926 + case (e_FM_PCD_PRS_COUNTERS_MURAM_READ_STALL_CYCLES):
45927 + WRITE_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_mrscs, value);
45928 + break;
45929 + case (e_FM_PCD_PRS_COUNTERS_MURAM_WRITE_CYCLES):
45930 + WRITE_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_mwcs, value);
45931 + break;
45932 + case (e_FM_PCD_PRS_COUNTERS_MURAM_WRITE_STALL_CYCLES):
45933 + WRITE_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_mwscs, value);
45934 + break;
45935 + case (e_FM_PCD_PRS_COUNTERS_FPM_COMMAND_STALL_CYCLES):
45936 + WRITE_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_fcscs, value);
45937 + break;
45938 + case (e_FM_PCD_KG_COUNTERS_TOTAL):
45939 + WRITE_UINT32(p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs->fmkg_tpc,value);
45940 + break;
45941 +
45942 + /*Policer counters*/
45943 + case (e_FM_PCD_PLCR_COUNTERS_YELLOW):
45944 + WRITE_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_ypcnt, value);
45945 + break;
45946 + case (e_FM_PCD_PLCR_COUNTERS_RED):
45947 + WRITE_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_rpcnt, value);
45948 + break;
45949 + case (e_FM_PCD_PLCR_COUNTERS_RECOLORED_TO_RED):
45950 + WRITE_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_rrpcnt, value);
45951 + break;
45952 + case (e_FM_PCD_PLCR_COUNTERS_RECOLORED_TO_YELLOW):
45953 + WRITE_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_rypcnt, value);
45954 + break;
45955 + case (e_FM_PCD_PLCR_COUNTERS_TOTAL):
45956 + WRITE_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_tpcnt, value);
45957 + break;
45958 + case (e_FM_PCD_PLCR_COUNTERS_LENGTH_MISMATCH):
45959 + WRITE_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_flmcnt, value);
45960 + break;
45961 + }
45962 +
45963 + return E_OK;
45964 +}
45965 +
45966 +t_Handle FM_PCD_GetHcPort(t_Handle h_FmPcd)
45967 +{
45968 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
45969 + return FmHcGetPort(p_FmPcd->h_Hc);
45970 +}
45971 +
45972 --- /dev/null
45973 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/fm_pcd.h
45974 @@ -0,0 +1,543 @@
45975 +/*
45976 + * Copyright 2008-2012 Freescale Semiconductor Inc.
45977 + *
45978 + * Redistribution and use in source and binary forms, with or without
45979 + * modification, are permitted provided that the following conditions are met:
45980 + * * Redistributions of source code must retain the above copyright
45981 + * notice, this list of conditions and the following disclaimer.
45982 + * * Redistributions in binary form must reproduce the above copyright
45983 + * notice, this list of conditions and the following disclaimer in the
45984 + * documentation and/or other materials provided with the distribution.
45985 + * * Neither the name of Freescale Semiconductor nor the
45986 + * names of its contributors may be used to endorse or promote products
45987 + * derived from this software without specific prior written permission.
45988 + *
45989 + *
45990 + * ALTERNATIVELY, this software may be distributed under the terms of the
45991 + * GNU General Public License ("GPL") as published by the Free Software
45992 + * Foundation, either version 2 of that License or (at your option) any
45993 + * later version.
45994 + *
45995 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
45996 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
45997 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
45998 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
45999 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
46000 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
46001 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
46002 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
46003 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
46004 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
46005 + */
46006 +
46007 +
46008 +/******************************************************************************
46009 + @File fm_pcd.h
46010 +
46011 + @Description FM PCD ...
46012 +*//***************************************************************************/
46013 +#ifndef __FM_PCD_H
46014 +#define __FM_PCD_H
46015 +
46016 +#include "std_ext.h"
46017 +#include "error_ext.h"
46018 +#include "list_ext.h"
46019 +#include "fm_pcd_ext.h"
46020 +#include "fm_common.h"
46021 +#include "fsl_fman_prs.h"
46022 +#include "fsl_fman_kg.h"
46023 +
46024 +#define __ERR_MODULE__ MODULE_FM_PCD
46025 +
46026 +
46027 +/****************************/
46028 +/* Defaults */
46029 +/****************************/
46030 +#define DEFAULT_plcrAutoRefresh FALSE
46031 +#define DEFAULT_fmPcdKgErrorExceptions (FM_EX_KG_DOUBLE_ECC | FM_EX_KG_KEYSIZE_OVERFLOW)
46032 +#define DEFAULT_fmPcdPlcrErrorExceptions (FM_PCD_EX_PLCR_DOUBLE_ECC | FM_PCD_EX_PLCR_INIT_ENTRY_ERROR)
46033 +#define DEFAULT_fmPcdPlcrExceptions 0
46034 +#define DEFAULT_fmPcdPrsErrorExceptions (FM_PCD_EX_PRS_DOUBLE_ECC)
46035 +
46036 +#define DEFAULT_fmPcdPrsExceptions FM_PCD_EX_PRS_SINGLE_ECC
46037 +#define DEFAULT_numOfUsedProfilesPerWindow 16
46038 +#define DEFAULT_numOfSharedPlcrProfiles 4
46039 +
46040 +/****************************/
46041 +/* Network defines */
46042 +/****************************/
46043 +#define UDP_HEADER_SIZE 8
46044 +
46045 +#define ESP_SPI_OFFSET 0
46046 +#define ESP_SPI_SIZE 4
46047 +#define ESP_SEQ_NUM_OFFSET ESP_SPI_SIZE
46048 +#define ESP_SEQ_NUM_SIZE 4
46049 +
46050 +/****************************/
46051 +/* General defines */
46052 +/****************************/
46053 +#define ILLEGAL_CLS_PLAN 0xff
46054 +#define ILLEGAL_NETENV 0xff
46055 +
46056 +#define FM_PCD_MAX_NUM_OF_ALIAS_HDRS 3
46057 +
46058 +/****************************/
46059 +/* Error defines */
46060 +/****************************/
46061 +
46062 +#define FM_PCD_EX_PLCR_DOUBLE_ECC 0x20000000
46063 +#define FM_PCD_EX_PLCR_INIT_ENTRY_ERROR 0x10000000
46064 +#define FM_PCD_EX_PLCR_PRAM_SELF_INIT_COMPLETE 0x08000000
46065 +#define FM_PCD_EX_PLCR_ATOMIC_ACTION_COMPLETE 0x04000000
46066 +
46067 +#define GET_FM_PCD_EXCEPTION_FLAG(bitMask, exception) \
46068 +switch (exception){ \
46069 + case e_FM_PCD_KG_EXCEPTION_DOUBLE_ECC: \
46070 + bitMask = FM_EX_KG_DOUBLE_ECC; break; \
46071 + case e_FM_PCD_PLCR_EXCEPTION_DOUBLE_ECC: \
46072 + bitMask = FM_PCD_EX_PLCR_DOUBLE_ECC; break; \
46073 + case e_FM_PCD_KG_EXCEPTION_KEYSIZE_OVERFLOW: \
46074 + bitMask = FM_EX_KG_KEYSIZE_OVERFLOW; break; \
46075 + case e_FM_PCD_PLCR_EXCEPTION_INIT_ENTRY_ERROR: \
46076 + bitMask = FM_PCD_EX_PLCR_INIT_ENTRY_ERROR; break; \
46077 + case e_FM_PCD_PLCR_EXCEPTION_PRAM_SELF_INIT_COMPLETE: \
46078 + bitMask = FM_PCD_EX_PLCR_PRAM_SELF_INIT_COMPLETE; break; \
46079 + case e_FM_PCD_PLCR_EXCEPTION_ATOMIC_ACTION_COMPLETE: \
46080 + bitMask = FM_PCD_EX_PLCR_ATOMIC_ACTION_COMPLETE; break; \
46081 + case e_FM_PCD_PRS_EXCEPTION_DOUBLE_ECC: \
46082 + bitMask = FM_PCD_EX_PRS_DOUBLE_ECC; break; \
46083 + case e_FM_PCD_PRS_EXCEPTION_SINGLE_ECC: \
46084 + bitMask = FM_PCD_EX_PRS_SINGLE_ECC; break; \
46085 + default: bitMask = 0;break;}
46086 +
46087 +/***********************************************************************/
46088 +/* Policer defines */
46089 +/***********************************************************************/
46090 +#define FM_PCD_PLCR_GCR_STEN 0x40000000
46091 +#define FM_PCD_PLCR_DOUBLE_ECC 0x80000000
46092 +#define FM_PCD_PLCR_INIT_ENTRY_ERROR 0x40000000
46093 +#define FM_PCD_PLCR_PRAM_SELF_INIT_COMPLETE 0x80000000
46094 +#define FM_PCD_PLCR_ATOMIC_ACTION_COMPLETE 0x40000000
46095 +
46096 +/***********************************************************************/
46097 +/* Memory map */
46098 +/***********************************************************************/
46099 +#if defined(__MWERKS__) && !defined(__GNUC__)
46100 +#pragma pack(push,1)
46101 +#endif /* defined(__MWERKS__) && ... */
46102 +
46103 +
46104 +typedef struct {
46105 +/* General Configuration and Status Registers */
46106 + volatile uint32_t fmpl_gcr; /* 0x000 FMPL_GCR - FM Policer General Configuration */
46107 + volatile uint32_t fmpl_gsr; /* 0x004 FMPL_GSR - FM Policer Global Status Register */
46108 + volatile uint32_t fmpl_evr; /* 0x008 FMPL_EVR - FM Policer Event Register */
46109 + volatile uint32_t fmpl_ier; /* 0x00C FMPL_IER - FM Policer Interrupt Enable Register */
46110 + volatile uint32_t fmpl_ifr; /* 0x010 FMPL_IFR - FM Policer Interrupt Force Register */
46111 + volatile uint32_t fmpl_eevr; /* 0x014 FMPL_EEVR - FM Policer Error Event Register */
46112 + volatile uint32_t fmpl_eier; /* 0x018 FMPL_EIER - FM Policer Error Interrupt Enable Register */
46113 + volatile uint32_t fmpl_eifr; /* 0x01C FMPL_EIFR - FM Policer Error Interrupt Force Register */
46114 +/* Global Statistic Counters */
46115 + volatile uint32_t fmpl_rpcnt; /* 0x020 FMPL_RPC - FM Policer RED Packets Counter */
46116 + volatile uint32_t fmpl_ypcnt; /* 0x024 FMPL_YPC - FM Policer YELLOW Packets Counter */
46117 + volatile uint32_t fmpl_rrpcnt; /* 0x028 FMPL_RRPC - FM Policer Recolored RED Packet Counter */
46118 + volatile uint32_t fmpl_rypcnt; /* 0x02C FMPL_RYPC - FM Policer Recolored YELLOW Packet Counter */
46119 + volatile uint32_t fmpl_tpcnt; /* 0x030 FMPL_TPC - FM Policer Total Packet Counter */
46120 + volatile uint32_t fmpl_flmcnt; /* 0x034 FMPL_FLMC - FM Policer Frame Length Mismatch Counter */
46121 + volatile uint32_t fmpl_res0[21]; /* 0x038 - 0x08B Reserved */
46122 +/* Profile RAM Access Registers */
46123 + volatile uint32_t fmpl_par; /* 0x08C FMPL_PAR - FM Policer Profile Action Register*/
46124 + t_FmPcdPlcrProfileRegs profileRegs;
46125 +/* Error Capture Registers */
46126 + volatile uint32_t fmpl_serc; /* 0x100 FMPL_SERC - FM Policer Soft Error Capture */
46127 + volatile uint32_t fmpl_upcr; /* 0x104 FMPL_UPCR - FM Policer Uninitialized Profile Capture Register */
46128 + volatile uint32_t fmpl_res2; /* 0x108 Reserved */
46129 +/* Debug Registers */
46130 + volatile uint32_t fmpl_res3[61]; /* 0x10C-0x200 Reserved Debug*/
46131 +/* Profile Selection Mapping Registers Per Port-ID (n=1-11, 16) */
46132 + volatile uint32_t fmpl_dpmr; /* 0x200 FMPL_DPMR - FM Policer Default Mapping Register */
46133 + volatile uint32_t fmpl_pmr[63]; /*+default 0x204-0x2FF FMPL_PMR1 - FMPL_PMR63, - FM Policer Profile Mapping Registers.
46134 + (for port-ID 1-11, only for supported Port-ID registers) */
46135 +} t_FmPcdPlcrRegs;
46136 +
46137 +#if defined(__MWERKS__) && !defined(__GNUC__)
46138 +#pragma pack(pop)
46139 +#endif /* defined(__MWERKS__) && ... */
46140 +
46141 +
46142 +/***********************************************************************/
46143 +/* Driver's internal structures */
46144 +/***********************************************************************/
46145 +
46146 +typedef struct {
46147 + bool known;
46148 + uint8_t id;
46149 +} t_FmPcdKgSchemesExtractsEntry;
46150 +
46151 +typedef struct {
46152 + t_FmPcdKgSchemesExtractsEntry extractsArray[FM_PCD_KG_MAX_NUM_OF_EXTRACTS_PER_KEY];
46153 +} t_FmPcdKgSchemesExtracts;
46154 +
46155 +typedef struct {
46156 + t_Handle h_Manip;
46157 + bool keepRes;
46158 + e_FmPcdEngine nextEngine;
46159 + uint8_t parseCode;
46160 +} t_FmPcdInfoForManip;
46161 +
46162 +/**************************************************************************//**
46163 + @Description A structure of parameters to communicate
46164 + between the port and PCD regarding the KG scheme.
46165 +*//***************************************************************************/
46166 +typedef struct {
46167 + uint8_t netEnvId; /* in */
46168 + uint8_t numOfDistinctionUnits; /* in */
46169 + uint8_t unitIds[FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS]; /* in */
46170 + uint32_t vector; /* out */
46171 +} t_NetEnvParams;
46172 +
46173 +typedef struct {
46174 + bool allocated;
46175 + uint8_t ownerId; /* guestId for KG in multi-partition only.
46176 + portId for PLCR in any environment */
46177 +} t_FmPcdAllocMng;
46178 +
46179 +typedef struct {
46180 + volatile bool lock;
46181 + bool used;
46182 + uint8_t owners;
46183 + uint8_t netEnvId;
46184 + uint8_t guestId;
46185 + uint8_t baseEntry;
46186 + uint16_t sizeOfGrp;
46187 + protocolOpt_t optArray[FM_PCD_MAX_NUM_OF_OPTIONS(FM_PCD_MAX_NUM_OF_CLS_PLANS)];
46188 +} t_FmPcdKgClsPlanGrp;
46189 +
46190 +typedef struct {
46191 + t_Handle h_FmPcd;
46192 + uint8_t schemeId;
46193 + t_FmPcdLock *p_Lock;
46194 + bool valid;
46195 + uint8_t netEnvId;
46196 + uint8_t owners;
46197 + uint32_t matchVector;
46198 + uint32_t ccUnits;
46199 + bool nextRelativePlcrProfile;
46200 + uint16_t relativeProfileId;
46201 + uint16_t numOfProfiles;
46202 + t_FmPcdKgKeyOrder orderedArray;
46203 + e_FmPcdEngine nextEngine;
46204 + e_FmPcdDoneAction doneAction;
46205 + bool requiredActionFlag;
46206 + uint32_t requiredAction;
46207 + bool extractedOrs;
46208 + uint8_t bitOffsetInPlcrProfile;
46209 + bool directPlcr;
46210 +#if (DPAA_VERSION >= 11)
46211 + bool vspe;
46212 +#endif
46213 +} t_FmPcdKgScheme;
46214 +
46215 +typedef union {
46216 + struct fman_kg_scheme_regs schemeRegs;
46217 + struct fman_kg_pe_regs portRegs;
46218 + struct fman_kg_cp_regs clsPlanRegs;
46219 +} u_FmPcdKgIndirectAccessRegs;
46220 +
46221 +typedef struct {
46222 + struct fman_kg_regs *p_FmPcdKgRegs;
46223 + uint32_t schemeExceptionsBitMask;
46224 + uint8_t numOfSchemes;
46225 + t_Handle h_HwSpinlock;
46226 + uint8_t schemesIds[FM_PCD_KG_NUM_OF_SCHEMES];
46227 + t_FmPcdKgScheme schemes[FM_PCD_KG_NUM_OF_SCHEMES];
46228 + t_FmPcdKgClsPlanGrp clsPlanGrps[FM_MAX_NUM_OF_PORTS];
46229 + uint8_t emptyClsPlanGrpId;
46230 + t_FmPcdAllocMng schemesMng[FM_PCD_KG_NUM_OF_SCHEMES]; /* only for MASTER ! */
46231 + t_FmPcdAllocMng clsPlanBlocksMng[FM_PCD_MAX_NUM_OF_CLS_PLANS/CLS_PLAN_NUM_PER_GRP];
46232 + u_FmPcdKgIndirectAccessRegs *p_IndirectAccessRegs;
46233 +} t_FmPcdKg;
46234 +
46235 +typedef struct {
46236 + uint16_t profilesBase;
46237 + uint16_t numOfProfiles;
46238 + t_Handle h_FmPort;
46239 +} t_FmPcdPlcrMapParam;
46240 +
46241 +typedef struct {
46242 + uint16_t absoluteProfileId;
46243 + t_Handle h_FmPcd;
46244 + bool valid;
46245 + t_FmPcdLock *p_Lock;
46246 + t_FmPcdAllocMng profilesMng;
46247 + bool requiredActionFlag;
46248 + uint32_t requiredAction;
46249 + e_FmPcdEngine nextEngineOnGreen; /**< Green next engine type */
46250 + u_FmPcdPlcrNextEngineParams paramsOnGreen; /**< Green next engine params */
46251 +
46252 + e_FmPcdEngine nextEngineOnYellow; /**< Yellow next engine type */
46253 + u_FmPcdPlcrNextEngineParams paramsOnYellow; /**< Yellow next engine params */
46254 +
46255 + e_FmPcdEngine nextEngineOnRed; /**< Red next engine type */
46256 + u_FmPcdPlcrNextEngineParams paramsOnRed; /**< Red next engine params */
46257 +} t_FmPcdPlcrProfile;
46258 +
46259 +typedef struct {
46260 + t_FmPcdPlcrRegs *p_FmPcdPlcrRegs;
46261 + uint16_t partPlcrProfilesBase;
46262 + uint16_t partNumOfPlcrProfiles;
46263 + t_FmPcdPlcrProfile profiles[FM_PCD_PLCR_NUM_ENTRIES];
46264 + uint16_t numOfSharedProfiles;
46265 + uint16_t sharedProfilesIds[FM_PCD_PLCR_NUM_ENTRIES];
46266 + t_FmPcdPlcrMapParam portsMapping[FM_MAX_NUM_OF_PORTS];
46267 + t_Handle h_HwSpinlock;
46268 + t_Handle h_SwSpinlock;
46269 +} t_FmPcdPlcr;
46270 +
46271 +typedef struct {
46272 + uint32_t *p_SwPrsCode;
46273 + uint32_t *p_CurrSwPrs;
46274 + uint8_t currLabel;
46275 + struct fman_prs_regs *p_FmPcdPrsRegs;
46276 + t_FmPcdPrsLabelParams labelsTable[FM_PCD_PRS_NUM_OF_LABELS];
46277 + uint32_t fmPcdPrsPortIdStatistics;
46278 +} t_FmPcdPrs;
46279 +
46280 +typedef struct {
46281 + struct {
46282 + e_NetHeaderType hdr;
46283 + protocolOpt_t opt; /* only one option !! */
46284 + } hdrs[FM_PCD_MAX_NUM_OF_INTERCHANGEABLE_HDRS];
46285 +} t_FmPcdIntDistinctionUnit;
46286 +
46287 +typedef struct {
46288 + e_NetHeaderType hdr;
46289 + protocolOpt_t opt; /* only one option !! */
46290 + e_NetHeaderType aliasHdr;
46291 +} t_FmPcdNetEnvAliases;
46292 +
46293 +typedef struct {
46294 + uint8_t netEnvId;
46295 + t_Handle h_FmPcd;
46296 + t_Handle h_Spinlock;
46297 + bool used;
46298 + uint8_t owners;
46299 + uint8_t clsPlanGrpId;
46300 + t_FmPcdIntDistinctionUnit units[FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS];
46301 + uint32_t unitsVectors[FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS];
46302 + uint32_t lcvs[FM_PCD_PRS_NUM_OF_HDRS];
46303 + uint32_t macsecVector;
46304 + t_FmPcdNetEnvAliases aliasHdrs[FM_PCD_MAX_NUM_OF_ALIAS_HDRS];
46305 +} t_FmPcdNetEnv;
46306 +
46307 +typedef struct {
46308 + struct fman_prs_cfg dfltCfg;
46309 + bool plcrAutoRefresh;
46310 + uint16_t prsMaxParseCycleLimit;
46311 +} t_FmPcdDriverParam;
46312 +
46313 +typedef struct {
46314 + t_Handle h_Fm;
46315 + t_Handle h_FmMuram;
46316 + t_FmRevisionInfo fmRevInfo;
46317 +
46318 + uint64_t physicalMuramBase;
46319 +
46320 + t_Handle h_Spinlock;
46321 + t_List freeLocksLst;
46322 + t_List acquiredLocksLst;
46323 +
46324 + t_Handle h_IpcSession; /* relevant for guest only */
46325 + bool enabled;
46326 + uint8_t guestId; /**< Guest Partition Id */
46327 + uint8_t numOfEnabledGuestPartitionsPcds;
46328 + char fmPcdModuleName[MODULE_NAME_SIZE];
46329 + char fmPcdIpcHandlerModuleName[MODULE_NAME_SIZE]; /* relevant for guest only - this is the master's name */
46330 + t_FmPcdNetEnv netEnvs[FM_MAX_NUM_OF_PORTS];
46331 + t_FmPcdKg *p_FmPcdKg;
46332 + t_FmPcdPlcr *p_FmPcdPlcr;
46333 + t_FmPcdPrs *p_FmPcdPrs;
46334 +
46335 + void *p_CcShadow; /**< CC MURAM shadow */
46336 + uint32_t ccShadowSize;
46337 + uint32_t ccShadowAlign;
46338 + volatile bool shadowLock;
46339 + t_Handle h_ShadowSpinlock;
46340 +
46341 + t_Handle h_Hc;
46342 +
46343 + uint32_t exceptions;
46344 + t_FmPcdExceptionCallback *f_Exception;
46345 + t_FmPcdIdExceptionCallback *f_FmPcdIndexedException;
46346 + t_Handle h_App;
46347 + uintptr_t ipv6FrameIdAddr;
46348 + uintptr_t capwapFrameIdAddr;
46349 + bool advancedOffloadSupport;
46350 +
46351 + t_FmPcdDriverParam *p_FmPcdDriverParam;
46352 +} t_FmPcd;
46353 +
46354 +#if (DPAA_VERSION >= 11)
46355 +typedef uint8_t t_FmPcdFrmReplicUpdateType;
46356 +#define FRM_REPLIC_UPDATE_COUNTER 0x01
46357 +#define FRM_REPLIC_UPDATE_INFO 0x02
46358 +#endif /* (DPAA_VERSION >= 11) */
46359 +/***********************************************************************/
46360 +/* PCD internal routines */
46361 +/***********************************************************************/
46362 +
46363 +t_Error PcdGetVectorForOpt(t_FmPcd *p_FmPcd, uint8_t netEnvId, protocolOpt_t opt, uint32_t *p_Vector);
46364 +t_Error PcdGetUnitsVector(t_FmPcd *p_FmPcd, t_NetEnvParams *p_Params);
46365 +bool PcdNetEnvIsUnitWithoutOpts(t_FmPcd *p_FmPcd, uint8_t netEnvId, uint32_t unitVector);
46366 +t_Error PcdGetClsPlanGrpParams(t_FmPcd *p_FmPcd, t_FmPcdKgInterModuleClsPlanGrpParams *p_GrpParams);
46367 +void FmPcdSetClsPlanGrpId(t_FmPcd *p_FmPcd, uint8_t netEnvId, uint8_t clsPlanGrpId);
46368 +e_NetHeaderType FmPcdGetAliasHdr(t_FmPcd *p_FmPcd, uint8_t netEnvId, e_NetHeaderType hdr);
46369 +uint8_t FmPcdNetEnvGetUnitIdForSingleHdr(t_FmPcd *p_FmPcd, uint8_t netEnvId, e_NetHeaderType hdr);
46370 +uint8_t FmPcdNetEnvGetUnitId(t_FmPcd *p_FmPcd, uint8_t netEnvId, e_NetHeaderType hdr, bool interchangeable, protocolOpt_t opt);
46371 +
46372 +t_Error FmPcdManipBuildIpReassmScheme(t_FmPcd *p_FmPcd, t_Handle h_NetEnv, t_Handle h_CcTree, t_Handle h_Manip, bool isIpv4, uint8_t groupId);
46373 +t_Error FmPcdManipDeleteIpReassmSchemes(t_Handle h_Manip);
46374 +t_Error FmPcdManipBuildCapwapReassmScheme(t_FmPcd *p_FmPcd, t_Handle h_NetEnv, t_Handle h_CcTree, t_Handle h_Manip, uint8_t groupId);
46375 +t_Error FmPcdManipDeleteCapwapReassmSchemes(t_Handle h_Manip);
46376 +bool FmPcdManipIpReassmIsIpv6Hdr(t_Handle h_Manip);
46377 +
46378 +t_Handle KgConfig( t_FmPcd *p_FmPcd, t_FmPcdParams *p_FmPcdParams);
46379 +t_Error KgInit(t_FmPcd *p_FmPcd);
46380 +t_Error KgFree(t_FmPcd *p_FmPcd);
46381 +void KgSetClsPlan(t_Handle h_FmPcd, t_FmPcdKgInterModuleClsPlanSet *p_Set);
46382 +bool KgIsSchemeAlwaysDirect(t_Handle h_FmPcd, uint8_t schemeId);
46383 +void KgEnable(t_FmPcd *p_FmPcd);
46384 +void KgDisable(t_FmPcd *p_FmPcd);
46385 +t_Error KgAllocClsPlanEntries(t_Handle h_FmPcd, uint16_t numOfClsPlanEntries, uint8_t guestId, uint8_t *p_First);
46386 +void KgFreeClsPlanEntries(t_Handle h_FmPcd, uint16_t numOfClsPlanEntries, uint8_t guestId, uint8_t base);
46387 +
46388 +/* only for MULTI partittion */
46389 +t_Error FmPcdKgAllocSchemes(t_Handle h_FmPcd, uint8_t numOfSchemes, uint8_t guestId, uint8_t *p_SchemesIds);
46390 +t_Error FmPcdKgFreeSchemes(t_Handle h_FmPcd, uint8_t numOfSchemes, uint8_t guestId, uint8_t *p_SchemesIds);
46391 +/* only for SINGLE partittion */
46392 +t_Error KgBindPortToSchemes(t_Handle h_FmPcd , uint8_t hardwarePortId, uint32_t spReg);
46393 +
46394 +t_FmPcdLock *FmPcdAcquireLock(t_Handle h_FmPcd);
46395 +void FmPcdReleaseLock(t_Handle h_FmPcd, t_FmPcdLock *p_Lock);
46396 +
46397 +t_Handle PlcrConfig(t_FmPcd *p_FmPcd, t_FmPcdParams *p_FmPcdParams);
46398 +t_Error PlcrInit(t_FmPcd *p_FmPcd);
46399 +t_Error PlcrFree(t_FmPcd *p_FmPcd);
46400 +void PlcrEnable(t_FmPcd *p_FmPcd);
46401 +void PlcrDisable(t_FmPcd *p_FmPcd);
46402 +uint16_t PlcrAllocProfilesForPartition(t_FmPcd *p_FmPcd, uint16_t base, uint16_t numOfProfiles, uint8_t guestId);
46403 +void PlcrFreeProfilesForPartition(t_FmPcd *p_FmPcd, uint16_t base, uint16_t numOfProfiles, uint8_t guestId);
46404 +t_Error PlcrSetPortProfiles(t_FmPcd *p_FmPcd,
46405 + uint8_t hardwarePortId,
46406 + uint16_t numOfProfiles,
46407 + uint16_t base);
46408 +t_Error PlcrClearPortProfiles(t_FmPcd *p_FmPcd, uint8_t hardwarePortId);
46409 +
46410 +t_Handle PrsConfig(t_FmPcd *p_FmPcd,t_FmPcdParams *p_FmPcdParams);
46411 +t_Error PrsInit(t_FmPcd *p_FmPcd);
46412 +void PrsEnable(t_FmPcd *p_FmPcd);
46413 +void PrsDisable(t_FmPcd *p_FmPcd);
46414 +void PrsFree(t_FmPcd *p_FmPcd );
46415 +t_Error PrsIncludePortInStatistics(t_FmPcd *p_FmPcd, uint8_t hardwarePortId, bool include);
46416 +
46417 +t_Error FmPcdCcGetGrpParams(t_Handle treeId, uint8_t grpId, uint32_t *p_GrpBits, uint8_t *p_GrpBase);
46418 +uint8_t FmPcdCcGetOffset(t_Handle h_CcNode);
46419 +uint8_t FmPcdCcGetParseCode(t_Handle h_CcNode);
46420 +uint16_t FmPcdCcGetNumOfKeys(t_Handle h_CcNode);
46421 +t_Error ValidateNextEngineParams(t_Handle h_FmPcd, t_FmPcdCcNextEngineParams *p_FmPcdCcNextEngineParams, e_FmPcdCcStatsMode supportedStatsMode);
46422 +
46423 +void FmPcdManipUpdateOwner(t_Handle h_Manip, bool add);
46424 +t_Error FmPcdManipCheckParamsForCcNextEngine(t_FmPcdCcNextEngineParams *p_InfoForManip, uint32_t *requiredAction);
46425 +void FmPcdManipUpdateAdResultForCc(t_Handle h_Manip,
46426 + t_FmPcdCcNextEngineParams *p_CcNextEngineParams,
46427 + t_Handle p_Ad,
46428 + t_Handle *p_AdNewPtr);
46429 +void FmPcdManipUpdateAdContLookupForCc(t_Handle h_Manip, t_Handle p_Ad, t_Handle *p_AdNew, uint32_t adTableOffset);
46430 +void FmPcdManipUpdateOwner(t_Handle h_Manip, bool add);
46431 +t_Error FmPcdManipCheckParamsWithCcNodeParams(t_Handle h_Manip, t_Handle h_FmPcdCcNode);
46432 +#ifdef FM_CAPWAP_SUPPORT
46433 +t_Handle FmPcdManipApplSpecificBuild(void);
46434 +bool FmPcdManipIsCapwapApplSpecific(t_Handle h_Manip);
46435 +#endif /* FM_CAPWAP_SUPPORT */
46436 +#if (DPAA_VERSION >= 11)
46437 +void * FrmReplicGroupGetSourceTableDescriptor(t_Handle h_ReplicGroup);
46438 +void FrmReplicGroupUpdateOwner(t_Handle h_ReplicGroup, bool add);
46439 +void FrmReplicGroupUpdateAd(t_Handle h_ReplicGroup, void *p_Ad, t_Handle *h_AdNew);
46440 +
46441 +void FmPcdCcGetAdTablesThatPointOnReplicGroup(t_Handle h_Node,
46442 + t_Handle h_ReplicGroup,
46443 + t_List *p_AdTables,
46444 + uint32_t *p_NumOfAdTables);
46445 +#endif /* (DPAA_VERSION >= 11) */
46446 +
46447 +void EnqueueNodeInfoToRelevantLst(t_List *p_List, t_CcNodeInformation *p_CcInfo, t_Handle h_Spinlock);
46448 +void DequeueNodeInfoFromRelevantLst(t_List *p_List, t_Handle h_Info, t_Handle h_Spinlock);
46449 +t_CcNodeInformation* FindNodeInfoInReleventLst(t_List *p_List, t_Handle h_Info, t_Handle h_Spinlock);
46450 +t_List *FmPcdManipGetSpinlock(t_Handle h_Manip);
46451 +t_List *FmPcdManipGetNodeLstPointedOnThisManip(t_Handle h_Manip);
46452 +
46453 +typedef struct
46454 +{
46455 + t_Handle h_StatsAd;
46456 + t_Handle h_StatsCounters;
46457 +#if (DPAA_VERSION >= 11)
46458 + t_Handle h_StatsFLRs;
46459 +#endif /* (DPAA_VERSION >= 11) */
46460 +} t_FmPcdCcStatsParams;
46461 +
46462 +void NextStepAd(t_Handle h_Ad,
46463 + t_FmPcdCcStatsParams *p_FmPcdCcStatsParams,
46464 + t_FmPcdCcNextEngineParams *p_FmPcdCcNextEngineParams,
46465 + t_FmPcd *p_FmPcd);
46466 +void ReleaseLst(t_List *p_List);
46467 +
46468 +static __inline__ t_Handle FmPcdGetMuramHandle(t_Handle h_FmPcd)
46469 +{
46470 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
46471 + ASSERT_COND(p_FmPcd);
46472 + return p_FmPcd->h_FmMuram;
46473 +}
46474 +
46475 +static __inline__ uint64_t FmPcdGetMuramPhysBase(t_Handle h_FmPcd)
46476 +{
46477 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
46478 + ASSERT_COND(p_FmPcd);
46479 + return p_FmPcd->physicalMuramBase;
46480 +}
46481 +
46482 +static __inline__ uint32_t FmPcdLockSpinlock(t_FmPcdLock *p_Lock)
46483 +{
46484 + ASSERT_COND(p_Lock);
46485 + return XX_LockIntrSpinlock(p_Lock->h_Spinlock);
46486 +}
46487 +
46488 +static __inline__ void FmPcdUnlockSpinlock(t_FmPcdLock *p_Lock, uint32_t flags)
46489 +{
46490 + ASSERT_COND(p_Lock);
46491 + XX_UnlockIntrSpinlock(p_Lock->h_Spinlock, flags);
46492 +}
46493 +
46494 +static __inline__ bool FmPcdLockTryLock(t_FmPcdLock *p_Lock)
46495 +{
46496 + uint32_t intFlags;
46497 +
46498 + ASSERT_COND(p_Lock);
46499 + intFlags = XX_LockIntrSpinlock(p_Lock->h_Spinlock);
46500 + if (p_Lock->flag)
46501 + {
46502 + XX_UnlockIntrSpinlock(p_Lock->h_Spinlock, intFlags);
46503 + return FALSE;
46504 + }
46505 + p_Lock->flag = TRUE;
46506 + XX_UnlockIntrSpinlock(p_Lock->h_Spinlock, intFlags);
46507 + return TRUE;
46508 +}
46509 +
46510 +static __inline__ void FmPcdLockUnlock(t_FmPcdLock *p_Lock)
46511 +{
46512 + ASSERT_COND(p_Lock);
46513 + p_Lock->flag = FALSE;
46514 +}
46515 +
46516 +
46517 +#endif /* __FM_PCD_H */
46518 --- /dev/null
46519 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/fm_pcd_ipc.h
46520 @@ -0,0 +1,280 @@
46521 +/*
46522 + * Copyright 2008-2012 Freescale Semiconductor Inc.
46523 + *
46524 + * Redistribution and use in source and binary forms, with or without
46525 + * modification, are permitted provided that the following conditions are met:
46526 + * * Redistributions of source code must retain the above copyright
46527 + * notice, this list of conditions and the following disclaimer.
46528 + * * Redistributions in binary form must reproduce the above copyright
46529 + * notice, this list of conditions and the following disclaimer in the
46530 + * documentation and/or other materials provided with the distribution.
46531 + * * Neither the name of Freescale Semiconductor nor the
46532 + * names of its contributors may be used to endorse or promote products
46533 + * derived from this software without specific prior written permission.
46534 + *
46535 + *
46536 + * ALTERNATIVELY, this software may be distributed under the terms of the
46537 + * GNU General Public License ("GPL") as published by the Free Software
46538 + * Foundation, either version 2 of that License or (at your option) any
46539 + * later version.
46540 + *
46541 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
46542 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
46543 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
46544 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
46545 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
46546 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
46547 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
46548 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
46549 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
46550 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
46551 + */
46552 +
46553 +
46554 +/**************************************************************************//**
46555 + @File fm_pcd_ipc.h
46556 +
46557 + @Description FM PCD Inter-Partition prototypes, structures and definitions.
46558 +*//***************************************************************************/
46559 +#ifndef __FM_PCD_IPC_H
46560 +#define __FM_PCD_IPC_H
46561 +
46562 +#include "std_ext.h"
46563 +
46564 +
46565 +/**************************************************************************//**
46566 + @Group FM_grp Frame Manager API
46567 +
46568 + @Description FM API functions, definitions and enums
46569 +
46570 + @{
46571 +*//***************************************************************************/
46572 +
46573 +
46574 +#if defined(__MWERKS__) && !defined(__GNUC__)
46575 +#pragma pack(push,1)
46576 +#endif /* defined(__MWERKS__) && ... */
46577 +
46578 +/**************************************************************************//**
46579 + @Description Structure for getting a sw parser address according to a label
46580 + Fields commented 'IN' are passed by the port module to be used
46581 + by the FM module.
46582 + Fields commented 'OUT' will be filled by FM before returning to port.
46583 +*//***************************************************************************/
46584 +typedef _Packed struct t_FmPcdIpcSwPrsLable
46585 +{
46586 + uint32_t enumHdr; /**< IN. The existence of this header will invoke
46587 + the sw parser code. */
46588 + uint8_t indexPerHdr; /**< IN. Normally 0, if more than one sw parser
46589 + attachments for the same header, use this
46590 +
46591 + index to distinguish between them. */
46592 +} _PackedType t_FmPcdIpcSwPrsLable;
46593 +
46594 +/**************************************************************************//**
46595 + @Description Structure for port-PCD communication.
46596 + Fields commented 'IN' are passed by the port module to be used
46597 + by the FM module.
46598 + Fields commented 'OUT' will be filled by FM before returning to port.
46599 + Some fields are optional (depending on configuration) and
46600 + will be analized by the port and FM modules accordingly.
46601 +*//***************************************************************************/
46602 +
46603 +typedef struct t_FmPcdIpcKgSchemesParams
46604 +{
46605 + uint8_t guestId;
46606 + uint8_t numOfSchemes;
46607 + uint8_t schemesIds[FM_PCD_KG_NUM_OF_SCHEMES];
46608 +} _PackedType t_FmPcdIpcKgSchemesParams;
46609 +
46610 +typedef struct t_FmPcdIpcKgClsPlanParams
46611 +{
46612 + uint8_t guestId;
46613 + uint16_t numOfClsPlanEntries;
46614 + uint8_t clsPlanBase;
46615 +} _PackedType t_FmPcdIpcKgClsPlanParams;
46616 +
46617 +typedef _Packed struct t_FmPcdIpcPrsIncludePort
46618 +{
46619 + uint8_t hardwarePortId;
46620 + bool include;
46621 +} _PackedType t_FmPcdIpcPrsIncludePort;
46622 +
46623 +
46624 +#define FM_PCD_MAX_REPLY_SIZE 16
46625 +#define FM_PCD_MAX_MSG_SIZE 36
46626 +#define FM_PCD_MAX_REPLY_BODY_SIZE 36
46627 +
46628 +typedef _Packed struct {
46629 + uint32_t msgId;
46630 + uint8_t msgBody[FM_PCD_MAX_MSG_SIZE];
46631 +} _PackedType t_FmPcdIpcMsg;
46632 +
46633 +typedef _Packed struct t_FmPcdIpcReply {
46634 + uint32_t error;
46635 + uint8_t replyBody[FM_PCD_MAX_REPLY_BODY_SIZE];
46636 +} _PackedType t_FmPcdIpcReply;
46637 +
46638 +typedef _Packed struct t_FmIpcResourceAllocParams {
46639 + uint8_t guestId;
46640 + uint16_t base;
46641 + uint16_t num;
46642 +}_PackedType t_FmIpcResourceAllocParams;
46643 +
46644 +#if defined(__MWERKS__) && !defined(__GNUC__)
46645 +#pragma pack(pop)
46646 +#endif /* defined(__MWERKS__) && ... */
46647 +
46648 +
46649 +
46650 +/**************************************************************************//**
46651 + @Function FM_PCD_ALLOC_KG_SCHEMES
46652 +
46653 + @Description Used by FM PCD front-end in order to allocate KG resources
46654 +
46655 + @Param[in/out] t_FmPcdIpcKgAllocParams Pointer
46656 +*//***************************************************************************/
46657 +#define FM_PCD_ALLOC_KG_SCHEMES 3
46658 +
46659 +/**************************************************************************//**
46660 + @Function FM_PCD_FREE_KG_SCHEMES
46661 +
46662 + @Description Used by FM PCD front-end in order to Free KG resources
46663 +
46664 + @Param[in/out] t_FmPcdIpcKgSchemesParams Pointer
46665 +*//***************************************************************************/
46666 +#define FM_PCD_FREE_KG_SCHEMES 4
46667 +
46668 +/**************************************************************************//**
46669 + @Function FM_PCD_ALLOC_PROFILES
46670 +
46671 + @Description Used by FM PCD front-end in order to allocate Policer profiles
46672 +
46673 + @Param[in/out] t_FmIpcResourceAllocParams Pointer
46674 +*//***************************************************************************/
46675 +#define FM_PCD_ALLOC_PROFILES 5
46676 +
46677 +/**************************************************************************//**
46678 + @Function FM_PCD_FREE_PROFILES
46679 +
46680 + @Description Used by FM PCD front-end in order to Free Policer profiles
46681 +
46682 + @Param[in/out] t_FmIpcResourceAllocParams Pointer
46683 +*//***************************************************************************/
46684 +#define FM_PCD_FREE_PROFILES 6
46685 +
46686 +/**************************************************************************//**
46687 + @Function FM_PCD_SET_PORT_PROFILES
46688 +
46689 + @Description Used by FM PCD front-end in order to allocate Policer profiles
46690 + for specific port
46691 +
46692 + @Param[in/out] t_FmIpcResourceAllocParams Pointer
46693 +*//***************************************************************************/
46694 +#define FM_PCD_SET_PORT_PROFILES 7
46695 +
46696 +/**************************************************************************//**
46697 + @Function FM_PCD_CLEAR_PORT_PROFILES
46698 +
46699 + @Description Used by FM PCD front-end in order to allocate Policer profiles
46700 + for specific port
46701 +
46702 + @Param[in/out] t_FmIpcResourceAllocParams Pointer
46703 +*//***************************************************************************/
46704 +#define FM_PCD_CLEAR_PORT_PROFILES 8
46705 +
46706 +/**************************************************************************//**
46707 + @Function FM_PCD_GET_PHYS_MURAM_BASE
46708 +
46709 + @Description Used by FM PCD front-end in order to get MURAM base address
46710 +
46711 + @Param[in/out] t_FmPcdIcPhysAddr Pointer
46712 +*//***************************************************************************/
46713 +#define FM_PCD_GET_PHYS_MURAM_BASE 9
46714 +
46715 +/**************************************************************************//**
46716 + @Function FM_PCD_GET_SW_PRS_OFFSET
46717 +
46718 + @Description Used by FM front-end to get the SW parser offset of the start of
46719 + code relevant to a given label.
46720 +
46721 + @Param[in/out] t_FmPcdIpcSwPrsLable Pointer
46722 +*//***************************************************************************/
46723 +#define FM_PCD_GET_SW_PRS_OFFSET 10
46724 +
46725 +/**************************************************************************//**
46726 + @Function FM_PCD_MASTER_IS_ENABLED
46727 +
46728 + @Description Used by FM front-end in order to verify
46729 + PCD enablement.
46730 +
46731 + @Param[in] bool Pointer
46732 +*//***************************************************************************/
46733 +#define FM_PCD_MASTER_IS_ENABLED 15
46734 +
46735 +/**************************************************************************//**
46736 + @Function FM_PCD_GUEST_DISABLE
46737 +
46738 + @Description Used by FM front-end to inform back-end when
46739 + front-end PCD is disabled
46740 +
46741 + @Param[in] None
46742 +*//***************************************************************************/
46743 +#define FM_PCD_GUEST_DISABLE 16
46744 +
46745 +/**************************************************************************//**
46746 + @Function FM_PCD_FREE_KG_CLSPLAN
46747 +
46748 + @Description Used by FM PCD front-end in order to Free KG classification plan entries
46749 +
46750 + @Param[in/out] t_FmPcdIpcKgClsPlanParams Pointer
46751 +*//***************************************************************************/
46752 +#define FM_PCD_FREE_KG_CLSPLAN 22
46753 +
46754 +/**************************************************************************//**
46755 + @Function FM_PCD_ALLOC_KG_CLSPLAN
46756 +
46757 + @Description Used by FM PCD front-end in order to allocate KG classification plan entries
46758 +
46759 + @Param[in/out] t_FmPcdIpcKgClsPlanParams Pointer
46760 +*//***************************************************************************/
46761 +#define FM_PCD_ALLOC_KG_CLSPLAN 23
46762 +
46763 +/**************************************************************************//**
46764 + @Function FM_PCD_MASTER_IS_ALIVE
46765 +
46766 + @Description Used by FM front-end to check that back-end exists
46767 +
46768 + @Param[in] None
46769 +*//***************************************************************************/
46770 +#define FM_PCD_MASTER_IS_ALIVE 24
46771 +
46772 +/**************************************************************************//**
46773 + @Function FM_PCD_GET_COUNTER
46774 +
46775 + @Description Used by FM front-end to read PCD counters
46776 +
46777 + @Param[in/out] t_FmPcdIpcGetCounter Pointer
46778 +*//***************************************************************************/
46779 +#define FM_PCD_GET_COUNTER 25
46780 +
46781 +/**************************************************************************//**
46782 + @Function FM_PCD_PRS_INC_PORT_STATS
46783 +
46784 + @Description Used by FM front-end to set/clear statistics for port
46785 +
46786 + @Param[in/out] t_FmPcdIpcPrsIncludePort Pointer
46787 +*//***************************************************************************/
46788 +#define FM_PCD_PRS_INC_PORT_STATS 26
46789 +
46790 +#if (DPAA_VERSION >= 11)
46791 +/* TODO - doc */
46792 +#define FM_PCD_ALLOC_SP 27
46793 +#endif /* (DPAA_VERSION >= 11) */
46794 +
46795 +
46796 +/** @} */ /* end of FM_PCD_IPC_grp group */
46797 +/** @} */ /* end of FM_grp group */
46798 +
46799 +
46800 +#endif /* __FM_PCD_IPC_H */
46801 --- /dev/null
46802 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/fm_plcr.c
46803 @@ -0,0 +1,1847 @@
46804 +/*
46805 + * Copyright 2008-2012 Freescale Semiconductor Inc.
46806 + *
46807 + * Redistribution and use in source and binary forms, with or without
46808 + * modification, are permitted provided that the following conditions are met:
46809 + * * Redistributions of source code must retain the above copyright
46810 + * notice, this list of conditions and the following disclaimer.
46811 + * * Redistributions in binary form must reproduce the above copyright
46812 + * notice, this list of conditions and the following disclaimer in the
46813 + * documentation and/or other materials provided with the distribution.
46814 + * * Neither the name of Freescale Semiconductor nor the
46815 + * names of its contributors may be used to endorse or promote products
46816 + * derived from this software without specific prior written permission.
46817 + *
46818 + *
46819 + * ALTERNATIVELY, this software may be distributed under the terms of the
46820 + * GNU General Public License ("GPL") as published by the Free Software
46821 + * Foundation, either version 2 of that License or (at your option) any
46822 + * later version.
46823 + *
46824 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
46825 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
46826 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
46827 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
46828 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
46829 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
46830 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
46831 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
46832 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
46833 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
46834 + */
46835 +
46836 +
46837 +/******************************************************************************
46838 + @File fm_plcr.c
46839 +
46840 + @Description FM PCD POLICER...
46841 +*//***************************************************************************/
46842 +#include <linux/math64.h>
46843 +#include "std_ext.h"
46844 +#include "error_ext.h"
46845 +#include "string_ext.h"
46846 +#include "debug_ext.h"
46847 +#include "net_ext.h"
46848 +#include "fm_ext.h"
46849 +
46850 +#include "fm_common.h"
46851 +#include "fm_pcd.h"
46852 +#include "fm_hc.h"
46853 +#include "fm_pcd_ipc.h"
46854 +#include "fm_plcr.h"
46855 +
46856 +
46857 +/****************************************/
46858 +/* static functions */
46859 +/****************************************/
46860 +
46861 +static uint32_t PlcrProfileLock(t_Handle h_Profile)
46862 +{
46863 + ASSERT_COND(h_Profile);
46864 + return FmPcdLockSpinlock(((t_FmPcdPlcrProfile *)h_Profile)->p_Lock);
46865 +}
46866 +
46867 +static void PlcrProfileUnlock(t_Handle h_Profile, uint32_t intFlags)
46868 +{
46869 + ASSERT_COND(h_Profile);
46870 + FmPcdUnlockSpinlock(((t_FmPcdPlcrProfile *)h_Profile)->p_Lock, intFlags);
46871 +}
46872 +
46873 +static bool PlcrProfileFlagTryLock(t_Handle h_Profile)
46874 +{
46875 + ASSERT_COND(h_Profile);
46876 + return FmPcdLockTryLock(((t_FmPcdPlcrProfile *)h_Profile)->p_Lock);
46877 +}
46878 +
46879 +static void PlcrProfileFlagUnlock(t_Handle h_Profile)
46880 +{
46881 + ASSERT_COND(h_Profile);
46882 + FmPcdLockUnlock(((t_FmPcdPlcrProfile *)h_Profile)->p_Lock);
46883 +}
46884 +
46885 +static uint32_t PlcrHwLock(t_Handle h_FmPcdPlcr)
46886 +{
46887 + ASSERT_COND(h_FmPcdPlcr);
46888 + return XX_LockIntrSpinlock(((t_FmPcdPlcr*)h_FmPcdPlcr)->h_HwSpinlock);
46889 +}
46890 +
46891 +static void PlcrHwUnlock(t_Handle h_FmPcdPlcr, uint32_t intFlags)
46892 +{
46893 + ASSERT_COND(h_FmPcdPlcr);
46894 + XX_UnlockIntrSpinlock(((t_FmPcdPlcr*)h_FmPcdPlcr)->h_HwSpinlock, intFlags);
46895 +}
46896 +
46897 +static uint32_t PlcrSwLock(t_Handle h_FmPcdPlcr)
46898 +{
46899 + ASSERT_COND(h_FmPcdPlcr);
46900 + return XX_LockIntrSpinlock(((t_FmPcdPlcr*)h_FmPcdPlcr)->h_SwSpinlock);
46901 +}
46902 +
46903 +static void PlcrSwUnlock(t_Handle h_FmPcdPlcr, uint32_t intFlags)
46904 +{
46905 + ASSERT_COND(h_FmPcdPlcr);
46906 + XX_UnlockIntrSpinlock(((t_FmPcdPlcr*)h_FmPcdPlcr)->h_SwSpinlock, intFlags);
46907 +}
46908 +
46909 +static bool IsProfileShared(t_Handle h_FmPcd, uint16_t absoluteProfileId)
46910 +{
46911 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
46912 + uint16_t i;
46913 +
46914 + SANITY_CHECK_RETURN_VALUE(p_FmPcd, E_INVALID_HANDLE, FALSE);
46915 +
46916 + for (i=0;i<p_FmPcd->p_FmPcdPlcr->numOfSharedProfiles;i++)
46917 + if (p_FmPcd->p_FmPcdPlcr->sharedProfilesIds[i] == absoluteProfileId)
46918 + return TRUE;
46919 + return FALSE;
46920 +}
46921 +
46922 +static t_Error SetProfileNia(t_FmPcd *p_FmPcd, e_FmPcdEngine nextEngine, u_FmPcdPlcrNextEngineParams *p_NextEngineParams, uint32_t *nextAction)
46923 +{
46924 + uint32_t nia;
46925 + uint16_t absoluteProfileId;
46926 + uint8_t relativeSchemeId, physicalSchemeId;
46927 +
46928 + nia = FM_PCD_PLCR_NIA_VALID;
46929 +
46930 + switch (nextEngine)
46931 + {
46932 + case e_FM_PCD_DONE :
46933 + switch (p_NextEngineParams->action)
46934 + {
46935 + case e_FM_PCD_DROP_FRAME :
46936 + nia |= GET_NIA_BMI_AC_DISCARD_FRAME(p_FmPcd);
46937 + break;
46938 + case e_FM_PCD_ENQ_FRAME:
46939 + nia |= GET_NIA_BMI_AC_ENQ_FRAME(p_FmPcd);
46940 + break;
46941 + default:
46942 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION, NO_MSG);
46943 + }
46944 + break;
46945 + case e_FM_PCD_KG:
46946 + physicalSchemeId = FmPcdKgGetSchemeId(p_NextEngineParams->h_DirectScheme);
46947 + relativeSchemeId = FmPcdKgGetRelativeSchemeId(p_FmPcd, physicalSchemeId);
46948 + if (relativeSchemeId >= FM_PCD_KG_NUM_OF_SCHEMES)
46949 + RETURN_ERROR(MAJOR, E_NOT_IN_RANGE, NO_MSG);
46950 + if (!FmPcdKgIsSchemeValidSw(p_NextEngineParams->h_DirectScheme))
46951 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Invalid direct scheme."));
46952 + if (!KgIsSchemeAlwaysDirect(p_FmPcd, relativeSchemeId))
46953 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Policer Profile may point only to a scheme that is always direct."));
46954 + nia |= NIA_ENG_KG | NIA_KG_DIRECT | physicalSchemeId;
46955 + break;
46956 + case e_FM_PCD_PLCR:
46957 + absoluteProfileId = ((t_FmPcdPlcrProfile *)p_NextEngineParams->h_Profile)->absoluteProfileId;
46958 + if (!IsProfileShared(p_FmPcd, absoluteProfileId))
46959 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Next profile must be a shared profile"));
46960 + if (!FmPcdPlcrIsProfileValid(p_FmPcd, absoluteProfileId))
46961 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Invalid profile "));
46962 + nia |= NIA_ENG_PLCR | NIA_PLCR_ABSOLUTE | absoluteProfileId;
46963 + break;
46964 + default:
46965 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION, NO_MSG);
46966 + }
46967 +
46968 + *nextAction = nia;
46969 +
46970 + return E_OK;
46971 +}
46972 +
46973 +static uint32_t CalcFPP(uint32_t fpp)
46974 +{
46975 + if (fpp > 15)
46976 + return 15 - (0x1f - fpp);
46977 + else
46978 + return 16 + fpp;
46979 +}
46980 +
46981 +static void GetInfoRateReg(e_FmPcdPlcrRateMode rateMode,
46982 + uint32_t rate,
46983 + uint64_t tsuInTenthNano,
46984 + uint32_t fppShift,
46985 + uint64_t *p_Integer,
46986 + uint64_t *p_Fraction)
46987 +{
46988 + uint64_t tmp, div;
46989 +
46990 + if (rateMode == e_FM_PCD_PLCR_BYTE_MODE)
46991 + {
46992 + /* now we calculate the initial integer for the bigger rate */
46993 + /* from Kbps to Bytes/TSU */
46994 + tmp = (uint64_t)rate;
46995 + tmp *= 1000; /* kb --> b */
46996 + tmp *= tsuInTenthNano; /* bps --> bpTsu(in 10nano) */
46997 +
46998 + div = 1000000000; /* nano */
46999 + div *= 10; /* 10 nano */
47000 + div *= 8; /* bit to byte */
47001 + }
47002 + else
47003 + {
47004 + /* now we calculate the initial integer for the bigger rate */
47005 + /* from Kbps to Bytes/TSU */
47006 + tmp = (uint64_t)rate;
47007 + tmp *= tsuInTenthNano; /* bps --> bpTsu(in 10nano) */
47008 +
47009 + div = 1000000000; /* nano */
47010 + div *= 10; /* 10 nano */
47011 + }
47012 + *p_Integer = div64_u64(tmp<<fppShift, div);
47013 +
47014 + /* for calculating the fraction, we will recalculate cir and deduct the integer.
47015 + * For precision, we will multiply by 2^16. we do not divid back, since we write
47016 + * this value as fraction - see spec.
47017 + */
47018 + *p_Fraction = div64_u64(((tmp<<fppShift)<<16) - ((*p_Integer<<16)*div), div);
47019 +}
47020 +
47021 +/* .......... */
47022 +
47023 +static void CalcRates(uint32_t bitFor1Micro,
47024 + t_FmPcdPlcrNonPassthroughAlgParams *p_NonPassthroughAlgParam,
47025 + uint32_t *cir,
47026 + uint32_t *cbs,
47027 + uint32_t *pir_eir,
47028 + uint32_t *pbs_ebs,
47029 + uint32_t *fpp)
47030 +{
47031 + uint64_t integer, fraction;
47032 + uint32_t temp, tsuInTenthNanos;
47033 + uint8_t fppShift=0;
47034 +
47035 + /* we want the tsu to count 10 nano for better precision normally tsu is 3.9 nano, now we will get 39 */
47036 + tsuInTenthNanos = (uint32_t)(1000*10/(1 << bitFor1Micro));
47037 +
47038 + /* we choose the faster rate to calibrate fpp */
47039 + /* The meaning of this step:
47040 + * when fppShift is 0 it means all TS bits are treated as integer and TSU is the TS LSB count.
47041 + * In this configuration we calculate the integer and fraction that represent the higher infoRate
47042 + * When this is done, we can tell where we have "spare" unused bits and optimize the division of TS
47043 + * into "integer" and "fraction" where the logic is - as many bits as possible for integer at
47044 + * high rate, as many bits as possible for fraction at low rate.
47045 + */
47046 + if (p_NonPassthroughAlgParam->committedInfoRate > p_NonPassthroughAlgParam->peakOrExcessInfoRate)
47047 + GetInfoRateReg(p_NonPassthroughAlgParam->rateMode, p_NonPassthroughAlgParam->committedInfoRate, tsuInTenthNanos, 0, &integer, &fraction);
47048 + else
47049 + GetInfoRateReg(p_NonPassthroughAlgParam->rateMode, p_NonPassthroughAlgParam->peakOrExcessInfoRate, tsuInTenthNanos, 0, &integer, &fraction);
47050 +
47051 + /* we shift integer, as in cir/pir it is represented by the MSB 16 bits, and
47052 + * the LSB bits are for the fraction */
47053 + temp = (uint32_t)((integer<<16) & 0x00000000FFFFFFFF);
47054 + /* temp is effected by the rate. For low rates it may be as low as 0, and then we'll
47055 + * take max FP = 31.
47056 + * For high rates it will never exceed the 32 bit reg (after the 16 shift), as it is
47057 + * limited by the 10G physical port.
47058 + */
47059 + if (temp != 0)
47060 + {
47061 + /* In this case, the largest rate integer is non 0, if it does not occupy all (high) 16
47062 + * bits of the PIR_EIR we can use this fact and enlarge it to occupy all 16 bits.
47063 + * The logic is to have as many bits for integer in the higher rates, but if we have "0"s
47064 + * in the integer part of the cir/pir register, than these bits are wasted. So we want
47065 + * to use these bits for the fraction. in this way we will have for fraction - the number
47066 + * of "0" bits and the rest - for integer.
47067 + * In other words: For each bit we shift it in PIR_EIR, we move the FP in the TS
47068 + * one bit to the left - preserving the relationship and achieving more bits
47069 + * for integer in the TS.
47070 + */
47071 +
47072 + /* count zeroes left of the higher used bit (in order to shift the value such that
47073 + * unused bits may be used for fraction).
47074 + */
47075 + while ((temp & 0x80000000) == 0)
47076 + {
47077 + temp = temp << 1;
47078 + fppShift++;
47079 + }
47080 + if (fppShift > 15)
47081 + {
47082 + REPORT_ERROR(MAJOR, E_INVALID_SELECTION, ("timeStampPeriod to Information rate ratio is too small"));
47083 + return;
47084 + }
47085 + }
47086 + else
47087 + {
47088 + temp = (uint32_t)fraction; /* fraction will alyas be smaller than 2^16 */
47089 + if (!temp)
47090 + /* integer and fraction are 0, we set FP to its max val */
47091 + fppShift = 31;
47092 + else
47093 + {
47094 + /* integer was 0 but fraction is not. FP is 16 for the fraction,
47095 + * + all left zeroes of the fraction. */
47096 + fppShift=16;
47097 + /* count zeroes left of the higher used bit (in order to shift the value such that
47098 + * unused bits may be used for fraction).
47099 + */
47100 + while ((temp & 0x8000) == 0)
47101 + {
47102 + temp = temp << 1;
47103 + fppShift++;
47104 + }
47105 + }
47106 + }
47107 +
47108 + /*
47109 + * This means that the FM TS register will now be used so that 'fppShift' bits are for
47110 + * fraction and the rest for integer */
47111 + /* now we re-calculate cir and pir_eir with the calculated FP */
47112 + GetInfoRateReg(p_NonPassthroughAlgParam->rateMode, p_NonPassthroughAlgParam->committedInfoRate, tsuInTenthNanos, fppShift, &integer, &fraction);
47113 + *cir = (uint32_t)(integer << 16 | (fraction & 0xFFFF));
47114 + GetInfoRateReg(p_NonPassthroughAlgParam->rateMode, p_NonPassthroughAlgParam->peakOrExcessInfoRate, tsuInTenthNanos, fppShift, &integer, &fraction);
47115 + *pir_eir = (uint32_t)(integer << 16 | (fraction & 0xFFFF));
47116 +
47117 + *cbs = p_NonPassthroughAlgParam->committedBurstSize;
47118 + *pbs_ebs = p_NonPassthroughAlgParam->peakOrExcessBurstSize;
47119 +
47120 + /* convert FP as it should be written to reg.
47121 + * 0-15 --> 16-31
47122 + * 16-31 --> 0-15
47123 + */
47124 + *fpp = CalcFPP(fppShift);
47125 +}
47126 +
47127 +static void WritePar(t_FmPcd *p_FmPcd, uint32_t par)
47128 +{
47129 + t_FmPcdPlcrRegs *p_FmPcdPlcrRegs = p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs;
47130 +
47131 + ASSERT_COND(FmIsMaster(p_FmPcd->h_Fm));
47132 + WRITE_UINT32(p_FmPcdPlcrRegs->fmpl_par, par);
47133 +
47134 + while (GET_UINT32(p_FmPcdPlcrRegs->fmpl_par) & FM_PCD_PLCR_PAR_GO) ;
47135 +}
47136 +
47137 +static t_Error BuildProfileRegs(t_FmPcd *p_FmPcd,
47138 + t_FmPcdPlcrProfileParams *p_ProfileParams,
47139 + t_FmPcdPlcrProfileRegs *p_PlcrRegs)
47140 +{
47141 + t_Error err = E_OK;
47142 + uint32_t pemode, gnia, ynia, rnia, bitFor1Micro;
47143 +
47144 + ASSERT_COND(p_FmPcd);
47145 +
47146 + bitFor1Micro = FmGetTimeStampScale(p_FmPcd->h_Fm);
47147 + if (bitFor1Micro == 0)
47148 + RETURN_ERROR(MAJOR, E_NOT_AVAILABLE, ("Timestamp scale"));
47149 +
47150 +/* Set G, Y, R Nia */
47151 + err = SetProfileNia(p_FmPcd, p_ProfileParams->nextEngineOnGreen, &(p_ProfileParams->paramsOnGreen), &gnia);
47152 + if (err)
47153 + RETURN_ERROR(MAJOR, err, NO_MSG);
47154 + err = SetProfileNia(p_FmPcd, p_ProfileParams->nextEngineOnYellow, &(p_ProfileParams->paramsOnYellow), &ynia);
47155 + if (err)
47156 + RETURN_ERROR(MAJOR, err, NO_MSG);
47157 + err = SetProfileNia(p_FmPcd, p_ProfileParams->nextEngineOnRed, &(p_ProfileParams->paramsOnRed), &rnia);
47158 + if (err)
47159 + RETURN_ERROR(MAJOR, err, NO_MSG);
47160 +
47161 +/* Mode fmpl_pemode */
47162 + pemode = FM_PCD_PLCR_PEMODE_PI;
47163 +
47164 + switch (p_ProfileParams->algSelection)
47165 + {
47166 + case e_FM_PCD_PLCR_PASS_THROUGH:
47167 + p_PlcrRegs->fmpl_pecir = 0;
47168 + p_PlcrRegs->fmpl_pecbs = 0;
47169 + p_PlcrRegs->fmpl_pepepir_eir = 0;
47170 + p_PlcrRegs->fmpl_pepbs_ebs = 0;
47171 + p_PlcrRegs->fmpl_pelts = 0;
47172 + p_PlcrRegs->fmpl_pects = 0;
47173 + p_PlcrRegs->fmpl_pepts_ets = 0;
47174 + pemode &= ~FM_PCD_PLCR_PEMODE_ALG_MASK;
47175 + switch (p_ProfileParams->colorMode)
47176 + {
47177 + case e_FM_PCD_PLCR_COLOR_BLIND:
47178 + pemode |= FM_PCD_PLCR_PEMODE_CBLND;
47179 + switch (p_ProfileParams->color.dfltColor)
47180 + {
47181 + case e_FM_PCD_PLCR_GREEN:
47182 + pemode &= ~FM_PCD_PLCR_PEMODE_DEFC_MASK;
47183 + break;
47184 + case e_FM_PCD_PLCR_YELLOW:
47185 + pemode |= FM_PCD_PLCR_PEMODE_DEFC_Y;
47186 + break;
47187 + case e_FM_PCD_PLCR_RED:
47188 + pemode |= FM_PCD_PLCR_PEMODE_DEFC_R;
47189 + break;
47190 + case e_FM_PCD_PLCR_OVERRIDE:
47191 + pemode |= FM_PCD_PLCR_PEMODE_DEFC_OVERRIDE;
47192 + break;
47193 + default:
47194 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION, NO_MSG);
47195 + }
47196 +
47197 + break;
47198 + case e_FM_PCD_PLCR_COLOR_AWARE:
47199 + pemode &= ~FM_PCD_PLCR_PEMODE_CBLND;
47200 + break;
47201 + default:
47202 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION, NO_MSG);
47203 + }
47204 + break;
47205 +
47206 + case e_FM_PCD_PLCR_RFC_2698:
47207 + /* Select algorithm MODE[ALG] = "01" */
47208 + pemode |= FM_PCD_PLCR_PEMODE_ALG_RFC2698;
47209 + if (p_ProfileParams->nonPassthroughAlgParams.committedInfoRate > p_ProfileParams->nonPassthroughAlgParams.peakOrExcessInfoRate)
47210 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION, ("in RFC2698 Peak rate must be equal or larger than committedInfoRate."));
47211 + goto cont_rfc;
47212 + case e_FM_PCD_PLCR_RFC_4115:
47213 + /* Select algorithm MODE[ALG] = "10" */
47214 + pemode |= FM_PCD_PLCR_PEMODE_ALG_RFC4115;
47215 +cont_rfc:
47216 + /* Select Color-Blind / Color-Aware operation (MODE[CBLND]) */
47217 + switch (p_ProfileParams->colorMode)
47218 + {
47219 + case e_FM_PCD_PLCR_COLOR_BLIND:
47220 + pemode |= FM_PCD_PLCR_PEMODE_CBLND;
47221 + break;
47222 + case e_FM_PCD_PLCR_COLOR_AWARE:
47223 + pemode &= ~FM_PCD_PLCR_PEMODE_CBLND;
47224 + /*In color aware more select override color interpretation (MODE[OVCLR]) */
47225 + switch (p_ProfileParams->color.override)
47226 + {
47227 + case e_FM_PCD_PLCR_GREEN:
47228 + pemode &= ~FM_PCD_PLCR_PEMODE_OVCLR_MASK;
47229 + break;
47230 + case e_FM_PCD_PLCR_YELLOW:
47231 + pemode |= FM_PCD_PLCR_PEMODE_OVCLR_Y;
47232 + break;
47233 + case e_FM_PCD_PLCR_RED:
47234 + pemode |= FM_PCD_PLCR_PEMODE_OVCLR_R;
47235 + break;
47236 + case e_FM_PCD_PLCR_OVERRIDE:
47237 + pemode |= FM_PCD_PLCR_PEMODE_OVCLR_G_NC;
47238 + break;
47239 + default:
47240 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION, NO_MSG);
47241 + }
47242 + break;
47243 + default:
47244 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION, NO_MSG);
47245 + }
47246 + /* Select Measurement Unit Mode to BYTE or PACKET (MODE[PKT]) */
47247 + switch (p_ProfileParams->nonPassthroughAlgParams.rateMode)
47248 + {
47249 + case e_FM_PCD_PLCR_BYTE_MODE :
47250 + pemode &= ~FM_PCD_PLCR_PEMODE_PKT;
47251 + switch (p_ProfileParams->nonPassthroughAlgParams.byteModeParams.frameLengthSelection)
47252 + {
47253 + case e_FM_PCD_PLCR_L2_FRM_LEN:
47254 + pemode |= FM_PCD_PLCR_PEMODE_FLS_L2;
47255 + break;
47256 + case e_FM_PCD_PLCR_L3_FRM_LEN:
47257 + pemode |= FM_PCD_PLCR_PEMODE_FLS_L3;
47258 + break;
47259 + case e_FM_PCD_PLCR_L4_FRM_LEN:
47260 + pemode |= FM_PCD_PLCR_PEMODE_FLS_L4;
47261 + break;
47262 + case e_FM_PCD_PLCR_FULL_FRM_LEN:
47263 + pemode |= FM_PCD_PLCR_PEMODE_FLS_FULL;
47264 + break;
47265 + default:
47266 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION, NO_MSG);
47267 + }
47268 + switch (p_ProfileParams->nonPassthroughAlgParams.byteModeParams.rollBackFrameSelection)
47269 + {
47270 + case e_FM_PCD_PLCR_ROLLBACK_L2_FRM_LEN:
47271 + pemode &= ~FM_PCD_PLCR_PEMODE_RBFLS;
47272 + break;
47273 + case e_FM_PCD_PLCR_ROLLBACK_FULL_FRM_LEN:
47274 + pemode |= FM_PCD_PLCR_PEMODE_RBFLS;
47275 + break;
47276 + default:
47277 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION, NO_MSG);
47278 + }
47279 + break;
47280 + case e_FM_PCD_PLCR_PACKET_MODE :
47281 + pemode |= FM_PCD_PLCR_PEMODE_PKT;
47282 + break;
47283 + default:
47284 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION, NO_MSG);
47285 + }
47286 + /* Select timeStamp floating point position (MODE[FPP]) to fit the actual traffic rates. For PACKET
47287 + mode with low traffic rates move the fixed point to the left to increase fraction accuracy. For BYTE
47288 + mode with high traffic rates move the fixed point to the right to increase integer accuracy. */
47289 +
47290 + /* Configure Traffic Parameters*/
47291 + {
47292 + uint32_t cir=0, cbs=0, pir_eir=0, pbs_ebs=0, fpp=0;
47293 +
47294 + CalcRates(bitFor1Micro, &p_ProfileParams->nonPassthroughAlgParams, &cir, &cbs, &pir_eir, &pbs_ebs, &fpp);
47295 +
47296 + /* Set Committed Information Rate (CIR) */
47297 + p_PlcrRegs->fmpl_pecir = cir;
47298 + /* Set Committed Burst Size (CBS). */
47299 + p_PlcrRegs->fmpl_pecbs = cbs;
47300 + /* Set Peak Information Rate (PIR_EIR used as PIR) */
47301 + p_PlcrRegs->fmpl_pepepir_eir = pir_eir;
47302 + /* Set Peak Burst Size (PBS_EBS used as PBS) */
47303 + p_PlcrRegs->fmpl_pepbs_ebs = pbs_ebs;
47304 +
47305 + /* Initialize the Metering Buckets to be full (write them with 0xFFFFFFFF. */
47306 + /* Peak Rate Token Bucket Size (PTS_ETS used as PTS) */
47307 + p_PlcrRegs->fmpl_pepts_ets = 0xFFFFFFFF;
47308 + /* Committed Rate Token Bucket Size (CTS) */
47309 + p_PlcrRegs->fmpl_pects = 0xFFFFFFFF;
47310 +
47311 + /* Set the FPP based on calculation */
47312 + pemode |= (fpp << FM_PCD_PLCR_PEMODE_FPP_SHIFT);
47313 + }
47314 + break; /* FM_PCD_PLCR_PEMODE_ALG_RFC2698 , FM_PCD_PLCR_PEMODE_ALG_RFC4115 */
47315 + default:
47316 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION, NO_MSG);
47317 + }
47318 +
47319 + p_PlcrRegs->fmpl_pemode = pemode;
47320 +
47321 + p_PlcrRegs->fmpl_pegnia = gnia;
47322 + p_PlcrRegs->fmpl_peynia = ynia;
47323 + p_PlcrRegs->fmpl_pernia = rnia;
47324 +
47325 + /* Zero Counters */
47326 + p_PlcrRegs->fmpl_pegpc = 0;
47327 + p_PlcrRegs->fmpl_peypc = 0;
47328 + p_PlcrRegs->fmpl_perpc = 0;
47329 + p_PlcrRegs->fmpl_perypc = 0;
47330 + p_PlcrRegs->fmpl_perrpc = 0;
47331 +
47332 + return E_OK;
47333 +}
47334 +
47335 +static t_Error AllocSharedProfiles(t_FmPcd *p_FmPcd, uint16_t numOfProfiles, uint16_t *profilesIds)
47336 +{
47337 + uint32_t profilesFound;
47338 + uint16_t i, k=0;
47339 + uint32_t intFlags;
47340 +
47341 + SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);
47342 +
47343 + if (!numOfProfiles)
47344 + return E_OK;
47345 +
47346 + if (numOfProfiles>FM_PCD_PLCR_NUM_ENTRIES)
47347 + RETURN_ERROR(MINOR, E_INVALID_VALUE, ("numProfiles is too big."));
47348 +
47349 + intFlags = PlcrSwLock(p_FmPcd->p_FmPcdPlcr);
47350 + /* Find numOfProfiles free profiles (may be spread) */
47351 + profilesFound = 0;
47352 + for (i=0;i<FM_PCD_PLCR_NUM_ENTRIES; i++)
47353 + if (!p_FmPcd->p_FmPcdPlcr->profiles[i].profilesMng.allocated)
47354 + {
47355 + profilesFound++;
47356 + profilesIds[k] = i;
47357 + k++;
47358 + if (profilesFound == numOfProfiles)
47359 + break;
47360 + }
47361 +
47362 + if (profilesFound != numOfProfiles)
47363 + {
47364 + PlcrSwUnlock(p_FmPcd->p_FmPcdPlcr, intFlags);
47365 + RETURN_ERROR(MAJOR, E_INVALID_STATE,NO_MSG);
47366 + }
47367 +
47368 + for (i = 0;i<k;i++)
47369 + {
47370 + p_FmPcd->p_FmPcdPlcr->profiles[profilesIds[i]].profilesMng.allocated = TRUE;
47371 + p_FmPcd->p_FmPcdPlcr->profiles[profilesIds[i]].profilesMng.ownerId = 0;
47372 + }
47373 + PlcrSwUnlock(p_FmPcd->p_FmPcdPlcr, intFlags);
47374 +
47375 + return E_OK;
47376 +}
47377 +
47378 +static void FreeSharedProfiles(t_FmPcd *p_FmPcd, uint16_t numOfProfiles, uint16_t *profilesIds)
47379 +{
47380 + uint16_t i;
47381 +
47382 + SANITY_CHECK_RETURN(p_FmPcd, E_INVALID_HANDLE);
47383 +
47384 + ASSERT_COND(numOfProfiles);
47385 +
47386 + for (i=0; i < numOfProfiles; i++)
47387 + {
47388 + ASSERT_COND(p_FmPcd->p_FmPcdPlcr->profiles[profilesIds[i]].profilesMng.allocated);
47389 + p_FmPcd->p_FmPcdPlcr->profiles[profilesIds[i]].profilesMng.allocated = FALSE;
47390 + p_FmPcd->p_FmPcdPlcr->profiles[profilesIds[i]].profilesMng.ownerId = p_FmPcd->guestId;
47391 + }
47392 +}
47393 +
47394 +static void UpdateRequiredActionFlag(t_Handle h_FmPcd, uint16_t absoluteProfileId, bool set)
47395 +{
47396 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
47397 +
47398 + /* this routine is protected by calling routine */
47399 +
47400 + ASSERT_COND(p_FmPcd->p_FmPcdPlcr->profiles[absoluteProfileId].valid);
47401 +
47402 + if (set)
47403 + p_FmPcd->p_FmPcdPlcr->profiles[absoluteProfileId].requiredActionFlag = TRUE;
47404 + else
47405 + {
47406 + p_FmPcd->p_FmPcdPlcr->profiles[absoluteProfileId].requiredAction = 0;
47407 + p_FmPcd->p_FmPcdPlcr->profiles[absoluteProfileId].requiredActionFlag = FALSE;
47408 + }
47409 +}
47410 +
47411 +/*********************************************/
47412 +/*............Policer Exception..............*/
47413 +/*********************************************/
47414 +static void EventsCB(t_Handle h_FmPcd)
47415 +{
47416 + t_FmPcd *p_FmPcd = (t_FmPcd *)h_FmPcd;
47417 + uint32_t event, mask, force;
47418 +
47419 + ASSERT_COND(FmIsMaster(p_FmPcd->h_Fm));
47420 + event = GET_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_evr);
47421 + mask = GET_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_ier);
47422 +
47423 + event &= mask;
47424 +
47425 + /* clear the forced events */
47426 + force = GET_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_ifr);
47427 + if (force & event)
47428 + WRITE_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_ifr, force & ~event);
47429 +
47430 +
47431 + WRITE_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_evr, event);
47432 +
47433 + if (event & FM_PCD_PLCR_PRAM_SELF_INIT_COMPLETE)
47434 + p_FmPcd->f_Exception(p_FmPcd->h_App,e_FM_PCD_PLCR_EXCEPTION_PRAM_SELF_INIT_COMPLETE);
47435 + if (event & FM_PCD_PLCR_ATOMIC_ACTION_COMPLETE)
47436 + p_FmPcd->f_Exception(p_FmPcd->h_App,e_FM_PCD_PLCR_EXCEPTION_ATOMIC_ACTION_COMPLETE);
47437 +}
47438 +
47439 +/* ..... */
47440 +
47441 +static void ErrorExceptionsCB(t_Handle h_FmPcd)
47442 +{
47443 + t_FmPcd *p_FmPcd = (t_FmPcd *)h_FmPcd;
47444 + uint32_t event, force, captureReg, mask;
47445 +
47446 + ASSERT_COND(FmIsMaster(p_FmPcd->h_Fm));
47447 + event = GET_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_eevr);
47448 + mask = GET_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_eier);
47449 +
47450 + event &= mask;
47451 +
47452 + /* clear the forced events */
47453 + force = GET_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_eifr);
47454 + if (force & event)
47455 + WRITE_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_eifr, force & ~event);
47456 +
47457 + WRITE_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_eevr, event);
47458 +
47459 + if (event & FM_PCD_PLCR_DOUBLE_ECC)
47460 + p_FmPcd->f_Exception(p_FmPcd->h_App,e_FM_PCD_PLCR_EXCEPTION_DOUBLE_ECC);
47461 + if (event & FM_PCD_PLCR_INIT_ENTRY_ERROR)
47462 + {
47463 + captureReg = GET_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_upcr);
47464 + /*ASSERT_COND(captureReg & PLCR_ERR_UNINIT_CAP);
47465 + p_UnInitCapt->profileNum = (uint8_t)(captureReg & PLCR_ERR_UNINIT_NUM_MASK);
47466 + p_UnInitCapt->portId = (uint8_t)((captureReg & PLCR_ERR_UNINIT_PID_MASK) >>PLCR_ERR_UNINIT_PID_SHIFT) ;
47467 + p_UnInitCapt->absolute = (bool)(captureReg & PLCR_ERR_UNINIT_ABSOLUTE_MASK);*/
47468 + p_FmPcd->f_FmPcdIndexedException(p_FmPcd->h_App,e_FM_PCD_PLCR_EXCEPTION_INIT_ENTRY_ERROR,(uint16_t)(captureReg & PLCR_ERR_UNINIT_NUM_MASK));
47469 + WRITE_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_upcr, PLCR_ERR_UNINIT_CAP);
47470 + }
47471 +}
47472 +
47473 +
47474 +/*****************************************************************************/
47475 +/* Inter-module API routines */
47476 +/*****************************************************************************/
47477 +
47478 +t_Handle PlcrConfig(t_FmPcd *p_FmPcd, t_FmPcdParams *p_FmPcdParams)
47479 +{
47480 + t_FmPcdPlcr *p_FmPcdPlcr;
47481 + uint16_t i=0;
47482 +
47483 + UNUSED(p_FmPcd);
47484 + UNUSED(p_FmPcdParams);
47485 +
47486 + p_FmPcdPlcr = (t_FmPcdPlcr *) XX_Malloc(sizeof(t_FmPcdPlcr));
47487 + if (!p_FmPcdPlcr)
47488 + {
47489 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FM Policer structure allocation FAILED"));
47490 + return NULL;
47491 + }
47492 + memset(p_FmPcdPlcr, 0, sizeof(t_FmPcdPlcr));
47493 + if (p_FmPcd->guestId == NCSW_MASTER_ID)
47494 + {
47495 + p_FmPcdPlcr->p_FmPcdPlcrRegs = (t_FmPcdPlcrRegs *)UINT_TO_PTR(FmGetPcdPlcrBaseAddr(p_FmPcdParams->h_Fm));
47496 + p_FmPcd->p_FmPcdDriverParam->plcrAutoRefresh = DEFAULT_plcrAutoRefresh;
47497 + p_FmPcd->exceptions |= (DEFAULT_fmPcdPlcrExceptions | DEFAULT_fmPcdPlcrErrorExceptions);
47498 + }
47499 +
47500 + p_FmPcdPlcr->numOfSharedProfiles = DEFAULT_numOfSharedPlcrProfiles;
47501 +
47502 + p_FmPcdPlcr->partPlcrProfilesBase = p_FmPcdParams->partPlcrProfilesBase;
47503 + p_FmPcdPlcr->partNumOfPlcrProfiles = p_FmPcdParams->partNumOfPlcrProfiles;
47504 + /* for backward compatabilty. if no policer profile, will set automatically to the max */
47505 + if ((p_FmPcd->guestId == NCSW_MASTER_ID) &&
47506 + (p_FmPcdPlcr->partNumOfPlcrProfiles == 0))
47507 + p_FmPcdPlcr->partNumOfPlcrProfiles = FM_PCD_PLCR_NUM_ENTRIES;
47508 +
47509 + for (i=0; i<FM_PCD_PLCR_NUM_ENTRIES; i++)
47510 + p_FmPcdPlcr->profiles[i].profilesMng.ownerId = (uint8_t)ILLEGAL_BASE;
47511 +
47512 + return p_FmPcdPlcr;
47513 +}
47514 +
47515 +t_Error PlcrInit(t_FmPcd *p_FmPcd)
47516 +{
47517 + t_FmPcdDriverParam *p_Param = p_FmPcd->p_FmPcdDriverParam;
47518 + t_FmPcdPlcr *p_FmPcdPlcr = p_FmPcd->p_FmPcdPlcr;
47519 + t_FmPcdPlcrRegs *p_Regs = p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs;
47520 + t_Error err = E_OK;
47521 + uint32_t tmpReg32 = 0;
47522 + uint16_t base;
47523 +
47524 + if ((p_FmPcdPlcr->partPlcrProfilesBase + p_FmPcdPlcr->partNumOfPlcrProfiles) > FM_PCD_PLCR_NUM_ENTRIES)
47525 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("partPlcrProfilesBase+partNumOfPlcrProfiles out of range!!!"));
47526 +
47527 + p_FmPcdPlcr->h_HwSpinlock = XX_InitSpinlock();
47528 + if (!p_FmPcdPlcr->h_HwSpinlock)
47529 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("FM Policer HW spinlock"));
47530 +
47531 + p_FmPcdPlcr->h_SwSpinlock = XX_InitSpinlock();
47532 + if (!p_FmPcdPlcr->h_SwSpinlock)
47533 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("FM Policer SW spinlock"));
47534 +
47535 + base = PlcrAllocProfilesForPartition(p_FmPcd,
47536 + p_FmPcdPlcr->partPlcrProfilesBase,
47537 + p_FmPcdPlcr->partNumOfPlcrProfiles,
47538 + p_FmPcd->guestId);
47539 + if (base == (uint16_t)ILLEGAL_BASE)
47540 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, NO_MSG);
47541 +
47542 + if (p_FmPcdPlcr->numOfSharedProfiles)
47543 + {
47544 + err = AllocSharedProfiles(p_FmPcd,
47545 + p_FmPcdPlcr->numOfSharedProfiles,
47546 + p_FmPcdPlcr->sharedProfilesIds);
47547 + if (err)
47548 + RETURN_ERROR(MAJOR, err,NO_MSG);
47549 + }
47550 +
47551 + if (p_FmPcd->guestId != NCSW_MASTER_ID)
47552 + return E_OK;
47553 +
47554 + /**********************FMPL_GCR******************/
47555 + tmpReg32 = 0;
47556 + tmpReg32 |= FM_PCD_PLCR_GCR_STEN;
47557 + if (p_Param->plcrAutoRefresh)
47558 + tmpReg32 |= FM_PCD_PLCR_GCR_DAR;
47559 + tmpReg32 |= GET_NIA_BMI_AC_ENQ_FRAME(p_FmPcd);
47560 +
47561 + WRITE_UINT32(p_Regs->fmpl_gcr, tmpReg32);
47562 + /**********************FMPL_GCR******************/
47563 +
47564 + /**********************FMPL_EEVR******************/
47565 + WRITE_UINT32(p_Regs->fmpl_eevr, (FM_PCD_PLCR_DOUBLE_ECC | FM_PCD_PLCR_INIT_ENTRY_ERROR));
47566 + /**********************FMPL_EEVR******************/
47567 + /**********************FMPL_EIER******************/
47568 + tmpReg32 = 0;
47569 + if (p_FmPcd->exceptions & FM_PCD_EX_PLCR_DOUBLE_ECC)
47570 + {
47571 + FmEnableRamsEcc(p_FmPcd->h_Fm);
47572 + tmpReg32 |= FM_PCD_PLCR_DOUBLE_ECC;
47573 + }
47574 + if (p_FmPcd->exceptions & FM_PCD_EX_PLCR_INIT_ENTRY_ERROR)
47575 + tmpReg32 |= FM_PCD_PLCR_INIT_ENTRY_ERROR;
47576 + WRITE_UINT32(p_Regs->fmpl_eier, tmpReg32);
47577 + /**********************FMPL_EIER******************/
47578 +
47579 + /**********************FMPL_EVR******************/
47580 + WRITE_UINT32(p_Regs->fmpl_evr, (FM_PCD_PLCR_PRAM_SELF_INIT_COMPLETE | FM_PCD_PLCR_ATOMIC_ACTION_COMPLETE));
47581 + /**********************FMPL_EVR******************/
47582 + /**********************FMPL_IER******************/
47583 + tmpReg32 = 0;
47584 + if (p_FmPcd->exceptions & FM_PCD_EX_PLCR_PRAM_SELF_INIT_COMPLETE)
47585 + tmpReg32 |= FM_PCD_PLCR_PRAM_SELF_INIT_COMPLETE;
47586 + if (p_FmPcd->exceptions & FM_PCD_EX_PLCR_ATOMIC_ACTION_COMPLETE)
47587 + tmpReg32 |= FM_PCD_PLCR_ATOMIC_ACTION_COMPLETE;
47588 + WRITE_UINT32(p_Regs->fmpl_ier, tmpReg32);
47589 + /**********************FMPL_IER******************/
47590 +
47591 + /* register even if no interrupts enabled, to allow future enablement */
47592 + FmRegisterIntr(p_FmPcd->h_Fm,
47593 + e_FM_MOD_PLCR,
47594 + 0,
47595 + e_FM_INTR_TYPE_ERR,
47596 + ErrorExceptionsCB,
47597 + p_FmPcd);
47598 + FmRegisterIntr(p_FmPcd->h_Fm,
47599 + e_FM_MOD_PLCR,
47600 + 0,
47601 + e_FM_INTR_TYPE_NORMAL,
47602 + EventsCB,
47603 + p_FmPcd);
47604 +
47605 + /* driver initializes one DFLT profile at the last entry*/
47606 + /**********************FMPL_DPMR******************/
47607 + tmpReg32 = 0;
47608 + WRITE_UINT32(p_Regs->fmpl_dpmr, tmpReg32);
47609 + p_FmPcd->p_FmPcdPlcr->profiles[0].profilesMng.allocated = TRUE;
47610 +
47611 + return E_OK;
47612 +}
47613 +
47614 +t_Error PlcrFree(t_FmPcd *p_FmPcd)
47615 +{
47616 + FmUnregisterIntr(p_FmPcd->h_Fm, e_FM_MOD_PLCR, 0, e_FM_INTR_TYPE_ERR);
47617 + FmUnregisterIntr(p_FmPcd->h_Fm, e_FM_MOD_PLCR, 0, e_FM_INTR_TYPE_NORMAL);
47618 +
47619 + if (p_FmPcd->p_FmPcdPlcr->numOfSharedProfiles)
47620 + FreeSharedProfiles(p_FmPcd,
47621 + p_FmPcd->p_FmPcdPlcr->numOfSharedProfiles,
47622 + p_FmPcd->p_FmPcdPlcr->sharedProfilesIds);
47623 +
47624 + if (p_FmPcd->p_FmPcdPlcr->partNumOfPlcrProfiles)
47625 + PlcrFreeProfilesForPartition(p_FmPcd,
47626 + p_FmPcd->p_FmPcdPlcr->partPlcrProfilesBase,
47627 + p_FmPcd->p_FmPcdPlcr->partNumOfPlcrProfiles,
47628 + p_FmPcd->guestId);
47629 +
47630 + if (p_FmPcd->p_FmPcdPlcr->h_SwSpinlock)
47631 + XX_FreeSpinlock(p_FmPcd->p_FmPcdPlcr->h_SwSpinlock);
47632 +
47633 + if (p_FmPcd->p_FmPcdPlcr->h_HwSpinlock)
47634 + XX_FreeSpinlock(p_FmPcd->p_FmPcdPlcr->h_HwSpinlock);
47635 +
47636 + return E_OK;
47637 +}
47638 +
47639 +void PlcrEnable(t_FmPcd *p_FmPcd)
47640 +{
47641 + t_FmPcdPlcrRegs *p_Regs = p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs;
47642 +
47643 + WRITE_UINT32(p_Regs->fmpl_gcr, GET_UINT32(p_Regs->fmpl_gcr) | FM_PCD_PLCR_GCR_EN);
47644 +}
47645 +
47646 +void PlcrDisable(t_FmPcd *p_FmPcd)
47647 +{
47648 + t_FmPcdPlcrRegs *p_Regs = p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs;
47649 +
47650 + WRITE_UINT32(p_Regs->fmpl_gcr, GET_UINT32(p_Regs->fmpl_gcr) & ~FM_PCD_PLCR_GCR_EN);
47651 +}
47652 +
47653 +uint16_t PlcrAllocProfilesForPartition(t_FmPcd *p_FmPcd, uint16_t base, uint16_t numOfProfiles, uint8_t guestId)
47654 +{
47655 + uint32_t intFlags;
47656 + uint16_t profilesFound = 0;
47657 + int i = 0;
47658 +
47659 + ASSERT_COND(p_FmPcd);
47660 + ASSERT_COND(p_FmPcd->p_FmPcdPlcr);
47661 +
47662 + if (!numOfProfiles)
47663 + return 0;
47664 +
47665 + if ((numOfProfiles > FM_PCD_PLCR_NUM_ENTRIES) ||
47666 + (base + numOfProfiles > FM_PCD_PLCR_NUM_ENTRIES))
47667 + return (uint16_t)ILLEGAL_BASE;
47668 +
47669 + if (p_FmPcd->h_IpcSession)
47670 + {
47671 + t_FmIpcResourceAllocParams ipcAllocParams;
47672 + t_FmPcdIpcMsg msg;
47673 + t_FmPcdIpcReply reply;
47674 + t_Error err;
47675 + uint32_t replyLength;
47676 +
47677 + memset(&msg, 0, sizeof(msg));
47678 + memset(&reply, 0, sizeof(reply));
47679 + memset(&ipcAllocParams, 0, sizeof(t_FmIpcResourceAllocParams));
47680 + ipcAllocParams.guestId = p_FmPcd->guestId;
47681 + ipcAllocParams.num = p_FmPcd->p_FmPcdPlcr->partNumOfPlcrProfiles;
47682 + ipcAllocParams.base = p_FmPcd->p_FmPcdPlcr->partPlcrProfilesBase;
47683 + msg.msgId = FM_PCD_ALLOC_PROFILES;
47684 + memcpy(msg.msgBody, &ipcAllocParams, sizeof(t_FmIpcResourceAllocParams));
47685 + replyLength = sizeof(uint32_t) + sizeof(uint16_t);
47686 + err = XX_IpcSendMessage(p_FmPcd->h_IpcSession,
47687 + (uint8_t*)&msg,
47688 + sizeof(msg.msgId) + sizeof(t_FmIpcResourceAllocParams),
47689 + (uint8_t*)&reply,
47690 + &replyLength,
47691 + NULL,
47692 + NULL);
47693 + if ((err != E_OK) ||
47694 + (replyLength != (sizeof(uint32_t) + sizeof(uint16_t))))
47695 + {
47696 + REPORT_ERROR(MAJOR, err, NO_MSG);
47697 + return (uint16_t)ILLEGAL_BASE;
47698 + }
47699 + else
47700 + memcpy((uint8_t*)&p_FmPcd->p_FmPcdPlcr->partPlcrProfilesBase, reply.replyBody, sizeof(uint16_t));
47701 + if (p_FmPcd->p_FmPcdPlcr->partPlcrProfilesBase == (uint16_t)ILLEGAL_BASE)
47702 + {
47703 + REPORT_ERROR(MAJOR, err, NO_MSG);
47704 + return (uint16_t)ILLEGAL_BASE;
47705 + }
47706 + }
47707 + else if (p_FmPcd->guestId != NCSW_MASTER_ID)
47708 + {
47709 + DBG(WARNING, ("FM Guest mode, without IPC - can't validate Policer-profiles range!"));
47710 + return (uint16_t)ILLEGAL_BASE;
47711 + }
47712 +
47713 + intFlags = XX_LockIntrSpinlock(p_FmPcd->h_Spinlock);
47714 + for (i=base; i<(base+numOfProfiles); i++)
47715 + if (p_FmPcd->p_FmPcdPlcr->profiles[i].profilesMng.ownerId == (uint8_t)ILLEGAL_BASE)
47716 + profilesFound++;
47717 + else
47718 + break;
47719 +
47720 + if (profilesFound == numOfProfiles)
47721 + for (i=base; i<(base+numOfProfiles); i++)
47722 + p_FmPcd->p_FmPcdPlcr->profiles[i].profilesMng.ownerId = guestId;
47723 + else
47724 + {
47725 + XX_UnlockIntrSpinlock(p_FmPcd->h_Spinlock, intFlags);
47726 + return (uint16_t)ILLEGAL_BASE;
47727 + }
47728 + XX_UnlockIntrSpinlock(p_FmPcd->h_Spinlock, intFlags);
47729 +
47730 + return base;
47731 +}
47732 +
47733 +void PlcrFreeProfilesForPartition(t_FmPcd *p_FmPcd, uint16_t base, uint16_t numOfProfiles, uint8_t guestId)
47734 +{
47735 + int i = 0;
47736 +
47737 + ASSERT_COND(p_FmPcd);
47738 + ASSERT_COND(p_FmPcd->p_FmPcdPlcr);
47739 +
47740 + if (p_FmPcd->h_IpcSession)
47741 + {
47742 + t_FmIpcResourceAllocParams ipcAllocParams;
47743 + t_FmPcdIpcMsg msg;
47744 + t_Error err;
47745 +
47746 + memset(&msg, 0, sizeof(msg));
47747 + memset(&ipcAllocParams, 0, sizeof(t_FmIpcResourceAllocParams));
47748 + ipcAllocParams.guestId = p_FmPcd->guestId;
47749 + ipcAllocParams.num = p_FmPcd->p_FmPcdPlcr->partNumOfPlcrProfiles;
47750 + ipcAllocParams.base = p_FmPcd->p_FmPcdPlcr->partPlcrProfilesBase;
47751 + msg.msgId = FM_PCD_FREE_PROFILES;
47752 + memcpy(msg.msgBody, &ipcAllocParams, sizeof(t_FmIpcResourceAllocParams));
47753 + err = XX_IpcSendMessage(p_FmPcd->h_IpcSession,
47754 + (uint8_t*)&msg,
47755 + sizeof(msg.msgId) + sizeof(t_FmIpcResourceAllocParams),
47756 + NULL,
47757 + NULL,
47758 + NULL,
47759 + NULL);
47760 + if (err != E_OK)
47761 + REPORT_ERROR(MAJOR, err, NO_MSG);
47762 + return;
47763 + }
47764 + else if (p_FmPcd->guestId != NCSW_MASTER_ID)
47765 + {
47766 + DBG(WARNING, ("FM Guest mode, without IPC - can't validate Policer-profiles range!"));
47767 + return;
47768 + }
47769 +
47770 + for (i=base; i<(base+numOfProfiles); i++)
47771 + {
47772 + if (p_FmPcd->p_FmPcdPlcr->profiles[i].profilesMng.ownerId == guestId)
47773 + p_FmPcd->p_FmPcdPlcr->profiles[i].profilesMng.ownerId = (uint8_t)ILLEGAL_BASE;
47774 + else
47775 + DBG(WARNING, ("Request for freeing storage profile window which wasn't allocated to this partition"));
47776 + }
47777 +}
47778 +
47779 +t_Error PlcrSetPortProfiles(t_FmPcd *p_FmPcd,
47780 + uint8_t hardwarePortId,
47781 + uint16_t numOfProfiles,
47782 + uint16_t base)
47783 +{
47784 + t_FmPcdPlcrRegs *p_Regs = p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs;
47785 + uint32_t log2Num, tmpReg32;
47786 +
47787 + if ((p_FmPcd->guestId != NCSW_MASTER_ID) &&
47788 + !p_Regs &&
47789 + p_FmPcd->h_IpcSession)
47790 + {
47791 + t_FmIpcResourceAllocParams ipcAllocParams;
47792 + t_FmPcdIpcMsg msg;
47793 + t_Error err;
47794 +
47795 + memset(&msg, 0, sizeof(msg));
47796 + memset(&ipcAllocParams, 0, sizeof(t_FmIpcResourceAllocParams));
47797 + ipcAllocParams.guestId = hardwarePortId;
47798 + ipcAllocParams.num = numOfProfiles;
47799 + ipcAllocParams.base = base;
47800 + msg.msgId = FM_PCD_SET_PORT_PROFILES;
47801 + memcpy(msg.msgBody, &ipcAllocParams, sizeof(t_FmIpcResourceAllocParams));
47802 + err = XX_IpcSendMessage(p_FmPcd->h_IpcSession,
47803 + (uint8_t*)&msg,
47804 + sizeof(msg.msgId) + sizeof(t_FmIpcResourceAllocParams),
47805 + NULL,
47806 + NULL,
47807 + NULL,
47808 + NULL);
47809 + if (err != E_OK)
47810 + RETURN_ERROR(MAJOR, err, NO_MSG);
47811 + return E_OK;
47812 + }
47813 + else if (!p_Regs)
47814 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED,
47815 + ("Either IPC or 'baseAddress' is required!"));
47816 +
47817 + ASSERT_COND(IN_RANGE(1, hardwarePortId, 63));
47818 +
47819 + if (GET_UINT32(p_Regs->fmpl_pmr[hardwarePortId-1]) & FM_PCD_PLCR_PMR_V)
47820 + RETURN_ERROR(MAJOR, E_INVALID_VALUE,
47821 + ("The requesting port has already an allocated profiles window."));
47822 +
47823 + /**********************FMPL_PMRx******************/
47824 + LOG2((uint64_t)numOfProfiles, log2Num);
47825 + tmpReg32 = base;
47826 + tmpReg32 |= log2Num << 16;
47827 + tmpReg32 |= FM_PCD_PLCR_PMR_V;
47828 + WRITE_UINT32(p_Regs->fmpl_pmr[hardwarePortId-1], tmpReg32);
47829 +
47830 + return E_OK;
47831 +}
47832 +
47833 +t_Error PlcrClearPortProfiles(t_FmPcd *p_FmPcd, uint8_t hardwarePortId)
47834 +{
47835 + t_FmPcdPlcrRegs *p_Regs = p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs;
47836 +
47837 + if ((p_FmPcd->guestId != NCSW_MASTER_ID) &&
47838 + !p_Regs &&
47839 + p_FmPcd->h_IpcSession)
47840 + {
47841 + t_FmIpcResourceAllocParams ipcAllocParams;
47842 + t_FmPcdIpcMsg msg;
47843 + t_Error err;
47844 +
47845 + memset(&msg, 0, sizeof(msg));
47846 + memset(&ipcAllocParams, 0, sizeof(t_FmIpcResourceAllocParams));
47847 + ipcAllocParams.guestId = hardwarePortId;
47848 + msg.msgId = FM_PCD_CLEAR_PORT_PROFILES;
47849 + memcpy(msg.msgBody, &ipcAllocParams, sizeof(t_FmIpcResourceAllocParams));
47850 + err = XX_IpcSendMessage(p_FmPcd->h_IpcSession,
47851 + (uint8_t*)&msg,
47852 + sizeof(msg.msgId) + sizeof(t_FmIpcResourceAllocParams),
47853 + NULL,
47854 + NULL,
47855 + NULL,
47856 + NULL);
47857 + if (err != E_OK)
47858 + RETURN_ERROR(MAJOR, err, NO_MSG);
47859 + return E_OK;
47860 + }
47861 + else if (!p_Regs)
47862 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED,
47863 + ("Either IPC or 'baseAddress' is required!"));
47864 +
47865 + ASSERT_COND(IN_RANGE(1, hardwarePortId, 63));
47866 + WRITE_UINT32(p_Regs->fmpl_pmr[hardwarePortId-1], 0);
47867 +
47868 + return E_OK;
47869 +}
47870 +
47871 +t_Error FmPcdPlcrAllocProfiles(t_Handle h_FmPcd, uint8_t hardwarePortId, uint16_t numOfProfiles)
47872 +{
47873 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
47874 + t_Error err = E_OK;
47875 + uint32_t profilesFound;
47876 + uint32_t intFlags;
47877 + uint16_t i, first, swPortIndex = 0;
47878 +
47879 + SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);
47880 +
47881 + if (!numOfProfiles)
47882 + return E_OK;
47883 +
47884 + ASSERT_COND(hardwarePortId);
47885 +
47886 + if (numOfProfiles>FM_PCD_PLCR_NUM_ENTRIES)
47887 + RETURN_ERROR(MINOR, E_INVALID_VALUE, ("numProfiles is too big."));
47888 +
47889 + if (!POWER_OF_2(numOfProfiles))
47890 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("numProfiles must be a power of 2."));
47891 +
47892 + first = 0;
47893 + profilesFound = 0;
47894 + intFlags = PlcrSwLock(p_FmPcd->p_FmPcdPlcr);
47895 +
47896 + for (i=0; i<FM_PCD_PLCR_NUM_ENTRIES; )
47897 + {
47898 + if (!p_FmPcd->p_FmPcdPlcr->profiles[i].profilesMng.allocated)
47899 + {
47900 + profilesFound++;
47901 + i++;
47902 + if (profilesFound == numOfProfiles)
47903 + break;
47904 + }
47905 + else
47906 + {
47907 + profilesFound = 0;
47908 + /* advance i to the next aligned address */
47909 + i = first = (uint16_t)(first + numOfProfiles);
47910 + }
47911 + }
47912 +
47913 + if (profilesFound == numOfProfiles)
47914 + {
47915 + for (i=first; i<first + numOfProfiles; i++)
47916 + {
47917 + p_FmPcd->p_FmPcdPlcr->profiles[i].profilesMng.allocated = TRUE;
47918 + p_FmPcd->p_FmPcdPlcr->profiles[i].profilesMng.ownerId = hardwarePortId;
47919 + }
47920 + }
47921 + else
47922 + {
47923 + PlcrSwUnlock(p_FmPcd->p_FmPcdPlcr, intFlags);
47924 + RETURN_ERROR(MINOR, E_FULL, ("No profiles."));
47925 + }
47926 + PlcrSwUnlock(p_FmPcd->p_FmPcdPlcr, intFlags);
47927 +
47928 + err = PlcrSetPortProfiles(p_FmPcd, hardwarePortId, numOfProfiles, first);
47929 + if (err)
47930 + {
47931 + RETURN_ERROR(MAJOR, err, NO_MSG);
47932 + }
47933 +
47934 + HW_PORT_ID_TO_SW_PORT_INDX(swPortIndex, hardwarePortId);
47935 +
47936 + p_FmPcd->p_FmPcdPlcr->portsMapping[swPortIndex].numOfProfiles = numOfProfiles;
47937 + p_FmPcd->p_FmPcdPlcr->portsMapping[swPortIndex].profilesBase = first;
47938 +
47939 + return E_OK;
47940 +}
47941 +
47942 +t_Error FmPcdPlcrFreeProfiles(t_Handle h_FmPcd, uint8_t hardwarePortId)
47943 +{
47944 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
47945 + t_Error err = E_OK;
47946 + uint32_t intFlags;
47947 + uint16_t i, swPortIndex = 0;
47948 +
47949 + ASSERT_COND(IN_RANGE(1, hardwarePortId, 63));
47950 +
47951 + SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);
47952 + SANITY_CHECK_RETURN_ERROR(!p_FmPcd->p_FmPcdDriverParam, E_INVALID_HANDLE);
47953 +
47954 + HW_PORT_ID_TO_SW_PORT_INDX(swPortIndex, hardwarePortId);
47955 +
47956 + err = PlcrClearPortProfiles(p_FmPcd, hardwarePortId);
47957 + if (err)
47958 + RETURN_ERROR(MAJOR, err,NO_MSG);
47959 +
47960 + intFlags = PlcrSwLock(p_FmPcd->p_FmPcdPlcr);
47961 + for (i=p_FmPcd->p_FmPcdPlcr->portsMapping[swPortIndex].profilesBase;
47962 + i<(p_FmPcd->p_FmPcdPlcr->portsMapping[swPortIndex].profilesBase +
47963 + p_FmPcd->p_FmPcdPlcr->portsMapping[swPortIndex].numOfProfiles);
47964 + i++)
47965 + {
47966 + ASSERT_COND(p_FmPcd->p_FmPcdPlcr->profiles[i].profilesMng.ownerId == hardwarePortId);
47967 + ASSERT_COND(p_FmPcd->p_FmPcdPlcr->profiles[i].profilesMng.allocated);
47968 +
47969 + p_FmPcd->p_FmPcdPlcr->profiles[i].profilesMng.allocated = FALSE;
47970 + p_FmPcd->p_FmPcdPlcr->profiles[i].profilesMng.ownerId = p_FmPcd->guestId;
47971 + }
47972 + PlcrSwUnlock(p_FmPcd->p_FmPcdPlcr, intFlags);
47973 +
47974 + p_FmPcd->p_FmPcdPlcr->portsMapping[swPortIndex].numOfProfiles = 0;
47975 + p_FmPcd->p_FmPcdPlcr->portsMapping[swPortIndex].profilesBase = 0;
47976 +
47977 + return E_OK;
47978 +}
47979 +
47980 +t_Error FmPcdPlcrCcGetSetParams(t_Handle h_FmPcd, uint16_t profileIndx ,uint32_t requiredAction)
47981 +{
47982 + t_FmPcd *p_FmPcd = (t_FmPcd *)h_FmPcd;
47983 + t_FmPcdPlcr *p_FmPcdPlcr = p_FmPcd->p_FmPcdPlcr;
47984 + t_FmPcdPlcrRegs *p_FmPcdPlcrRegs = p_FmPcdPlcr->p_FmPcdPlcrRegs;
47985 + uint32_t tmpReg32, intFlags;
47986 + t_Error err;
47987 +
47988 + /* Calling function locked all PCD modules, so no need to lock here */
47989 +
47990 + if (profileIndx >= FM_PCD_PLCR_NUM_ENTRIES)
47991 + RETURN_ERROR(MAJOR, E_INVALID_VALUE,("Policer profile out of range"));
47992 +
47993 + if (!FmPcdPlcrIsProfileValid(p_FmPcd, profileIndx))
47994 + RETURN_ERROR(MAJOR, E_INVALID_VALUE,("Policer profile is not valid"));
47995 +
47996 + /*intFlags = PlcrProfileLock(&p_FmPcd->p_FmPcdPlcr->profiles[profileIndx]);*/
47997 +
47998 + if (p_FmPcd->h_Hc)
47999 + {
48000 + err = FmHcPcdPlcrCcGetSetParams(p_FmPcd->h_Hc, profileIndx, requiredAction);
48001 +
48002 + UpdateRequiredActionFlag(p_FmPcd, profileIndx, TRUE);
48003 + FmPcdPlcrUpdateRequiredAction(p_FmPcd, profileIndx, requiredAction);
48004 +
48005 + /*PlcrProfileUnlock(&p_FmPcd->p_FmPcdPlcr->profiles[profileIndx], intFlags);*/
48006 + return err;
48007 + }
48008 +
48009 + /* lock the HW because once we read the registers we don't want them to be changed
48010 + * by another access. (We can copy to a tmp location and release the lock!) */
48011 +
48012 + intFlags = PlcrHwLock(p_FmPcdPlcr);
48013 + WritePar(p_FmPcd, FmPcdPlcrBuildReadPlcrActionReg(profileIndx));
48014 +
48015 + if (!p_FmPcd->p_FmPcdPlcr->profiles[profileIndx].requiredActionFlag ||
48016 + !(p_FmPcd->p_FmPcdPlcr->profiles[profileIndx].requiredAction & requiredAction))
48017 + {
48018 + if (requiredAction & UPDATE_NIA_ENQ_WITHOUT_DMA)
48019 + {
48020 + if ((p_FmPcd->p_FmPcdPlcr->profiles[profileIndx].nextEngineOnGreen!= e_FM_PCD_DONE) ||
48021 + (p_FmPcd->p_FmPcdPlcr->profiles[profileIndx].nextEngineOnYellow!= e_FM_PCD_DONE) ||
48022 + (p_FmPcd->p_FmPcdPlcr->profiles[profileIndx].nextEngineOnRed!= e_FM_PCD_DONE))
48023 + {
48024 + PlcrHwUnlock(p_FmPcdPlcr, intFlags);
48025 + /*PlcrProfileUnlock(&p_FmPcd->p_FmPcdPlcr->profiles[profileIndx], intFlags);*/
48026 + RETURN_ERROR (MAJOR, E_OK, ("In this case the next engine can be e_FM_PCD_DONE"));
48027 + }
48028 +
48029 + if (p_FmPcd->p_FmPcdPlcr->profiles[profileIndx].paramsOnGreen.action == e_FM_PCD_ENQ_FRAME)
48030 + {
48031 + tmpReg32 = GET_UINT32(p_FmPcdPlcrRegs->profileRegs.fmpl_pegnia);
48032 + if (!(tmpReg32 & (NIA_ENG_BMI | NIA_BMI_AC_ENQ_FRAME)))
48033 + {
48034 + PlcrHwUnlock(p_FmPcdPlcr, intFlags);
48035 + /*PlcrProfileUnlock(&p_FmPcd->p_FmPcdPlcr->profiles[profileIndx], intFlags);*/
48036 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Next engine of this policer profile has to be assigned to FM_PCD_DONE"));
48037 + }
48038 + tmpReg32 |= NIA_BMI_AC_ENQ_FRAME_WITHOUT_DMA;
48039 + WRITE_UINT32(p_FmPcdPlcrRegs->profileRegs.fmpl_pegnia, tmpReg32);
48040 + tmpReg32 = FmPcdPlcrBuildWritePlcrActionReg(profileIndx);
48041 + tmpReg32 |= FM_PCD_PLCR_PAR_PWSEL_PEGNIA;
48042 + WritePar(p_FmPcd, tmpReg32);
48043 + }
48044 +
48045 + if (p_FmPcd->p_FmPcdPlcr->profiles[profileIndx].paramsOnYellow.action == e_FM_PCD_ENQ_FRAME)
48046 + {
48047 + tmpReg32 = GET_UINT32(p_FmPcdPlcrRegs->profileRegs.fmpl_peynia);
48048 + if (!(tmpReg32 & (NIA_ENG_BMI | NIA_BMI_AC_ENQ_FRAME)))
48049 + {
48050 + PlcrHwUnlock(p_FmPcdPlcr, intFlags);
48051 + /*PlcrProfileUnlock(&p_FmPcd->p_FmPcdPlcr->profiles[profileIndx], intFlags);*/
48052 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Next engine of this policer profile has to be assigned to FM_PCD_DONE"));
48053 + }
48054 + tmpReg32 |= NIA_BMI_AC_ENQ_FRAME_WITHOUT_DMA;
48055 + WRITE_UINT32(p_FmPcdPlcrRegs->profileRegs.fmpl_peynia, tmpReg32);
48056 + tmpReg32 = FmPcdPlcrBuildWritePlcrActionReg(profileIndx);
48057 + tmpReg32 |= FM_PCD_PLCR_PAR_PWSEL_PEYNIA;
48058 + WritePar(p_FmPcd, tmpReg32);
48059 + PlcrHwUnlock(p_FmPcdPlcr, intFlags);
48060 + }
48061 +
48062 + if (p_FmPcd->p_FmPcdPlcr->profiles[profileIndx].paramsOnRed.action == e_FM_PCD_ENQ_FRAME)
48063 + {
48064 + tmpReg32 = GET_UINT32(p_FmPcdPlcrRegs->profileRegs.fmpl_pernia);
48065 + if (!(tmpReg32 & (NIA_ENG_BMI | NIA_BMI_AC_ENQ_FRAME)))
48066 + {
48067 + PlcrHwUnlock(p_FmPcdPlcr, intFlags);
48068 + /*PlcrProfileUnlock(&p_FmPcd->p_FmPcdPlcr->profiles[profileIndx], intFlags);*/
48069 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Next engine of this policer profile has to be assigned to FM_PCD_DONE"));
48070 + }
48071 + tmpReg32 |= NIA_BMI_AC_ENQ_FRAME_WITHOUT_DMA;
48072 + WRITE_UINT32(p_FmPcdPlcrRegs->profileRegs.fmpl_pernia, tmpReg32);
48073 + tmpReg32 = FmPcdPlcrBuildWritePlcrActionReg(profileIndx);
48074 + tmpReg32 |= FM_PCD_PLCR_PAR_PWSEL_PERNIA;
48075 + WritePar(p_FmPcd, tmpReg32);
48076 +
48077 + }
48078 + }
48079 + }
48080 + PlcrHwUnlock(p_FmPcdPlcr, intFlags);
48081 +
48082 + UpdateRequiredActionFlag(p_FmPcd, profileIndx, TRUE);
48083 + FmPcdPlcrUpdateRequiredAction(p_FmPcd, profileIndx, requiredAction);
48084 +
48085 + /*PlcrProfileUnlock(&p_FmPcd->p_FmPcdPlcr->profiles[profileIndx], intFlags);*/
48086 +
48087 + return E_OK;
48088 +}
48089 +
48090 +uint32_t FmPcdPlcrGetRequiredActionFlag(t_Handle h_FmPcd, uint16_t absoluteProfileId)
48091 +{
48092 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
48093 +
48094 + ASSERT_COND(p_FmPcd->p_FmPcdPlcr->profiles[absoluteProfileId].valid);
48095 +
48096 + return p_FmPcd->p_FmPcdPlcr->profiles[absoluteProfileId].requiredActionFlag;
48097 +}
48098 +
48099 +uint32_t FmPcdPlcrGetRequiredAction(t_Handle h_FmPcd, uint16_t absoluteProfileId)
48100 +{
48101 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
48102 +
48103 + ASSERT_COND(p_FmPcd->p_FmPcdPlcr->profiles[absoluteProfileId].valid);
48104 +
48105 + return p_FmPcd->p_FmPcdPlcr->profiles[absoluteProfileId].requiredAction;
48106 +}
48107 +
48108 +bool FmPcdPlcrIsProfileValid(t_Handle h_FmPcd, uint16_t absoluteProfileId)
48109 +{
48110 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
48111 + t_FmPcdPlcr *p_FmPcdPlcr = p_FmPcd->p_FmPcdPlcr;
48112 +
48113 + ASSERT_COND(absoluteProfileId < FM_PCD_PLCR_NUM_ENTRIES);
48114 +
48115 + return p_FmPcdPlcr->profiles[absoluteProfileId].valid;
48116 +}
48117 +
48118 +void FmPcdPlcrValidateProfileSw(t_Handle h_FmPcd, uint16_t absoluteProfileId)
48119 +{
48120 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
48121 + uint32_t intFlags;
48122 +
48123 + ASSERT_COND(!p_FmPcd->p_FmPcdPlcr->profiles[absoluteProfileId].valid);
48124 +
48125 + intFlags = PlcrProfileLock(&p_FmPcd->p_FmPcdPlcr->profiles[absoluteProfileId]);
48126 + p_FmPcd->p_FmPcdPlcr->profiles[absoluteProfileId].valid = TRUE;
48127 + PlcrProfileUnlock(&p_FmPcd->p_FmPcdPlcr->profiles[absoluteProfileId], intFlags);
48128 +}
48129 +
48130 +void FmPcdPlcrInvalidateProfileSw(t_Handle h_FmPcd, uint16_t absoluteProfileId)
48131 +{
48132 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
48133 + uint32_t intFlags;
48134 +
48135 + ASSERT_COND(p_FmPcd->p_FmPcdPlcr->profiles[absoluteProfileId].valid);
48136 +
48137 + intFlags = PlcrProfileLock(&p_FmPcd->p_FmPcdPlcr->profiles[absoluteProfileId]);
48138 + p_FmPcd->p_FmPcdPlcr->profiles[absoluteProfileId].valid = FALSE;
48139 + PlcrProfileUnlock(&p_FmPcd->p_FmPcdPlcr->profiles[absoluteProfileId], intFlags);
48140 +}
48141 +
48142 +uint16_t FmPcdPlcrProfileGetAbsoluteId(t_Handle h_Profile)
48143 +{
48144 + return ((t_FmPcdPlcrProfile*)h_Profile)->absoluteProfileId;
48145 +}
48146 +
48147 +t_Error FmPcdPlcrGetAbsoluteIdByProfileParams(t_Handle h_FmPcd,
48148 + e_FmPcdProfileTypeSelection profileType,
48149 + t_Handle h_FmPort,
48150 + uint16_t relativeProfile,
48151 + uint16_t *p_AbsoluteId)
48152 +{
48153 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
48154 + t_FmPcdPlcr *p_FmPcdPlcr = p_FmPcd->p_FmPcdPlcr;
48155 + uint8_t i;
48156 +
48157 + switch (profileType)
48158 + {
48159 + case e_FM_PCD_PLCR_PORT_PRIVATE:
48160 + /* get port PCD id from port handle */
48161 + for (i=0;i<FM_MAX_NUM_OF_PORTS;i++)
48162 + if (p_FmPcd->p_FmPcdPlcr->portsMapping[i].h_FmPort == h_FmPort)
48163 + break;
48164 + if (i == FM_MAX_NUM_OF_PORTS)
48165 + RETURN_ERROR(MAJOR, E_INVALID_STATE , ("Invalid port handle."));
48166 +
48167 + if (!p_FmPcd->p_FmPcdPlcr->portsMapping[i].numOfProfiles)
48168 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION , ("Port has no allocated profiles"));
48169 + if (relativeProfile >= p_FmPcd->p_FmPcdPlcr->portsMapping[i].numOfProfiles)
48170 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION , ("Profile id is out of range"));
48171 + *p_AbsoluteId = (uint16_t)(p_FmPcd->p_FmPcdPlcr->portsMapping[i].profilesBase + relativeProfile);
48172 + break;
48173 + case e_FM_PCD_PLCR_SHARED:
48174 + if (relativeProfile >= p_FmPcdPlcr->numOfSharedProfiles)
48175 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION , ("Profile id is out of range"));
48176 + *p_AbsoluteId = (uint16_t)(p_FmPcdPlcr->sharedProfilesIds[relativeProfile]);
48177 + break;
48178 + default:
48179 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION, ("Invalid policer profile type"));
48180 + }
48181 +
48182 + return E_OK;
48183 +}
48184 +
48185 +uint16_t FmPcdPlcrGetPortProfilesBase(t_Handle h_FmPcd, uint8_t hardwarePortId)
48186 +{
48187 + t_FmPcd *p_FmPcd = (t_FmPcd *)h_FmPcd;
48188 + uint16_t swPortIndex = 0;
48189 +
48190 + HW_PORT_ID_TO_SW_PORT_INDX(swPortIndex, hardwarePortId);
48191 +
48192 + return p_FmPcd->p_FmPcdPlcr->portsMapping[swPortIndex].profilesBase;
48193 +}
48194 +
48195 +uint16_t FmPcdPlcrGetPortNumOfProfiles(t_Handle h_FmPcd, uint8_t hardwarePortId)
48196 +{
48197 + t_FmPcd *p_FmPcd = (t_FmPcd *)h_FmPcd;
48198 + uint16_t swPortIndex = 0;
48199 +
48200 + HW_PORT_ID_TO_SW_PORT_INDX(swPortIndex, hardwarePortId);
48201 +
48202 + return p_FmPcd->p_FmPcdPlcr->portsMapping[swPortIndex].numOfProfiles;
48203 +
48204 +}
48205 +uint32_t FmPcdPlcrBuildWritePlcrActionReg(uint16_t absoluteProfileId)
48206 +{
48207 + return (uint32_t)(FM_PCD_PLCR_PAR_GO |
48208 + ((uint32_t)absoluteProfileId << FM_PCD_PLCR_PAR_PNUM_SHIFT));
48209 +}
48210 +
48211 +uint32_t FmPcdPlcrBuildWritePlcrActionRegs(uint16_t absoluteProfileId)
48212 +{
48213 + return (uint32_t)(FM_PCD_PLCR_PAR_GO |
48214 + ((uint32_t)absoluteProfileId << FM_PCD_PLCR_PAR_PNUM_SHIFT) |
48215 + FM_PCD_PLCR_PAR_PWSEL_MASK);
48216 +}
48217 +
48218 +bool FmPcdPlcrHwProfileIsValid(uint32_t profileModeReg)
48219 +{
48220 +
48221 + if (profileModeReg & FM_PCD_PLCR_PEMODE_PI)
48222 + return TRUE;
48223 + else
48224 + return FALSE;
48225 +}
48226 +
48227 +uint32_t FmPcdPlcrBuildReadPlcrActionReg(uint16_t absoluteProfileId)
48228 +{
48229 + return (uint32_t)(FM_PCD_PLCR_PAR_GO |
48230 + FM_PCD_PLCR_PAR_R |
48231 + ((uint32_t)absoluteProfileId << FM_PCD_PLCR_PAR_PNUM_SHIFT) |
48232 + FM_PCD_PLCR_PAR_PWSEL_MASK);
48233 +}
48234 +
48235 +uint32_t FmPcdPlcrBuildCounterProfileReg(e_FmPcdPlcrProfileCounters counter)
48236 +{
48237 + switch (counter)
48238 + {
48239 + case (e_FM_PCD_PLCR_PROFILE_GREEN_PACKET_TOTAL_COUNTER):
48240 + return FM_PCD_PLCR_PAR_PWSEL_PEGPC;
48241 + case (e_FM_PCD_PLCR_PROFILE_YELLOW_PACKET_TOTAL_COUNTER):
48242 + return FM_PCD_PLCR_PAR_PWSEL_PEYPC;
48243 + case (e_FM_PCD_PLCR_PROFILE_RED_PACKET_TOTAL_COUNTER) :
48244 + return FM_PCD_PLCR_PAR_PWSEL_PERPC;
48245 + case (e_FM_PCD_PLCR_PROFILE_RECOLOURED_YELLOW_PACKET_TOTAL_COUNTER) :
48246 + return FM_PCD_PLCR_PAR_PWSEL_PERYPC;
48247 + case (e_FM_PCD_PLCR_PROFILE_RECOLOURED_RED_PACKET_TOTAL_COUNTER) :
48248 + return FM_PCD_PLCR_PAR_PWSEL_PERRPC;
48249 + default:
48250 + REPORT_ERROR(MAJOR, E_INVALID_SELECTION, NO_MSG);
48251 + return 0;
48252 + }
48253 +}
48254 +
48255 +uint32_t FmPcdPlcrBuildNiaProfileReg(bool green, bool yellow, bool red)
48256 +{
48257 +
48258 + uint32_t tmpReg32 = 0;
48259 +
48260 + if (green)
48261 + tmpReg32 |= FM_PCD_PLCR_PAR_PWSEL_PEGNIA;
48262 + if (yellow)
48263 + tmpReg32 |= FM_PCD_PLCR_PAR_PWSEL_PEYNIA;
48264 + if (red)
48265 + tmpReg32 |= FM_PCD_PLCR_PAR_PWSEL_PERNIA;
48266 +
48267 + return tmpReg32;
48268 +}
48269 +
48270 +void FmPcdPlcrUpdateRequiredAction(t_Handle h_FmPcd, uint16_t absoluteProfileId, uint32_t requiredAction)
48271 +{
48272 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
48273 +
48274 + /* this routine is protected by calling routine */
48275 +
48276 + ASSERT_COND(p_FmPcd->p_FmPcdPlcr->profiles[absoluteProfileId].valid);
48277 +
48278 + p_FmPcd->p_FmPcdPlcr->profiles[absoluteProfileId].requiredAction |= requiredAction;
48279 +}
48280 +
48281 +/*********************** End of inter-module routines ************************/
48282 +
48283 +
48284 +/**************************************************/
48285 +/*............Policer API.........................*/
48286 +/**************************************************/
48287 +
48288 +t_Error FM_PCD_ConfigPlcrAutoRefreshMode(t_Handle h_FmPcd, bool enable)
48289 +{
48290 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
48291 +
48292 + SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);
48293 + SANITY_CHECK_RETURN_ERROR(p_FmPcd->p_FmPcdDriverParam, E_INVALID_HANDLE);
48294 + SANITY_CHECK_RETURN_ERROR(p_FmPcd->p_FmPcdPlcr, E_INVALID_HANDLE);
48295 +
48296 + if (!FmIsMaster(p_FmPcd->h_Fm))
48297 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("FM_PCD_ConfigPlcrAutoRefreshMode - guest mode!"));
48298 +
48299 + p_FmPcd->p_FmPcdDriverParam->plcrAutoRefresh = enable;
48300 +
48301 + return E_OK;
48302 +}
48303 +
48304 +t_Error FM_PCD_ConfigPlcrNumOfSharedProfiles(t_Handle h_FmPcd, uint16_t numOfSharedPlcrProfiles)
48305 +{
48306 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
48307 +
48308 + SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);
48309 + SANITY_CHECK_RETURN_ERROR(p_FmPcd->p_FmPcdDriverParam, E_INVALID_HANDLE);
48310 + SANITY_CHECK_RETURN_ERROR(p_FmPcd->p_FmPcdPlcr, E_INVALID_HANDLE);
48311 +
48312 + p_FmPcd->p_FmPcdPlcr->numOfSharedProfiles = numOfSharedPlcrProfiles;
48313 +
48314 + return E_OK;
48315 +}
48316 +
48317 +t_Error FM_PCD_SetPlcrStatistics(t_Handle h_FmPcd, bool enable)
48318 +{
48319 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
48320 + uint32_t tmpReg32;
48321 +
48322 + SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);
48323 + SANITY_CHECK_RETURN_ERROR(!p_FmPcd->p_FmPcdDriverParam, E_INVALID_HANDLE);
48324 + SANITY_CHECK_RETURN_ERROR(p_FmPcd->p_FmPcdPlcr, E_INVALID_HANDLE);
48325 +
48326 + if (!FmIsMaster(p_FmPcd->h_Fm))
48327 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("FM_PCD_SetPlcrStatistics - guest mode!"));
48328 +
48329 + tmpReg32 = GET_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_gcr);
48330 + if (enable)
48331 + tmpReg32 |= FM_PCD_PLCR_GCR_STEN;
48332 + else
48333 + tmpReg32 &= ~FM_PCD_PLCR_GCR_STEN;
48334 +
48335 + WRITE_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_gcr, tmpReg32);
48336 + return E_OK;
48337 +}
48338 +
48339 +t_Handle FM_PCD_PlcrProfileSet(t_Handle h_FmPcd,
48340 + t_FmPcdPlcrProfileParams *p_ProfileParams)
48341 +{
48342 + t_FmPcd *p_FmPcd;
48343 + t_FmPcdPlcrRegs *p_FmPcdPlcrRegs;
48344 + t_FmPcdPlcrProfileRegs plcrProfileReg;
48345 + uint32_t intFlags;
48346 + uint16_t absoluteProfileId;
48347 + t_Error err = E_OK;
48348 + uint32_t tmpReg32;
48349 + t_FmPcdPlcrProfile *p_Profile;
48350 +
48351 + SANITY_CHECK_RETURN_VALUE(h_FmPcd, E_INVALID_HANDLE, NULL);
48352 +
48353 + if (p_ProfileParams->modify)
48354 + {
48355 + p_Profile = (t_FmPcdPlcrProfile *)p_ProfileParams->id.h_Profile;
48356 + p_FmPcd = p_Profile->h_FmPcd;
48357 + absoluteProfileId = p_Profile->absoluteProfileId;
48358 + if (absoluteProfileId >= FM_PCD_PLCR_NUM_ENTRIES)
48359 + {
48360 + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("profileId too Big "));
48361 + return NULL;
48362 + }
48363 +
48364 + SANITY_CHECK_RETURN_VALUE(p_FmPcd->p_FmPcdPlcr, E_INVALID_HANDLE, NULL);
48365 +
48366 + /* Try lock profile using flag */
48367 + if (!PlcrProfileFlagTryLock(p_Profile))
48368 + {
48369 + DBG(TRACE, ("Profile Try Lock - BUSY"));
48370 + /* Signal to caller BUSY condition */
48371 + p_ProfileParams->id.h_Profile = NULL;
48372 + return NULL;
48373 + }
48374 + }
48375 + else
48376 + {
48377 + p_FmPcd = (t_FmPcd*)h_FmPcd;
48378 +
48379 + SANITY_CHECK_RETURN_VALUE(p_FmPcd->p_FmPcdPlcr, E_INVALID_HANDLE, NULL);
48380 +
48381 + /* SMP: needs to be protected only if another core now changes the windows */
48382 + err = FmPcdPlcrGetAbsoluteIdByProfileParams(h_FmPcd,
48383 + p_ProfileParams->id.newParams.profileType,
48384 + p_ProfileParams->id.newParams.h_FmPort,
48385 + p_ProfileParams->id.newParams.relativeProfileId,
48386 + &absoluteProfileId);
48387 + if (err)
48388 + {
48389 + REPORT_ERROR(MAJOR, err, NO_MSG);
48390 + return NULL;
48391 + }
48392 +
48393 + if (absoluteProfileId >= FM_PCD_PLCR_NUM_ENTRIES)
48394 + {
48395 + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("profileId too Big "));
48396 + return NULL;
48397 + }
48398 +
48399 + if (FmPcdPlcrIsProfileValid(p_FmPcd, absoluteProfileId))
48400 + {
48401 + REPORT_ERROR(MAJOR, E_ALREADY_EXISTS, ("Policer Profile is already used"));
48402 + return NULL;
48403 + }
48404 +
48405 + /* initialize profile struct */
48406 + p_Profile = &p_FmPcd->p_FmPcdPlcr->profiles[absoluteProfileId];
48407 +
48408 + p_Profile->h_FmPcd = p_FmPcd;
48409 + p_Profile->absoluteProfileId = absoluteProfileId;
48410 +
48411 + p_Profile->p_Lock = FmPcdAcquireLock(p_FmPcd);
48412 + if (!p_Profile->p_Lock)
48413 + REPORT_ERROR(MAJOR, E_NOT_AVAILABLE, ("FM Policer Profile lock obj!"));
48414 + }
48415 +
48416 + SANITY_CHECK_RETURN_VALUE(!p_FmPcd->p_FmPcdDriverParam, E_INVALID_STATE, NULL);
48417 +
48418 + p_Profile->nextEngineOnGreen = p_ProfileParams->nextEngineOnGreen;
48419 + memcpy(&p_Profile->paramsOnGreen, &(p_ProfileParams->paramsOnGreen), sizeof(u_FmPcdPlcrNextEngineParams));
48420 +
48421 + p_Profile->nextEngineOnYellow = p_ProfileParams->nextEngineOnYellow;
48422 + memcpy(&p_Profile->paramsOnYellow, &(p_ProfileParams->paramsOnYellow), sizeof(u_FmPcdPlcrNextEngineParams));
48423 +
48424 + p_Profile->nextEngineOnRed = p_ProfileParams->nextEngineOnRed;
48425 + memcpy(&p_Profile->paramsOnRed, &(p_ProfileParams->paramsOnRed), sizeof(u_FmPcdPlcrNextEngineParams));
48426 +
48427 + memset(&plcrProfileReg, 0, sizeof(t_FmPcdPlcrProfileRegs));
48428 +
48429 + /* build the policer profile registers */
48430 + err = BuildProfileRegs(h_FmPcd, p_ProfileParams, &plcrProfileReg);
48431 + if (err)
48432 + {
48433 + REPORT_ERROR(MAJOR, err, NO_MSG);
48434 + if (p_ProfileParams->modify)
48435 + /* unlock */
48436 + PlcrProfileFlagUnlock(p_Profile);
48437 + if (!p_ProfileParams->modify &&
48438 + p_Profile->p_Lock)
48439 + /* release allocated Profile lock */
48440 + FmPcdReleaseLock(p_FmPcd, p_Profile->p_Lock);
48441 + return NULL;
48442 + }
48443 +
48444 + if (p_FmPcd->h_Hc)
48445 + {
48446 + err = FmHcPcdPlcrSetProfile(p_FmPcd->h_Hc, (t_Handle)p_Profile, &plcrProfileReg);
48447 + if (p_ProfileParams->modify)
48448 + PlcrProfileFlagUnlock(p_Profile);
48449 + if (err)
48450 + {
48451 + /* release the allocated scheme lock */
48452 + if (!p_ProfileParams->modify &&
48453 + p_Profile->p_Lock)
48454 + FmPcdReleaseLock(p_FmPcd, p_Profile->p_Lock);
48455 +
48456 + return NULL;
48457 + }
48458 + if (!p_ProfileParams->modify)
48459 + FmPcdPlcrValidateProfileSw(p_FmPcd,absoluteProfileId);
48460 + return (t_Handle)p_Profile;
48461 + }
48462 +
48463 + p_FmPcdPlcrRegs = p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs;
48464 + SANITY_CHECK_RETURN_VALUE(p_FmPcdPlcrRegs, E_INVALID_HANDLE, NULL);
48465 +
48466 + intFlags = PlcrHwLock(p_FmPcd->p_FmPcdPlcr);
48467 + WRITE_UINT32(p_FmPcdPlcrRegs->profileRegs.fmpl_pemode , plcrProfileReg.fmpl_pemode);
48468 + WRITE_UINT32(p_FmPcdPlcrRegs->profileRegs.fmpl_pegnia , plcrProfileReg.fmpl_pegnia);
48469 + WRITE_UINT32(p_FmPcdPlcrRegs->profileRegs.fmpl_peynia , plcrProfileReg.fmpl_peynia);
48470 + WRITE_UINT32(p_FmPcdPlcrRegs->profileRegs.fmpl_pernia , plcrProfileReg.fmpl_pernia);
48471 + WRITE_UINT32(p_FmPcdPlcrRegs->profileRegs.fmpl_pecir , plcrProfileReg.fmpl_pecir);
48472 + WRITE_UINT32(p_FmPcdPlcrRegs->profileRegs.fmpl_pecbs , plcrProfileReg.fmpl_pecbs);
48473 + WRITE_UINT32(p_FmPcdPlcrRegs->profileRegs.fmpl_pepepir_eir,plcrProfileReg.fmpl_pepepir_eir);
48474 + WRITE_UINT32(p_FmPcdPlcrRegs->profileRegs.fmpl_pepbs_ebs,plcrProfileReg.fmpl_pepbs_ebs);
48475 + WRITE_UINT32(p_FmPcdPlcrRegs->profileRegs.fmpl_pelts , plcrProfileReg.fmpl_pelts);
48476 + WRITE_UINT32(p_FmPcdPlcrRegs->profileRegs.fmpl_pects , plcrProfileReg.fmpl_pects);
48477 + WRITE_UINT32(p_FmPcdPlcrRegs->profileRegs.fmpl_pepts_ets,plcrProfileReg.fmpl_pepts_ets);
48478 + WRITE_UINT32(p_FmPcdPlcrRegs->profileRegs.fmpl_pegpc , plcrProfileReg.fmpl_pegpc);
48479 + WRITE_UINT32(p_FmPcdPlcrRegs->profileRegs.fmpl_peypc , plcrProfileReg.fmpl_peypc);
48480 + WRITE_UINT32(p_FmPcdPlcrRegs->profileRegs.fmpl_perpc , plcrProfileReg.fmpl_perpc);
48481 + WRITE_UINT32(p_FmPcdPlcrRegs->profileRegs.fmpl_perypc , plcrProfileReg.fmpl_perypc);
48482 + WRITE_UINT32(p_FmPcdPlcrRegs->profileRegs.fmpl_perrpc , plcrProfileReg.fmpl_perrpc);
48483 +
48484 + tmpReg32 = FmPcdPlcrBuildWritePlcrActionRegs(absoluteProfileId);
48485 + WritePar(p_FmPcd, tmpReg32);
48486 +
48487 + PlcrHwUnlock(p_FmPcd->p_FmPcdPlcr, intFlags);
48488 +
48489 + if (!p_ProfileParams->modify)
48490 + FmPcdPlcrValidateProfileSw(p_FmPcd,absoluteProfileId);
48491 + else
48492 + PlcrProfileFlagUnlock(p_Profile);
48493 +
48494 + return (t_Handle)p_Profile;
48495 +}
48496 +
48497 +t_Error FM_PCD_PlcrProfileDelete(t_Handle h_Profile)
48498 +{
48499 + t_FmPcdPlcrProfile *p_Profile = (t_FmPcdPlcrProfile*)h_Profile;
48500 + t_FmPcd *p_FmPcd;
48501 + uint16_t profileIndx;
48502 + uint32_t tmpReg32, intFlags;
48503 + t_Error err;
48504 +
48505 + SANITY_CHECK_RETURN_ERROR(p_Profile, E_INVALID_HANDLE);
48506 + p_FmPcd = p_Profile->h_FmPcd;
48507 + SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);
48508 +
48509 + profileIndx = p_Profile->absoluteProfileId;
48510 +
48511 + UpdateRequiredActionFlag(p_FmPcd, profileIndx, FALSE);
48512 +
48513 + FmPcdPlcrInvalidateProfileSw(p_FmPcd,profileIndx);
48514 +
48515 + if (p_FmPcd->h_Hc)
48516 + {
48517 + err = FmHcPcdPlcrDeleteProfile(p_FmPcd->h_Hc, h_Profile);
48518 + if (p_Profile->p_Lock)
48519 + /* release allocated Profile lock */
48520 + FmPcdReleaseLock(p_FmPcd, p_Profile->p_Lock);
48521 +
48522 + return err;
48523 + }
48524 +
48525 + intFlags = PlcrHwLock(p_FmPcd->p_FmPcdPlcr);
48526 + WRITE_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->profileRegs.fmpl_pemode, ~FM_PCD_PLCR_PEMODE_PI);
48527 +
48528 + tmpReg32 = FmPcdPlcrBuildWritePlcrActionRegs(profileIndx);
48529 + WritePar(p_FmPcd, tmpReg32);
48530 + PlcrHwUnlock(p_FmPcd->p_FmPcdPlcr, intFlags);
48531 +
48532 +
48533 + if (p_Profile->p_Lock)
48534 + /* release allocated Profile lock */
48535 + FmPcdReleaseLock(p_FmPcd, p_Profile->p_Lock);
48536 +
48537 + /* we do not memset profile as all its fields are being re-initialized at "set",
48538 + * plus its allocation information is still valid. */
48539 + return E_OK;
48540 +}
48541 +
48542 +/***************************************************/
48543 +/*............Policer Profile Counter..............*/
48544 +/***************************************************/
48545 +uint32_t FM_PCD_PlcrProfileGetCounter(t_Handle h_Profile, e_FmPcdPlcrProfileCounters counter)
48546 +{
48547 + t_FmPcdPlcrProfile *p_Profile = (t_FmPcdPlcrProfile*)h_Profile;
48548 + t_FmPcd *p_FmPcd;
48549 + uint16_t profileIndx;
48550 + uint32_t intFlags, counterVal = 0;
48551 + t_FmPcdPlcrRegs *p_FmPcdPlcrRegs;
48552 +
48553 + SANITY_CHECK_RETURN_ERROR(p_Profile, E_INVALID_HANDLE);
48554 + p_FmPcd = p_Profile->h_FmPcd;
48555 + SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);
48556 +
48557 + if (p_FmPcd->h_Hc)
48558 + return FmHcPcdPlcrGetProfileCounter(p_FmPcd->h_Hc, h_Profile, counter);
48559 +
48560 + p_FmPcdPlcrRegs = p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs;
48561 + SANITY_CHECK_RETURN_VALUE(p_FmPcdPlcrRegs, E_INVALID_HANDLE, 0);
48562 +
48563 + profileIndx = p_Profile->absoluteProfileId;
48564 +
48565 + if (profileIndx >= FM_PCD_PLCR_NUM_ENTRIES)
48566 + {
48567 + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("profileId too Big "));
48568 + return 0;
48569 + }
48570 + intFlags = PlcrHwLock(p_FmPcd->p_FmPcdPlcr);
48571 + WritePar(p_FmPcd, FmPcdPlcrBuildReadPlcrActionReg(profileIndx));
48572 +
48573 + switch (counter)
48574 + {
48575 + case e_FM_PCD_PLCR_PROFILE_GREEN_PACKET_TOTAL_COUNTER:
48576 + counterVal = (GET_UINT32(p_FmPcdPlcrRegs->profileRegs.fmpl_pegpc));
48577 + break;
48578 + case e_FM_PCD_PLCR_PROFILE_YELLOW_PACKET_TOTAL_COUNTER:
48579 + counterVal = GET_UINT32(p_FmPcdPlcrRegs->profileRegs.fmpl_peypc);
48580 + break;
48581 + case e_FM_PCD_PLCR_PROFILE_RED_PACKET_TOTAL_COUNTER:
48582 + counterVal = GET_UINT32(p_FmPcdPlcrRegs->profileRegs.fmpl_perpc);
48583 + break;
48584 + case e_FM_PCD_PLCR_PROFILE_RECOLOURED_YELLOW_PACKET_TOTAL_COUNTER:
48585 + counterVal = GET_UINT32(p_FmPcdPlcrRegs->profileRegs.fmpl_perypc);
48586 + break;
48587 + case e_FM_PCD_PLCR_PROFILE_RECOLOURED_RED_PACKET_TOTAL_COUNTER:
48588 + counterVal = GET_UINT32(p_FmPcdPlcrRegs->profileRegs.fmpl_perrpc);
48589 + break;
48590 + default:
48591 + REPORT_ERROR(MAJOR, E_INVALID_SELECTION, NO_MSG);
48592 + break;
48593 + }
48594 + PlcrHwUnlock(p_FmPcd->p_FmPcdPlcr, intFlags);
48595 +
48596 + return counterVal;
48597 +}
48598 +
48599 +t_Error FM_PCD_PlcrProfileSetCounter(t_Handle h_Profile, e_FmPcdPlcrProfileCounters counter, uint32_t value)
48600 +{
48601 + t_FmPcdPlcrProfile *p_Profile = (t_FmPcdPlcrProfile*)h_Profile;
48602 + t_FmPcd *p_FmPcd;
48603 + uint16_t profileIndx;
48604 + uint32_t tmpReg32, intFlags;
48605 + t_FmPcdPlcrRegs *p_FmPcdPlcrRegs;
48606 +
48607 + SANITY_CHECK_RETURN_ERROR(p_Profile, E_INVALID_HANDLE);
48608 +
48609 + p_FmPcd = p_Profile->h_FmPcd;
48610 + profileIndx = p_Profile->absoluteProfileId;
48611 +
48612 + if (p_FmPcd->h_Hc)
48613 + return FmHcPcdPlcrSetProfileCounter(p_FmPcd->h_Hc, h_Profile, counter, value);
48614 +
48615 + p_FmPcdPlcrRegs = p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs;
48616 + SANITY_CHECK_RETURN_ERROR(p_FmPcdPlcrRegs, E_INVALID_HANDLE);
48617 +
48618 + intFlags = PlcrHwLock(p_FmPcd->p_FmPcdPlcr);
48619 + switch (counter)
48620 + {
48621 + case e_FM_PCD_PLCR_PROFILE_GREEN_PACKET_TOTAL_COUNTER:
48622 + WRITE_UINT32(p_FmPcdPlcrRegs->profileRegs.fmpl_pegpc, value);
48623 + break;
48624 + case e_FM_PCD_PLCR_PROFILE_YELLOW_PACKET_TOTAL_COUNTER:
48625 + WRITE_UINT32(p_FmPcdPlcrRegs->profileRegs.fmpl_peypc, value);
48626 + break;
48627 + case e_FM_PCD_PLCR_PROFILE_RED_PACKET_TOTAL_COUNTER:
48628 + WRITE_UINT32(p_FmPcdPlcrRegs->profileRegs.fmpl_perpc, value);
48629 + break;
48630 + case e_FM_PCD_PLCR_PROFILE_RECOLOURED_YELLOW_PACKET_TOTAL_COUNTER:
48631 + WRITE_UINT32(p_FmPcdPlcrRegs->profileRegs.fmpl_perypc ,value);
48632 + break;
48633 + case e_FM_PCD_PLCR_PROFILE_RECOLOURED_RED_PACKET_TOTAL_COUNTER:
48634 + WRITE_UINT32(p_FmPcdPlcrRegs->profileRegs.fmpl_perrpc ,value);
48635 + break;
48636 + default:
48637 + PlcrHwUnlock(p_FmPcd->p_FmPcdPlcr, intFlags);
48638 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION, NO_MSG);
48639 + }
48640 +
48641 + /* Activate the atomic write action by writing FMPL_PAR with: GO=1, RW=1, PSI=0, PNUM =
48642 + * Profile Number, PWSEL=0xFFFF (select all words).
48643 + */
48644 + tmpReg32 = FmPcdPlcrBuildWritePlcrActionReg(profileIndx);
48645 + tmpReg32 |= FmPcdPlcrBuildCounterProfileReg(counter);
48646 + WritePar(p_FmPcd, tmpReg32);
48647 + PlcrHwUnlock(p_FmPcd->p_FmPcdPlcr, intFlags);
48648 +
48649 + return E_OK;
48650 +}
48651 --- /dev/null
48652 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/fm_plcr.h
48653 @@ -0,0 +1,165 @@
48654 +/*
48655 + * Copyright 2008-2012 Freescale Semiconductor Inc.
48656 + *
48657 + * Redistribution and use in source and binary forms, with or without
48658 + * modification, are permitted provided that the following conditions are met:
48659 + * * Redistributions of source code must retain the above copyright
48660 + * notice, this list of conditions and the following disclaimer.
48661 + * * Redistributions in binary form must reproduce the above copyright
48662 + * notice, this list of conditions and the following disclaimer in the
48663 + * documentation and/or other materials provided with the distribution.
48664 + * * Neither the name of Freescale Semiconductor nor the
48665 + * names of its contributors may be used to endorse or promote products
48666 + * derived from this software without specific prior written permission.
48667 + *
48668 + *
48669 + * ALTERNATIVELY, this software may be distributed under the terms of the
48670 + * GNU General Public License ("GPL") as published by the Free Software
48671 + * Foundation, either version 2 of that License or (at your option) any
48672 + * later version.
48673 + *
48674 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
48675 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
48676 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
48677 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
48678 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
48679 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
48680 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
48681 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
48682 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
48683 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
48684 + */
48685 +
48686 +
48687 +/******************************************************************************
48688 + @File fm_plcr.h
48689 +
48690 + @Description FM Policer private header
48691 +*//***************************************************************************/
48692 +#ifndef __FM_PLCR_H
48693 +#define __FM_PLCR_H
48694 +
48695 +#include "std_ext.h"
48696 +
48697 +
48698 +/***********************************************************************/
48699 +/* Policer defines */
48700 +/***********************************************************************/
48701 +
48702 +#define FM_PCD_PLCR_PAR_GO 0x80000000
48703 +#define FM_PCD_PLCR_PAR_PWSEL_MASK 0x0000FFFF
48704 +#define FM_PCD_PLCR_PAR_R 0x40000000
48705 +
48706 +/* shifts */
48707 +#define FM_PCD_PLCR_PAR_PNUM_SHIFT 16
48708 +
48709 +/* masks */
48710 +#define FM_PCD_PLCR_PEMODE_PI 0x80000000
48711 +#define FM_PCD_PLCR_PEMODE_CBLND 0x40000000
48712 +#define FM_PCD_PLCR_PEMODE_ALG_MASK 0x30000000
48713 +#define FM_PCD_PLCR_PEMODE_ALG_RFC2698 0x10000000
48714 +#define FM_PCD_PLCR_PEMODE_ALG_RFC4115 0x20000000
48715 +#define FM_PCD_PLCR_PEMODE_DEFC_MASK 0x0C000000
48716 +#define FM_PCD_PLCR_PEMODE_DEFC_Y 0x04000000
48717 +#define FM_PCD_PLCR_PEMODE_DEFC_R 0x08000000
48718 +#define FM_PCD_PLCR_PEMODE_DEFC_OVERRIDE 0x0C000000
48719 +#define FM_PCD_PLCR_PEMODE_OVCLR_MASK 0x03000000
48720 +#define FM_PCD_PLCR_PEMODE_OVCLR_Y 0x01000000
48721 +#define FM_PCD_PLCR_PEMODE_OVCLR_R 0x02000000
48722 +#define FM_PCD_PLCR_PEMODE_OVCLR_G_NC 0x03000000
48723 +#define FM_PCD_PLCR_PEMODE_PKT 0x00800000
48724 +#define FM_PCD_PLCR_PEMODE_FPP_MASK 0x001F0000
48725 +#define FM_PCD_PLCR_PEMODE_FPP_SHIFT 16
48726 +#define FM_PCD_PLCR_PEMODE_FLS_MASK 0x0000F000
48727 +#define FM_PCD_PLCR_PEMODE_FLS_L2 0x00003000
48728 +#define FM_PCD_PLCR_PEMODE_FLS_L3 0x0000B000
48729 +#define FM_PCD_PLCR_PEMODE_FLS_L4 0x0000E000
48730 +#define FM_PCD_PLCR_PEMODE_FLS_FULL 0x0000F000
48731 +#define FM_PCD_PLCR_PEMODE_RBFLS 0x00000800
48732 +#define FM_PCD_PLCR_PEMODE_TRA 0x00000004
48733 +#define FM_PCD_PLCR_PEMODE_TRB 0x00000002
48734 +#define FM_PCD_PLCR_PEMODE_TRC 0x00000001
48735 +#define FM_PCD_PLCR_DOUBLE_ECC 0x80000000
48736 +#define FM_PCD_PLCR_INIT_ENTRY_ERROR 0x40000000
48737 +#define FM_PCD_PLCR_PRAM_SELF_INIT_COMPLETE 0x80000000
48738 +#define FM_PCD_PLCR_ATOMIC_ACTION_COMPLETE 0x40000000
48739 +
48740 +#define FM_PCD_PLCR_NIA_VALID 0x80000000
48741 +
48742 +#define FM_PCD_PLCR_GCR_EN 0x80000000
48743 +#define FM_PCD_PLCR_GCR_STEN 0x40000000
48744 +#define FM_PCD_PLCR_GCR_DAR 0x20000000
48745 +#define FM_PCD_PLCR_GCR_DEFNIA 0x00FFFFFF
48746 +#define FM_PCD_PLCR_NIA_ABS 0x00000100
48747 +
48748 +#define FM_PCD_PLCR_GSR_BSY 0x80000000
48749 +#define FM_PCD_PLCR_GSR_DQS 0x60000000
48750 +#define FM_PCD_PLCR_GSR_RPB 0x20000000
48751 +#define FM_PCD_PLCR_GSR_FQS 0x0C000000
48752 +#define FM_PCD_PLCR_GSR_LPALG 0x0000C000
48753 +#define FM_PCD_PLCR_GSR_LPCA 0x00003000
48754 +#define FM_PCD_PLCR_GSR_LPNUM 0x000000FF
48755 +
48756 +#define FM_PCD_PLCR_EVR_PSIC 0x80000000
48757 +#define FM_PCD_PLCR_EVR_AAC 0x40000000
48758 +
48759 +#define FM_PCD_PLCR_PAR_PSI 0x20000000
48760 +#define FM_PCD_PLCR_PAR_PNUM 0x00FF0000
48761 +/* PWSEL Selctive select options */
48762 +#define FM_PCD_PLCR_PAR_PWSEL_PEMODE 0x00008000 /* 0 */
48763 +#define FM_PCD_PLCR_PAR_PWSEL_PEGNIA 0x00004000 /* 1 */
48764 +#define FM_PCD_PLCR_PAR_PWSEL_PEYNIA 0x00002000 /* 2 */
48765 +#define FM_PCD_PLCR_PAR_PWSEL_PERNIA 0x00001000 /* 3 */
48766 +#define FM_PCD_PLCR_PAR_PWSEL_PECIR 0x00000800 /* 4 */
48767 +#define FM_PCD_PLCR_PAR_PWSEL_PECBS 0x00000400 /* 5 */
48768 +#define FM_PCD_PLCR_PAR_PWSEL_PEPIR_EIR 0x00000200 /* 6 */
48769 +#define FM_PCD_PLCR_PAR_PWSEL_PEPBS_EBS 0x00000100 /* 7 */
48770 +#define FM_PCD_PLCR_PAR_PWSEL_PELTS 0x00000080 /* 8 */
48771 +#define FM_PCD_PLCR_PAR_PWSEL_PECTS 0x00000040 /* 9 */
48772 +#define FM_PCD_PLCR_PAR_PWSEL_PEPTS_ETS 0x00000020 /* 10 */
48773 +#define FM_PCD_PLCR_PAR_PWSEL_PEGPC 0x00000010 /* 11 */
48774 +#define FM_PCD_PLCR_PAR_PWSEL_PEYPC 0x00000008 /* 12 */
48775 +#define FM_PCD_PLCR_PAR_PWSEL_PERPC 0x00000004 /* 13 */
48776 +#define FM_PCD_PLCR_PAR_PWSEL_PERYPC 0x00000002 /* 14 */
48777 +#define FM_PCD_PLCR_PAR_PWSEL_PERRPC 0x00000001 /* 15 */
48778 +
48779 +#define FM_PCD_PLCR_PAR_PMR_BRN_1TO1 0x0000 /* - Full bit replacement. {PBNUM[0:N-1]
48780 + 1-> 2^N specific locations. */
48781 +#define FM_PCD_PLCR_PAR_PMR_BRN_2TO2 0x1 /* - {PBNUM[0:N-2],PNUM[N-1]}.
48782 + 2-> 2^(N-1) base locations. */
48783 +#define FM_PCD_PLCR_PAR_PMR_BRN_4TO4 0x2 /* - {PBNUM[0:N-3],PNUM[N-2:N-1]}.
48784 + 4-> 2^(N-2) base locations. */
48785 +#define FM_PCD_PLCR_PAR_PMR_BRN_8TO8 0x3 /* - {PBNUM[0:N-4],PNUM[N-3:N-1]}.
48786 + 8->2^(N-3) base locations. */
48787 +#define FM_PCD_PLCR_PAR_PMR_BRN_16TO16 0x4 /* - {PBNUM[0:N-5],PNUM[N-4:N-1]}.
48788 + 16-> 2^(N-4) base locations. */
48789 +#define FM_PCD_PLCR_PAR_PMR_BRN_32TO32 0x5 /* {PBNUM[0:N-6],PNUM[N-5:N-1]}.
48790 + 32-> 2^(N-5) base locations. */
48791 +#define FM_PCD_PLCR_PAR_PMR_BRN_64TO64 0x6 /* {PBNUM[0:N-7],PNUM[N-6:N-1]}.
48792 + 64-> 2^(N-6) base locations. */
48793 +#define FM_PCD_PLCR_PAR_PMR_BRN_128TO128 0x7 /* {PBNUM[0:N-8],PNUM[N-7:N-1]}.
48794 + 128-> 2^(N-7) base locations. */
48795 +#define FM_PCD_PLCR_PAR_PMR_BRN_256TO256 0x8 /* - No bit replacement for N=8. {PNUM[N-8:N-1]}.
48796 + When N=8 this option maps all 256 profiles by the DISPATCH bus into one group. */
48797 +
48798 +#define FM_PCD_PLCR_PMR_V 0x80000000
48799 +#define PLCR_ERR_ECC_CAP 0x80000000
48800 +#define PLCR_ERR_ECC_TYPE_DOUBLE 0x40000000
48801 +#define PLCR_ERR_ECC_PNUM_MASK 0x00000FF0
48802 +#define PLCR_ERR_ECC_OFFSET_MASK 0x0000000F
48803 +
48804 +#define PLCR_ERR_UNINIT_CAP 0x80000000
48805 +#define PLCR_ERR_UNINIT_NUM_MASK 0x000000FF
48806 +#define PLCR_ERR_UNINIT_PID_MASK 0x003f0000
48807 +#define PLCR_ERR_UNINIT_ABSOLUTE_MASK 0x00008000
48808 +
48809 +/* shifts */
48810 +#define PLCR_ERR_ECC_PNUM_SHIFT 4
48811 +#define PLCR_ERR_UNINIT_PID_SHIFT 16
48812 +
48813 +#define FM_PCD_PLCR_PMR_BRN_SHIFT 16
48814 +
48815 +#define PLCR_PORT_WINDOW_SIZE(hardwarePortId)
48816 +
48817 +
48818 +#endif /* __FM_PLCR_H */
48819 --- /dev/null
48820 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/fm_prs.c
48821 @@ -0,0 +1,423 @@
48822 +/*
48823 + * Copyright 2008-2012 Freescale Semiconductor Inc.
48824 + *
48825 + * Redistribution and use in source and binary forms, with or without
48826 + * modification, are permitted provided that the following conditions are met:
48827 + * * Redistributions of source code must retain the above copyright
48828 + * notice, this list of conditions and the following disclaimer.
48829 + * * Redistributions in binary form must reproduce the above copyright
48830 + * notice, this list of conditions and the following disclaimer in the
48831 + * documentation and/or other materials provided with the distribution.
48832 + * * Neither the name of Freescale Semiconductor nor the
48833 + * names of its contributors may be used to endorse or promote products
48834 + * derived from this software without specific prior written permission.
48835 + *
48836 + *
48837 + * ALTERNATIVELY, this software may be distributed under the terms of the
48838 + * GNU General Public License ("GPL") as published by the Free Software
48839 + * Foundation, either version 2 of that License or (at your option) any
48840 + * later version.
48841 + *
48842 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
48843 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
48844 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
48845 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
48846 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
48847 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
48848 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
48849 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
48850 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
48851 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
48852 + */
48853 +
48854 +
48855 +/******************************************************************************
48856 + @File fm_pcd.c
48857 +
48858 + @Description FM PCD ...
48859 +*//***************************************************************************/
48860 +#include <linux/math64.h>
48861 +#include "std_ext.h"
48862 +#include "error_ext.h"
48863 +#include "string_ext.h"
48864 +#include "debug_ext.h"
48865 +#include "net_ext.h"
48866 +
48867 +#include "fm_common.h"
48868 +#include "fm_pcd.h"
48869 +#include "fm_pcd_ipc.h"
48870 +#include "fm_prs.h"
48871 +#include "fsl_fman_prs.h"
48872 +
48873 +
48874 +static void PcdPrsErrorException(t_Handle h_FmPcd)
48875 +{
48876 + t_FmPcd *p_FmPcd = (t_FmPcd *)h_FmPcd;
48877 + uint32_t event, ev_mask;
48878 + struct fman_prs_regs *PrsRegs = (struct fman_prs_regs *)p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs;
48879 +
48880 + ASSERT_COND(p_FmPcd->guestId == NCSW_MASTER_ID);
48881 + ev_mask = fman_prs_get_err_ev_mask(PrsRegs);
48882 +
48883 + event = fman_prs_get_err_event(PrsRegs, ev_mask);
48884 +
48885 + fman_prs_ack_err_event(PrsRegs, event);
48886 +
48887 + DBG(TRACE, ("parser error - 0x%08x\n",event));
48888 +
48889 + if(event & FM_PCD_PRS_DOUBLE_ECC)
48890 + p_FmPcd->f_Exception(p_FmPcd->h_App,e_FM_PCD_PRS_EXCEPTION_DOUBLE_ECC);
48891 +}
48892 +
48893 +static void PcdPrsException(t_Handle h_FmPcd)
48894 +{
48895 + t_FmPcd *p_FmPcd = (t_FmPcd *)h_FmPcd;
48896 + uint32_t event, ev_mask;
48897 + struct fman_prs_regs *PrsRegs = (struct fman_prs_regs *)p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs;
48898 +
48899 + ASSERT_COND(p_FmPcd->guestId == NCSW_MASTER_ID);
48900 + ev_mask = fman_prs_get_expt_ev_mask(PrsRegs);
48901 + event = fman_prs_get_expt_event(PrsRegs, ev_mask);
48902 +
48903 + ASSERT_COND(event & FM_PCD_PRS_SINGLE_ECC);
48904 +
48905 + DBG(TRACE, ("parser event - 0x%08x\n",event));
48906 +
48907 + fman_prs_ack_expt_event(PrsRegs, event);
48908 +
48909 + p_FmPcd->f_Exception(p_FmPcd->h_App,e_FM_PCD_PRS_EXCEPTION_SINGLE_ECC);
48910 +}
48911 +
48912 +t_Handle PrsConfig(t_FmPcd *p_FmPcd,t_FmPcdParams *p_FmPcdParams)
48913 +{
48914 + t_FmPcdPrs *p_FmPcdPrs;
48915 + uintptr_t baseAddr;
48916 +
48917 + UNUSED(p_FmPcd);
48918 + UNUSED(p_FmPcdParams);
48919 +
48920 + p_FmPcdPrs = (t_FmPcdPrs *) XX_Malloc(sizeof(t_FmPcdPrs));
48921 + if (!p_FmPcdPrs)
48922 + {
48923 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FM Parser structure allocation FAILED"));
48924 + return NULL;
48925 + }
48926 + memset(p_FmPcdPrs, 0, sizeof(t_FmPcdPrs));
48927 + fman_prs_defconfig(&p_FmPcd->p_FmPcdDriverParam->dfltCfg);
48928 +
48929 + if (p_FmPcd->guestId == NCSW_MASTER_ID)
48930 + {
48931 + baseAddr = FmGetPcdPrsBaseAddr(p_FmPcdParams->h_Fm);
48932 + p_FmPcdPrs->p_SwPrsCode = (uint32_t *)UINT_TO_PTR(baseAddr);
48933 + p_FmPcdPrs->p_FmPcdPrsRegs = (struct fman_prs_regs *)UINT_TO_PTR(baseAddr + PRS_REGS_OFFSET);
48934 + }
48935 +
48936 + p_FmPcdPrs->fmPcdPrsPortIdStatistics = p_FmPcd->p_FmPcdDriverParam->dfltCfg.port_id_stat;
48937 + p_FmPcd->p_FmPcdDriverParam->prsMaxParseCycleLimit = p_FmPcd->p_FmPcdDriverParam->dfltCfg.max_prs_cyc_lim;
48938 + p_FmPcd->exceptions |= p_FmPcd->p_FmPcdDriverParam->dfltCfg.prs_exceptions;
48939 +
48940 + return p_FmPcdPrs;
48941 +}
48942 +
48943 +#if ((DPAA_VERSION == 10) && defined(FM_CAPWAP_SUPPORT))
48944 + static uint8_t swPrsPatch[] = SW_PRS_UDP_LITE_PATCH;
48945 +#else
48946 + static uint8_t swPrsPatch[] = SW_PRS_OFFLOAD_PATCH;
48947 +#endif /* FM_CAPWAP_SUPPORT */
48948 +
48949 +t_Error PrsInit(t_FmPcd *p_FmPcd)
48950 +{
48951 + t_FmPcdDriverParam *p_Param = p_FmPcd->p_FmPcdDriverParam;
48952 + uint32_t *p_TmpCode;
48953 + uint32_t *p_LoadTarget = (uint32_t *)PTR_MOVE(p_FmPcd->p_FmPcdPrs->p_SwPrsCode,
48954 + FM_PCD_SW_PRS_SIZE-FM_PCD_PRS_SW_PATCHES_SIZE);
48955 + struct fman_prs_regs *PrsRegs = (struct fman_prs_regs *)p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs;
48956 + uint32_t i;
48957 +
48958 + ASSERT_COND(sizeof(swPrsPatch) <= (FM_PCD_PRS_SW_PATCHES_SIZE-FM_PCD_PRS_SW_TAIL_SIZE));
48959 +
48960 + /* nothing to do in guest-partition */
48961 + if (p_FmPcd->guestId != NCSW_MASTER_ID)
48962 + return E_OK;
48963 +
48964 + p_TmpCode = (uint32_t *)XX_MallocSmart(ROUND_UP(sizeof(swPrsPatch),4), 0, sizeof(uint32_t));
48965 + if (!p_TmpCode)
48966 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("Tmp Sw-Parser code allocation FAILED"));
48967 + memset((uint8_t *)p_TmpCode, 0, ROUND_UP(sizeof(swPrsPatch),4));
48968 + memcpy((uint8_t *)p_TmpCode, (uint8_t *)swPrsPatch, sizeof(swPrsPatch));
48969 +
48970 + fman_prs_init(PrsRegs, &p_Param->dfltCfg);
48971 +
48972 + /* register even if no interrupts enabled, to allow future enablement */
48973 + FmRegisterIntr(p_FmPcd->h_Fm, e_FM_MOD_PRS, 0, e_FM_INTR_TYPE_ERR, PcdPrsErrorException, p_FmPcd);
48974 +
48975 + /* register even if no interrupts enabled, to allow future enablement */
48976 + FmRegisterIntr(p_FmPcd->h_Fm, e_FM_MOD_PRS, 0, e_FM_INTR_TYPE_NORMAL, PcdPrsException, p_FmPcd);
48977 +
48978 + if(p_FmPcd->exceptions & FM_PCD_EX_PRS_SINGLE_ECC)
48979 + FmEnableRamsEcc(p_FmPcd->h_Fm);
48980 +
48981 + if(p_FmPcd->exceptions & FM_PCD_EX_PRS_DOUBLE_ECC)
48982 + FmEnableRamsEcc(p_FmPcd->h_Fm);
48983 +
48984 + /* load sw parser Ip-Frag patch */
48985 + for (i=0; i<DIV_CEIL(sizeof(swPrsPatch), 4); i++)
48986 + WRITE_UINT32(p_LoadTarget[i], GET_UINT32(p_TmpCode[i]));
48987 +
48988 + XX_FreeSmart(p_TmpCode);
48989 +
48990 + return E_OK;
48991 +}
48992 +
48993 +void PrsFree(t_FmPcd *p_FmPcd)
48994 +{
48995 + ASSERT_COND(p_FmPcd->guestId == NCSW_MASTER_ID);
48996 + FmUnregisterIntr(p_FmPcd->h_Fm, e_FM_MOD_PRS, 0, e_FM_INTR_TYPE_ERR);
48997 + /* register even if no interrupts enabled, to allow future enablement */
48998 + FmUnregisterIntr(p_FmPcd->h_Fm, e_FM_MOD_PRS, 0, e_FM_INTR_TYPE_NORMAL);
48999 +}
49000 +
49001 +void PrsEnable(t_FmPcd *p_FmPcd)
49002 +{
49003 + struct fman_prs_regs *PrsRegs = (struct fman_prs_regs *)p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs;
49004 +
49005 + ASSERT_COND(p_FmPcd->guestId == NCSW_MASTER_ID);
49006 + fman_prs_enable(PrsRegs);
49007 +}
49008 +
49009 +void PrsDisable(t_FmPcd *p_FmPcd)
49010 +{
49011 + struct fman_prs_regs *PrsRegs = (struct fman_prs_regs *)p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs;
49012 +
49013 + ASSERT_COND(p_FmPcd->guestId == NCSW_MASTER_ID);
49014 + fman_prs_disable(PrsRegs);
49015 +}
49016 +
49017 +int PrsIsEnabled(t_FmPcd *p_FmPcd)
49018 +{
49019 + struct fman_prs_regs *PrsRegs = (struct fman_prs_regs *)p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs;
49020 +
49021 + ASSERT_COND(p_FmPcd->guestId == NCSW_MASTER_ID);
49022 + return fman_prs_is_enabled(PrsRegs);
49023 +}
49024 +
49025 +t_Error PrsIncludePortInStatistics(t_FmPcd *p_FmPcd, uint8_t hardwarePortId, bool include)
49026 +{
49027 + struct fman_prs_regs *PrsRegs;
49028 + uint32_t bitMask = 0;
49029 + uint8_t prsPortId;
49030 +
49031 + SANITY_CHECK_RETURN_ERROR((hardwarePortId >=1 && hardwarePortId <= 16), E_INVALID_VALUE);
49032 + SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);
49033 + SANITY_CHECK_RETURN_ERROR(p_FmPcd->p_FmPcdPrs, E_INVALID_HANDLE);
49034 +
49035 + PrsRegs = (struct fman_prs_regs *)p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs;
49036 +
49037 + GET_FM_PCD_PRS_PORT_ID(prsPortId, hardwarePortId);
49038 + GET_FM_PCD_INDEX_FLAG(bitMask, prsPortId);
49039 +
49040 + if (include)
49041 + p_FmPcd->p_FmPcdPrs->fmPcdPrsPortIdStatistics |= bitMask;
49042 + else
49043 + p_FmPcd->p_FmPcdPrs->fmPcdPrsPortIdStatistics &= ~bitMask;
49044 +
49045 + fman_prs_set_stst_port_msk(PrsRegs,
49046 + p_FmPcd->p_FmPcdPrs->fmPcdPrsPortIdStatistics);
49047 +
49048 + return E_OK;
49049 +}
49050 +
49051 +t_Error FmPcdPrsIncludePortInStatistics(t_Handle h_FmPcd, uint8_t hardwarePortId, bool include)
49052 +{
49053 + t_FmPcd *p_FmPcd = (t_FmPcd *)h_FmPcd;
49054 + t_Error err;
49055 +
49056 + SANITY_CHECK_RETURN_ERROR((hardwarePortId >=1 && hardwarePortId <= 16), E_INVALID_VALUE);
49057 + SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);
49058 + SANITY_CHECK_RETURN_ERROR(p_FmPcd->p_FmPcdPrs, E_INVALID_HANDLE);
49059 +
49060 + if ((p_FmPcd->guestId != NCSW_MASTER_ID) &&
49061 + p_FmPcd->h_IpcSession)
49062 + {
49063 + t_FmPcdIpcPrsIncludePort prsIncludePortParams;
49064 + t_FmPcdIpcMsg msg;
49065 +
49066 + prsIncludePortParams.hardwarePortId = hardwarePortId;
49067 + prsIncludePortParams.include = include;
49068 + memset(&msg, 0, sizeof(msg));
49069 + msg.msgId = FM_PCD_PRS_INC_PORT_STATS;
49070 + memcpy(msg.msgBody, &prsIncludePortParams, sizeof(prsIncludePortParams));
49071 + err = XX_IpcSendMessage(p_FmPcd->h_IpcSession,
49072 + (uint8_t*)&msg,
49073 + sizeof(msg.msgId) +sizeof(prsIncludePortParams),
49074 + NULL,
49075 + NULL,
49076 + NULL,
49077 + NULL);
49078 + if (err != E_OK)
49079 + RETURN_ERROR(MAJOR, err, NO_MSG);
49080 + return E_OK;
49081 + }
49082 + else if (p_FmPcd->guestId != NCSW_MASTER_ID)
49083 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED,
49084 + ("running in guest-mode without IPC!"));
49085 +
49086 + return PrsIncludePortInStatistics(p_FmPcd, hardwarePortId, include);
49087 +}
49088 +
49089 +uint32_t FmPcdGetSwPrsOffset(t_Handle h_FmPcd, e_NetHeaderType hdr, uint8_t indexPerHdr)
49090 +{
49091 + t_FmPcd *p_FmPcd = (t_FmPcd *)h_FmPcd;
49092 + t_FmPcdPrsLabelParams *p_Label;
49093 + int i;
49094 +
49095 + SANITY_CHECK_RETURN_VALUE(p_FmPcd, E_INVALID_HANDLE, 0);
49096 + SANITY_CHECK_RETURN_VALUE(!p_FmPcd->p_FmPcdDriverParam, E_INVALID_HANDLE, 0);
49097 +
49098 + if ((p_FmPcd->guestId != NCSW_MASTER_ID) &&
49099 + p_FmPcd->h_IpcSession)
49100 + {
49101 + t_Error err = E_OK;
49102 + t_FmPcdIpcSwPrsLable labelParams;
49103 + t_FmPcdIpcMsg msg;
49104 + uint32_t prsOffset = 0;
49105 + t_FmPcdIpcReply reply;
49106 + uint32_t replyLength;
49107 +
49108 + memset(&reply, 0, sizeof(reply));
49109 + memset(&msg, 0, sizeof(msg));
49110 + labelParams.enumHdr = (uint32_t)hdr;
49111 + labelParams.indexPerHdr = indexPerHdr;
49112 + msg.msgId = FM_PCD_GET_SW_PRS_OFFSET;
49113 + memcpy(msg.msgBody, &labelParams, sizeof(labelParams));
49114 + replyLength = sizeof(uint32_t) + sizeof(uint32_t);
49115 + err = XX_IpcSendMessage(p_FmPcd->h_IpcSession,
49116 + (uint8_t*)&msg,
49117 + sizeof(msg.msgId) +sizeof(labelParams),
49118 + (uint8_t*)&reply,
49119 + &replyLength,
49120 + NULL,
49121 + NULL);
49122 + if (err != E_OK)
49123 + RETURN_ERROR(MAJOR, err, NO_MSG);
49124 + if (replyLength != sizeof(uint32_t) + sizeof(uint32_t))
49125 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch"));
49126 +
49127 + memcpy((uint8_t*)&prsOffset, reply.replyBody, sizeof(uint32_t));
49128 + return prsOffset;
49129 + }
49130 + else if (p_FmPcd->guestId != NCSW_MASTER_ID)
49131 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED,
49132 + ("running in guest-mode without IPC!"));
49133 +
49134 + ASSERT_COND(p_FmPcd->p_FmPcdPrs->currLabel < FM_PCD_PRS_NUM_OF_LABELS);
49135 +
49136 + for (i=0; i<p_FmPcd->p_FmPcdPrs->currLabel; i++)
49137 + {
49138 + p_Label = &p_FmPcd->p_FmPcdPrs->labelsTable[i];
49139 +
49140 + if ((hdr == p_Label->hdr) && (indexPerHdr == p_Label->indexPerHdr))
49141 + return p_Label->instructionOffset;
49142 + }
49143 +
49144 + REPORT_ERROR(MAJOR, E_NOT_FOUND, ("Sw Parser attachment Not found"));
49145 + return (uint32_t)ILLEGAL_BASE;
49146 +}
49147 +
49148 +void FM_PCD_SetPrsStatistics(t_Handle h_FmPcd, bool enable)
49149 +{
49150 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
49151 + struct fman_prs_regs *PrsRegs;
49152 +
49153 + SANITY_CHECK_RETURN(p_FmPcd, E_INVALID_HANDLE);
49154 + SANITY_CHECK_RETURN(p_FmPcd->p_FmPcdPrs, E_INVALID_HANDLE);
49155 +
49156 + PrsRegs = (struct fman_prs_regs *)p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs;
49157 +
49158 +
49159 + if(p_FmPcd->guestId != NCSW_MASTER_ID)
49160 + {
49161 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("FM_PCD_SetPrsStatistics - guest mode!"));
49162 + return;
49163 + }
49164 +
49165 + fman_prs_set_stst(PrsRegs, enable);
49166 +}
49167 +
49168 +t_Error FM_PCD_PrsLoadSw(t_Handle h_FmPcd, t_FmPcdPrsSwParams *p_SwPrs)
49169 +{
49170 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
49171 + uint32_t *p_LoadTarget;
49172 + uint32_t *p_TmpCode;
49173 + int i;
49174 +
49175 + SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);
49176 + SANITY_CHECK_RETURN_ERROR(!p_FmPcd->p_FmPcdDriverParam, E_INVALID_STATE);
49177 + SANITY_CHECK_RETURN_ERROR(p_FmPcd->p_FmPcdPrs, E_INVALID_STATE);
49178 + SANITY_CHECK_RETURN_ERROR(p_SwPrs, E_INVALID_HANDLE);
49179 + SANITY_CHECK_RETURN_ERROR(!p_FmPcd->enabled, E_INVALID_HANDLE);
49180 +
49181 + if (p_FmPcd->guestId != NCSW_MASTER_ID)
49182 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("FM in guest-mode!"));
49183 +
49184 + if (!p_SwPrs->override)
49185 + {
49186 + if(p_FmPcd->p_FmPcdPrs->p_CurrSwPrs > p_FmPcd->p_FmPcdPrs->p_SwPrsCode + p_SwPrs->base*2/4)
49187 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("SW parser base must be larger than current loaded code"));
49188 + }
49189 + else
49190 + p_FmPcd->p_FmPcdPrs->currLabel = 0;
49191 +
49192 + if (p_SwPrs->size > FM_PCD_SW_PRS_SIZE - FM_PCD_PRS_SW_TAIL_SIZE - p_SwPrs->base*2)
49193 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("p_SwPrs->size may not be larger than MAX_SW_PRS_CODE_SIZE"));
49194 +
49195 + if (p_FmPcd->p_FmPcdPrs->currLabel + p_SwPrs->numOfLabels > FM_PCD_PRS_NUM_OF_LABELS)
49196 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Exceeded number of labels allowed "));
49197 +
49198 + p_TmpCode = (uint32_t *)XX_MallocSmart(ROUND_UP(p_SwPrs->size,4), 0, sizeof(uint32_t));
49199 + if (!p_TmpCode)
49200 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("Tmp Sw-Parser code allocation FAILED"));
49201 + memset((uint8_t *)p_TmpCode, 0, ROUND_UP(p_SwPrs->size,4));
49202 + memcpy((uint8_t *)p_TmpCode, p_SwPrs->p_Code, p_SwPrs->size);
49203 +
49204 + /* save sw parser labels */
49205 + memcpy(&p_FmPcd->p_FmPcdPrs->labelsTable[p_FmPcd->p_FmPcdPrs->currLabel],
49206 + p_SwPrs->labelsTable,
49207 + p_SwPrs->numOfLabels*sizeof(t_FmPcdPrsLabelParams));
49208 + p_FmPcd->p_FmPcdPrs->currLabel += p_SwPrs->numOfLabels;
49209 +
49210 + /* load sw parser code */
49211 + p_LoadTarget = p_FmPcd->p_FmPcdPrs->p_SwPrsCode + p_SwPrs->base*2/4;
49212 +
49213 + for(i=0; i<DIV_CEIL(p_SwPrs->size, 4); i++)
49214 + WRITE_UINT32(p_LoadTarget[i], GET_UINT32(p_TmpCode[i]));
49215 +
49216 + p_FmPcd->p_FmPcdPrs->p_CurrSwPrs =
49217 + p_FmPcd->p_FmPcdPrs->p_SwPrsCode + p_SwPrs->base*2/4 + ROUND_UP(p_SwPrs->size,4);
49218 +
49219 + /* copy data parameters */
49220 + for (i=0;i<FM_PCD_PRS_NUM_OF_HDRS;i++)
49221 + WRITE_UINT32(*(p_FmPcd->p_FmPcdPrs->p_SwPrsCode+PRS_SW_DATA/4+i), p_SwPrs->swPrsDataParams[i]);
49222 +
49223 + /* Clear last 4 bytes */
49224 + WRITE_UINT32(*(p_FmPcd->p_FmPcdPrs->p_SwPrsCode+(PRS_SW_DATA-FM_PCD_PRS_SW_TAIL_SIZE)/4), 0);
49225 +
49226 + XX_FreeSmart(p_TmpCode);
49227 +
49228 + return E_OK;
49229 +}
49230 +
49231 +t_Error FM_PCD_ConfigPrsMaxCycleLimit(t_Handle h_FmPcd,uint16_t value)
49232 +{
49233 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
49234 +
49235 + SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);
49236 + SANITY_CHECK_RETURN_ERROR(p_FmPcd->p_FmPcdDriverParam, E_INVALID_HANDLE);
49237 +
49238 + if(p_FmPcd->guestId != NCSW_MASTER_ID)
49239 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("FM_PCD_ConfigPrsMaxCycleLimit - guest mode!"));
49240 +
49241 + p_FmPcd->p_FmPcdDriverParam->prsMaxParseCycleLimit = value;
49242 +
49243 + return E_OK;
49244 +}
49245 --- /dev/null
49246 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/fm_prs.h
49247 @@ -0,0 +1,316 @@
49248 +/*
49249 + * Copyright 2008-2012 Freescale Semiconductor Inc.
49250 + *
49251 + * Redistribution and use in source and binary forms, with or without
49252 + * modification, are permitted provided that the following conditions are met:
49253 + * * Redistributions of source code must retain the above copyright
49254 + * notice, this list of conditions and the following disclaimer.
49255 + * * Redistributions in binary form must reproduce the above copyright
49256 + * notice, this list of conditions and the following disclaimer in the
49257 + * documentation and/or other materials provided with the distribution.
49258 + * * Neither the name of Freescale Semiconductor nor the
49259 + * names of its contributors may be used to endorse or promote products
49260 + * derived from this software without specific prior written permission.
49261 + *
49262 + *
49263 + * ALTERNATIVELY, this software may be distributed under the terms of the
49264 + * GNU General Public License ("GPL") as published by the Free Software
49265 + * Foundation, either version 2 of that License or (at your option) any
49266 + * later version.
49267 + *
49268 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
49269 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
49270 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
49271 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
49272 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
49273 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
49274 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
49275 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
49276 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
49277 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
49278 + */
49279 +
49280 +
49281 +/******************************************************************************
49282 + @File fm_prs.h
49283 +
49284 + @Description FM Parser private header
49285 + *//***************************************************************************/
49286 +#ifndef __FM_PRS_H
49287 +#define __FM_PRS_H
49288 +
49289 +#include "std_ext.h"
49290 +
49291 +/***********************************************************************/
49292 +/* SW parser IP_FRAG patch */
49293 +/***********************************************************************/
49294 +
49295 +#if ((DPAA_VERSION == 10) && defined(FM_CAPWAP_SUPPORT))
49296 +#define SW_PRS_UDP_LITE_PATCH \
49297 +{\
49298 + 0x31,0x52,0x00,0xDA,0xFC,0x00,0x00,0x00,0x00,0x00, \
49299 + 0x00,0x00,0x50,0x2C,0x40,0x00,0x31,0x92,0x50,0x2C, \
49300 + 0x00,0x88,0x18,0x2F,0x00,0x01,0x1B,0xFE,0x18,0x71, \
49301 + 0x02,0x1F,0x00,0x08,0x00,0x83,0x02,0x1F,0x00,0x20, \
49302 + 0x28,0x1B,0x00,0x05,0x29,0x1F,0x30,0xD0,0x60,0x4F, \
49303 + 0x00,0x07,0x00,0x05,0x00,0x00,0xC3,0x8F,0x00,0x52, \
49304 + 0x00,0x01,0x07,0x01,0x60,0x3B,0x00,0x00,0x30,0xD0, \
49305 + 0x00,0xDA,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00, \
49306 + 0x40,0x4C,0x00,0x00,0x02,0x8F,0x00,0x00,0x30,0xF2, \
49307 + 0x00,0x06,0x18,0x5D,0x00,0x00,0x9F,0xFF,0x30,0xF2, \
49308 + 0x00,0x06,0x29,0x1E,0x07,0x08,0x30,0xD0,0x00,0x52, \
49309 + 0x00,0x08,0x28,0x1A,0x60,0x37,0x00,0x00,0x30,0xF2, \
49310 + 0x18,0x5D,0x06,0x00,0x29,0x1E,0x30,0xF2,0x2F,0x0E, \
49311 + 0x30,0x72,0x00,0x00,0x9B,0x8F,0x00,0x06,0x2F,0x0E, \
49312 + 0x32,0xF1,0x32,0xB0,0x00,0x4F,0x00,0x57,0x00,0x28, \
49313 + 0x00,0x00,0x97,0x9E,0x00,0x4E,0x30,0x72,0x00,0x06, \
49314 + 0x2F,0x0E,0x32,0xC1,0x32,0xF0,0x00,0x4A,0x00,0x80, \
49315 + 0x00,0x02,0x00,0x00,0x97,0x9E,0x40,0x7E,0x00,0x08, \
49316 + 0x08,0x16,0x00,0x54,0x00,0x01,0x1B,0xFE,0x00,0x00, \
49317 + 0x9F,0x9E,0x40,0xB3,0x00,0x00,0x02,0x1F,0x00,0x08, \
49318 + 0x28,0x1B,0x30,0x73,0x29,0x1F,0x30,0xD0,0x60,0x9F, \
49319 + 0x00,0x07,0x00,0x05,0x00,0x00,0xC3,0x8F,0x00,0x52, \
49320 + 0x00,0x01,0x07,0x01,0x60,0x8B,0x00,0x00,0x30,0xD0, \
49321 + 0x00,0xDA,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00, \
49322 + 0x40,0x9C,0x00,0x00,0x02,0x8F,0x00,0x00,0x30,0xF2, \
49323 + 0x00,0x06,0x18,0xAD,0x00,0x00,0x9F,0xFF,0x30,0xF2, \
49324 + 0x00,0x06,0x29,0x1E,0x07,0x08,0x30,0xD0,0x00,0x52, \
49325 + 0x00,0x08,0x28,0x1A,0x60,0x87,0x00,0x00,0x30,0xF2, \
49326 + 0x18,0xAD,0x06,0x00,0x29,0x1E,0x30,0xF2,0x50,0xB3, \
49327 + 0xFF,0xFF,0x18,0xB8,0x08,0x16,0x00,0x54,0x00,0x01, \
49328 + 0x1B,0xFE,0x18,0xC5,0x32,0xF1,0x28,0x5D,0x32,0xF1, \
49329 + 0x00,0x55,0x00,0x08,0x28,0x5F,0x00,0x00,0x8F,0x9F, \
49330 + 0x29,0x33,0x08,0x16,0x00,0x49,0x00,0x01,0x1B,0xFF, \
49331 + 0x00,0x01,0x1B,0xFF \
49332 +}
49333 +#endif /* ((DPAA_VERSION == 10) && defined(FM_CAPWAP_SUPPORT)) */
49334 +
49335 +#if (DPAA_VERSION == 10)
49336 +/* Version: 106.1.9 */
49337 +#define SW_PRS_OFFLOAD_PATCH \
49338 +{ \
49339 + 0x31,0x52,0x00,0xDA,0x0A,0x00,0x00,0x00,0x00,0x00, \
49340 + 0x00,0x00,0x43,0x0A,0x00,0x00,0x00,0x01,0x1B,0xFE, \
49341 + 0x00,0x00,0x99,0x00,0x53,0x13,0x00,0x00,0x00,0x00, \
49342 + 0x9F,0x98,0x53,0x13,0x00,0x00,0x1B,0x23,0x33,0xF1, \
49343 + 0x00,0xF9,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00, \
49344 + 0x28,0x7F,0x00,0x03,0x00,0x02,0x00,0x00,0x00,0x01, \
49345 + 0x32,0xC1,0x32,0xF0,0x00,0x4A,0x00,0x80,0x1F,0xFF, \
49346 + 0x00,0x01,0x1B,0xFE,0x31,0x52,0x00,0xDA,0x06,0x00, \
49347 + 0x00,0x00,0x00,0x00,0x00,0x00,0x43,0x2F,0x00,0x00, \
49348 + 0x00,0x01,0x1B,0xFE,0x31,0x52,0x00,0xDA,0x00,0x40, \
49349 + 0x00,0x00,0x00,0x00,0x00,0x00,0x53,0x95,0x00,0x00, \
49350 + 0x00,0x00,0x9B,0x8F,0x2F,0x0F,0x32,0xC1,0x00,0x55, \
49351 + 0x00,0x28,0x28,0x43,0x30,0x7E,0x43,0x45,0x00,0x00, \
49352 + 0x30,0x7E,0x43,0x45,0x00,0x3C,0x1B,0x5D,0x32,0x11, \
49353 + 0x32,0xC0,0x00,0x4F,0x00,0x81,0x00,0x00,0x83,0x8F, \
49354 + 0x2F,0x0F,0x06,0x00,0x32,0x11,0x32,0xC0,0x00,0x4F, \
49355 + 0x00,0x55,0x00,0x01,0x00,0x81,0x32,0x11,0x00,0x00, \
49356 + 0x83,0x8E,0x00,0x50,0x00,0x01,0x01,0x04,0x00,0x4D, \
49357 + 0x28,0x43,0x06,0x00,0x1B,0x3E,0x30,0x7E,0x53,0x79, \
49358 + 0x00,0x2B,0x32,0x11,0x32,0xC0,0x00,0x4F,0x00,0x81, \
49359 + 0x00,0x00,0x87,0x8F,0x28,0x23,0x06,0x00,0x32,0x11, \
49360 + 0x32,0xC0,0x00,0x4F,0x00,0x55,0x00,0x01,0x00,0x81, \
49361 + 0x32,0x11,0x00,0x00,0x83,0x8E,0x00,0x50,0x00,0x01, \
49362 + 0x01,0x04,0x00,0x4D,0x28,0x43,0x06,0x00,0x00,0x01, \
49363 + 0x1B,0xFE,0x00,0x00,0x9B,0x8E,0x53,0x90,0x00,0x00, \
49364 + 0x06,0x29,0x00,0x00,0x83,0x8F,0x28,0x23,0x06,0x00, \
49365 + 0x06,0x29,0x32,0xC1,0x00,0x55,0x00,0x28,0x00,0x00, \
49366 + 0x83,0x8E,0x00,0x50,0x00,0x01,0x01,0x04,0x00,0x4D, \
49367 + 0x28,0x43,0x06,0x00,0x00,0x01,0x1B,0xFE,0x32,0xC1, \
49368 + 0x00,0x55,0x00,0x28,0x28,0x43,0x1B,0xCF,0x00,0x00, \
49369 + 0x9B,0x8F,0x2F,0x0F,0x32,0xC1,0x00,0x55,0x00,0x28, \
49370 + 0x28,0x43,0x30,0x7E,0x43,0xBF,0x00,0x2C,0x32,0x11, \
49371 + 0x32,0xC0,0x00,0x4F,0x00,0x81,0x00,0x00,0x87,0x8F, \
49372 + 0x28,0x23,0x06,0x00,0x32,0x11,0x32,0xC0,0x00,0x4F, \
49373 + 0x00,0x81,0x00,0x00,0x83,0x8F,0x2F,0x0F,0x06,0x00, \
49374 + 0x32,0x11,0x32,0xC0,0x00,0x4F,0x00,0x55,0x00,0x01, \
49375 + 0x00,0x81,0x32,0x11,0x00,0x00,0x83,0x8E,0x00,0x50, \
49376 + 0x00,0x01,0x01,0x04,0x00,0x4D,0x28,0x43,0x06,0x00, \
49377 + 0x1B,0x9C,0x33,0xF1,0x00,0xF9,0x00,0x01,0x00,0x00, \
49378 + 0x00,0x00,0x00,0x00,0x28,0x7F,0x00,0x03,0x00,0x02, \
49379 + 0x00,0x00,0x00,0x01,0x32,0xC1,0x32,0xF0,0x00,0x4A, \
49380 + 0x00,0x80,0x1F,0xFF,0x00,0x01,0x1B,0xFE, \
49381 +}
49382 +
49383 +#else
49384 +#define SW_PRS_OFFLOAD_PATCH \
49385 +{ \
49386 + 0x31,0x52,0x00,0xDA,0x0E,0x4F,0x00,0x00,0x00,0x00, \
49387 + 0x00,0x00,0x51,0x16,0x08,0x4B,0x31,0x53,0x00,0xFB, \
49388 + 0xFF,0xF0,0x00,0x00,0x00,0x00,0x00,0x00,0x29,0x2B, \
49389 + 0x33,0xF1,0x00,0xFB,0x00,0xDF,0x00,0x00,0x00,0x00, \
49390 + 0x00,0x00,0x28,0x7F,0x31,0x52,0x00,0xDA,0x0A,0x00, \
49391 + 0x00,0x00,0x00,0x00,0x00,0x00,0x41,0x20,0x00,0x00, \
49392 + 0x00,0x01,0x1B,0xFE,0x00,0x00,0x99,0x00,0x51,0x29, \
49393 + 0x00,0x00,0x00,0x00,0x9F,0x98,0x51,0x29,0x00,0x00, \
49394 + 0x19,0x44,0x09,0x5F,0x00,0x20,0x00,0x00,0x09,0x4F, \
49395 + 0x00,0x20,0x00,0x00,0x34,0xB7,0x00,0xF9,0x00,0x00, \
49396 + 0x01,0x00,0x00,0x00,0x00,0x00,0x2B,0x97,0x31,0xB3, \
49397 + 0x29,0x8F,0x33,0xF1,0x00,0xF9,0x00,0x01,0x00,0x00, \
49398 + 0x00,0x00,0x00,0x00,0x28,0x7F,0x00,0x03,0x00,0x02, \
49399 + 0x00,0x00,0x00,0x01,0x1B,0xFE,0x00,0x01,0x1B,0xFE, \
49400 + 0x31,0x52,0x00,0xDA,0xFC,0x00,0x00,0x00,0x00,0x00, \
49401 + 0x00,0x00,0x51,0x52,0x40,0x00,0x31,0x92,0x51,0x52, \
49402 + 0x00,0x88,0x19,0x55,0x08,0x05,0x00,0x00,0x19,0x99, \
49403 + 0x02,0x1F,0x00,0x08,0x00,0x83,0x02,0x1F,0x00,0x20, \
49404 + 0x28,0x1B,0x00,0x05,0x29,0x1F,0x30,0xD0,0x61,0x75, \
49405 + 0x00,0x07,0x00,0x05,0x00,0x00,0xC3,0x8F,0x00,0x52, \
49406 + 0x00,0x01,0x07,0x01,0x61,0x61,0x00,0x00,0x30,0xD0, \
49407 + 0x00,0xDA,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00, \
49408 + 0x41,0x72,0x00,0x00,0x02,0x8F,0x00,0x00,0x30,0xF2, \
49409 + 0x00,0x06,0x19,0x83,0x00,0x00,0x9F,0xFF,0x30,0xF2, \
49410 + 0x00,0x06,0x29,0x1E,0x07,0x08,0x30,0xD0,0x00,0x52, \
49411 + 0x00,0x08,0x28,0x1A,0x61,0x5D,0x00,0x00,0x30,0xF2, \
49412 + 0x19,0x83,0x06,0x00,0x29,0x1E,0x30,0xF2,0x29,0x0E, \
49413 + 0x30,0x72,0x00,0x00,0x9B,0x8F,0x00,0x06,0x29,0x0E, \
49414 + 0x32,0xF1,0x32,0xB0,0x00,0x4F,0x00,0x57,0x00,0x28, \
49415 + 0x00,0x00,0x97,0x9E,0x00,0x4E,0x30,0x72,0x00,0x06, \
49416 + 0x29,0x0E,0x08,0x05,0x00,0x01,0x31,0x52,0x00,0xDA, \
49417 + 0x0E,0x4F,0x00,0x00,0x00,0x00,0x00,0x00,0x51,0xAF, \
49418 + 0x04,0x4B,0x31,0x53,0x00,0xFB,0xFF,0xF0,0x00,0x00, \
49419 + 0x00,0x00,0x00,0x00,0x29,0x2B,0x33,0xF1,0x00,0xFB, \
49420 + 0x00,0xDF,0x00,0x00,0x00,0x00,0x00,0x00,0x28,0x7F, \
49421 + 0x31,0x52,0x00,0xDA,0x06,0x00,0x00,0x00,0x00,0x00, \
49422 + 0x00,0x00,0x41,0xB9,0x00,0x00,0x00,0x01,0x1B,0xFE, \
49423 + 0x31,0x52,0x00,0xDA,0x00,0x40,0x00,0x00,0x00,0x00, \
49424 + 0x00,0x00,0x42,0x06,0x00,0x00,0x00,0x00,0x9B,0x8F, \
49425 + 0x28,0x01,0x32,0xC1,0x00,0x55,0x00,0x28,0x28,0x43, \
49426 + 0x30,0x00,0x41,0xEB,0x00,0x2C,0x32,0x11,0x32,0xC0, \
49427 + 0x00,0x4F,0x00,0x81,0x00,0x00,0x87,0x8F,0x28,0x23, \
49428 + 0x06,0x00,0x32,0x11,0x32,0xC0,0x00,0x4F,0x00,0x81, \
49429 + 0x00,0x00,0x83,0x8F,0x28,0x01,0x06,0x00,0x32,0x11, \
49430 + 0x32,0xC0,0x00,0x4F,0x00,0x55,0x00,0x01,0x00,0x81, \
49431 + 0x32,0x11,0x00,0x00,0x83,0x8E,0x00,0x50,0x00,0x01, \
49432 + 0x01,0x04,0x00,0x4D,0x28,0x43,0x06,0x00,0x19,0xC8, \
49433 + 0x09,0x5F,0x00,0x20,0x00,0x00,0x09,0x4F,0x00,0x20, \
49434 + 0x00,0x00,0x34,0xB7,0x00,0xF9,0x00,0x00,0x01,0x00, \
49435 + 0x00,0x00,0x00,0x00,0x2B,0x97,0x31,0xB3,0x29,0x8F, \
49436 + 0x33,0xF1,0x00,0xF9,0x00,0x01,0x00,0x00,0x00,0x00, \
49437 + 0x00,0x00,0x28,0x7F,0x00,0x03,0x00,0x02,0x00,0x00, \
49438 + 0x00,0x01,0x1B,0xFE,0x30,0x50,0x52,0x0B,0x00,0x00, \
49439 + 0x00,0x01,0x1B,0xFE,0x32,0xF1,0x32,0xC0,0x00,0x4F, \
49440 + 0x00,0x81,0x00,0x02,0x00,0x00,0x97,0x9E,0x42,0x18, \
49441 + 0x00,0x08,0x08,0x16,0x00,0x54,0x00,0x01,0x1B,0xFE, \
49442 + 0x00,0x00,0x9F,0x9E,0x42,0x4D,0x00,0x00,0x02,0x1F, \
49443 + 0x00,0x08,0x28,0x1B,0x30,0x73,0x29,0x1F,0x30,0xD0, \
49444 + 0x62,0x39,0x00,0x07,0x00,0x05,0x00,0x00,0xC3,0x8F, \
49445 + 0x00,0x52,0x00,0x01,0x07,0x01,0x62,0x25,0x00,0x00, \
49446 + 0x30,0xD0,0x00,0xDA,0x00,0x01,0x00,0x00,0x00,0x00, \
49447 + 0x00,0x00,0x42,0x36,0x00,0x00,0x02,0x8F,0x00,0x00, \
49448 + 0x30,0xF2,0x00,0x06,0x1A,0x47,0x00,0x00,0x9F,0xFF, \
49449 + 0x30,0xF2,0x00,0x06,0x29,0x1E,0x07,0x08,0x30,0xD0, \
49450 + 0x00,0x52,0x00,0x08,0x28,0x1A,0x62,0x21,0x00,0x00, \
49451 + 0x30,0xF2,0x1A,0x47,0x06,0x00,0x29,0x1E,0x30,0xF2, \
49452 + 0x52,0x4D,0xFF,0xFF,0x1A,0x52,0x08,0x16,0x00,0x54, \
49453 + 0x00,0x01,0x1B,0xFE,0x1A,0x5F,0x32,0xF1,0x28,0x5D, \
49454 + 0x32,0xF1,0x00,0x55,0x00,0x08,0x28,0x5F,0x00,0x00, \
49455 + 0x8F,0x9F,0x29,0x33,0x08,0x16,0x00,0x49,0x00,0x01, \
49456 + 0x1B,0xFF,0x00,0x01,0x1B,0xFF,0x31,0x52,0x00,0xDA, \
49457 + 0xFC,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x52,0x6D, \
49458 + 0x40,0x00,0x31,0x92,0x52,0x6D,0x00,0x88,0x1A,0x70, \
49459 + 0x08,0x05,0x00,0x00,0x1A,0xB4,0x02,0x1F,0x00,0x08, \
49460 + 0x00,0x83,0x02,0x1F,0x00,0x20,0x28,0x1B,0x00,0x05, \
49461 + 0x29,0x1F,0x30,0xD0,0x62,0x90,0x00,0x07,0x00,0x05, \
49462 + 0x00,0x00,0xC3,0x8F,0x00,0x52,0x00,0x01,0x07,0x01, \
49463 + 0x62,0x7C,0x00,0x00,0x30,0xD0,0x00,0xDA,0x00,0x01, \
49464 + 0x00,0x00,0x00,0x00,0x00,0x00,0x42,0x8D,0x00,0x00, \
49465 + 0x02,0x8F,0x00,0x00,0x30,0xF2,0x00,0x06,0x1A,0x9E, \
49466 + 0x00,0x00,0x9F,0xFF,0x30,0xF2,0x00,0x06,0x29,0x1E, \
49467 + 0x07,0x08,0x30,0xD0,0x00,0x52,0x00,0x08,0x28,0x1A, \
49468 + 0x62,0x78,0x00,0x00,0x30,0xF2,0x1A,0x9E,0x06,0x00, \
49469 + 0x29,0x1E,0x30,0xF2,0x29,0x0E,0x30,0x72,0x00,0x00, \
49470 + 0x9B,0x8F,0x00,0x06,0x29,0x0E,0x32,0xF1,0x32,0xB0, \
49471 + 0x00,0x4F,0x00,0x57,0x00,0x28,0x00,0x00,0x97,0x9E, \
49472 + 0x00,0x4E,0x30,0x72,0x00,0x06,0x29,0x0E,0x08,0x05, \
49473 + 0x00,0x01,0x31,0x52,0x00,0xDA,0x0E,0x4F,0x00,0x00, \
49474 + 0x00,0x00,0x00,0x00,0x52,0xCA,0x04,0x4B,0x31,0x53, \
49475 + 0x00,0xFB,0xFF,0xF0,0x00,0x00,0x00,0x00,0x00,0x00, \
49476 + 0x29,0x2B,0x33,0xF1,0x00,0xFB,0x00,0xDF,0x00,0x00, \
49477 + 0x00,0x00,0x00,0x00,0x28,0x7F,0x31,0x52,0x00,0xDA, \
49478 + 0x06,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x42,0xD4, \
49479 + 0x00,0x00,0x00,0x01,0x1B,0xFE,0x31,0x52,0x00,0xDA, \
49480 + 0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x53,0x37, \
49481 + 0x00,0x00,0x00,0x00,0x9B,0x8F,0x28,0x01,0x32,0xC1, \
49482 + 0x00,0x55,0x00,0x28,0x28,0x43,0x30,0x00,0x42,0xEA, \
49483 + 0x00,0x00,0x30,0x00,0x42,0xEA,0x00,0x3C,0x1B,0x02, \
49484 + 0x32,0x11,0x32,0xC0,0x00,0x4F,0x00,0x81,0x00,0x00, \
49485 + 0x83,0x8F,0x28,0x01,0x06,0x00,0x32,0x11,0x32,0xC0, \
49486 + 0x00,0x4F,0x00,0x55,0x00,0x01,0x00,0x81,0x32,0x11, \
49487 + 0x00,0x00,0x83,0x8E,0x00,0x50,0x00,0x01,0x01,0x04, \
49488 + 0x00,0x4D,0x28,0x43,0x06,0x00,0x1A,0xE3,0x30,0x00, \
49489 + 0x43,0x20,0x00,0x2B,0x00,0x00,0x9B,0x8E,0x43,0x0E, \
49490 + 0x00,0x00,0x32,0xC1,0x00,0x55,0x00,0x28,0x28,0x43, \
49491 + 0x1B,0x1F,0x06,0x29,0x00,0x00,0x83,0x8F,0x28,0x23, \
49492 + 0x06,0x00,0x06,0x29,0x32,0xC1,0x00,0x55,0x00,0x28, \
49493 + 0x00,0x00,0x83,0x8E,0x00,0x50,0x00,0x01,0x01,0x04, \
49494 + 0x00,0x4D,0x28,0x43,0x06,0x00,0x1B,0x37,0x32,0x11, \
49495 + 0x32,0xC0,0x00,0x4F,0x00,0x81,0x00,0x00,0x87,0x8F, \
49496 + 0x28,0x23,0x06,0x00,0x32,0x11,0x32,0xC0,0x00,0x4F, \
49497 + 0x00,0x55,0x00,0x01,0x00,0x81,0x32,0x11,0x00,0x00, \
49498 + 0x83,0x8E,0x00,0x50,0x00,0x01,0x01,0x04,0x00,0x4D, \
49499 + 0x28,0x43,0x06,0x00,0x30,0x50,0x53,0x3C,0x00,0x00, \
49500 + 0x00,0x01,0x1B,0xFE,0x32,0xF1,0x32,0xC0,0x00,0x4F, \
49501 + 0x00,0x81,0x00,0x02,0x00,0x00,0x97,0x9E,0x43,0x49, \
49502 + 0x00,0x08,0x08,0x16,0x00,0x54,0x00,0x01,0x1B,0xFE, \
49503 + 0x00,0x00,0x9F,0x9E,0x43,0x7E,0x00,0x00,0x02,0x1F, \
49504 + 0x00,0x08,0x28,0x1B,0x30,0x73,0x29,0x1F,0x30,0xD0, \
49505 + 0x63,0x6A,0x00,0x07,0x00,0x05,0x00,0x00,0xC3,0x8F, \
49506 + 0x00,0x52,0x00,0x01,0x07,0x01,0x63,0x56,0x00,0x00, \
49507 + 0x30,0xD0,0x00,0xDA,0x00,0x01,0x00,0x00,0x00,0x00, \
49508 + 0x00,0x00,0x43,0x67,0x00,0x00,0x02,0x8F,0x00,0x00, \
49509 + 0x30,0xF2,0x00,0x06,0x1B,0x78,0x00,0x00,0x9F,0xFF, \
49510 + 0x30,0xF2,0x00,0x06,0x29,0x1E,0x07,0x08,0x30,0xD0, \
49511 + 0x00,0x52,0x00,0x08,0x28,0x1A,0x63,0x52,0x00,0x00, \
49512 + 0x30,0xF2,0x1B,0x78,0x06,0x00,0x29,0x1E,0x30,0xF2, \
49513 + 0x53,0x7E,0xFF,0xFF,0x1B,0x83,0x08,0x16,0x00,0x54, \
49514 + 0x00,0x01,0x1B,0xFE,0x1B,0x90,0x32,0xF1,0x28,0x5D, \
49515 + 0x32,0xF1,0x00,0x55,0x00,0x08,0x28,0x5F,0x00,0x00, \
49516 + 0x8F,0x9F,0x29,0x33,0x08,0x16,0x00,0x49,0x00,0x01, \
49517 + 0x1B,0xFF,0x00,0x01,0x1B,0xFF,0x08,0x07,0x00,0x02, \
49518 + 0x00,0x00,0x8D,0x80,0x53,0x9C,0x00,0x01,0x30,0x71, \
49519 + 0x00,0x55,0x00,0x01,0x28,0x0F,0x00,0x00,0x8D,0x00, \
49520 + 0x53,0xA4,0x00,0x01,0x30,0x71,0x00,0x55,0x00,0x01, \
49521 + 0x28,0x0F,0x00,0x00,0x83,0x8E,0x53,0xB9,0x00,0x00, \
49522 + 0x00,0x00,0x86,0x08,0x30,0x71,0x00,0x7B,0x03,0xB9, \
49523 + 0x33,0xB4,0x00,0xDA,0xFF,0xFF,0x00,0x0F,0x00,0x00, \
49524 + 0x00,0x00,0x00,0x00,0x86,0x09,0x01,0x03,0x00,0x7D, \
49525 + 0x03,0xB9,0x1B,0xC8,0x33,0xD1,0x00,0xF9,0x00,0x10, \
49526 + 0x00,0x00,0x00,0x00,0x00,0x00,0x28,0x7B,0x09,0x5F, \
49527 + 0x00,0x1A,0x00,0x00,0x09,0x4F,0x00,0x1A,0x00,0x00, \
49528 + 0x00,0x01,0x1B,0xFF,0x00,0x00,0x8C,0x00,0x53,0xF0, \
49529 + 0x00,0x01,0x34,0xF5,0x00,0xFB,0xFF,0xFF,0x00,0x7F, \
49530 + 0x00,0x00,0x00,0x00,0x2A,0x9F,0x00,0x00,0x93,0x8F, \
49531 + 0x28,0x49,0x00,0x00,0x97,0x8F,0x28,0x4B,0x34,0x61, \
49532 + 0x28,0x4D,0x34,0x71,0x28,0x4F,0x34,0xB7,0x00,0xF9, \
49533 + 0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x2B,0x97, \
49534 + 0x33,0xF1,0x00,0xF9,0x00,0x01,0x00,0x00,0x00,0x00, \
49535 + 0x00,0x00,0x28,0x7F,0x00,0x03,0x00,0x02,0x00,0x00, \
49536 + 0x00,0x01,0x1B,0xFF,0x00,0x01,0x1B,0xFF, \
49537 +}
49538 +#endif /* (DPAA_VERSION == 10) */
49539 +
49540 +/****************************/
49541 +/* Parser defines */
49542 +/****************************/
49543 +#define FM_PCD_PRS_SW_TAIL_SIZE 4 /**< Number of bytes that must be cleared at
49544 + the end of the SW parser area */
49545 +
49546 +/* masks */
49547 +#define PRS_ERR_CAP 0x80000000
49548 +#define PRS_ERR_TYPE_DOUBLE 0x40000000
49549 +#define PRS_ERR_SINGLE_ECC_CNT_MASK 0x00FF0000
49550 +#define PRS_ERR_ADDR_MASK 0x000001FF
49551 +
49552 +/* others */
49553 +#define PRS_MAX_CYCLE_LIMIT 8191
49554 +#define PRS_SW_DATA 0x00000800
49555 +#define PRS_REGS_OFFSET 0x00000840
49556 +
49557 +#define GET_FM_PCD_PRS_PORT_ID(prsPortId,hardwarePortId) \
49558 + prsPortId = (uint8_t)(hardwarePortId & 0x0f)
49559 +
49560 +#define GET_FM_PCD_INDEX_FLAG(bitMask, prsPortId) \
49561 + bitMask = 0x80000000>>prsPortId
49562 +
49563 +#endif /* __FM_PRS_H */
49564 --- /dev/null
49565 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/fm_replic.c
49566 @@ -0,0 +1,984 @@
49567 +/*
49568 + * Copyright 2008-2012 Freescale Semiconductor Inc.
49569 + *
49570 + * Redistribution and use in source and binary forms, with or without
49571 + * modification, are permitted provided that the following conditions are met:
49572 + * * Redistributions of source code must retain the above copyright
49573 + * notice, this list of conditions and the following disclaimer.
49574 + * * Redistributions in binary form must reproduce the above copyright
49575 + * notice, this list of conditions and the following disclaimer in the
49576 + * documentation and/or other materials provided with the distribution.
49577 + * * Neither the name of Freescale Semiconductor nor the
49578 + * names of its contributors may be used to endorse or promote products
49579 + * derived from this software without specific prior written permission.
49580 + *
49581 + *
49582 + * ALTERNATIVELY, this software may be distributed under the terms of the
49583 + * GNU General Public License ("GPL") as published by the Free Software
49584 + * Foundation, either version 2 of that License or (at your option) any
49585 + * later version.
49586 + *
49587 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
49588 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
49589 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
49590 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
49591 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
49592 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
49593 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
49594 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
49595 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
49596 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
49597 + */
49598 +
49599 +
49600 +/******************************************************************************
49601 + @File fm_replic.c
49602 +
49603 + @Description FM frame replicator
49604 +*//***************************************************************************/
49605 +#include "std_ext.h"
49606 +#include "error_ext.h"
49607 +#include "string_ext.h"
49608 +#include "debug_ext.h"
49609 +#include "fm_pcd_ext.h"
49610 +#include "fm_muram_ext.h"
49611 +#include "fm_common.h"
49612 +#include "fm_hc.h"
49613 +#include "fm_replic.h"
49614 +#include "fm_cc.h"
49615 +#include "list_ext.h"
49616 +
49617 +
49618 +/****************************************/
49619 +/* static functions */
49620 +/****************************************/
49621 +static uint8_t GetMemberPosition(t_FmPcdFrmReplicGroup *p_ReplicGroup,
49622 + uint32_t memberIndex,
49623 + bool isAddOperation)
49624 +{
49625 + uint8_t memberPosition;
49626 + uint32_t lastMemberIndex;
49627 +
49628 + ASSERT_COND(p_ReplicGroup);
49629 +
49630 + /* the last member index is different between add and remove operation -
49631 + in case of remove - this is exactly the last member index
49632 + in case of add - this is the last member index + 1 - e.g.
49633 + if we have 4 members, the index of the actual last member is 3(because the
49634 + index starts from 0) therefore in order to add a new member as the last
49635 + member we shall use memberIndex = 4 and not 3
49636 + */
49637 + if (isAddOperation)
49638 + lastMemberIndex = p_ReplicGroup->numOfEntries;
49639 + else
49640 + lastMemberIndex = p_ReplicGroup->numOfEntries-1;
49641 +
49642 + /* last */
49643 + if (memberIndex == lastMemberIndex)
49644 + memberPosition = FRM_REPLIC_LAST_MEMBER_INDEX;
49645 + else
49646 + {
49647 + /* first */
49648 + if (memberIndex == 0)
49649 + memberPosition = FRM_REPLIC_FIRST_MEMBER_INDEX;
49650 + else
49651 + {
49652 + /* middle */
49653 + ASSERT_COND(memberIndex < lastMemberIndex);
49654 + memberPosition = FRM_REPLIC_MIDDLE_MEMBER_INDEX;
49655 + }
49656 + }
49657 + return memberPosition;
49658 +}
49659 +
49660 +static t_Error MemberCheckParams(t_Handle h_FmPcd,
49661 + t_FmPcdCcNextEngineParams *p_MemberParams)
49662 +{
49663 + t_Error err;
49664 +
49665 +
49666 + if ((p_MemberParams->nextEngine != e_FM_PCD_DONE) &&
49667 + (p_MemberParams->nextEngine != e_FM_PCD_KG) &&
49668 + (p_MemberParams->nextEngine != e_FM_PCD_PLCR))
49669 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("Next engine of a member should be MatchTable(cc) or Done or Policer"));
49670 +
49671 + /* check the regular parameters of the next engine */
49672 + err = ValidateNextEngineParams(h_FmPcd, p_MemberParams, e_FM_PCD_CC_STATS_MODE_NONE);
49673 + if (err)
49674 + RETURN_ERROR(MAJOR, err, ("member next engine parameters"));
49675 +
49676 + return E_OK;
49677 +}
49678 +
49679 +static t_Error CheckParams(t_Handle h_FmPcd,
49680 + t_FmPcdFrmReplicGroupParams *p_ReplicGroupParam)
49681 +{
49682 + int i;
49683 + t_Error err;
49684 +
49685 + /* check that max num of entries is at least 2 */
49686 + if (!IN_RANGE(2, p_ReplicGroupParam->maxNumOfEntries, FM_PCD_FRM_REPLIC_MAX_NUM_OF_ENTRIES))
49687 + 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));
49688 +
49689 + /* check that number of entries is greater than zero */
49690 + if (!p_ReplicGroupParam->numOfEntries)
49691 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("numOFEntries in the frame replicator group should be greater than zero"));
49692 +
49693 + /* check that max num of entries is equal or greater than number of entries */
49694 + if (p_ReplicGroupParam->maxNumOfEntries < p_ReplicGroupParam->numOfEntries)
49695 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("maxNumOfEntries should be equal or greater than numOfEntries"));
49696 +
49697 + for (i=0; i<p_ReplicGroupParam->numOfEntries; i++)
49698 + {
49699 + err = MemberCheckParams(h_FmPcd, &p_ReplicGroupParam->nextEngineParams[i]);
49700 + if (err)
49701 + RETURN_ERROR(MAJOR, err, ("member check parameters"));
49702 + }
49703 + return E_OK;
49704 +}
49705 +
49706 +static t_FmPcdFrmReplicMember *GetAvailableMember(t_FmPcdFrmReplicGroup *p_ReplicGroup)
49707 +{
49708 + t_FmPcdFrmReplicMember *p_ReplicMember = NULL;
49709 + t_List *p_Next;
49710 +
49711 + if (!LIST_IsEmpty(&p_ReplicGroup->availableMembersList))
49712 + {
49713 + p_Next = LIST_FIRST(&p_ReplicGroup->availableMembersList);
49714 + p_ReplicMember = LIST_OBJECT(p_Next, t_FmPcdFrmReplicMember, node);
49715 + ASSERT_COND(p_ReplicMember);
49716 + LIST_DelAndInit(p_Next);
49717 + }
49718 + return p_ReplicMember;
49719 +}
49720 +
49721 +static void PutAvailableMember(t_FmPcdFrmReplicGroup *p_ReplicGroup,
49722 + t_FmPcdFrmReplicMember *p_ReplicMember)
49723 +{
49724 + LIST_AddToTail(&p_ReplicMember->node, &p_ReplicGroup->availableMembersList);
49725 +}
49726 +
49727 +static void AddMemberToList(t_FmPcdFrmReplicGroup *p_ReplicGroup,
49728 + t_FmPcdFrmReplicMember *p_CurrentMember,
49729 + t_List *p_ListHead)
49730 +{
49731 + LIST_Add(&p_CurrentMember->node, p_ListHead);
49732 +
49733 + p_ReplicGroup->numOfEntries++;
49734 +}
49735 +
49736 +static void RemoveMemberFromList(t_FmPcdFrmReplicGroup *p_ReplicGroup,
49737 + t_FmPcdFrmReplicMember *p_CurrentMember)
49738 +{
49739 + ASSERT_COND(p_ReplicGroup->numOfEntries);
49740 + LIST_DelAndInit(&p_CurrentMember->node);
49741 + p_ReplicGroup->numOfEntries--;
49742 +}
49743 +
49744 +static void LinkSourceToMember(t_FmPcdFrmReplicGroup *p_ReplicGroup,
49745 + t_AdOfTypeContLookup *p_SourceTd,
49746 + t_FmPcdFrmReplicMember *p_ReplicMember)
49747 +{
49748 + t_FmPcd *p_FmPcd;
49749 +
49750 + ASSERT_COND(p_SourceTd);
49751 + ASSERT_COND(p_ReplicMember);
49752 + ASSERT_COND(p_ReplicGroup);
49753 + ASSERT_COND(p_ReplicGroup->h_FmPcd);
49754 +
49755 + /* Link the first member in the group to the source TD */
49756 + p_FmPcd = p_ReplicGroup->h_FmPcd;
49757 +
49758 + WRITE_UINT32(p_SourceTd->matchTblPtr,
49759 + (uint32_t)(XX_VirtToPhys(p_ReplicMember->p_MemberAd) -
49760 + p_FmPcd->physicalMuramBase));
49761 +}
49762 +
49763 +static void LinkMemberToMember(t_FmPcdFrmReplicGroup *p_ReplicGroup,
49764 + t_FmPcdFrmReplicMember *p_CurrentMember,
49765 + t_FmPcdFrmReplicMember *p_NextMember)
49766 +{
49767 + t_AdOfTypeResult *p_CurrReplicAd = (t_AdOfTypeResult*)p_CurrentMember->p_MemberAd;
49768 + t_AdOfTypeResult *p_NextReplicAd = NULL;
49769 + t_FmPcd *p_FmPcd;
49770 + uint32_t offset = 0;
49771 +
49772 + /* Check if the next member exists or it's NULL (- means that this is the last member) */
49773 + if (p_NextMember)
49774 + {
49775 + p_NextReplicAd = (t_AdOfTypeResult*)p_NextMember->p_MemberAd;
49776 + p_FmPcd = p_ReplicGroup->h_FmPcd;
49777 + offset = (XX_VirtToPhys(p_NextReplicAd) - (p_FmPcd->physicalMuramBase));
49778 + offset = ((offset>>NEXT_FRM_REPLIC_ADDR_SHIFT)<< NEXT_FRM_REPLIC_MEMBER_INDEX_SHIFT);
49779 + }
49780 +
49781 + /* link the current AD to point to the AD of the next member */
49782 + WRITE_UINT32(p_CurrReplicAd->res, offset);
49783 +}
49784 +
49785 +static t_Error ModifyDescriptor(t_FmPcdFrmReplicGroup *p_ReplicGroup,
49786 + void *p_OldDescriptor,
49787 + void *p_NewDescriptor)
49788 +{
49789 + t_Handle h_Hc;
49790 + t_Error err;
49791 + t_FmPcd *p_FmPcd;
49792 +
49793 + ASSERT_COND(p_ReplicGroup);
49794 + ASSERT_COND(p_ReplicGroup->h_FmPcd);
49795 + ASSERT_COND(p_OldDescriptor);
49796 + ASSERT_COND(p_NewDescriptor);
49797 +
49798 + p_FmPcd = p_ReplicGroup->h_FmPcd;
49799 + h_Hc = FmPcdGetHcHandle(p_FmPcd);
49800 + if (!h_Hc)
49801 + RETURN_ERROR(MAJOR, E_INVALID_HANDLE, ("Host command"));
49802 +
49803 + err = FmHcPcdCcDoDynamicChange(h_Hc,
49804 + (uint32_t)(XX_VirtToPhys(p_OldDescriptor) - p_FmPcd->physicalMuramBase),
49805 + (uint32_t)(XX_VirtToPhys(p_NewDescriptor) - p_FmPcd->physicalMuramBase));
49806 + if (err)
49807 + RETURN_ERROR(MAJOR, err, ("Dynamic change host command"));
49808 +
49809 + return E_OK;
49810 +}
49811 +
49812 +static void FillReplicAdOfTypeResult(void *p_ReplicAd, bool last)
49813 +{
49814 + t_AdOfTypeResult *p_CurrReplicAd = (t_AdOfTypeResult*)p_ReplicAd;
49815 + uint32_t tmp;
49816 +
49817 + tmp = GET_UINT32(p_CurrReplicAd->plcrProfile);
49818 + if (last)
49819 + /* clear the NL bit in case it's the last member in the group*/
49820 + WRITE_UINT32(p_CurrReplicAd->plcrProfile,(tmp & ~FRM_REPLIC_NL_BIT));
49821 + else
49822 + /* set the NL bit in case it's not the last member in the group */
49823 + WRITE_UINT32(p_CurrReplicAd->plcrProfile, (tmp |FRM_REPLIC_NL_BIT));
49824 +
49825 + /* set FR bit in the action descriptor */
49826 + tmp = GET_UINT32(p_CurrReplicAd->nia);
49827 + WRITE_UINT32(p_CurrReplicAd->nia,
49828 + (tmp | FRM_REPLIC_FR_BIT | FM_PCD_AD_RESULT_EXTENDED_MODE ));
49829 +}
49830 +
49831 +static void BuildSourceTd(void *p_Ad)
49832 +{
49833 + t_AdOfTypeContLookup *p_SourceTd;
49834 +
49835 + ASSERT_COND(p_Ad);
49836 +
49837 + p_SourceTd = (t_AdOfTypeContLookup *)p_Ad;
49838 +
49839 + IOMemSet32((uint8_t*)p_SourceTd, 0, FM_PCD_CC_AD_ENTRY_SIZE);
49840 +
49841 + /* initialize the source table descriptor */
49842 + WRITE_UINT32(p_SourceTd->ccAdBase, FM_PCD_AD_CONT_LOOKUP_TYPE);
49843 + WRITE_UINT32(p_SourceTd->pcAndOffsets, FRM_REPLIC_SOURCE_TD_OPCODE);
49844 +}
49845 +
49846 +static t_Error BuildShadowAndModifyDescriptor(t_FmPcdFrmReplicGroup *p_ReplicGroup,
49847 + t_FmPcdFrmReplicMember *p_NextMember,
49848 + t_FmPcdFrmReplicMember *p_CurrentMember,
49849 + bool sourceDescriptor,
49850 + bool last)
49851 +{
49852 + t_FmPcd *p_FmPcd;
49853 + t_FmPcdFrmReplicMember shadowMember;
49854 + t_Error err;
49855 +
49856 + ASSERT_COND(p_ReplicGroup);
49857 + ASSERT_COND(p_ReplicGroup->h_FmPcd);
49858 +
49859 + p_FmPcd = p_ReplicGroup->h_FmPcd;
49860 + ASSERT_COND(p_FmPcd->p_CcShadow);
49861 +
49862 + if (!TRY_LOCK(p_FmPcd->h_ShadowSpinlock, &p_FmPcd->shadowLock))
49863 + return ERROR_CODE(E_BUSY);
49864 +
49865 + if (sourceDescriptor)
49866 + {
49867 + BuildSourceTd(p_FmPcd->p_CcShadow);
49868 + LinkSourceToMember(p_ReplicGroup, p_FmPcd->p_CcShadow, p_NextMember);
49869 +
49870 + /* Modify the source table descriptor according to the prepared shadow descriptor */
49871 + err = ModifyDescriptor(p_ReplicGroup,
49872 + p_ReplicGroup->p_SourceTd,
49873 + p_FmPcd->p_CcShadow/* new prepared source td */);
49874 +
49875 + RELEASE_LOCK(p_FmPcd->shadowLock);
49876 + if (err)
49877 + RETURN_ERROR(MAJOR, err, ("Modify source Descriptor in BuildShadowAndModifyDescriptor"));
49878 +
49879 + }
49880 + else
49881 + {
49882 + IO2IOCpy32(p_FmPcd->p_CcShadow,
49883 + p_CurrentMember->p_MemberAd,
49884 + FM_PCD_CC_AD_ENTRY_SIZE);
49885 +
49886 + /* update the last bit in the shadow ad */
49887 + FillReplicAdOfTypeResult(p_FmPcd->p_CcShadow, last);
49888 +
49889 + shadowMember.p_MemberAd = p_FmPcd->p_CcShadow;
49890 +
49891 + /* update the next FR member index */
49892 + LinkMemberToMember(p_ReplicGroup, &shadowMember, p_NextMember);
49893 +
49894 + /* Modify the next member according to the prepared shadow descriptor */
49895 + err = ModifyDescriptor(p_ReplicGroup,
49896 + p_CurrentMember->p_MemberAd,
49897 + p_FmPcd->p_CcShadow);
49898 +
49899 + RELEASE_LOCK(p_FmPcd->shadowLock);
49900 + if (err)
49901 + RETURN_ERROR(MAJOR, err, ("Modify Descriptor in BuildShadowAndModifyDescriptor"));
49902 + }
49903 +
49904 +
49905 + return E_OK;
49906 +}
49907 +
49908 +static t_FmPcdFrmReplicMember* GetMemberByIndex(t_FmPcdFrmReplicGroup *p_ReplicGroup,
49909 + uint16_t memberIndex)
49910 +{
49911 + int i=0;
49912 + t_List *p_Pos;
49913 + t_FmPcdFrmReplicMember *p_Member = NULL;
49914 +
49915 + LIST_FOR_EACH(p_Pos, &p_ReplicGroup->membersList)
49916 + {
49917 + if (i == memberIndex)
49918 + {
49919 + p_Member = LIST_OBJECT(p_Pos, t_FmPcdFrmReplicMember, node);
49920 + return p_Member;
49921 + }
49922 + i++;
49923 + }
49924 + return p_Member;
49925 +}
49926 +
49927 +static t_Error AllocMember(t_FmPcdFrmReplicGroup *p_ReplicGroup)
49928 +{
49929 + t_FmPcdFrmReplicMember *p_CurrentMember;
49930 + t_Handle h_Muram;
49931 +
49932 + ASSERT_COND(p_ReplicGroup);
49933 +
49934 + h_Muram = FmPcdGetMuramHandle(p_ReplicGroup->h_FmPcd);
49935 + ASSERT_COND(h_Muram);
49936 +
49937 + /* Initialize an internal structure of a member to add to the available members list */
49938 + p_CurrentMember = (t_FmPcdFrmReplicMember *)XX_Malloc(sizeof(t_FmPcdFrmReplicMember));
49939 + if (!p_CurrentMember)
49940 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("Frame replicator member"));
49941 +
49942 + memset(p_CurrentMember, 0 ,sizeof(t_FmPcdFrmReplicMember));
49943 +
49944 + /* Allocate the member AD */
49945 + p_CurrentMember->p_MemberAd =
49946 + (t_AdOfTypeResult*)FM_MURAM_AllocMem(h_Muram,
49947 + FM_PCD_CC_AD_ENTRY_SIZE,
49948 + FM_PCD_CC_AD_TABLE_ALIGN);
49949 + if (!p_CurrentMember->p_MemberAd)
49950 + {
49951 + XX_Free(p_CurrentMember);
49952 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("member AD table"));
49953 + }
49954 + IOMemSet32((uint8_t*)p_CurrentMember->p_MemberAd, 0, FM_PCD_CC_AD_ENTRY_SIZE);
49955 +
49956 + /* Add the new member to the available members list */
49957 + LIST_AddToTail(&p_CurrentMember->node, &(p_ReplicGroup->availableMembersList));
49958 +
49959 + return E_OK;
49960 +}
49961 +
49962 +static t_FmPcdFrmReplicMember* InitMember(t_FmPcdFrmReplicGroup *p_ReplicGroup,
49963 + t_FmPcdCcNextEngineParams *p_MemberParams,
49964 + bool last)
49965 +{
49966 + t_FmPcdFrmReplicMember *p_CurrentMember = NULL;
49967 +
49968 + ASSERT_COND(p_ReplicGroup);
49969 +
49970 + /* Get an available member from the internal members list */
49971 + p_CurrentMember = GetAvailableMember(p_ReplicGroup);
49972 + if (!p_CurrentMember)
49973 + {
49974 + REPORT_ERROR(MAJOR, E_NOT_FOUND, ("Available member"));
49975 + return NULL;
49976 + }
49977 + p_CurrentMember->h_Manip = NULL;
49978 +
49979 + /* clear the Ad of the new member */
49980 + IOMemSet32((uint8_t*)p_CurrentMember->p_MemberAd, 0, FM_PCD_CC_AD_ENTRY_SIZE);
49981 +
49982 + INIT_LIST(&p_CurrentMember->node);
49983 +
49984 + /* Initialize the Ad of the member */
49985 + NextStepAd(p_CurrentMember->p_MemberAd,
49986 + NULL,
49987 + p_MemberParams,
49988 + p_ReplicGroup->h_FmPcd);
49989 +
49990 + /* save Manip handle (for free needs) */
49991 + if (p_MemberParams->h_Manip)
49992 + p_CurrentMember->h_Manip = p_MemberParams->h_Manip;
49993 +
49994 + /* Initialize the relevant frame replicator fields in the AD */
49995 + FillReplicAdOfTypeResult(p_CurrentMember->p_MemberAd, last);
49996 +
49997 + return p_CurrentMember;
49998 +}
49999 +
50000 +static void FreeMember(t_FmPcdFrmReplicGroup *p_ReplicGroup,
50001 + t_FmPcdFrmReplicMember *p_Member)
50002 +{
50003 + /* Note: Can't free the member AD just returns the member to the available
50004 + member list - therefore only memset the AD */
50005 +
50006 + /* zero the AD */
50007 + IOMemSet32(p_Member->p_MemberAd, 0, FM_PCD_CC_AD_ENTRY_SIZE);
50008 +
50009 +
50010 + /* return the member to the available members list */
50011 + PutAvailableMember(p_ReplicGroup, p_Member);
50012 +}
50013 +
50014 +static t_Error RemoveMember(t_FmPcdFrmReplicGroup *p_ReplicGroup,
50015 + uint16_t memberIndex)
50016 +{
50017 + t_FmPcd *p_FmPcd = NULL;
50018 + t_FmPcdFrmReplicMember *p_CurrentMember = NULL, *p_PreviousMember = NULL, *p_NextMember = NULL;
50019 + t_Error err;
50020 + uint8_t memberPosition;
50021 +
50022 + p_FmPcd = p_ReplicGroup->h_FmPcd;
50023 + ASSERT_COND(p_FmPcd);
50024 + UNUSED(p_FmPcd);
50025 +
50026 + p_CurrentMember = GetMemberByIndex(p_ReplicGroup, memberIndex);
50027 + ASSERT_COND(p_CurrentMember);
50028 +
50029 + /* determine the member position in the group */
50030 + memberPosition = GetMemberPosition(p_ReplicGroup,
50031 + memberIndex,
50032 + FALSE/*remove operation*/);
50033 +
50034 + switch (memberPosition)
50035 + {
50036 + case FRM_REPLIC_FIRST_MEMBER_INDEX:
50037 + p_NextMember = GetMemberByIndex(p_ReplicGroup, (uint16_t)(memberIndex+1));
50038 + ASSERT_COND(p_NextMember);
50039 +
50040 + /* update the source td itself by using a host command */
50041 + err = BuildShadowAndModifyDescriptor(p_ReplicGroup,
50042 + p_NextMember,
50043 + NULL,
50044 + TRUE/*sourceDescriptor*/,
50045 + FALSE/*last*/);
50046 + break;
50047 +
50048 + case FRM_REPLIC_MIDDLE_MEMBER_INDEX:
50049 + p_PreviousMember = GetMemberByIndex(p_ReplicGroup, (uint16_t)(memberIndex-1));
50050 + ASSERT_COND(p_PreviousMember);
50051 +
50052 + p_NextMember = GetMemberByIndex(p_ReplicGroup, (uint16_t)(memberIndex+1));
50053 + ASSERT_COND(p_NextMember);
50054 +
50055 + err = BuildShadowAndModifyDescriptor(p_ReplicGroup,
50056 + p_NextMember,
50057 + p_PreviousMember,
50058 + FALSE/*sourceDescriptor*/,
50059 + FALSE/*last*/);
50060 +
50061 + break;
50062 +
50063 + case FRM_REPLIC_LAST_MEMBER_INDEX:
50064 + p_PreviousMember = GetMemberByIndex(p_ReplicGroup, (uint16_t)(memberIndex-1));
50065 + ASSERT_COND(p_PreviousMember);
50066 +
50067 + err = BuildShadowAndModifyDescriptor(p_ReplicGroup,
50068 + NULL,
50069 + p_PreviousMember,
50070 + FALSE/*sourceDescriptor*/,
50071 + TRUE/*last*/);
50072 + break;
50073 +
50074 + default:
50075 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION, ("member position in remove member"));
50076 + }
50077 +
50078 + if (err)
50079 + RETURN_ERROR(MAJOR, err, NO_MSG);
50080 +
50081 + if (p_CurrentMember->h_Manip)
50082 + {
50083 + FmPcdManipUpdateOwner(p_CurrentMember->h_Manip, FALSE);
50084 + p_CurrentMember->h_Manip = NULL;
50085 + }
50086 +
50087 + /* remove the member from the driver internal members list */
50088 + RemoveMemberFromList(p_ReplicGroup, p_CurrentMember);
50089 +
50090 + /* return the member to the available members list */
50091 + FreeMember(p_ReplicGroup, p_CurrentMember);
50092 +
50093 + return E_OK;
50094 +}
50095 +
50096 +static void DeleteGroup(t_FmPcdFrmReplicGroup *p_ReplicGroup)
50097 +{
50098 + int i, j;
50099 + t_Handle h_Muram;
50100 + t_FmPcdFrmReplicMember *p_Member, *p_CurrentMember;
50101 +
50102 + if (p_ReplicGroup)
50103 + {
50104 + ASSERT_COND(p_ReplicGroup->h_FmPcd);
50105 + h_Muram = FmPcdGetMuramHandle(p_ReplicGroup->h_FmPcd);
50106 + ASSERT_COND(h_Muram);
50107 +
50108 + /* free the source table descriptor */
50109 + if (p_ReplicGroup->p_SourceTd)
50110 + {
50111 + FM_MURAM_FreeMem(h_Muram, p_ReplicGroup->p_SourceTd);
50112 + p_ReplicGroup->p_SourceTd = NULL;
50113 + }
50114 +
50115 + /* Remove all members from the members linked list (hw and sw) and
50116 + return the members to the available members list */
50117 + if (p_ReplicGroup->numOfEntries)
50118 + {
50119 + j = p_ReplicGroup->numOfEntries-1;
50120 +
50121 + /* manually removal of the member because there are no owners of
50122 + this group */
50123 + for (i=j; i>=0; i--)
50124 + {
50125 + p_CurrentMember = GetMemberByIndex(p_ReplicGroup, (uint16_t)i/*memberIndex*/);
50126 + ASSERT_COND(p_CurrentMember);
50127 +
50128 + if (p_CurrentMember->h_Manip)
50129 + {
50130 + FmPcdManipUpdateOwner(p_CurrentMember->h_Manip, FALSE);
50131 + p_CurrentMember->h_Manip = NULL;
50132 + }
50133 +
50134 + /* remove the member from the internal driver members list */
50135 + RemoveMemberFromList(p_ReplicGroup, p_CurrentMember);
50136 +
50137 + /* return the member to the available members list */
50138 + FreeMember(p_ReplicGroup, p_CurrentMember);
50139 + }
50140 + }
50141 +
50142 + /* Free members AD */
50143 + for (i=0; i<p_ReplicGroup->maxNumOfEntries; i++)
50144 + {
50145 + p_Member = GetAvailableMember(p_ReplicGroup);
50146 + ASSERT_COND(p_Member);
50147 + if (p_Member->p_MemberAd)
50148 + {
50149 + FM_MURAM_FreeMem(h_Muram, p_Member->p_MemberAd);
50150 + p_Member->p_MemberAd = NULL;
50151 + }
50152 + XX_Free(p_Member);
50153 + }
50154 +
50155 + /* release the group lock */
50156 + if (p_ReplicGroup->p_Lock)
50157 + FmPcdReleaseLock(p_ReplicGroup->h_FmPcd, p_ReplicGroup->p_Lock);
50158 +
50159 + /* free the replicator group */
50160 + XX_Free(p_ReplicGroup);
50161 + }
50162 +}
50163 +
50164 +
50165 +/*****************************************************************************/
50166 +/* Inter-module API routines */
50167 +/*****************************************************************************/
50168 +
50169 +/* NOTE: the inter-module routines are locked by cc in case of using them */
50170 +void * FrmReplicGroupGetSourceTableDescriptor(t_Handle h_ReplicGroup)
50171 +{
50172 + t_FmPcdFrmReplicGroup *p_ReplicGroup = (t_FmPcdFrmReplicGroup *)h_ReplicGroup;
50173 + ASSERT_COND(p_ReplicGroup);
50174 +
50175 + return (p_ReplicGroup->p_SourceTd);
50176 +}
50177 +
50178 +void FrmReplicGroupUpdateAd(t_Handle h_ReplicGroup,
50179 + void *p_Ad,
50180 + t_Handle *h_AdNew)
50181 +{
50182 + t_FmPcdFrmReplicGroup *p_ReplicGroup = (t_FmPcdFrmReplicGroup *)h_ReplicGroup;
50183 + t_AdOfTypeResult *p_AdResult = (t_AdOfTypeResult*)p_Ad;
50184 + t_FmPcd *p_FmPcd;
50185 +
50186 + ASSERT_COND(p_ReplicGroup);
50187 + p_FmPcd = p_ReplicGroup->h_FmPcd;
50188 +
50189 + /* build a bypass ad */
50190 + WRITE_UINT32(p_AdResult->fqid, FM_PCD_AD_BYPASS_TYPE |
50191 + (uint32_t)((XX_VirtToPhys(p_ReplicGroup->p_SourceTd)) - p_FmPcd->physicalMuramBase));
50192 +
50193 + *h_AdNew = NULL;
50194 +}
50195 +
50196 +void FrmReplicGroupUpdateOwner(t_Handle h_ReplicGroup,
50197 + bool add)
50198 +{
50199 + t_FmPcdFrmReplicGroup *p_ReplicGroup = (t_FmPcdFrmReplicGroup *)h_ReplicGroup;
50200 + ASSERT_COND(p_ReplicGroup);
50201 +
50202 + /* update the group owner counter */
50203 + if (add)
50204 + p_ReplicGroup->owners++;
50205 + else
50206 + {
50207 + ASSERT_COND(p_ReplicGroup->owners);
50208 + p_ReplicGroup->owners--;
50209 + }
50210 +}
50211 +
50212 +t_Error FrmReplicGroupTryLock(t_Handle h_ReplicGroup)
50213 +{
50214 + t_FmPcdFrmReplicGroup *p_ReplicGroup = (t_FmPcdFrmReplicGroup *)h_ReplicGroup;
50215 +
50216 + ASSERT_COND(h_ReplicGroup);
50217 +
50218 + if (FmPcdLockTryLock(p_ReplicGroup->p_Lock))
50219 + return E_OK;
50220 +
50221 + return ERROR_CODE(E_BUSY);
50222 +}
50223 +
50224 +void FrmReplicGroupUnlock(t_Handle h_ReplicGroup)
50225 +{
50226 + t_FmPcdFrmReplicGroup *p_ReplicGroup = (t_FmPcdFrmReplicGroup *)h_ReplicGroup;
50227 +
50228 + ASSERT_COND(h_ReplicGroup);
50229 +
50230 + FmPcdLockUnlock(p_ReplicGroup->p_Lock);
50231 +}
50232 +/*********************** End of inter-module routines ************************/
50233 +
50234 +
50235 +/****************************************/
50236 +/* API Init unit functions */
50237 +/****************************************/
50238 +t_Handle FM_PCD_FrmReplicSetGroup(t_Handle h_FmPcd,
50239 + t_FmPcdFrmReplicGroupParams *p_ReplicGroupParam)
50240 +{
50241 + t_FmPcdFrmReplicGroup *p_ReplicGroup;
50242 + t_FmPcdFrmReplicMember *p_CurrentMember, *p_NextMember = NULL;
50243 + int i;
50244 + t_Error err;
50245 + bool last = FALSE;
50246 + t_Handle h_Muram;
50247 +
50248 + SANITY_CHECK_RETURN_VALUE(h_FmPcd, E_INVALID_HANDLE, NULL);
50249 + SANITY_CHECK_RETURN_VALUE(p_ReplicGroupParam, E_INVALID_HANDLE, NULL);
50250 +
50251 + if (!FmPcdIsAdvancedOffloadSupported(h_FmPcd))
50252 + {
50253 + REPORT_ERROR(MAJOR, E_INVALID_STATE, ("Advanced-offload must be enabled"));
50254 + return NULL;
50255 + }
50256 +
50257 + err = CheckParams(h_FmPcd, p_ReplicGroupParam);
50258 + if (err)
50259 + {
50260 + REPORT_ERROR(MAJOR, err, (NO_MSG));
50261 + return NULL;
50262 + }
50263 +
50264 + p_ReplicGroup = (t_FmPcdFrmReplicGroup*)XX_Malloc(sizeof(t_FmPcdFrmReplicGroup));
50265 + if (!p_ReplicGroup)
50266 + {
50267 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("No memory"));
50268 + return NULL;
50269 + }
50270 + memset(p_ReplicGroup, 0, sizeof(t_FmPcdFrmReplicGroup));
50271 +
50272 + /* initialize lists for internal driver use */
50273 + INIT_LIST(&p_ReplicGroup->availableMembersList);
50274 + INIT_LIST(&p_ReplicGroup->membersList);
50275 +
50276 + p_ReplicGroup->h_FmPcd = h_FmPcd;
50277 +
50278 + h_Muram = FmPcdGetMuramHandle(p_ReplicGroup->h_FmPcd);
50279 + ASSERT_COND(h_Muram);
50280 +
50281 + /* initialize the group lock */
50282 + p_ReplicGroup->p_Lock = FmPcdAcquireLock(p_ReplicGroup->h_FmPcd);
50283 + if (!p_ReplicGroup->p_Lock)
50284 + {
50285 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("Replic group lock"));
50286 + DeleteGroup(p_ReplicGroup);
50287 + return NULL;
50288 + }
50289 +
50290 + /* Allocate the frame replicator source table descriptor */
50291 + p_ReplicGroup->p_SourceTd =
50292 + (t_Handle)FM_MURAM_AllocMem(h_Muram,
50293 + FM_PCD_CC_AD_ENTRY_SIZE,
50294 + FM_PCD_CC_AD_TABLE_ALIGN);
50295 + if (!p_ReplicGroup->p_SourceTd)
50296 + {
50297 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("frame replicator source table descriptor"));
50298 + DeleteGroup(p_ReplicGroup);
50299 + return NULL;
50300 + }
50301 +
50302 + /* update the shadow size - required for the host commands */
50303 + err = FmPcdUpdateCcShadow(p_ReplicGroup->h_FmPcd,
50304 + FM_PCD_CC_AD_ENTRY_SIZE,
50305 + FM_PCD_CC_AD_TABLE_ALIGN);
50306 + if (err)
50307 + {
50308 + REPORT_ERROR(MAJOR, err, ("Update CC shadow"));
50309 + DeleteGroup(p_ReplicGroup);
50310 + return NULL;
50311 + }
50312 +
50313 + p_ReplicGroup->maxNumOfEntries = p_ReplicGroupParam->maxNumOfEntries;
50314 +
50315 + /* Allocate the maximal number of members ADs and Statistics AD for the group
50316 + It prevents allocation of Muram in run-time */
50317 + for (i=0; i<p_ReplicGroup->maxNumOfEntries; i++)
50318 + {
50319 + err = AllocMember(p_ReplicGroup);
50320 + if (err)
50321 + {
50322 + REPORT_ERROR(MAJOR, err, ("allocate a new member"));
50323 + DeleteGroup(p_ReplicGroup);
50324 + return NULL;
50325 + }
50326 + }
50327 +
50328 + /* Initialize the members linked lists:
50329 + (hw - the one that is used by the FMan controller and
50330 + sw - the one that is managed by the driver internally) */
50331 + for (i=(p_ReplicGroupParam->numOfEntries-1); i>=0; i--)
50332 + {
50333 + /* check if this is the last member in the group */
50334 + if (i == (p_ReplicGroupParam->numOfEntries-1))
50335 + last = TRUE;
50336 + else
50337 + last = FALSE;
50338 +
50339 + /* Initialize a new member */
50340 + p_CurrentMember = InitMember(p_ReplicGroup,
50341 + &(p_ReplicGroupParam->nextEngineParams[i]),
50342 + last);
50343 + if (!p_CurrentMember)
50344 + {
50345 + REPORT_ERROR(MAJOR, E_INVALID_HANDLE, ("No available member"));
50346 + DeleteGroup(p_ReplicGroup);
50347 + return NULL;
50348 + }
50349 +
50350 + /* Build the members group - link two consecutive members in the hw linked list */
50351 + LinkMemberToMember(p_ReplicGroup, p_CurrentMember, p_NextMember);
50352 +
50353 + /* update the driver internal members list to be compatible to the hw members linked list */
50354 + AddMemberToList(p_ReplicGroup, p_CurrentMember, &p_ReplicGroup->membersList);
50355 +
50356 + p_NextMember = p_CurrentMember;
50357 + }
50358 +
50359 + /* initialize the source table descriptor */
50360 + BuildSourceTd(p_ReplicGroup->p_SourceTd);
50361 +
50362 + /* link the source table descriptor to point to the first member in the group */
50363 + LinkSourceToMember(p_ReplicGroup, p_ReplicGroup->p_SourceTd, p_NextMember);
50364 +
50365 + return p_ReplicGroup;
50366 +}
50367 +
50368 +t_Error FM_PCD_FrmReplicDeleteGroup(t_Handle h_ReplicGroup)
50369 +{
50370 + t_FmPcdFrmReplicGroup *p_ReplicGroup = (t_FmPcdFrmReplicGroup *)h_ReplicGroup;
50371 +
50372 + SANITY_CHECK_RETURN_ERROR(p_ReplicGroup, E_INVALID_HANDLE);
50373 +
50374 + if (p_ReplicGroup->owners)
50375 + RETURN_ERROR(MAJOR,
50376 + E_INVALID_STATE,
50377 + ("the group has owners and can't be deleted"));
50378 +
50379 + DeleteGroup(p_ReplicGroup);
50380 +
50381 + return E_OK;
50382 +}
50383 +
50384 +
50385 +/*****************************************************************************/
50386 +/* API Run-time Frame replicator Control unit functions */
50387 +/*****************************************************************************/
50388 +t_Error FM_PCD_FrmReplicAddMember(t_Handle h_ReplicGroup,
50389 + uint16_t memberIndex,
50390 + t_FmPcdCcNextEngineParams *p_MemberParams)
50391 +{
50392 + t_FmPcdFrmReplicGroup *p_ReplicGroup = (t_FmPcdFrmReplicGroup*) h_ReplicGroup;
50393 + t_FmPcdFrmReplicMember *p_NewMember, *p_CurrentMember = NULL, *p_PreviousMember = NULL;
50394 + t_Error err;
50395 + uint8_t memberPosition;
50396 +
50397 + SANITY_CHECK_RETURN_ERROR(p_ReplicGroup, E_INVALID_HANDLE);
50398 + SANITY_CHECK_RETURN_ERROR(p_MemberParams, E_INVALID_HANDLE);
50399 +
50400 + /* group lock */
50401 + err = FrmReplicGroupTryLock(p_ReplicGroup);
50402 + if (GET_ERROR_TYPE(err) == E_BUSY)
50403 + return ERROR_CODE(E_BUSY);
50404 +
50405 + if (memberIndex > p_ReplicGroup->numOfEntries)
50406 + {
50407 + /* unlock */
50408 + FrmReplicGroupUnlock(p_ReplicGroup);
50409 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION,
50410 + ("memberIndex is greater than the members in the list"));
50411 + }
50412 +
50413 + if (memberIndex >= p_ReplicGroup->maxNumOfEntries)
50414 + {
50415 + /* unlock */
50416 + FrmReplicGroupUnlock(p_ReplicGroup);
50417 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION, ("memberIndex is greater than the allowed number of members in the group"));
50418 + }
50419 +
50420 + if ((p_ReplicGroup->numOfEntries + 1) > FM_PCD_FRM_REPLIC_MAX_NUM_OF_ENTRIES)
50421 + {
50422 + /* unlock */
50423 + FrmReplicGroupUnlock(p_ReplicGroup);
50424 + RETURN_ERROR(MAJOR, E_INVALID_VALUE,
50425 + ("numOfEntries with new entry can not be larger than %d\n",
50426 + FM_PCD_FRM_REPLIC_MAX_NUM_OF_ENTRIES));
50427 + }
50428 +
50429 + err = MemberCheckParams(p_ReplicGroup->h_FmPcd, p_MemberParams);
50430 + if (err)
50431 + {
50432 + /* unlock */
50433 + FrmReplicGroupUnlock(p_ReplicGroup);
50434 + RETURN_ERROR(MAJOR, err, ("member check parameters in add operation"));
50435 + }
50436 + /* determine the member position in the group */
50437 + memberPosition = GetMemberPosition(p_ReplicGroup,
50438 + memberIndex,
50439 + TRUE/* add operation */);
50440 +
50441 + /* Initialize a new member */
50442 + p_NewMember = InitMember(p_ReplicGroup,
50443 + p_MemberParams,
50444 + (memberPosition == FRM_REPLIC_LAST_MEMBER_INDEX ? TRUE : FALSE));
50445 + if (!p_NewMember)
50446 + {
50447 + /* unlock */
50448 + FrmReplicGroupUnlock(p_ReplicGroup);
50449 + RETURN_ERROR(MAJOR, E_INVALID_HANDLE, ("No available member"));
50450 + }
50451 +
50452 + switch (memberPosition)
50453 + {
50454 + case FRM_REPLIC_FIRST_MEMBER_INDEX:
50455 + p_CurrentMember = GetMemberByIndex(p_ReplicGroup, memberIndex);
50456 + ASSERT_COND(p_CurrentMember);
50457 +
50458 + LinkMemberToMember(p_ReplicGroup, p_NewMember, p_CurrentMember);
50459 +
50460 + /* update the internal group source TD */
50461 + LinkSourceToMember(p_ReplicGroup,
50462 + p_ReplicGroup->p_SourceTd,
50463 + p_NewMember);
50464 +
50465 + /* add member to the internal sw member list */
50466 + AddMemberToList(p_ReplicGroup,
50467 + p_NewMember,
50468 + &p_ReplicGroup->membersList);
50469 + break;
50470 +
50471 + case FRM_REPLIC_MIDDLE_MEMBER_INDEX:
50472 + p_CurrentMember = GetMemberByIndex(p_ReplicGroup, memberIndex);
50473 + ASSERT_COND(p_CurrentMember);
50474 +
50475 + p_PreviousMember = GetMemberByIndex(p_ReplicGroup, (uint16_t)(memberIndex-1));
50476 + ASSERT_COND(p_PreviousMember);
50477 +
50478 + LinkMemberToMember(p_ReplicGroup, p_NewMember, p_CurrentMember);
50479 + LinkMemberToMember(p_ReplicGroup, p_PreviousMember, p_NewMember);
50480 +
50481 + AddMemberToList(p_ReplicGroup, p_NewMember, &p_PreviousMember->node);
50482 + break;
50483 +
50484 + case FRM_REPLIC_LAST_MEMBER_INDEX:
50485 + p_PreviousMember = GetMemberByIndex(p_ReplicGroup, (uint16_t)(memberIndex-1));
50486 + ASSERT_COND(p_PreviousMember);
50487 +
50488 + LinkMemberToMember(p_ReplicGroup, p_PreviousMember, p_NewMember);
50489 + FillReplicAdOfTypeResult(p_PreviousMember->p_MemberAd, FALSE/*last*/);
50490 +
50491 + /* add the new member to the internal sw member list */
50492 + AddMemberToList(p_ReplicGroup, p_NewMember, &p_PreviousMember->node);
50493 + break;
50494 +
50495 + default:
50496 + /* unlock */
50497 + FrmReplicGroupUnlock(p_ReplicGroup);
50498 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION, ("member position in add member"));
50499 +
50500 + }
50501 +
50502 + /* unlock */
50503 + FrmReplicGroupUnlock(p_ReplicGroup);
50504 +
50505 + return E_OK;
50506 +}
50507 +
50508 +t_Error FM_PCD_FrmReplicRemoveMember(t_Handle h_ReplicGroup,
50509 + uint16_t memberIndex)
50510 +{
50511 + t_FmPcdFrmReplicGroup *p_ReplicGroup = (t_FmPcdFrmReplicGroup*) h_ReplicGroup;
50512 + t_Error err;
50513 +
50514 + SANITY_CHECK_RETURN_ERROR(p_ReplicGroup, E_INVALID_HANDLE);
50515 +
50516 + /* lock */
50517 + err = FrmReplicGroupTryLock(p_ReplicGroup);
50518 + if (GET_ERROR_TYPE(err) == E_BUSY)
50519 + return ERROR_CODE(E_BUSY);
50520 +
50521 + if (memberIndex >= p_ReplicGroup->numOfEntries)
50522 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION, ("member index to remove"));
50523 +
50524 + /* Design decision: group must contain at least one member
50525 + No possibility to remove the last member from the group */
50526 + if (p_ReplicGroup->numOfEntries == 1)
50527 + RETURN_ERROR(MAJOR, E_CONFLICT, ("Can't remove the last member. At least one member should be related to a group."));
50528 +
50529 + err = RemoveMember(p_ReplicGroup, memberIndex);
50530 +
50531 + /* unlock */
50532 + FrmReplicGroupUnlock(p_ReplicGroup);
50533 +
50534 + switch (GET_ERROR_TYPE(err))
50535 + {
50536 + case E_OK:
50537 + return E_OK;
50538 +
50539 + case E_BUSY:
50540 + DBG(TRACE, ("E_BUSY error"));
50541 + return ERROR_CODE(E_BUSY);
50542 +
50543 + default:
50544 + RETURN_ERROR(MAJOR, err, NO_MSG);
50545 + }
50546 +}
50547 +
50548 +/*********************** End of API routines ************************/
50549 +
50550 +
50551 --- /dev/null
50552 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/fm_replic.h
50553 @@ -0,0 +1,101 @@
50554 +/*
50555 + * Copyright 2008-2012 Freescale Semiconductor Inc.
50556 + *
50557 + * Redistribution and use in source and binary forms, with or without
50558 + * modification, are permitted provided that the following conditions are met:
50559 + * * Redistributions of source code must retain the above copyright
50560 + * notice, this list of conditions and the following disclaimer.
50561 + * * Redistributions in binary form must reproduce the above copyright
50562 + * notice, this list of conditions and the following disclaimer in the
50563 + * documentation and/or other materials provided with the distribution.
50564 + * * Neither the name of Freescale Semiconductor nor the
50565 + * names of its contributors may be used to endorse or promote products
50566 + * derived from this software without specific prior written permission.
50567 + *
50568 + *
50569 + * ALTERNATIVELY, this software may be distributed under the terms of the
50570 + * GNU General Public License ("GPL") as published by the Free Software
50571 + * Foundation, either version 2 of that License or (at your option) any
50572 + * later version.
50573 + *
50574 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
50575 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
50576 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
50577 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
50578 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
50579 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
50580 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
50581 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
50582 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
50583 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
50584 + */
50585 +
50586 +
50587 +/******************************************************************************
50588 + @File fm_replic.h
50589 +
50590 + @Description FM frame replicator
50591 +*//***************************************************************************/
50592 +#ifndef __FM_REPLIC_H
50593 +#define __FM_REPLIC_H
50594 +
50595 +#include "std_ext.h"
50596 +#include "error_ext.h"
50597 +
50598 +
50599 +#define FRM_REPLIC_SOURCE_TD_OPCODE 0x75
50600 +#define NEXT_FRM_REPLIC_ADDR_SHIFT 4
50601 +#define NEXT_FRM_REPLIC_MEMBER_INDEX_SHIFT 16
50602 +#define FRM_REPLIC_FR_BIT 0x08000000
50603 +#define FRM_REPLIC_NL_BIT 0x10000000
50604 +#define FRM_REPLIC_INVALID_MEMBER_INDEX 0xffff
50605 +#define FRM_REPLIC_FIRST_MEMBER_INDEX 0
50606 +
50607 +#define FRM_REPLIC_MIDDLE_MEMBER_INDEX 1
50608 +#define FRM_REPLIC_LAST_MEMBER_INDEX 2
50609 +
50610 +#define SOURCE_TD_ITSELF_OPTION 0x01
50611 +#define SOURCE_TD_COPY_OPTION 0x02
50612 +#define SOURCE_TD_ITSELF_AND_COPY_OPTION SOURCE_TD_ITSELF_OPTION | SOURCE_TD_COPY_OPTION
50613 +#define SOURCE_TD_NONE 0x04
50614 +
50615 +/*typedef enum e_SourceTdOption
50616 +{
50617 + e_SOURCE_TD_NONE = 0,
50618 + e_SOURCE_TD_ITSELF_OPTION = 1,
50619 + e_SOURCE_TD_COPY_OPTION = 2,
50620 + e_SOURCE_TD_ITSELF_AND_COPY_OPTION = e_SOURCE_TD_ITSELF_OPTION | e_SOURCE_TD_COPY_OPTION
50621 +} e_SourceTdOption;
50622 +*/
50623 +
50624 +typedef struct
50625 +{
50626 + volatile uint32_t type;
50627 + volatile uint32_t frGroupPointer;
50628 + volatile uint32_t operationCode;
50629 + volatile uint32_t reserved;
50630 +} t_FrmReplicGroupSourceAd;
50631 +
50632 +typedef struct t_FmPcdFrmReplicMember
50633 +{
50634 + void *p_MemberAd; /**< pointer to the member AD */
50635 + void *p_StatisticsAd;/**< pointer to the statistics AD of the member */
50636 + t_Handle h_Manip; /**< manip handle - need for free routines */
50637 + t_List node;
50638 +} t_FmPcdFrmReplicMember;
50639 +
50640 +typedef struct t_FmPcdFrmReplicGroup
50641 +{
50642 + t_Handle h_FmPcd;
50643 +
50644 + uint8_t maxNumOfEntries;/**< maximal number of members in the group */
50645 + uint8_t numOfEntries; /**< actual number of members in the group */
50646 + uint16_t owners; /**< how many keys share this frame replicator group */
50647 + void *p_SourceTd; /**< pointer to the frame replicator source table descriptor */
50648 + t_List membersList; /**< the members list - should reflect the order of the members as in the hw linked list*/
50649 + t_List availableMembersList;/**< list of all the available members in the group */
50650 + t_FmPcdLock *p_Lock;
50651 +} t_FmPcdFrmReplicGroup;
50652 +
50653 +
50654 +#endif /* __FM_REPLIC_H */
50655 --- /dev/null
50656 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/fman_kg.c
50657 @@ -0,0 +1,888 @@
50658 +/*
50659 + * Copyright 2008-2012 Freescale Semiconductor Inc.
50660 + *
50661 + * Redistribution and use in source and binary forms, with or without
50662 + * modification, are permitted provided that the following conditions are met:
50663 + * * Redistributions of source code must retain the above copyright
50664 + * notice, this list of conditions and the following disclaimer.
50665 + * * Redistributions in binary form must reproduce the above copyright
50666 + * notice, this list of conditions and the following disclaimer in the
50667 + * documentation and/or other materials provided with the distribution.
50668 + * * Neither the name of Freescale Semiconductor nor the
50669 + * names of its contributors may be used to endorse or promote products
50670 + * derived from this software without specific prior written permission.
50671 + *
50672 + *
50673 + * ALTERNATIVELY, this software may be distributed under the terms of the
50674 + * GNU General Public License ("GPL") as published by the Free Software
50675 + * Foundation, either version 2 of that License or (at your option) any
50676 + * later version.
50677 + *
50678 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
50679 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
50680 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
50681 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
50682 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
50683 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
50684 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
50685 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
50686 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
50687 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
50688 + */
50689 +
50690 +#include "fsl_fman_kg.h"
50691 +
50692 +/****************************************/
50693 +/* static functions */
50694 +/****************************************/
50695 +
50696 +
50697 +static uint32_t build_ar_bind_scheme(uint8_t hwport_id, bool write)
50698 +{
50699 + uint32_t rw;
50700 +
50701 + rw = write ? (uint32_t)FM_KG_KGAR_WRITE : (uint32_t)FM_KG_KGAR_READ;
50702 +
50703 + return (uint32_t)(FM_KG_KGAR_GO |
50704 + rw |
50705 + FM_PCD_KG_KGAR_SEL_PORT_ENTRY |
50706 + hwport_id |
50707 + FM_PCD_KG_KGAR_SEL_PORT_WSEL_SP);
50708 +}
50709 +
50710 +static void clear_pe_all_scheme(struct fman_kg_regs *regs, uint8_t hwport_id)
50711 +{
50712 + uint32_t ar;
50713 +
50714 + fman_kg_write_sp(regs, 0xffffffff, 0);
50715 +
50716 + ar = build_ar_bind_scheme(hwport_id, TRUE);
50717 + fman_kg_write_ar_wait(regs, ar);
50718 +}
50719 +
50720 +static uint32_t build_ar_bind_cls_plan(uint8_t hwport_id, bool write)
50721 +{
50722 + uint32_t rw;
50723 +
50724 + rw = write ? (uint32_t)FM_KG_KGAR_WRITE : (uint32_t)FM_KG_KGAR_READ;
50725 +
50726 + return (uint32_t)(FM_KG_KGAR_GO |
50727 + rw |
50728 + FM_PCD_KG_KGAR_SEL_PORT_ENTRY |
50729 + hwport_id |
50730 + FM_PCD_KG_KGAR_SEL_PORT_WSEL_CPP);
50731 +}
50732 +
50733 +static void clear_pe_all_cls_plan(struct fman_kg_regs *regs, uint8_t hwport_id)
50734 +{
50735 + uint32_t ar;
50736 +
50737 + fman_kg_write_cpp(regs, 0);
50738 +
50739 + ar = build_ar_bind_cls_plan(hwport_id, TRUE);
50740 + fman_kg_write_ar_wait(regs, ar);
50741 +}
50742 +
50743 +static uint8_t get_gen_ht_code(enum fman_kg_gen_extract_src src,
50744 + bool no_validation,
50745 + uint8_t *offset)
50746 +{
50747 + int code;
50748 +
50749 + switch (src) {
50750 + case E_FMAN_KG_GEN_EXTRACT_ETH:
50751 + code = no_validation ? 0x73 : 0x3;
50752 + break;
50753 +
50754 + case E_FMAN_KG_GEN_EXTRACT_ETYPE:
50755 + code = no_validation ? 0x77 : 0x7;
50756 + break;
50757 +
50758 + case E_FMAN_KG_GEN_EXTRACT_SNAP:
50759 + code = no_validation ? 0x74 : 0x4;
50760 + break;
50761 +
50762 + case E_FMAN_KG_GEN_EXTRACT_VLAN_TCI_1:
50763 + code = no_validation ? 0x75 : 0x5;
50764 + break;
50765 +
50766 + case E_FMAN_KG_GEN_EXTRACT_VLAN_TCI_N:
50767 + code = no_validation ? 0x76 : 0x6;
50768 + break;
50769 +
50770 + case E_FMAN_KG_GEN_EXTRACT_PPPoE:
50771 + code = no_validation ? 0x78 : 0x8;
50772 + break;
50773 +
50774 + case E_FMAN_KG_GEN_EXTRACT_MPLS_1:
50775 + code = no_validation ? 0x79 : 0x9;
50776 + break;
50777 +
50778 + case E_FMAN_KG_GEN_EXTRACT_MPLS_2:
50779 + code = no_validation ? FM_KG_SCH_GEN_HT_INVALID : 0x19;
50780 + break;
50781 +
50782 + case E_FMAN_KG_GEN_EXTRACT_MPLS_3:
50783 + code = no_validation ? FM_KG_SCH_GEN_HT_INVALID : 0x29;
50784 + break;
50785 +
50786 + case E_FMAN_KG_GEN_EXTRACT_MPLS_N:
50787 + code = no_validation ? 0x7a : 0xa;
50788 + break;
50789 +
50790 + case E_FMAN_KG_GEN_EXTRACT_IPv4_1:
50791 + code = no_validation ? 0x7b : 0xb;
50792 + break;
50793 +
50794 + case E_FMAN_KG_GEN_EXTRACT_IPv6_1:
50795 + code = no_validation ? 0x7b : 0x1b;
50796 + break;
50797 +
50798 + case E_FMAN_KG_GEN_EXTRACT_IPv4_2:
50799 + code = no_validation ? 0x7c : 0xc;
50800 + break;
50801 +
50802 + case E_FMAN_KG_GEN_EXTRACT_IPv6_2:
50803 + code = no_validation ? 0x7c : 0x1c;
50804 + break;
50805 +
50806 + case E_FMAN_KG_GEN_EXTRACT_MINENCAP:
50807 + code = no_validation ? 0x7c : 0x2c;
50808 + break;
50809 +
50810 + case E_FMAN_KG_GEN_EXTRACT_IP_PID:
50811 + code = no_validation ? 0x72 : 0x2;
50812 + break;
50813 +
50814 + case E_FMAN_KG_GEN_EXTRACT_GRE:
50815 + code = no_validation ? 0x7d : 0xd;
50816 + break;
50817 +
50818 + case E_FMAN_KG_GEN_EXTRACT_TCP:
50819 + code = no_validation ? 0x7e : 0xe;
50820 + break;
50821 +
50822 + case E_FMAN_KG_GEN_EXTRACT_UDP:
50823 + code = no_validation ? 0x7e : 0x1e;
50824 + break;
50825 +
50826 + case E_FMAN_KG_GEN_EXTRACT_SCTP:
50827 + code = no_validation ? 0x7e : 0x3e;
50828 + break;
50829 +
50830 + case E_FMAN_KG_GEN_EXTRACT_DCCP:
50831 + code = no_validation ? 0x7e : 0x4e;
50832 + break;
50833 +
50834 + case E_FMAN_KG_GEN_EXTRACT_IPSEC_AH:
50835 + code = no_validation ? 0x7e : 0x2e;
50836 + break;
50837 +
50838 + case E_FMAN_KG_GEN_EXTRACT_IPSEC_ESP:
50839 + code = no_validation ? 0x7e : 0x6e;
50840 + break;
50841 +
50842 + case E_FMAN_KG_GEN_EXTRACT_SHIM_1:
50843 + code = 0x70;
50844 + break;
50845 +
50846 + case E_FMAN_KG_GEN_EXTRACT_SHIM_2:
50847 + code = 0x71;
50848 + break;
50849 +
50850 + case E_FMAN_KG_GEN_EXTRACT_FROM_DFLT:
50851 + code = 0x10;
50852 + break;
50853 +
50854 + case E_FMAN_KG_GEN_EXTRACT_FROM_FRAME_START:
50855 + code = 0x40;
50856 + break;
50857 +
50858 + case E_FMAN_KG_GEN_EXTRACT_FROM_PARSE_RESULT:
50859 + code = 0x20;
50860 + break;
50861 +
50862 + case E_FMAN_KG_GEN_EXTRACT_FROM_END_OF_PARSE:
50863 + code = 0x7f;
50864 + break;
50865 +
50866 + case E_FMAN_KG_GEN_EXTRACT_FROM_FQID:
50867 + code = 0x20;
50868 + *offset += 0x20;
50869 + break;
50870 +
50871 + default:
50872 + code = FM_KG_SCH_GEN_HT_INVALID;
50873 + }
50874 +
50875 + return (uint8_t)code;
50876 +}
50877 +
50878 +static uint32_t build_ar_scheme(uint8_t scheme,
50879 + uint8_t hwport_id,
50880 + bool update_counter,
50881 + bool write)
50882 +{
50883 + uint32_t rw;
50884 +
50885 + rw = (uint32_t)(write ? FM_KG_KGAR_WRITE : FM_KG_KGAR_READ);
50886 +
50887 + return (uint32_t)(FM_KG_KGAR_GO |
50888 + rw |
50889 + FM_KG_KGAR_SEL_SCHEME_ENTRY |
50890 + hwport_id |
50891 + ((uint32_t)scheme << FM_KG_KGAR_NUM_SHIFT) |
50892 + (update_counter ? FM_KG_KGAR_SCM_WSEL_UPDATE_CNT : 0));
50893 +}
50894 +
50895 +static uint32_t build_ar_cls_plan(uint8_t grp,
50896 + uint8_t entries_mask,
50897 + uint8_t hwport_id,
50898 + bool write)
50899 +{
50900 + uint32_t rw;
50901 +
50902 + rw = (uint32_t)(write ? FM_KG_KGAR_WRITE : FM_KG_KGAR_READ);
50903 +
50904 + return (uint32_t)(FM_KG_KGAR_GO |
50905 + rw |
50906 + FM_PCD_KG_KGAR_SEL_CLS_PLAN_ENTRY |
50907 + hwport_id |
50908 + ((uint32_t)grp << FM_KG_KGAR_NUM_SHIFT) |
50909 + ((uint32_t)entries_mask << FM_KG_KGAR_WSEL_SHIFT));
50910 +}
50911 +
50912 +int fman_kg_write_ar_wait(struct fman_kg_regs *regs, uint32_t fmkg_ar)
50913 +{
50914 + iowrite32be(fmkg_ar, &regs->fmkg_ar);
50915 + /* Wait for GO to be idle and read error */
50916 + while ((fmkg_ar = ioread32be(&regs->fmkg_ar)) & FM_KG_KGAR_GO) ;
50917 + if (fmkg_ar & FM_PCD_KG_KGAR_ERR)
50918 + return -EINVAL;
50919 + return 0;
50920 +}
50921 +
50922 +void fman_kg_write_sp(struct fman_kg_regs *regs, uint32_t sp, bool add)
50923 +{
50924 +
50925 + struct fman_kg_pe_regs *kgpe_regs;
50926 + uint32_t tmp;
50927 +
50928 + kgpe_regs = (struct fman_kg_pe_regs *)&(regs->fmkg_indirect[0]);
50929 + tmp = ioread32be(&kgpe_regs->fmkg_pe_sp);
50930 +
50931 + if (add)
50932 + tmp |= sp;
50933 + else /* clear */
50934 + tmp &= ~sp;
50935 +
50936 + iowrite32be(tmp, &kgpe_regs->fmkg_pe_sp);
50937 +
50938 +}
50939 +
50940 +void fman_kg_write_cpp(struct fman_kg_regs *regs, uint32_t cpp)
50941 +{
50942 + struct fman_kg_pe_regs *kgpe_regs;
50943 +
50944 + kgpe_regs = (struct fman_kg_pe_regs *)&(regs->fmkg_indirect[0]);
50945 +
50946 + iowrite32be(cpp, &kgpe_regs->fmkg_pe_cpp);
50947 +}
50948 +
50949 +void fman_kg_get_event(struct fman_kg_regs *regs,
50950 + uint32_t *event,
50951 + uint32_t *scheme_idx)
50952 +{
50953 + uint32_t mask, force;
50954 +
50955 + *event = ioread32be(&regs->fmkg_eer);
50956 + mask = ioread32be(&regs->fmkg_eeer);
50957 + *scheme_idx = ioread32be(&regs->fmkg_seer);
50958 + *scheme_idx &= ioread32be(&regs->fmkg_seeer);
50959 +
50960 + *event &= mask;
50961 +
50962 + /* clear the forced events */
50963 + force = ioread32be(&regs->fmkg_feer);
50964 + if (force & *event)
50965 + iowrite32be(force & ~*event ,&regs->fmkg_feer);
50966 +
50967 + iowrite32be(*event, &regs->fmkg_eer);
50968 + iowrite32be(*scheme_idx, &regs->fmkg_seer);
50969 +}
50970 +
50971 +
50972 +void fman_kg_init(struct fman_kg_regs *regs,
50973 + uint32_t exceptions,
50974 + uint32_t dflt_nia)
50975 +{
50976 + uint32_t tmp;
50977 + int i;
50978 +
50979 + iowrite32be(FM_EX_KG_DOUBLE_ECC | FM_EX_KG_KEYSIZE_OVERFLOW,
50980 + &regs->fmkg_eer);
50981 +
50982 + tmp = 0;
50983 + if (exceptions & FM_EX_KG_DOUBLE_ECC)
50984 + tmp |= FM_EX_KG_DOUBLE_ECC;
50985 +
50986 + if (exceptions & FM_EX_KG_KEYSIZE_OVERFLOW)
50987 + tmp |= FM_EX_KG_KEYSIZE_OVERFLOW;
50988 +
50989 + iowrite32be(tmp, &regs->fmkg_eeer);
50990 + iowrite32be(0, &regs->fmkg_fdor);
50991 + iowrite32be(0, &regs->fmkg_gdv0r);
50992 + iowrite32be(0, &regs->fmkg_gdv1r);
50993 + iowrite32be(dflt_nia, &regs->fmkg_gcr);
50994 +
50995 + /* Clear binding between ports to schemes and classification plans
50996 + * so that all ports are not bound to any scheme/classification plan */
50997 + for (i = 0; i < FMAN_MAX_NUM_OF_HW_PORTS; i++) {
50998 + clear_pe_all_scheme(regs, (uint8_t)i);
50999 + clear_pe_all_cls_plan(regs, (uint8_t)i);
51000 + }
51001 +}
51002 +
51003 +void fman_kg_enable_scheme_interrupts(struct fman_kg_regs *regs)
51004 +{
51005 + /* enable and enable all scheme interrupts */
51006 + iowrite32be(0xFFFFFFFF, &regs->fmkg_seer);
51007 + iowrite32be(0xFFFFFFFF, &regs->fmkg_seeer);
51008 +}
51009 +
51010 +void fman_kg_enable(struct fman_kg_regs *regs)
51011 +{
51012 + iowrite32be(ioread32be(&regs->fmkg_gcr) | FM_KG_KGGCR_EN,
51013 + &regs->fmkg_gcr);
51014 +}
51015 +
51016 +void fman_kg_disable(struct fman_kg_regs *regs)
51017 +{
51018 + iowrite32be(ioread32be(&regs->fmkg_gcr) & ~FM_KG_KGGCR_EN,
51019 + &regs->fmkg_gcr);
51020 +}
51021 +
51022 +void fman_kg_set_data_after_prs(struct fman_kg_regs *regs, uint8_t offset)
51023 +{
51024 + iowrite32be(offset, &regs->fmkg_fdor);
51025 +}
51026 +
51027 +void fman_kg_set_dflt_val(struct fman_kg_regs *regs,
51028 + uint8_t def_id,
51029 + uint32_t val)
51030 +{
51031 + if(def_id == 0)
51032 + iowrite32be(val, &regs->fmkg_gdv0r);
51033 + else
51034 + iowrite32be(val, &regs->fmkg_gdv1r);
51035 +}
51036 +
51037 +
51038 +void fman_kg_set_exception(struct fman_kg_regs *regs,
51039 + uint32_t exception,
51040 + bool enable)
51041 +{
51042 + uint32_t tmp;
51043 +
51044 + tmp = ioread32be(&regs->fmkg_eeer);
51045 +
51046 + if (enable) {
51047 + tmp |= exception;
51048 + } else {
51049 + tmp &= ~exception;
51050 + }
51051 +
51052 + iowrite32be(tmp, &regs->fmkg_eeer);
51053 +}
51054 +
51055 +void fman_kg_get_exception(struct fman_kg_regs *regs,
51056 + uint32_t *events,
51057 + uint32_t *scheme_ids,
51058 + bool clear)
51059 +{
51060 + uint32_t mask;
51061 +
51062 + *events = ioread32be(&regs->fmkg_eer);
51063 + mask = ioread32be(&regs->fmkg_eeer);
51064 + *events &= mask;
51065 +
51066 + *scheme_ids = 0;
51067 +
51068 + if (*events & FM_EX_KG_KEYSIZE_OVERFLOW) {
51069 + *scheme_ids = ioread32be(&regs->fmkg_seer);
51070 + mask = ioread32be(&regs->fmkg_seeer);
51071 + *scheme_ids &= mask;
51072 + }
51073 +
51074 + if (clear) {
51075 + iowrite32be(*scheme_ids, &regs->fmkg_seer);
51076 + iowrite32be(*events, &regs->fmkg_eer);
51077 + }
51078 +}
51079 +
51080 +void fman_kg_get_capture(struct fman_kg_regs *regs,
51081 + struct fman_kg_ex_ecc_attr *ecc_attr,
51082 + bool clear)
51083 +{
51084 + uint32_t tmp;
51085 +
51086 + tmp = ioread32be(&regs->fmkg_serc);
51087 +
51088 + if (tmp & KG_FMKG_SERC_CAP) {
51089 + /* Captured data is valid */
51090 + ecc_attr->valid = TRUE;
51091 + ecc_attr->double_ecc =
51092 + (bool)((tmp & KG_FMKG_SERC_CET) ? TRUE : FALSE);
51093 + ecc_attr->single_ecc_count =
51094 + (uint8_t)((tmp & KG_FMKG_SERC_CNT_MSK) >>
51095 + KG_FMKG_SERC_CNT_SHIFT);
51096 + ecc_attr->addr = (uint16_t)(tmp & KG_FMKG_SERC_ADDR_MSK);
51097 +
51098 + if (clear)
51099 + iowrite32be(KG_FMKG_SERC_CAP, &regs->fmkg_serc);
51100 + } else {
51101 + /* No ECC error is captured */
51102 + ecc_attr->valid = FALSE;
51103 + }
51104 +}
51105 +
51106 +int fman_kg_build_scheme(struct fman_kg_scheme_params *params,
51107 + struct fman_kg_scheme_regs *scheme_regs)
51108 +{
51109 + struct fman_kg_extract_params *extract_params;
51110 + struct fman_kg_gen_extract_params *gen_params;
51111 + uint32_t tmp_reg, i, select, mask, fqb;
51112 + uint8_t offset, shift, ht;
51113 +
51114 + /* Zero out all registers so no need to care about unused ones */
51115 + memset(scheme_regs, 0, sizeof(struct fman_kg_scheme_regs));
51116 +
51117 + /* Mode register */
51118 + tmp_reg = fm_kg_build_nia(params->next_engine,
51119 + params->next_engine_action);
51120 + if (tmp_reg == KG_NIA_INVALID) {
51121 + return -EINVAL;
51122 + }
51123 +
51124 + if (params->next_engine == E_FMAN_PCD_PLCR) {
51125 + tmp_reg |= FMAN_KG_SCH_MODE_NIA_PLCR;
51126 + }
51127 + else if (params->next_engine == E_FMAN_PCD_CC) {
51128 + tmp_reg |= (uint32_t)params->cc_params.base_offset <<
51129 + FMAN_KG_SCH_MODE_CCOBASE_SHIFT;
51130 + }
51131 +
51132 + tmp_reg |= FMAN_KG_SCH_MODE_EN;
51133 + scheme_regs->kgse_mode = tmp_reg;
51134 +
51135 + /* Match vector */
51136 + scheme_regs->kgse_mv = params->match_vector;
51137 +
51138 + extract_params = &params->extract_params;
51139 +
51140 + /* Scheme default values registers */
51141 + scheme_regs->kgse_dv0 = extract_params->def_scheme_0;
51142 + scheme_regs->kgse_dv1 = extract_params->def_scheme_1;
51143 +
51144 + /* Extract Known Fields Command register */
51145 + scheme_regs->kgse_ekfc = extract_params->known_fields;
51146 +
51147 + /* Entry Extract Known Default Value register */
51148 + tmp_reg = 0;
51149 + tmp_reg |= extract_params->known_fields_def.mac_addr <<
51150 + FMAN_KG_SCH_DEF_MAC_ADDR_SHIFT;
51151 + tmp_reg |= extract_params->known_fields_def.vlan_tci <<
51152 + FMAN_KG_SCH_DEF_VLAN_TCI_SHIFT;
51153 + tmp_reg |= extract_params->known_fields_def.etype <<
51154 + FMAN_KG_SCH_DEF_ETYPE_SHIFT;
51155 + tmp_reg |= extract_params->known_fields_def.ppp_sid <<
51156 + FMAN_KG_SCH_DEF_PPP_SID_SHIFT;
51157 + tmp_reg |= extract_params->known_fields_def.ppp_pid <<
51158 + FMAN_KG_SCH_DEF_PPP_PID_SHIFT;
51159 + tmp_reg |= extract_params->known_fields_def.mpls <<
51160 + FMAN_KG_SCH_DEF_MPLS_SHIFT;
51161 + tmp_reg |= extract_params->known_fields_def.ip_addr <<
51162 + FMAN_KG_SCH_DEF_IP_ADDR_SHIFT;
51163 + tmp_reg |= extract_params->known_fields_def.ptype <<
51164 + FMAN_KG_SCH_DEF_PTYPE_SHIFT;
51165 + tmp_reg |= extract_params->known_fields_def.ip_tos_tc <<
51166 + FMAN_KG_SCH_DEF_IP_TOS_TC_SHIFT;
51167 + tmp_reg |= extract_params->known_fields_def.ipv6_fl <<
51168 + FMAN_KG_SCH_DEF_IPv6_FL_SHIFT;
51169 + tmp_reg |= extract_params->known_fields_def.ipsec_spi <<
51170 + FMAN_KG_SCH_DEF_IPSEC_SPI_SHIFT;
51171 + tmp_reg |= extract_params->known_fields_def.l4_port <<
51172 + FMAN_KG_SCH_DEF_L4_PORT_SHIFT;
51173 + tmp_reg |= extract_params->known_fields_def.tcp_flg <<
51174 + FMAN_KG_SCH_DEF_TCP_FLG_SHIFT;
51175 +
51176 + scheme_regs->kgse_ekdv = tmp_reg;
51177 +
51178 + /* Generic extract registers */
51179 + if (extract_params->gen_extract_num > FM_KG_NUM_OF_GENERIC_REGS) {
51180 + return -EINVAL;
51181 + }
51182 +
51183 + for (i = 0; i < extract_params->gen_extract_num; i++) {
51184 + gen_params = extract_params->gen_extract + i;
51185 +
51186 + tmp_reg = FMAN_KG_SCH_GEN_VALID;
51187 + tmp_reg |= (uint32_t)gen_params->def_val <<
51188 + FMAN_KG_SCH_GEN_DEF_SHIFT;
51189 +
51190 + if (gen_params->type == E_FMAN_KG_HASH_EXTRACT) {
51191 + if ((gen_params->extract > FMAN_KG_SCH_GEN_SIZE_MAX) ||
51192 + (gen_params->extract == 0)) {
51193 + return -EINVAL;
51194 + }
51195 + } else {
51196 + tmp_reg |= FMAN_KG_SCH_GEN_OR;
51197 + }
51198 +
51199 + tmp_reg |= (uint32_t)gen_params->extract <<
51200 + FMAN_KG_SCH_GEN_SIZE_SHIFT;
51201 + tmp_reg |= (uint32_t)gen_params->mask <<
51202 + FMAN_KG_SCH_GEN_MASK_SHIFT;
51203 +
51204 + offset = gen_params->offset;
51205 + ht = get_gen_ht_code(gen_params->src,
51206 + gen_params->no_validation,
51207 + &offset);
51208 + tmp_reg |= (uint32_t)ht << FMAN_KG_SCH_GEN_HT_SHIFT;
51209 + tmp_reg |= offset;
51210 +
51211 + scheme_regs->kgse_gec[i] = tmp_reg;
51212 + }
51213 +
51214 + /* Masks registers */
51215 + if (extract_params->masks_num > FM_KG_EXTRACT_MASKS_NUM) {
51216 + return -EINVAL;
51217 + }
51218 +
51219 + select = 0;
51220 + mask = 0;
51221 + fqb = 0;
51222 + for (i = 0; i < extract_params->masks_num; i++) {
51223 + /* MCSx fields */
51224 + KG_GET_MASK_SEL_SHIFT(shift, i);
51225 + if (extract_params->masks[i].is_known) {
51226 + /* Mask known field */
51227 + select |= extract_params->masks[i].field_or_gen_idx <<
51228 + shift;
51229 + } else {
51230 + /* Mask generic extract */
51231 + select |= (extract_params->masks[i].field_or_gen_idx +
51232 + FM_KG_MASK_SEL_GEN_BASE) << shift;
51233 + }
51234 +
51235 + /* MOx fields - spread between se_bmch and se_fqb registers */
51236 + KG_GET_MASK_OFFSET_SHIFT(shift, i);
51237 + if (i < 2) {
51238 + select |= (uint32_t)extract_params->masks[i].offset <<
51239 + shift;
51240 + } else {
51241 + fqb |= (uint32_t)extract_params->masks[i].offset <<
51242 + shift;
51243 + }
51244 +
51245 + /* BMx fields */
51246 + KG_GET_MASK_SHIFT(shift, i);
51247 + mask |= (uint32_t)extract_params->masks[i].mask << shift;
51248 + }
51249 +
51250 + /* Finish with rest of BMx fileds -
51251 + * don't mask bits for unused masks by setting
51252 + * corresponding BMx field = 0xFF */
51253 + for (i = extract_params->masks_num; i < FM_KG_EXTRACT_MASKS_NUM; i++) {
51254 + KG_GET_MASK_SHIFT(shift, i);
51255 + mask |= 0xFF << shift;
51256 + }
51257 +
51258 + scheme_regs->kgse_bmch = select;
51259 + scheme_regs->kgse_bmcl = mask;
51260 +
51261 + /* Finish with FQB register initialization.
51262 + * Check fqid is 24-bit value. */
51263 + if (params->base_fqid & ~0x00FFFFFF) {
51264 + return -EINVAL;
51265 + }
51266 +
51267 + fqb |= params->base_fqid;
51268 + scheme_regs->kgse_fqb = fqb;
51269 +
51270 + /* Hash Configuration register */
51271 + tmp_reg = 0;
51272 + if (params->hash_params.use_hash) {
51273 + /* Check hash mask is 24-bit value */
51274 + if (params->hash_params.mask & ~0x00FFFFFF) {
51275 + return -EINVAL;
51276 + }
51277 +
51278 + /* Hash function produces 64-bit value, 24 bits of that
51279 + * are used to generate fq_id and policer profile.
51280 + * Thus, maximal shift is 40 bits to allow 24 bits out of 64.
51281 + */
51282 + if (params->hash_params.shift_r > FMAN_KG_SCH_HASH_HSHIFT_MAX) {
51283 + return -EINVAL;
51284 + }
51285 +
51286 + tmp_reg |= params->hash_params.mask;
51287 + tmp_reg |= (uint32_t)params->hash_params.shift_r <<
51288 + FMAN_KG_SCH_HASH_HSHIFT_SHIFT;
51289 +
51290 + if (params->hash_params.sym) {
51291 + tmp_reg |= FMAN_KG_SCH_HASH_SYM;
51292 + }
51293 +
51294 + }
51295 +
51296 + if (params->bypass_fqid_gen) {
51297 + tmp_reg |= FMAN_KG_SCH_HASH_NO_FQID_GEN;
51298 + }
51299 +
51300 + scheme_regs->kgse_hc = tmp_reg;
51301 +
51302 + /* Policer Profile register */
51303 + if (params->policer_params.bypass_pp_gen) {
51304 + tmp_reg = 0;
51305 + } else {
51306 + /* Lower 8 bits of 24-bits extracted from hash result
51307 + * are used for policer profile generation.
51308 + * That leaves maximum shift value = 23. */
51309 + if (params->policer_params.shift > FMAN_KG_SCH_PP_SHIFT_MAX) {
51310 + return -EINVAL;
51311 + }
51312 +
51313 + tmp_reg = params->policer_params.base;
51314 + tmp_reg |= ((uint32_t)params->policer_params.shift <<
51315 + FMAN_KG_SCH_PP_SH_SHIFT) &
51316 + FMAN_KG_SCH_PP_SH_MASK;
51317 + tmp_reg |= ((uint32_t)params->policer_params.shift <<
51318 + FMAN_KG_SCH_PP_SL_SHIFT) &
51319 + FMAN_KG_SCH_PP_SL_MASK;
51320 + tmp_reg |= (uint32_t)params->policer_params.mask <<
51321 + FMAN_KG_SCH_PP_MASK_SHIFT;
51322 + }
51323 +
51324 + scheme_regs->kgse_ppc = tmp_reg;
51325 +
51326 + /* Coarse Classification Bit Select register */
51327 + if (params->next_engine == E_FMAN_PCD_CC) {
51328 + scheme_regs->kgse_ccbs = params->cc_params.qlcv_bits_sel;
51329 + }
51330 +
51331 + /* Packets Counter register */
51332 + if (params->update_counter) {
51333 + scheme_regs->kgse_spc = params->counter_value;
51334 + }
51335 +
51336 + return 0;
51337 +}
51338 +
51339 +int fman_kg_write_scheme(struct fman_kg_regs *regs,
51340 + uint8_t scheme_id,
51341 + uint8_t hwport_id,
51342 + struct fman_kg_scheme_regs *scheme_regs,
51343 + bool update_counter)
51344 +{
51345 + struct fman_kg_scheme_regs *kgse_regs;
51346 + uint32_t tmp_reg;
51347 + int err, i;
51348 +
51349 + /* Write indirect scheme registers */
51350 + kgse_regs = (struct fman_kg_scheme_regs *)&(regs->fmkg_indirect[0]);
51351 +
51352 + iowrite32be(scheme_regs->kgse_mode, &kgse_regs->kgse_mode);
51353 + iowrite32be(scheme_regs->kgse_ekfc, &kgse_regs->kgse_ekfc);
51354 + iowrite32be(scheme_regs->kgse_ekdv, &kgse_regs->kgse_ekdv);
51355 + iowrite32be(scheme_regs->kgse_bmch, &kgse_regs->kgse_bmch);
51356 + iowrite32be(scheme_regs->kgse_bmcl, &kgse_regs->kgse_bmcl);
51357 + iowrite32be(scheme_regs->kgse_fqb, &kgse_regs->kgse_fqb);
51358 + iowrite32be(scheme_regs->kgse_hc, &kgse_regs->kgse_hc);
51359 + iowrite32be(scheme_regs->kgse_ppc, &kgse_regs->kgse_ppc);
51360 + iowrite32be(scheme_regs->kgse_spc, &kgse_regs->kgse_spc);
51361 + iowrite32be(scheme_regs->kgse_dv0, &kgse_regs->kgse_dv0);
51362 + iowrite32be(scheme_regs->kgse_dv1, &kgse_regs->kgse_dv1);
51363 + iowrite32be(scheme_regs->kgse_ccbs, &kgse_regs->kgse_ccbs);
51364 + iowrite32be(scheme_regs->kgse_mv, &kgse_regs->kgse_mv);
51365 +
51366 + for (i = 0 ; i < FM_KG_NUM_OF_GENERIC_REGS ; i++)
51367 + iowrite32be(scheme_regs->kgse_gec[i], &kgse_regs->kgse_gec[i]);
51368 +
51369 + /* Write AR (Action register) */
51370 + tmp_reg = build_ar_scheme(scheme_id, hwport_id, update_counter, TRUE);
51371 + err = fman_kg_write_ar_wait(regs, tmp_reg);
51372 + return err;
51373 +}
51374 +
51375 +int fman_kg_delete_scheme(struct fman_kg_regs *regs,
51376 + uint8_t scheme_id,
51377 + uint8_t hwport_id)
51378 +{
51379 + struct fman_kg_scheme_regs *kgse_regs;
51380 + uint32_t tmp_reg;
51381 + int err, i;
51382 +
51383 + kgse_regs = (struct fman_kg_scheme_regs *)&(regs->fmkg_indirect[0]);
51384 +
51385 + /* Clear all registers including enable bit in mode register */
51386 + for (i = 0; i < (sizeof(struct fman_kg_scheme_regs)) / 4; ++i) {
51387 + iowrite32be(0, ((uint32_t *)kgse_regs + i));
51388 + }
51389 +
51390 + /* Write AR (Action register) */
51391 + tmp_reg = build_ar_scheme(scheme_id, hwport_id, FALSE, TRUE);
51392 + err = fman_kg_write_ar_wait(regs, tmp_reg);
51393 + return err;
51394 +}
51395 +
51396 +int fman_kg_get_scheme_counter(struct fman_kg_regs *regs,
51397 + uint8_t scheme_id,
51398 + uint8_t hwport_id,
51399 + uint32_t *counter)
51400 +{
51401 + struct fman_kg_scheme_regs *kgse_regs;
51402 + uint32_t tmp_reg;
51403 + int err;
51404 +
51405 + kgse_regs = (struct fman_kg_scheme_regs *)&(regs->fmkg_indirect[0]);
51406 +
51407 + tmp_reg = build_ar_scheme(scheme_id, hwport_id, TRUE, FALSE);
51408 + err = fman_kg_write_ar_wait(regs, tmp_reg);
51409 +
51410 + if (err != 0)
51411 + return err;
51412 +
51413 + *counter = ioread32be(&kgse_regs->kgse_spc);
51414 +
51415 + return 0;
51416 +}
51417 +
51418 +int fman_kg_set_scheme_counter(struct fman_kg_regs *regs,
51419 + uint8_t scheme_id,
51420 + uint8_t hwport_id,
51421 + uint32_t counter)
51422 +{
51423 + struct fman_kg_scheme_regs *kgse_regs;
51424 + uint32_t tmp_reg;
51425 + int err;
51426 +
51427 + kgse_regs = (struct fman_kg_scheme_regs *)&(regs->fmkg_indirect[0]);
51428 +
51429 + tmp_reg = build_ar_scheme(scheme_id, hwport_id, TRUE, FALSE);
51430 +
51431 + err = fman_kg_write_ar_wait(regs, tmp_reg);
51432 + if (err != 0)
51433 + return err;
51434 +
51435 + /* Keygen indirect access memory contains all scheme_id registers
51436 + * by now. Change only counter value. */
51437 + iowrite32be(counter, &kgse_regs->kgse_spc);
51438 +
51439 + /* Write back scheme registers */
51440 + tmp_reg = build_ar_scheme(scheme_id, hwport_id, TRUE, TRUE);
51441 + err = fman_kg_write_ar_wait(regs, tmp_reg);
51442 +
51443 + return err;
51444 +}
51445 +
51446 +uint32_t fman_kg_get_schemes_total_counter(struct fman_kg_regs *regs)
51447 +{
51448 + return ioread32be(&regs->fmkg_tpc);
51449 +}
51450 +
51451 +int fman_kg_build_cls_plan(struct fman_kg_cls_plan_params *params,
51452 + struct fman_kg_cp_regs *cls_plan_regs)
51453 +{
51454 + uint8_t entries_set, entry_bit;
51455 + int i;
51456 +
51457 + /* Zero out all group's register */
51458 + memset(cls_plan_regs, 0, sizeof(struct fman_kg_cp_regs));
51459 +
51460 + /* Go over all classification entries in params->entries_mask and
51461 + * configure the corresponding cpe register */
51462 + entries_set = params->entries_mask;
51463 + for (i = 0; entries_set; i++) {
51464 + entry_bit = (uint8_t)(0x80 >> i);
51465 + if ((entry_bit & entries_set) == 0)
51466 + continue;
51467 + entries_set ^= entry_bit;
51468 + cls_plan_regs->kgcpe[i] = params->mask_vector[i];
51469 + }
51470 +
51471 + return 0;
51472 +}
51473 +
51474 +int fman_kg_write_cls_plan(struct fman_kg_regs *regs,
51475 + uint8_t grp_id,
51476 + uint8_t entries_mask,
51477 + uint8_t hwport_id,
51478 + struct fman_kg_cp_regs *cls_plan_regs)
51479 +{
51480 + struct fman_kg_cp_regs *kgcpe_regs;
51481 + uint32_t tmp_reg;
51482 + int i, err;
51483 +
51484 + /* Check group index is valid and the group isn't empty */
51485 + if (grp_id >= FM_KG_CLS_PLAN_GRPS_NUM)
51486 + return -EINVAL;
51487 +
51488 + /* Write indirect classification plan registers */
51489 + kgcpe_regs = (struct fman_kg_cp_regs *)&(regs->fmkg_indirect[0]);
51490 +
51491 + for (i = 0; i < FM_KG_NUM_CLS_PLAN_ENTR; i++) {
51492 + iowrite32be(cls_plan_regs->kgcpe[i], &kgcpe_regs->kgcpe[i]);
51493 + }
51494 +
51495 + tmp_reg = build_ar_cls_plan(grp_id, entries_mask, hwport_id, TRUE);
51496 + err = fman_kg_write_ar_wait(regs, tmp_reg);
51497 + return err;
51498 +}
51499 +
51500 +int fman_kg_write_bind_schemes(struct fman_kg_regs *regs,
51501 + uint8_t hwport_id,
51502 + uint32_t schemes)
51503 +{
51504 + struct fman_kg_pe_regs *kg_pe_regs;
51505 + uint32_t tmp_reg;
51506 + int err;
51507 +
51508 + kg_pe_regs = (struct fman_kg_pe_regs *)&(regs->fmkg_indirect[0]);
51509 +
51510 + iowrite32be(schemes, &kg_pe_regs->fmkg_pe_sp);
51511 +
51512 + tmp_reg = build_ar_bind_scheme(hwport_id, TRUE);
51513 + err = fman_kg_write_ar_wait(regs, tmp_reg);
51514 + return err;
51515 +}
51516 +
51517 +int fman_kg_build_bind_cls_plans(uint8_t grp_base,
51518 + uint8_t grp_mask,
51519 + uint32_t *bind_cls_plans)
51520 +{
51521 + /* Check grp_base and grp_mask are 5-bits values */
51522 + if ((grp_base & ~0x0000001F) || (grp_mask & ~0x0000001F))
51523 + return -EINVAL;
51524 +
51525 + *bind_cls_plans = (uint32_t) ((grp_mask << FMAN_KG_PE_CPP_MASK_SHIFT) | grp_base);
51526 + return 0;
51527 +}
51528 +
51529 +
51530 +int fman_kg_write_bind_cls_plans(struct fman_kg_regs *regs,
51531 + uint8_t hwport_id,
51532 + uint32_t bind_cls_plans)
51533 +{
51534 + struct fman_kg_pe_regs *kg_pe_regs;
51535 + uint32_t tmp_reg;
51536 + int err;
51537 +
51538 + kg_pe_regs = (struct fman_kg_pe_regs *)&(regs->fmkg_indirect[0]);
51539 +
51540 + iowrite32be(bind_cls_plans, &kg_pe_regs->fmkg_pe_cpp);
51541 +
51542 + tmp_reg = build_ar_bind_cls_plan(hwport_id, TRUE);
51543 + err = fman_kg_write_ar_wait(regs, tmp_reg);
51544 + return err;
51545 +}
51546 --- /dev/null
51547 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/fman_prs.c
51548 @@ -0,0 +1,129 @@
51549 +/*
51550 + * Copyright 2012 Freescale Semiconductor Inc.
51551 + *
51552 + * Redistribution and use in source and binary forms, with or without
51553 + * modification, are permitted provided that the following conditions are met:
51554 + * * Redistributions of source code must retain the above copyright
51555 + * notice, this list of conditions and the following disclaimer.
51556 + * * Redistributions in binary form must reproduce the above copyright
51557 + * notice, this list of conditions and the following disclaimer in the
51558 + * documentation and/or other materials provided with the distribution.
51559 + * * Neither the name of Freescale Semiconductor nor the
51560 + * names of its contributors may be used to endorse or promote products
51561 + * derived from this software without specific prior written permission.
51562 + *
51563 + *
51564 + * ALTERNATIVELY, this software may be distributed under the terms of the
51565 + * GNU General Public License ("GPL") as published by the Free Software
51566 + * Foundation, either version 2 of that License or (at your option) any
51567 + * later version.
51568 + *
51569 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
51570 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
51571 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
51572 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
51573 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
51574 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
51575 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
51576 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
51577 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
51578 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
51579 + */
51580 +
51581 +#include "fsl_fman_prs.h"
51582 +
51583 +uint32_t fman_prs_get_err_event(struct fman_prs_regs *regs, uint32_t ev_mask)
51584 +{
51585 + return ioread32be(&regs->fmpr_perr) & ev_mask;
51586 +}
51587 +
51588 +uint32_t fman_prs_get_err_ev_mask(struct fman_prs_regs *regs)
51589 +{
51590 + return ioread32be(&regs->fmpr_perer);
51591 +}
51592 +
51593 +void fman_prs_ack_err_event(struct fman_prs_regs *regs, uint32_t event)
51594 +{
51595 + iowrite32be(event, &regs->fmpr_perr);
51596 +}
51597 +
51598 +uint32_t fman_prs_get_expt_event(struct fman_prs_regs *regs, uint32_t ev_mask)
51599 +{
51600 + return ioread32be(&regs->fmpr_pevr) & ev_mask;
51601 +}
51602 +
51603 +uint32_t fman_prs_get_expt_ev_mask(struct fman_prs_regs *regs)
51604 +{
51605 + return ioread32be(&regs->fmpr_pever);
51606 +}
51607 +
51608 +void fman_prs_ack_expt_event(struct fman_prs_regs *regs, uint32_t event)
51609 +{
51610 + iowrite32be(event, &regs->fmpr_pevr);
51611 +}
51612 +
51613 +void fman_prs_defconfig(struct fman_prs_cfg *cfg)
51614 +{
51615 + cfg->port_id_stat = 0;
51616 + cfg->max_prs_cyc_lim = DEFAULT_MAX_PRS_CYC_LIM;
51617 + cfg->prs_exceptions = 0x03000000;
51618 +}
51619 +
51620 +int fman_prs_init(struct fman_prs_regs *regs, struct fman_prs_cfg *cfg)
51621 +{
51622 + uint32_t tmp;
51623 +
51624 + iowrite32be(cfg->max_prs_cyc_lim, &regs->fmpr_rpclim);
51625 + iowrite32be((FM_PCD_PRS_SINGLE_ECC | FM_PCD_PRS_PORT_IDLE_STS),
51626 + &regs->fmpr_pevr);
51627 +
51628 + if (cfg->prs_exceptions & FM_PCD_EX_PRS_SINGLE_ECC)
51629 + iowrite32be(FM_PCD_PRS_SINGLE_ECC, &regs->fmpr_pever);
51630 + else
51631 + iowrite32be(0, &regs->fmpr_pever);
51632 +
51633 + iowrite32be(FM_PCD_PRS_DOUBLE_ECC, &regs->fmpr_perr);
51634 +
51635 + tmp = 0;
51636 + if (cfg->prs_exceptions & FM_PCD_EX_PRS_DOUBLE_ECC)
51637 + tmp |= FM_PCD_PRS_DOUBLE_ECC;
51638 + iowrite32be(tmp, &regs->fmpr_perer);
51639 +
51640 + iowrite32be(cfg->port_id_stat, &regs->fmpr_ppsc);
51641 +
51642 + return 0;
51643 +}
51644 +
51645 +void fman_prs_enable(struct fman_prs_regs *regs)
51646 +{
51647 + uint32_t tmp;
51648 +
51649 + tmp = ioread32be(&regs->fmpr_rpimac) | FM_PCD_PRS_RPIMAC_EN;
51650 + iowrite32be(tmp, &regs->fmpr_rpimac);
51651 +}
51652 +
51653 +void fman_prs_disable(struct fman_prs_regs *regs)
51654 +{
51655 + uint32_t tmp;
51656 +
51657 + tmp = ioread32be(&regs->fmpr_rpimac) & ~FM_PCD_PRS_RPIMAC_EN;
51658 + iowrite32be(tmp, &regs->fmpr_rpimac);
51659 +}
51660 +
51661 +int fman_prs_is_enabled(struct fman_prs_regs *regs)
51662 +{
51663 + return ioread32be(&regs->fmpr_rpimac) & FM_PCD_PRS_RPIMAC_EN;
51664 +}
51665 +
51666 +void fman_prs_set_stst_port_msk(struct fman_prs_regs *regs, uint32_t pid_msk)
51667 +{
51668 + iowrite32be(pid_msk, &regs->fmpr_ppsc);
51669 +}
51670 +
51671 +void fman_prs_set_stst(struct fman_prs_regs *regs, bool enable)
51672 +{
51673 + if (enable)
51674 + iowrite32be(FM_PCD_PRS_PPSC_ALL_PORTS, &regs->fmpr_ppsc);
51675 + else
51676 + iowrite32be(0, &regs->fmpr_ppsc);
51677 +}
51678 --- /dev/null
51679 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Port/Makefile
51680 @@ -0,0 +1,15 @@
51681 +#
51682 +# Makefile for the Freescale Ethernet controllers
51683 +#
51684 +ccflags-y += -DVERSION=\"\"
51685 +#
51686 +#Include netcomm SW specific definitions
51687 +include $(srctree)/drivers/net/ethernet/freescale/sdk_fman/ncsw_config.mk
51688 +
51689 +NCSW_FM_INC = $(srctree)/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/inc
51690 +
51691 +ccflags-y += -I$(NCSW_FM_INC)
51692 +
51693 +obj-y += fsl-ncsw-Pcd.o
51694 +
51695 +fsl-ncsw-Pcd-objs := fm_port.o fm_port_im.o fman_port.o
51696 --- /dev/null
51697 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Port/fm_port.c
51698 @@ -0,0 +1,6436 @@
51699 +/*
51700 + * Copyright 2008-2012 Freescale Semiconductor Inc.
51701 + *
51702 + * Redistribution and use in source and binary forms, with or without
51703 + * modification, are permitted provided that the following conditions are met:
51704 + * * Redistributions of source code must retain the above copyright
51705 + * notice, this list of conditions and the following disclaimer.
51706 + * * Redistributions in binary form must reproduce the above copyright
51707 + * notice, this list of conditions and the following disclaimer in the
51708 + * documentation and/or other materials provided with the distribution.
51709 + * * Neither the name of Freescale Semiconductor nor the
51710 + * names of its contributors may be used to endorse or promote products
51711 + * derived from this software without specific prior written permission.
51712 + *
51713 + *
51714 + * ALTERNATIVELY, this software may be distributed under the terms of the
51715 + * GNU General Public License ("GPL") as published by the Free Software
51716 + * Foundation, either version 2 of that License or (at your option) any
51717 + * later version.
51718 + *
51719 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
51720 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
51721 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
51722 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
51723 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
51724 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
51725 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
51726 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
51727 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
51728 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
51729 + */
51730 +
51731 +
51732 +/******************************************************************************
51733 + @File fm_port.c
51734 +
51735 + @Description FM driver routines implementation.
51736 + *//***************************************************************************/
51737 +#include "error_ext.h"
51738 +#include "std_ext.h"
51739 +#include "string_ext.h"
51740 +#include "sprint_ext.h"
51741 +#include "debug_ext.h"
51742 +#include "fm_muram_ext.h"
51743 +
51744 +#include "fman_common.h"
51745 +#include "fm_port.h"
51746 +#include "fm_port_dsar.h"
51747 +#include "common/general.h"
51748 +
51749 +/****************************************/
51750 +/* static functions */
51751 +/****************************************/
51752 +static t_Error FmPortConfigAutoResForDeepSleepSupport1(t_FmPort *p_FmPort);
51753 +
51754 +static t_Error CheckInitParameters(t_FmPort *p_FmPort)
51755 +{
51756 + t_FmPortDriverParam *p_Params = p_FmPort->p_FmPortDriverParam;
51757 + struct fman_port_cfg *p_DfltConfig = &p_Params->dfltCfg;
51758 + t_Error ans = E_OK;
51759 + uint32_t unusedMask;
51760 +
51761 + if (p_FmPort->imEn)
51762 + {
51763 + if (p_FmPort->portType == e_FM_PORT_TYPE_RX_10G)
51764 + if (p_FmPort->p_FmPortDriverParam->dfltCfg.tx_fifo_deq_pipeline_depth
51765 + > 2)
51766 + RETURN_ERROR(
51767 + MAJOR,
51768 + E_INVALID_VALUE,
51769 + ("fifoDeqPipelineDepth for IM 10G can't be larger than 2"));
51770 +
51771 + if ((ans = FmPortImCheckInitParameters(p_FmPort)) != E_OK)
51772 + return ERROR_CODE(ans);
51773 + }
51774 + else
51775 + {
51776 + /****************************************/
51777 + /* Rx only */
51778 + /****************************************/
51779 + if ((p_FmPort->portType == e_FM_PORT_TYPE_RX)
51780 + || (p_FmPort->portType == e_FM_PORT_TYPE_RX_10G))
51781 + {
51782 + /* external buffer pools */
51783 + if (!p_Params->extBufPools.numOfPoolsUsed)
51784 + RETURN_ERROR(
51785 + MAJOR,
51786 + E_INVALID_VALUE,
51787 + ("extBufPools.numOfPoolsUsed=0. At least one buffer pool must be defined"));
51788 +
51789 + if (FmSpCheckBufPoolsParams(&p_Params->extBufPools,
51790 + p_Params->p_BackupBmPools,
51791 + &p_Params->bufPoolDepletion) != E_OK)
51792 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, NO_MSG);
51793 +
51794 + /* Check that part of IC that needs copying is small enough to enter start margin */
51795 + if (p_Params->intContext.size
51796 + && (p_Params->intContext.size
51797 + + p_Params->intContext.extBufOffset
51798 + > p_Params->bufMargins.startMargins))
51799 + RETURN_ERROR(MAJOR, E_INVALID_VALUE,
51800 + ("intContext.size is larger than start margins"));
51801 +
51802 + if ((p_Params->liodnOffset != (uint16_t)DPAA_LIODN_DONT_OVERRIDE)
51803 + && (p_Params->liodnOffset & ~FM_LIODN_OFFSET_MASK))
51804 + RETURN_ERROR(
51805 + MAJOR,
51806 + E_INVALID_VALUE,
51807 + ("liodnOffset is larger than %d", FM_LIODN_OFFSET_MASK+1));
51808 +
51809 +#ifdef FM_NO_BACKUP_POOLS
51810 + if ((p_FmPort->fmRevInfo.majorRev != 4) && (p_FmPort->fmRevInfo.majorRev < 6))
51811 + if (p_FmPort->p_FmPortDriverParam->p_BackupBmPools)
51812 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("BackupBmPools"));
51813 +#endif /* FM_NO_BACKUP_POOLS */
51814 + }
51815 +
51816 + /****************************************/
51817 + /* Non Rx ports */
51818 + /****************************************/
51819 + else
51820 + {
51821 + if (p_Params->deqSubPortal >= FM_MAX_NUM_OF_SUB_PORTALS)
51822 + RETURN_ERROR(
51823 + MAJOR,
51824 + E_INVALID_VALUE,
51825 + (" deqSubPortal has to be in the range of 0 - %d", FM_MAX_NUM_OF_SUB_PORTALS));
51826 +
51827 + /* to protect HW internal-context from overwrite */
51828 + if ((p_Params->intContext.size)
51829 + && (p_Params->intContext.intContextOffset
51830 + < MIN_TX_INT_OFFSET))
51831 + RETURN_ERROR(
51832 + MAJOR,
51833 + E_INVALID_VALUE,
51834 + ("non-Rx intContext.intContextOffset can't be smaller than %d", MIN_TX_INT_OFFSET));
51835 +
51836 + if ((p_FmPort->portType == e_FM_PORT_TYPE_TX)
51837 + || (p_FmPort->portType == e_FM_PORT_TYPE_TX_10G)
51838 + /* in O/H DEFAULT_notSupported indicates that it is not supported and should not be checked */
51839 + || (p_FmPort->p_FmPortDriverParam->dfltCfg.tx_fifo_deq_pipeline_depth
51840 + != DEFAULT_notSupported))
51841 + {
51842 + /* Check that not larger than 8 */
51843 + if ((!p_FmPort->p_FmPortDriverParam->dfltCfg.tx_fifo_deq_pipeline_depth)
51844 + || (p_FmPort->p_FmPortDriverParam->dfltCfg.tx_fifo_deq_pipeline_depth
51845 + > MAX_FIFO_PIPELINE_DEPTH))
51846 + RETURN_ERROR(
51847 + MAJOR,
51848 + E_INVALID_VALUE,
51849 + ("fifoDeqPipelineDepth can't be larger than %d", MAX_FIFO_PIPELINE_DEPTH));
51850 + }
51851 + }
51852 +
51853 + /****************************************/
51854 + /* Rx Or Offline Parsing */
51855 + /****************************************/
51856 + if ((p_FmPort->portType == e_FM_PORT_TYPE_RX)
51857 + || (p_FmPort->portType == e_FM_PORT_TYPE_RX_10G)
51858 + || (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING))
51859 + {
51860 + if (!p_Params->dfltFqid)
51861 + RETURN_ERROR(MAJOR, E_INVALID_VALUE,
51862 + ("dfltFqid must be between 1 and 2^24-1"));
51863 +#if defined(FM_CAPWAP_SUPPORT) && defined(FM_LOCKUP_ALIGNMENT_ERRATA_FMAN_SW004)
51864 + if (p_FmPort->p_FmPortDriverParam->bufferPrefixContent.manipExtraSpace % 16)
51865 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("bufferPrefixContent.manipExtraSpace has to be devidable by 16"));
51866 +#endif /* defined(FM_CAPWAP_SUPPORT) && ... */
51867 + }
51868 +
51869 + /****************************************/
51870 + /* All ports */
51871 + /****************************************/
51872 + /* common BMI registers values */
51873 + /* Check that Queue Id is not larger than 2^24, and is not 0 */
51874 + if ((p_Params->errFqid & ~0x00FFFFFF) || !p_Params->errFqid)
51875 + RETURN_ERROR(MAJOR, E_INVALID_VALUE,
51876 + ("errFqid must be between 1 and 2^24-1"));
51877 + if (p_Params->dfltFqid & ~0x00FFFFFF)
51878 + RETURN_ERROR(MAJOR, E_INVALID_VALUE,
51879 + ("dfltFqid must be between 1 and 2^24-1"));
51880 + }
51881 +
51882 + /****************************************/
51883 + /* Rx only */
51884 + /****************************************/
51885 + if ((p_FmPort->portType == e_FM_PORT_TYPE_RX)
51886 + || (p_FmPort->portType == e_FM_PORT_TYPE_RX_10G))
51887 + {
51888 + if (p_DfltConfig->rx_pri_elevation % BMI_FIFO_UNITS)
51889 + RETURN_ERROR(
51890 + MAJOR,
51891 + E_INVALID_VALUE,
51892 + ("rxFifoPriElevationLevel has to be divisible by %d", BMI_FIFO_UNITS));
51893 + if ((p_DfltConfig->rx_pri_elevation < BMI_FIFO_UNITS)
51894 + || (p_DfltConfig->rx_pri_elevation > MAX_PORT_FIFO_SIZE))
51895 + RETURN_ERROR(
51896 + MAJOR,
51897 + E_INVALID_VALUE,
51898 + ("rxFifoPriElevationLevel has to be in the range of 256 - %d", MAX_PORT_FIFO_SIZE));
51899 + if (p_DfltConfig->rx_fifo_thr % BMI_FIFO_UNITS)
51900 + RETURN_ERROR(
51901 + MAJOR,
51902 + E_INVALID_VALUE,
51903 + ("rxFifoThreshold has to be divisible by %d", BMI_FIFO_UNITS));
51904 + if ((p_DfltConfig->rx_fifo_thr < BMI_FIFO_UNITS)
51905 + || (p_DfltConfig->rx_fifo_thr > MAX_PORT_FIFO_SIZE))
51906 + RETURN_ERROR(
51907 + MAJOR,
51908 + E_INVALID_VALUE,
51909 + ("rxFifoThreshold has to be in the range of 256 - %d", MAX_PORT_FIFO_SIZE));
51910 +
51911 + /* Check that not larger than 16 */
51912 + if (p_DfltConfig->rx_cut_end_bytes > FRAME_END_DATA_SIZE)
51913 + RETURN_ERROR(
51914 + MAJOR,
51915 + E_INVALID_VALUE,
51916 + ("cutBytesFromEnd can't be larger than %d", FRAME_END_DATA_SIZE));
51917 +
51918 + if (FmSpCheckBufMargins(&p_Params->bufMargins) != E_OK)
51919 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, NO_MSG);
51920 +
51921 + /* extra FIFO size (allowed only to Rx ports) */
51922 + if (p_Params->setSizeOfFifo
51923 + && (p_FmPort->fifoBufs.extra % BMI_FIFO_UNITS))
51924 + RETURN_ERROR(
51925 + MAJOR,
51926 + E_INVALID_VALUE,
51927 + ("fifoBufs.extra has to be divisible by %d", BMI_FIFO_UNITS));
51928 +
51929 + if (p_Params->bufPoolDepletion.poolsGrpModeEnable
51930 + && !p_Params->bufPoolDepletion.numOfPools)
51931 + RETURN_ERROR(
51932 + MAJOR,
51933 + E_INVALID_VALUE,
51934 + ("bufPoolDepletion.numOfPools can not be 0 when poolsGrpModeEnable=TRUE"));
51935 +#ifdef FM_CSI_CFED_LIMIT
51936 + if (p_FmPort->fmRevInfo.majorRev == 4)
51937 + {
51938 + /* Check that not larger than 16 */
51939 + if (p_DfltConfig->rx_cut_end_bytes + p_DfltConfig->checksum_bytes_ignore > FRAME_END_DATA_SIZE)
51940 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("cheksumLastBytesIgnore + cutBytesFromEnd can't be larger than %d", FRAME_END_DATA_SIZE));
51941 + }
51942 +#endif /* FM_CSI_CFED_LIMIT */
51943 + }
51944 +
51945 + /****************************************/
51946 + /* Non Rx ports */
51947 + /****************************************/
51948 + /* extra FIFO size (allowed only to Rx ports) */
51949 + else
51950 + if (p_FmPort->fifoBufs.extra)
51951 + RETURN_ERROR(MAJOR, E_INVALID_VALUE,
51952 + (" No fifoBufs.extra for non Rx ports"));
51953 +
51954 + /****************************************/
51955 + /* Tx only */
51956 + /****************************************/
51957 + if ((p_FmPort->portType == e_FM_PORT_TYPE_TX)
51958 + || (p_FmPort->portType == e_FM_PORT_TYPE_TX_10G))
51959 + {
51960 + if (p_DfltConfig->tx_fifo_min_level % BMI_FIFO_UNITS)
51961 + RETURN_ERROR(
51962 + MAJOR,
51963 + E_INVALID_VALUE,
51964 + ("txFifoMinFillLevel has to be divisible by %d", BMI_FIFO_UNITS));
51965 + if (p_DfltConfig->tx_fifo_min_level > (MAX_PORT_FIFO_SIZE - 256))
51966 + RETURN_ERROR(
51967 + MAJOR,
51968 + E_INVALID_VALUE,
51969 + ("txFifoMinFillLevel has to be in the range of 0 - %d", (MAX_PORT_FIFO_SIZE - 256)));
51970 + if (p_DfltConfig->tx_fifo_low_comf_level % BMI_FIFO_UNITS)
51971 + RETURN_ERROR(
51972 + MAJOR,
51973 + E_INVALID_VALUE,
51974 + ("txFifoLowComfLevel has to be divisible by %d", BMI_FIFO_UNITS));
51975 + if ((p_DfltConfig->tx_fifo_low_comf_level < BMI_FIFO_UNITS)
51976 + || (p_DfltConfig->tx_fifo_low_comf_level > MAX_PORT_FIFO_SIZE))
51977 + RETURN_ERROR(
51978 + MAJOR,
51979 + E_INVALID_VALUE,
51980 + ("txFifoLowComfLevel has to be in the range of 256 - %d", MAX_PORT_FIFO_SIZE));
51981 +
51982 + if (p_FmPort->portType == e_FM_PORT_TYPE_TX)
51983 + if (p_FmPort->p_FmPortDriverParam->dfltCfg.tx_fifo_deq_pipeline_depth
51984 + > 2)
51985 + RETURN_ERROR(
51986 + MAJOR, E_INVALID_VALUE,
51987 + ("fifoDeqPipelineDepth for 1G can't be larger than 2"));
51988 + }
51989 +
51990 + /****************************************/
51991 + /* Non Tx Ports */
51992 + /****************************************/
51993 + /* If discard override was selected , no frames may be discarded. */
51994 + else
51995 + if (p_DfltConfig->discard_override && p_Params->errorsToDiscard)
51996 + RETURN_ERROR(
51997 + MAJOR,
51998 + E_CONFLICT,
51999 + ("errorsToDiscard is not empty, but frmDiscardOverride selected (all discarded frames to be enqueued to error queue)."));
52000 +
52001 + /****************************************/
52002 + /* Rx and Offline parsing */
52003 + /****************************************/
52004 + if ((p_FmPort->portType == e_FM_PORT_TYPE_RX)
52005 + || (p_FmPort->portType == e_FM_PORT_TYPE_RX_10G)
52006 + || (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING))
52007 + {
52008 + if (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING)
52009 + unusedMask = BMI_STATUS_OP_MASK_UNUSED;
52010 + else
52011 + unusedMask = BMI_STATUS_RX_MASK_UNUSED;
52012 +
52013 + /* Check that no common bits with BMI_STATUS_MASK_UNUSED */
52014 + if (p_Params->errorsToDiscard & unusedMask)
52015 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION,
52016 + ("errorsToDiscard contains undefined bits"));
52017 + }
52018 +
52019 + /****************************************/
52020 + /* Offline Ports */
52021 + /****************************************/
52022 +#ifdef FM_OP_OPEN_DMA_MIN_LIMIT
52023 + if ((p_FmPort->fmRevInfo.majorRev >= 6)
52024 + && (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING)
52025 + && p_Params->setNumOfOpenDmas
52026 + && (p_FmPort->openDmas.num < MIN_NUM_OF_OP_DMAS))
52027 + RETURN_ERROR(
52028 + MAJOR,
52029 + E_INVALID_VALUE,
52030 + ("For Offline port, openDmas.num can't be smaller than %d", MIN_NUM_OF_OP_DMAS));
52031 +#endif /* FM_OP_OPEN_DMA_MIN_LIMIT */
52032 +
52033 + /****************************************/
52034 + /* Offline & HC Ports */
52035 + /****************************************/
52036 + if ((p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING)
52037 + || (p_FmPort->portType == e_FM_PORT_TYPE_OH_HOST_COMMAND))
52038 + {
52039 +#ifndef FM_FRAME_END_PARAMS_FOR_OP
52040 + if ((p_FmPort->fmRevInfo.majorRev < 6) &&
52041 + (p_FmPort->p_FmPortDriverParam->cheksumLastBytesIgnore != DEFAULT_notSupported))
52042 + /* this is an indication that user called config for this mode which is not supported in this integration */
52043 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("cheksumLastBytesIgnore is available for Rx & Tx ports only"));
52044 +#endif /* !FM_FRAME_END_PARAMS_FOR_OP */
52045 +
52046 +#ifndef FM_DEQ_PIPELINE_PARAMS_FOR_OP
52047 + if ((!((p_FmPort->fmRevInfo.majorRev == 4) ||
52048 + (p_FmPort->fmRevInfo.majorRev >= 6))) &&
52049 + (p_FmPort->p_FmPortDriverParam->dfltCfg.tx_fifo_deq_pipeline_depth != DEFAULT_notSupported))
52050 + /* this is an indication that user called config for this mode which is not supported in this integration */
52051 + RETURN_ERROR(MAJOR, E_INVALID_OPERATION, ("fifoDeqPipelineDepth is available for Tx ports only"));
52052 +#endif /* !FM_DEQ_PIPELINE_PARAMS_FOR_OP */
52053 + }
52054 +
52055 + /****************************************/
52056 + /* All ports */
52057 + /****************************************/
52058 + /* Check that not larger than 16 */
52059 + if ((p_Params->cheksumLastBytesIgnore > FRAME_END_DATA_SIZE)
52060 + && ((p_Params->cheksumLastBytesIgnore != DEFAULT_notSupported)))
52061 + RETURN_ERROR(
52062 + MAJOR,
52063 + E_INVALID_VALUE,
52064 + ("cheksumLastBytesIgnore can't be larger than %d", FRAME_END_DATA_SIZE));
52065 +
52066 + if (FmSpCheckIntContextParams(&p_Params->intContext) != E_OK)
52067 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, NO_MSG);
52068 +
52069 + /* common BMI registers values */
52070 + if (p_Params->setNumOfTasks
52071 + && ((!p_FmPort->tasks.num)
52072 + || (p_FmPort->tasks.num > MAX_NUM_OF_TASKS)))
52073 + RETURN_ERROR(MAJOR, E_INVALID_VALUE,
52074 + ("tasks.num can't be larger than %d", MAX_NUM_OF_TASKS));
52075 + if (p_Params->setNumOfTasks
52076 + && (p_FmPort->tasks.extra > MAX_NUM_OF_EXTRA_TASKS))
52077 + RETURN_ERROR(
52078 + MAJOR,
52079 + E_INVALID_VALUE,
52080 + ("tasks.extra can't be larger than %d", MAX_NUM_OF_EXTRA_TASKS));
52081 + if (p_Params->setNumOfOpenDmas
52082 + && ((!p_FmPort->openDmas.num)
52083 + || (p_FmPort->openDmas.num > MAX_NUM_OF_DMAS)))
52084 + RETURN_ERROR(MAJOR, E_INVALID_VALUE,
52085 + ("openDmas.num can't be larger than %d", MAX_NUM_OF_DMAS));
52086 + if (p_Params->setNumOfOpenDmas
52087 + && (p_FmPort->openDmas.extra > MAX_NUM_OF_EXTRA_DMAS))
52088 + RETURN_ERROR(
52089 + MAJOR,
52090 + E_INVALID_VALUE,
52091 + ("openDmas.extra can't be larger than %d", MAX_NUM_OF_EXTRA_DMAS));
52092 + if (p_Params->setSizeOfFifo
52093 + && (!p_FmPort->fifoBufs.num
52094 + || (p_FmPort->fifoBufs.num > MAX_PORT_FIFO_SIZE)))
52095 + RETURN_ERROR(
52096 + MAJOR,
52097 + E_INVALID_VALUE,
52098 + ("fifoBufs.num has to be in the range of 256 - %d", MAX_PORT_FIFO_SIZE));
52099 + if (p_Params->setSizeOfFifo && (p_FmPort->fifoBufs.num % BMI_FIFO_UNITS))
52100 + RETURN_ERROR(
52101 + MAJOR, E_INVALID_VALUE,
52102 + ("fifoBufs.num has to be divisible by %d", BMI_FIFO_UNITS));
52103 +
52104 +#ifdef FM_QMI_NO_DEQ_OPTIONS_SUPPORT
52105 + if (p_FmPort->fmRevInfo.majorRev == 4)
52106 + if (p_FmPort->p_FmPortDriverParam->deqPrefetchOption != DEFAULT_notSupported)
52107 + /* this is an indication that user called config for this mode which is not supported in this integration */
52108 + RETURN_ERROR(MAJOR, E_INVALID_OPERATION, ("deqPrefetchOption"));
52109 +#endif /* FM_QMI_NO_DEQ_OPTIONS_SUPPORT */
52110 +
52111 + return E_OK;
52112 +}
52113 +
52114 +static t_Error VerifySizeOfFifo(t_FmPort *p_FmPort)
52115 +{
52116 + uint32_t minFifoSizeRequired = 0, optFifoSizeForB2B = 0;
52117 +
52118 + /*************************/
52119 + /* TX PORTS */
52120 + /*************************/
52121 + if ((p_FmPort->portType == e_FM_PORT_TYPE_TX)
52122 + || (p_FmPort->portType == e_FM_PORT_TYPE_TX_10G))
52123 + {
52124 + minFifoSizeRequired =
52125 + (uint32_t)(ROUND_UP(p_FmPort->maxFrameLength, BMI_FIFO_UNITS)
52126 + + (3 * BMI_FIFO_UNITS));
52127 + if (!p_FmPort->imEn)
52128 + minFifoSizeRequired +=
52129 + p_FmPort->p_FmPortDriverParam->dfltCfg.tx_fifo_deq_pipeline_depth
52130 + * BMI_FIFO_UNITS;
52131 +
52132 + optFifoSizeForB2B = minFifoSizeRequired;
52133 +
52134 + /* Add some margin for back-to-back capability to improve performance,
52135 + allows the hardware to pipeline new frame dma while the previous
52136 + frame not yet transmitted. */
52137 + if (p_FmPort->portType == e_FM_PORT_TYPE_TX_10G)
52138 + optFifoSizeForB2B += 3 * BMI_FIFO_UNITS;
52139 + else
52140 + optFifoSizeForB2B += 2 * BMI_FIFO_UNITS;
52141 + }
52142 +
52143 + /*************************/
52144 + /* RX IM PORTS */
52145 + /*************************/
52146 + else
52147 + if (((p_FmPort->portType == e_FM_PORT_TYPE_RX)
52148 + || (p_FmPort->portType == e_FM_PORT_TYPE_RX_10G))
52149 + && p_FmPort->imEn)
52150 + {
52151 + optFifoSizeForB2B =
52152 + minFifoSizeRequired =
52153 + (uint32_t)(ROUND_UP(p_FmPort->maxFrameLength, BMI_FIFO_UNITS)
52154 + + (4 * BMI_FIFO_UNITS));
52155 + }
52156 +
52157 + /*************************/
52158 + /* RX non-IM PORTS */
52159 + /*************************/
52160 + else
52161 + if (((p_FmPort->portType == e_FM_PORT_TYPE_RX)
52162 + || (p_FmPort->portType == e_FM_PORT_TYPE_RX_10G))
52163 + && !p_FmPort->imEn)
52164 + {
52165 + if (p_FmPort->fmRevInfo.majorRev == 4)
52166 + {
52167 + if (p_FmPort->rxPoolsParams.numOfPools == 1)
52168 + minFifoSizeRequired = 8 * BMI_FIFO_UNITS;
52169 + else
52170 + minFifoSizeRequired =
52171 + (uint32_t)(ROUND_UP(p_FmPort->rxPoolsParams.secondLargestBufSize, BMI_FIFO_UNITS)
52172 + + (7 * BMI_FIFO_UNITS));
52173 + }
52174 + else
52175 + {
52176 +#if (DPAA_VERSION >= 11)
52177 + minFifoSizeRequired =
52178 + (uint32_t)(ROUND_UP(p_FmPort->maxFrameLength, BMI_FIFO_UNITS)
52179 + + (5 * BMI_FIFO_UNITS));
52180 + /* 4 according to spec + 1 for FOF>0 */
52181 +#else
52182 + minFifoSizeRequired = (uint32_t)
52183 + (ROUND_UP(MIN(p_FmPort->maxFrameLength, p_FmPort->rxPoolsParams.largestBufSize), BMI_FIFO_UNITS)
52184 + + (7*BMI_FIFO_UNITS));
52185 +#endif /* (DPAA_VERSION >= 11) */
52186 + }
52187 +
52188 + optFifoSizeForB2B = minFifoSizeRequired;
52189 +
52190 + /* Add some margin for back-to-back capability to improve performance,
52191 + allows the hardware to pipeline new frame dma while the previous
52192 + frame not yet transmitted. */
52193 + if (p_FmPort->portType == e_FM_PORT_TYPE_RX_10G)
52194 + optFifoSizeForB2B += 8 * BMI_FIFO_UNITS;
52195 + else
52196 + optFifoSizeForB2B += 3 * BMI_FIFO_UNITS;
52197 + }
52198 +
52199 + /* For O/H ports, check fifo size and update if necessary */
52200 + else
52201 + if ((p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING)
52202 + || (p_FmPort->portType == e_FM_PORT_TYPE_OH_HOST_COMMAND))
52203 + {
52204 +#if (DPAA_VERSION >= 11)
52205 + optFifoSizeForB2B =
52206 + minFifoSizeRequired =
52207 + (uint32_t)(ROUND_UP(p_FmPort->maxFrameLength, BMI_FIFO_UNITS)
52208 + + ((p_FmPort->p_FmPortDriverParam->dfltCfg.tx_fifo_deq_pipeline_depth
52209 + + 5) * BMI_FIFO_UNITS));
52210 + /* 4 according to spec + 1 for FOF>0 */
52211 +#else
52212 + optFifoSizeForB2B = minFifoSizeRequired = (uint32_t)((p_FmPort->tasks.num + 2) * BMI_FIFO_UNITS);
52213 +#endif /* (DPAA_VERSION >= 11) */
52214 + }
52215 +
52216 + ASSERT_COND(minFifoSizeRequired > 0);
52217 + ASSERT_COND(optFifoSizeForB2B >= minFifoSizeRequired);
52218 +
52219 + /* Verify the size */
52220 + if (p_FmPort->fifoBufs.num < minFifoSizeRequired)
52221 + DBG(INFO,
52222 + ("FIFO size is %d and should be enlarged to %d bytes",p_FmPort->fifoBufs.num, minFifoSizeRequired));
52223 + else if (p_FmPort->fifoBufs.num < optFifoSizeForB2B)
52224 + DBG(INFO,
52225 + ("For back-to-back frames processing, FIFO size is %d and needs to enlarge to %d bytes", p_FmPort->fifoBufs.num, optFifoSizeForB2B));
52226 +
52227 + return E_OK;
52228 +}
52229 +
52230 +static void FmPortDriverParamFree(t_FmPort *p_FmPort)
52231 +{
52232 + if (p_FmPort->p_FmPortDriverParam)
52233 + {
52234 + XX_Free(p_FmPort->p_FmPortDriverParam);
52235 + p_FmPort->p_FmPortDriverParam = NULL;
52236 + }
52237 +}
52238 +
52239 +static t_Error SetExtBufferPools(t_FmPort *p_FmPort)
52240 +{
52241 + t_FmExtPools *p_ExtBufPools = &p_FmPort->p_FmPortDriverParam->extBufPools;
52242 + t_FmBufPoolDepletion *p_BufPoolDepletion =
52243 + &p_FmPort->p_FmPortDriverParam->bufPoolDepletion;
52244 + uint8_t orderedArray[FM_PORT_MAX_NUM_OF_EXT_POOLS];
52245 + uint16_t sizesArray[BM_MAX_NUM_OF_POOLS];
52246 + int i = 0, j = 0, err;
52247 + struct fman_port_bpools bpools;
52248 +
52249 + memset(&orderedArray, 0, sizeof(uint8_t) * FM_PORT_MAX_NUM_OF_EXT_POOLS);
52250 + memset(&sizesArray, 0, sizeof(uint16_t) * BM_MAX_NUM_OF_POOLS);
52251 + memcpy(&p_FmPort->extBufPools, p_ExtBufPools, sizeof(t_FmExtPools));
52252 +
52253 + FmSpSetBufPoolsInAscOrderOfBufSizes(p_ExtBufPools, orderedArray,
52254 + sizesArray);
52255 +
52256 + /* Prepare flibs bpools structure */
52257 + memset(&bpools, 0, sizeof(struct fman_port_bpools));
52258 + bpools.count = p_ExtBufPools->numOfPoolsUsed;
52259 + bpools.counters_enable = TRUE;
52260 + for (i = 0; i < p_ExtBufPools->numOfPoolsUsed; i++)
52261 + {
52262 + bpools.bpool[i].bpid = orderedArray[i];
52263 + bpools.bpool[i].size = sizesArray[orderedArray[i]];
52264 + /* functionality available only for some derivatives (limited by config) */
52265 + if (p_FmPort->p_FmPortDriverParam->p_BackupBmPools)
52266 + for (j = 0;
52267 + j
52268 + < p_FmPort->p_FmPortDriverParam->p_BackupBmPools->numOfBackupPools;
52269 + j++)
52270 + if (orderedArray[i]
52271 + == p_FmPort->p_FmPortDriverParam->p_BackupBmPools->poolIds[j])
52272 + {
52273 + bpools.bpool[i].is_backup = TRUE;
52274 + break;
52275 + }
52276 + }
52277 +
52278 + /* save pools parameters for later use */
52279 + p_FmPort->rxPoolsParams.numOfPools = p_ExtBufPools->numOfPoolsUsed;
52280 + p_FmPort->rxPoolsParams.largestBufSize =
52281 + sizesArray[orderedArray[p_ExtBufPools->numOfPoolsUsed - 1]];
52282 + p_FmPort->rxPoolsParams.secondLargestBufSize =
52283 + sizesArray[orderedArray[p_ExtBufPools->numOfPoolsUsed - 2]];
52284 +
52285 + /* FMBM_RMPD reg. - pool depletion */
52286 + if (p_BufPoolDepletion->poolsGrpModeEnable)
52287 + {
52288 + bpools.grp_bp_depleted_num = p_BufPoolDepletion->numOfPools;
52289 + for (i = 0; i < BM_MAX_NUM_OF_POOLS; i++)
52290 + {
52291 + if (p_BufPoolDepletion->poolsToConsider[i])
52292 + {
52293 + for (j = 0; j < p_ExtBufPools->numOfPoolsUsed; j++)
52294 + {
52295 + if (i == orderedArray[j])
52296 + {
52297 + bpools.bpool[j].grp_bp_depleted = TRUE;
52298 + break;
52299 + }
52300 + }
52301 + }
52302 + }
52303 + }
52304 +
52305 + if (p_BufPoolDepletion->singlePoolModeEnable)
52306 + {
52307 + for (i = 0; i < BM_MAX_NUM_OF_POOLS; i++)
52308 + {
52309 + if (p_BufPoolDepletion->poolsToConsiderForSingleMode[i])
52310 + {
52311 + for (j = 0; j < p_ExtBufPools->numOfPoolsUsed; j++)
52312 + {
52313 + if (i == orderedArray[j])
52314 + {
52315 + bpools.bpool[j].single_bp_depleted = TRUE;
52316 + break;
52317 + }
52318 + }
52319 + }
52320 + }
52321 + }
52322 +
52323 +#if (DPAA_VERSION >= 11)
52324 + /* fill QbbPEV */
52325 + if (p_BufPoolDepletion->poolsGrpModeEnable
52326 + || p_BufPoolDepletion->singlePoolModeEnable)
52327 + {
52328 + for (i = 0; i < FM_MAX_NUM_OF_PFC_PRIORITIES; i++)
52329 + {
52330 + if (p_BufPoolDepletion->pfcPrioritiesEn[i] == TRUE)
52331 + {
52332 + bpools.bpool[i].pfc_priorities_en = TRUE;
52333 + }
52334 + }
52335 + }
52336 +#endif /* (DPAA_VERSION >= 11) */
52337 +
52338 + /* Issue flibs function */
52339 + err = fman_port_set_bpools(&p_FmPort->port, &bpools);
52340 + if (err != 0)
52341 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("fman_port_set_bpools"));
52342 +
52343 + if (p_FmPort->p_FmPortDriverParam->p_BackupBmPools)
52344 + XX_Free(p_FmPort->p_FmPortDriverParam->p_BackupBmPools);
52345 +
52346 + return E_OK;
52347 +}
52348 +
52349 +static t_Error ClearPerfCnts(t_FmPort *p_FmPort)
52350 +{
52351 + if (p_FmPort->portType != e_FM_PORT_TYPE_OH_OFFLINE_PARSING)
52352 + FM_PORT_ModifyCounter(p_FmPort, e_FM_PORT_COUNTERS_QUEUE_UTIL, 0);
52353 + FM_PORT_ModifyCounter(p_FmPort, e_FM_PORT_COUNTERS_TASK_UTIL, 0);
52354 + FM_PORT_ModifyCounter(p_FmPort, e_FM_PORT_COUNTERS_DMA_UTIL, 0);
52355 + FM_PORT_ModifyCounter(p_FmPort, e_FM_PORT_COUNTERS_FIFO_UTIL, 0);
52356 + return E_OK;
52357 +}
52358 +
52359 +static t_Error InitLowLevelDriver(t_FmPort *p_FmPort)
52360 +{
52361 + t_FmPortDriverParam *p_DriverParams = p_FmPort->p_FmPortDriverParam;
52362 + struct fman_port_params portParams;
52363 + uint32_t tmpVal;
52364 + t_Error err;
52365 +
52366 + /* Set up flibs parameters and issue init function */
52367 +
52368 + memset(&portParams, 0, sizeof(struct fman_port_params));
52369 + portParams.discard_mask = p_DriverParams->errorsToDiscard;
52370 + portParams.dflt_fqid = p_DriverParams->dfltFqid;
52371 + portParams.err_fqid = p_DriverParams->errFqid;
52372 + portParams.deq_sp = p_DriverParams->deqSubPortal;
52373 + portParams.dont_release_buf = p_DriverParams->dontReleaseBuf;
52374 + switch (p_FmPort->portType)
52375 + {
52376 + case (e_FM_PORT_TYPE_RX_10G):
52377 + case (e_FM_PORT_TYPE_RX):
52378 + portParams.err_mask = (RX_ERRS_TO_ENQ & ~portParams.discard_mask);
52379 + if (!p_FmPort->imEn)
52380 + {
52381 + if (p_DriverParams->forwardReuseIntContext)
52382 + p_DriverParams->dfltCfg.rx_fd_bits =
52383 + (uint8_t)(BMI_PORT_RFNE_FRWD_RPD >> 24);
52384 + }
52385 + break;
52386 +
52387 + case (e_FM_PORT_TYPE_OH_OFFLINE_PARSING):
52388 + portParams.err_mask = (OP_ERRS_TO_ENQ & ~portParams.discard_mask);
52389 + break;
52390 + break;
52391 +
52392 + default:
52393 + break;
52394 + }
52395 +
52396 + tmpVal =
52397 + (uint32_t)(
52398 + (p_FmPort->internalBufferOffset % OFFSET_UNITS) ? (p_FmPort->internalBufferOffset
52399 + / OFFSET_UNITS + 1) :
52400 + (p_FmPort->internalBufferOffset / OFFSET_UNITS));
52401 + p_FmPort->internalBufferOffset = (uint8_t)(tmpVal * OFFSET_UNITS);
52402 + p_DriverParams->dfltCfg.int_buf_start_margin =
52403 + p_FmPort->internalBufferOffset;
52404 +
52405 + p_DriverParams->dfltCfg.ext_buf_start_margin =
52406 + p_DriverParams->bufMargins.startMargins;
52407 + p_DriverParams->dfltCfg.ext_buf_end_margin =
52408 + p_DriverParams->bufMargins.endMargins;
52409 +
52410 + p_DriverParams->dfltCfg.ic_ext_offset =
52411 + p_DriverParams->intContext.extBufOffset;
52412 + p_DriverParams->dfltCfg.ic_int_offset =
52413 + p_DriverParams->intContext.intContextOffset;
52414 + p_DriverParams->dfltCfg.ic_size = p_DriverParams->intContext.size;
52415 +
52416 + p_DriverParams->dfltCfg.stats_counters_enable = TRUE;
52417 + p_DriverParams->dfltCfg.perf_counters_enable = TRUE;
52418 + p_DriverParams->dfltCfg.queue_counters_enable = TRUE;
52419 +
52420 + p_DriverParams->dfltCfg.perf_cnt_params.task_val =
52421 + (uint8_t)p_FmPort->tasks.num;
52422 + if (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING ||
52423 + p_FmPort->portType == e_FM_PORT_TYPE_OH_HOST_COMMAND)p_DriverParams->dfltCfg.perf_cnt_params.queue_val = 0;
52424 + else
52425 + p_DriverParams->dfltCfg.perf_cnt_params.queue_val = 1;
52426 + p_DriverParams->dfltCfg.perf_cnt_params.dma_val =
52427 + (uint8_t)p_FmPort->openDmas.num;
52428 + p_DriverParams->dfltCfg.perf_cnt_params.fifo_val = p_FmPort->fifoBufs.num;
52429 +
52430 + if (0
52431 + != fman_port_init(&p_FmPort->port, &p_DriverParams->dfltCfg,
52432 + &portParams))
52433 + RETURN_ERROR(MAJOR, E_NO_DEVICE, ("fman_port_init"));
52434 +
52435 + if (p_FmPort->imEn && ((err = FmPortImInit(p_FmPort)) != E_OK))
52436 + RETURN_ERROR(MAJOR, err, NO_MSG);
52437 + else
52438 + {
52439 + // from QMIInit
52440 + if ((p_FmPort->portType != e_FM_PORT_TYPE_RX_10G)
52441 + && (p_FmPort->portType != e_FM_PORT_TYPE_RX))
52442 + {
52443 + if (p_DriverParams->deqPrefetchOption == e_FM_PORT_DEQ_NO_PREFETCH)
52444 + FmSetPortPreFetchConfiguration(p_FmPort->h_Fm, p_FmPort->portId,
52445 + FALSE);
52446 + else
52447 + FmSetPortPreFetchConfiguration(p_FmPort->h_Fm, p_FmPort->portId,
52448 + TRUE);
52449 + }
52450 + }
52451 + /* The code bellow is a trick so the FM will not release the buffer
52452 + to BM nor will try to enqueue the frame to QM */
52453 + if (((p_FmPort->portType == e_FM_PORT_TYPE_TX_10G)
52454 + || (p_FmPort->portType == e_FM_PORT_TYPE_TX)) && (!p_FmPort->imEn))
52455 + {
52456 + if (!p_DriverParams->dfltFqid && p_DriverParams->dontReleaseBuf)
52457 + {
52458 + /* override fmbm_tcfqid 0 with a false non-0 value. This will force FM to
52459 + * act according to tfene. Otherwise, if fmbm_tcfqid is 0 the FM will release
52460 + * buffers to BM regardless of fmbm_tfene
52461 + */
52462 + WRITE_UINT32(p_FmPort->port.bmi_regs->tx.fmbm_tcfqid, 0xFFFFFF);
52463 + WRITE_UINT32(p_FmPort->port.bmi_regs->tx.fmbm_tfene,
52464 + NIA_ENG_BMI | NIA_BMI_AC_TX_RELEASE);
52465 + }
52466 + }
52467 +
52468 + return E_OK;
52469 +}
52470 +
52471 +static bool CheckRxBmiCounter(t_FmPort *p_FmPort, e_FmPortCounters counter)
52472 +{
52473 + UNUSED(p_FmPort);
52474 +
52475 + switch (counter)
52476 + {
52477 + case (e_FM_PORT_COUNTERS_CYCLE):
52478 + case (e_FM_PORT_COUNTERS_TASK_UTIL):
52479 + case (e_FM_PORT_COUNTERS_QUEUE_UTIL):
52480 + case (e_FM_PORT_COUNTERS_DMA_UTIL):
52481 + case (e_FM_PORT_COUNTERS_FIFO_UTIL):
52482 + case (e_FM_PORT_COUNTERS_RX_PAUSE_ACTIVATION):
52483 + case (e_FM_PORT_COUNTERS_FRAME):
52484 + case (e_FM_PORT_COUNTERS_DISCARD_FRAME):
52485 + case (e_FM_PORT_COUNTERS_RX_BAD_FRAME):
52486 + case (e_FM_PORT_COUNTERS_RX_LARGE_FRAME):
52487 + case (e_FM_PORT_COUNTERS_RX_FILTER_FRAME):
52488 + case (e_FM_PORT_COUNTERS_RX_LIST_DMA_ERR):
52489 + case (e_FM_PORT_COUNTERS_RX_OUT_OF_BUFFERS_DISCARD):
52490 + case (e_FM_PORT_COUNTERS_DEALLOC_BUF):
52491 + case (e_FM_PORT_COUNTERS_PREPARE_TO_ENQUEUE_COUNTER):
52492 + return TRUE;
52493 + default:
52494 + return FALSE;
52495 + }
52496 +}
52497 +
52498 +static bool CheckTxBmiCounter(t_FmPort *p_FmPort, e_FmPortCounters counter)
52499 +{
52500 + UNUSED(p_FmPort);
52501 +
52502 + switch (counter)
52503 + {
52504 + case (e_FM_PORT_COUNTERS_CYCLE):
52505 + case (e_FM_PORT_COUNTERS_TASK_UTIL):
52506 + case (e_FM_PORT_COUNTERS_QUEUE_UTIL):
52507 + case (e_FM_PORT_COUNTERS_DMA_UTIL):
52508 + case (e_FM_PORT_COUNTERS_FIFO_UTIL):
52509 + case (e_FM_PORT_COUNTERS_FRAME):
52510 + case (e_FM_PORT_COUNTERS_DISCARD_FRAME):
52511 + case (e_FM_PORT_COUNTERS_LENGTH_ERR):
52512 + case (e_FM_PORT_COUNTERS_UNSUPPRTED_FORMAT):
52513 + case (e_FM_PORT_COUNTERS_DEALLOC_BUF):
52514 + return TRUE;
52515 + default:
52516 + return FALSE;
52517 + }
52518 +}
52519 +
52520 +static bool CheckOhBmiCounter(t_FmPort *p_FmPort, e_FmPortCounters counter)
52521 +{
52522 + switch (counter)
52523 + {
52524 + case (e_FM_PORT_COUNTERS_CYCLE):
52525 + case (e_FM_PORT_COUNTERS_TASK_UTIL):
52526 + case (e_FM_PORT_COUNTERS_DMA_UTIL):
52527 + case (e_FM_PORT_COUNTERS_FIFO_UTIL):
52528 + case (e_FM_PORT_COUNTERS_FRAME):
52529 + case (e_FM_PORT_COUNTERS_DISCARD_FRAME):
52530 + case (e_FM_PORT_COUNTERS_RX_LIST_DMA_ERR):
52531 + case (e_FM_PORT_COUNTERS_WRED_DISCARD):
52532 + case (e_FM_PORT_COUNTERS_LENGTH_ERR):
52533 + case (e_FM_PORT_COUNTERS_UNSUPPRTED_FORMAT):
52534 + case (e_FM_PORT_COUNTERS_DEALLOC_BUF):
52535 + return TRUE;
52536 + case (e_FM_PORT_COUNTERS_RX_FILTER_FRAME):
52537 + if (p_FmPort->portType == e_FM_PORT_TYPE_OH_HOST_COMMAND)
52538 + return FALSE;
52539 + else
52540 + return TRUE;
52541 + default:
52542 + return FALSE;
52543 + }
52544 +}
52545 +
52546 +static t_Error BmiPortCheckAndGetCounterType(
52547 + t_FmPort *p_FmPort, e_FmPortCounters counter,
52548 + enum fman_port_stats_counters *p_StatsType,
52549 + enum fman_port_perf_counters *p_PerfType, bool *p_IsStats)
52550 +{
52551 + volatile uint32_t *p_Reg;
52552 + bool isValid;
52553 +
52554 + switch (p_FmPort->portType)
52555 + {
52556 + case (e_FM_PORT_TYPE_RX_10G):
52557 + case (e_FM_PORT_TYPE_RX):
52558 + p_Reg = &p_FmPort->port.bmi_regs->rx.fmbm_rstc;
52559 + isValid = CheckRxBmiCounter(p_FmPort, counter);
52560 + break;
52561 + case (e_FM_PORT_TYPE_TX_10G):
52562 + case (e_FM_PORT_TYPE_TX):
52563 + p_Reg = &p_FmPort->port.bmi_regs->tx.fmbm_tstc;
52564 + isValid = CheckTxBmiCounter(p_FmPort, counter);
52565 + break;
52566 + case (e_FM_PORT_TYPE_OH_OFFLINE_PARSING):
52567 + case (e_FM_PORT_TYPE_OH_HOST_COMMAND):
52568 + p_Reg = &p_FmPort->port.bmi_regs->oh.fmbm_ostc;
52569 + isValid = CheckOhBmiCounter(p_FmPort, counter);
52570 + break;
52571 + default:
52572 + RETURN_ERROR(MINOR, E_INVALID_STATE, ("Unsupported port type"));
52573 + }
52574 +
52575 + if (!isValid)
52576 + RETURN_ERROR(MINOR, E_INVALID_STATE,
52577 + ("Requested counter is not available for this port type"));
52578 +
52579 + /* check that counters are enabled */
52580 + switch (counter)
52581 + {
52582 + case (e_FM_PORT_COUNTERS_CYCLE):
52583 + case (e_FM_PORT_COUNTERS_TASK_UTIL):
52584 + case (e_FM_PORT_COUNTERS_QUEUE_UTIL):
52585 + case (e_FM_PORT_COUNTERS_DMA_UTIL):
52586 + case (e_FM_PORT_COUNTERS_FIFO_UTIL):
52587 + case (e_FM_PORT_COUNTERS_RX_PAUSE_ACTIVATION):
52588 + /* performance counters - may be read when disabled */
52589 + *p_IsStats = FALSE;
52590 + break;
52591 + case (e_FM_PORT_COUNTERS_FRAME):
52592 + case (e_FM_PORT_COUNTERS_DISCARD_FRAME):
52593 + case (e_FM_PORT_COUNTERS_DEALLOC_BUF):
52594 + case (e_FM_PORT_COUNTERS_RX_BAD_FRAME):
52595 + case (e_FM_PORT_COUNTERS_RX_LARGE_FRAME):
52596 + case (e_FM_PORT_COUNTERS_RX_FILTER_FRAME):
52597 + case (e_FM_PORT_COUNTERS_RX_LIST_DMA_ERR):
52598 + case (e_FM_PORT_COUNTERS_RX_OUT_OF_BUFFERS_DISCARD):
52599 + case (e_FM_PORT_COUNTERS_LENGTH_ERR):
52600 + case (e_FM_PORT_COUNTERS_UNSUPPRTED_FORMAT):
52601 + case (e_FM_PORT_COUNTERS_WRED_DISCARD):
52602 + *p_IsStats = TRUE;
52603 + if (!(GET_UINT32(*p_Reg) & BMI_COUNTERS_EN))
52604 + RETURN_ERROR(MINOR, E_INVALID_STATE,
52605 + ("Requested counter was not enabled"));
52606 + break;
52607 + default:
52608 + break;
52609 + }
52610 +
52611 + /* Set counter */
52612 + switch (counter)
52613 + {
52614 + case (e_FM_PORT_COUNTERS_CYCLE):
52615 + *p_PerfType = E_FMAN_PORT_PERF_CNT_CYCLE;
52616 + break;
52617 + case (e_FM_PORT_COUNTERS_TASK_UTIL):
52618 + *p_PerfType = E_FMAN_PORT_PERF_CNT_TASK_UTIL;
52619 + break;
52620 + case (e_FM_PORT_COUNTERS_QUEUE_UTIL):
52621 + *p_PerfType = E_FMAN_PORT_PERF_CNT_QUEUE_UTIL;
52622 + break;
52623 + case (e_FM_PORT_COUNTERS_DMA_UTIL):
52624 + *p_PerfType = E_FMAN_PORT_PERF_CNT_DMA_UTIL;
52625 + break;
52626 + case (e_FM_PORT_COUNTERS_FIFO_UTIL):
52627 + *p_PerfType = E_FMAN_PORT_PERF_CNT_FIFO_UTIL;
52628 + break;
52629 + case (e_FM_PORT_COUNTERS_RX_PAUSE_ACTIVATION):
52630 + *p_PerfType = E_FMAN_PORT_PERF_CNT_RX_PAUSE;
52631 + break;
52632 + case (e_FM_PORT_COUNTERS_FRAME):
52633 + *p_StatsType = E_FMAN_PORT_STATS_CNT_FRAME;
52634 + break;
52635 + case (e_FM_PORT_COUNTERS_DISCARD_FRAME):
52636 + *p_StatsType = E_FMAN_PORT_STATS_CNT_DISCARD;
52637 + break;
52638 + case (e_FM_PORT_COUNTERS_DEALLOC_BUF):
52639 + *p_StatsType = E_FMAN_PORT_STATS_CNT_DEALLOC_BUF;
52640 + break;
52641 + case (e_FM_PORT_COUNTERS_RX_BAD_FRAME):
52642 + *p_StatsType = E_FMAN_PORT_STATS_CNT_RX_BAD_FRAME;
52643 + break;
52644 + case (e_FM_PORT_COUNTERS_RX_LARGE_FRAME):
52645 + *p_StatsType = E_FMAN_PORT_STATS_CNT_RX_LARGE_FRAME;
52646 + break;
52647 + case (e_FM_PORT_COUNTERS_RX_OUT_OF_BUFFERS_DISCARD):
52648 + *p_StatsType = E_FMAN_PORT_STATS_CNT_RX_OUT_OF_BUF;
52649 + break;
52650 + case (e_FM_PORT_COUNTERS_RX_FILTER_FRAME):
52651 + *p_StatsType = E_FMAN_PORT_STATS_CNT_FILTERED_FRAME;
52652 + break;
52653 + case (e_FM_PORT_COUNTERS_RX_LIST_DMA_ERR):
52654 + *p_StatsType = E_FMAN_PORT_STATS_CNT_DMA_ERR;
52655 + break;
52656 + case (e_FM_PORT_COUNTERS_WRED_DISCARD):
52657 + *p_StatsType = E_FMAN_PORT_STATS_CNT_WRED_DISCARD;
52658 + break;
52659 + case (e_FM_PORT_COUNTERS_LENGTH_ERR):
52660 + *p_StatsType = E_FMAN_PORT_STATS_CNT_LEN_ERR;
52661 + break;
52662 + case (e_FM_PORT_COUNTERS_UNSUPPRTED_FORMAT):
52663 + *p_StatsType = E_FMAN_PORT_STATS_CNT_UNSUPPORTED_FORMAT;
52664 + break;
52665 + default:
52666 + break;
52667 + }
52668 +
52669 + return E_OK;
52670 +}
52671 +
52672 +static t_Error AdditionalPrsParams(t_FmPort *p_FmPort,
52673 + t_FmPcdPrsAdditionalHdrParams *p_HdrParams,
52674 + uint32_t *p_SoftSeqAttachReg)
52675 +{
52676 + uint8_t hdrNum, Ipv4HdrNum;
52677 + u_FmPcdHdrPrsOpts *p_prsOpts;
52678 + uint32_t tmpReg = *p_SoftSeqAttachReg, tmpPrsOffset;
52679 +
52680 + if (IS_PRIVATE_HEADER(p_HdrParams->hdr)
52681 + || IS_SPECIAL_HEADER(p_HdrParams->hdr))
52682 + RETURN_ERROR(
52683 + MAJOR, E_NOT_SUPPORTED,
52684 + ("No additional parameters for private or special headers."));
52685 +
52686 + if (p_HdrParams->errDisable)
52687 + tmpReg |= PRS_HDR_ERROR_DIS;
52688 +
52689 + /* Set parser options */
52690 + if (p_HdrParams->usePrsOpts)
52691 + {
52692 + p_prsOpts = &p_HdrParams->prsOpts;
52693 + switch (p_HdrParams->hdr)
52694 + {
52695 + case (HEADER_TYPE_MPLS):
52696 + if (p_prsOpts->mplsPrsOptions.labelInterpretationEnable)
52697 + tmpReg |= PRS_HDR_MPLS_LBL_INTER_EN;
52698 + hdrNum = GetPrsHdrNum(p_prsOpts->mplsPrsOptions.nextParse);
52699 + if (hdrNum == ILLEGAL_HDR_NUM)
52700 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, NO_MSG);
52701 + Ipv4HdrNum = GetPrsHdrNum(HEADER_TYPE_IPv4);
52702 + if (hdrNum < Ipv4HdrNum)
52703 + RETURN_ERROR(MAJOR, E_INVALID_VALUE,
52704 + ("Header must be equal or higher than IPv4"));
52705 + tmpReg |= ((uint32_t)hdrNum * PRS_HDR_ENTRY_SIZE)
52706 + << PRS_HDR_MPLS_NEXT_HDR_SHIFT;
52707 + break;
52708 + case (HEADER_TYPE_PPPoE):
52709 + if (p_prsOpts->pppoePrsOptions.enableMTUCheck)
52710 + tmpReg |= PRS_HDR_PPPOE_MTU_CHECK_EN;
52711 + break;
52712 + case (HEADER_TYPE_IPv6):
52713 + if (p_prsOpts->ipv6PrsOptions.routingHdrEnable)
52714 + tmpReg |= PRS_HDR_IPV6_ROUTE_HDR_EN;
52715 + break;
52716 + case (HEADER_TYPE_TCP):
52717 + if (p_prsOpts->tcpPrsOptions.padIgnoreChecksum)
52718 + tmpReg |= PRS_HDR_TCP_PAD_REMOVAL;
52719 + else
52720 + tmpReg &= ~PRS_HDR_TCP_PAD_REMOVAL;
52721 + break;
52722 + case (HEADER_TYPE_UDP):
52723 + if (p_prsOpts->udpPrsOptions.padIgnoreChecksum)
52724 + tmpReg |= PRS_HDR_UDP_PAD_REMOVAL;
52725 + else
52726 + tmpReg &= ~PRS_HDR_UDP_PAD_REMOVAL;
52727 + break;
52728 + default:
52729 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Invalid header"));
52730 + }
52731 + }
52732 +
52733 + /* set software parsing (address is divided in 2 since parser uses 2 byte access. */
52734 + if (p_HdrParams->swPrsEnable)
52735 + {
52736 + tmpPrsOffset = FmPcdGetSwPrsOffset(p_FmPort->h_FmPcd, p_HdrParams->hdr,
52737 + p_HdrParams->indexPerHdr);
52738 + if (tmpPrsOffset == ILLEGAL_BASE)
52739 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, NO_MSG);
52740 + tmpReg |= (PRS_HDR_SW_PRS_EN | tmpPrsOffset);
52741 + }
52742 + *p_SoftSeqAttachReg = tmpReg;
52743 +
52744 + return E_OK;
52745 +}
52746 +
52747 +static uint32_t GetPortSchemeBindParams(
52748 + t_Handle h_FmPort, t_FmPcdKgInterModuleBindPortToSchemes *p_SchemeBind)
52749 +{
52750 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
52751 + uint32_t walking1Mask = 0x80000000, tmp;
52752 + uint8_t idx = 0;
52753 +
52754 + p_SchemeBind->netEnvId = p_FmPort->netEnvId;
52755 + p_SchemeBind->hardwarePortId = p_FmPort->hardwarePortId;
52756 + p_SchemeBind->useClsPlan = p_FmPort->useClsPlan;
52757 + p_SchemeBind->numOfSchemes = 0;
52758 + tmp = p_FmPort->schemesPerPortVector;
52759 + if (tmp)
52760 + {
52761 + while (tmp)
52762 + {
52763 + if (tmp & walking1Mask)
52764 + {
52765 + p_SchemeBind->schemesIds[p_SchemeBind->numOfSchemes] = idx;
52766 + p_SchemeBind->numOfSchemes++;
52767 + tmp &= ~walking1Mask;
52768 + }
52769 + walking1Mask >>= 1;
52770 + idx++;
52771 + }
52772 + }
52773 +
52774 + return tmp;
52775 +}
52776 +
52777 +static void FmPortCheckNApplyMacsec(t_Handle h_FmPort)
52778 +{
52779 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
52780 + volatile uint32_t *p_BmiCfgReg = NULL;
52781 + uint32_t macsecEn = BMI_PORT_CFG_EN_MACSEC;
52782 + uint32_t lcv, walking1Mask = 0x80000000;
52783 + uint8_t cnt = 0;
52784 +
52785 + ASSERT_COND(p_FmPort);
52786 + ASSERT_COND(p_FmPort->h_FmPcd);
52787 + ASSERT_COND(!p_FmPort->p_FmPortDriverParam);
52788 +
52789 + if ((p_FmPort->portType != e_FM_PORT_TYPE_RX_10G)
52790 + && (p_FmPort->portType != e_FM_PORT_TYPE_RX))
52791 + return;
52792 +
52793 + p_BmiCfgReg = &p_FmPort->port.bmi_regs->rx.fmbm_rcfg;
52794 + /* get LCV for MACSEC */
52795 + if ((lcv = FmPcdGetMacsecLcv(p_FmPort->h_FmPcd, p_FmPort->netEnvId))
52796 + != 0)
52797 + {
52798 + while (!(lcv & walking1Mask))
52799 + {
52800 + cnt++;
52801 + walking1Mask >>= 1;
52802 + }
52803 +
52804 + macsecEn |= (uint32_t)cnt << BMI_PORT_CFG_MS_SEL_SHIFT;
52805 + WRITE_UINT32(*p_BmiCfgReg, GET_UINT32(*p_BmiCfgReg) | macsecEn);
52806 + }
52807 +}
52808 +
52809 +static t_Error SetPcd(t_FmPort *p_FmPort, t_FmPortPcdParams *p_PcdParams)
52810 +{
52811 + t_Error err = E_OK;
52812 + uint32_t tmpReg;
52813 + volatile uint32_t *p_BmiNia = NULL;
52814 + volatile uint32_t *p_BmiPrsNia = NULL;
52815 + volatile uint32_t *p_BmiPrsStartOffset = NULL;
52816 + volatile uint32_t *p_BmiInitPrsResult = NULL;
52817 + volatile uint32_t *p_BmiCcBase = NULL;
52818 + uint16_t hdrNum, L3HdrNum, greHdrNum;
52819 + int i;
52820 + bool isEmptyClsPlanGrp;
52821 + uint32_t tmpHxs[FM_PCD_PRS_NUM_OF_HDRS];
52822 + uint16_t absoluteProfileId;
52823 + uint8_t physicalSchemeId;
52824 + uint32_t ccTreePhysOffset;
52825 + t_FmPcdKgInterModuleBindPortToSchemes schemeBind;
52826 + uint32_t initialSwPrs = 0;
52827 +
52828 + ASSERT_COND(p_FmPort);
52829 + SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE);
52830 +
52831 + if (p_FmPort->imEn)
52832 + RETURN_ERROR(MAJOR, E_INVALID_OPERATION,
52833 + ("available for non-independant mode ports only"));
52834 +
52835 + if ((p_FmPort->portType != e_FM_PORT_TYPE_RX_10G)
52836 + && (p_FmPort->portType != e_FM_PORT_TYPE_RX)
52837 + && (p_FmPort->portType != e_FM_PORT_TYPE_OH_OFFLINE_PARSING))
52838 + RETURN_ERROR(MAJOR, E_INVALID_OPERATION,
52839 + ("available for Rx and offline parsing ports only"));
52840 +
52841 + p_FmPort->netEnvId = FmPcdGetNetEnvId(p_PcdParams->h_NetEnv);
52842 +
52843 + p_FmPort->pcdEngines = 0;
52844 +
52845 + /* initialize p_FmPort->pcdEngines field in port's structure */
52846 + switch (p_PcdParams->pcdSupport)
52847 + {
52848 + case (e_FM_PORT_PCD_SUPPORT_NONE):
52849 + RETURN_ERROR(
52850 + MAJOR,
52851 + E_INVALID_STATE,
52852 + ("No PCD configuration required if e_FM_PORT_PCD_SUPPORT_NONE selected"));
52853 + case (e_FM_PORT_PCD_SUPPORT_PRS_ONLY):
52854 + p_FmPort->pcdEngines |= FM_PCD_PRS;
52855 + break;
52856 + case (e_FM_PORT_PCD_SUPPORT_PLCR_ONLY):
52857 + p_FmPort->pcdEngines |= FM_PCD_PLCR;
52858 + break;
52859 + case (e_FM_PORT_PCD_SUPPORT_PRS_AND_PLCR):
52860 + p_FmPort->pcdEngines |= FM_PCD_PRS;
52861 + p_FmPort->pcdEngines |= FM_PCD_PLCR;
52862 + break;
52863 + case (e_FM_PORT_PCD_SUPPORT_PRS_AND_KG):
52864 + p_FmPort->pcdEngines |= FM_PCD_PRS;
52865 + p_FmPort->pcdEngines |= FM_PCD_KG;
52866 + break;
52867 + case (e_FM_PORT_PCD_SUPPORT_PRS_AND_KG_AND_CC):
52868 + p_FmPort->pcdEngines |= FM_PCD_PRS;
52869 + p_FmPort->pcdEngines |= FM_PCD_CC;
52870 + p_FmPort->pcdEngines |= FM_PCD_KG;
52871 + break;
52872 + case (e_FM_PORT_PCD_SUPPORT_PRS_AND_KG_AND_CC_AND_PLCR):
52873 + p_FmPort->pcdEngines |= FM_PCD_PRS;
52874 + p_FmPort->pcdEngines |= FM_PCD_KG;
52875 + p_FmPort->pcdEngines |= FM_PCD_CC;
52876 + p_FmPort->pcdEngines |= FM_PCD_PLCR;
52877 + break;
52878 + case (e_FM_PORT_PCD_SUPPORT_PRS_AND_CC):
52879 + p_FmPort->pcdEngines |= FM_PCD_PRS;
52880 + p_FmPort->pcdEngines |= FM_PCD_CC;
52881 + break;
52882 + case (e_FM_PORT_PCD_SUPPORT_PRS_AND_CC_AND_PLCR):
52883 + p_FmPort->pcdEngines |= FM_PCD_PRS;
52884 + p_FmPort->pcdEngines |= FM_PCD_CC;
52885 + p_FmPort->pcdEngines |= FM_PCD_PLCR;
52886 + break;
52887 + case (e_FM_PORT_PCD_SUPPORT_PRS_AND_KG_AND_PLCR):
52888 + p_FmPort->pcdEngines |= FM_PCD_PRS;
52889 + p_FmPort->pcdEngines |= FM_PCD_KG;
52890 + p_FmPort->pcdEngines |= FM_PCD_PLCR;
52891 + break;
52892 + case (e_FM_PORT_PCD_SUPPORT_CC_ONLY):
52893 + p_FmPort->pcdEngines |= FM_PCD_CC;
52894 + break;
52895 +#ifdef FM_CAPWAP_SUPPORT
52896 + case (e_FM_PORT_PCD_SUPPORT_CC_AND_KG):
52897 + p_FmPort->pcdEngines |= FM_PCD_CC;
52898 + p_FmPort->pcdEngines |= FM_PCD_KG;
52899 + break;
52900 + case (e_FM_PORT_PCD_SUPPORT_CC_AND_KG_AND_PLCR):
52901 + p_FmPort->pcdEngines |= FM_PCD_CC;
52902 + p_FmPort->pcdEngines |= FM_PCD_KG;
52903 + p_FmPort->pcdEngines |= FM_PCD_PLCR;
52904 + break;
52905 +#endif /* FM_CAPWAP_SUPPORT */
52906 +
52907 + default:
52908 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("invalid pcdSupport"));
52909 + }
52910 +
52911 + if ((p_FmPort->pcdEngines & FM_PCD_PRS)
52912 + && (p_PcdParams->p_PrsParams->numOfHdrsWithAdditionalParams
52913 + > FM_PCD_PRS_NUM_OF_HDRS))
52914 + RETURN_ERROR(
52915 + MAJOR,
52916 + E_INVALID_VALUE,
52917 + ("Port parser numOfHdrsWithAdditionalParams may not exceed %d", FM_PCD_PRS_NUM_OF_HDRS));
52918 +
52919 + /* check that parameters exist for each and only each defined engine */
52920 + if ((!!(p_FmPort->pcdEngines & FM_PCD_PRS) != !!p_PcdParams->p_PrsParams)
52921 + || (!!(p_FmPort->pcdEngines & FM_PCD_KG)
52922 + != !!p_PcdParams->p_KgParams)
52923 + || (!!(p_FmPort->pcdEngines & FM_PCD_CC)
52924 + != !!p_PcdParams->p_CcParams))
52925 + RETURN_ERROR(
52926 + MAJOR,
52927 + E_INVALID_STATE,
52928 + ("PCD initialization structure is not consistent with pcdSupport"));
52929 +
52930 + /* get PCD registers pointers */
52931 + switch (p_FmPort->portType)
52932 + {
52933 + case (e_FM_PORT_TYPE_RX_10G):
52934 + case (e_FM_PORT_TYPE_RX):
52935 + p_BmiNia = &p_FmPort->port.bmi_regs->rx.fmbm_rfne;
52936 + p_BmiPrsNia = &p_FmPort->port.bmi_regs->rx.fmbm_rfpne;
52937 + p_BmiPrsStartOffset = &p_FmPort->port.bmi_regs->rx.fmbm_rpso;
52938 + p_BmiInitPrsResult = &p_FmPort->port.bmi_regs->rx.fmbm_rprai[0];
52939 + p_BmiCcBase = &p_FmPort->port.bmi_regs->rx.fmbm_rccb;
52940 + break;
52941 + case (e_FM_PORT_TYPE_OH_OFFLINE_PARSING):
52942 + p_BmiNia = &p_FmPort->port.bmi_regs->oh.fmbm_ofne;
52943 + p_BmiPrsNia = &p_FmPort->port.bmi_regs->oh.fmbm_ofpne;
52944 + p_BmiPrsStartOffset = &p_FmPort->port.bmi_regs->oh.fmbm_opso;
52945 + p_BmiInitPrsResult = &p_FmPort->port.bmi_regs->oh.fmbm_oprai[0];
52946 + p_BmiCcBase = &p_FmPort->port.bmi_regs->oh.fmbm_occb;
52947 + break;
52948 + default:
52949 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Invalid port type"));
52950 + }
52951 +
52952 + /* set PCD port parameter */
52953 + if (p_FmPort->pcdEngines & FM_PCD_CC)
52954 + {
52955 + err = FmPcdCcBindTree(p_FmPort->h_FmPcd, p_PcdParams,
52956 + p_PcdParams->p_CcParams->h_CcTree,
52957 + &ccTreePhysOffset, p_FmPort);
52958 + if (err)
52959 + RETURN_ERROR(MAJOR, err, NO_MSG);
52960 +
52961 + WRITE_UINT32(*p_BmiCcBase, ccTreePhysOffset);
52962 + p_FmPort->ccTreeId = p_PcdParams->p_CcParams->h_CcTree;
52963 + }
52964 +
52965 + if (p_FmPort->pcdEngines & FM_PCD_KG)
52966 + {
52967 + if (p_PcdParams->p_KgParams->numOfSchemes == 0)
52968 + RETURN_ERROR(
52969 + MAJOR,
52970 + E_INVALID_VALUE,
52971 + ("For ports using Keygen, at least one scheme must be bound. "));
52972 +
52973 + err = FmPcdKgSetOrBindToClsPlanGrp(p_FmPort->h_FmPcd,
52974 + p_FmPort->hardwarePortId,
52975 + p_FmPort->netEnvId,
52976 + p_FmPort->optArray,
52977 + &p_FmPort->clsPlanGrpId,
52978 + &isEmptyClsPlanGrp);
52979 + if (err)
52980 + RETURN_ERROR(MAJOR, E_INVALID_VALUE,
52981 + ("FmPcdKgSetOrBindToClsPlanGrp failed. "));
52982 +
52983 + p_FmPort->useClsPlan = !isEmptyClsPlanGrp;
52984 +
52985 + schemeBind.netEnvId = p_FmPort->netEnvId;
52986 + schemeBind.hardwarePortId = p_FmPort->hardwarePortId;
52987 + schemeBind.numOfSchemes = p_PcdParams->p_KgParams->numOfSchemes;
52988 + schemeBind.useClsPlan = p_FmPort->useClsPlan;
52989 +
52990 + /* for each scheme */
52991 + for (i = 0; i < p_PcdParams->p_KgParams->numOfSchemes; i++)
52992 + {
52993 + ASSERT_COND(p_PcdParams->p_KgParams->h_Schemes[i]);
52994 + physicalSchemeId = FmPcdKgGetSchemeId(
52995 + p_PcdParams->p_KgParams->h_Schemes[i]);
52996 + schemeBind.schemesIds[i] = physicalSchemeId;
52997 + /* build vector */
52998 + p_FmPort->schemesPerPortVector |= 1
52999 + << (31 - (uint32_t)physicalSchemeId);
53000 +#if (DPAA_VERSION >= 11)
53001 + /*because of the state that VSPE is defined per port - all PCD path should be according to this requirement
53002 + if !VSPE - in port, for relevant scheme VSPE can not be set*/
53003 + if (!p_FmPort->vspe
53004 + && FmPcdKgGetVspe((p_PcdParams->p_KgParams->h_Schemes[i])))
53005 + RETURN_ERROR(MAJOR, E_INVALID_STATE,
53006 + ("VSPE is not at port level"));
53007 +#endif /* (DPAA_VERSION >= 11) */
53008 + }
53009 +
53010 + err = FmPcdKgBindPortToSchemes(p_FmPort->h_FmPcd, &schemeBind);
53011 + if (err)
53012 + RETURN_ERROR(MAJOR, err, NO_MSG);
53013 + }
53014 +
53015 + /***************************/
53016 + /* configure NIA after BMI */
53017 + /***************************/
53018 + /* rfne may contain FDCS bits, so first we read them. */
53019 + p_FmPort->savedBmiNia = GET_UINT32(*p_BmiNia) & BMI_RFNE_FDCS_MASK;
53020 +
53021 + /* If policer is used directly after BMI or PRS */
53022 + if ((p_FmPort->pcdEngines & FM_PCD_PLCR)
53023 + && ((p_PcdParams->pcdSupport == e_FM_PORT_PCD_SUPPORT_PLCR_ONLY)
53024 + || (p_PcdParams->pcdSupport
53025 + == e_FM_PORT_PCD_SUPPORT_PRS_AND_PLCR)))
53026 + {
53027 + if (!p_PcdParams->p_PlcrParams->h_Profile)
53028 + RETURN_ERROR(MAJOR, E_INVALID_STATE,
53029 + ("Profile should be initialized"));
53030 +
53031 + absoluteProfileId = (uint16_t)FmPcdPlcrProfileGetAbsoluteId(
53032 + p_PcdParams->p_PlcrParams->h_Profile);
53033 +
53034 + if (!FmPcdPlcrIsProfileValid(p_FmPort->h_FmPcd, absoluteProfileId))
53035 + RETURN_ERROR(MAJOR, E_INVALID_STATE,
53036 + ("Private port profile not valid."));
53037 +
53038 + tmpReg = (uint32_t)(absoluteProfileId | NIA_PLCR_ABSOLUTE);
53039 +
53040 + if (p_FmPort->pcdEngines & FM_PCD_PRS) /* e_FM_PCD_SUPPORT_PRS_AND_PLCR */
53041 + /* update BMI HPNIA */
53042 + WRITE_UINT32(*p_BmiPrsNia, (uint32_t)(NIA_ENG_PLCR | tmpReg));
53043 + else
53044 + /* e_FM_PCD_SUPPORT_PLCR_ONLY */
53045 + /* update BMI NIA */
53046 + p_FmPort->savedBmiNia |= (uint32_t)(NIA_ENG_PLCR);
53047 + }
53048 +
53049 + /* if CC is used directly after BMI */
53050 + if ((p_PcdParams->pcdSupport == e_FM_PORT_PCD_SUPPORT_CC_ONLY)
53051 +#ifdef FM_CAPWAP_SUPPORT
53052 + || (p_PcdParams->pcdSupport == e_FM_PORT_PCD_SUPPORT_CC_AND_KG)
53053 + || (p_PcdParams->pcdSupport == e_FM_PORT_PCD_SUPPORT_CC_AND_KG_AND_PLCR)
53054 +#endif /* FM_CAPWAP_SUPPORT */
53055 + )
53056 + {
53057 + if (p_FmPort->portType != e_FM_PORT_TYPE_OH_OFFLINE_PARSING)
53058 + RETURN_ERROR(
53059 + MAJOR,
53060 + E_INVALID_OPERATION,
53061 + ("e_FM_PORT_PCD_SUPPORT_CC_xx available for offline parsing ports only"));
53062 + p_FmPort->savedBmiNia |= (uint32_t)(NIA_ENG_FM_CTL | NIA_FM_CTL_AC_CC);
53063 + /* check that prs start offset == RIM[FOF] */
53064 + }
53065 +
53066 + if (p_FmPort->pcdEngines & FM_PCD_PRS)
53067 + {
53068 + ASSERT_COND(p_PcdParams->p_PrsParams);
53069 +#if (DPAA_VERSION >= 11)
53070 + if (p_PcdParams->p_PrsParams->firstPrsHdr == HEADER_TYPE_CAPWAP)
53071 + hdrNum = OFFLOAD_SW_PATCH_CAPWAP_LABEL;
53072 + else
53073 + {
53074 +#endif /* (DPAA_VERSION >= 11) */
53075 + /* if PRS is used it is always first */
53076 + hdrNum = GetPrsHdrNum(p_PcdParams->p_PrsParams->firstPrsHdr);
53077 + if (hdrNum == ILLEGAL_HDR_NUM)
53078 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("Unsupported header."));
53079 +#if (DPAA_VERSION >= 11)
53080 + }
53081 +#endif /* (DPAA_VERSION >= 11) */
53082 + p_FmPort->savedBmiNia |= (uint32_t)(NIA_ENG_PRS | (uint32_t)(hdrNum));
53083 + /* set after parser NIA */
53084 + tmpReg = 0;
53085 + switch (p_PcdParams->pcdSupport)
53086 + {
53087 + case (e_FM_PORT_PCD_SUPPORT_PRS_ONLY):
53088 + WRITE_UINT32(*p_BmiPrsNia,
53089 + GET_NIA_BMI_AC_ENQ_FRAME(p_FmPort->h_FmPcd));
53090 + break;
53091 + case (e_FM_PORT_PCD_SUPPORT_PRS_AND_KG_AND_CC):
53092 + case (e_FM_PORT_PCD_SUPPORT_PRS_AND_KG_AND_CC_AND_PLCR):
53093 + tmpReg = NIA_KG_CC_EN;
53094 + case (e_FM_PORT_PCD_SUPPORT_PRS_AND_KG):
53095 + case (e_FM_PORT_PCD_SUPPORT_PRS_AND_KG_AND_PLCR):
53096 + if (p_PcdParams->p_KgParams->directScheme)
53097 + {
53098 + physicalSchemeId = FmPcdKgGetSchemeId(
53099 + p_PcdParams->p_KgParams->h_DirectScheme);
53100 + /* check that this scheme was bound to this port */
53101 + for (i = 0; i < p_PcdParams->p_KgParams->numOfSchemes; i++)
53102 + if (p_PcdParams->p_KgParams->h_DirectScheme
53103 + == p_PcdParams->p_KgParams->h_Schemes[i])
53104 + break;
53105 + if (i == p_PcdParams->p_KgParams->numOfSchemes)
53106 + RETURN_ERROR(
53107 + MAJOR,
53108 + E_INVALID_VALUE,
53109 + ("Direct scheme is not one of the port selected schemes."));
53110 + tmpReg |= (uint32_t)(NIA_KG_DIRECT | physicalSchemeId);
53111 + }
53112 + WRITE_UINT32(*p_BmiPrsNia, NIA_ENG_KG | tmpReg);
53113 + break;
53114 + case (e_FM_PORT_PCD_SUPPORT_PRS_AND_CC):
53115 + case (e_FM_PORT_PCD_SUPPORT_PRS_AND_CC_AND_PLCR):
53116 + WRITE_UINT32(*p_BmiPrsNia,
53117 + (uint32_t)(NIA_ENG_FM_CTL | NIA_FM_CTL_AC_CC));
53118 + break;
53119 + case (e_FM_PORT_PCD_SUPPORT_PRS_AND_PLCR):
53120 + break;
53121 + default:
53122 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Invalid PCD support"));
53123 + }
53124 +
53125 + /* set start parsing offset */
53126 + WRITE_UINT32(*p_BmiPrsStartOffset,
53127 + p_PcdParams->p_PrsParams->parsingOffset);
53128 +
53129 + /************************************/
53130 + /* Parser port parameters */
53131 + /************************************/
53132 + /* stop before configuring */
53133 + WRITE_UINT32(p_FmPort->p_FmPortPrsRegs->pcac, PRS_CAC_STOP);
53134 + /* wait for parser to be in idle state */
53135 + while (GET_UINT32(p_FmPort->p_FmPortPrsRegs->pcac) & PRS_CAC_ACTIVE)
53136 + ;
53137 +
53138 + /* set soft seq attachment register */
53139 + memset(tmpHxs, 0, FM_PCD_PRS_NUM_OF_HDRS * sizeof(uint32_t));
53140 +
53141 + /* set protocol options */
53142 + for (i = 0; p_FmPort->optArray[i]; i++)
53143 + switch (p_FmPort->optArray[i])
53144 + {
53145 + case (ETH_BROADCAST):
53146 + hdrNum = GetPrsHdrNum(HEADER_TYPE_ETH);
53147 + tmpHxs[hdrNum] |= (i + 1) << PRS_HDR_ETH_BC_SHIFT;
53148 + break;
53149 + case (ETH_MULTICAST):
53150 + hdrNum = GetPrsHdrNum(HEADER_TYPE_ETH);
53151 + tmpHxs[hdrNum] |= (i + 1) << PRS_HDR_ETH_MC_SHIFT;
53152 + break;
53153 + case (VLAN_STACKED):
53154 + hdrNum = GetPrsHdrNum(HEADER_TYPE_VLAN);
53155 + tmpHxs[hdrNum] |= (i + 1) << PRS_HDR_VLAN_STACKED_SHIFT;
53156 + break;
53157 + case (MPLS_STACKED):
53158 + hdrNum = GetPrsHdrNum(HEADER_TYPE_MPLS);
53159 + tmpHxs[hdrNum] |= (i + 1) << PRS_HDR_MPLS_STACKED_SHIFT;
53160 + break;
53161 + case (IPV4_BROADCAST_1):
53162 + hdrNum = GetPrsHdrNum(HEADER_TYPE_IPv4);
53163 + tmpHxs[hdrNum] |= (i + 1) << PRS_HDR_IPV4_1_BC_SHIFT;
53164 + break;
53165 + case (IPV4_MULTICAST_1):
53166 + hdrNum = GetPrsHdrNum(HEADER_TYPE_IPv4);
53167 + tmpHxs[hdrNum] |= (i + 1) << PRS_HDR_IPV4_1_MC_SHIFT;
53168 + break;
53169 + case (IPV4_UNICAST_2):
53170 + hdrNum = GetPrsHdrNum(HEADER_TYPE_IPv4);
53171 + tmpHxs[hdrNum] |= (i + 1) << PRS_HDR_IPV4_2_UC_SHIFT;
53172 + break;
53173 + case (IPV4_MULTICAST_BROADCAST_2):
53174 + hdrNum = GetPrsHdrNum(HEADER_TYPE_IPv4);
53175 + tmpHxs[hdrNum] |= (i + 1) << PRS_HDR_IPV4_2_MC_BC_SHIFT;
53176 + break;
53177 + case (IPV6_MULTICAST_1):
53178 + hdrNum = GetPrsHdrNum(HEADER_TYPE_IPv6);
53179 + tmpHxs[hdrNum] |= (i + 1) << PRS_HDR_IPV6_1_MC_SHIFT;
53180 + break;
53181 + case (IPV6_UNICAST_2):
53182 + hdrNum = GetPrsHdrNum(HEADER_TYPE_IPv6);
53183 + tmpHxs[hdrNum] |= (i + 1) << PRS_HDR_IPV6_2_UC_SHIFT;
53184 + break;
53185 + case (IPV6_MULTICAST_2):
53186 + hdrNum = GetPrsHdrNum(HEADER_TYPE_IPv6);
53187 + tmpHxs[hdrNum] |= (i + 1) << PRS_HDR_IPV6_2_MC_SHIFT;
53188 + break;
53189 + }
53190 +
53191 + if (FmPcdNetEnvIsHdrExist(p_FmPort->h_FmPcd, p_FmPort->netEnvId,
53192 + HEADER_TYPE_UDP_ENCAP_ESP))
53193 + {
53194 + if (p_PcdParams->p_PrsParams->numOfHdrsWithAdditionalParams == FM_PCD_PRS_NUM_OF_HDRS)
53195 + RETURN_ERROR(
53196 + MINOR, E_INVALID_VALUE,
53197 + ("If HEADER_TYPE_UDP_ENCAP_ESP is used, numOfHdrsWithAdditionalParams may be up to FM_PCD_PRS_NUM_OF_HDRS - 1"));
53198 +
53199 + p_PcdParams->p_PrsParams->additionalParams[p_PcdParams->p_PrsParams->numOfHdrsWithAdditionalParams].hdr =
53200 + HEADER_TYPE_UDP;
53201 + p_PcdParams->p_PrsParams->additionalParams[p_PcdParams->p_PrsParams->numOfHdrsWithAdditionalParams].swPrsEnable =
53202 + TRUE;
53203 + p_PcdParams->p_PrsParams->numOfHdrsWithAdditionalParams++;
53204 + }
53205 +
53206 + /* set MPLS default next header - HW reset workaround */
53207 + hdrNum = GetPrsHdrNum(HEADER_TYPE_MPLS);
53208 + tmpHxs[hdrNum] |= PRS_HDR_MPLS_LBL_INTER_EN;
53209 + L3HdrNum = GetPrsHdrNum(HEADER_TYPE_USER_DEFINED_L3);
53210 + tmpHxs[hdrNum] |= (uint32_t)L3HdrNum << PRS_HDR_MPLS_NEXT_HDR_SHIFT;
53211 +
53212 + /* for GRE, disable errors */
53213 + greHdrNum = GetPrsHdrNum(HEADER_TYPE_GRE);
53214 + tmpHxs[greHdrNum] |= PRS_HDR_ERROR_DIS;
53215 +
53216 + /* For UDP remove PAD from L4 checksum calculation */
53217 + hdrNum = GetPrsHdrNum(HEADER_TYPE_UDP);
53218 + tmpHxs[hdrNum] |= PRS_HDR_UDP_PAD_REMOVAL;
53219 + /* For TCP remove PAD from L4 checksum calculation */
53220 + hdrNum = GetPrsHdrNum(HEADER_TYPE_TCP);
53221 + tmpHxs[hdrNum] |= PRS_HDR_TCP_PAD_REMOVAL;
53222 +
53223 + /* config additional params for specific headers */
53224 + for (i = 0; i < p_PcdParams->p_PrsParams->numOfHdrsWithAdditionalParams;
53225 + i++)
53226 + {
53227 + /* case for using sw parser as the initial NIA address, before
53228 + * HW parsing
53229 + */
53230 + if ((p_PcdParams->p_PrsParams->additionalParams[i].hdr == HEADER_TYPE_NONE) &&
53231 + p_PcdParams->p_PrsParams->additionalParams[i].swPrsEnable)
53232 + {
53233 + initialSwPrs = FmPcdGetSwPrsOffset(p_FmPort->h_FmPcd, HEADER_TYPE_NONE,
53234 + p_PcdParams->p_PrsParams->additionalParams[i].indexPerHdr);
53235 + if (initialSwPrs == ILLEGAL_BASE)
53236 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, NO_MSG);
53237 +
53238 + /* clear parser first HXS */
53239 + p_FmPort->savedBmiNia &= ~BMI_RFNE_HXS_MASK; /* 0x000000FF */
53240 + /* rewrite with soft parser start */
53241 + p_FmPort->savedBmiNia |= initialSwPrs;
53242 + continue;
53243 + }
53244 +
53245 + hdrNum =
53246 + GetPrsHdrNum(p_PcdParams->p_PrsParams->additionalParams[i].hdr);
53247 + if (hdrNum == ILLEGAL_HDR_NUM)
53248 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, NO_MSG);
53249 + if (hdrNum == NO_HDR_NUM)
53250 + RETURN_ERROR(
53251 + MAJOR, E_INVALID_VALUE,
53252 + ("Private headers may not use additional parameters"));
53253 +
53254 + err = AdditionalPrsParams(
53255 + p_FmPort, &p_PcdParams->p_PrsParams->additionalParams[i],
53256 + &tmpHxs[hdrNum]);
53257 + if (err)
53258 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, NO_MSG);
53259 + }
53260 +
53261 + /* Check if ip-reassembly port - need to link sw-parser code */
53262 + if (p_FmPort->h_IpReassemblyManip)
53263 + {
53264 + /* link to sw parser code for IP Frag - only if no other code is applied. */
53265 + hdrNum = GetPrsHdrNum(HEADER_TYPE_IPv4);
53266 + if (!(tmpHxs[hdrNum] & PRS_HDR_SW_PRS_EN))
53267 + tmpHxs[hdrNum] |= (PRS_HDR_SW_PRS_EN | OFFLOAD_SW_PATCH_IPv4_IPR_LABEL);
53268 + hdrNum = GetPrsHdrNum(HEADER_TYPE_IPv6);
53269 + if (!(tmpHxs[hdrNum] & PRS_HDR_SW_PRS_EN))
53270 + tmpHxs[hdrNum] |= (PRS_HDR_SW_PRS_EN | OFFLOAD_SW_PATCH_IPv6_IPR_LABEL);
53271 + } else {
53272 + if (FmPcdNetEnvIsHdrExist(p_FmPort->h_FmPcd, p_FmPort->netEnvId, HEADER_TYPE_UDP_LITE))
53273 + {
53274 + hdrNum = GetPrsHdrNum(HEADER_TYPE_IPv6);
53275 + if (!(tmpHxs[hdrNum] & PRS_HDR_SW_PRS_EN))
53276 + tmpHxs[hdrNum] |= (PRS_HDR_SW_PRS_EN | OFFLOAD_SW_PATCH_IPv6_IPF_LABEL);
53277 + } else if ((FmPcdIsAdvancedOffloadSupported(p_FmPort->h_FmPcd)
53278 + && (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING)))
53279 + {
53280 + hdrNum = GetPrsHdrNum(HEADER_TYPE_IPv6);
53281 + if (!(tmpHxs[hdrNum] & PRS_HDR_SW_PRS_EN))
53282 + tmpHxs[hdrNum] |= (PRS_HDR_SW_PRS_EN | OFFLOAD_SW_PATCH_IPv6_IPF_LABEL);
53283 + }
53284 + }
53285 +
53286 +#if ((DPAA_VERSION == 10) && defined(FM_CAPWAP_SUPPORT))
53287 + if (FmPcdNetEnvIsHdrExist(p_FmPort->h_FmPcd, p_FmPort->netEnvId,
53288 + HEADER_TYPE_UDP_LITE))
53289 + {
53290 + /* link to sw parser code for udp lite - only if no other code is applied. */
53291 + hdrNum = GetPrsHdrNum(HEADER_TYPE_IPv6);
53292 + if (!(tmpHxs[hdrNum] & PRS_HDR_SW_PRS_EN))
53293 + tmpHxs[hdrNum] |= (PRS_HDR_SW_PRS_EN | UDP_LITE_SW_PATCH_LABEL);
53294 + }
53295 +#endif /* ((DPAA_VERSION == 10) && defined(FM_CAPWAP_SUPPORT)) */
53296 + for (i = 0; i < FM_PCD_PRS_NUM_OF_HDRS; i++)
53297 + {
53298 + /* For all header set LCV as taken from netEnv*/
53299 + WRITE_UINT32(
53300 + p_FmPort->p_FmPortPrsRegs->hdrs[i].lcv,
53301 + FmPcdGetLcv(p_FmPort->h_FmPcd, p_FmPort->netEnvId, (uint8_t)i));
53302 + /* set HXS register according to default+Additional params+protocol options */
53303 + WRITE_UINT32(p_FmPort->p_FmPortPrsRegs->hdrs[i].softSeqAttach,
53304 + tmpHxs[i]);
53305 + }
53306 +
53307 + /* set tpid. */
53308 + tmpReg = PRS_TPID_DFLT;
53309 + if (p_PcdParams->p_PrsParams->setVlanTpid1)
53310 + {
53311 + tmpReg &= PRS_TPID2_MASK;
53312 + tmpReg |= (uint32_t)p_PcdParams->p_PrsParams->vlanTpid1
53313 + << PRS_PCTPID_SHIFT;
53314 + }
53315 + if (p_PcdParams->p_PrsParams->setVlanTpid2)
53316 + {
53317 + tmpReg &= PRS_TPID1_MASK;
53318 + tmpReg |= (uint32_t)p_PcdParams->p_PrsParams->vlanTpid2;
53319 + }WRITE_UINT32(p_FmPort->p_FmPortPrsRegs->pctpid, tmpReg);
53320 +
53321 + /* enable parser */
53322 + WRITE_UINT32(p_FmPort->p_FmPortPrsRegs->pcac, 0);
53323 +
53324 + if (p_PcdParams->p_PrsParams->prsResultPrivateInfo)
53325 + p_FmPort->privateInfo =
53326 + p_PcdParams->p_PrsParams->prsResultPrivateInfo;
53327 +
53328 + } /* end parser */
53329 + else {
53330 + if (FmPcdIsAdvancedOffloadSupported(p_FmPort->h_FmPcd)
53331 + && (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING))
53332 + {
53333 + hdrNum = GetPrsHdrNum(HEADER_TYPE_IPv6);
53334 + WRITE_UINT32(p_FmPort->p_FmPortPrsRegs->hdrs[hdrNum].softSeqAttach,
53335 + (PRS_HDR_SW_PRS_EN | OFFLOAD_SW_PATCH_IPv6_IPF_LABEL));
53336 + }
53337 +
53338 + WRITE_UINT32(*p_BmiPrsStartOffset, 0);
53339 +
53340 + p_FmPort->privateInfo = 0;
53341 + }
53342 +
53343 + FmPortCheckNApplyMacsec(p_FmPort);
53344 +
53345 + WRITE_UINT32(
53346 + *p_BmiPrsStartOffset,
53347 + GET_UINT32(*p_BmiPrsStartOffset) + p_FmPort->internalBufferOffset);
53348 +
53349 + /* set initial parser result - used for all engines */
53350 + for (i = 0; i < FM_PORT_PRS_RESULT_NUM_OF_WORDS; i++)
53351 + {
53352 + if (!i)
53353 + WRITE_UINT32(
53354 + *(p_BmiInitPrsResult),
53355 + (uint32_t)(((uint32_t)p_FmPort->privateInfo << BMI_PR_PORTID_SHIFT) | BMI_PRS_RESULT_HIGH));
53356 + else
53357 + {
53358 + if (i < FM_PORT_PRS_RESULT_NUM_OF_WORDS / 2)
53359 + WRITE_UINT32(*(p_BmiInitPrsResult+i), BMI_PRS_RESULT_HIGH);
53360 + else
53361 + WRITE_UINT32(*(p_BmiInitPrsResult+i), BMI_PRS_RESULT_LOW);
53362 + }
53363 + }
53364 +
53365 + return E_OK;
53366 +}
53367 +
53368 +static t_Error DeletePcd(t_FmPort *p_FmPort)
53369 +{
53370 + t_Error err = E_OK;
53371 + volatile uint32_t *p_BmiNia = NULL;
53372 + volatile uint32_t *p_BmiPrsStartOffset = NULL;
53373 +
53374 + ASSERT_COND(p_FmPort);
53375 + SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE);
53376 +
53377 + if (p_FmPort->imEn)
53378 + RETURN_ERROR(MAJOR, E_INVALID_OPERATION,
53379 + ("available for non-independant mode ports only"));
53380 +
53381 + if ((p_FmPort->portType != e_FM_PORT_TYPE_RX_10G)
53382 + && (p_FmPort->portType != e_FM_PORT_TYPE_RX)
53383 + && (p_FmPort->portType != e_FM_PORT_TYPE_OH_OFFLINE_PARSING))
53384 + RETURN_ERROR( MAJOR, E_INVALID_OPERATION,
53385 + ("available for Rx and offline parsing ports only"));
53386 +
53387 + if (!p_FmPort->pcdEngines)
53388 + RETURN_ERROR(MAJOR, E_INVALID_OPERATION, ("called for non PCD port"));
53389 +
53390 + /* get PCD registers pointers */
53391 + switch (p_FmPort->portType)
53392 + {
53393 + case (e_FM_PORT_TYPE_RX_10G):
53394 + case (e_FM_PORT_TYPE_RX):
53395 + p_BmiNia = &p_FmPort->port.bmi_regs->rx.fmbm_rfne;
53396 + p_BmiPrsStartOffset = &p_FmPort->port.bmi_regs->rx.fmbm_rpso;
53397 + break;
53398 + case (e_FM_PORT_TYPE_OH_OFFLINE_PARSING):
53399 + p_BmiNia = &p_FmPort->port.bmi_regs->oh.fmbm_ofne;
53400 + p_BmiPrsStartOffset = &p_FmPort->port.bmi_regs->oh.fmbm_opso;
53401 + break;
53402 + default:
53403 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Invalid port type"));
53404 + }
53405 +
53406 + if ((GET_UINT32(*p_BmiNia) & GET_NO_PCD_NIA_BMI_AC_ENQ_FRAME())
53407 + != GET_NO_PCD_NIA_BMI_AC_ENQ_FRAME())
53408 + RETURN_ERROR(MAJOR, E_INVALID_OPERATION,
53409 + ("port has to be detached previousely"));
53410 +
53411 + WRITE_UINT32(*p_BmiPrsStartOffset, 0);
53412 +
53413 + /* "cut" PCD out of the port's flow - go to BMI */
53414 + /* WRITE_UINT32(*p_BmiNia, (p_FmPort->savedBmiNia & BMI_RFNE_FDCS_MASK) | (NIA_ENG_BMI | NIA_BMI_AC_ENQ_FRAME)); */
53415 +
53416 + if (p_FmPort->pcdEngines & FM_PCD_PRS)
53417 + {
53418 + /* stop parser */
53419 + WRITE_UINT32(p_FmPort->p_FmPortPrsRegs->pcac, PRS_CAC_STOP);
53420 + /* wait for parser to be in idle state */
53421 + while (GET_UINT32(p_FmPort->p_FmPortPrsRegs->pcac) & PRS_CAC_ACTIVE)
53422 + ;
53423 + }
53424 +
53425 + if (p_FmPort->pcdEngines & FM_PCD_KG)
53426 + {
53427 + t_FmPcdKgInterModuleBindPortToSchemes schemeBind;
53428 +
53429 + /* unbind all schemes */
53430 + p_FmPort->schemesPerPortVector = GetPortSchemeBindParams(p_FmPort,
53431 + &schemeBind);
53432 +
53433 + err = FmPcdKgUnbindPortToSchemes(p_FmPort->h_FmPcd, &schemeBind);
53434 + if (err)
53435 + RETURN_ERROR(MAJOR, err, NO_MSG);
53436 +
53437 + err = FmPcdKgDeleteOrUnbindPortToClsPlanGrp(p_FmPort->h_FmPcd,
53438 + p_FmPort->hardwarePortId,
53439 + p_FmPort->clsPlanGrpId);
53440 + if (err)
53441 + RETURN_ERROR(MAJOR, err, NO_MSG);
53442 + p_FmPort->useClsPlan = FALSE;
53443 + }
53444 +
53445 + if (p_FmPort->pcdEngines & FM_PCD_CC)
53446 + {
53447 + /* unbind - we need to get the treeId too */
53448 + err = FmPcdCcUnbindTree(p_FmPort->h_FmPcd, p_FmPort->ccTreeId);
53449 + if (err)
53450 + RETURN_ERROR(MAJOR, err, NO_MSG);
53451 + }
53452 +
53453 + p_FmPort->pcdEngines = 0;
53454 +
53455 + return E_OK;
53456 +}
53457 +
53458 +static t_Error AttachPCD(t_FmPort *p_FmPort)
53459 +{
53460 + volatile uint32_t *p_BmiNia = NULL;
53461 +
53462 + ASSERT_COND(p_FmPort);
53463 +
53464 + /* get PCD registers pointers */
53465 + if (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING)
53466 + p_BmiNia = &p_FmPort->port.bmi_regs->oh.fmbm_ofne;
53467 + else
53468 + p_BmiNia = &p_FmPort->port.bmi_regs->rx.fmbm_rfne;
53469 +
53470 + /* check that current NIA is BMI to BMI */
53471 + if ((GET_UINT32(*p_BmiNia) & ~BMI_RFNE_FDCS_MASK)
53472 + != GET_NO_PCD_NIA_BMI_AC_ENQ_FRAME())
53473 + RETURN_ERROR( MAJOR, E_INVALID_OPERATION,
53474 + ("may be called only for ports in BMI-to-BMI state."));
53475 +
53476 + if (p_FmPort->requiredAction & UPDATE_FMFP_PRC_WITH_ONE_RISC_ONLY)
53477 + if (FmSetNumOfRiscsPerPort(p_FmPort->h_Fm, p_FmPort->hardwarePortId, 1,
53478 + p_FmPort->orFmanCtrl) != E_OK)
53479 + RETURN_ERROR(MAJOR, E_INVALID_STATE, NO_MSG);
53480 +
53481 + if (p_FmPort->requiredAction & UPDATE_NIA_CMNE)
53482 + {
53483 + if (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING)
53484 + WRITE_UINT32(p_FmPort->port.bmi_regs->oh.fmbm_ocmne,
53485 + p_FmPort->savedBmiCmne);
53486 + else
53487 + WRITE_UINT32(p_FmPort->port.bmi_regs->rx.fmbm_rcmne,
53488 + p_FmPort->savedBmiCmne);
53489 + }
53490 +
53491 + if (p_FmPort->requiredAction & UPDATE_NIA_PNEN)
53492 + WRITE_UINT32(p_FmPort->p_FmPortQmiRegs->fmqm_pnen,
53493 + p_FmPort->savedQmiPnen);
53494 +
53495 + if (p_FmPort->requiredAction & UPDATE_NIA_FENE)
53496 + {
53497 + if (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING)
53498 + WRITE_UINT32(p_FmPort->port.bmi_regs->oh.fmbm_ofene,
53499 + p_FmPort->savedBmiFene);
53500 + else
53501 + WRITE_UINT32(p_FmPort->port.bmi_regs->rx.fmbm_rfene,
53502 + p_FmPort->savedBmiFene);
53503 + }
53504 +
53505 + if (p_FmPort->requiredAction & UPDATE_NIA_FPNE)
53506 + {
53507 + if (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING)
53508 + WRITE_UINT32(p_FmPort->port.bmi_regs->oh.fmbm_ofpne,
53509 + p_FmPort->savedBmiFpne);
53510 + else
53511 + WRITE_UINT32(p_FmPort->port.bmi_regs->rx.fmbm_rfpne,
53512 + p_FmPort->savedBmiFpne);
53513 + }
53514 +
53515 + if (p_FmPort->requiredAction & UPDATE_OFP_DPTE)
53516 + {
53517 + ASSERT_COND(p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING);
53518 +
53519 + WRITE_UINT32(p_FmPort->port.bmi_regs->oh.fmbm_ofp,
53520 + p_FmPort->savedBmiOfp);
53521 + }
53522 +
53523 + WRITE_UINT32(*p_BmiNia, p_FmPort->savedBmiNia);
53524 +
53525 + if (p_FmPort->requiredAction & UPDATE_NIA_PNDN)
53526 + {
53527 + p_FmPort->origNonRxQmiRegsPndn =
53528 + GET_UINT32(p_FmPort->port.qmi_regs->fmqm_pndn);
53529 + WRITE_UINT32(p_FmPort->port.qmi_regs->fmqm_pndn,
53530 + p_FmPort->savedNonRxQmiRegsPndn);
53531 + }
53532 +
53533 + return E_OK;
53534 +}
53535 +
53536 +static t_Error DetachPCD(t_FmPort *p_FmPort)
53537 +{
53538 + volatile uint32_t *p_BmiNia = NULL;
53539 +
53540 + ASSERT_COND(p_FmPort);
53541 +
53542 + /* get PCD registers pointers */
53543 + if (p_FmPort->requiredAction & UPDATE_NIA_PNDN)
53544 + WRITE_UINT32(p_FmPort->port.qmi_regs->fmqm_pndn,
53545 + p_FmPort->origNonRxQmiRegsPndn);
53546 +
53547 + if (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING)
53548 + p_BmiNia = &p_FmPort->port.bmi_regs->oh.fmbm_ofne;
53549 + else
53550 + p_BmiNia = &p_FmPort->port.bmi_regs->rx.fmbm_rfne;
53551 +
53552 + WRITE_UINT32(
53553 + *p_BmiNia,
53554 + (p_FmPort->savedBmiNia & BMI_RFNE_FDCS_MASK) | GET_NO_PCD_NIA_BMI_AC_ENQ_FRAME());
53555 +
53556 + if (FmPcdGetHcHandle(p_FmPort->h_FmPcd))
53557 + FmPcdHcSync(p_FmPort->h_FmPcd);
53558 +
53559 + if (p_FmPort->requiredAction & UPDATE_NIA_FENE)
53560 + {
53561 + if (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING)
53562 + WRITE_UINT32(p_FmPort->port.bmi_regs->oh.fmbm_ofene,
53563 + NIA_ENG_QMI_ENQ | NIA_ORDER_RESTOR);
53564 + else
53565 + WRITE_UINT32(p_FmPort->port.bmi_regs->rx.fmbm_rfene,
53566 + NIA_ENG_QMI_ENQ | NIA_ORDER_RESTOR);
53567 + }
53568 +
53569 + if (p_FmPort->requiredAction & UPDATE_NIA_PNEN)
53570 + WRITE_UINT32(p_FmPort->port.qmi_regs->fmqm_pnen,
53571 + NIA_ENG_BMI | NIA_BMI_AC_RELEASE);
53572 +
53573 + if (p_FmPort->requiredAction & UPDATE_FMFP_PRC_WITH_ONE_RISC_ONLY)
53574 + if (FmSetNumOfRiscsPerPort(p_FmPort->h_Fm, p_FmPort->hardwarePortId, 2,
53575 + p_FmPort->orFmanCtrl) != E_OK)
53576 + RETURN_ERROR(MAJOR, E_INVALID_STATE, NO_MSG);
53577 +
53578 + p_FmPort->requiredAction = 0;
53579 +
53580 + return E_OK;
53581 +}
53582 +
53583 +/*****************************************************************************/
53584 +/* Inter-module API routines */
53585 +/*****************************************************************************/
53586 +void FmPortSetMacsecCmd(t_Handle h_FmPort, uint8_t dfltSci)
53587 +{
53588 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
53589 + volatile uint32_t *p_BmiCfgReg = NULL;
53590 + uint32_t tmpReg;
53591 +
53592 + SANITY_CHECK_RETURN(p_FmPort, E_INVALID_HANDLE);
53593 + SANITY_CHECK_RETURN(p_FmPort->p_FmPortDriverParam, E_INVALID_STATE);
53594 +
53595 + if ((p_FmPort->portType != e_FM_PORT_TYPE_TX_10G)
53596 + && (p_FmPort->portType != e_FM_PORT_TYPE_TX))
53597 + {
53598 + REPORT_ERROR(MAJOR, E_INVALID_OPERATION, ("The routine is relevant for Tx ports only"));
53599 + return;
53600 + }
53601 +
53602 + p_BmiCfgReg = &p_FmPort->port.bmi_regs->tx.fmbm_tfca;
53603 + tmpReg = GET_UINT32(*p_BmiCfgReg) & ~BMI_CMD_ATTR_MACCMD_MASK;
53604 + tmpReg |= BMI_CMD_ATTR_MACCMD_SECURED;
53605 + tmpReg |= (((uint32_t)dfltSci << BMI_CMD_ATTR_MACCMD_SC_SHIFT)
53606 + & BMI_CMD_ATTR_MACCMD_SC_MASK);
53607 +
53608 + WRITE_UINT32(*p_BmiCfgReg, tmpReg);
53609 +}
53610 +
53611 +uint8_t FmPortGetNetEnvId(t_Handle h_FmPort)
53612 +{
53613 + return ((t_FmPort*)h_FmPort)->netEnvId;
53614 +}
53615 +
53616 +uint8_t FmPortGetHardwarePortId(t_Handle h_FmPort)
53617 +{
53618 + return ((t_FmPort*)h_FmPort)->hardwarePortId;
53619 +}
53620 +
53621 +uint32_t FmPortGetPcdEngines(t_Handle h_FmPort)
53622 +{
53623 + return ((t_FmPort*)h_FmPort)->pcdEngines;
53624 +}
53625 +
53626 +#if (DPAA_VERSION >= 11)
53627 +t_Error FmPortSetGprFunc(t_Handle h_FmPort, e_FmPortGprFuncType gprFunc,
53628 + void **p_Value)
53629 +{
53630 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
53631 + uint32_t muramPageOffset;
53632 +
53633 + ASSERT_COND(p_FmPort);
53634 + ASSERT_COND(p_Value);
53635 +
53636 + if (p_FmPort->gprFunc != e_FM_PORT_GPR_EMPTY)
53637 + {
53638 + if (p_FmPort->gprFunc != gprFunc)
53639 + RETURN_ERROR(MAJOR, E_INVALID_STATE,
53640 + ("gpr was assigned with different func"));
53641 + }
53642 + else
53643 + {
53644 + switch (gprFunc)
53645 + {
53646 + case (e_FM_PORT_GPR_MURAM_PAGE):
53647 + p_FmPort->p_ParamsPage = FM_MURAM_AllocMem(p_FmPort->h_FmMuram,
53648 + 256, 8);
53649 + if (!p_FmPort->p_ParamsPage)
53650 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("MURAM alloc for page"));
53651 +
53652 + IOMemSet32(p_FmPort->p_ParamsPage, 0, 256);
53653 + muramPageOffset =
53654 + (uint32_t)(XX_VirtToPhys(p_FmPort->p_ParamsPage)
53655 + - p_FmPort->fmMuramPhysBaseAddr);
53656 + switch (p_FmPort->portType)
53657 + {
53658 + case (e_FM_PORT_TYPE_RX_10G):
53659 + case (e_FM_PORT_TYPE_RX):
53660 + WRITE_UINT32(
53661 + p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rgpr,
53662 + muramPageOffset);
53663 + break;
53664 + case (e_FM_PORT_TYPE_OH_OFFLINE_PARSING):
53665 + WRITE_UINT32(
53666 + p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs.fmbm_ogpr,
53667 + muramPageOffset);
53668 + break;
53669 + default:
53670 + RETURN_ERROR(MAJOR, E_INVALID_STATE,
53671 + ("Invalid port type"));
53672 + }
53673 + break;
53674 + default:
53675 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION, NO_MSG);
53676 + }
53677 + p_FmPort->gprFunc = gprFunc;
53678 + }
53679 +
53680 + switch (p_FmPort->gprFunc)
53681 + {
53682 + case (e_FM_PORT_GPR_MURAM_PAGE):
53683 + *p_Value = p_FmPort->p_ParamsPage;
53684 + break;
53685 + default:
53686 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION, NO_MSG);
53687 + }
53688 +
53689 + return E_OK;
53690 +}
53691 +#endif /* (DPAA_VERSION >= 11) */
53692 +
53693 +t_Error FmPortGetSetCcParams(t_Handle h_FmPort,
53694 + t_FmPortGetSetCcParams *p_CcParams)
53695 +{
53696 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
53697 + int tmpInt;
53698 + volatile uint32_t *p_BmiPrsStartOffset = NULL;
53699 +
53700 + /* this function called from Cc for pass and receive parameters port params between CC and PORT*/
53701 +
53702 + if ((p_CcParams->getCcParams.type & OFFSET_OF_PR)
53703 + && (p_FmPort->bufferOffsets.prsResultOffset != ILLEGAL_BASE))
53704 + {
53705 + p_CcParams->getCcParams.prOffset =
53706 + (uint8_t)p_FmPort->bufferOffsets.prsResultOffset;
53707 + p_CcParams->getCcParams.type &= ~OFFSET_OF_PR;
53708 + }
53709 + if (p_CcParams->getCcParams.type & HW_PORT_ID)
53710 + {
53711 + p_CcParams->getCcParams.hardwarePortId =
53712 + (uint8_t)p_FmPort->hardwarePortId;
53713 + p_CcParams->getCcParams.type &= ~HW_PORT_ID;
53714 + }
53715 + if ((p_CcParams->getCcParams.type & OFFSET_OF_DATA)
53716 + && (p_FmPort->bufferOffsets.dataOffset != ILLEGAL_BASE))
53717 + {
53718 + p_CcParams->getCcParams.dataOffset =
53719 + (uint16_t)p_FmPort->bufferOffsets.dataOffset;
53720 + p_CcParams->getCcParams.type &= ~OFFSET_OF_DATA;
53721 + }
53722 + if (p_CcParams->getCcParams.type & NUM_OF_TASKS)
53723 + {
53724 + p_CcParams->getCcParams.numOfTasks = (uint8_t)p_FmPort->tasks.num;
53725 + p_CcParams->getCcParams.type &= ~NUM_OF_TASKS;
53726 + }
53727 + if (p_CcParams->getCcParams.type & NUM_OF_EXTRA_TASKS)
53728 + {
53729 + p_CcParams->getCcParams.numOfExtraTasks =
53730 + (uint8_t)p_FmPort->tasks.extra;
53731 + p_CcParams->getCcParams.type &= ~NUM_OF_EXTRA_TASKS;
53732 + }
53733 + if (p_CcParams->getCcParams.type & FM_REV)
53734 + {
53735 + p_CcParams->getCcParams.revInfo.majorRev = p_FmPort->fmRevInfo.majorRev;
53736 + p_CcParams->getCcParams.revInfo.minorRev = p_FmPort->fmRevInfo.minorRev;
53737 + p_CcParams->getCcParams.type &= ~FM_REV;
53738 + }
53739 + if (p_CcParams->getCcParams.type & DISCARD_MASK)
53740 + {
53741 + if (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING)
53742 + p_CcParams->getCcParams.discardMask =
53743 + GET_UINT32(p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs.fmbm_ofsdm);
53744 + else
53745 + p_CcParams->getCcParams.discardMask =
53746 + GET_UINT32(p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rfsdm);
53747 + p_CcParams->getCcParams.type &= ~DISCARD_MASK;
53748 + }
53749 + if (p_CcParams->getCcParams.type & MANIP_EXTRA_SPACE)
53750 + {
53751 + p_CcParams->getCcParams.internalBufferOffset =
53752 + p_FmPort->internalBufferOffset;
53753 + p_CcParams->getCcParams.type &= ~MANIP_EXTRA_SPACE;
53754 + }
53755 + if (p_CcParams->getCcParams.type & GET_NIA_FPNE)
53756 + {
53757 + if (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING)
53758 + p_CcParams->getCcParams.nia =
53759 + GET_UINT32(p_FmPort->port.bmi_regs->oh.fmbm_ofpne);
53760 + else
53761 + p_CcParams->getCcParams.nia =
53762 + GET_UINT32(p_FmPort->port.bmi_regs->rx.fmbm_rfpne);
53763 + p_CcParams->getCcParams.type &= ~GET_NIA_FPNE;
53764 + }
53765 + if (p_CcParams->getCcParams.type & GET_NIA_PNDN)
53766 + {
53767 + if (p_FmPort->portType != e_FM_PORT_TYPE_OH_OFFLINE_PARSING)
53768 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Invalid port type"));
53769 + p_CcParams->getCcParams.nia =
53770 + GET_UINT32(p_FmPort->p_FmPortQmiRegs->nonRxQmiRegs.fmqm_pndn);
53771 + p_CcParams->getCcParams.type &= ~GET_NIA_PNDN;
53772 + }
53773 +
53774 + if ((p_CcParams->setCcParams.type & UPDATE_FMFP_PRC_WITH_ONE_RISC_ONLY)
53775 + && !(p_FmPort->requiredAction & UPDATE_FMFP_PRC_WITH_ONE_RISC_ONLY))
53776 + {
53777 + p_FmPort->requiredAction |= UPDATE_FMFP_PRC_WITH_ONE_RISC_ONLY;
53778 + p_FmPort->orFmanCtrl = p_CcParams->setCcParams.orFmanCtrl;
53779 + }
53780 +
53781 + if ((p_CcParams->setCcParams.type & UPDATE_NIA_PNEN)
53782 + && !(p_FmPort->requiredAction & UPDATE_NIA_PNEN))
53783 + {
53784 + p_FmPort->savedQmiPnen = p_CcParams->setCcParams.nia;
53785 + p_FmPort->requiredAction |= UPDATE_NIA_PNEN;
53786 + }
53787 + else
53788 + if (p_CcParams->setCcParams.type & UPDATE_NIA_PNEN)
53789 + {
53790 + if (p_FmPort->savedQmiPnen != p_CcParams->setCcParams.nia)
53791 + RETURN_ERROR(MAJOR, E_INVALID_STATE,
53792 + ("PNEN was defined previously different"));
53793 + }
53794 +
53795 + if ((p_CcParams->setCcParams.type & UPDATE_NIA_PNDN)
53796 + && !(p_FmPort->requiredAction & UPDATE_NIA_PNDN))
53797 + {
53798 + p_FmPort->savedNonRxQmiRegsPndn = p_CcParams->setCcParams.nia;
53799 + p_FmPort->requiredAction |= UPDATE_NIA_PNDN;
53800 + }
53801 + else
53802 + if (p_CcParams->setCcParams.type & UPDATE_NIA_PNDN)
53803 + {
53804 + if (p_FmPort->savedNonRxQmiRegsPndn != p_CcParams->setCcParams.nia)
53805 + RETURN_ERROR(MAJOR, E_INVALID_STATE,
53806 + ("PNDN was defined previously different"));
53807 + }
53808 +
53809 + if ((p_CcParams->setCcParams.type & UPDATE_NIA_FENE)
53810 + && (p_CcParams->setCcParams.overwrite
53811 + || !(p_FmPort->requiredAction & UPDATE_NIA_FENE)))
53812 + {
53813 + p_FmPort->savedBmiFene = p_CcParams->setCcParams.nia;
53814 + p_FmPort->requiredAction |= UPDATE_NIA_FENE;
53815 + }
53816 + else
53817 + if (p_CcParams->setCcParams.type & UPDATE_NIA_FENE)
53818 + {
53819 + if (p_FmPort->savedBmiFene != p_CcParams->setCcParams.nia)
53820 + RETURN_ERROR( MAJOR, E_INVALID_STATE,
53821 + ("xFENE was defined previously different"));
53822 + }
53823 +
53824 + if ((p_CcParams->setCcParams.type & UPDATE_NIA_FPNE)
53825 + && !(p_FmPort->requiredAction & UPDATE_NIA_FPNE))
53826 + {
53827 + p_FmPort->savedBmiFpne = p_CcParams->setCcParams.nia;
53828 + p_FmPort->requiredAction |= UPDATE_NIA_FPNE;
53829 + }
53830 + else
53831 + if (p_CcParams->setCcParams.type & UPDATE_NIA_FPNE)
53832 + {
53833 + if (p_FmPort->savedBmiFpne != p_CcParams->setCcParams.nia)
53834 + RETURN_ERROR( MAJOR, E_INVALID_STATE,
53835 + ("xFPNE was defined previously different"));
53836 + }
53837 +
53838 + if ((p_CcParams->setCcParams.type & UPDATE_NIA_CMNE)
53839 + && !(p_FmPort->requiredAction & UPDATE_NIA_CMNE))
53840 + {
53841 + p_FmPort->savedBmiCmne = p_CcParams->setCcParams.nia;
53842 + p_FmPort->requiredAction |= UPDATE_NIA_CMNE;
53843 + }
53844 + else
53845 + if (p_CcParams->setCcParams.type & UPDATE_NIA_CMNE)
53846 + {
53847 + if (p_FmPort->savedBmiCmne != p_CcParams->setCcParams.nia)
53848 + RETURN_ERROR( MAJOR, E_INVALID_STATE,
53849 + ("xCMNE was defined previously different"));
53850 + }
53851 +
53852 + if ((p_CcParams->setCcParams.type & UPDATE_PSO)
53853 + && !(p_FmPort->requiredAction & UPDATE_PSO))
53854 + {
53855 + /* get PCD registers pointers */
53856 + switch (p_FmPort->portType)
53857 + {
53858 + case (e_FM_PORT_TYPE_RX_10G):
53859 + case (e_FM_PORT_TYPE_RX):
53860 + p_BmiPrsStartOffset = &p_FmPort->port.bmi_regs->rx.fmbm_rpso;
53861 + break;
53862 + case (e_FM_PORT_TYPE_OH_OFFLINE_PARSING):
53863 + p_BmiPrsStartOffset = &p_FmPort->port.bmi_regs->oh.fmbm_opso;
53864 + break;
53865 + default:
53866 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Invalid port type"));
53867 + }
53868 +
53869 + /* set start parsing offset */
53870 + tmpInt = (int)GET_UINT32(*p_BmiPrsStartOffset)
53871 + + p_CcParams->setCcParams.psoSize;
53872 + if (tmpInt > 0)
53873 + WRITE_UINT32(*p_BmiPrsStartOffset, (uint32_t)tmpInt);
53874 +
53875 + p_FmPort->requiredAction |= UPDATE_PSO;
53876 + p_FmPort->savedPrsStartOffset = p_CcParams->setCcParams.psoSize;
53877 + }
53878 + else
53879 + if (p_CcParams->setCcParams.type & UPDATE_PSO)
53880 + {
53881 + if (p_FmPort->savedPrsStartOffset
53882 + != p_CcParams->setCcParams.psoSize)
53883 + RETURN_ERROR(
53884 + MAJOR,
53885 + E_INVALID_STATE,
53886 + ("parser start offset was defoned previousley different"));
53887 + }
53888 +
53889 + if ((p_CcParams->setCcParams.type & UPDATE_OFP_DPTE)
53890 + && !(p_FmPort->requiredAction & UPDATE_OFP_DPTE))
53891 + {
53892 + if (p_FmPort->portType != e_FM_PORT_TYPE_OH_OFFLINE_PARSING)
53893 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Invalid port type"));
53894 + p_FmPort->savedBmiOfp = GET_UINT32(p_FmPort->port.bmi_regs->oh.fmbm_ofp);
53895 + p_FmPort->savedBmiOfp &= ~BMI_FIFO_PIPELINE_DEPTH_MASK;
53896 + p_FmPort->savedBmiOfp |= p_CcParams->setCcParams.ofpDpde
53897 + << BMI_FIFO_PIPELINE_DEPTH_SHIFT;
53898 + p_FmPort->requiredAction |= UPDATE_OFP_DPTE;
53899 + }
53900 +
53901 + return E_OK;
53902 +}
53903 +/*********************** End of inter-module routines ************************/
53904 +
53905 +/****************************************/
53906 +/* API Init unit functions */
53907 +/****************************************/
53908 +
53909 +t_Handle FM_PORT_Config(t_FmPortParams *p_FmPortParams)
53910 +{
53911 + t_FmPort *p_FmPort;
53912 + uintptr_t baseAddr = p_FmPortParams->baseAddr;
53913 + uint32_t tmpReg;
53914 +
53915 + /* Allocate FM structure */
53916 + p_FmPort = (t_FmPort *)XX_Malloc(sizeof(t_FmPort));
53917 + if (!p_FmPort)
53918 + {
53919 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FM Port driver structure"));
53920 + return NULL;
53921 + }
53922 + memset(p_FmPort, 0, sizeof(t_FmPort));
53923 +
53924 + /* Allocate the FM driver's parameters structure */
53925 + p_FmPort->p_FmPortDriverParam = (t_FmPortDriverParam *)XX_Malloc(
53926 + sizeof(t_FmPortDriverParam));
53927 + if (!p_FmPort->p_FmPortDriverParam)
53928 + {
53929 + XX_Free(p_FmPort);
53930 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FM Port driver parameters"));
53931 + return NULL;
53932 + }
53933 + memset(p_FmPort->p_FmPortDriverParam, 0, sizeof(t_FmPortDriverParam));
53934 +
53935 + /* Initialize FM port parameters which will be kept by the driver */
53936 + p_FmPort->portType = p_FmPortParams->portType;
53937 + p_FmPort->portId = p_FmPortParams->portId;
53938 + p_FmPort->pcdEngines = FM_PCD_NONE;
53939 + p_FmPort->f_Exception = p_FmPortParams->f_Exception;
53940 + p_FmPort->h_App = p_FmPortParams->h_App;
53941 + p_FmPort->h_Fm = p_FmPortParams->h_Fm;
53942 +
53943 + /* get FM revision */
53944 + FM_GetRevision(p_FmPort->h_Fm, &p_FmPort->fmRevInfo);
53945 +
53946 + /* calculate global portId number */
53947 + p_FmPort->hardwarePortId = SwPortIdToHwPortId(p_FmPort->portType,
53948 + p_FmPortParams->portId,
53949 + p_FmPort->fmRevInfo.majorRev,
53950 + p_FmPort->fmRevInfo.minorRev);
53951 +
53952 + if (p_FmPort->fmRevInfo.majorRev >= 6)
53953 + {
53954 + if ((p_FmPort->portType == e_FM_PORT_TYPE_OH_HOST_COMMAND)
53955 + && (p_FmPortParams->portId != FM_OH_PORT_ID))
53956 + DBG(WARNING,
53957 + ("Port ID %d is recommended for HC port. Overwriting HW defaults to be suitable for HC.",
53958 + FM_OH_PORT_ID));
53959 +
53960 + if ((p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING)
53961 + && (p_FmPortParams->portId == FM_OH_PORT_ID))
53962 + DBG(WARNING, ("Use non-zero portId for OP port due to insufficient resources on portId 0."));
53963 + }
53964 +
53965 + /* Set up FM port parameters for initialization phase only */
53966 +
53967 + /* First, fill in flibs struct */
53968 + fman_port_defconfig(&p_FmPort->p_FmPortDriverParam->dfltCfg,
53969 + (enum fman_port_type)p_FmPort->portType);
53970 + /* Overwrite some integration specific parameters */
53971 + p_FmPort->p_FmPortDriverParam->dfltCfg.rx_pri_elevation =
53972 + DEFAULT_PORT_rxFifoPriElevationLevel;
53973 + p_FmPort->p_FmPortDriverParam->dfltCfg.rx_fifo_thr =
53974 + DEFAULT_PORT_rxFifoThreshold;
53975 +
53976 +#if defined(FM_OP_NO_VSP_NO_RELEASE_ERRATA_FMAN_A006675) || defined(FM_ERROR_VSP_NO_MATCH_SW006)
53977 + p_FmPort->p_FmPortDriverParam->dfltCfg.errata_A006675 = TRUE;
53978 +#else
53979 + p_FmPort->p_FmPortDriverParam->dfltCfg.errata_A006675 = FALSE;
53980 +#endif
53981 + if ((p_FmPort->fmRevInfo.majorRev == 6)
53982 + && (p_FmPort->fmRevInfo.minorRev == 0))
53983 + p_FmPort->p_FmPortDriverParam->dfltCfg.errata_A006320 = TRUE;
53984 + else
53985 + p_FmPort->p_FmPortDriverParam->dfltCfg.errata_A006320 = FALSE;
53986 +
53987 + /* Excessive Threshold register - exists for pre-FMv3 chips only */
53988 + if (p_FmPort->fmRevInfo.majorRev < 6)
53989 + {
53990 +#ifdef FM_NO_RESTRICT_ON_ACCESS_RSRC
53991 + p_FmPort->p_FmPortDriverParam->dfltCfg.excessive_threshold_register =
53992 + TRUE;
53993 +#endif
53994 + p_FmPort->p_FmPortDriverParam->dfltCfg.fmbm_rebm_has_sgd = FALSE;
53995 + p_FmPort->p_FmPortDriverParam->dfltCfg.fmbm_tfne_has_features = FALSE;
53996 + }
53997 + else
53998 + {
53999 + p_FmPort->p_FmPortDriverParam->dfltCfg.excessive_threshold_register =
54000 + FALSE;
54001 + p_FmPort->p_FmPortDriverParam->dfltCfg.fmbm_rebm_has_sgd = TRUE;
54002 + p_FmPort->p_FmPortDriverParam->dfltCfg.fmbm_tfne_has_features = TRUE;
54003 + }
54004 + if (p_FmPort->fmRevInfo.majorRev == 4)
54005 + p_FmPort->p_FmPortDriverParam->dfltCfg.qmi_deq_options_support = FALSE;
54006 + else
54007 + p_FmPort->p_FmPortDriverParam->dfltCfg.qmi_deq_options_support = TRUE;
54008 +
54009 + /* Continue with other parameters */
54010 + p_FmPort->p_FmPortDriverParam->baseAddr = baseAddr;
54011 + /* set memory map pointers */
54012 + p_FmPort->p_FmPortQmiRegs =
54013 + (t_FmPortQmiRegs *)UINT_TO_PTR(baseAddr + QMI_PORT_REGS_OFFSET);
54014 + p_FmPort->p_FmPortBmiRegs =
54015 + (u_FmPortBmiRegs *)UINT_TO_PTR(baseAddr + BMI_PORT_REGS_OFFSET);
54016 + p_FmPort->p_FmPortPrsRegs =
54017 + (t_FmPortPrsRegs *)UINT_TO_PTR(baseAddr + PRS_PORT_REGS_OFFSET);
54018 +
54019 + p_FmPort->p_FmPortDriverParam->bufferPrefixContent.privDataSize =
54020 + DEFAULT_PORT_bufferPrefixContent_privDataSize;
54021 + p_FmPort->p_FmPortDriverParam->bufferPrefixContent.passPrsResult =
54022 + DEFAULT_PORT_bufferPrefixContent_passPrsResult;
54023 + p_FmPort->p_FmPortDriverParam->bufferPrefixContent.passTimeStamp =
54024 + DEFAULT_PORT_bufferPrefixContent_passTimeStamp;
54025 + p_FmPort->p_FmPortDriverParam->bufferPrefixContent.passAllOtherPCDInfo =
54026 + DEFAULT_PORT_bufferPrefixContent_passTimeStamp;
54027 + p_FmPort->p_FmPortDriverParam->bufferPrefixContent.dataAlign =
54028 + DEFAULT_PORT_bufferPrefixContent_dataAlign;
54029 + /* p_FmPort->p_FmPortDriverParam->dmaSwapData = (e_FmDmaSwapOption)DEFAULT_PORT_dmaSwapData;
54030 + p_FmPort->p_FmPortDriverParam->dmaIntContextCacheAttr = (e_FmDmaCacheOption)DEFAULT_PORT_dmaIntContextCacheAttr;
54031 + p_FmPort->p_FmPortDriverParam->dmaHeaderCacheAttr = (e_FmDmaCacheOption)DEFAULT_PORT_dmaHeaderCacheAttr;
54032 + p_FmPort->p_FmPortDriverParam->dmaScatterGatherCacheAttr = (e_FmDmaCacheOption)DEFAULT_PORT_dmaScatterGatherCacheAttr;
54033 + p_FmPort->p_FmPortDriverParam->dmaWriteOptimize = DEFAULT_PORT_dmaWriteOptimize;
54034 + */
54035 + p_FmPort->p_FmPortDriverParam->liodnBase = p_FmPortParams->liodnBase;
54036 + p_FmPort->p_FmPortDriverParam->cheksumLastBytesIgnore =
54037 + DEFAULT_PORT_cheksumLastBytesIgnore;
54038 +
54039 + p_FmPort->maxFrameLength = DEFAULT_PORT_maxFrameLength;
54040 + /* resource distribution. */
54041 + p_FmPort->fifoBufs.num = DEFAULT_PORT_numOfFifoBufs(p_FmPort->portType)
54042 + * BMI_FIFO_UNITS;
54043 + p_FmPort->fifoBufs.extra = DEFAULT_PORT_extraNumOfFifoBufs
54044 + * BMI_FIFO_UNITS;
54045 + p_FmPort->openDmas.num = DEFAULT_PORT_numOfOpenDmas(p_FmPort->portType);
54046 + p_FmPort->openDmas.extra =
54047 + DEFAULT_PORT_extraNumOfOpenDmas(p_FmPort->portType);
54048 + p_FmPort->tasks.num = DEFAULT_PORT_numOfTasks(p_FmPort->portType);
54049 + p_FmPort->tasks.extra = DEFAULT_PORT_extraNumOfTasks(p_FmPort->portType);
54050 +
54051 +
54052 +#ifdef FM_HEAVY_TRAFFIC_SEQUENCER_HANG_ERRATA_FMAN_A006981
54053 + if ((p_FmPort->fmRevInfo.majorRev == 6)
54054 + && (p_FmPort->fmRevInfo.minorRev == 0)
54055 + && ((p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING)
54056 + || (p_FmPort->portType == e_FM_PORT_TYPE_TX)))
54057 + {
54058 + p_FmPort->openDmas.num = 16;
54059 + p_FmPort->openDmas.extra = 0;
54060 + }
54061 +#endif /* FM_HEAVY_TRAFFIC_SEQUENCER_HANG_ERRATA_FMAN_A006981 */
54062 +
54063 + /* Port type specific initialization: */
54064 + switch (p_FmPort->portType)
54065 + {
54066 + case (e_FM_PORT_TYPE_RX):
54067 + case (e_FM_PORT_TYPE_RX_10G):
54068 + /* Initialize FM port parameters for initialization phase only */
54069 + p_FmPort->p_FmPortDriverParam->cutBytesFromEnd =
54070 + DEFAULT_PORT_cutBytesFromEnd;
54071 + p_FmPort->p_FmPortDriverParam->enBufPoolDepletion = FALSE;
54072 + p_FmPort->p_FmPortDriverParam->frmDiscardOverride =
54073 + DEFAULT_PORT_frmDiscardOverride;
54074 +
54075 + tmpReg =
54076 + GET_UINT32(p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rfp);
54077 + p_FmPort->p_FmPortDriverParam->rxFifoPriElevationLevel =
54078 + (((tmpReg & BMI_RX_FIFO_PRI_ELEVATION_MASK)
54079 + >> BMI_RX_FIFO_PRI_ELEVATION_SHIFT) + 1)
54080 + * BMI_FIFO_UNITS;
54081 + p_FmPort->p_FmPortDriverParam->rxFifoThreshold = (((tmpReg
54082 + & BMI_RX_FIFO_THRESHOLD_MASK)
54083 + >> BMI_RX_FIFO_THRESHOLD_SHIFT) + 1) * BMI_FIFO_UNITS;
54084 +
54085 + p_FmPort->p_FmPortDriverParam->bufMargins.endMargins =
54086 + DEFAULT_PORT_BufMargins_endMargins;
54087 + p_FmPort->p_FmPortDriverParam->errorsToDiscard =
54088 + DEFAULT_PORT_errorsToDiscard;
54089 + p_FmPort->p_FmPortDriverParam->forwardReuseIntContext =
54090 + DEFAULT_PORT_forwardIntContextReuse;
54091 +#if (DPAA_VERSION >= 11)
54092 + p_FmPort->p_FmPortDriverParam->noScatherGather =
54093 + DEFAULT_PORT_noScatherGather;
54094 +#endif /* (DPAA_VERSION >= 11) */
54095 + break;
54096 +
54097 + case (e_FM_PORT_TYPE_TX):
54098 + p_FmPort->p_FmPortDriverParam->dontReleaseBuf = FALSE;
54099 +#ifdef FM_WRONG_RESET_VALUES_ERRATA_FMAN_A005127
54100 + tmpReg = 0x00001013;
54101 + WRITE_UINT32( p_FmPort->p_FmPortBmiRegs->txPortBmiRegs.fmbm_tfp,
54102 + tmpReg);
54103 +#endif /* FM_WRONG_RESET_VALUES_ERRATA_FMAN_A005127 */
54104 + case (e_FM_PORT_TYPE_TX_10G):
54105 + tmpReg =
54106 + GET_UINT32(p_FmPort->p_FmPortBmiRegs->txPortBmiRegs.fmbm_tfp);
54107 + p_FmPort->p_FmPortDriverParam->txFifoMinFillLevel = ((tmpReg
54108 + & BMI_TX_FIFO_MIN_FILL_MASK)
54109 + >> BMI_TX_FIFO_MIN_FILL_SHIFT) * BMI_FIFO_UNITS;
54110 + p_FmPort->p_FmPortDriverParam->dfltCfg.tx_fifo_deq_pipeline_depth =
54111 + (uint8_t)(((tmpReg & BMI_FIFO_PIPELINE_DEPTH_MASK)
54112 + >> BMI_FIFO_PIPELINE_DEPTH_SHIFT) + 1);
54113 + p_FmPort->p_FmPortDriverParam->txFifoLowComfLevel = (((tmpReg
54114 + & BMI_TX_LOW_COMF_MASK) >> BMI_TX_LOW_COMF_SHIFT) + 1)
54115 + * BMI_FIFO_UNITS;
54116 +
54117 + p_FmPort->p_FmPortDriverParam->deqType = DEFAULT_PORT_deqType;
54118 + p_FmPort->p_FmPortDriverParam->deqPrefetchOption =
54119 + DEFAULT_PORT_deqPrefetchOption;
54120 + p_FmPort->p_FmPortDriverParam->deqHighPriority =
54121 + (bool)((p_FmPort->portType == e_FM_PORT_TYPE_TX) ? DEFAULT_PORT_deqHighPriority_1G :
54122 + DEFAULT_PORT_deqHighPriority_10G);
54123 + p_FmPort->p_FmPortDriverParam->deqByteCnt =
54124 + (uint16_t)(
54125 + (p_FmPort->portType == e_FM_PORT_TYPE_TX) ? DEFAULT_PORT_deqByteCnt_1G :
54126 + DEFAULT_PORT_deqByteCnt_10G);
54127 + break;
54128 + case (e_FM_PORT_TYPE_OH_OFFLINE_PARSING):
54129 + p_FmPort->p_FmPortDriverParam->errorsToDiscard =
54130 + DEFAULT_PORT_errorsToDiscard;
54131 +#if (DPAA_VERSION >= 11)
54132 + p_FmPort->p_FmPortDriverParam->noScatherGather =
54133 + DEFAULT_PORT_noScatherGather;
54134 +#endif /* (DPAA_VERSION >= 11) */
54135 + case (e_FM_PORT_TYPE_OH_HOST_COMMAND):
54136 + p_FmPort->p_FmPortDriverParam->deqPrefetchOption =
54137 + DEFAULT_PORT_deqPrefetchOption_HC;
54138 + p_FmPort->p_FmPortDriverParam->deqHighPriority =
54139 + DEFAULT_PORT_deqHighPriority_1G;
54140 + p_FmPort->p_FmPortDriverParam->deqType = DEFAULT_PORT_deqType;
54141 + p_FmPort->p_FmPortDriverParam->deqByteCnt =
54142 + DEFAULT_PORT_deqByteCnt_1G;
54143 +
54144 + tmpReg =
54145 + GET_UINT32(p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs.fmbm_ofp);
54146 + p_FmPort->p_FmPortDriverParam->dfltCfg.tx_fifo_deq_pipeline_depth =
54147 + (uint8_t)(((tmpReg & BMI_FIFO_PIPELINE_DEPTH_MASK)
54148 + >> BMI_FIFO_PIPELINE_DEPTH_SHIFT) + 1);
54149 + if ((p_FmPort->portType == e_FM_PORT_TYPE_OH_HOST_COMMAND)
54150 + && (p_FmPortParams->portId != FM_OH_PORT_ID))
54151 + {
54152 + /* Overwrite HC defaults */
54153 + p_FmPort->p_FmPortDriverParam->dfltCfg.tx_fifo_deq_pipeline_depth =
54154 + DEFAULT_PORT_fifoDeqPipelineDepth_OH;
54155 + }
54156 +
54157 +#ifndef FM_FRAME_END_PARAMS_FOR_OP
54158 + if (p_FmPort->fmRevInfo.majorRev < 6)
54159 + p_FmPort->p_FmPortDriverParam->cheksumLastBytesIgnore = DEFAULT_notSupported;
54160 +#endif /* !FM_FRAME_END_PARAMS_FOR_OP */
54161 +
54162 +#ifndef FM_DEQ_PIPELINE_PARAMS_FOR_OP
54163 + if (!((p_FmPort->fmRevInfo.majorRev == 4) ||
54164 + (p_FmPort->fmRevInfo.majorRev >= 6)))
54165 + p_FmPort->p_FmPortDriverParam->dfltCfg.tx_fifo_deq_pipeline_depth = DEFAULT_notSupported;
54166 +#endif /* !FM_DEQ_PIPELINE_PARAMS_FOR_OP */
54167 + break;
54168 +
54169 + default:
54170 + XX_Free(p_FmPort->p_FmPortDriverParam);
54171 + XX_Free(p_FmPort);
54172 + REPORT_ERROR(MAJOR, E_INVALID_STATE, ("Invalid port type"));
54173 + return NULL;
54174 + }
54175 +#ifdef FM_QMI_NO_DEQ_OPTIONS_SUPPORT
54176 + if (p_FmPort->fmRevInfo.majorRev == 4)
54177 + p_FmPort->p_FmPortDriverParam->deqPrefetchOption = (e_FmPortDeqPrefetchOption)DEFAULT_notSupported;
54178 +#endif /* FM_QMI_NO_DEQ_OPTIONS_SUPPORT */
54179 +
54180 + p_FmPort->imEn = p_FmPortParams->independentModeEnable;
54181 +
54182 + if (p_FmPort->imEn)
54183 + {
54184 + if ((p_FmPort->portType == e_FM_PORT_TYPE_TX)
54185 + || (p_FmPort->portType == e_FM_PORT_TYPE_TX_10G))
54186 + p_FmPort->p_FmPortDriverParam->dfltCfg.tx_fifo_deq_pipeline_depth =
54187 + DEFAULT_PORT_fifoDeqPipelineDepth_IM;
54188 + FmPortConfigIM(p_FmPort, p_FmPortParams);
54189 + }
54190 + else
54191 + {
54192 + switch (p_FmPort->portType)
54193 + {
54194 + case (e_FM_PORT_TYPE_RX):
54195 + case (e_FM_PORT_TYPE_RX_10G):
54196 + /* Initialize FM port parameters for initialization phase only */
54197 + memcpy(&p_FmPort->p_FmPortDriverParam->extBufPools,
54198 + &p_FmPortParams->specificParams.rxParams.extBufPools,
54199 + sizeof(t_FmExtPools));
54200 + p_FmPort->p_FmPortDriverParam->errFqid =
54201 + p_FmPortParams->specificParams.rxParams.errFqid;
54202 + p_FmPort->p_FmPortDriverParam->dfltFqid =
54203 + p_FmPortParams->specificParams.rxParams.dfltFqid;
54204 + p_FmPort->p_FmPortDriverParam->liodnOffset =
54205 + p_FmPortParams->specificParams.rxParams.liodnOffset;
54206 + break;
54207 + case (e_FM_PORT_TYPE_OH_OFFLINE_PARSING):
54208 + case (e_FM_PORT_TYPE_TX):
54209 + case (e_FM_PORT_TYPE_TX_10G):
54210 + case (e_FM_PORT_TYPE_OH_HOST_COMMAND):
54211 + p_FmPort->p_FmPortDriverParam->errFqid =
54212 + p_FmPortParams->specificParams.nonRxParams.errFqid;
54213 + p_FmPort->p_FmPortDriverParam->deqSubPortal =
54214 + (uint8_t)(p_FmPortParams->specificParams.nonRxParams.qmChannel
54215 + & QMI_DEQ_CFG_SUBPORTAL_MASK);
54216 + p_FmPort->p_FmPortDriverParam->dfltFqid =
54217 + p_FmPortParams->specificParams.nonRxParams.dfltFqid;
54218 + break;
54219 + default:
54220 + XX_Free(p_FmPort->p_FmPortDriverParam);
54221 + XX_Free(p_FmPort);
54222 + REPORT_ERROR(MAJOR, E_INVALID_STATE, ("Invalid port type"));
54223 + return NULL;
54224 + }
54225 + }
54226 +
54227 + memset(p_FmPort->name, 0, (sizeof(char)) * MODULE_NAME_SIZE);
54228 + if (Sprint(
54229 + p_FmPort->name,
54230 + "FM-%d-port-%s-%d",
54231 + FmGetId(p_FmPort->h_Fm),
54232 + ((p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING
54233 + || (p_FmPort->portType == e_FM_PORT_TYPE_OH_HOST_COMMAND)) ? "OH" :
54234 + (p_FmPort->portType == e_FM_PORT_TYPE_RX ? "1g-RX" :
54235 + (p_FmPort->portType == e_FM_PORT_TYPE_TX ? "1g-TX" :
54236 + (p_FmPort->portType
54237 + == e_FM_PORT_TYPE_RX_10G ? "10g-RX" :
54238 + "10g-TX")))),
54239 + p_FmPort->portId) == 0)
54240 + {
54241 + XX_Free(p_FmPort->p_FmPortDriverParam);
54242 + XX_Free(p_FmPort);
54243 + REPORT_ERROR(MAJOR, E_INVALID_STATE, ("Sprint failed"));
54244 + return NULL;
54245 + }
54246 +
54247 + p_FmPort->h_Spinlock = XX_InitSpinlock();
54248 + if (!p_FmPort->h_Spinlock)
54249 + {
54250 + XX_Free(p_FmPort->p_FmPortDriverParam);
54251 + XX_Free(p_FmPort);
54252 + REPORT_ERROR(MAJOR, E_INVALID_STATE, ("Sprint failed"));
54253 + return NULL;
54254 + }
54255 +
54256 + return p_FmPort;
54257 +}
54258 +
54259 +t_FmPort *rx_port = 0;
54260 +t_FmPort *tx_port = 0;
54261 +
54262 +/**************************************************************************//**
54263 + @Function FM_PORT_Init
54264 +
54265 + @Description Initializes the FM module
54266 +
54267 + @Param[in] h_FmPort - FM module descriptor
54268 +
54269 + @Return E_OK on success; Error code otherwise.
54270 + *//***************************************************************************/
54271 +t_Error FM_PORT_Init(t_Handle h_FmPort)
54272 +{
54273 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
54274 + t_FmPortDriverParam *p_DriverParams;
54275 + t_Error errCode;
54276 + t_FmInterModulePortInitParams fmParams;
54277 + t_FmRevisionInfo revInfo;
54278 +
54279 + SANITY_CHECK_RETURN_ERROR(h_FmPort, E_INVALID_HANDLE);
54280 + SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
54281 +
54282 + errCode = FmSpBuildBufferStructure(
54283 + &p_FmPort->p_FmPortDriverParam->intContext,
54284 + &p_FmPort->p_FmPortDriverParam->bufferPrefixContent,
54285 + &p_FmPort->p_FmPortDriverParam->bufMargins,
54286 + &p_FmPort->bufferOffsets, &p_FmPort->internalBufferOffset);
54287 + if (errCode != E_OK)
54288 + RETURN_ERROR(MAJOR, errCode, NO_MSG);
54289 +#ifdef FM_HEAVY_TRAFFIC_HANG_ERRATA_FMAN_A005669
54290 + if ((p_FmPort->p_FmPortDriverParam->bcbWorkaround) &&
54291 + (p_FmPort->portType == e_FM_PORT_TYPE_RX))
54292 + {
54293 + p_FmPort->p_FmPortDriverParam->errorsToDiscard |= FM_PORT_FRM_ERR_PHYSICAL;
54294 + if (!p_FmPort->fifoBufs.num)
54295 + p_FmPort->fifoBufs.num = DEFAULT_PORT_numOfFifoBufs(p_FmPort->portType)*BMI_FIFO_UNITS;
54296 + p_FmPort->fifoBufs.num += 4*KILOBYTE;
54297 + }
54298 +#endif /* FM_HEAVY_TRAFFIC_HANG_ERRATA_FMAN_A005669 */
54299 +
54300 + CHECK_INIT_PARAMETERS(p_FmPort, CheckInitParameters);
54301 +
54302 + p_DriverParams = p_FmPort->p_FmPortDriverParam;
54303 +
54304 + /* Set up flibs port structure */
54305 + memset(&p_FmPort->port, 0, sizeof(struct fman_port));
54306 + p_FmPort->port.type = (enum fman_port_type)p_FmPort->portType;
54307 + FM_GetRevision(p_FmPort->h_Fm, &revInfo);
54308 + p_FmPort->port.fm_rev_maj = revInfo.majorRev;
54309 + p_FmPort->port.fm_rev_min = revInfo.minorRev;
54310 + p_FmPort->port.bmi_regs =
54311 + (union fman_port_bmi_regs *)UINT_TO_PTR(p_DriverParams->baseAddr + BMI_PORT_REGS_OFFSET);
54312 + p_FmPort->port.qmi_regs =
54313 + (struct fman_port_qmi_regs *)UINT_TO_PTR(p_DriverParams->baseAddr + QMI_PORT_REGS_OFFSET);
54314 + p_FmPort->port.ext_pools_num = (uint8_t)((revInfo.majorRev == 4) ? 4 : 8);
54315 + p_FmPort->port.im_en = p_FmPort->imEn;
54316 + p_FmPort->p_FmPortPrsRegs =
54317 + (t_FmPortPrsRegs *)UINT_TO_PTR(p_DriverParams->baseAddr + PRS_PORT_REGS_OFFSET);
54318 +
54319 + if (((p_FmPort->portType == e_FM_PORT_TYPE_RX_10G)
54320 + || (p_FmPort->portType == e_FM_PORT_TYPE_RX)) && !p_FmPort->imEn)
54321 + {
54322 + /* Call the external Buffer routine which also checks fifo
54323 + size and updates it if necessary */
54324 + /* define external buffer pools and pool depletion*/
54325 + errCode = SetExtBufferPools(p_FmPort);
54326 + if (errCode)
54327 + RETURN_ERROR(MAJOR, errCode, NO_MSG);
54328 + /* check if the largest external buffer pool is large enough */
54329 + if (p_DriverParams->bufMargins.startMargins + MIN_EXT_BUF_SIZE
54330 + + p_DriverParams->bufMargins.endMargins
54331 + > p_FmPort->rxPoolsParams.largestBufSize)
54332 + RETURN_ERROR(
54333 + MAJOR,
54334 + E_INVALID_VALUE,
54335 + ("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));
54336 + }
54337 + if (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING)
54338 + {
54339 + {
54340 +#ifdef FM_NO_OP_OBSERVED_POOLS
54341 + t_FmRevisionInfo revInfo;
54342 +
54343 + FM_GetRevision(p_FmPort->h_Fm, &revInfo);
54344 + if ((revInfo.majorRev == 4) && (p_DriverParams->enBufPoolDepletion))
54345 +#endif /* FM_NO_OP_OBSERVED_POOLS */
54346 + {
54347 + /* define external buffer pools */
54348 + errCode = SetExtBufferPools(p_FmPort);
54349 + if (errCode)
54350 + RETURN_ERROR(MAJOR, errCode, NO_MSG);
54351 + }
54352 + }
54353 + }
54354 +
54355 + /************************************************************/
54356 + /* Call FM module routine for communicating parameters */
54357 + /************************************************************/
54358 + memset(&fmParams, 0, sizeof(fmParams));
54359 + fmParams.hardwarePortId = p_FmPort->hardwarePortId;
54360 + fmParams.portType = (e_FmPortType)p_FmPort->portType;
54361 + fmParams.numOfTasks = (uint8_t)p_FmPort->tasks.num;
54362 + fmParams.numOfExtraTasks = (uint8_t)p_FmPort->tasks.extra;
54363 + fmParams.numOfOpenDmas = (uint8_t)p_FmPort->openDmas.num;
54364 + fmParams.numOfExtraOpenDmas = (uint8_t)p_FmPort->openDmas.extra;
54365 +
54366 + if (p_FmPort->fifoBufs.num)
54367 + {
54368 + errCode = VerifySizeOfFifo(p_FmPort);
54369 + if (errCode != E_OK)
54370 + RETURN_ERROR(MAJOR, errCode, NO_MSG);
54371 + }
54372 + fmParams.sizeOfFifo = p_FmPort->fifoBufs.num;
54373 + fmParams.extraSizeOfFifo = p_FmPort->fifoBufs.extra;
54374 + fmParams.independentMode = p_FmPort->imEn;
54375 + fmParams.liodnOffset = p_DriverParams->liodnOffset;
54376 + fmParams.liodnBase = p_DriverParams->liodnBase;
54377 + fmParams.deqPipelineDepth =
54378 + p_FmPort->p_FmPortDriverParam->dfltCfg.tx_fifo_deq_pipeline_depth;
54379 + fmParams.maxFrameLength = p_FmPort->maxFrameLength;
54380 +#ifndef FM_DEQ_PIPELINE_PARAMS_FOR_OP
54381 + if ((p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING) ||
54382 + (p_FmPort->portType == e_FM_PORT_TYPE_OH_HOST_COMMAND))
54383 + {
54384 + if (!((p_FmPort->fmRevInfo.majorRev == 4) ||
54385 + (p_FmPort->fmRevInfo.majorRev >= 6)))
54386 + /* HC ports do not have fifoDeqPipelineDepth, but it is needed only
54387 + * for deq threshold calculation.
54388 + */
54389 + fmParams.deqPipelineDepth = 2;
54390 + }
54391 +#endif /* !FM_DEQ_PIPELINE_PARAMS_FOR_OP */
54392 +
54393 + errCode = FmGetSetPortParams(p_FmPort->h_Fm, &fmParams);
54394 + if (errCode)
54395 + RETURN_ERROR(MAJOR, errCode, NO_MSG);
54396 +
54397 + /* get params for use in init */
54398 + p_FmPort->fmMuramPhysBaseAddr =
54399 + (uint64_t)((uint64_t)(fmParams.fmMuramPhysBaseAddr.low)
54400 + | ((uint64_t)(fmParams.fmMuramPhysBaseAddr.high) << 32));
54401 + p_FmPort->h_FmMuram = FmGetMuramHandle(p_FmPort->h_Fm);
54402 +
54403 + errCode = InitLowLevelDriver(p_FmPort);
54404 + if (errCode != E_OK)
54405 + RETURN_ERROR(MAJOR, errCode, NO_MSG);
54406 +
54407 + FmPortDriverParamFree(p_FmPort);
54408 +
54409 +#if (DPAA_VERSION >= 11)
54410 + if ((p_FmPort->portType == e_FM_PORT_TYPE_RX_10G)
54411 + || (p_FmPort->portType == e_FM_PORT_TYPE_RX)
54412 + || (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING))
54413 + {
54414 + t_FmPcdCtrlParamsPage *p_ParamsPage;
54415 +
54416 + FmPortSetGprFunc(p_FmPort, e_FM_PORT_GPR_MURAM_PAGE,
54417 + (void**)&p_ParamsPage);
54418 + ASSERT_COND(p_ParamsPage);
54419 +
54420 + WRITE_UINT32(p_ParamsPage->misc, FM_CTL_PARAMS_PAGE_ALWAYS_ON);
54421 +#ifdef FM_OP_NO_VSP_NO_RELEASE_ERRATA_FMAN_A006675
54422 + if (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING)
54423 + {
54424 + WRITE_UINT32(
54425 + p_ParamsPage->misc,
54426 + (GET_UINT32(p_ParamsPage->misc) | FM_CTL_PARAMS_PAGE_OP_FIX_EN));
54427 + WRITE_UINT32(
54428 + p_ParamsPage->discardMask,
54429 + GET_UINT32(p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs.fmbm_ofsdm));
54430 + }
54431 +#endif /* FM_OP_NO_VSP_NO_RELEASE_ERRATA_FMAN_A006675 */
54432 +#ifdef FM_ERROR_VSP_NO_MATCH_SW006
54433 + if (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING)
54434 + WRITE_UINT32(
54435 + p_ParamsPage->errorsDiscardMask,
54436 + (GET_UINT32(p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs.fmbm_ofsdm) | GET_UINT32(p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs.fmbm_ofsem)));
54437 + else
54438 + WRITE_UINT32(
54439 + p_ParamsPage->errorsDiscardMask,
54440 + (GET_UINT32(p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rfsdm) | GET_UINT32(p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rfsem)));
54441 +#endif /* FM_ERROR_VSP_NO_MATCH_SW006 */
54442 + }
54443 +#endif /* (DPAA_VERSION >= 11) */
54444 +
54445 + if (p_FmPort->deepSleepVars.autoResMaxSizes)
54446 + FmPortConfigAutoResForDeepSleepSupport1(p_FmPort);
54447 + return E_OK;
54448 +}
54449 +
54450 +/**************************************************************************//**
54451 + @Function FM_PORT_Free
54452 +
54453 + @Description Frees all resources that were assigned to FM module.
54454 +
54455 + Calling this routine invalidates the descriptor.
54456 +
54457 + @Param[in] h_FmPort - FM module descriptor
54458 +
54459 + @Return E_OK on success; Error code otherwise.
54460 + *//***************************************************************************/
54461 +t_Error FM_PORT_Free(t_Handle h_FmPort)
54462 +{
54463 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
54464 + t_FmInterModulePortFreeParams fmParams;
54465 +
54466 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
54467 +
54468 + if (p_FmPort->pcdEngines)
54469 + RETURN_ERROR(
54470 + MAJOR,
54471 + E_INVALID_STATE,
54472 + ("Trying to free a port with PCD. FM_PORT_DeletePCD must be called first."));
54473 +
54474 + if (p_FmPort->enabled)
54475 + {
54476 + if (FM_PORT_Disable(p_FmPort) != E_OK)
54477 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("FM_PORT_Disable FAILED"));
54478 + }
54479 +
54480 + if (p_FmPort->imEn)
54481 + FmPortImFree(p_FmPort);
54482 +
54483 + FmPortDriverParamFree(p_FmPort);
54484 +
54485 + memset(&fmParams, 0, sizeof(fmParams));
54486 + fmParams.hardwarePortId = p_FmPort->hardwarePortId;
54487 + fmParams.portType = (e_FmPortType)p_FmPort->portType;
54488 + fmParams.deqPipelineDepth =
54489 + p_FmPort->p_FmPortDriverParam->dfltCfg.tx_fifo_deq_pipeline_depth;
54490 +
54491 + FmFreePortParams(p_FmPort->h_Fm, &fmParams);
54492 +
54493 +#if (DPAA_VERSION >= 11)
54494 + if (FmVSPFreeForPort(p_FmPort->h_Fm, p_FmPort->portType, p_FmPort->portId)
54495 + != E_OK)
54496 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("VSP free of port FAILED"));
54497 +
54498 + if (p_FmPort->p_ParamsPage)
54499 + FM_MURAM_FreeMem(p_FmPort->h_FmMuram, p_FmPort->p_ParamsPage);
54500 +#endif /* (DPAA_VERSION >= 11) */
54501 +
54502 + if (p_FmPort->h_Spinlock)
54503 + XX_FreeSpinlock(p_FmPort->h_Spinlock);
54504 +
54505 + XX_Free(p_FmPort);
54506 +
54507 + return E_OK;
54508 +}
54509 +
54510 +/*************************************************/
54511 +/* API Advanced Init unit functions */
54512 +/*************************************************/
54513 +
54514 +t_Error FM_PORT_ConfigNumOfOpenDmas(t_Handle h_FmPort, t_FmPortRsrc *p_OpenDmas)
54515 +{
54516 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
54517 +
54518 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
54519 + SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
54520 +
54521 + p_FmPort->p_FmPortDriverParam->setNumOfOpenDmas = TRUE;
54522 + memcpy(&p_FmPort->openDmas, p_OpenDmas, sizeof(t_FmPortRsrc));
54523 +
54524 + return E_OK;
54525 +}
54526 +
54527 +t_Error FM_PORT_ConfigNumOfTasks(t_Handle h_FmPort, t_FmPortRsrc *p_NumOfTasks)
54528 +{
54529 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
54530 +
54531 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
54532 + SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
54533 +
54534 + memcpy(&p_FmPort->tasks, p_NumOfTasks, sizeof(t_FmPortRsrc));
54535 + p_FmPort->p_FmPortDriverParam->setNumOfTasks = TRUE;
54536 + return E_OK;
54537 +}
54538 +
54539 +t_Error FM_PORT_ConfigSizeOfFifo(t_Handle h_FmPort, t_FmPortRsrc *p_SizeOfFifo)
54540 +{
54541 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
54542 +
54543 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
54544 + SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
54545 +
54546 + p_FmPort->p_FmPortDriverParam->setSizeOfFifo = TRUE;
54547 + memcpy(&p_FmPort->fifoBufs, p_SizeOfFifo, sizeof(t_FmPortRsrc));
54548 +
54549 + return E_OK;
54550 +}
54551 +
54552 +t_Error FM_PORT_ConfigDeqHighPriority(t_Handle h_FmPort, bool highPri)
54553 +{
54554 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
54555 +
54556 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
54557 + SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
54558 + if ((p_FmPort->portType == e_FM_PORT_TYPE_RX_10G)
54559 + || (p_FmPort->portType == e_FM_PORT_TYPE_RX))
54560 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("not available for Rx ports"));
54561 +
54562 + p_FmPort->p_FmPortDriverParam->dfltCfg.deq_high_pri = highPri;
54563 +
54564 + return E_OK;
54565 +}
54566 +
54567 +t_Error FM_PORT_ConfigDeqType(t_Handle h_FmPort, e_FmPortDeqType deqType)
54568 +{
54569 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
54570 +
54571 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
54572 + SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
54573 + if ((p_FmPort->portType == e_FM_PORT_TYPE_RX_10G)
54574 + || (p_FmPort->portType == e_FM_PORT_TYPE_RX))
54575 + RETURN_ERROR(MAJOR, E_INVALID_OPERATION,
54576 + ("not available for Rx ports"));
54577 +
54578 + p_FmPort->p_FmPortDriverParam->dfltCfg.deq_type =
54579 + (enum fman_port_deq_type)deqType;
54580 +
54581 + return E_OK;
54582 +}
54583 +
54584 +t_Error FM_PORT_ConfigDeqPrefetchOption(
54585 + t_Handle h_FmPort, e_FmPortDeqPrefetchOption deqPrefetchOption)
54586 +{
54587 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
54588 +
54589 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
54590 + SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
54591 + if ((p_FmPort->portType == e_FM_PORT_TYPE_RX_10G)
54592 + || (p_FmPort->portType == e_FM_PORT_TYPE_RX))
54593 + RETURN_ERROR(MAJOR, E_INVALID_OPERATION,
54594 + ("not available for Rx ports"));
54595 + p_FmPort->p_FmPortDriverParam->dfltCfg.deq_prefetch_opt =
54596 + (enum fman_port_deq_prefetch)deqPrefetchOption;
54597 +
54598 + return E_OK;
54599 +}
54600 +
54601 +t_Error FM_PORT_ConfigBackupPools(t_Handle h_FmPort,
54602 + t_FmBackupBmPools *p_BackupBmPools)
54603 +{
54604 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
54605 +
54606 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
54607 + SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
54608 + if ((p_FmPort->portType != e_FM_PORT_TYPE_RX_10G)
54609 + && (p_FmPort->portType != e_FM_PORT_TYPE_RX))
54610 + RETURN_ERROR(MAJOR, E_INVALID_OPERATION,
54611 + ("available for Rx ports only"));
54612 +
54613 + p_FmPort->p_FmPortDriverParam->p_BackupBmPools =
54614 + (t_FmBackupBmPools *)XX_Malloc(sizeof(t_FmBackupBmPools));
54615 + if (!p_FmPort->p_FmPortDriverParam->p_BackupBmPools)
54616 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("p_BackupBmPools allocation failed"));
54617 + memcpy(p_FmPort->p_FmPortDriverParam->p_BackupBmPools, p_BackupBmPools,
54618 + sizeof(t_FmBackupBmPools));
54619 +
54620 + return E_OK;
54621 +}
54622 +
54623 +t_Error FM_PORT_ConfigDeqByteCnt(t_Handle h_FmPort, uint16_t deqByteCnt)
54624 +{
54625 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
54626 +
54627 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
54628 + SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
54629 + if ((p_FmPort->portType == e_FM_PORT_TYPE_RX_10G)
54630 + || (p_FmPort->portType == e_FM_PORT_TYPE_RX))
54631 + RETURN_ERROR(MAJOR, E_INVALID_OPERATION,
54632 + ("not available for Rx ports"));
54633 +
54634 + p_FmPort->p_FmPortDriverParam->dfltCfg.deq_byte_cnt = deqByteCnt;
54635 +
54636 + return E_OK;
54637 +}
54638 +
54639 +t_Error FM_PORT_ConfigBufferPrefixContent(
54640 + t_Handle h_FmPort, t_FmBufferPrefixContent *p_FmBufferPrefixContent)
54641 +{
54642 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
54643 +
54644 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
54645 + SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
54646 +
54647 + memcpy(&p_FmPort->p_FmPortDriverParam->bufferPrefixContent,
54648 + p_FmBufferPrefixContent, sizeof(t_FmBufferPrefixContent));
54649 + /* if dataAlign was not initialized by user, we return to driver's default */
54650 + if (!p_FmPort->p_FmPortDriverParam->bufferPrefixContent.dataAlign)
54651 + p_FmPort->p_FmPortDriverParam->bufferPrefixContent.dataAlign =
54652 + DEFAULT_PORT_bufferPrefixContent_dataAlign;
54653 +
54654 + return E_OK;
54655 +}
54656 +
54657 +t_Error FM_PORT_ConfigCheksumLastBytesIgnore(t_Handle h_FmPort,
54658 + uint8_t checksumLastBytesIgnore)
54659 +{
54660 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
54661 +
54662 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
54663 + SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
54664 +
54665 + p_FmPort->p_FmPortDriverParam->dfltCfg.checksum_bytes_ignore =
54666 + checksumLastBytesIgnore;
54667 +
54668 + return E_OK;
54669 +}
54670 +
54671 +t_Error FM_PORT_ConfigCutBytesFromEnd(t_Handle h_FmPort,
54672 + uint8_t cutBytesFromEnd)
54673 +{
54674 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
54675 +
54676 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
54677 + SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
54678 + if ((p_FmPort->portType != e_FM_PORT_TYPE_RX_10G)
54679 + && (p_FmPort->portType != e_FM_PORT_TYPE_RX))
54680 + RETURN_ERROR(MAJOR, E_INVALID_OPERATION,
54681 + ("available for Rx ports only"));
54682 +
54683 + p_FmPort->p_FmPortDriverParam->dfltCfg.rx_cut_end_bytes = cutBytesFromEnd;
54684 +
54685 + return E_OK;
54686 +}
54687 +
54688 +t_Error FM_PORT_ConfigPoolDepletion(t_Handle h_FmPort,
54689 + t_FmBufPoolDepletion *p_BufPoolDepletion)
54690 +{
54691 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
54692 +
54693 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
54694 + SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
54695 + if ((p_FmPort->portType != e_FM_PORT_TYPE_RX_10G)
54696 + && (p_FmPort->portType != e_FM_PORT_TYPE_RX))
54697 + RETURN_ERROR(MAJOR, E_INVALID_OPERATION,
54698 + ("available for Rx ports only"));
54699 +
54700 + p_FmPort->p_FmPortDriverParam->enBufPoolDepletion = TRUE;
54701 + memcpy(&p_FmPort->p_FmPortDriverParam->bufPoolDepletion, p_BufPoolDepletion,
54702 + sizeof(t_FmBufPoolDepletion));
54703 +
54704 + return E_OK;
54705 +}
54706 +
54707 +t_Error FM_PORT_ConfigObservedPoolDepletion(
54708 + t_Handle h_FmPort,
54709 + t_FmPortObservedBufPoolDepletion *p_FmPortObservedBufPoolDepletion)
54710 +{
54711 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
54712 +
54713 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
54714 + SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
54715 + if (p_FmPort->portType != e_FM_PORT_TYPE_OH_OFFLINE_PARSING)
54716 + RETURN_ERROR(MAJOR, E_INVALID_OPERATION,
54717 + ("available for OP ports only"));
54718 +
54719 + p_FmPort->p_FmPortDriverParam->enBufPoolDepletion = TRUE;
54720 + memcpy(&p_FmPort->p_FmPortDriverParam->bufPoolDepletion,
54721 + &p_FmPortObservedBufPoolDepletion->poolDepletionParams,
54722 + sizeof(t_FmBufPoolDepletion));
54723 + memcpy(&p_FmPort->p_FmPortDriverParam->extBufPools,
54724 + &p_FmPortObservedBufPoolDepletion->poolsParams,
54725 + sizeof(t_FmExtPools));
54726 +
54727 + return E_OK;
54728 +}
54729 +
54730 +t_Error FM_PORT_ConfigExtBufPools(t_Handle h_FmPort, t_FmExtPools *p_FmExtPools)
54731 +{
54732 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
54733 +
54734 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
54735 + SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
54736 +
54737 + if (p_FmPort->portType != e_FM_PORT_TYPE_OH_OFFLINE_PARSING)
54738 + RETURN_ERROR(MAJOR, E_INVALID_OPERATION,
54739 + ("available for OP ports only"));
54740 +
54741 + memcpy(&p_FmPort->p_FmPortDriverParam->extBufPools, p_FmExtPools,
54742 + sizeof(t_FmExtPools));
54743 +
54744 + return E_OK;
54745 +}
54746 +
54747 +t_Error FM_PORT_ConfigDontReleaseTxBufToBM(t_Handle h_FmPort)
54748 +{
54749 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
54750 +
54751 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
54752 + SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
54753 + if ((p_FmPort->portType != e_FM_PORT_TYPE_TX_10G)
54754 + && (p_FmPort->portType != e_FM_PORT_TYPE_TX))
54755 + RETURN_ERROR(MAJOR, E_INVALID_OPERATION,
54756 + ("available for Tx ports only"));
54757 +
54758 + p_FmPort->p_FmPortDriverParam->dontReleaseBuf = TRUE;
54759 +
54760 + return E_OK;
54761 +}
54762 +
54763 +t_Error FM_PORT_ConfigDfltColor(t_Handle h_FmPort, e_FmPortColor color)
54764 +{
54765 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
54766 +
54767 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
54768 + SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
54769 + p_FmPort->p_FmPortDriverParam->dfltCfg.color = (enum fman_port_color)color;
54770 +
54771 + return E_OK;
54772 +}
54773 +
54774 +t_Error FM_PORT_ConfigSyncReq(t_Handle h_FmPort, bool syncReq)
54775 +{
54776 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
54777 +
54778 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
54779 + SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
54780 +
54781 + if ((p_FmPort->portType == e_FM_PORT_TYPE_TX_10G)
54782 + || (p_FmPort->portType == e_FM_PORT_TYPE_TX))
54783 + RETURN_ERROR(MAJOR, E_INVALID_OPERATION,
54784 + ("Not available for Tx ports"));
54785 +
54786 + p_FmPort->p_FmPortDriverParam->dfltCfg.sync_req = syncReq;
54787 +
54788 + return E_OK;
54789 +}
54790 +
54791 +t_Error FM_PORT_ConfigFrmDiscardOverride(t_Handle h_FmPort, bool override)
54792 +{
54793 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
54794 +
54795 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
54796 + SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
54797 + if ((p_FmPort->portType == e_FM_PORT_TYPE_TX_10G)
54798 + || (p_FmPort->portType == e_FM_PORT_TYPE_TX))
54799 + RETURN_ERROR(MAJOR, E_INVALID_OPERATION,
54800 + ("Not available for Tx ports"));
54801 +
54802 + p_FmPort->p_FmPortDriverParam->dfltCfg.discard_override = override;
54803 +
54804 + return E_OK;
54805 +}
54806 +
54807 +t_Error FM_PORT_ConfigErrorsToDiscard(t_Handle h_FmPort,
54808 + fmPortFrameErrSelect_t errs)
54809 +{
54810 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
54811 +
54812 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
54813 + SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
54814 + if ((p_FmPort->portType != e_FM_PORT_TYPE_RX_10G)
54815 + && (p_FmPort->portType != e_FM_PORT_TYPE_RX)
54816 + && (p_FmPort->portType != e_FM_PORT_TYPE_OH_OFFLINE_PARSING))
54817 + RETURN_ERROR( MAJOR, E_INVALID_OPERATION,
54818 + ("available for Rx and offline parsing ports only"));
54819 +
54820 + p_FmPort->p_FmPortDriverParam->errorsToDiscard = errs;
54821 +
54822 + return E_OK;
54823 +}
54824 +
54825 +t_Error FM_PORT_ConfigDmaSwapData(t_Handle h_FmPort, e_FmDmaSwapOption swapData)
54826 +{
54827 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
54828 +
54829 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
54830 + SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
54831 +
54832 + p_FmPort->p_FmPortDriverParam->dfltCfg.dma_swap_data =
54833 + (enum fman_port_dma_swap)swapData;
54834 +
54835 + return E_OK;
54836 +}
54837 +
54838 +t_Error FM_PORT_ConfigDmaIcCacheAttr(t_Handle h_FmPort,
54839 + e_FmDmaCacheOption intContextCacheAttr)
54840 +{
54841 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
54842 +
54843 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
54844 + SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
54845 +
54846 + p_FmPort->p_FmPortDriverParam->dfltCfg.dma_ic_stash_on =
54847 + (bool)(intContextCacheAttr == e_FM_DMA_STASH);
54848 +
54849 + return E_OK;
54850 +}
54851 +
54852 +t_Error FM_PORT_ConfigDmaHdrAttr(t_Handle h_FmPort,
54853 + e_FmDmaCacheOption headerCacheAttr)
54854 +{
54855 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
54856 +
54857 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
54858 + SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
54859 +
54860 + p_FmPort->p_FmPortDriverParam->dfltCfg.dma_header_stash_on =
54861 + (bool)(headerCacheAttr == e_FM_DMA_STASH);
54862 +
54863 + return E_OK;
54864 +}
54865 +
54866 +t_Error FM_PORT_ConfigDmaScatterGatherAttr(
54867 + t_Handle h_FmPort, e_FmDmaCacheOption scatterGatherCacheAttr)
54868 +{
54869 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
54870 +
54871 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
54872 + SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
54873 +
54874 + p_FmPort->p_FmPortDriverParam->dfltCfg.dma_sg_stash_on =
54875 + (bool)(scatterGatherCacheAttr == e_FM_DMA_STASH);
54876 +
54877 + return E_OK;
54878 +}
54879 +
54880 +t_Error FM_PORT_ConfigDmaWriteOptimize(t_Handle h_FmPort, bool optimize)
54881 +{
54882 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
54883 +
54884 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
54885 + SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
54886 +
54887 + if ((p_FmPort->portType == e_FM_PORT_TYPE_TX_10G)
54888 + || (p_FmPort->portType == e_FM_PORT_TYPE_TX))
54889 + RETURN_ERROR(MAJOR, E_INVALID_OPERATION,
54890 + ("Not available for Tx ports"));
54891 +
54892 + p_FmPort->p_FmPortDriverParam->dfltCfg.dma_write_optimize = optimize;
54893 +
54894 + return E_OK;
54895 +}
54896 +
54897 +#if (DPAA_VERSION >= 11)
54898 +t_Error FM_PORT_ConfigNoScatherGather(t_Handle h_FmPort, bool noScatherGather)
54899 +{
54900 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
54901 +
54902 + UNUSED(noScatherGather);
54903 + UNUSED(p_FmPort);
54904 +
54905 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
54906 + SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
54907 +
54908 + p_FmPort->p_FmPortDriverParam->noScatherGather = noScatherGather;
54909 +
54910 + return E_OK;
54911 +}
54912 +#endif /* (DPAA_VERSION >= 11) */
54913 +
54914 +t_Error FM_PORT_ConfigForwardReuseIntContext(t_Handle h_FmPort,
54915 + bool forwardReuse)
54916 +{
54917 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
54918 +
54919 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
54920 + SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
54921 +
54922 + if ((p_FmPort->portType != e_FM_PORT_TYPE_RX_10G)
54923 + && (p_FmPort->portType != e_FM_PORT_TYPE_RX))
54924 + RETURN_ERROR(MAJOR, E_INVALID_OPERATION,
54925 + ("available for Rx ports only"));
54926 +
54927 + p_FmPort->p_FmPortDriverParam->forwardReuseIntContext = forwardReuse;
54928 +
54929 + return E_OK;
54930 +}
54931 +
54932 +t_Error FM_PORT_ConfigMaxFrameLength(t_Handle h_FmPort, uint16_t length)
54933 +{
54934 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
54935 +
54936 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
54937 + SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
54938 +
54939 + p_FmPort->maxFrameLength = length;
54940 +
54941 + return E_OK;
54942 +}
54943 +
54944 +#ifdef FM_HEAVY_TRAFFIC_HANG_ERRATA_FMAN_A005669
54945 +t_Error FM_PORT_ConfigBCBWorkaround(t_Handle h_FmPort)
54946 +{
54947 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
54948 +
54949 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
54950 + SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
54951 +
54952 + p_FmPort->p_FmPortDriverParam->bcbWorkaround = TRUE;
54953 +
54954 + return E_OK;
54955 +}
54956 +#endif /* FM_HEAVY_TRAFFIC_HANG_ERRATA_FMAN_A005669 */
54957 +
54958 +/****************************************************/
54959 +/* Hidden-DEBUG Only API */
54960 +/****************************************************/
54961 +
54962 +t_Error FM_PORT_ConfigTxFifoMinFillLevel(t_Handle h_FmPort,
54963 + uint32_t minFillLevel)
54964 +{
54965 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
54966 +
54967 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
54968 + SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
54969 + if ((p_FmPort->portType != e_FM_PORT_TYPE_TX_10G)
54970 + && (p_FmPort->portType != e_FM_PORT_TYPE_TX))
54971 + RETURN_ERROR(MAJOR, E_INVALID_OPERATION,
54972 + ("available for Tx ports only"));
54973 +
54974 + p_FmPort->p_FmPortDriverParam->dfltCfg.tx_fifo_min_level = minFillLevel;
54975 +
54976 + return E_OK;
54977 +}
54978 +
54979 +t_Error FM_PORT_ConfigFifoDeqPipelineDepth(t_Handle h_FmPort,
54980 + uint8_t deqPipelineDepth)
54981 +{
54982 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
54983 +
54984 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
54985 + SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
54986 +
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 + ("Not available for Rx ports"));
54991 +
54992 + if (p_FmPort->imEn)
54993 + RETURN_ERROR(MAJOR, E_INVALID_OPERATION,
54994 + ("Not available for IM ports!"));
54995 +
54996 + p_FmPort->p_FmPortDriverParam->dfltCfg.tx_fifo_deq_pipeline_depth =
54997 + deqPipelineDepth;
54998 +
54999 + return E_OK;
55000 +}
55001 +
55002 +t_Error FM_PORT_ConfigTxFifoLowComfLevel(t_Handle h_FmPort,
55003 + uint32_t fifoLowComfLevel)
55004 +{
55005 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
55006 +
55007 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
55008 + SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
55009 + if ((p_FmPort->portType != e_FM_PORT_TYPE_TX_10G)
55010 + && (p_FmPort->portType != e_FM_PORT_TYPE_TX))
55011 + RETURN_ERROR(MAJOR, E_INVALID_OPERATION,
55012 + ("available for Tx ports only"));
55013 +
55014 + p_FmPort->p_FmPortDriverParam->dfltCfg.tx_fifo_low_comf_level =
55015 + fifoLowComfLevel;
55016 +
55017 + return E_OK;
55018 +}
55019 +
55020 +t_Error FM_PORT_ConfigRxFifoThreshold(t_Handle h_FmPort, uint32_t fifoThreshold)
55021 +{
55022 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
55023 +
55024 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
55025 + SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
55026 + if ((p_FmPort->portType != e_FM_PORT_TYPE_RX_10G)
55027 + && (p_FmPort->portType != e_FM_PORT_TYPE_RX))
55028 + RETURN_ERROR(MAJOR, E_INVALID_OPERATION,
55029 + ("available for Rx ports only"));
55030 +
55031 + p_FmPort->p_FmPortDriverParam->dfltCfg.rx_fifo_thr = fifoThreshold;
55032 +
55033 + return E_OK;
55034 +}
55035 +
55036 +t_Error FM_PORT_ConfigRxFifoPriElevationLevel(t_Handle h_FmPort,
55037 + uint32_t priElevationLevel)
55038 +{
55039 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
55040 +
55041 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
55042 + SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
55043 + if ((p_FmPort->portType != e_FM_PORT_TYPE_RX_10G)
55044 + && (p_FmPort->portType != e_FM_PORT_TYPE_RX))
55045 + RETURN_ERROR(MAJOR, E_INVALID_OPERATION,
55046 + ("available for Rx ports only"));
55047 +
55048 + p_FmPort->p_FmPortDriverParam->dfltCfg.rx_pri_elevation = priElevationLevel;
55049 +
55050 + return E_OK;
55051 +}
55052 +/****************************************************/
55053 +/* API Run-time Control unit functions */
55054 +/****************************************************/
55055 +
55056 +t_Error FM_PORT_SetNumOfOpenDmas(t_Handle h_FmPort,
55057 + t_FmPortRsrc *p_NumOfOpenDmas)
55058 +{
55059 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
55060 + t_Error err;
55061 +
55062 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
55063 + SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
55064 +
55065 + if ((!p_NumOfOpenDmas->num) || (p_NumOfOpenDmas->num > MAX_NUM_OF_DMAS))
55066 + RETURN_ERROR( MAJOR, E_INVALID_VALUE,
55067 + ("openDmas-num can't be larger than %d", MAX_NUM_OF_DMAS));
55068 + if (p_NumOfOpenDmas->extra > MAX_NUM_OF_EXTRA_DMAS)
55069 + RETURN_ERROR(
55070 + MAJOR,
55071 + E_INVALID_VALUE,
55072 + ("openDmas-extra can't be larger than %d", MAX_NUM_OF_EXTRA_DMAS));
55073 + err = FmSetNumOfOpenDmas(p_FmPort->h_Fm, p_FmPort->hardwarePortId,
55074 + (uint8_t*)&p_NumOfOpenDmas->num,
55075 + (uint8_t*)&p_NumOfOpenDmas->extra, FALSE);
55076 + if (err)
55077 + RETURN_ERROR(MAJOR, err, NO_MSG);
55078 +
55079 + memcpy(&p_FmPort->openDmas, p_NumOfOpenDmas, sizeof(t_FmPortRsrc));
55080 +
55081 + return E_OK;
55082 +}
55083 +
55084 +t_Error FM_PORT_SetNumOfTasks(t_Handle h_FmPort, t_FmPortRsrc *p_NumOfTasks)
55085 +{
55086 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
55087 + t_Error err;
55088 +
55089 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
55090 + SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
55091 +
55092 + /* only driver uses host command port, so ASSERT rather than RETURN_ERROR */
55093 + ASSERT_COND(p_FmPort->portType != e_FM_PORT_TYPE_OH_HOST_COMMAND);
55094 +
55095 + if ((!p_NumOfTasks->num) || (p_NumOfTasks->num > MAX_NUM_OF_TASKS))
55096 + RETURN_ERROR(
55097 + MAJOR, E_INVALID_VALUE,
55098 + ("NumOfTasks-num can't be larger than %d", MAX_NUM_OF_TASKS));
55099 + if (p_NumOfTasks->extra > MAX_NUM_OF_EXTRA_TASKS)
55100 + RETURN_ERROR(
55101 + MAJOR,
55102 + E_INVALID_VALUE,
55103 + ("NumOfTasks-extra can't be larger than %d", MAX_NUM_OF_EXTRA_TASKS));
55104 +
55105 + err = FmSetNumOfTasks(p_FmPort->h_Fm, p_FmPort->hardwarePortId,
55106 + (uint8_t*)&p_NumOfTasks->num,
55107 + (uint8_t*)&p_NumOfTasks->extra, FALSE);
55108 + if (err)
55109 + RETURN_ERROR(MAJOR, err, NO_MSG);
55110 +
55111 + /* update driver's struct */
55112 + memcpy(&p_FmPort->tasks, p_NumOfTasks, sizeof(t_FmPortRsrc));
55113 + return E_OK;
55114 +}
55115 +
55116 +t_Error FM_PORT_SetSizeOfFifo(t_Handle h_FmPort, t_FmPortRsrc *p_SizeOfFifo)
55117 +{
55118 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
55119 + t_Error err;
55120 +
55121 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
55122 + SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
55123 +
55124 + if (!p_SizeOfFifo->num || (p_SizeOfFifo->num > MAX_PORT_FIFO_SIZE))
55125 + RETURN_ERROR(
55126 + MAJOR,
55127 + E_INVALID_VALUE,
55128 + ("SizeOfFifo-num has to be in the range of 256 - %d", MAX_PORT_FIFO_SIZE));
55129 + if (p_SizeOfFifo->num % BMI_FIFO_UNITS)
55130 + RETURN_ERROR(
55131 + MAJOR, E_INVALID_VALUE,
55132 + ("SizeOfFifo-num has to be divisible by %d", BMI_FIFO_UNITS));
55133 + if ((p_FmPort->portType == e_FM_PORT_TYPE_RX)
55134 + || (p_FmPort->portType == e_FM_PORT_TYPE_RX_10G))
55135 + {
55136 + /* extra FIFO size (allowed only to Rx ports) */
55137 + if (p_SizeOfFifo->extra % BMI_FIFO_UNITS)
55138 + RETURN_ERROR(
55139 + MAJOR,
55140 + E_INVALID_VALUE,
55141 + ("SizeOfFifo-extra has to be divisible by %d", BMI_FIFO_UNITS));
55142 + }
55143 + else
55144 + if (p_SizeOfFifo->extra)
55145 + RETURN_ERROR(MAJOR, E_INVALID_VALUE,
55146 + (" No SizeOfFifo-extra for non Rx ports"));
55147 +
55148 + memcpy(&p_FmPort->fifoBufs, p_SizeOfFifo, sizeof(t_FmPortRsrc));
55149 +
55150 + /* we do not change user's parameter */
55151 + err = VerifySizeOfFifo(p_FmPort);
55152 + if (err)
55153 + RETURN_ERROR(MAJOR, err, NO_MSG);
55154 +
55155 + err = FmSetSizeOfFifo(p_FmPort->h_Fm, p_FmPort->hardwarePortId,
55156 + &p_SizeOfFifo->num, &p_SizeOfFifo->extra, FALSE);
55157 + if (err)
55158 + RETURN_ERROR(MAJOR, err, NO_MSG);
55159 +
55160 + return E_OK;
55161 +}
55162 +
55163 +uint32_t FM_PORT_GetBufferDataOffset(t_Handle h_FmPort)
55164 +{
55165 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
55166 +
55167 + SANITY_CHECK_RETURN_VALUE(p_FmPort, E_INVALID_HANDLE, 0);
55168 + SANITY_CHECK_RETURN_VALUE(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE,
55169 + 0);
55170 +
55171 + return p_FmPort->bufferOffsets.dataOffset;
55172 +}
55173 +
55174 +uint8_t * FM_PORT_GetBufferICInfo(t_Handle h_FmPort, char *p_Data)
55175 +{
55176 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
55177 +
55178 + SANITY_CHECK_RETURN_VALUE(p_FmPort, E_INVALID_HANDLE, NULL);
55179 + SANITY_CHECK_RETURN_VALUE(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE,
55180 + NULL);
55181 +
55182 + if (p_FmPort->bufferOffsets.pcdInfoOffset == ILLEGAL_BASE)
55183 + return NULL;
55184 +
55185 + return (uint8_t *)PTR_MOVE(p_Data, p_FmPort->bufferOffsets.pcdInfoOffset);
55186 +}
55187 +
55188 +t_FmPrsResult * FM_PORT_GetBufferPrsResult(t_Handle h_FmPort, char *p_Data)
55189 +{
55190 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
55191 +
55192 + SANITY_CHECK_RETURN_VALUE(p_FmPort, E_INVALID_HANDLE, NULL);
55193 + SANITY_CHECK_RETURN_VALUE(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE,
55194 + NULL);
55195 +
55196 + if (p_FmPort->bufferOffsets.prsResultOffset == ILLEGAL_BASE)
55197 + return NULL;
55198 +
55199 + return (t_FmPrsResult *)PTR_MOVE(p_Data, p_FmPort->bufferOffsets.prsResultOffset);
55200 +}
55201 +
55202 +uint64_t * FM_PORT_GetBufferTimeStamp(t_Handle h_FmPort, char *p_Data)
55203 +{
55204 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
55205 +
55206 + SANITY_CHECK_RETURN_VALUE(p_FmPort, E_INVALID_HANDLE, NULL);
55207 + SANITY_CHECK_RETURN_VALUE(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE,
55208 + NULL);
55209 +
55210 + if (p_FmPort->bufferOffsets.timeStampOffset == ILLEGAL_BASE)
55211 + return NULL;
55212 +
55213 + return (uint64_t *)PTR_MOVE(p_Data, p_FmPort->bufferOffsets.timeStampOffset);
55214 +}
55215 +
55216 +uint8_t * FM_PORT_GetBufferHashResult(t_Handle h_FmPort, char *p_Data)
55217 +{
55218 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
55219 +
55220 + SANITY_CHECK_RETURN_VALUE(p_FmPort, E_INVALID_HANDLE, NULL);
55221 + SANITY_CHECK_RETURN_VALUE(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE,
55222 + NULL);
55223 +
55224 + if (p_FmPort->bufferOffsets.hashResultOffset == ILLEGAL_BASE)
55225 + return NULL;
55226 +
55227 + return (uint8_t *)PTR_MOVE(p_Data, p_FmPort->bufferOffsets.hashResultOffset);
55228 +}
55229 +
55230 +t_Error FM_PORT_Disable(t_Handle h_FmPort)
55231 +{
55232 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
55233 + int err;
55234 +
55235 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
55236 + SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE);
55237 +
55238 + if (p_FmPort->imEn)
55239 + FmPortImDisable(p_FmPort);
55240 +
55241 + err = fman_port_disable(&p_FmPort->port);
55242 + if (err == -EBUSY)
55243 + {
55244 + DBG(WARNING, ("%s: BMI or QMI is Busy. Port forced down",
55245 + p_FmPort->name));
55246 + }
55247 + else
55248 + if (err != 0)
55249 + {
55250 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("fman_port_disable"));
55251 + }
55252 +
55253 + p_FmPort->enabled = FALSE;
55254 +
55255 + return E_OK;
55256 +}
55257 +
55258 +t_Error FM_PORT_Enable(t_Handle h_FmPort)
55259 +{
55260 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
55261 + int err;
55262 +
55263 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
55264 + SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE);
55265 +
55266 + /* Used by FM_PORT_Free routine as indication
55267 + if to disable port. Thus set it to TRUE prior
55268 + to enabling itself. This way if part of enable
55269 + process fails there will be still things
55270 + to disable during Free. For example, if BMI
55271 + enable succeeded but QMI failed, still BMI
55272 + needs to be disabled by Free. */
55273 + p_FmPort->enabled = TRUE;
55274 +
55275 + if (p_FmPort->imEn)
55276 + FmPortImEnable(p_FmPort);
55277 +
55278 + err = fman_port_enable(&p_FmPort->port);
55279 + if (err != 0)
55280 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("fman_port_enable"));
55281 +
55282 + return E_OK;
55283 +}
55284 +
55285 +t_Error FM_PORT_SetRateLimit(t_Handle h_FmPort, t_FmPortRateLimit *p_RateLimit)
55286 +{
55287 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
55288 + uint8_t factor, countUnitBit;
55289 + uint16_t baseGran;
55290 + struct fman_port_rate_limiter params;
55291 + int err;
55292 +
55293 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
55294 + SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
55295 +
55296 + switch (p_FmPort->portType)
55297 + {
55298 + case (e_FM_PORT_TYPE_TX_10G):
55299 + case (e_FM_PORT_TYPE_TX):
55300 + baseGran = BMI_RATE_LIMIT_GRAN_TX;
55301 + break;
55302 + case (e_FM_PORT_TYPE_OH_OFFLINE_PARSING):
55303 + baseGran = BMI_RATE_LIMIT_GRAN_OP;
55304 + break;
55305 + default:
55306 + RETURN_ERROR( MAJOR, E_INVALID_OPERATION,
55307 + ("available for Tx and Offline parsing ports only"));
55308 + }
55309 +
55310 + countUnitBit = (uint8_t)FmGetTimeStampScale(p_FmPort->h_Fm); /* TimeStamp per nano seconds units */
55311 + /* normally, we use 1 usec as the reference count */
55312 + factor = 1;
55313 + /* if ratelimit is too small for a 1usec factor, multiply the factor */
55314 + while (p_RateLimit->rateLimit < baseGran / factor)
55315 + {
55316 + if (countUnitBit == 31)
55317 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Rate limit is too small"));
55318 +
55319 + countUnitBit++;
55320 + factor <<= 1;
55321 + }
55322 + /* if ratelimit is too large for a 1usec factor, it is also larger than max rate*/
55323 + if (p_RateLimit->rateLimit
55324 + > ((uint32_t)baseGran * (1 << 10) * (uint32_t)factor))
55325 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Rate limit is too large"));
55326 +
55327 + if (!p_RateLimit->maxBurstSize
55328 + || (p_RateLimit->maxBurstSize > BMI_RATE_LIMIT_MAX_BURST_SIZE))
55329 + RETURN_ERROR(
55330 + MAJOR,
55331 + E_INVALID_VALUE,
55332 + ("maxBurstSize must be between 1K and %dk", BMI_RATE_LIMIT_MAX_BURST_SIZE));
55333 +
55334 + params.count_1micro_bit = (uint8_t)FmGetTimeStampScale(p_FmPort->h_Fm);
55335 + params.high_burst_size_gran = FALSE;
55336 + params.burst_size = p_RateLimit->maxBurstSize;
55337 + params.rate = p_RateLimit->rateLimit;
55338 + params.rate_factor = E_FMAN_PORT_RATE_DOWN_NONE;
55339 +
55340 + if (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING)
55341 + {
55342 +#ifndef FM_NO_ADVANCED_RATE_LIMITER
55343 +
55344 + if ((p_FmPort->fmRevInfo.majorRev == 4)
55345 + || (p_FmPort->fmRevInfo.majorRev >= 6))
55346 + {
55347 + params.high_burst_size_gran = TRUE;
55348 + }
55349 + else
55350 +#endif /* ! FM_NO_ADVANCED_RATE_LIMITER */
55351 + {
55352 + if (p_RateLimit->rateLimitDivider
55353 + != e_FM_PORT_DUAL_RATE_LIMITER_NONE)
55354 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED,
55355 + ("FM_PORT_ConfigDualRateLimitScaleDown"));
55356 +
55357 + if (p_RateLimit->maxBurstSize % 1000)
55358 + {
55359 + p_RateLimit->maxBurstSize =
55360 + (uint16_t)((p_RateLimit->maxBurstSize / 1000) + 1);
55361 + DBG(WARNING, ("rateLimit.maxBurstSize rounded up to %d", (p_RateLimit->maxBurstSize/1000+1)*1000));
55362 + }
55363 + else
55364 + p_RateLimit->maxBurstSize = (uint16_t)(p_RateLimit->maxBurstSize
55365 + / 1000);
55366 + }
55367 + params.rate_factor =
55368 + (enum fman_port_rate_limiter_scale_down)p_RateLimit->rateLimitDivider;
55369 + params.burst_size = p_RateLimit->maxBurstSize;
55370 + }
55371 +
55372 + err = fman_port_set_rate_limiter(&p_FmPort->port, &params);
55373 + if (err != 0)
55374 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("fman_port_set_rate_limiter"));
55375 +
55376 + return E_OK;
55377 +}
55378 +
55379 +t_Error FM_PORT_DeleteRateLimit(t_Handle h_FmPort)
55380 +{
55381 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
55382 + int err;
55383 +
55384 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
55385 + SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
55386 +
55387 + if ((p_FmPort->portType == e_FM_PORT_TYPE_RX_10G)
55388 + || (p_FmPort->portType == e_FM_PORT_TYPE_RX)
55389 + || (p_FmPort->portType == e_FM_PORT_TYPE_OH_HOST_COMMAND))
55390 + RETURN_ERROR( MAJOR, E_INVALID_OPERATION,
55391 + ("available for Tx and Offline parsing ports only"));
55392 +
55393 + err = fman_port_delete_rate_limiter(&p_FmPort->port);
55394 + if (err != 0)
55395 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("fman_port_set_rate_limiter"));
55396 + return E_OK;
55397 +}
55398 +
55399 +t_Error FM_PORT_SetPfcPrioritiesMappingToQmanWQ(t_Handle h_FmPort, uint8_t prio,
55400 + uint8_t wq)
55401 +{
55402 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
55403 + uint32_t tmpReg;
55404 + uint32_t wqTmpReg;
55405 +
55406 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
55407 + SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE);
55408 +
55409 + if ((p_FmPort->portType != e_FM_PORT_TYPE_TX)
55410 + && (p_FmPort->portType != e_FM_PORT_TYPE_TX_10G))
55411 + RETURN_ERROR(MAJOR, E_INVALID_OPERATION,
55412 + ("PFC mapping is available for Tx ports only"));
55413 +
55414 + if (prio > 7)
55415 + RETURN_ERROR(MAJOR, E_NOT_IN_RANGE,
55416 + ("PFC priority (%d) is out of range (0-7)", prio));
55417 + if (wq > 7)
55418 + RETURN_ERROR(MAJOR, E_NOT_IN_RANGE,
55419 + ("WQ (%d) is out of range (0-7)", wq));
55420 +
55421 + tmpReg = GET_UINT32(p_FmPort->p_FmPortBmiRegs->txPortBmiRegs.fmbm_tpfcm[0]);
55422 + tmpReg &= ~(0xf << ((7 - prio) * 4));
55423 + wqTmpReg = ((uint32_t)wq << ((7 - prio) * 4));
55424 + tmpReg |= wqTmpReg;
55425 +
55426 + WRITE_UINT32(p_FmPort->p_FmPortBmiRegs->txPortBmiRegs.fmbm_tpfcm[0],
55427 + tmpReg);
55428 +
55429 + return E_OK;
55430 +}
55431 +
55432 +t_Error FM_PORT_SetFrameQueueCounters(t_Handle h_FmPort, bool enable)
55433 +{
55434 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
55435 +
55436 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
55437 + SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE);
55438 +
55439 + fman_port_set_queue_cnt_mode(&p_FmPort->port, enable);
55440 +
55441 + return E_OK;
55442 +}
55443 +
55444 +t_Error FM_PORT_SetPerformanceCounters(t_Handle h_FmPort, bool enable)
55445 +{
55446 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
55447 + int err;
55448 +
55449 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
55450 + SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE);
55451 +
55452 + err = fman_port_set_perf_cnt_mode(&p_FmPort->port, enable);
55453 + if (err != 0)
55454 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("fman_port_set_perf_cnt_mode"));
55455 + return E_OK;
55456 +}
55457 +
55458 +t_Error FM_PORT_SetPerformanceCountersParams(
55459 + t_Handle h_FmPort, t_FmPortPerformanceCnt *p_FmPortPerformanceCnt)
55460 +{
55461 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
55462 + struct fman_port_perf_cnt_params params;
55463 + int err;
55464 +
55465 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
55466 +
55467 + /* check parameters */
55468 + if (!p_FmPortPerformanceCnt->taskCompVal
55469 + || (p_FmPortPerformanceCnt->taskCompVal > p_FmPort->tasks.num))
55470 + RETURN_ERROR(
55471 + MAJOR,
55472 + E_INVALID_VALUE,
55473 + ("taskCompVal (%d) has to be in the range of 1 - %d (current value)!", p_FmPortPerformanceCnt->taskCompVal, p_FmPort->tasks.num));
55474 + if (!p_FmPortPerformanceCnt->dmaCompVal
55475 + || (p_FmPortPerformanceCnt->dmaCompVal > p_FmPort->openDmas.num))
55476 + RETURN_ERROR(
55477 + MAJOR,
55478 + E_INVALID_VALUE,
55479 + ("dmaCompVal (%d) has to be in the range of 1 - %d (current value)!", p_FmPortPerformanceCnt->dmaCompVal, p_FmPort->openDmas.num));
55480 + if (!p_FmPortPerformanceCnt->fifoCompVal
55481 + || (p_FmPortPerformanceCnt->fifoCompVal > p_FmPort->fifoBufs.num))
55482 + RETURN_ERROR(
55483 + MAJOR,
55484 + E_INVALID_VALUE,
55485 + ("fifoCompVal (%d) has to be in the range of 256 - %d (current value)!", p_FmPortPerformanceCnt->fifoCompVal, p_FmPort->fifoBufs.num));
55486 + if (p_FmPortPerformanceCnt->fifoCompVal % BMI_FIFO_UNITS)
55487 + RETURN_ERROR(
55488 + MAJOR,
55489 + E_INVALID_VALUE,
55490 + ("fifoCompVal (%d) has to be divisible by %d", p_FmPortPerformanceCnt->fifoCompVal, BMI_FIFO_UNITS));
55491 +
55492 + switch (p_FmPort->portType)
55493 + {
55494 + case (e_FM_PORT_TYPE_RX_10G):
55495 + case (e_FM_PORT_TYPE_RX):
55496 + if (!p_FmPortPerformanceCnt->queueCompVal
55497 + || (p_FmPortPerformanceCnt->queueCompVal
55498 + > MAX_PERFORMANCE_RX_QUEUE_COMP))
55499 + RETURN_ERROR(
55500 + MAJOR,
55501 + E_INVALID_VALUE,
55502 + ("performanceCnt.queueCompVal for Rx has to be in the range of 1 - %d", MAX_PERFORMANCE_RX_QUEUE_COMP));
55503 + break;
55504 + case (e_FM_PORT_TYPE_TX_10G):
55505 + case (e_FM_PORT_TYPE_TX):
55506 + if (!p_FmPortPerformanceCnt->queueCompVal
55507 + || (p_FmPortPerformanceCnt->queueCompVal
55508 + > MAX_PERFORMANCE_TX_QUEUE_COMP))
55509 + RETURN_ERROR(
55510 + MAJOR,
55511 + E_INVALID_VALUE,
55512 + ("performanceCnt.queueCompVal for Tx has to be in the range of 1 - %d", MAX_PERFORMANCE_TX_QUEUE_COMP));
55513 + break;
55514 + case (e_FM_PORT_TYPE_OH_OFFLINE_PARSING):
55515 + case (e_FM_PORT_TYPE_OH_HOST_COMMAND):
55516 + if (p_FmPortPerformanceCnt->queueCompVal)
55517 + RETURN_ERROR(
55518 + MAJOR,
55519 + E_INVALID_VALUE,
55520 + ("performanceCnt.queueCompVal is not relevant for H/O ports."));
55521 + break;
55522 + default:
55523 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Invalid port type"));
55524 + }
55525 +
55526 + params.task_val = p_FmPortPerformanceCnt->taskCompVal;
55527 + params.queue_val = p_FmPortPerformanceCnt->queueCompVal;
55528 + params.dma_val = p_FmPortPerformanceCnt->dmaCompVal;
55529 + params.fifo_val = p_FmPortPerformanceCnt->fifoCompVal;
55530 +
55531 + err = fman_port_set_perf_cnt_params(&p_FmPort->port, &params);
55532 + if (err != 0)
55533 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("fman_port_set_perf_cnt_params"));
55534 +
55535 + return E_OK;
55536 +}
55537 +
55538 +t_Error FM_PORT_AnalyzePerformanceParams(t_Handle h_FmPort)
55539 +{
55540 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
55541 + t_FmPortPerformanceCnt currParams, savedParams;
55542 + t_Error err;
55543 + bool underTest, failed = FALSE;
55544 +
55545 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
55546 +
55547 + XX_Print("Analyzing Performance parameters for port (type %d, id%d)\n",
55548 + p_FmPort->portType, p_FmPort->portId);
55549 +
55550 + currParams.taskCompVal = (uint8_t)p_FmPort->tasks.num;
55551 + if ((p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING)
55552 + || (p_FmPort->portType == e_FM_PORT_TYPE_OH_HOST_COMMAND))
55553 + currParams.queueCompVal = 0;
55554 + else
55555 + currParams.queueCompVal = 1;
55556 + currParams.dmaCompVal = (uint8_t)p_FmPort->openDmas.num;
55557 + currParams.fifoCompVal = p_FmPort->fifoBufs.num;
55558 +
55559 + FM_PORT_SetPerformanceCounters(p_FmPort, FALSE);
55560 + ClearPerfCnts(p_FmPort);
55561 + if ((err = FM_PORT_SetPerformanceCountersParams(p_FmPort, &currParams))
55562 + != E_OK)
55563 + RETURN_ERROR(MAJOR, err, NO_MSG);
55564 + FM_PORT_SetPerformanceCounters(p_FmPort, TRUE);
55565 + XX_UDelay(1000000);
55566 + FM_PORT_SetPerformanceCounters(p_FmPort, FALSE);
55567 + if (FM_PORT_GetCounter(p_FmPort, e_FM_PORT_COUNTERS_TASK_UTIL))
55568 + {
55569 + XX_Print(
55570 + "Max num of defined port tasks (%d) utilized - Please enlarge\n",
55571 + p_FmPort->tasks.num);
55572 + failed = TRUE;
55573 + }
55574 + if (FM_PORT_GetCounter(p_FmPort, e_FM_PORT_COUNTERS_DMA_UTIL))
55575 + {
55576 + XX_Print(
55577 + "Max num of defined port openDmas (%d) utilized - Please enlarge\n",
55578 + p_FmPort->openDmas.num);
55579 + failed = TRUE;
55580 + }
55581 + if (FM_PORT_GetCounter(p_FmPort, e_FM_PORT_COUNTERS_FIFO_UTIL))
55582 + {
55583 + XX_Print(
55584 + "Max size of defined port fifo (%d) utilized - Please enlarge\n",
55585 + p_FmPort->fifoBufs.num);
55586 + failed = TRUE;
55587 + }
55588 + if (failed)
55589 + RETURN_ERROR(MAJOR, E_INVALID_STATE, NO_MSG);
55590 +
55591 + memset(&savedParams, 0, sizeof(savedParams));
55592 + while (TRUE)
55593 + {
55594 + underTest = FALSE;
55595 + if ((currParams.taskCompVal != 1) && !savedParams.taskCompVal)
55596 + {
55597 + currParams.taskCompVal--;
55598 + underTest = TRUE;
55599 + }
55600 + if ((currParams.dmaCompVal != 1) && !savedParams.dmaCompVal)
55601 + {
55602 + currParams.dmaCompVal--;
55603 + underTest = TRUE;
55604 + }
55605 + if ((currParams.fifoCompVal != BMI_FIFO_UNITS)
55606 + && !savedParams.fifoCompVal)
55607 + {
55608 + currParams.fifoCompVal -= BMI_FIFO_UNITS;
55609 + underTest = TRUE;
55610 + }
55611 + if (!underTest)
55612 + break;
55613 +
55614 + ClearPerfCnts(p_FmPort);
55615 + if ((err = FM_PORT_SetPerformanceCountersParams(p_FmPort, &currParams))
55616 + != E_OK)
55617 + RETURN_ERROR(MAJOR, err, NO_MSG);
55618 + FM_PORT_SetPerformanceCounters(p_FmPort, TRUE);
55619 + XX_UDelay(1000000);
55620 + FM_PORT_SetPerformanceCounters(p_FmPort, FALSE);
55621 +
55622 + if (!savedParams.taskCompVal
55623 + && FM_PORT_GetCounter(p_FmPort, e_FM_PORT_COUNTERS_TASK_UTIL))
55624 + savedParams.taskCompVal = (uint8_t)(currParams.taskCompVal + 2);
55625 + if (!savedParams.dmaCompVal
55626 + && FM_PORT_GetCounter(p_FmPort, e_FM_PORT_COUNTERS_DMA_UTIL))
55627 + savedParams.dmaCompVal = (uint8_t)(currParams.dmaCompVal + 2);
55628 + if (!savedParams.fifoCompVal
55629 + && FM_PORT_GetCounter(p_FmPort, e_FM_PORT_COUNTERS_FIFO_UTIL))
55630 + savedParams.fifoCompVal = currParams.fifoCompVal
55631 + + (2 * BMI_FIFO_UNITS);
55632 + }
55633 +
55634 + XX_Print("best vals: tasks %d, dmas %d, fifos %d\n",
55635 + savedParams.taskCompVal, savedParams.dmaCompVal,
55636 + savedParams.fifoCompVal);
55637 + return E_OK;
55638 +}
55639 +
55640 +t_Error FM_PORT_SetStatisticsCounters(t_Handle h_FmPort, bool enable)
55641 +{
55642 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
55643 + int err;
55644 +
55645 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
55646 + SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE);
55647 +
55648 + err = fman_port_set_stats_cnt_mode(&p_FmPort->port, enable);
55649 + if (err != 0)
55650 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("fman_port_set_stats_cnt_mode"));
55651 + return E_OK;
55652 +}
55653 +
55654 +t_Error FM_PORT_SetErrorsRoute(t_Handle h_FmPort, fmPortFrameErrSelect_t errs)
55655 +{
55656 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
55657 + volatile uint32_t *p_ErrDiscard = NULL;
55658 + int err;
55659 +
55660 + UNUSED(p_ErrDiscard);
55661 + err = fman_port_set_err_mask(&p_FmPort->port, (uint32_t)errs);
55662 + if (err != 0)
55663 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("fman_port_set_err_mask"));
55664 +
55665 +#ifdef FM_ERROR_VSP_NO_MATCH_SW006
55666 + if (p_FmPort->fmRevInfo.majorRev >= 6)
55667 + {
55668 + t_FmPcdCtrlParamsPage *p_ParamsPage;
55669 +
55670 + FmPortSetGprFunc(p_FmPort, e_FM_PORT_GPR_MURAM_PAGE,
55671 + (void**)&p_ParamsPage);
55672 + ASSERT_COND(p_ParamsPage);
55673 + switch (p_FmPort->portType)
55674 + {
55675 + case (e_FM_PORT_TYPE_RX_10G):
55676 + case (e_FM_PORT_TYPE_RX):
55677 + p_ErrDiscard =
55678 + &p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rfsdm;
55679 + break;
55680 + case (e_FM_PORT_TYPE_OH_OFFLINE_PARSING):
55681 + p_ErrDiscard =
55682 + &p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs.fmbm_ofsdm;
55683 + break;
55684 + default:
55685 + RETURN_ERROR(
55686 + MAJOR, E_INVALID_OPERATION,
55687 + ("available for Rx and offline parsing ports only"));
55688 + }
55689 + WRITE_UINT32(p_ParamsPage->errorsDiscardMask,
55690 + GET_UINT32(*p_ErrDiscard) | errs);
55691 + }
55692 +#endif /* FM_ERROR_VSP_NO_MATCH_SW006 */
55693 +
55694 + return E_OK;
55695 +}
55696 +
55697 +t_Error FM_PORT_SetAllocBufCounter(t_Handle h_FmPort, uint8_t poolId,
55698 + bool enable)
55699 +{
55700 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
55701 + int err;
55702 +
55703 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
55704 + SANITY_CHECK_RETURN_ERROR(poolId<BM_MAX_NUM_OF_POOLS, E_INVALID_HANDLE);
55705 + SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE);
55706 +
55707 + if ((p_FmPort->portType != e_FM_PORT_TYPE_RX_10G)
55708 + && (p_FmPort->portType != e_FM_PORT_TYPE_RX))
55709 + RETURN_ERROR(MAJOR, E_INVALID_OPERATION,
55710 + ("available for Rx ports only"));
55711 +
55712 + err = fman_port_set_bpool_cnt_mode(&p_FmPort->port, poolId, enable);
55713 + if (err != 0)
55714 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("fman_port_set_bpool_cnt_mode"));
55715 + return E_OK;
55716 +}
55717 +
55718 +t_Error FM_PORT_GetBmiCounters(t_Handle h_FmPort, t_FmPortBmiStats *p_BmiStats)
55719 +{
55720 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
55721 +
55722 + if ((p_FmPort->portType == e_FM_PORT_TYPE_RX)
55723 + || (p_FmPort->portType == e_FM_PORT_TYPE_RX_10G)){
55724 + p_BmiStats->cntCycle =
55725 + FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_CYCLE);
55726 + /* fmbm_rccn */
55727 + p_BmiStats->cntTaskUtil =
55728 + FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_TASK_UTIL);
55729 + /* fmbm_rtuc */
55730 + p_BmiStats->cntQueueUtil =
55731 + FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_QUEUE_UTIL);
55732 + /* fmbm_rrquc */
55733 + p_BmiStats->cntDmaUtil =
55734 + FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_DMA_UTIL);
55735 + /* fmbm_rduc */
55736 + p_BmiStats->cntFifoUtil =
55737 + FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_FIFO_UTIL);
55738 + /* fmbm_rfuc */
55739 + p_BmiStats->cntRxPauseActivation =
55740 + FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_RX_PAUSE_ACTIVATION);
55741 + /* fmbm_rpac */
55742 + p_BmiStats->cntFrame =
55743 + FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_FRAME);
55744 + /* fmbm_rfrc */
55745 + p_BmiStats->cntDiscardFrame =
55746 + FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_DISCARD_FRAME);
55747 + /* fmbm_rfdc */
55748 + p_BmiStats->cntDeallocBuf =
55749 + FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_DEALLOC_BUF);
55750 + /* fmbm_rbdc */
55751 + p_BmiStats->cntRxBadFrame =
55752 + FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_RX_BAD_FRAME);
55753 + /* fmbm_rfbc */
55754 + p_BmiStats->cntRxLargeFrame =
55755 + FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_RX_LARGE_FRAME);
55756 + /* fmbm_rlfc */
55757 + p_BmiStats->cntRxFilterFrame =
55758 + FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_RX_FILTER_FRAME);
55759 + /* fmbm_rffc */
55760 + p_BmiStats->cntRxListDmaErr =
55761 + FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_RX_LIST_DMA_ERR);
55762 + /* fmbm_rfldec */
55763 + p_BmiStats->cntRxOutOfBuffersDiscard =
55764 + FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_RX_OUT_OF_BUFFERS_DISCARD);
55765 + /* fmbm_rodc */
55766 + p_BmiStats->cntWredDiscard = 0;
55767 + p_BmiStats->cntLengthErr = 0;
55768 + p_BmiStats->cntUnsupportedFormat = 0;
55769 + }
55770 + else if ((p_FmPort->portType == e_FM_PORT_TYPE_TX)
55771 + || (p_FmPort->portType == e_FM_PORT_TYPE_TX_10G)){
55772 + p_BmiStats->cntCycle =
55773 + FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_CYCLE);
55774 + /* fmbm_tccn */
55775 + p_BmiStats->cntTaskUtil =
55776 + FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_TASK_UTIL);
55777 + /* fmbm_ttuc */
55778 + p_BmiStats->cntQueueUtil =
55779 + FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_QUEUE_UTIL);
55780 + /* fmbm_ttcquc */
55781 + p_BmiStats->cntDmaUtil =
55782 + FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_DMA_UTIL);
55783 + /* fmbm_tduc */
55784 + p_BmiStats->cntFifoUtil =
55785 + FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_FIFO_UTIL);
55786 + /* fmbm_tfuc */
55787 + p_BmiStats->cntRxPauseActivation = 0;
55788 + p_BmiStats->cntFrame =
55789 + FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_FRAME);
55790 + /* fmbm_tfrc */
55791 + p_BmiStats->cntDiscardFrame =
55792 + FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_DISCARD_FRAME);
55793 + /* fmbm_tfdc */
55794 + p_BmiStats->cntDeallocBuf =
55795 + FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_DEALLOC_BUF);
55796 + /* fmbm_tbdc */
55797 + p_BmiStats->cntRxBadFrame = 0;
55798 + p_BmiStats->cntRxLargeFrame = 0;
55799 + p_BmiStats->cntRxFilterFrame = 0;
55800 + p_BmiStats->cntRxListDmaErr = 0;
55801 + p_BmiStats->cntRxOutOfBuffersDiscard = 0;
55802 + p_BmiStats->cntWredDiscard = 0;
55803 + p_BmiStats->cntLengthErr =
55804 + FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_LENGTH_ERR);
55805 + /* fmbm_tfledc */
55806 + p_BmiStats->cntUnsupportedFormat =
55807 + FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_UNSUPPRTED_FORMAT);
55808 + /* fmbm_tfufdc */
55809 + }
55810 + else if (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING) {
55811 + p_BmiStats->cntCycle =
55812 + FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_CYCLE);
55813 + /* fmbm_occn */
55814 + p_BmiStats->cntTaskUtil =
55815 + FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_TASK_UTIL);
55816 + /* fmbm_otuc */
55817 + p_BmiStats->cntQueueUtil = 0;
55818 + p_BmiStats->cntDmaUtil =
55819 + FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_DMA_UTIL);
55820 + /* fmbm_oduc */
55821 + p_BmiStats->cntFifoUtil =
55822 + FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_FIFO_UTIL);
55823 + /* fmbm_ofuc*/
55824 + p_BmiStats->cntRxPauseActivation = 0;
55825 + p_BmiStats->cntFrame =
55826 + FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_FRAME);
55827 + /* fmbm_ofrc */
55828 + p_BmiStats->cntDiscardFrame =
55829 + FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_DISCARD_FRAME);
55830 + /* fmbm_ofdc */
55831 + p_BmiStats->cntDeallocBuf =
55832 + FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_DEALLOC_BUF);
55833 + /* fmbm_obdc*/
55834 + p_BmiStats->cntRxBadFrame = 0;
55835 + p_BmiStats->cntRxLargeFrame = 0;
55836 + p_BmiStats->cntRxFilterFrame =
55837 + FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_RX_FILTER_FRAME);
55838 + /* fmbm_offc */
55839 + p_BmiStats->cntRxListDmaErr =
55840 + FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_RX_LIST_DMA_ERR);
55841 + /* fmbm_ofldec */
55842 + p_BmiStats->cntRxOutOfBuffersDiscard =
55843 + FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_RX_OUT_OF_BUFFERS_DISCARD);
55844 + /* fmbm_rodc */
55845 + p_BmiStats->cntWredDiscard =
55846 + FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_WRED_DISCARD);
55847 + /* fmbm_ofwdc */
55848 + p_BmiStats->cntLengthErr =
55849 + FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_LENGTH_ERR);
55850 + /* fmbm_ofledc */
55851 + p_BmiStats->cntUnsupportedFormat =
55852 + FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_UNSUPPRTED_FORMAT);
55853 + /* fmbm_ofufdc */
55854 + }
55855 + return E_OK;
55856 +}
55857 +
55858 +uint32_t FM_PORT_GetCounter(t_Handle h_FmPort, e_FmPortCounters counter)
55859 +{
55860 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
55861 + bool bmiCounter = FALSE;
55862 + enum fman_port_stats_counters statsType;
55863 + enum fman_port_perf_counters perfType;
55864 + enum fman_port_qmi_counters queueType;
55865 + bool isStats;
55866 + t_Error errCode;
55867 +
55868 + SANITY_CHECK_RETURN_VALUE(p_FmPort, E_INVALID_HANDLE, 0);
55869 + SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE);
55870 +
55871 + switch (counter)
55872 + {
55873 + case (e_FM_PORT_COUNTERS_DEQ_TOTAL):
55874 + case (e_FM_PORT_COUNTERS_DEQ_FROM_DEFAULT):
55875 + case (e_FM_PORT_COUNTERS_DEQ_CONFIRM):
55876 + /* check that counter is available for the port type */
55877 + if ((p_FmPort->portType == e_FM_PORT_TYPE_RX)
55878 + || (p_FmPort->portType == e_FM_PORT_TYPE_RX_10G))
55879 + {
55880 + REPORT_ERROR(MINOR, E_INVALID_STATE,
55881 + ("Requested counter is not available for Rx ports"));
55882 + return 0;
55883 + }
55884 + bmiCounter = FALSE;
55885 + break;
55886 + case (e_FM_PORT_COUNTERS_ENQ_TOTAL):
55887 + bmiCounter = FALSE;
55888 + break;
55889 + default: /* BMI counters (or error - will be checked in BMI routine )*/
55890 + bmiCounter = TRUE;
55891 + break;
55892 + }
55893 +
55894 + if (bmiCounter)
55895 + {
55896 + errCode = BmiPortCheckAndGetCounterType(p_FmPort, counter, &statsType,
55897 + &perfType, &isStats);
55898 + if (errCode != E_OK)
55899 + {
55900 + REPORT_ERROR(MINOR, errCode, NO_MSG);
55901 + return 0;
55902 + }
55903 + if (isStats)
55904 + return fman_port_get_stats_counter(&p_FmPort->port, statsType);
55905 + else
55906 + return fman_port_get_perf_counter(&p_FmPort->port, perfType);
55907 + }
55908 + else /* QMI counter */
55909 + {
55910 + /* check that counters are enabled */
55911 + if (!(GET_UINT32(p_FmPort->port.qmi_regs->fmqm_pnc)
55912 + & QMI_PORT_CFG_EN_COUNTERS))
55913 +
55914 + {
55915 + REPORT_ERROR(MINOR, E_INVALID_STATE, ("Requested counter was not enabled"));
55916 + return 0;
55917 + }
55918 +
55919 + /* Set counter */
55920 + switch (counter)
55921 + {
55922 + case (e_FM_PORT_COUNTERS_ENQ_TOTAL):
55923 + queueType = E_FMAN_PORT_ENQ_TOTAL;
55924 + break;
55925 + case (e_FM_PORT_COUNTERS_DEQ_TOTAL):
55926 + queueType = E_FMAN_PORT_DEQ_TOTAL;
55927 + break;
55928 + case (e_FM_PORT_COUNTERS_DEQ_FROM_DEFAULT):
55929 + queueType = E_FMAN_PORT_DEQ_FROM_DFLT;
55930 + break;
55931 + case (e_FM_PORT_COUNTERS_DEQ_CONFIRM):
55932 + queueType = E_FMAN_PORT_DEQ_CONFIRM;
55933 + break;
55934 + default:
55935 + REPORT_ERROR(MINOR, E_INVALID_STATE, ("Requested counter is not available"));
55936 + return 0;
55937 + }
55938 +
55939 + return fman_port_get_qmi_counter(&p_FmPort->port, queueType);
55940 + }
55941 +
55942 + return 0;
55943 +}
55944 +
55945 +t_Error FM_PORT_ModifyCounter(t_Handle h_FmPort, e_FmPortCounters counter,
55946 + uint32_t value)
55947 +{
55948 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
55949 + bool bmiCounter = FALSE;
55950 + enum fman_port_stats_counters statsType;
55951 + enum fman_port_perf_counters perfType;
55952 + enum fman_port_qmi_counters queueType;
55953 + bool isStats;
55954 + t_Error errCode;
55955 +
55956 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
55957 + SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE);
55958 +
55959 + switch (counter)
55960 + {
55961 + case (e_FM_PORT_COUNTERS_DEQ_TOTAL):
55962 + case (e_FM_PORT_COUNTERS_DEQ_FROM_DEFAULT):
55963 + case (e_FM_PORT_COUNTERS_DEQ_CONFIRM):
55964 + /* check that counter is available for the port type */
55965 + if ((p_FmPort->portType == e_FM_PORT_TYPE_RX)
55966 + || (p_FmPort->portType == e_FM_PORT_TYPE_RX_10G))
55967 + RETURN_ERROR(
55968 + MINOR, E_INVALID_STATE,
55969 + ("Requested counter is not available for Rx ports"));
55970 + case (e_FM_PORT_COUNTERS_ENQ_TOTAL):
55971 + bmiCounter = FALSE;
55972 + break;
55973 + default: /* BMI counters (or error - will be checked in BMI routine )*/
55974 + bmiCounter = TRUE;
55975 + break;
55976 + }
55977 +
55978 + if (bmiCounter)
55979 + {
55980 + errCode = BmiPortCheckAndGetCounterType(p_FmPort, counter, &statsType,
55981 + &perfType, &isStats);
55982 + if (errCode != E_OK)
55983 + {
55984 + RETURN_ERROR(MINOR, errCode, NO_MSG);
55985 + }
55986 + if (isStats)
55987 + fman_port_set_stats_counter(&p_FmPort->port, statsType, value);
55988 + else
55989 + fman_port_set_perf_counter(&p_FmPort->port, perfType, value);
55990 + }
55991 + else /* QMI counter */
55992 + {
55993 + /* check that counters are enabled */
55994 + if (!(GET_UINT32(p_FmPort->port.qmi_regs->fmqm_pnc)
55995 + & QMI_PORT_CFG_EN_COUNTERS))
55996 + {
55997 + RETURN_ERROR(MINOR, E_INVALID_STATE,
55998 + ("Requested counter was not enabled"));
55999 + }
56000 +
56001 + /* Set counter */
56002 + switch (counter)
56003 + {
56004 + case (e_FM_PORT_COUNTERS_ENQ_TOTAL):
56005 + queueType = E_FMAN_PORT_ENQ_TOTAL;
56006 + break;
56007 + case (e_FM_PORT_COUNTERS_DEQ_TOTAL):
56008 + queueType = E_FMAN_PORT_DEQ_TOTAL;
56009 + break;
56010 + case (e_FM_PORT_COUNTERS_DEQ_FROM_DEFAULT):
56011 + queueType = E_FMAN_PORT_DEQ_FROM_DFLT;
56012 + break;
56013 + case (e_FM_PORT_COUNTERS_DEQ_CONFIRM):
56014 + queueType = E_FMAN_PORT_DEQ_CONFIRM;
56015 + break;
56016 + default:
56017 + RETURN_ERROR(MAJOR, E_INVALID_STATE,
56018 + ("Requested counter is not available"));
56019 + }
56020 +
56021 + fman_port_set_qmi_counter(&p_FmPort->port, queueType, value);
56022 + }
56023 +
56024 + return E_OK;
56025 +}
56026 +
56027 +uint32_t FM_PORT_GetAllocBufCounter(t_Handle h_FmPort, uint8_t poolId)
56028 +{
56029 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
56030 +
56031 + SANITY_CHECK_RETURN_VALUE(p_FmPort, E_INVALID_HANDLE, 0);
56032 + SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE);
56033 +
56034 + if ((p_FmPort->portType != e_FM_PORT_TYPE_RX)
56035 + && (p_FmPort->portType == e_FM_PORT_TYPE_RX_10G))
56036 + {
56037 + REPORT_ERROR(MINOR, E_INVALID_STATE, ("Requested counter is not available for non-Rx ports"));
56038 + return 0;
56039 + }
56040 + return fman_port_get_bpool_counter(&p_FmPort->port, poolId);
56041 +}
56042 +
56043 +t_Error FM_PORT_ModifyAllocBufCounter(t_Handle h_FmPort, uint8_t poolId,
56044 + uint32_t value)
56045 +{
56046 + t_FmPort *p_FmPort = (t_FmPort *)h_FmPort;
56047 +
56048 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
56049 + SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE);
56050 +
56051 + if ((p_FmPort->portType != e_FM_PORT_TYPE_RX)
56052 + && (p_FmPort->portType == e_FM_PORT_TYPE_RX_10G))
56053 + RETURN_ERROR( MINOR, E_INVALID_STATE,
56054 + ("Requested counter is not available for non-Rx ports"));
56055 +
56056 + fman_port_set_bpool_counter(&p_FmPort->port, poolId, value);
56057 + return E_OK;
56058 +}
56059 +bool FM_PORT_IsStalled(t_Handle h_FmPort)
56060 +{
56061 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
56062 + t_Error err;
56063 + bool isStalled;
56064 +
56065 + SANITY_CHECK_RETURN_VALUE(p_FmPort, E_INVALID_HANDLE, FALSE);
56066 + SANITY_CHECK_RETURN_VALUE(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE,
56067 + FALSE);
56068 +
56069 + err = FmIsPortStalled(p_FmPort->h_Fm, p_FmPort->hardwarePortId, &isStalled);
56070 + if (err != E_OK)
56071 + {
56072 + REPORT_ERROR(MAJOR, err, NO_MSG);
56073 + return TRUE;
56074 + }
56075 + return isStalled;
56076 +}
56077 +
56078 +t_Error FM_PORT_ReleaseStalled(t_Handle h_FmPort)
56079 +{
56080 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
56081 +
56082 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
56083 + SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE);
56084 +
56085 + return FmResumeStalledPort(p_FmPort->h_Fm, p_FmPort->hardwarePortId);
56086 +}
56087 +
56088 +t_Error FM_PORT_SetRxL4ChecksumVerify(t_Handle h_FmPort, bool l4Checksum)
56089 +{
56090 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
56091 + int err;
56092 +
56093 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
56094 + SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE);
56095 +
56096 + if ((p_FmPort->portType != e_FM_PORT_TYPE_RX_10G)
56097 + && (p_FmPort->portType != e_FM_PORT_TYPE_RX))
56098 + RETURN_ERROR(MAJOR, E_INVALID_OPERATION,
56099 + ("available for Rx ports only"));
56100 +
56101 + if (l4Checksum)
56102 + err = fman_port_modify_rx_fd_bits(
56103 + &p_FmPort->port, (uint8_t)(BMI_PORT_RFNE_FRWD_DCL4C >> 24),
56104 + TRUE);
56105 + else
56106 + err = fman_port_modify_rx_fd_bits(
56107 + &p_FmPort->port, (uint8_t)(BMI_PORT_RFNE_FRWD_DCL4C >> 24),
56108 + FALSE);
56109 + if (err != 0)
56110 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("fman_port_modify_rx_fd_bits"));
56111 +
56112 + return E_OK;
56113 +}
56114 +
56115 +/*****************************************************************************/
56116 +/* API Run-time PCD Control unit functions */
56117 +/*****************************************************************************/
56118 +
56119 +#if (DPAA_VERSION >= 11)
56120 +t_Error FM_PORT_VSPAlloc(t_Handle h_FmPort, t_FmPortVSPAllocParams *p_VSPParams)
56121 +{
56122 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
56123 + t_Error err = E_OK;
56124 + volatile uint32_t *p_BmiStorageProfileId = NULL, *p_BmiVspe = NULL;
56125 + uint32_t tmpReg = 0, tmp = 0;
56126 + uint16_t hwStoragePrflId;
56127 +
56128 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
56129 + SANITY_CHECK_RETURN_ERROR(p_FmPort->h_Fm, E_INVALID_HANDLE);
56130 + /*for numOfProfiles = 0 don't call this function*/
56131 + SANITY_CHECK_RETURN_ERROR(p_VSPParams->numOfProfiles, E_INVALID_VALUE);
56132 + /*dfltRelativeId should be in the range of numOfProfiles*/
56133 + SANITY_CHECK_RETURN_ERROR(
56134 + p_VSPParams->dfltRelativeId < p_VSPParams->numOfProfiles,
56135 + E_INVALID_VALUE);
56136 + /*p_FmPort should be from Rx type or OP*/
56137 + SANITY_CHECK_RETURN_ERROR(
56138 + ((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)),
56139 + E_INVALID_VALUE);
56140 + /*port should be disabled*/
56141 + SANITY_CHECK_RETURN_ERROR(!p_FmPort->enabled, E_INVALID_STATE);
56142 + /*if its called for Rx port relevant Tx Port should be passed (initialized) too and it should be disabled*/
56143 + SANITY_CHECK_RETURN_ERROR(
56144 + ((p_VSPParams->h_FmTxPort && !((t_FmPort *)(p_VSPParams->h_FmTxPort))->enabled) || (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING)),
56145 + E_INVALID_VALUE);
56146 + /*should be called before SetPCD - this port should be without PCD*/
56147 + SANITY_CHECK_RETURN_ERROR(!p_FmPort->pcdEngines, E_INVALID_STATE);
56148 +
56149 + /*alloc window of VSPs for this port*/
56150 + err = FmVSPAllocForPort(p_FmPort->h_Fm, p_FmPort->portType,
56151 + p_FmPort->portId, p_VSPParams->numOfProfiles);
56152 + if (err != E_OK)
56153 + RETURN_ERROR(MAJOR, err, NO_MSG);
56154 +
56155 + /*get absolute VSP ID for dfltRelative*/
56156 + err = FmVSPGetAbsoluteProfileId(p_FmPort->h_Fm, p_FmPort->portType,
56157 + p_FmPort->portId,
56158 + p_VSPParams->dfltRelativeId,
56159 + &hwStoragePrflId);
56160 + if (err != E_OK)
56161 + RETURN_ERROR(MAJOR, err, NO_MSG);
56162 +
56163 + /*fill relevant registers for p_FmPort and relative TxPort in the case p_FmPort from Rx type*/
56164 + switch (p_FmPort->portType)
56165 + {
56166 + case (e_FM_PORT_TYPE_RX_10G):
56167 + case (e_FM_PORT_TYPE_RX):
56168 + p_BmiStorageProfileId =
56169 + &(((t_FmPort *)(p_VSPParams->h_FmTxPort))->p_FmPortBmiRegs->txPortBmiRegs.fmbm_tcfqid);
56170 + p_BmiVspe =
56171 + &(((t_FmPort *)(p_VSPParams->h_FmTxPort))->p_FmPortBmiRegs->txPortBmiRegs.fmbm_tfne);
56172 +
56173 + tmpReg = GET_UINT32(*p_BmiStorageProfileId) & ~BMI_SP_ID_MASK;
56174 + tmpReg |= (uint32_t)hwStoragePrflId << BMI_SP_ID_SHIFT;
56175 + WRITE_UINT32(*p_BmiStorageProfileId, tmpReg);
56176 +
56177 + tmpReg = GET_UINT32(*p_BmiVspe);
56178 + WRITE_UINT32(*p_BmiVspe, tmpReg | BMI_SP_EN);
56179 +
56180 + p_BmiStorageProfileId =
56181 + &p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rfqid;
56182 + p_BmiVspe = &p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rpp;
56183 + hwStoragePrflId = p_VSPParams->dfltRelativeId;
56184 + break;
56185 +
56186 + case (e_FM_PORT_TYPE_OH_OFFLINE_PARSING):
56187 + tmpReg = NIA_ENG_BMI | NIA_BMI_AC_FETCH_ALL_FRAME;
56188 + WRITE_UINT32( p_FmPort->p_FmPortQmiRegs->nonRxQmiRegs.fmqm_pndn,
56189 + tmpReg);
56190 +
56191 + p_BmiStorageProfileId =
56192 + &p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs.fmbm_ofqid;
56193 + p_BmiVspe = &p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs.fmbm_opp;
56194 + tmp |= BMI_EBD_EN;
56195 + break;
56196 +
56197 + default:
56198 + RETURN_ERROR( MAJOR, E_INVALID_OPERATION,
56199 + ("available for Rx and offline parsing ports only"));
56200 + }
56201 +
56202 + p_FmPort->vspe = TRUE;
56203 + p_FmPort->dfltRelativeId = p_VSPParams->dfltRelativeId;
56204 +
56205 + tmpReg = GET_UINT32(*p_BmiStorageProfileId) & ~BMI_SP_ID_MASK;
56206 + tmpReg |= (uint32_t)hwStoragePrflId << BMI_SP_ID_SHIFT;
56207 + WRITE_UINT32(*p_BmiStorageProfileId, tmpReg);
56208 +
56209 + tmpReg = GET_UINT32(*p_BmiVspe);
56210 + WRITE_UINT32(*p_BmiVspe, tmpReg | BMI_SP_EN | tmp);
56211 + return E_OK;
56212 +}
56213 +#endif /* (DPAA_VERSION >= 11) */
56214 +
56215 +t_Error FM_PORT_PcdPlcrAllocProfiles(t_Handle h_FmPort, uint16_t numOfProfiles)
56216 +{
56217 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
56218 + t_Error err = E_OK;
56219 +
56220 + p_FmPort->h_FmPcd = FmGetPcdHandle(p_FmPort->h_Fm);
56221 + ASSERT_COND(p_FmPort->h_FmPcd);
56222 +
56223 + if (!TRY_LOCK(p_FmPort->h_Spinlock, &p_FmPort->lock))
56224 + {
56225 + DBG(TRACE, ("FM Port Try Lock - BUSY"));
56226 + return ERROR_CODE(E_BUSY);
56227 + }
56228 +
56229 + if (numOfProfiles)
56230 + {
56231 + err = FmPcdPlcrAllocProfiles(p_FmPort->h_FmPcd,
56232 + p_FmPort->hardwarePortId, numOfProfiles);
56233 + if (err)
56234 + RETURN_ERROR(MAJOR, err, NO_MSG);
56235 + }
56236 + /* set the port handle within the PCD policer, even if no profiles defined */
56237 + FmPcdPortRegister(p_FmPort->h_FmPcd, h_FmPort, p_FmPort->hardwarePortId);
56238 +
56239 + RELEASE_LOCK(p_FmPort->lock);
56240 +
56241 + return E_OK;
56242 +}
56243 +
56244 +t_Error FM_PORT_PcdPlcrFreeProfiles(t_Handle h_FmPort)
56245 +{
56246 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
56247 + t_Error err = E_OK;
56248 +
56249 + if (!TRY_LOCK(p_FmPort->h_Spinlock, &p_FmPort->lock))
56250 + {
56251 + DBG(TRACE, ("FM Port Try Lock - BUSY"));
56252 + return ERROR_CODE(E_BUSY);
56253 + }
56254 +
56255 + err = FmPcdPlcrFreeProfiles(p_FmPort->h_FmPcd, p_FmPort->hardwarePortId);
56256 +
56257 + RELEASE_LOCK(p_FmPort->lock);
56258 +
56259 + if (err)
56260 + RETURN_ERROR(MAJOR, err, NO_MSG);
56261 +
56262 + return E_OK;
56263 +}
56264 +
56265 +t_Error FM_PORT_PcdKgModifyInitialScheme(t_Handle h_FmPort,
56266 + t_FmPcdKgSchemeSelect *p_FmPcdKgScheme)
56267 +{
56268 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
56269 + volatile uint32_t *p_BmiHpnia = NULL;
56270 + uint32_t tmpReg;
56271 + uint8_t relativeSchemeId;
56272 + uint8_t physicalSchemeId;
56273 +
56274 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
56275 + SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE);
56276 + SANITY_CHECK_RETURN_ERROR(p_FmPort->pcdEngines & FM_PCD_KG,
56277 + E_INVALID_STATE);
56278 +
56279 + tmpReg = (uint32_t)((p_FmPort->pcdEngines & FM_PCD_CC) ? NIA_KG_CC_EN : 0);
56280 + switch (p_FmPort->portType)
56281 + {
56282 + case (e_FM_PORT_TYPE_RX_10G):
56283 + case (e_FM_PORT_TYPE_RX):
56284 + p_BmiHpnia = &p_FmPort->port.bmi_regs->rx.fmbm_rfpne;
56285 + break;
56286 + case (e_FM_PORT_TYPE_OH_OFFLINE_PARSING):
56287 + p_BmiHpnia = &p_FmPort->port.bmi_regs->oh.fmbm_ofpne;
56288 + break;
56289 + default:
56290 + RETURN_ERROR( MAJOR, E_INVALID_OPERATION,
56291 + ("available for Rx and offline parsing ports only"));
56292 + }
56293 +
56294 + if (!TRY_LOCK(p_FmPort->h_Spinlock, &p_FmPort->lock))
56295 + {
56296 + DBG(TRACE, ("FM Port Try Lock - BUSY"));
56297 + return ERROR_CODE(E_BUSY);
56298 + }
56299 +
56300 + /* if we want to change to direct scheme, we need to check that this scheme is valid */
56301 + if (p_FmPcdKgScheme->direct)
56302 + {
56303 + physicalSchemeId = FmPcdKgGetSchemeId(p_FmPcdKgScheme->h_DirectScheme);
56304 + /* check that this scheme is bound to this port */
56305 + if (!(p_FmPort->schemesPerPortVector
56306 + & (uint32_t)(1 << (31 - (uint32_t)physicalSchemeId))))
56307 + {
56308 + RELEASE_LOCK(p_FmPort->lock);
56309 + RETURN_ERROR(
56310 + MAJOR, E_INVALID_STATE,
56311 + ("called with a scheme that is not bound to this port"));
56312 + }
56313 +
56314 + relativeSchemeId = FmPcdKgGetRelativeSchemeId(p_FmPort->h_FmPcd,
56315 + physicalSchemeId);
56316 + if (relativeSchemeId >= FM_PCD_KG_NUM_OF_SCHEMES)
56317 + {
56318 + RELEASE_LOCK(p_FmPort->lock);
56319 + RETURN_ERROR(MAJOR, E_NOT_IN_RANGE,
56320 + ("called with invalid Scheme "));
56321 + }
56322 +
56323 + if (!FmPcdKgIsSchemeValidSw(p_FmPcdKgScheme->h_DirectScheme))
56324 + {
56325 + RELEASE_LOCK(p_FmPort->lock);
56326 + RETURN_ERROR(MAJOR, E_INVALID_STATE,
56327 + ("called with uninitialized Scheme "));
56328 + }
56329 +
56330 + WRITE_UINT32(
56331 + *p_BmiHpnia,
56332 + NIA_ENG_KG | tmpReg | NIA_KG_DIRECT | (uint32_t)physicalSchemeId);
56333 + }
56334 + else
56335 + /* change to indirect scheme */
56336 + WRITE_UINT32(*p_BmiHpnia, NIA_ENG_KG | tmpReg);
56337 + RELEASE_LOCK(p_FmPort->lock);
56338 +
56339 + return E_OK;
56340 +}
56341 +
56342 +t_Error FM_PORT_PcdPlcrModifyInitialProfile(t_Handle h_FmPort,
56343 + t_Handle h_Profile)
56344 +{
56345 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
56346 + volatile uint32_t *p_BmiNia;
56347 + volatile uint32_t *p_BmiHpnia;
56348 + uint32_t tmpReg;
56349 + uint16_t absoluteProfileId = FmPcdPlcrProfileGetAbsoluteId(h_Profile);
56350 +
56351 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
56352 + SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE);
56353 + SANITY_CHECK_RETURN_ERROR(p_FmPort->pcdEngines & FM_PCD_PLCR,
56354 + E_INVALID_STATE);
56355 +
56356 + /* check relevance of this routine - only when policer is used
56357 + directly after BMI or Parser */
56358 + if ((p_FmPort->pcdEngines & FM_PCD_KG)
56359 + || (p_FmPort->pcdEngines & FM_PCD_CC))
56360 + RETURN_ERROR(
56361 + MAJOR,
56362 + E_INVALID_STATE,
56363 + ("relevant only when PCD support mode is e_FM_PCD_SUPPORT_PLCR_ONLY or e_FM_PCD_SUPPORT_PRS_AND_PLCR"));
56364 +
56365 + switch (p_FmPort->portType)
56366 + {
56367 + case (e_FM_PORT_TYPE_RX_10G):
56368 + case (e_FM_PORT_TYPE_RX):
56369 + p_BmiNia = &p_FmPort->port.bmi_regs->rx.fmbm_rfne;
56370 + p_BmiHpnia = &p_FmPort->port.bmi_regs->rx.fmbm_rfpne;
56371 + tmpReg = GET_UINT32(*p_BmiNia) & BMI_RFNE_FDCS_MASK;
56372 + break;
56373 + case (e_FM_PORT_TYPE_OH_OFFLINE_PARSING):
56374 + p_BmiNia = &p_FmPort->port.bmi_regs->oh.fmbm_ofne;
56375 + p_BmiHpnia = &p_FmPort->port.bmi_regs->oh.fmbm_ofpne;
56376 + tmpReg = 0;
56377 + break;
56378 + default:
56379 + RETURN_ERROR( MAJOR, E_INVALID_OPERATION,
56380 + ("available for Rx and offline parsing ports only"));
56381 + }
56382 +
56383 + if (!TRY_LOCK(p_FmPort->h_Spinlock, &p_FmPort->lock))
56384 + {
56385 + DBG(TRACE, ("FM Port Try Lock - BUSY"));
56386 + return ERROR_CODE(E_BUSY);
56387 + }
56388 +
56389 + if (!FmPcdPlcrIsProfileValid(p_FmPort->h_FmPcd, absoluteProfileId))
56390 + {
56391 + RELEASE_LOCK(p_FmPort->lock);
56392 + RETURN_ERROR(MAJOR, E_INVALID_OPERATION, ("Invalid profile"));
56393 + }
56394 +
56395 + tmpReg |= (uint32_t)(NIA_ENG_PLCR | NIA_PLCR_ABSOLUTE | absoluteProfileId);
56396 +
56397 + if (p_FmPort->pcdEngines & FM_PCD_PRS) /* e_FM_PCD_SUPPORT_PRS_AND_PLCR */
56398 + {
56399 + /* update BMI HPNIA */
56400 + WRITE_UINT32(*p_BmiHpnia, tmpReg);
56401 + }
56402 + else /* e_FM_PCD_SUPPORT_PLCR_ONLY */
56403 + {
56404 + /* rfne may contain FDCS bits, so first we read them. */
56405 + tmpReg |= (GET_UINT32(*p_BmiNia) & BMI_RFNE_FDCS_MASK);
56406 + /* update BMI NIA */
56407 + WRITE_UINT32(*p_BmiNia, tmpReg);
56408 + }RELEASE_LOCK(p_FmPort->lock);
56409 +
56410 + return E_OK;
56411 +}
56412 +
56413 +t_Error FM_PORT_PcdCcModifyTree(t_Handle h_FmPort, t_Handle h_CcTree)
56414 +{
56415 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
56416 + t_Error err = E_OK;
56417 + volatile uint32_t *p_BmiCcBase = NULL;
56418 + volatile uint32_t *p_BmiNia = NULL;
56419 + uint32_t ccTreePhysOffset;
56420 +
56421 + SANITY_CHECK_RETURN_ERROR(h_FmPort, E_INVALID_HANDLE);
56422 + SANITY_CHECK_RETURN_ERROR(h_CcTree, E_INVALID_HANDLE);
56423 +
56424 + if (p_FmPort->imEn)
56425 + RETURN_ERROR(MAJOR, E_INVALID_OPERATION,
56426 + ("available for non-independent mode ports only"));
56427 +
56428 + /* get PCD registers pointers */
56429 + switch (p_FmPort->portType)
56430 + {
56431 + case (e_FM_PORT_TYPE_RX_10G):
56432 + case (e_FM_PORT_TYPE_RX):
56433 + p_BmiNia = &p_FmPort->port.bmi_regs->rx.fmbm_rfne;
56434 + break;
56435 + case (e_FM_PORT_TYPE_OH_OFFLINE_PARSING):
56436 + p_BmiNia = &p_FmPort->port.bmi_regs->oh.fmbm_ofne;
56437 + break;
56438 + default:
56439 + RETURN_ERROR( MAJOR, E_INVALID_OPERATION,
56440 + ("available for Rx and offline parsing ports only"));
56441 + }
56442 +
56443 + /* check that current NIA is BMI to BMI */
56444 + if ((GET_UINT32(*p_BmiNia) & ~BMI_RFNE_FDCS_MASK)
56445 + != GET_NIA_BMI_AC_ENQ_FRAME(p_FmPort->h_FmPcd))
56446 + RETURN_ERROR( MAJOR, E_INVALID_OPERATION,
56447 + ("may be called only for ports in BMI-to-BMI state."));
56448 +
56449 + if (p_FmPort->pcdEngines & FM_PCD_CC)
56450 + {
56451 + if (p_FmPort->h_IpReassemblyManip)
56452 + {
56453 + err = FmPcdCcTreeAddIPR(p_FmPort->h_FmPcd, h_CcTree, NULL,
56454 + p_FmPort->h_IpReassemblyManip, FALSE);
56455 + if (err != E_OK)
56456 + {
56457 + RETURN_ERROR(MAJOR, err, NO_MSG);
56458 + }
56459 + }
56460 + else
56461 + if (p_FmPort->h_CapwapReassemblyManip)
56462 + {
56463 + err = FmPcdCcTreeAddCPR(p_FmPort->h_FmPcd, h_CcTree, NULL,
56464 + p_FmPort->h_CapwapReassemblyManip,
56465 + FALSE);
56466 + if (err != E_OK)
56467 + {
56468 + RETURN_ERROR(MAJOR, err, NO_MSG);
56469 + }
56470 + }
56471 + switch (p_FmPort->portType)
56472 + {
56473 + case (e_FM_PORT_TYPE_RX_10G):
56474 + case (e_FM_PORT_TYPE_RX):
56475 + p_BmiCcBase = &p_FmPort->port.bmi_regs->rx.fmbm_rccb;
56476 + break;
56477 + case (e_FM_PORT_TYPE_OH_OFFLINE_PARSING):
56478 + p_BmiCcBase = &p_FmPort->port.bmi_regs->oh.fmbm_occb;
56479 + break;
56480 + default:
56481 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Invalid port type"));
56482 + }
56483 +
56484 + if (!TRY_LOCK(p_FmPort->h_Spinlock, &p_FmPort->lock))
56485 + {
56486 + DBG(TRACE, ("FM Port Try Lock - BUSY"));
56487 + return ERROR_CODE(E_BUSY);
56488 + }
56489 + err = FmPcdCcBindTree(p_FmPort->h_FmPcd, NULL, h_CcTree,
56490 + &ccTreePhysOffset, h_FmPort);
56491 + if (err)
56492 + {
56493 + RELEASE_LOCK(p_FmPort->lock);
56494 + RETURN_ERROR(MAJOR, err, NO_MSG);
56495 + }WRITE_UINT32(*p_BmiCcBase, ccTreePhysOffset);
56496 +
56497 + p_FmPort->ccTreeId = h_CcTree;
56498 + RELEASE_LOCK(p_FmPort->lock);
56499 + }
56500 + else
56501 + RETURN_ERROR( MAJOR, E_INVALID_STATE,
56502 + ("Coarse Classification not defined for this port."));
56503 +
56504 + return E_OK;
56505 +}
56506 +
56507 +t_Error FM_PORT_AttachPCD(t_Handle h_FmPort)
56508 +{
56509 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
56510 + t_Error err = E_OK;
56511 +
56512 + SANITY_CHECK_RETURN_ERROR(h_FmPort, E_INVALID_HANDLE);
56513 + SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE);
56514 +
56515 + if (p_FmPort->imEn)
56516 + RETURN_ERROR(MAJOR, E_INVALID_OPERATION,
56517 + ("available for non-independent mode ports only"));
56518 +
56519 + if ((p_FmPort->portType != e_FM_PORT_TYPE_RX_10G)
56520 + && (p_FmPort->portType != e_FM_PORT_TYPE_RX)
56521 + && (p_FmPort->portType != e_FM_PORT_TYPE_OH_OFFLINE_PARSING))
56522 + RETURN_ERROR( MAJOR, E_INVALID_OPERATION,
56523 + ("available for Rx and offline parsing ports only"));
56524 +
56525 + if (!TRY_LOCK(p_FmPort->h_Spinlock, &p_FmPort->lock))
56526 + {
56527 + DBG(TRACE, ("FM Port Try Lock - BUSY"));
56528 + return ERROR_CODE(E_BUSY);
56529 + }
56530 +
56531 + if (p_FmPort->h_ReassemblyTree)
56532 + p_FmPort->pcdEngines |= FM_PCD_CC;
56533 +
56534 + err = AttachPCD(h_FmPort);
56535 + RELEASE_LOCK(p_FmPort->lock);
56536 +
56537 + return err;
56538 +}
56539 +
56540 +t_Error FM_PORT_DetachPCD(t_Handle h_FmPort)
56541 +{
56542 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
56543 + t_Error err = E_OK;
56544 +
56545 + SANITY_CHECK_RETURN_ERROR(h_FmPort, E_INVALID_HANDLE);
56546 + SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE);
56547 +
56548 + if (p_FmPort->imEn)
56549 + RETURN_ERROR(MAJOR, E_INVALID_OPERATION,
56550 + ("available for non-independent mode ports only"));
56551 +
56552 + if ((p_FmPort->portType != e_FM_PORT_TYPE_RX_10G)
56553 + && (p_FmPort->portType != e_FM_PORT_TYPE_RX)
56554 + && (p_FmPort->portType != e_FM_PORT_TYPE_OH_OFFLINE_PARSING))
56555 + RETURN_ERROR( MAJOR, E_INVALID_OPERATION,
56556 + ("available for Rx and offline parsing ports only"));
56557 +
56558 + if (!TRY_LOCK(p_FmPort->h_Spinlock, &p_FmPort->lock))
56559 + {
56560 + DBG(TRACE, ("FM Port Try Lock - BUSY"));
56561 + return ERROR_CODE(E_BUSY);
56562 + }
56563 +
56564 + err = DetachPCD(h_FmPort);
56565 + if (err != E_OK)
56566 + {
56567 + RELEASE_LOCK(p_FmPort->lock);
56568 + RETURN_ERROR(MAJOR, err, NO_MSG);
56569 + }
56570 +
56571 + if (p_FmPort->h_ReassemblyTree)
56572 + p_FmPort->pcdEngines &= ~FM_PCD_CC;
56573 + RELEASE_LOCK(p_FmPort->lock);
56574 +
56575 + return E_OK;
56576 +}
56577 +
56578 +t_Error FM_PORT_SetPCD(t_Handle h_FmPort, t_FmPortPcdParams *p_PcdParam)
56579 +{
56580 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
56581 + t_Error err = E_OK;
56582 + t_FmPortPcdParams modifiedPcdParams, *p_PcdParams;
56583 + t_FmPcdCcTreeParams *p_FmPcdCcTreeParams;
56584 + t_FmPortPcdCcParams fmPortPcdCcParams;
56585 + t_FmPortGetSetCcParams fmPortGetSetCcParams;
56586 +
56587 + SANITY_CHECK_RETURN_ERROR(h_FmPort, E_INVALID_HANDLE);
56588 + SANITY_CHECK_RETURN_ERROR(p_PcdParam, E_NULL_POINTER);
56589 + SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE);
56590 +
56591 + if (p_FmPort->imEn)
56592 + RETURN_ERROR(MAJOR, E_INVALID_OPERATION,
56593 + ("available for non-independent mode ports only"));
56594 +
56595 + if ((p_FmPort->portType != e_FM_PORT_TYPE_RX_10G)
56596 + && (p_FmPort->portType != e_FM_PORT_TYPE_RX)
56597 + && (p_FmPort->portType != e_FM_PORT_TYPE_OH_OFFLINE_PARSING))
56598 + RETURN_ERROR( MAJOR, E_INVALID_OPERATION,
56599 + ("available for Rx and offline parsing ports only"));
56600 +
56601 + if (!TRY_LOCK(p_FmPort->h_Spinlock, &p_FmPort->lock))
56602 + {
56603 + DBG(TRACE, ("FM Port Try Lock - BUSY"));
56604 + return ERROR_CODE(E_BUSY);
56605 + }
56606 +
56607 + p_FmPort->h_FmPcd = FmGetPcdHandle(p_FmPort->h_Fm);
56608 + ASSERT_COND(p_FmPort->h_FmPcd);
56609 +
56610 + if (p_PcdParam->p_CcParams && !p_PcdParam->p_CcParams->h_CcTree)
56611 + RETURN_ERROR(MAJOR, E_INVALID_HANDLE,
56612 + ("Tree handle must be given if CC is required"));
56613 +
56614 + memcpy(&modifiedPcdParams, p_PcdParam, sizeof(t_FmPortPcdParams));
56615 + p_PcdParams = &modifiedPcdParams;
56616 + if ((p_PcdParams->h_IpReassemblyManip)
56617 +#if (DPAA_VERSION >= 11)
56618 + || (p_PcdParams->h_CapwapReassemblyManip)
56619 +#endif /* (DPAA_VERSION >= 11) */
56620 + )
56621 + {
56622 + if ((p_PcdParams->pcdSupport != e_FM_PORT_PCD_SUPPORT_PRS_AND_KG)
56623 + && (p_PcdParams->pcdSupport
56624 + != e_FM_PORT_PCD_SUPPORT_PRS_AND_KG_AND_CC)
56625 + && (p_PcdParams->pcdSupport
56626 + != e_FM_PORT_PCD_SUPPORT_PRS_AND_KG_AND_CC_AND_PLCR)
56627 + && (p_PcdParams->pcdSupport
56628 + != e_FM_PORT_PCD_SUPPORT_PRS_AND_KG_AND_PLCR))
56629 + {
56630 + RELEASE_LOCK(p_FmPort->lock);
56631 + RETURN_ERROR( MAJOR, E_INVALID_STATE,
56632 + ("pcdSupport must have KG for supporting Reassembly"));
56633 + }
56634 + p_FmPort->h_IpReassemblyManip = p_PcdParams->h_IpReassemblyManip;
56635 +#if (DPAA_VERSION >= 11)
56636 + if ((p_PcdParams->h_IpReassemblyManip)
56637 + && (p_PcdParams->h_CapwapReassemblyManip))
56638 + RETURN_ERROR(MAJOR, E_INVALID_STATE,
56639 + ("Either IP-R or CAPWAP-R is allowed"));
56640 + if ((p_PcdParams->h_CapwapReassemblyManip)
56641 + && (p_FmPort->portType != e_FM_PORT_TYPE_OH_OFFLINE_PARSING))
56642 + RETURN_ERROR(MAJOR, E_INVALID_STATE,
56643 + ("CAPWAP-R is allowed only on offline-port"));
56644 + if (p_PcdParams->h_CapwapReassemblyManip)
56645 + p_FmPort->h_CapwapReassemblyManip =
56646 + p_PcdParams->h_CapwapReassemblyManip;
56647 +#endif /* (DPAA_VERSION >= 11) */
56648 +
56649 + if (!p_PcdParams->p_CcParams)
56650 + {
56651 + if (!((p_PcdParams->pcdSupport == e_FM_PORT_PCD_SUPPORT_PRS_AND_KG)
56652 + || (p_PcdParams->pcdSupport
56653 + == e_FM_PORT_PCD_SUPPORT_PRS_AND_KG_AND_PLCR)))
56654 + {
56655 + RELEASE_LOCK(p_FmPort->lock);
56656 + RETURN_ERROR(
56657 + MAJOR,
56658 + E_INVALID_STATE,
56659 + ("PCD initialization structure is not consistent with pcdSupport"));
56660 + }
56661 +
56662 + /* No user-tree, need to build internal tree */
56663 + p_FmPcdCcTreeParams = (t_FmPcdCcTreeParams*)XX_Malloc(
56664 + sizeof(t_FmPcdCcTreeParams));
56665 + if (!p_FmPcdCcTreeParams)
56666 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("p_FmPcdCcTreeParams"));
56667 + memset(p_FmPcdCcTreeParams, 0, sizeof(t_FmPcdCcTreeParams));
56668 + p_FmPcdCcTreeParams->h_NetEnv = p_PcdParams->h_NetEnv;
56669 + p_FmPort->h_ReassemblyTree = FM_PCD_CcRootBuild(
56670 + p_FmPort->h_FmPcd, p_FmPcdCcTreeParams);
56671 +
56672 + if (!p_FmPort->h_ReassemblyTree)
56673 + {
56674 + RELEASE_LOCK(p_FmPort->lock);
56675 + XX_Free(p_FmPcdCcTreeParams);
56676 + RETURN_ERROR( MAJOR, E_INVALID_HANDLE,
56677 + ("FM_PCD_CcBuildTree for Reassembly failed"));
56678 + }
56679 + if (p_PcdParams->pcdSupport == e_FM_PORT_PCD_SUPPORT_PRS_AND_KG)
56680 + p_PcdParams->pcdSupport =
56681 + e_FM_PORT_PCD_SUPPORT_PRS_AND_KG_AND_CC;
56682 + else
56683 + p_PcdParams->pcdSupport =
56684 + e_FM_PORT_PCD_SUPPORT_PRS_AND_KG_AND_CC_AND_PLCR;
56685 +
56686 + memset(&fmPortPcdCcParams, 0, sizeof(t_FmPortPcdCcParams));
56687 + fmPortPcdCcParams.h_CcTree = p_FmPort->h_ReassemblyTree;
56688 + p_PcdParams->p_CcParams = &fmPortPcdCcParams;
56689 + XX_Free(p_FmPcdCcTreeParams);
56690 + }
56691 +
56692 + if (p_FmPort->h_IpReassemblyManip)
56693 + err = FmPcdCcTreeAddIPR(p_FmPort->h_FmPcd,
56694 + p_PcdParams->p_CcParams->h_CcTree,
56695 + p_PcdParams->h_NetEnv,
56696 + p_FmPort->h_IpReassemblyManip, TRUE);
56697 +#if (DPAA_VERSION >= 11)
56698 + else
56699 + if (p_FmPort->h_CapwapReassemblyManip)
56700 + err = FmPcdCcTreeAddCPR(p_FmPort->h_FmPcd,
56701 + p_PcdParams->p_CcParams->h_CcTree,
56702 + p_PcdParams->h_NetEnv,
56703 + p_FmPort->h_CapwapReassemblyManip,
56704 + TRUE);
56705 +#endif /* (DPAA_VERSION >= 11) */
56706 +
56707 + if (err != E_OK)
56708 + {
56709 + if (p_FmPort->h_ReassemblyTree)
56710 + {
56711 + FM_PCD_CcRootDelete(p_FmPort->h_ReassemblyTree);
56712 + p_FmPort->h_ReassemblyTree = NULL;
56713 + }RELEASE_LOCK(p_FmPort->lock);
56714 + RETURN_ERROR(MAJOR, err, NO_MSG);
56715 + }
56716 + }
56717 +
56718 + if (!FmPcdLockTryLockAll(p_FmPort->h_FmPcd))
56719 + {
56720 + if (p_FmPort->h_ReassemblyTree)
56721 + {
56722 + FM_PCD_CcRootDelete(p_FmPort->h_ReassemblyTree);
56723 + p_FmPort->h_ReassemblyTree = NULL;
56724 + }RELEASE_LOCK(p_FmPort->lock);
56725 + DBG(TRACE, ("Try LockAll - BUSY"));
56726 + return ERROR_CODE(E_BUSY);
56727 + }
56728 +
56729 + err = SetPcd(h_FmPort, p_PcdParams);
56730 + if (err)
56731 + {
56732 + if (p_FmPort->h_ReassemblyTree)
56733 + {
56734 + FM_PCD_CcRootDelete(p_FmPort->h_ReassemblyTree);
56735 + p_FmPort->h_ReassemblyTree = NULL;
56736 + }
56737 + FmPcdLockUnlockAll(p_FmPort->h_FmPcd);
56738 + RELEASE_LOCK(p_FmPort->lock);
56739 + RETURN_ERROR(MAJOR, err, NO_MSG);
56740 + }
56741 +
56742 + if ((p_FmPort->pcdEngines & FM_PCD_PRS)
56743 + && (p_PcdParams->p_PrsParams->includeInPrsStatistics))
56744 + {
56745 + err = FmPcdPrsIncludePortInStatistics(p_FmPort->h_FmPcd,
56746 + p_FmPort->hardwarePortId, TRUE);
56747 + if (err)
56748 + {
56749 + DeletePcd(p_FmPort);
56750 + if (p_FmPort->h_ReassemblyTree)
56751 + {
56752 + FM_PCD_CcRootDelete(p_FmPort->h_ReassemblyTree);
56753 + p_FmPort->h_ReassemblyTree = NULL;
56754 + }
56755 + FmPcdLockUnlockAll(p_FmPort->h_FmPcd);
56756 + RELEASE_LOCK(p_FmPort->lock);
56757 + RETURN_ERROR(MAJOR, err, NO_MSG);
56758 + }
56759 + p_FmPort->includeInPrsStatistics = TRUE;
56760 + }
56761 +
56762 + FmPcdIncNetEnvOwners(p_FmPort->h_FmPcd, p_FmPort->netEnvId);
56763 +
56764 + if (FmPcdIsAdvancedOffloadSupported(p_FmPort->h_FmPcd))
56765 + {
56766 + memset(&fmPortGetSetCcParams, 0, sizeof(t_FmPortGetSetCcParams));
56767 +
56768 + if (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING)
56769 + {
56770 +#ifdef FM_KG_ERASE_FLOW_ID_ERRATA_FMAN_SW004
56771 + if ((p_FmPort->fmRevInfo.majorRev < 6) &&
56772 + (p_FmPort->pcdEngines & FM_PCD_KG))
56773 + {
56774 + int i;
56775 + for (i = 0; i<p_PcdParams->p_KgParams->numOfSchemes; i++)
56776 + /* The following function must be locked */
56777 + FmPcdKgCcGetSetParams(p_FmPort->h_FmPcd,
56778 + p_PcdParams->p_KgParams->h_Schemes[i],
56779 + UPDATE_KG_NIA_CC_WA,
56780 + 0);
56781 + }
56782 +#endif /* FM_KG_ERASE_FLOW_ID_ERRATA_FMAN_SW004 */
56783 +
56784 +#if (DPAA_VERSION >= 11)
56785 + {
56786 + t_FmPcdCtrlParamsPage *p_ParamsPage;
56787 +
56788 + FmPortSetGprFunc(p_FmPort, e_FM_PORT_GPR_MURAM_PAGE,
56789 + (void**)&p_ParamsPage);
56790 + ASSERT_COND(p_ParamsPage);
56791 + WRITE_UINT32(p_ParamsPage->postBmiFetchNia,
56792 + p_FmPort->savedBmiNia);
56793 + }
56794 +#endif /* (DPAA_VERSION >= 11) */
56795 +
56796 + /* Set post-bmi-fetch nia */
56797 + p_FmPort->savedBmiNia &= BMI_RFNE_FDCS_MASK;
56798 + p_FmPort->savedBmiNia |= (NIA_FM_CTL_AC_POST_BMI_FETCH
56799 + | NIA_ENG_FM_CTL);
56800 +
56801 + /* Set pre-bmi-fetch nia */
56802 + fmPortGetSetCcParams.setCcParams.type = UPDATE_NIA_PNDN;
56803 +#if (DPAA_VERSION >= 11)
56804 + fmPortGetSetCcParams.setCcParams.nia =
56805 + (NIA_FM_CTL_AC_PRE_BMI_FETCH_FULL_FRAME | NIA_ENG_FM_CTL);
56806 +#else
56807 + fmPortGetSetCcParams.setCcParams.nia = (NIA_FM_CTL_AC_PRE_BMI_FETCH_HEADER | NIA_ENG_FM_CTL);
56808 +#endif /* (DPAA_VERSION >= 11) */
56809 + if ((err = FmPortGetSetCcParams(p_FmPort, &fmPortGetSetCcParams))
56810 + != E_OK)
56811 + {
56812 + DeletePcd(p_FmPort);
56813 + if (p_FmPort->h_ReassemblyTree)
56814 + {
56815 + FM_PCD_CcRootDelete(p_FmPort->h_ReassemblyTree);
56816 + p_FmPort->h_ReassemblyTree = NULL;
56817 + }
56818 + FmPcdLockUnlockAll(p_FmPort->h_FmPcd);
56819 + RELEASE_LOCK(p_FmPort->lock);
56820 + RETURN_ERROR(MAJOR, err, NO_MSG);
56821 + }
56822 + }
56823 +
56824 + FmPcdLockUnlockAll(p_FmPort->h_FmPcd);
56825 +
56826 + /* Set pop-to-next-step nia */
56827 +#if (DPAA_VERSION == 10)
56828 + if (p_FmPort->fmRevInfo.majorRev < 6)
56829 + {
56830 + fmPortGetSetCcParams.setCcParams.type = UPDATE_NIA_PNEN;
56831 + fmPortGetSetCcParams.setCcParams.nia = NIA_FM_CTL_AC_POP_TO_N_STEP | NIA_ENG_FM_CTL;
56832 + }
56833 + else
56834 + {
56835 +#endif /* (DPAA_VERSION == 10) */
56836 + fmPortGetSetCcParams.getCcParams.type = GET_NIA_FPNE;
56837 +#if (DPAA_VERSION == 10)
56838 + }
56839 +#endif /* (DPAA_VERSION == 10) */
56840 + if ((err = FmPortGetSetCcParams(h_FmPort, &fmPortGetSetCcParams))
56841 + != E_OK)
56842 + {
56843 + DeletePcd(p_FmPort);
56844 + if (p_FmPort->h_ReassemblyTree)
56845 + {
56846 + FM_PCD_CcRootDelete(p_FmPort->h_ReassemblyTree);
56847 + p_FmPort->h_ReassemblyTree = NULL;
56848 + }RELEASE_LOCK(p_FmPort->lock);
56849 + RETURN_ERROR(MAJOR, err, NO_MSG);
56850 + }
56851 +
56852 + /* Set post-bmi-prepare-to-enq nia */
56853 + fmPortGetSetCcParams.setCcParams.type = UPDATE_NIA_FENE;
56854 + fmPortGetSetCcParams.setCcParams.nia = (NIA_FM_CTL_AC_POST_BMI_ENQ
56855 + | NIA_ENG_FM_CTL);
56856 + if ((err = FmPortGetSetCcParams(h_FmPort, &fmPortGetSetCcParams))
56857 + != E_OK)
56858 + {
56859 + DeletePcd(p_FmPort);
56860 + if (p_FmPort->h_ReassemblyTree)
56861 + {
56862 + FM_PCD_CcRootDelete(p_FmPort->h_ReassemblyTree);
56863 + p_FmPort->h_ReassemblyTree = NULL;
56864 + }RELEASE_LOCK(p_FmPort->lock);
56865 + RETURN_ERROR(MAJOR, err, NO_MSG);
56866 + }
56867 +
56868 + if ((p_FmPort->h_IpReassemblyManip)
56869 + || (p_FmPort->h_CapwapReassemblyManip))
56870 + {
56871 +#if (DPAA_VERSION == 10)
56872 + if (p_FmPort->fmRevInfo.majorRev < 6)
56873 + {
56874 + /* Overwrite post-bmi-prepare-to-enq nia */
56875 + fmPortGetSetCcParams.setCcParams.type = UPDATE_NIA_FENE;
56876 + fmPortGetSetCcParams.setCcParams.nia = (NIA_FM_CTL_AC_POST_BMI_ENQ_ORR | NIA_ENG_FM_CTL | NIA_ORDER_RESTOR);
56877 + fmPortGetSetCcParams.setCcParams.overwrite = TRUE;
56878 + }
56879 + else
56880 + {
56881 +#endif /* (DPAA_VERSION == 10) */
56882 + /* Set the ORR bit (for order-restoration) */
56883 + fmPortGetSetCcParams.setCcParams.type = UPDATE_NIA_FPNE;
56884 + fmPortGetSetCcParams.setCcParams.nia =
56885 + fmPortGetSetCcParams.getCcParams.nia | NIA_ORDER_RESTOR;
56886 +#if (DPAA_VERSION == 10)
56887 + }
56888 +#endif /* (DPAA_VERSION == 10) */
56889 + if ((err = FmPortGetSetCcParams(h_FmPort, &fmPortGetSetCcParams))
56890 + != E_OK)
56891 + {
56892 + DeletePcd(p_FmPort);
56893 + if (p_FmPort->h_ReassemblyTree)
56894 + {
56895 + FM_PCD_CcRootDelete(p_FmPort->h_ReassemblyTree);
56896 + p_FmPort->h_ReassemblyTree = NULL;
56897 + }RELEASE_LOCK(p_FmPort->lock);
56898 + RETURN_ERROR(MAJOR, err, NO_MSG);
56899 + }
56900 + }
56901 + }
56902 + else
56903 + FmPcdLockUnlockAll(p_FmPort->h_FmPcd);
56904 +
56905 +#if (DPAA_VERSION >= 11)
56906 + {
56907 + t_FmPcdCtrlParamsPage *p_ParamsPage;
56908 +
56909 + memset(&fmPortGetSetCcParams, 0, sizeof(t_FmPortGetSetCcParams));
56910 +
56911 + fmPortGetSetCcParams.setCcParams.type = UPDATE_NIA_CMNE;
56912 + if (FmPcdIsAdvancedOffloadSupported(p_FmPort->h_FmPcd))
56913 + fmPortGetSetCcParams.setCcParams.nia = NIA_FM_CTL_AC_POP_TO_N_STEP
56914 + | NIA_ENG_FM_CTL;
56915 + else
56916 + fmPortGetSetCcParams.setCcParams.nia =
56917 + NIA_FM_CTL_AC_NO_IPACC_POP_TO_N_STEP | NIA_ENG_FM_CTL;
56918 + if ((err = FmPortGetSetCcParams(h_FmPort, &fmPortGetSetCcParams))
56919 + != E_OK)
56920 + {
56921 + DeletePcd(p_FmPort);
56922 + if (p_FmPort->h_ReassemblyTree)
56923 + {
56924 + FM_PCD_CcRootDelete(p_FmPort->h_ReassemblyTree);
56925 + p_FmPort->h_ReassemblyTree = NULL;
56926 + }RELEASE_LOCK(p_FmPort->lock);
56927 + RETURN_ERROR(MAJOR, err, NO_MSG);
56928 + }
56929 +
56930 + FmPortSetGprFunc(p_FmPort, e_FM_PORT_GPR_MURAM_PAGE,
56931 + (void**)&p_ParamsPage);
56932 + ASSERT_COND(p_ParamsPage);
56933 +
56934 + if (FmPcdIsAdvancedOffloadSupported(p_FmPort->h_FmPcd))
56935 + WRITE_UINT32(
56936 + p_ParamsPage->misc,
56937 + GET_UINT32(p_ParamsPage->misc) | FM_CTL_PARAMS_PAGE_OFFLOAD_SUPPORT_EN);
56938 +
56939 + if ((p_FmPort->h_IpReassemblyManip)
56940 + || (p_FmPort->h_CapwapReassemblyManip))
56941 + {
56942 + if (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING)
56943 + WRITE_UINT32(
56944 + p_ParamsPage->discardMask,
56945 + GET_UINT32(p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs.fmbm_ofsdm));
56946 + else
56947 + WRITE_UINT32(
56948 + p_ParamsPage->discardMask,
56949 + GET_UINT32(p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rfsdm));
56950 + }
56951 +#ifdef FM_ERROR_VSP_NO_MATCH_SW006
56952 + if (p_FmPort->vspe)
56953 + WRITE_UINT32(
56954 + p_ParamsPage->misc,
56955 + GET_UINT32(p_ParamsPage->misc) | (p_FmPort->dfltRelativeId & FM_CTL_PARAMS_PAGE_ERROR_VSP_MASK));
56956 +#endif /* FM_ERROR_VSP_NO_MATCH_SW006 */
56957 + }
56958 +#endif /* (DPAA_VERSION >= 11) */
56959 +
56960 + err = AttachPCD(h_FmPort);
56961 + if (err)
56962 + {
56963 + DeletePcd(p_FmPort);
56964 + if (p_FmPort->h_ReassemblyTree)
56965 + {
56966 + FM_PCD_CcRootDelete(p_FmPort->h_ReassemblyTree);
56967 + p_FmPort->h_ReassemblyTree = NULL;
56968 + }RELEASE_LOCK(p_FmPort->lock);
56969 + RETURN_ERROR(MAJOR, err, NO_MSG);
56970 + }
56971 +
56972 + RELEASE_LOCK(p_FmPort->lock);
56973 +
56974 + return err;
56975 +}
56976 +
56977 +t_Error FM_PORT_DeletePCD(t_Handle h_FmPort)
56978 +{
56979 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
56980 + t_Error err = E_OK;
56981 +
56982 + SANITY_CHECK_RETURN_ERROR(h_FmPort, E_INVALID_HANDLE);
56983 + SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE);
56984 +
56985 + if (p_FmPort->imEn)
56986 + RETURN_ERROR(MAJOR, E_INVALID_OPERATION,
56987 + ("available for non-independant mode ports only"));
56988 +
56989 + if ((p_FmPort->portType != e_FM_PORT_TYPE_RX_10G)
56990 + && (p_FmPort->portType != e_FM_PORT_TYPE_RX)
56991 + && (p_FmPort->portType != e_FM_PORT_TYPE_OH_OFFLINE_PARSING))
56992 + RETURN_ERROR( MAJOR, E_INVALID_OPERATION,
56993 + ("available for Rx and offline parsing ports only"));
56994 +
56995 + if (!TRY_LOCK(p_FmPort->h_Spinlock, &p_FmPort->lock))
56996 + {
56997 + DBG(TRACE, ("FM Port Try Lock - BUSY"));
56998 + return ERROR_CODE(E_BUSY);
56999 + }
57000 +
57001 + err = DetachPCD(h_FmPort);
57002 + if (err)
57003 + {
57004 + RELEASE_LOCK(p_FmPort->lock);
57005 + RETURN_ERROR(MAJOR, err, NO_MSG);
57006 + }
57007 +
57008 + FmPcdDecNetEnvOwners(p_FmPort->h_FmPcd, p_FmPort->netEnvId);
57009 +
57010 + /* we do it anyway, instead of checking if included */
57011 + if ((p_FmPort->pcdEngines & FM_PCD_PRS) && p_FmPort->includeInPrsStatistics)
57012 + {
57013 + FmPcdPrsIncludePortInStatistics(p_FmPort->h_FmPcd,
57014 + p_FmPort->hardwarePortId, FALSE);
57015 + p_FmPort->includeInPrsStatistics = FALSE;
57016 + }
57017 +
57018 + if (!FmPcdLockTryLockAll(p_FmPort->h_FmPcd))
57019 + {
57020 + RELEASE_LOCK(p_FmPort->lock);
57021 + DBG(TRACE, ("Try LockAll - BUSY"));
57022 + return ERROR_CODE(E_BUSY);
57023 + }
57024 +
57025 + err = DeletePcd(h_FmPort);
57026 + FmPcdLockUnlockAll(p_FmPort->h_FmPcd);
57027 + if (err)
57028 + {
57029 + RELEASE_LOCK(p_FmPort->lock);
57030 + RETURN_ERROR(MAJOR, err, NO_MSG);
57031 + }
57032 +
57033 + if (p_FmPort->h_ReassemblyTree)
57034 + {
57035 + err = FM_PCD_CcRootDelete(p_FmPort->h_ReassemblyTree);
57036 + if (err)
57037 + {
57038 + RELEASE_LOCK(p_FmPort->lock);
57039 + RETURN_ERROR(MAJOR, err, NO_MSG);
57040 + }
57041 + p_FmPort->h_ReassemblyTree = NULL;
57042 + }RELEASE_LOCK(p_FmPort->lock);
57043 +
57044 + return err;
57045 +}
57046 +
57047 +t_Error FM_PORT_PcdKgBindSchemes(t_Handle h_FmPort,
57048 + t_FmPcdPortSchemesParams *p_PortScheme)
57049 +{
57050 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
57051 + t_FmPcdKgInterModuleBindPortToSchemes schemeBind;
57052 + t_Error err = E_OK;
57053 + uint32_t tmpScmVec = 0;
57054 + int i;
57055 +
57056 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
57057 + SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE);
57058 + SANITY_CHECK_RETURN_ERROR(p_FmPort->pcdEngines & FM_PCD_KG,
57059 + E_INVALID_STATE);
57060 +
57061 + schemeBind.netEnvId = p_FmPort->netEnvId;
57062 + schemeBind.hardwarePortId = p_FmPort->hardwarePortId;
57063 + schemeBind.numOfSchemes = p_PortScheme->numOfSchemes;
57064 + schemeBind.useClsPlan = p_FmPort->useClsPlan;
57065 + for (i = 0; i < schemeBind.numOfSchemes; i++)
57066 + {
57067 + schemeBind.schemesIds[i] = FmPcdKgGetSchemeId(
57068 + p_PortScheme->h_Schemes[i]);
57069 + /* build vector */
57070 + tmpScmVec |= 1 << (31 - (uint32_t)schemeBind.schemesIds[i]);
57071 + }
57072 +
57073 + if (!TRY_LOCK(p_FmPort->h_Spinlock, &p_FmPort->lock))
57074 + {
57075 + DBG(TRACE, ("FM Port Try Lock - BUSY"));
57076 + return ERROR_CODE(E_BUSY);
57077 + }
57078 +
57079 + err = FmPcdKgBindPortToSchemes(p_FmPort->h_FmPcd, &schemeBind);
57080 + if (err == E_OK)
57081 + p_FmPort->schemesPerPortVector |= tmpScmVec;
57082 +
57083 +#ifdef FM_KG_ERASE_FLOW_ID_ERRATA_FMAN_SW004
57084 + if ((FmPcdIsAdvancedOffloadSupported(p_FmPort->h_FmPcd)) &&
57085 + (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING) &&
57086 + (p_FmPort->fmRevInfo.majorRev < 6))
57087 + {
57088 + for (i=0; i<p_PortScheme->numOfSchemes; i++)
57089 + FmPcdKgCcGetSetParams(p_FmPort->h_FmPcd, p_PortScheme->h_Schemes[i], UPDATE_KG_NIA_CC_WA, 0);
57090 + }
57091 +#endif /* FM_KG_ERASE_FLOW_ID_ERRATA_FMAN_SW004 */
57092 +
57093 + RELEASE_LOCK(p_FmPort->lock);
57094 +
57095 + return err;
57096 +}
57097 +
57098 +t_Error FM_PORT_PcdKgUnbindSchemes(t_Handle h_FmPort,
57099 + t_FmPcdPortSchemesParams *p_PortScheme)
57100 +{
57101 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
57102 + t_FmPcdKgInterModuleBindPortToSchemes schemeBind;
57103 + t_Error err = E_OK;
57104 + uint32_t tmpScmVec = 0;
57105 + int i;
57106 +
57107 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
57108 + SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE);
57109 + SANITY_CHECK_RETURN_ERROR(p_FmPort->pcdEngines & FM_PCD_KG,
57110 + E_INVALID_STATE);
57111 +
57112 + schemeBind.netEnvId = p_FmPort->netEnvId;
57113 + schemeBind.hardwarePortId = p_FmPort->hardwarePortId;
57114 + schemeBind.numOfSchemes = p_PortScheme->numOfSchemes;
57115 + for (i = 0; i < schemeBind.numOfSchemes; i++)
57116 + {
57117 + schemeBind.schemesIds[i] = FmPcdKgGetSchemeId(
57118 + p_PortScheme->h_Schemes[i]);
57119 + /* build vector */
57120 + tmpScmVec |= 1 << (31 - (uint32_t)schemeBind.schemesIds[i]);
57121 + }
57122 +
57123 + if (!TRY_LOCK(p_FmPort->h_Spinlock, &p_FmPort->lock))
57124 + {
57125 + DBG(TRACE, ("FM Port Try Lock - BUSY"));
57126 + return ERROR_CODE(E_BUSY);
57127 + }
57128 +
57129 + err = FmPcdKgUnbindPortToSchemes(p_FmPort->h_FmPcd, &schemeBind);
57130 + if (err == E_OK)
57131 + p_FmPort->schemesPerPortVector &= ~tmpScmVec;
57132 + RELEASE_LOCK(p_FmPort->lock);
57133 +
57134 + return err;
57135 +}
57136 +
57137 +t_Error FM_PORT_AddCongestionGrps(t_Handle h_FmPort,
57138 + t_FmPortCongestionGrps *p_CongestionGrps)
57139 +{
57140 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
57141 + uint8_t priorityTmpArray[FM_PORT_NUM_OF_CONGESTION_GRPS];
57142 + uint8_t mod, index;
57143 + uint32_t i, grpsMap[FMAN_PORT_CG_MAP_NUM];
57144 + int err;
57145 +#if (DPAA_VERSION >= 11)
57146 + int j;
57147 +#endif /* (DPAA_VERSION >= 11) */
57148 +
57149 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
57150 +
57151 + /* un-necessary check of the indexes; probably will be needed in the future when there
57152 + will be more CGs available ....
57153 + for (i=0; i<p_CongestionGrps->numOfCongestionGrpsToConsider; i++)
57154 + if (p_CongestionGrps->congestionGrpsToConsider[i] >= FM_PORT_NUM_OF_CONGESTION_GRPS)
57155 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("CG id!"));
57156 + */
57157 +
57158 +#ifdef FM_NO_OP_OBSERVED_CGS
57159 + if ((p_FmPort->fmRevInfo.majorRev != 4) &&
57160 + (p_FmPort->fmRevInfo.majorRev < 6))
57161 + {
57162 + if ((p_FmPort->portType != e_FM_PORT_TYPE_RX_10G) &&
57163 + (p_FmPort->portType != e_FM_PORT_TYPE_RX))
57164 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("Available for Rx ports only"));
57165 + }
57166 + else
57167 +#endif /* FM_NO_OP_OBSERVED_CGS */
57168 + if ((p_FmPort->portType != e_FM_PORT_TYPE_RX_10G)
57169 + && (p_FmPort->portType != e_FM_PORT_TYPE_RX)
57170 + && (p_FmPort->portType != e_FM_PORT_TYPE_OH_OFFLINE_PARSING))
57171 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED,
57172 + ("Available for Rx & OP ports only"));
57173 +
57174 + /* Prepare groups map array */
57175 + memset(grpsMap, 0, FMAN_PORT_CG_MAP_NUM * sizeof(uint32_t));
57176 + for (i = 0; i < p_CongestionGrps->numOfCongestionGrpsToConsider; i++)
57177 + {
57178 + index = (uint8_t)(p_CongestionGrps->congestionGrpsToConsider[i] / 32);
57179 + mod = (uint8_t)(p_CongestionGrps->congestionGrpsToConsider[i] % 32);
57180 + if (p_FmPort->fmRevInfo.majorRev != 4)
57181 + grpsMap[7 - index] |= (uint32_t)(1 << mod);
57182 + else
57183 + grpsMap[0] |= (uint32_t)(1 << mod);
57184 + }
57185 +
57186 + memset(&priorityTmpArray, 0,
57187 + FM_PORT_NUM_OF_CONGESTION_GRPS * sizeof(uint8_t));
57188 +
57189 + for (i = 0; i < p_CongestionGrps->numOfCongestionGrpsToConsider; i++)
57190 + {
57191 +#if (DPAA_VERSION >= 11)
57192 + for (j = 0; j < FM_MAX_NUM_OF_PFC_PRIORITIES; j++)
57193 + if (p_CongestionGrps->pfcPrioritiesEn[i][j])
57194 + priorityTmpArray[p_CongestionGrps->congestionGrpsToConsider[i]] |=
57195 + (0x01 << (FM_MAX_NUM_OF_PFC_PRIORITIES - j - 1));
57196 +#endif /* (DPAA_VERSION >= 11) */
57197 + }
57198 +
57199 +#if (DPAA_VERSION >= 11)
57200 + for (i = 0; i < FM_PORT_NUM_OF_CONGESTION_GRPS; i++)
57201 + {
57202 + err = FmSetCongestionGroupPFCpriority(p_FmPort->h_Fm, i,
57203 + priorityTmpArray[i]);
57204 + if (err)
57205 + return err;
57206 + }
57207 +#endif /* (DPAA_VERSION >= 11) */
57208 +
57209 + err = fman_port_add_congestion_grps(&p_FmPort->port, grpsMap);
57210 + if (err != 0)
57211 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("fman_port_add_congestion_grps"));
57212 +
57213 + return E_OK;
57214 +}
57215 +
57216 +t_Error FM_PORT_RemoveCongestionGrps(t_Handle h_FmPort,
57217 + t_FmPortCongestionGrps *p_CongestionGrps)
57218 +{
57219 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
57220 + uint8_t mod, index;
57221 + uint32_t i, grpsMap[FMAN_PORT_CG_MAP_NUM];
57222 + int err;
57223 +
57224 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
57225 +
57226 + {
57227 +#ifdef FM_NO_OP_OBSERVED_CGS
57228 + t_FmRevisionInfo revInfo;
57229 +
57230 + FM_GetRevision(p_FmPort->h_Fm, &revInfo);
57231 + if (revInfo.majorRev != 4)
57232 + {
57233 + if ((p_FmPort->portType != e_FM_PORT_TYPE_RX_10G) &&
57234 + (p_FmPort->portType != e_FM_PORT_TYPE_RX))
57235 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("Available for Rx ports only"));
57236 + }
57237 + else
57238 +#endif /* FM_NO_OP_OBSERVED_CGS */
57239 + if ((p_FmPort->portType != e_FM_PORT_TYPE_RX_10G)
57240 + && (p_FmPort->portType != e_FM_PORT_TYPE_RX)
57241 + && (p_FmPort->portType != e_FM_PORT_TYPE_OH_OFFLINE_PARSING))
57242 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED,
57243 + ("Available for Rx & OP ports only"));
57244 + }
57245 +
57246 + /* Prepare groups map array */
57247 + memset(grpsMap, 0, FMAN_PORT_CG_MAP_NUM * sizeof(uint32_t));
57248 + for (i = 0; i < p_CongestionGrps->numOfCongestionGrpsToConsider; i++)
57249 + {
57250 + index = (uint8_t)(p_CongestionGrps->congestionGrpsToConsider[i] / 32);
57251 + mod = (uint8_t)(p_CongestionGrps->congestionGrpsToConsider[i] % 32);
57252 + if (p_FmPort->fmRevInfo.majorRev != 4)
57253 + grpsMap[7 - index] |= (uint32_t)(1 << mod);
57254 + else
57255 + grpsMap[0] |= (uint32_t)(1 << mod);
57256 + }
57257 +
57258 +#if (DPAA_VERSION >= 11)
57259 + for (i = 0; i < p_CongestionGrps->numOfCongestionGrpsToConsider; i++)
57260 + {
57261 + t_Error err = FmSetCongestionGroupPFCpriority(
57262 + p_FmPort->h_Fm, p_CongestionGrps->congestionGrpsToConsider[i],
57263 + 0);
57264 + if (err)
57265 + return err;
57266 + }
57267 +#endif /* (DPAA_VERSION >= 11) */
57268 +
57269 + err = fman_port_remove_congestion_grps(&p_FmPort->port, grpsMap);
57270 + if (err != 0)
57271 + RETURN_ERROR(MAJOR, E_INVALID_VALUE,
57272 + ("fman_port_remove_congestion_grps"));
57273 + return E_OK;
57274 +}
57275 +
57276 +#if (DPAA_VERSION >= 11)
57277 +t_Error FM_PORT_GetIPv4OptionsCount(t_Handle h_FmPort,
57278 + uint32_t *p_Ipv4OptionsCount)
57279 +{
57280 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
57281 +
57282 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
57283 + SANITY_CHECK_RETURN_ERROR(
57284 + (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING),
57285 + E_INVALID_VALUE);
57286 + SANITY_CHECK_RETURN_ERROR(p_FmPort->p_ParamsPage, E_INVALID_STATE);
57287 + SANITY_CHECK_RETURN_ERROR(p_Ipv4OptionsCount, E_NULL_POINTER);
57288 +
57289 + *p_Ipv4OptionsCount = GET_UINT32(p_FmPort->p_ParamsPage->ipfOptionsCounter);
57290 +
57291 + return E_OK;
57292 +}
57293 +#endif /* (DPAA_VERSION >= 11) */
57294 +
57295 +t_Error FM_PORT_ConfigDsarSupport(t_Handle h_FmPortRx,
57296 + t_FmPortDsarTablesSizes *params)
57297 +{
57298 + t_FmPort *p_FmPort = (t_FmPort *)h_FmPortRx;
57299 + p_FmPort->deepSleepVars.autoResMaxSizes = XX_Malloc(
57300 + sizeof(struct t_FmPortDsarTablesSizes));
57301 + memcpy(p_FmPort->deepSleepVars.autoResMaxSizes, params,
57302 + sizeof(struct t_FmPortDsarTablesSizes));
57303 + return E_OK;
57304 +}
57305 +
57306 +static t_Error FmPortConfigAutoResForDeepSleepSupport1(t_FmPort *p_FmPort)
57307 +{
57308 + uint32_t *param_page;
57309 + t_FmPortDsarTablesSizes *params = p_FmPort->deepSleepVars.autoResMaxSizes;
57310 + t_ArCommonDesc *ArCommonDescPtr;
57311 + uint32_t size = sizeof(t_ArCommonDesc);
57312 + // ARP
57313 + // should put here if (params->max_num_of_arp_entries)?
57314 + size = ROUND_UP(size,4);
57315 + size += sizeof(t_DsarArpDescriptor);
57316 + size += sizeof(t_DsarArpBindingEntry) * params->maxNumOfArpEntries;
57317 + size += sizeof(t_DsarArpStatistics);
57318 + //ICMPV4
57319 + size = ROUND_UP(size,4);
57320 + size += sizeof(t_DsarIcmpV4Descriptor);
57321 + size += sizeof(t_DsarIcmpV4BindingEntry) * params->maxNumOfEchoIpv4Entries;
57322 + size += sizeof(t_DsarIcmpV4Statistics);
57323 + //ICMPV6
57324 + size = ROUND_UP(size,4);
57325 + size += sizeof(t_DsarIcmpV6Descriptor);
57326 + size += sizeof(t_DsarIcmpV6BindingEntry) * params->maxNumOfEchoIpv6Entries;
57327 + size += sizeof(t_DsarIcmpV6Statistics);
57328 + //ND
57329 + size = ROUND_UP(size,4);
57330 + size += sizeof(t_DsarNdDescriptor);
57331 + size += sizeof(t_DsarIcmpV6BindingEntry) * params->maxNumOfNdpEntries;
57332 + size += sizeof(t_DsarIcmpV6Statistics);
57333 + //SNMP
57334 + size = ROUND_UP(size,4);
57335 + size += sizeof(t_DsarSnmpDescriptor);
57336 + size += sizeof(t_DsarSnmpIpv4AddrTblEntry)
57337 + * params->maxNumOfSnmpIPV4Entries;
57338 + size += sizeof(t_DsarSnmpIpv6AddrTblEntry)
57339 + * params->maxNumOfSnmpIPV6Entries;
57340 + size += sizeof(t_OidsTblEntry) * params->maxNumOfSnmpOidEntries;
57341 + size += params->maxNumOfSnmpOidChar;
57342 + size += sizeof(t_DsarIcmpV6Statistics);
57343 + //filters
57344 + size = ROUND_UP(size,4);
57345 + size += params->maxNumOfIpProtFiltering;
57346 + size = ROUND_UP(size,4);
57347 + size += params->maxNumOfUdpPortFiltering * sizeof(t_PortTblEntry);
57348 + size = ROUND_UP(size,4);
57349 + size += params->maxNumOfTcpPortFiltering * sizeof(t_PortTblEntry);
57350 +
57351 + // add here for more protocols
57352 +
57353 + // statistics
57354 + size = ROUND_UP(size,4);
57355 + size += sizeof(t_ArStatistics);
57356 +
57357 + ArCommonDescPtr = FM_MURAM_AllocMem(p_FmPort->h_FmMuram, size, 0x10);
57358 +
57359 + param_page =
57360 + XX_PhysToVirt(
57361 + p_FmPort->fmMuramPhysBaseAddr
57362 + + GET_UINT32(p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rgpr));
57363 + WRITE_UINT32(
57364 + *param_page,
57365 + (uint32_t)(XX_VirtToPhys(ArCommonDescPtr) - p_FmPort->fmMuramPhysBaseAddr));
57366 + return E_OK;
57367 +}
57368 +
57369 +t_FmPortDsarTablesSizes* FM_PORT_GetDsarTablesMaxSizes(t_Handle h_FmPortRx)
57370 +{
57371 + t_FmPort *p_FmPort = (t_FmPort *)h_FmPortRx;
57372 + return p_FmPort->deepSleepVars.autoResMaxSizes;
57373 +}
57374 +
57375 +struct arOffsets
57376 +{
57377 + uint32_t arp;
57378 + uint32_t nd;
57379 + uint32_t icmpv4;
57380 + uint32_t icmpv6;
57381 + uint32_t snmp;
57382 + uint32_t stats;
57383 + uint32_t filtIp;
57384 + uint32_t filtUdp;
57385 + uint32_t filtTcp;
57386 +};
57387 +
57388 +static uint32_t AR_ComputeOffsets(struct arOffsets* of,
57389 + struct t_FmPortDsarParams *params,
57390 + t_FmPort *p_FmPort)
57391 +{
57392 + uint32_t size = sizeof(t_ArCommonDesc);
57393 + // ARP
57394 + if (params->p_AutoResArpInfo)
57395 + {
57396 + size = ROUND_UP(size,4);
57397 + of->arp = size;
57398 + size += sizeof(t_DsarArpDescriptor);
57399 + size += sizeof(t_DsarArpBindingEntry)
57400 + * params->p_AutoResArpInfo->tableSize;
57401 + size += sizeof(t_DsarArpStatistics);
57402 + }
57403 + // ICMPV4
57404 + if (params->p_AutoResEchoIpv4Info)
57405 + {
57406 + size = ROUND_UP(size,4);
57407 + of->icmpv4 = size;
57408 + size += sizeof(t_DsarIcmpV4Descriptor);
57409 + size += sizeof(t_DsarIcmpV4BindingEntry)
57410 + * params->p_AutoResEchoIpv4Info->tableSize;
57411 + size += sizeof(t_DsarIcmpV4Statistics);
57412 + }
57413 + // ICMPV6
57414 + if (params->p_AutoResEchoIpv6Info)
57415 + {
57416 + size = ROUND_UP(size,4);
57417 + of->icmpv6 = size;
57418 + size += sizeof(t_DsarIcmpV6Descriptor);
57419 + size += sizeof(t_DsarIcmpV6BindingEntry)
57420 + * params->p_AutoResEchoIpv6Info->tableSize;
57421 + size += sizeof(t_DsarIcmpV6Statistics);
57422 + }
57423 + // ND
57424 + if (params->p_AutoResNdpInfo)
57425 + {
57426 + size = ROUND_UP(size,4);
57427 + of->nd = size;
57428 + size += sizeof(t_DsarNdDescriptor);
57429 + size += sizeof(t_DsarIcmpV6BindingEntry)
57430 + * (params->p_AutoResNdpInfo->tableSizeAssigned
57431 + + params->p_AutoResNdpInfo->tableSizeTmp);
57432 + size += sizeof(t_DsarIcmpV6Statistics);
57433 + }
57434 + // SNMP
57435 + if (params->p_AutoResSnmpInfo)
57436 + {
57437 + size = ROUND_UP(size,4);
57438 + of->snmp = size;
57439 + size += sizeof(t_DsarSnmpDescriptor);
57440 + size += sizeof(t_DsarSnmpIpv4AddrTblEntry)
57441 + * params->p_AutoResSnmpInfo->numOfIpv4Addresses;
57442 + size += sizeof(t_DsarSnmpIpv6AddrTblEntry)
57443 + * params->p_AutoResSnmpInfo->numOfIpv6Addresses;
57444 + size += sizeof(t_OidsTblEntry) * params->p_AutoResSnmpInfo->oidsTblSize;
57445 + size += p_FmPort->deepSleepVars.autoResMaxSizes->maxNumOfSnmpOidChar;
57446 + size += sizeof(t_DsarIcmpV6Statistics);
57447 + }
57448 + //filters
57449 + size = ROUND_UP(size,4);
57450 + if (params->p_AutoResFilteringInfo)
57451 + {
57452 + of->filtIp = size;
57453 + size += params->p_AutoResFilteringInfo->ipProtTableSize;
57454 + size = ROUND_UP(size,4);
57455 + of->filtUdp = size;
57456 + size += params->p_AutoResFilteringInfo->udpPortsTableSize
57457 + * sizeof(t_PortTblEntry);
57458 + size = ROUND_UP(size,4);
57459 + of->filtTcp = size;
57460 + size += params->p_AutoResFilteringInfo->tcpPortsTableSize
57461 + * sizeof(t_PortTblEntry);
57462 + }
57463 + // add here for more protocols
57464 + // statistics
57465 + size = ROUND_UP(size,4);
57466 + of->stats = size;
57467 + size += sizeof(t_ArStatistics);
57468 + return size;
57469 +}
57470 +
57471 +uint32_t* ARDesc;
57472 +void PrsEnable(t_Handle p_FmPcd);
57473 +void PrsDisable(t_Handle p_FmPcd);
57474 +int PrsIsEnabled(t_Handle p_FmPcd);
57475 +t_Handle FM_PCD_GetHcPort(t_Handle h_FmPcd);
57476 +
57477 +static t_Error DsarCheckParams(t_FmPortDsarParams *params,
57478 + t_FmPortDsarTablesSizes *sizes)
57479 +{
57480 + bool macInit = FALSE;
57481 + uint8_t mac[6];
57482 + int i = 0;
57483 +
57484 + // check table sizes
57485 + if (params->p_AutoResArpInfo
57486 + && sizes->maxNumOfArpEntries < params->p_AutoResArpInfo->tableSize)
57487 + RETURN_ERROR(
57488 + MAJOR, E_INVALID_VALUE,
57489 + ("DSAR: Arp table size exceeds the configured maximum size."));
57490 + if (params->p_AutoResEchoIpv4Info
57491 + && sizes->maxNumOfEchoIpv4Entries
57492 + < params->p_AutoResEchoIpv4Info->tableSize)
57493 + RETURN_ERROR(
57494 + MAJOR,
57495 + E_INVALID_VALUE,
57496 + ("DSAR: EchoIpv4 table size exceeds the configured maximum size."));
57497 + if (params->p_AutoResNdpInfo
57498 + && sizes->maxNumOfNdpEntries
57499 + < params->p_AutoResNdpInfo->tableSizeAssigned
57500 + + params->p_AutoResNdpInfo->tableSizeTmp)
57501 + RETURN_ERROR(
57502 + MAJOR, E_INVALID_VALUE,
57503 + ("DSAR: NDP table size exceeds the configured maximum size."));
57504 + if (params->p_AutoResEchoIpv6Info
57505 + && sizes->maxNumOfEchoIpv6Entries
57506 + < params->p_AutoResEchoIpv6Info->tableSize)
57507 + RETURN_ERROR(
57508 + MAJOR,
57509 + E_INVALID_VALUE,
57510 + ("DSAR: EchoIpv6 table size exceeds the configured maximum size."));
57511 + if (params->p_AutoResSnmpInfo
57512 + && sizes->maxNumOfSnmpOidEntries
57513 + < params->p_AutoResSnmpInfo->oidsTblSize)
57514 + RETURN_ERROR(
57515 + MAJOR,
57516 + E_INVALID_VALUE,
57517 + ("DSAR: Snmp Oid table size exceeds the configured maximum size."));
57518 + if (params->p_AutoResSnmpInfo
57519 + && sizes->maxNumOfSnmpIPV4Entries
57520 + < params->p_AutoResSnmpInfo->numOfIpv4Addresses)
57521 + RETURN_ERROR(
57522 + MAJOR,
57523 + E_INVALID_VALUE,
57524 + ("DSAR: Snmp ipv4 table size exceeds the configured maximum size."));
57525 + if (params->p_AutoResSnmpInfo
57526 + && sizes->maxNumOfSnmpIPV6Entries
57527 + < params->p_AutoResSnmpInfo->numOfIpv6Addresses)
57528 + RETURN_ERROR(
57529 + MAJOR,
57530 + E_INVALID_VALUE,
57531 + ("DSAR: Snmp ipv6 table size exceeds the configured maximum size."));
57532 + if (params->p_AutoResFilteringInfo)
57533 + {
57534 + if (sizes->maxNumOfIpProtFiltering
57535 + < params->p_AutoResFilteringInfo->ipProtTableSize)
57536 + RETURN_ERROR(
57537 + MAJOR,
57538 + E_INVALID_VALUE,
57539 + ("DSAR: ip filter table size exceeds the configured maximum size."));
57540 + if (sizes->maxNumOfTcpPortFiltering
57541 + < params->p_AutoResFilteringInfo->udpPortsTableSize)
57542 + RETURN_ERROR(
57543 + MAJOR,
57544 + E_INVALID_VALUE,
57545 + ("DSAR: udp filter table size exceeds the configured maximum size."));
57546 + if (sizes->maxNumOfUdpPortFiltering
57547 + < params->p_AutoResFilteringInfo->tcpPortsTableSize)
57548 + RETURN_ERROR(
57549 + MAJOR,
57550 + E_INVALID_VALUE,
57551 + ("DSAR: tcp filter table size exceeds the configured maximum size."));
57552 + }
57553 + /* check only 1 MAC address is configured (this is what ucode currently supports) */
57554 + if (params->p_AutoResArpInfo && params->p_AutoResArpInfo->tableSize)
57555 + {
57556 + memcpy(mac, params->p_AutoResArpInfo->p_AutoResTable[0].mac, 6);
57557 + i = 1;
57558 + macInit = TRUE;
57559 +
57560 + for (; i < params->p_AutoResArpInfo->tableSize; i++)
57561 + if (memcmp(mac, params->p_AutoResArpInfo->p_AutoResTable[i].mac, 6))
57562 + RETURN_ERROR(
57563 + MAJOR, E_INVALID_VALUE,
57564 + ("DSAR: Only 1 mac address is currently supported."));
57565 + }
57566 + if (params->p_AutoResEchoIpv4Info
57567 + && params->p_AutoResEchoIpv4Info->tableSize)
57568 + {
57569 + i = 0;
57570 + if (!macInit)
57571 + {
57572 + memcpy(mac, params->p_AutoResEchoIpv4Info->p_AutoResTable[0].mac,
57573 + 6);
57574 + i = 1;
57575 + macInit = TRUE;
57576 + }
57577 + for (; i < params->p_AutoResEchoIpv4Info->tableSize; i++)
57578 + if (memcmp(mac,
57579 + params->p_AutoResEchoIpv4Info->p_AutoResTable[i].mac, 6))
57580 + RETURN_ERROR(
57581 + MAJOR, E_INVALID_VALUE,
57582 + ("DSAR: Only 1 mac address is currently supported."));
57583 + }
57584 + if (params->p_AutoResEchoIpv6Info
57585 + && params->p_AutoResEchoIpv6Info->tableSize)
57586 + {
57587 + i = 0;
57588 + if (!macInit)
57589 + {
57590 + memcpy(mac, params->p_AutoResEchoIpv6Info->p_AutoResTable[0].mac,
57591 + 6);
57592 + i = 1;
57593 + macInit = TRUE;
57594 + }
57595 + for (; i < params->p_AutoResEchoIpv6Info->tableSize; i++)
57596 + if (memcmp(mac,
57597 + params->p_AutoResEchoIpv6Info->p_AutoResTable[i].mac, 6))
57598 + RETURN_ERROR(
57599 + MAJOR, E_INVALID_VALUE,
57600 + ("DSAR: Only 1 mac address is currently supported."));
57601 + }
57602 + if (params->p_AutoResNdpInfo && params->p_AutoResNdpInfo->tableSizeAssigned)
57603 + {
57604 + i = 0;
57605 + if (!macInit)
57606 + {
57607 + memcpy(mac, params->p_AutoResNdpInfo->p_AutoResTableAssigned[0].mac,
57608 + 6);
57609 + i = 1;
57610 + macInit = TRUE;
57611 + }
57612 + for (; i < params->p_AutoResNdpInfo->tableSizeAssigned; i++)
57613 + if (memcmp(mac,
57614 + params->p_AutoResNdpInfo->p_AutoResTableAssigned[i].mac,
57615 + 6))
57616 + RETURN_ERROR(
57617 + MAJOR, E_INVALID_VALUE,
57618 + ("DSAR: Only 1 mac address is currently supported."));
57619 + }
57620 + if (params->p_AutoResNdpInfo && params->p_AutoResNdpInfo->tableSizeTmp)
57621 + {
57622 + i = 0;
57623 + if (!macInit)
57624 + {
57625 + memcpy(mac, params->p_AutoResNdpInfo->p_AutoResTableTmp[0].mac, 6);
57626 + i = 1;
57627 + }
57628 + for (; i < params->p_AutoResNdpInfo->tableSizeTmp; i++)
57629 + if (memcmp(mac, params->p_AutoResNdpInfo->p_AutoResTableTmp[i].mac,
57630 + 6))
57631 + RETURN_ERROR(
57632 + MAJOR, E_INVALID_VALUE,
57633 + ("DSAR: Only 1 mac address is currently supported."));
57634 + }
57635 + return E_OK;
57636 +}
57637 +
57638 +static int GetBERLen(uint8_t* buf)
57639 +{
57640 + if (*buf & 0x80)
57641 + {
57642 + if ((*buf & 0x7F) == 1)
57643 + return buf[1];
57644 + else
57645 + return *(uint16_t*)&buf[1]; // assuming max len is 2
57646 + }
57647 + else
57648 + return buf[0];
57649 +}
57650 +#define TOTAL_BER_LEN(len) (len < 128) ? len + 2 : len + 3
57651 +
57652 +#define SCFG_FMCLKDPSLPCR_ADDR 0xFFE0FC00C
57653 +#define SCFG_FMCLKDPSLPCR_DS_VAL 0x08402000
57654 +#define SCFG_FMCLKDPSLPCR_NORMAL_VAL 0x00402000
57655 +static int fm_soc_suspend(void)
57656 +{
57657 + uint32_t *fmclk, tmp32;
57658 + fmclk = ioremap(SCFG_FMCLKDPSLPCR_ADDR, 4);
57659 + tmp32 = GET_UINT32(*fmclk);
57660 + WRITE_UINT32(*fmclk, SCFG_FMCLKDPSLPCR_DS_VAL);
57661 + tmp32 = GET_UINT32(*fmclk);
57662 + iounmap(fmclk);
57663 + return 0;
57664 +}
57665 +
57666 +void fm_clk_down(void)
57667 +{
57668 + uint32_t *fmclk, tmp32;
57669 + fmclk = ioremap(SCFG_FMCLKDPSLPCR_ADDR, 4);
57670 + tmp32 = GET_UINT32(*fmclk);
57671 + WRITE_UINT32(*fmclk, SCFG_FMCLKDPSLPCR_DS_VAL | 0x40000000);
57672 + tmp32 = GET_UINT32(*fmclk);
57673 + iounmap(fmclk);
57674 +}
57675 +
57676 +t_Error FM_PORT_EnterDsar(t_Handle h_FmPortRx, t_FmPortDsarParams *params)
57677 +{
57678 + int i, j;
57679 + t_Error err;
57680 + uint32_t nia;
57681 + t_FmPort *p_FmPort = (t_FmPort *)h_FmPortRx;
57682 + t_FmPort *p_FmPortTx = (t_FmPort *)params->h_FmPortTx;
57683 + t_DsarArpDescriptor *ArpDescriptor;
57684 + t_DsarIcmpV4Descriptor* ICMPV4Descriptor;
57685 + t_DsarIcmpV6Descriptor* ICMPV6Descriptor;
57686 + t_DsarNdDescriptor* NDDescriptor;
57687 +
57688 + uint64_t fmMuramVirtBaseAddr = (uint64_t)PTR_TO_UINT(XX_PhysToVirt(p_FmPort->fmMuramPhysBaseAddr));
57689 + uint32_t *param_page = XX_PhysToVirt(p_FmPort->fmMuramPhysBaseAddr + GET_UINT32(p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rgpr));
57690 + t_ArCommonDesc *ArCommonDescPtr = (t_ArCommonDesc*)(XX_PhysToVirt(p_FmPort->fmMuramPhysBaseAddr + GET_UINT32(*param_page)));
57691 + struct arOffsets* of;
57692 + uint8_t tmp = 0;
57693 + t_FmGetSetParams fmGetSetParams;
57694 + memset(&fmGetSetParams, 0, sizeof (t_FmGetSetParams));
57695 + fmGetSetParams.setParams.type = UPDATE_FPM_BRKC_SLP;
57696 + fmGetSetParams.setParams.sleep = 1;
57697 +
57698 + err = DsarCheckParams(params, p_FmPort->deepSleepVars.autoResMaxSizes);
57699 + if (err != E_OK)
57700 + return err;
57701 +
57702 + p_FmPort->deepSleepVars.autoResOffsets = XX_Malloc(sizeof(struct arOffsets));
57703 + of = (struct arOffsets *)p_FmPort->deepSleepVars.autoResOffsets;
57704 + IOMemSet32(ArCommonDescPtr, 0, AR_ComputeOffsets(of, params, p_FmPort));
57705 +
57706 + // common
57707 + WRITE_UINT8(ArCommonDescPtr->arTxPort, p_FmPortTx->hardwarePortId);
57708 + nia = GET_UINT32(p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rfne); // bmi nia
57709 + if ((nia & 0x007C0000) == 0x00440000) // bmi nia is parser
57710 + WRITE_UINT32(ArCommonDescPtr->activeHPNIA, GET_UINT32(p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rfpne));
57711 + else
57712 + WRITE_UINT32(ArCommonDescPtr->activeHPNIA, nia);
57713 + WRITE_UINT16(ArCommonDescPtr->snmpPort, 161);
57714 +
57715 + // ARP
57716 + if (params->p_AutoResArpInfo)
57717 + {
57718 + t_DsarArpBindingEntry* arp_bindings;
57719 + ArpDescriptor = (t_DsarArpDescriptor*)(PTR_TO_UINT(ArCommonDescPtr) + of->arp);
57720 + WRITE_UINT32(ArCommonDescPtr->p_ArpDescriptor, PTR_TO_UINT(ArpDescriptor) - fmMuramVirtBaseAddr);
57721 + arp_bindings = (t_DsarArpBindingEntry*)(PTR_TO_UINT(ArpDescriptor) + sizeof(t_DsarArpDescriptor));
57722 + if (params->p_AutoResArpInfo->enableConflictDetection)
57723 + WRITE_UINT16(ArpDescriptor->control, 1);
57724 + else
57725 + WRITE_UINT16(ArpDescriptor->control, 0);
57726 + if (params->p_AutoResArpInfo->tableSize)
57727 + {
57728 + t_FmPortDsarArpEntry* arp_entry = params->p_AutoResArpInfo->p_AutoResTable;
57729 + WRITE_UINT16(*(uint16_t*)&ArCommonDescPtr->macStationAddr[0], *(uint16_t*)&arp_entry[0].mac[0]);
57730 + WRITE_UINT32(*(uint32_t*)&ArCommonDescPtr->macStationAddr[2], *(uint32_t*)&arp_entry[0].mac[2]);
57731 + WRITE_UINT16(ArpDescriptor->numOfBindings, params->p_AutoResArpInfo->tableSize);
57732 +
57733 + for (i = 0; i < params->p_AutoResArpInfo->tableSize; i++)
57734 + {
57735 + WRITE_UINT32(arp_bindings[i].ipv4Addr, arp_entry[i].ipAddress);
57736 + if (arp_entry[i].isVlan)
57737 + WRITE_UINT16(arp_bindings[i].vlanId, arp_entry[i].vid & 0xFFF);
57738 + }
57739 + WRITE_UINT32(ArpDescriptor->p_Bindings, PTR_TO_UINT(arp_bindings) - fmMuramVirtBaseAddr);
57740 + }
57741 + WRITE_UINT32(ArpDescriptor->p_Statistics, PTR_TO_UINT(arp_bindings) +
57742 + sizeof(t_DsarArpBindingEntry) * params->p_AutoResArpInfo->tableSize - fmMuramVirtBaseAddr);
57743 + }
57744 +
57745 + // ICMPV4
57746 + if (params->p_AutoResEchoIpv4Info)
57747 + {
57748 + t_DsarIcmpV4BindingEntry* icmpv4_bindings;
57749 + ICMPV4Descriptor = (t_DsarIcmpV4Descriptor*)(PTR_TO_UINT(ArCommonDescPtr) + of->icmpv4);
57750 + WRITE_UINT32(ArCommonDescPtr->p_IcmpV4Descriptor, PTR_TO_UINT(ICMPV4Descriptor) - fmMuramVirtBaseAddr);
57751 + icmpv4_bindings = (t_DsarIcmpV4BindingEntry*)(PTR_TO_UINT(ICMPV4Descriptor) + sizeof(t_DsarIcmpV4Descriptor));
57752 + WRITE_UINT16(ICMPV4Descriptor->control, 0);
57753 + if (params->p_AutoResEchoIpv4Info->tableSize)
57754 + {
57755 + t_FmPortDsarArpEntry* arp_entry = params->p_AutoResEchoIpv4Info->p_AutoResTable;
57756 + WRITE_UINT16(*(uint16_t*)&ArCommonDescPtr->macStationAddr[0], *(uint16_t*)&arp_entry[0].mac[0]);
57757 + WRITE_UINT32(*(uint32_t*)&ArCommonDescPtr->macStationAddr[2], *(uint32_t*)&arp_entry[0].mac[2]);
57758 + WRITE_UINT16(ICMPV4Descriptor->numOfBindings, params->p_AutoResEchoIpv4Info->tableSize);
57759 +
57760 + for (i = 0; i < params->p_AutoResEchoIpv4Info->tableSize; i++)
57761 + {
57762 + WRITE_UINT32(icmpv4_bindings[i].ipv4Addr, arp_entry[i].ipAddress);
57763 + if (arp_entry[i].isVlan)
57764 + WRITE_UINT16(icmpv4_bindings[i].vlanId, arp_entry[i].vid & 0xFFF);
57765 + }
57766 + WRITE_UINT32(ICMPV4Descriptor->p_Bindings, PTR_TO_UINT(icmpv4_bindings) - fmMuramVirtBaseAddr);
57767 + }
57768 + WRITE_UINT32(ICMPV4Descriptor->p_Statistics, PTR_TO_UINT(icmpv4_bindings) +
57769 + sizeof(t_DsarIcmpV4BindingEntry) * params->p_AutoResEchoIpv4Info->tableSize - fmMuramVirtBaseAddr);
57770 + }
57771 +
57772 + // ICMPV6
57773 + if (params->p_AutoResEchoIpv6Info)
57774 + {
57775 + t_DsarIcmpV6BindingEntry* icmpv6_bindings;
57776 + ICMPV6Descriptor = (t_DsarIcmpV6Descriptor*)(PTR_TO_UINT(ArCommonDescPtr) + of->icmpv6);
57777 + WRITE_UINT32(ArCommonDescPtr->p_IcmpV6Descriptor, PTR_TO_UINT(ICMPV6Descriptor) - fmMuramVirtBaseAddr);
57778 + icmpv6_bindings = (t_DsarIcmpV6BindingEntry*)(PTR_TO_UINT(ICMPV6Descriptor) + sizeof(t_DsarIcmpV6Descriptor));
57779 + WRITE_UINT16(ICMPV6Descriptor->control, 0);
57780 + if (params->p_AutoResEchoIpv6Info->tableSize)
57781 + {
57782 + t_FmPortDsarNdpEntry* ndp_entry = params->p_AutoResEchoIpv6Info->p_AutoResTable;
57783 + WRITE_UINT16(*(uint16_t*)&ArCommonDescPtr->macStationAddr[0], *(uint16_t*)&ndp_entry[0].mac[0]);
57784 + WRITE_UINT32(*(uint32_t*)&ArCommonDescPtr->macStationAddr[2], *(uint32_t*)&ndp_entry[0].mac[2]);
57785 + WRITE_UINT16(ICMPV6Descriptor->numOfBindings, params->p_AutoResEchoIpv6Info->tableSize);
57786 +
57787 + for (i = 0; i < params->p_AutoResEchoIpv6Info->tableSize; i++)
57788 + {
57789 + for (j = 0; j < 4; j++)
57790 + WRITE_UINT32(icmpv6_bindings[i].ipv6Addr[j], ndp_entry[i].ipAddress[j]);
57791 + if (ndp_entry[i].isVlan)
57792 + WRITE_UINT16(*(uint16_t*)&icmpv6_bindings[i].ipv6Addr[4], ndp_entry[i].vid & 0xFFF); // writing vlan
57793 + }
57794 + WRITE_UINT32(ICMPV6Descriptor->p_Bindings, PTR_TO_UINT(icmpv6_bindings) - fmMuramVirtBaseAddr);
57795 + }
57796 + WRITE_UINT32(ICMPV6Descriptor->p_Statistics, PTR_TO_UINT(icmpv6_bindings) +
57797 + sizeof(t_DsarIcmpV6BindingEntry) * params->p_AutoResEchoIpv6Info->tableSize - fmMuramVirtBaseAddr);
57798 + }
57799 +
57800 + // ND
57801 + if (params->p_AutoResNdpInfo)
57802 + {
57803 + t_DsarIcmpV6BindingEntry* icmpv6_bindings;
57804 + NDDescriptor = (t_DsarNdDescriptor*)(PTR_TO_UINT(ArCommonDescPtr) + of->nd);
57805 + WRITE_UINT32(ArCommonDescPtr->p_NdDescriptor, PTR_TO_UINT(NDDescriptor) - fmMuramVirtBaseAddr);
57806 + icmpv6_bindings = (t_DsarIcmpV6BindingEntry*)(PTR_TO_UINT(NDDescriptor) + sizeof(t_DsarNdDescriptor));
57807 + if (params->p_AutoResNdpInfo->enableConflictDetection)
57808 + WRITE_UINT16(NDDescriptor->control, 1);
57809 + else
57810 + WRITE_UINT16(NDDescriptor->control, 0);
57811 + if (params->p_AutoResNdpInfo->tableSizeAssigned + params->p_AutoResNdpInfo->tableSizeTmp)
57812 + {
57813 + t_FmPortDsarNdpEntry* ndp_entry = params->p_AutoResNdpInfo->p_AutoResTableAssigned;
57814 + WRITE_UINT16(*(uint16_t*)&ArCommonDescPtr->macStationAddr[0], *(uint16_t*)&ndp_entry[0].mac[0]);
57815 + WRITE_UINT32(*(uint32_t*)&ArCommonDescPtr->macStationAddr[2], *(uint32_t*)&ndp_entry[0].mac[2]);
57816 + WRITE_UINT16(NDDescriptor->numOfBindings, params->p_AutoResNdpInfo->tableSizeAssigned
57817 + + params->p_AutoResNdpInfo->tableSizeTmp);
57818 +
57819 + for (i = 0; i < params->p_AutoResNdpInfo->tableSizeAssigned; i++)
57820 + {
57821 + for (j = 0; j < 4; j++)
57822 + WRITE_UINT32(icmpv6_bindings[i].ipv6Addr[j], ndp_entry[i].ipAddress[j]);
57823 + if (ndp_entry[i].isVlan)
57824 + WRITE_UINT16(*(uint16_t*)&icmpv6_bindings[i].ipv6Addr[4], ndp_entry[i].vid & 0xFFF); // writing vlan
57825 + }
57826 + ndp_entry = params->p_AutoResNdpInfo->p_AutoResTableTmp;
57827 + for (i = 0; i < params->p_AutoResNdpInfo->tableSizeTmp; i++)
57828 + {
57829 + for (j = 0; j < 4; j++)
57830 + WRITE_UINT32(icmpv6_bindings[i + params->p_AutoResNdpInfo->tableSizeAssigned].ipv6Addr[j], ndp_entry[i].ipAddress[j]);
57831 + if (ndp_entry[i].isVlan)
57832 + WRITE_UINT16(*(uint16_t*)&icmpv6_bindings[i + params->p_AutoResNdpInfo->tableSizeAssigned].ipv6Addr[4], ndp_entry[i].vid & 0xFFF); // writing vlan
57833 + }
57834 + WRITE_UINT32(NDDescriptor->p_Bindings, PTR_TO_UINT(icmpv6_bindings) - fmMuramVirtBaseAddr);
57835 + }
57836 + WRITE_UINT32(NDDescriptor->p_Statistics, PTR_TO_UINT(icmpv6_bindings) + sizeof(t_DsarIcmpV6BindingEntry)
57837 + * (params->p_AutoResNdpInfo->tableSizeAssigned + params->p_AutoResNdpInfo->tableSizeTmp)
57838 + - fmMuramVirtBaseAddr);
57839 + WRITE_UINT32(NDDescriptor->solicitedAddr, 0xFFFFFFFF);
57840 + }
57841 +
57842 + // SNMP
57843 + if (params->p_AutoResSnmpInfo)
57844 + {
57845 + t_FmPortDsarSnmpInfo *snmpSrc = params->p_AutoResSnmpInfo;
57846 + t_DsarSnmpIpv4AddrTblEntry* snmpIpv4Addr;
57847 + t_DsarSnmpIpv6AddrTblEntry* snmpIpv6Addr;
57848 + t_OidsTblEntry* snmpOid;
57849 + uint8_t *charPointer;
57850 + int len;
57851 + t_DsarSnmpDescriptor* SnmpDescriptor = (t_DsarSnmpDescriptor*)(PTR_TO_UINT(ArCommonDescPtr) + of->snmp);
57852 + WRITE_UINT32(ArCommonDescPtr->p_SnmpDescriptor, PTR_TO_UINT(SnmpDescriptor) - fmMuramVirtBaseAddr);
57853 + WRITE_UINT16(SnmpDescriptor->control, snmpSrc->control);
57854 + WRITE_UINT16(SnmpDescriptor->maxSnmpMsgLength, snmpSrc->maxSnmpMsgLength);
57855 + snmpIpv4Addr = (t_DsarSnmpIpv4AddrTblEntry*)(PTR_TO_UINT(SnmpDescriptor) + sizeof(t_DsarSnmpDescriptor));
57856 + if (snmpSrc->numOfIpv4Addresses)
57857 + {
57858 + t_FmPortDsarSnmpIpv4AddrTblEntry* snmpIpv4AddrSrc = snmpSrc->p_Ipv4AddrTbl;
57859 + WRITE_UINT16(SnmpDescriptor->numOfIpv4Addresses, snmpSrc->numOfIpv4Addresses);
57860 + for (i = 0; i < snmpSrc->numOfIpv4Addresses; i++)
57861 + {
57862 + WRITE_UINT32(snmpIpv4Addr[i].ipv4Addr, snmpIpv4AddrSrc[i].ipv4Addr);
57863 + if (snmpIpv4AddrSrc[i].isVlan)
57864 + WRITE_UINT16(snmpIpv4Addr[i].vlanId, snmpIpv4AddrSrc[i].vid & 0xFFF);
57865 + }
57866 + WRITE_UINT32(SnmpDescriptor->p_Ipv4AddrTbl, PTR_TO_UINT(snmpIpv4Addr) - fmMuramVirtBaseAddr);
57867 + }
57868 + snmpIpv6Addr = (t_DsarSnmpIpv6AddrTblEntry*)(PTR_TO_UINT(snmpIpv4Addr)
57869 + + sizeof(t_DsarSnmpIpv4AddrTblEntry) * snmpSrc->numOfIpv4Addresses);
57870 + if (snmpSrc->numOfIpv6Addresses)
57871 + {
57872 + t_FmPortDsarSnmpIpv6AddrTblEntry* snmpIpv6AddrSrc = snmpSrc->p_Ipv6AddrTbl;
57873 + WRITE_UINT16(SnmpDescriptor->numOfIpv6Addresses, snmpSrc->numOfIpv6Addresses);
57874 + for (i = 0; i < snmpSrc->numOfIpv6Addresses; i++)
57875 + {
57876 + for (j = 0; j < 4; j++)
57877 + WRITE_UINT32(snmpIpv6Addr[i].ipv6Addr[j], snmpIpv6AddrSrc[i].ipv6Addr[j]);
57878 + if (snmpIpv6AddrSrc[i].isVlan)
57879 + WRITE_UINT16(snmpIpv6Addr[i].vlanId, snmpIpv6AddrSrc[i].vid & 0xFFF);
57880 + }
57881 + WRITE_UINT32(SnmpDescriptor->p_Ipv6AddrTbl, PTR_TO_UINT(snmpIpv6Addr) - fmMuramVirtBaseAddr);
57882 + }
57883 + snmpOid = (t_OidsTblEntry*)(PTR_TO_UINT(snmpIpv6Addr)
57884 + + sizeof(t_DsarSnmpIpv6AddrTblEntry) * snmpSrc->numOfIpv6Addresses);
57885 + charPointer = (uint8_t*)(PTR_TO_UINT(snmpOid)
57886 + + sizeof(t_OidsTblEntry) * snmpSrc->oidsTblSize);
57887 + len = TOTAL_BER_LEN(GetBERLen(&snmpSrc->p_RdOnlyCommunityStr[1]));
57888 + Mem2IOCpy32(charPointer, snmpSrc->p_RdOnlyCommunityStr, len);
57889 + WRITE_UINT32(SnmpDescriptor->p_RdOnlyCommunityStr, PTR_TO_UINT(charPointer) - fmMuramVirtBaseAddr);
57890 + charPointer += len;
57891 + len = TOTAL_BER_LEN(GetBERLen(&snmpSrc->p_RdWrCommunityStr[1]));
57892 + Mem2IOCpy32(charPointer, snmpSrc->p_RdWrCommunityStr, len);
57893 + WRITE_UINT32(SnmpDescriptor->p_RdWrCommunityStr, PTR_TO_UINT(charPointer) - fmMuramVirtBaseAddr);
57894 + charPointer += len;
57895 + WRITE_UINT32(SnmpDescriptor->oidsTblSize, snmpSrc->oidsTblSize);
57896 + WRITE_UINT32(SnmpDescriptor->p_OidsTbl, PTR_TO_UINT(snmpOid) - fmMuramVirtBaseAddr);
57897 + for (i = 0; i < snmpSrc->oidsTblSize; i++)
57898 + {
57899 + WRITE_UINT16(snmpOid->oidSize, snmpSrc->p_OidsTbl[i].oidSize);
57900 + WRITE_UINT16(snmpOid->resSize, snmpSrc->p_OidsTbl[i].resSize);
57901 + Mem2IOCpy32(charPointer, snmpSrc->p_OidsTbl[i].oidVal, snmpSrc->p_OidsTbl[i].oidSize);
57902 + WRITE_UINT32(snmpOid->p_Oid, PTR_TO_UINT(charPointer) - fmMuramVirtBaseAddr);
57903 + charPointer += snmpSrc->p_OidsTbl[i].oidSize;
57904 + if (snmpSrc->p_OidsTbl[i].resSize <= 4)
57905 + WRITE_UINT32(snmpOid->resValOrPtr, *snmpSrc->p_OidsTbl[i].resVal);
57906 + else
57907 + {
57908 + Mem2IOCpy32(charPointer, snmpSrc->p_OidsTbl[i].resVal, snmpSrc->p_OidsTbl[i].resSize);
57909 + WRITE_UINT32(snmpOid->resValOrPtr, PTR_TO_UINT(charPointer) - fmMuramVirtBaseAddr);
57910 + charPointer += snmpSrc->p_OidsTbl[i].resSize;
57911 + }
57912 + snmpOid++;
57913 + }
57914 + charPointer = UINT_TO_PTR(ROUND_UP(PTR_TO_UINT(charPointer),4));
57915 + WRITE_UINT32(SnmpDescriptor->p_Statistics, PTR_TO_UINT(charPointer) - fmMuramVirtBaseAddr);
57916 + }
57917 +
57918 + // filtering
57919 + if (params->p_AutoResFilteringInfo)
57920 + {
57921 + if (params->p_AutoResFilteringInfo->ipProtPassOnHit)
57922 + tmp |= IP_PROT_TBL_PASS_MASK;
57923 + if (params->p_AutoResFilteringInfo->udpPortPassOnHit)
57924 + tmp |= UDP_PORT_TBL_PASS_MASK;
57925 + if (params->p_AutoResFilteringInfo->tcpPortPassOnHit)
57926 + tmp |= TCP_PORT_TBL_PASS_MASK;
57927 + WRITE_UINT8(ArCommonDescPtr->filterControl, tmp);
57928 + WRITE_UINT16(ArCommonDescPtr->tcpControlPass, params->p_AutoResFilteringInfo->tcpFlagsMask);
57929 +
57930 + // ip filtering
57931 + if (params->p_AutoResFilteringInfo->ipProtTableSize)
57932 + {
57933 + uint8_t* ip_tbl = (uint8_t*)(PTR_TO_UINT(ArCommonDescPtr) + of->filtIp);
57934 + WRITE_UINT8(ArCommonDescPtr->ipProtocolTblSize, params->p_AutoResFilteringInfo->ipProtTableSize);
57935 + for (i = 0; i < params->p_AutoResFilteringInfo->ipProtTableSize; i++)
57936 + WRITE_UINT8(ip_tbl[i], params->p_AutoResFilteringInfo->p_IpProtTablePtr[i]);
57937 + WRITE_UINT32(ArCommonDescPtr->p_IpProtocolFiltTbl, PTR_TO_UINT(ip_tbl) - fmMuramVirtBaseAddr);
57938 + }
57939 +
57940 + // udp filtering
57941 + if (params->p_AutoResFilteringInfo->udpPortsTableSize)
57942 + {
57943 + t_PortTblEntry* udp_tbl = (t_PortTblEntry*)(PTR_TO_UINT(ArCommonDescPtr) + of->filtUdp);
57944 + WRITE_UINT8(ArCommonDescPtr->udpPortTblSize, params->p_AutoResFilteringInfo->udpPortsTableSize);
57945 + for (i = 0; i < params->p_AutoResFilteringInfo->udpPortsTableSize; i++)
57946 + {
57947 + WRITE_UINT32(udp_tbl[i].Ports,
57948 + (params->p_AutoResFilteringInfo->p_UdpPortsTablePtr[i].srcPort << 16) +
57949 + params->p_AutoResFilteringInfo->p_UdpPortsTablePtr[i].dstPort);
57950 + WRITE_UINT32(udp_tbl[i].PortsMask,
57951 + (params->p_AutoResFilteringInfo->p_UdpPortsTablePtr[i].srcPortMask << 16) +
57952 + params->p_AutoResFilteringInfo->p_UdpPortsTablePtr[i].dstPortMask);
57953 + }
57954 + WRITE_UINT32(ArCommonDescPtr->p_UdpPortFiltTbl, PTR_TO_UINT(udp_tbl) - fmMuramVirtBaseAddr);
57955 + }
57956 +
57957 + // tcp filtering
57958 + if (params->p_AutoResFilteringInfo->tcpPortsTableSize)
57959 + {
57960 + t_PortTblEntry* tcp_tbl = (t_PortTblEntry*)(PTR_TO_UINT(ArCommonDescPtr) + of->filtTcp);
57961 + WRITE_UINT8(ArCommonDescPtr->tcpPortTblSize, params->p_AutoResFilteringInfo->tcpPortsTableSize);
57962 + for (i = 0; i < params->p_AutoResFilteringInfo->tcpPortsTableSize; i++)
57963 + {
57964 + WRITE_UINT32(tcp_tbl[i].Ports,
57965 + (params->p_AutoResFilteringInfo->p_TcpPortsTablePtr[i].srcPort << 16) +
57966 + params->p_AutoResFilteringInfo->p_TcpPortsTablePtr[i].dstPort);
57967 + WRITE_UINT32(tcp_tbl[i].PortsMask,
57968 + (params->p_AutoResFilteringInfo->p_TcpPortsTablePtr[i].srcPortMask << 16) +
57969 + params->p_AutoResFilteringInfo->p_TcpPortsTablePtr[i].dstPortMask);
57970 + }
57971 + WRITE_UINT32(ArCommonDescPtr->p_TcpPortFiltTbl, PTR_TO_UINT(tcp_tbl) - fmMuramVirtBaseAddr);
57972 + }
57973 + }
57974 + // common stats
57975 + WRITE_UINT32(ArCommonDescPtr->p_ArStats, PTR_TO_UINT(ArCommonDescPtr) + of->stats - fmMuramVirtBaseAddr);
57976 +
57977 + // get into Deep Sleep sequence:
57978 +
57979 + // Ensures that FMan do not enter the idle state. This is done by programing
57980 + // FMDPSLPCR[FM_STOP] to one.
57981 + fm_soc_suspend();
57982 +
57983 + ARDesc = UINT_TO_PTR(XX_VirtToPhys(ArCommonDescPtr));
57984 + return E_OK;
57985 +
57986 +}
57987 +
57988 +void FM_ChangeClock(t_Handle h_Fm, int hardwarePortId);
57989 +t_Error FM_PORT_EnterDsarFinal(t_Handle h_DsarRxPort, t_Handle h_DsarTxPort)
57990 +{
57991 + t_FmGetSetParams fmGetSetParams;
57992 + t_FmPort *p_FmPort = (t_FmPort *)h_DsarRxPort;
57993 + t_FmPort *p_FmPortTx = (t_FmPort *)h_DsarTxPort;
57994 + t_Handle *h_FmPcd = FmGetPcd(p_FmPort->h_Fm);
57995 + t_FmPort *p_FmPortHc = FM_PCD_GetHcPort(h_FmPcd);
57996 + memset(&fmGetSetParams, 0, sizeof (t_FmGetSetParams));
57997 + fmGetSetParams.setParams.type = UPDATE_FM_CLD;
57998 + FmGetSetParams(p_FmPort->h_Fm, &fmGetSetParams);
57999 +
58000 + /* Issue graceful stop to HC port */
58001 + FM_PORT_Disable(p_FmPortHc);
58002 +
58003 + // config tx port
58004 + p_FmPort->deepSleepVars.fmbm_tcfg = GET_UINT32(p_FmPortTx->p_FmPortBmiRegs->txPortBmiRegs.fmbm_tcfg);
58005 + 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);
58006 + // ????
58007 + p_FmPort->deepSleepVars.fmbm_tcmne = GET_UINT32(p_FmPortTx->p_FmPortBmiRegs->txPortBmiRegs.fmbm_tcmne);
58008 + WRITE_UINT32(p_FmPortTx->p_FmPortBmiRegs->txPortBmiRegs.fmbm_tcmne, 0xE);
58009 + // Stage 7:echo
58010 + p_FmPort->deepSleepVars.fmbm_rfpne = GET_UINT32(p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rfpne);
58011 + WRITE_UINT32(p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rfpne, 0x2E);
58012 + if (!PrsIsEnabled(h_FmPcd))
58013 + {
58014 + p_FmPort->deepSleepVars.dsarEnabledParser = TRUE;
58015 + PrsEnable(h_FmPcd);
58016 + }
58017 + else
58018 + p_FmPort->deepSleepVars.dsarEnabledParser = FALSE;
58019 +
58020 + p_FmPort->deepSleepVars.fmbm_rfne = GET_UINT32(p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rfne);
58021 + WRITE_UINT32(p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rfne, 0x440000);
58022 +
58023 + // save rcfg for restoring: accumulate mode is changed by ucode
58024 + p_FmPort->deepSleepVars.fmbm_rcfg = GET_UINT32(p_FmPort->port.bmi_regs->rx.fmbm_rcfg);
58025 + WRITE_UINT32(p_FmPort->port.bmi_regs->rx.fmbm_rcfg, p_FmPort->deepSleepVars.fmbm_rcfg | BMI_PORT_CFG_AM);
58026 + memset(&fmGetSetParams, 0, sizeof (t_FmGetSetParams));
58027 + fmGetSetParams.setParams.type = UPDATE_FPM_BRKC_SLP;
58028 + fmGetSetParams.setParams.sleep = 1;
58029 + FmGetSetParams(p_FmPort->h_Fm, &fmGetSetParams);
58030 +
58031 +// ***** issue external request sync command
58032 + memset(&fmGetSetParams, 0, sizeof (t_FmGetSetParams));
58033 + fmGetSetParams.setParams.type = UPDATE_FPM_EXTC;
58034 + FmGetSetParams(p_FmPort->h_Fm, &fmGetSetParams);
58035 + // get
58036 + memset(&fmGetSetParams, 0, sizeof (t_FmGetSetParams));
58037 + fmGetSetParams.getParams.type = GET_FMFP_EXTC;
58038 + FmGetSetParams(p_FmPort->h_Fm, &fmGetSetParams);
58039 + if (fmGetSetParams.getParams.fmfp_extc != 0)
58040 + {
58041 + // clear
58042 + memset(&fmGetSetParams, 0, sizeof (t_FmGetSetParams));
58043 + fmGetSetParams.setParams.type = UPDATE_FPM_EXTC_CLEAR;
58044 + FmGetSetParams(p_FmPort->h_Fm, &fmGetSetParams);
58045 +}
58046 +
58047 + memset(&fmGetSetParams, 0, sizeof (t_FmGetSetParams));
58048 + fmGetSetParams.getParams.type = GET_FMFP_EXTC | GET_FM_NPI;
58049 + do
58050 + {
58051 + FmGetSetParams(p_FmPort->h_Fm, &fmGetSetParams);
58052 + } while (fmGetSetParams.getParams.fmfp_extc != 0 && fmGetSetParams.getParams.fm_npi == 0);
58053 + if (fmGetSetParams.getParams.fm_npi != 0)
58054 + XX_Print("FM: Sync did not finish\n");
58055 +
58056 + // check that all stoped
58057 + memset(&fmGetSetParams, 0, sizeof (t_FmGetSetParams));
58058 + fmGetSetParams.getParams.type = GET_FMQM_GS | GET_FM_NPI;
58059 + FmGetSetParams(p_FmPort->h_Fm, &fmGetSetParams);
58060 + while (fmGetSetParams.getParams.fmqm_gs & 0xF0000000)
58061 + FmGetSetParams(p_FmPort->h_Fm, &fmGetSetParams);
58062 + if (fmGetSetParams.getParams.fmqm_gs == 0 && fmGetSetParams.getParams.fm_npi == 0)
58063 + XX_Print("FM: Sleeping\n");
58064 +// FM_ChangeClock(p_FmPort->h_Fm, p_FmPort->hardwarePortId);
58065 +
58066 + return E_OK;
58067 +}
58068 +
58069 +EXPORT_SYMBOL(FM_PORT_EnterDsarFinal);
58070 +
58071 +void FM_PORT_Dsar_DumpRegs()
58072 +{
58073 + uint32_t* hh = XX_PhysToVirt(PTR_TO_UINT(ARDesc));
58074 + DUMP_MEMORY(hh, 0x220);
58075 +}
58076 +
58077 +void FM_PORT_ExitDsar(t_Handle h_FmPortRx, t_Handle h_FmPortTx)
58078 +{
58079 + t_FmPort *p_FmPort = (t_FmPort *)h_FmPortRx;
58080 + t_FmPort *p_FmPortTx = (t_FmPort *)h_FmPortTx;
58081 + t_Handle *h_FmPcd = FmGetPcd(p_FmPort->h_Fm);
58082 + t_FmPort *p_FmPortHc = FM_PCD_GetHcPort(h_FmPcd);
58083 + t_FmGetSetParams fmGetSetParams;
58084 + memset(&fmGetSetParams, 0, sizeof (t_FmGetSetParams));
58085 + fmGetSetParams.setParams.type = UPDATE_FPM_BRKC_SLP;
58086 + fmGetSetParams.setParams.sleep = 0;
58087 + if (p_FmPort->deepSleepVars.autoResOffsets)
58088 + {
58089 + XX_Free(p_FmPort->deepSleepVars.autoResOffsets);
58090 + p_FmPort->deepSleepVars.autoResOffsets = 0;
58091 + }
58092 +
58093 + if (p_FmPort->deepSleepVars.dsarEnabledParser)
58094 + PrsDisable(FmGetPcd(p_FmPort->h_Fm));
58095 + WRITE_UINT32(p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rfpne, p_FmPort->deepSleepVars.fmbm_rfpne);
58096 + WRITE_UINT32(p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rfne, p_FmPort->deepSleepVars.fmbm_rfne);
58097 + WRITE_UINT32(p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rcfg, p_FmPort->deepSleepVars.fmbm_rcfg);
58098 + FmGetSetParams(p_FmPort->h_Fm, &fmGetSetParams);
58099 + WRITE_UINT32(p_FmPortTx->p_FmPortBmiRegs->txPortBmiRegs.fmbm_tcmne, p_FmPort->deepSleepVars.fmbm_tcmne);
58100 + WRITE_UINT32(p_FmPortTx->p_FmPortBmiRegs->txPortBmiRegs.fmbm_tcfg, p_FmPort->deepSleepVars.fmbm_tcfg);
58101 + FM_PORT_Enable(p_FmPortHc);
58102 +}
58103 +
58104 +bool FM_PORT_IsInDsar(t_Handle h_FmPort)
58105 +{
58106 + t_FmPort *p_FmPort = (t_FmPort *)h_FmPort;
58107 + return PTR_TO_UINT(p_FmPort->deepSleepVars.autoResOffsets);
58108 +}
58109 +
58110 +t_Error FM_PORT_GetDsarStats(t_Handle h_FmPortRx, t_FmPortDsarStats *stats)
58111 +{
58112 + t_FmPort *p_FmPort = (t_FmPort *)h_FmPortRx;
58113 + struct arOffsets *of = (struct arOffsets*)p_FmPort->deepSleepVars.autoResOffsets;
58114 + uint8_t* fmMuramVirtBaseAddr = XX_PhysToVirt(p_FmPort->fmMuramPhysBaseAddr);
58115 + uint32_t *param_page = XX_PhysToVirt(p_FmPort->fmMuramPhysBaseAddr + GET_UINT32(p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rgpr));
58116 + t_ArCommonDesc *ArCommonDescPtr = (t_ArCommonDesc*)(XX_PhysToVirt(p_FmPort->fmMuramPhysBaseAddr + GET_UINT32(*param_page)));
58117 + t_DsarArpDescriptor *ArpDescriptor = (t_DsarArpDescriptor*)(PTR_TO_UINT(ArCommonDescPtr) + of->arp);
58118 + t_DsarArpStatistics* arp_stats = (t_DsarArpStatistics*)(PTR_TO_UINT(ArpDescriptor->p_Statistics) + fmMuramVirtBaseAddr);
58119 + t_DsarIcmpV4Descriptor* ICMPV4Descriptor = (t_DsarIcmpV4Descriptor*)(PTR_TO_UINT(ArCommonDescPtr) + of->icmpv4);
58120 + t_DsarIcmpV4Statistics* icmpv4_stats = (t_DsarIcmpV4Statistics*)(PTR_TO_UINT(ICMPV4Descriptor->p_Statistics) + fmMuramVirtBaseAddr);
58121 + t_DsarNdDescriptor* NDDescriptor = (t_DsarNdDescriptor*)(PTR_TO_UINT(ArCommonDescPtr) + of->nd);
58122 + t_NdStatistics* nd_stats = (t_NdStatistics*)(PTR_TO_UINT(NDDescriptor->p_Statistics) + fmMuramVirtBaseAddr);
58123 + t_DsarIcmpV6Descriptor* ICMPV6Descriptor = (t_DsarIcmpV6Descriptor*)(PTR_TO_UINT(ArCommonDescPtr) + of->icmpv6);
58124 + t_DsarIcmpV6Statistics* icmpv6_stats = (t_DsarIcmpV6Statistics*)(PTR_TO_UINT(ICMPV6Descriptor->p_Statistics) + fmMuramVirtBaseAddr);
58125 + t_DsarSnmpDescriptor* SnmpDescriptor = (t_DsarSnmpDescriptor*)(PTR_TO_UINT(ArCommonDescPtr) + of->snmp);
58126 + t_DsarSnmpStatistics* snmp_stats = (t_DsarSnmpStatistics*)(PTR_TO_UINT(SnmpDescriptor->p_Statistics) + fmMuramVirtBaseAddr);
58127 + stats->arpArCnt = arp_stats->arCnt;
58128 + stats->echoIcmpv4ArCnt = icmpv4_stats->arCnt;
58129 + stats->ndpArCnt = nd_stats->arCnt;
58130 + stats->echoIcmpv6ArCnt = icmpv6_stats->arCnt;
58131 + stats->snmpGetCnt = snmp_stats->snmpGetReqCnt;
58132 + stats->snmpGetNextCnt = snmp_stats->snmpGetNextReqCnt;
58133 + return E_OK;
58134 +}
58135 --- /dev/null
58136 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Port/fm_port.h
58137 @@ -0,0 +1,999 @@
58138 +/*
58139 + * Copyright 2008-2012 Freescale Semiconductor Inc.
58140 + *
58141 + * Redistribution and use in source and binary forms, with or without
58142 + * modification, are permitted provided that the following conditions are met:
58143 + * * Redistributions of source code must retain the above copyright
58144 + * notice, this list of conditions and the following disclaimer.
58145 + * * Redistributions in binary form must reproduce the above copyright
58146 + * notice, this list of conditions and the following disclaimer in the
58147 + * documentation and/or other materials provided with the distribution.
58148 + * * Neither the name of Freescale Semiconductor nor the
58149 + * names of its contributors may be used to endorse or promote products
58150 + * derived from this software without specific prior written permission.
58151 + *
58152 + *
58153 + * ALTERNATIVELY, this software may be distributed under the terms of the
58154 + * GNU General Public License ("GPL") as published by the Free Software
58155 + * Foundation, either version 2 of that License or (at your option) any
58156 + * later version.
58157 + *
58158 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
58159 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
58160 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
58161 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
58162 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
58163 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
58164 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
58165 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
58166 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
58167 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
58168 + */
58169 +
58170 +
58171 +/******************************************************************************
58172 + @File fm_port.h
58173 +
58174 + @Description FM Port internal structures and definitions.
58175 +*//***************************************************************************/
58176 +#ifndef __FM_PORT_H
58177 +#define __FM_PORT_H
58178 +
58179 +#include "error_ext.h"
58180 +#include "std_ext.h"
58181 +#include "fm_port_ext.h"
58182 +
58183 +#include "fm_common.h"
58184 +#include "fm_sp_common.h"
58185 +#include "fsl_fman_sp.h"
58186 +#include "fm_port_ext.h"
58187 +#include "fsl_fman_port.h"
58188 +
58189 +#define __ERR_MODULE__ MODULE_FM_PORT
58190 +
58191 +
58192 +#define MIN_EXT_BUF_SIZE 64
58193 +#define DATA_ALIGNMENT 64
58194 +#define MAX_LIODN_OFFSET 64
58195 +#define MAX_PORT_FIFO_SIZE MIN(BMI_MAX_FIFO_SIZE, 1024*BMI_FIFO_UNITS)
58196 +
58197 +/**************************************************************************//**
58198 + @Description Memory Map defines
58199 +*//***************************************************************************/
58200 +#define BMI_PORT_REGS_OFFSET 0
58201 +#define QMI_PORT_REGS_OFFSET 0x400
58202 +#define PRS_PORT_REGS_OFFSET 0x800
58203 +
58204 +/**************************************************************************//**
58205 + @Description defaults
58206 +*//***************************************************************************/
58207 +#define DEFAULT_PORT_deqHighPriority_1G FALSE
58208 +#define DEFAULT_PORT_deqHighPriority_10G TRUE
58209 +#define DEFAULT_PORT_deqType e_FM_PORT_DEQ_TYPE1
58210 +#define DEFAULT_PORT_deqPrefetchOption e_FM_PORT_DEQ_FULL_PREFETCH
58211 +#define DEFAULT_PORT_deqPrefetchOption_HC e_FM_PORT_DEQ_NO_PREFETCH
58212 +#define DEFAULT_PORT_deqByteCnt_10G 0x1400
58213 +#define DEFAULT_PORT_deqByteCnt_1G 0x400
58214 +#define DEFAULT_PORT_bufferPrefixContent_privDataSize DEFAULT_FM_SP_bufferPrefixContent_privDataSize
58215 +#define DEFAULT_PORT_bufferPrefixContent_passPrsResult DEFAULT_FM_SP_bufferPrefixContent_passPrsResult
58216 +#define DEFAULT_PORT_bufferPrefixContent_passTimeStamp DEFAULT_FM_SP_bufferPrefixContent_passTimeStamp
58217 +#define DEFAULT_PORT_bufferPrefixContent_allOtherPCDInfo DEFAULT_FM_SP_bufferPrefixContent_allOtherPCDInfo
58218 +#define DEFAULT_PORT_bufferPrefixContent_dataAlign DEFAULT_FM_SP_bufferPrefixContent_dataAlign
58219 +#define DEFAULT_PORT_cheksumLastBytesIgnore 0
58220 +#define DEFAULT_PORT_cutBytesFromEnd 4
58221 +#define DEFAULT_PORT_fifoDeqPipelineDepth_IM 2
58222 +
58223 +#define DEFAULT_PORT_frmDiscardOverride FALSE
58224 +
58225 +#define DEFAULT_PORT_dmaSwapData (e_FmDmaSwapOption)DEFAULT_FMAN_SP_DMA_SWAP_DATA
58226 +#define DEFAULT_PORT_dmaIntContextCacheAttr (e_FmDmaCacheOption)DEFAULT_FMAN_SP_DMA_INT_CONTEXT_CACHE_ATTR
58227 +#define DEFAULT_PORT_dmaHeaderCacheAttr (e_FmDmaCacheOption)DEFAULT_FMAN_SP_DMA_HEADER_CACHE_ATTR
58228 +#define DEFAULT_PORT_dmaScatterGatherCacheAttr (e_FmDmaCacheOption)DEFAULT_FMAN_SP_DMA_SCATTER_GATHER_CACHE_ATTR
58229 +#define DEFAULT_PORT_dmaWriteOptimize DEFAULT_FMAN_SP_DMA_WRITE_OPTIMIZE
58230 +
58231 +#define DEFAULT_PORT_noScatherGather DEFAULT_FMAN_SP_NO_SCATTER_GATHER
58232 +#define DEFAULT_PORT_forwardIntContextReuse FALSE
58233 +#define DEFAULT_PORT_BufMargins_startMargins 32
58234 +#define DEFAULT_PORT_BufMargins_endMargins 0
58235 +#define DEFAULT_PORT_syncReq TRUE
58236 +#define DEFAULT_PORT_syncReqForHc FALSE
58237 +#define DEFAULT_PORT_color e_FM_PORT_COLOR_GREEN
58238 +#define DEFAULT_PORT_errorsToDiscard FM_PORT_FRM_ERR_CLS_DISCARD
58239 +/* #define DEFAULT_PORT_dualRateLimitScaleDown e_FM_PORT_DUAL_RATE_LIMITER_NONE */
58240 +/* #define DEFAULT_PORT_rateLimitBurstSizeHighGranularity FALSE */
58241 +#define DEFAULT_PORT_exception IM_EV_BSY
58242 +#define DEFAULT_PORT_maxFrameLength 9600
58243 +
58244 +#define DEFAULT_notSupported 0xff
58245 +
58246 +#if (DPAA_VERSION < 11)
58247 +#define DEFAULT_PORT_rxFifoPriElevationLevel MAX_PORT_FIFO_SIZE
58248 +#define DEFAULT_PORT_rxFifoThreshold (MAX_PORT_FIFO_SIZE*3/4)
58249 +
58250 +#define DEFAULT_PORT_txFifoMinFillLevel 0
58251 +#define DEFAULT_PORT_txFifoLowComfLevel (5*KILOBYTE)
58252 +#define DEFAULT_PORT_fifoDeqPipelineDepth_1G 1
58253 +#define DEFAULT_PORT_fifoDeqPipelineDepth_10G 4
58254 +
58255 +#define DEFAULT_PORT_fifoDeqPipelineDepth_OH 2
58256 +
58257 +/* Host command port MUST NOT be changed to more than 1 !!! */
58258 +#define DEFAULT_PORT_numOfTasks(type) \
58259 + (uint32_t)((((type) == e_FM_PORT_TYPE_RX_10G) || \
58260 + ((type) == e_FM_PORT_TYPE_TX_10G)) ? 16 : \
58261 + ((((type) == e_FM_PORT_TYPE_RX) || \
58262 + ((type) == e_FM_PORT_TYPE_TX) || \
58263 + ((type) == e_FM_PORT_TYPE_OH_OFFLINE_PARSING)) ? 3 : 1))
58264 +
58265 +#define DEFAULT_PORT_extraNumOfTasks(type) \
58266 + (uint32_t)(((type) == e_FM_PORT_TYPE_RX_10G) ? 8 : \
58267 + (((type) == e_FM_PORT_TYPE_RX) ? 2 : 0))
58268 +
58269 +#define DEFAULT_PORT_numOfOpenDmas(type) \
58270 + (uint32_t)((((type) == e_FM_PORT_TYPE_TX_10G) || \
58271 + ((type) == e_FM_PORT_TYPE_RX_10G)) ? 8 : 1 )
58272 +
58273 +#define DEFAULT_PORT_extraNumOfOpenDmas(type) \
58274 + (uint32_t)(((type) == e_FM_PORT_TYPE_RX_10G) ? 8 : \
58275 + (((type) == e_FM_PORT_TYPE_RX) ? 1 : 0))
58276 +
58277 +#define DEFAULT_PORT_numOfFifoBufs(type) \
58278 + (uint32_t)((((type) == e_FM_PORT_TYPE_RX_10G) || \
58279 + ((type) == e_FM_PORT_TYPE_TX_10G)) ? 48 : \
58280 + ((type) == e_FM_PORT_TYPE_RX) ? 45 : \
58281 + ((type) == e_FM_PORT_TYPE_TX) ? 44 : 8)
58282 +
58283 +#define DEFAULT_PORT_extraNumOfFifoBufs 0
58284 +
58285 +#else /* (DPAA_VERSION < 11) */
58286 +/* Defaults are registers' reset values */
58287 +#define DEFAULT_PORT_rxFifoPriElevationLevel MAX_PORT_FIFO_SIZE
58288 +#define DEFAULT_PORT_rxFifoThreshold MAX_PORT_FIFO_SIZE
58289 +
58290 +#define DEFAULT_PORT_txFifoMinFillLevel 0
58291 +#define DEFAULT_PORT_txFifoLowComfLevel (5 * KILOBYTE)
58292 +#define DEFAULT_PORT_fifoDeqPipelineDepth_1G 2
58293 +#define DEFAULT_PORT_fifoDeqPipelineDepth_10G 4
58294 +
58295 +#define DEFAULT_PORT_fifoDeqPipelineDepth_OH 2
58296 +
58297 +#define DEFAULT_PORT_numOfTasks(type) \
58298 + (uint32_t)((((type) == e_FM_PORT_TYPE_RX_10G) || \
58299 + ((type) == e_FM_PORT_TYPE_TX_10G)) ? 14 : \
58300 + (((type) == e_FM_PORT_TYPE_RX) || \
58301 + ((type) == e_FM_PORT_TYPE_TX)) ? 4 : \
58302 + ((type) == e_FM_PORT_TYPE_OH_OFFLINE_PARSING) ? 6 : 1)
58303 +
58304 +#define DEFAULT_PORT_extraNumOfTasks(type) 0
58305 +
58306 +#define DEFAULT_PORT_numOfOpenDmas(type) \
58307 + (uint32_t)(((type) == e_FM_PORT_TYPE_RX_10G) ? 8 : \
58308 + ((type) == e_FM_PORT_TYPE_TX_10G) ? 12 : \
58309 + ((type) == e_FM_PORT_TYPE_RX) ? 2 : \
58310 + ((type) == e_FM_PORT_TYPE_TX) ? 3 : \
58311 + ((type) == e_FM_PORT_TYPE_OH_HOST_COMMAND) ? 2 : 4)
58312 +
58313 +#define DEFAULT_PORT_extraNumOfOpenDmas(type) 0
58314 +
58315 +#define DEFAULT_PORT_numOfFifoBufs(type) \
58316 + (uint32_t) (((type) == e_FM_PORT_TYPE_RX_10G) ? 96 : \
58317 + ((type) == e_FM_PORT_TYPE_TX_10G) ? 64 : \
58318 + ((type) == e_FM_PORT_TYPE_OH_HOST_COMMAND) ? 10 : 50)
58319 +
58320 +#define DEFAULT_PORT_extraNumOfFifoBufs 0
58321 +
58322 +#endif /* (DPAA_VERSION < 11) */
58323 +
58324 +#define DEFAULT_PORT_txBdRingLength 16
58325 +#define DEFAULT_PORT_rxBdRingLength 128
58326 +#define DEFAULT_PORT_ImfwExtStructsMemId 0
58327 +#define DEFAULT_PORT_ImfwExtStructsMemAttr MEMORY_ATTR_CACHEABLE
58328 +
58329 +#define FM_PORT_CG_REG_NUM(_cgId) (((FM_PORT_NUM_OF_CONGESTION_GRPS/32)-1)-_cgId/32)
58330 +
58331 +/**************************************************************************//**
58332 + @Collection PCD Engines
58333 +*//***************************************************************************/
58334 +typedef uint32_t fmPcdEngines_t; /**< options as defined below: */
58335 +
58336 +#define FM_PCD_NONE 0 /**< No PCD Engine indicated */
58337 +#define FM_PCD_PRS 0x80000000 /**< Parser indicated */
58338 +#define FM_PCD_KG 0x40000000 /**< Keygen indicated */
58339 +#define FM_PCD_CC 0x20000000 /**< Coarse classification indicated */
58340 +#define FM_PCD_PLCR 0x10000000 /**< Policer indicated */
58341 +#define FM_PCD_MANIP 0x08000000 /**< Manipulation indicated */
58342 +/* @} */
58343 +
58344 +#define FM_PORT_MAX_NUM_OF_EXT_POOLS_ALL_INTEGRATIONS 8
58345 +#define FM_PORT_MAX_NUM_OF_CONGESTION_GRPS_ALL_INTEGRATIONS 256
58346 +#define FM_PORT_CG_REG_NUM(_cgId) (((FM_PORT_NUM_OF_CONGESTION_GRPS/32)-1)-_cgId/32)
58347 +
58348 +#define FM_OH_PORT_ID 0
58349 +
58350 +/***********************************************************************/
58351 +/* SW parser OFFLOAD labels (offsets) */
58352 +/***********************************************************************/
58353 +#if (DPAA_VERSION == 10)
58354 +#define OFFLOAD_SW_PATCH_IPv4_IPR_LABEL 0x300
58355 +#define OFFLOAD_SW_PATCH_IPv6_IPR_LABEL 0x325
58356 +#define OFFLOAD_SW_PATCH_IPv6_IPF_LABEL 0x325
58357 +#else
58358 +#define OFFLOAD_SW_PATCH_IPv4_IPR_LABEL 0x100
58359 +/* Will be used for:
58360 + * 1. identify fragments
58361 + * 2. udp-lite
58362 + */
58363 +#define OFFLOAD_SW_PATCH_IPv6_IPR_LABEL 0x146
58364 +/* Will be used for:
58365 + * 1. will identify the fragmentable area
58366 + * 2. udp-lite
58367 + */
58368 +#define OFFLOAD_SW_PATCH_IPv6_IPF_LABEL 0x261
58369 +#define OFFLOAD_SW_PATCH_CAPWAP_LABEL 0x38d
58370 +#endif /* (DPAA_VERSION == 10) */
58371 +
58372 +#if ((DPAA_VERSION == 10) && defined(FM_CAPWAP_SUPPORT))
58373 +#define UDP_LITE_SW_PATCH_LABEL 0x2E0
58374 +#endif /* ((DPAA_VERSION == 10) && defined(FM_CAPWAP_SUPPORT)) */
58375 +
58376 +
58377 +/**************************************************************************//**
58378 + @Description Memory Mapped Registers
58379 +*//***************************************************************************/
58380 +
58381 +#if defined(__MWERKS__) && !defined(__GNUC__)
58382 +#pragma pack(push,1)
58383 +#endif /* defined(__MWERKS__) && ... */
58384 +
58385 +typedef struct
58386 +{
58387 + volatile uint32_t fmbm_rcfg; /**< Rx Configuration */
58388 + volatile uint32_t fmbm_rst; /**< Rx Status */
58389 + volatile uint32_t fmbm_rda; /**< Rx DMA attributes*/
58390 + volatile uint32_t fmbm_rfp; /**< Rx FIFO Parameters*/
58391 + volatile uint32_t fmbm_rfed; /**< Rx Frame End Data*/
58392 + volatile uint32_t fmbm_ricp; /**< Rx Internal Context Parameters*/
58393 + volatile uint32_t fmbm_rim; /**< Rx Internal Buffer Margins*/
58394 + volatile uint32_t fmbm_rebm; /**< Rx External Buffer Margins*/
58395 + volatile uint32_t fmbm_rfne; /**< Rx Frame Next Engine*/
58396 + volatile uint32_t fmbm_rfca; /**< Rx Frame Command Attributes.*/
58397 + volatile uint32_t fmbm_rfpne; /**< Rx Frame Parser Next Engine*/
58398 + volatile uint32_t fmbm_rpso; /**< Rx Parse Start Offset*/
58399 + volatile uint32_t fmbm_rpp; /**< Rx Policer Profile */
58400 + volatile uint32_t fmbm_rccb; /**< Rx Coarse Classification Base */
58401 + volatile uint32_t fmbm_reth; /**< Rx Excessive Threshold */
58402 + volatile uint32_t reserved1[0x01];/**< (0x03C) */
58403 + volatile uint32_t fmbm_rprai[FM_PORT_PRS_RESULT_NUM_OF_WORDS];
58404 + /**< Rx Parse Results Array Initialization*/
58405 + volatile uint32_t fmbm_rfqid; /**< Rx Frame Queue ID*/
58406 + volatile uint32_t fmbm_refqid; /**< Rx Error Frame Queue ID*/
58407 + volatile uint32_t fmbm_rfsdm; /**< Rx Frame Status Discard Mask*/
58408 + volatile uint32_t fmbm_rfsem; /**< Rx Frame Status Error Mask*/
58409 + volatile uint32_t fmbm_rfene; /**< Rx Frame Enqueue Next Engine */
58410 + volatile uint32_t reserved2[0x02];/**< (0x074-0x078) */
58411 + volatile uint32_t fmbm_rcmne; /**< Rx Frame Continuous Mode Next Engine */
58412 + volatile uint32_t reserved3[0x20];/**< (0x080 0x0FF) */
58413 + volatile uint32_t fmbm_ebmpi[FM_PORT_MAX_NUM_OF_EXT_POOLS_ALL_INTEGRATIONS];
58414 + /**< Buffer Manager pool Information-*/
58415 + volatile uint32_t fmbm_acnt[FM_PORT_MAX_NUM_OF_EXT_POOLS_ALL_INTEGRATIONS];
58416 + /**< Allocate Counter-*/
58417 + volatile uint32_t reserved4[0x08];
58418 + /**< 0x130/0x140 - 0x15F reserved -*/
58419 + volatile uint32_t fmbm_rcgm[FM_PORT_MAX_NUM_OF_CONGESTION_GRPS_ALL_INTEGRATIONS/32];
58420 + /**< Congestion Group Map*/
58421 + volatile uint32_t fmbm_rmpd; /**< BM Pool Depletion */
58422 + volatile uint32_t reserved5[0x1F];/**< (0x184 0x1FF) */
58423 + volatile uint32_t fmbm_rstc; /**< Rx Statistics Counters*/
58424 + volatile uint32_t fmbm_rfrc; /**< Rx Frame Counter*/
58425 + volatile uint32_t fmbm_rfbc; /**< Rx Bad Frames Counter*/
58426 + volatile uint32_t fmbm_rlfc; /**< Rx Large Frames Counter*/
58427 + volatile uint32_t fmbm_rffc; /**< Rx Filter Frames Counter*/
58428 + volatile uint32_t fmbm_rfcd; /**< Rx Frame Discard Counter*/
58429 + volatile uint32_t fmbm_rfldec; /**< Rx Frames List DMA Error Counter*/
58430 + volatile uint32_t fmbm_rodc; /**< Rx Out of Buffers Discard Counter-*/
58431 + volatile uint32_t fmbm_rbdc; /**< Rx Buffers Deallocate Counter-*/
58432 + volatile uint32_t fmbm_rpec; /**< Rx RX Prepare to enqueue Counter-*/
58433 + volatile uint32_t reserved6[0x16];/**< (0x228 0x27F) */
58434 + volatile uint32_t fmbm_rpc; /**< Rx Performance Counters*/
58435 + volatile uint32_t fmbm_rpcp; /**< Rx Performance Count Parameters*/
58436 + volatile uint32_t fmbm_rccn; /**< Rx Cycle Counter*/
58437 + volatile uint32_t fmbm_rtuc; /**< Rx Tasks Utilization Counter*/
58438 + volatile uint32_t fmbm_rrquc; /**< Rx Receive Queue Utilization Counter*/
58439 + volatile uint32_t fmbm_rduc; /**< Rx DMA Utilization Counter*/
58440 + volatile uint32_t fmbm_rfuc; /**< Rx FIFO Utilization Counter*/
58441 + volatile uint32_t fmbm_rpac; /**< Rx Pause Activation Counter*/
58442 + volatile uint32_t reserved7[0x18];/**< (0x2A0-0x2FF) */
58443 + volatile uint32_t fmbm_rdcfg[0x3];/**< Rx Debug-*/
58444 + volatile uint32_t fmbm_rgpr; /**< Rx General Purpose Register. */
58445 + volatile uint32_t reserved8[0x3a];/**< (0x310-0x3FF) */
58446 +} t_FmPortRxBmiRegs;
58447 +
58448 +typedef struct
58449 +{
58450 + volatile uint32_t fmbm_tcfg; /**< Tx Configuration */
58451 + volatile uint32_t fmbm_tst; /**< Tx Status */
58452 + volatile uint32_t fmbm_tda; /**< Tx DMA attributes */
58453 + volatile uint32_t fmbm_tfp; /**< Tx FIFO Parameters */
58454 + volatile uint32_t fmbm_tfed; /**< Tx Frame End Data */
58455 + volatile uint32_t fmbm_ticp; /**< Tx Internal Context Parameters */
58456 + volatile uint32_t fmbm_tfdne; /**< Tx Frame Dequeue Next Engine. */
58457 + volatile uint32_t fmbm_tfca; /**< Tx Frame Command attribute. */
58458 + volatile uint32_t fmbm_tcfqid; /**< Tx Confirmation Frame Queue ID. */
58459 + volatile uint32_t fmbm_tfeqid; /**< Tx Frame Error Queue ID */
58460 + volatile uint32_t fmbm_tfene; /**< Tx Frame Enqueue Next Engine */
58461 + volatile uint32_t fmbm_trlmts; /**< Tx Rate Limiter Scale */
58462 + volatile uint32_t fmbm_trlmt; /**< Tx Rate Limiter */
58463 + volatile uint32_t fmbm_tccb; /**< Tx Coarse Classification Base */
58464 + volatile uint32_t reserved0[0x0e];/**< (0x038-0x070) */
58465 + volatile uint32_t fmbm_tfne; /**< Tx Frame Next Engine */
58466 + volatile uint32_t fmbm_tpfcm[0x02];/**< Tx Priority based Flow Control (PFC) Mapping */
58467 + volatile uint32_t fmbm_tcmne; /**< Tx Frame Continuous Mode Next Engine */
58468 + volatile uint32_t reserved2[0x60];/**< (0x080-0x200) */
58469 + volatile uint32_t fmbm_tstc; /**< Tx Statistics Counters */
58470 + volatile uint32_t fmbm_tfrc; /**< Tx Frame Counter */
58471 + volatile uint32_t fmbm_tfdc; /**< Tx Frames Discard Counter */
58472 + volatile uint32_t fmbm_tfledc; /**< Tx Frame Length error discard counter */
58473 + volatile uint32_t fmbm_tfufdc; /**< Tx Frame unsupported format discard Counter */
58474 + volatile uint32_t fmbm_tbdc; /**< Tx Buffers Deallocate Counter */
58475 + volatile uint32_t reserved3[0x1A];/**< (0x218-0x280) */
58476 + volatile uint32_t fmbm_tpc; /**< Tx Performance Counters*/
58477 + volatile uint32_t fmbm_tpcp; /**< Tx Performance Count Parameters*/
58478 + volatile uint32_t fmbm_tccn; /**< Tx Cycle Counter*/
58479 + volatile uint32_t fmbm_ttuc; /**< Tx Tasks Utilization Counter*/
58480 + volatile uint32_t fmbm_ttcquc; /**< Tx Transmit Confirm Queue Utilization Counter*/
58481 + volatile uint32_t fmbm_tduc; /**< Tx DMA Utilization Counter*/
58482 + volatile uint32_t fmbm_tfuc; /**< Tx FIFO Utilization Counter*/
58483 + volatile uint32_t reserved4[16]; /**< (0x29C-0x2FF) */
58484 + volatile uint32_t fmbm_tdcfg[0x3];/**< Tx Debug-*/
58485 + volatile uint32_t fmbm_tgpr; /**< O/H General Purpose Register */
58486 + volatile uint32_t reserved5[0x3a];/**< (0x310-0x3FF) */
58487 +} t_FmPortTxBmiRegs;
58488 +
58489 +typedef struct
58490 +{
58491 + volatile uint32_t fmbm_ocfg; /**< O/H Configuration */
58492 + volatile uint32_t fmbm_ost; /**< O/H Status */
58493 + volatile uint32_t fmbm_oda; /**< O/H DMA attributes */
58494 + volatile uint32_t fmbm_oicp; /**< O/H Internal Context Parameters */
58495 + volatile uint32_t fmbm_ofdne; /**< O/H Frame Dequeue Next Engine */
58496 + volatile uint32_t fmbm_ofne; /**< O/H Frame Next Engine */
58497 + volatile uint32_t fmbm_ofca; /**< O/H Frame Command Attributes. */
58498 + volatile uint32_t fmbm_ofpne; /**< O/H Frame Parser Next Engine */
58499 + volatile uint32_t fmbm_opso; /**< O/H Parse Start Offset */
58500 + volatile uint32_t fmbm_opp; /**< O/H Policer Profile */
58501 + volatile uint32_t fmbm_occb; /**< O/H Coarse Classification base */
58502 + volatile uint32_t fmbm_oim; /**< O/H Internal margins*/
58503 + volatile uint32_t fmbm_ofp; /**< O/H Fifo Parameters*/
58504 + volatile uint32_t fmbm_ofed; /**< O/H Frame End Data*/
58505 + volatile uint32_t reserved0[2]; /**< (0x038 - 0x03F) */
58506 + volatile uint32_t fmbm_oprai[FM_PORT_PRS_RESULT_NUM_OF_WORDS];
58507 + /**< O/H Parse Results Array Initialization */
58508 + volatile uint32_t fmbm_ofqid; /**< O/H Frame Queue ID */
58509 + volatile uint32_t fmbm_oefqid; /**< O/H Error Frame Queue ID */
58510 + volatile uint32_t fmbm_ofsdm; /**< O/H Frame Status Discard Mask */
58511 + volatile uint32_t fmbm_ofsem; /**< O/H Frame Status Error Mask */
58512 + volatile uint32_t fmbm_ofene; /**< O/H Frame Enqueue Next Engine */
58513 + volatile uint32_t fmbm_orlmts; /**< O/H Rate Limiter Scale */
58514 + volatile uint32_t fmbm_orlmt; /**< O/H Rate Limiter */
58515 + volatile uint32_t fmbm_ocmne; /**< O/H Continuous Mode Next Engine */
58516 + volatile uint32_t reserved1[0x20];/**< (0x080 - 0x0FF) */
58517 + volatile uint32_t fmbm_oebmpi[2]; /**< Buffer Manager Observed Pool Information */
58518 + volatile uint32_t reserved2[0x16];/**< (0x108 - 0x15F) */
58519 + volatile uint32_t fmbm_ocgm; /**< Observed Congestion Group Map */
58520 + volatile uint32_t reserved3[0x7]; /**< (0x164 - 0x17F) */
58521 + volatile uint32_t fmbm_ompd; /**< Observed BMan Pool Depletion */
58522 + volatile uint32_t reserved4[0x1F];/**< (0x184 - 0x1FF) */
58523 + volatile uint32_t fmbm_ostc; /**< O/H Statistics Counters */
58524 + volatile uint32_t fmbm_ofrc; /**< O/H Frame Counter */
58525 + volatile uint32_t fmbm_ofdc; /**< O/H Frames Discard Counter */
58526 + volatile uint32_t fmbm_ofledc; /**< O/H Frames Length Error Discard Counter */
58527 + volatile uint32_t fmbm_ofufdc; /**< O/H Frames Unsupported Format Discard Counter */
58528 + volatile uint32_t fmbm_offc; /**< O/H Filter Frames Counter */
58529 + volatile uint32_t fmbm_ofwdc; /**< - Rx Frames WRED Discard Counter */
58530 + volatile uint32_t fmbm_ofldec; /**< O/H Frames List DMA Error Counter */
58531 + volatile uint32_t fmbm_obdc; /**< O/H Buffers Deallocate Counter */
58532 + volatile uint32_t fmbm_oodc; /**< O/H Out of Buffers Discard Counter */
58533 + volatile uint32_t fmbm_opec; /**< O/H Prepare to enqueue Counter */
58534 + volatile uint32_t reserved5[0x15];/**< ( - 0x27F) */
58535 + volatile uint32_t fmbm_opc; /**< O/H Performance Counters */
58536 + volatile uint32_t fmbm_opcp; /**< O/H Performance Count Parameters */
58537 + volatile uint32_t fmbm_occn; /**< O/H Cycle Counter */
58538 + volatile uint32_t fmbm_otuc; /**< O/H Tasks Utilization Counter */
58539 + volatile uint32_t fmbm_oduc; /**< O/H DMA Utilization Counter */
58540 + volatile uint32_t fmbm_ofuc; /**< O/H FIFO Utilization Counter */
58541 + volatile uint32_t reserved6[26]; /**< (0x298-0x2FF) */
58542 + volatile uint32_t fmbm_odcfg[0x3];/**< O/H Debug (only 1 in P1023) */
58543 + volatile uint32_t fmbm_ogpr; /**< O/H General Purpose Register. */
58544 + volatile uint32_t reserved7[0x3a];/**< (0x310 0x3FF) */
58545 +} t_FmPortOhBmiRegs;
58546 +
58547 +typedef union
58548 +{
58549 + t_FmPortRxBmiRegs rxPortBmiRegs;
58550 + t_FmPortTxBmiRegs txPortBmiRegs;
58551 + t_FmPortOhBmiRegs ohPortBmiRegs;
58552 +} u_FmPortBmiRegs;
58553 +
58554 +typedef struct
58555 +{
58556 + volatile uint32_t reserved1[2]; /**< 0xn024 - 0x02B */
58557 + volatile uint32_t fmqm_pndn; /**< PortID n Dequeue NIA Register */
58558 + volatile uint32_t fmqm_pndc; /**< PortID n Dequeue Config Register */
58559 + volatile uint32_t fmqm_pndtfc; /**< PortID n Dequeue Total Frame Counter */
58560 + volatile uint32_t fmqm_pndfdc; /**< PortID n Dequeue FQID from Default Counter */
58561 + volatile uint32_t fmqm_pndcc; /**< PortID n Dequeue Confirm Counter */
58562 +} t_FmPortNonRxQmiRegs;
58563 +
58564 +typedef struct
58565 +{
58566 + volatile uint32_t fmqm_pnc; /**< PortID n Configuration Register */
58567 + volatile uint32_t fmqm_pns; /**< PortID n Status Register */
58568 + volatile uint32_t fmqm_pnts; /**< PortID n Task Status Register */
58569 + volatile uint32_t reserved0[4]; /**< 0xn00C - 0xn01B */
58570 + volatile uint32_t fmqm_pnen; /**< PortID n Enqueue NIA Register */
58571 + volatile uint32_t fmqm_pnetfc; /**< PortID n Enqueue Total Frame Counter */
58572 + t_FmPortNonRxQmiRegs nonRxQmiRegs; /**< Registers for Tx Hc & Op ports */
58573 +} t_FmPortQmiRegs;
58574 +
58575 +typedef struct
58576 +{
58577 + struct
58578 + {
58579 + volatile uint32_t softSeqAttach; /**< Soft Sequence Attachment */
58580 + volatile uint32_t lcv; /**< Line-up Enable Confirmation Mask */
58581 + } hdrs[FM_PCD_PRS_NUM_OF_HDRS];
58582 + volatile uint32_t reserved0[0xde];
58583 + volatile uint32_t pcac; /**< Parse Internal Memory Configuration Access Control Register */
58584 + volatile uint32_t pctpid; /**< Parse Internal Memory Configured TPID Register */
58585 +} t_FmPortPrsRegs;
58586 +
58587 +/**************************************************************************//*
58588 + @Description Basic buffer descriptor (BD) structure
58589 +*//***************************************************************************/
58590 +typedef _Packed struct
58591 +{
58592 + volatile uint16_t status;
58593 + volatile uint16_t length;
58594 + volatile uint8_t reserved0[0x6];
58595 + volatile uint8_t reserved1[0x1];
58596 + volatile t_FmPhysAddr buff;
58597 +} _PackedType t_FmImBd;
58598 +
58599 +typedef _Packed struct
58600 +{
58601 + volatile uint16_t gen; /**< tbd */
58602 + volatile uint8_t reserved0[0x1];
58603 + volatile t_FmPhysAddr bdRingBase; /**< tbd */
58604 + volatile uint16_t bdRingSize; /**< tbd */
58605 + volatile uint16_t offsetIn; /**< tbd */
58606 + volatile uint16_t offsetOut; /**< tbd */
58607 + volatile uint8_t reserved1[0x12]; /**< 0x0e - 0x1f */
58608 +} _PackedType t_FmPortImQd;
58609 +
58610 +typedef _Packed struct
58611 +{
58612 + volatile uint32_t mode; /**< Mode register */
58613 + volatile uint32_t rxQdPtr; /**< tbd */
58614 + volatile uint32_t txQdPtr; /**< tbd */
58615 + volatile uint16_t mrblr; /**< tbd */
58616 + volatile uint16_t rxQdBsyCnt; /**< tbd */
58617 + volatile uint8_t reserved0[0x10]; /**< 0x10 - 0x1f */
58618 + t_FmPortImQd rxQd;
58619 + t_FmPortImQd txQd;
58620 + volatile uint8_t reserved1[0xa0]; /**< 0x60 - 0xff */
58621 +} _PackedType t_FmPortImPram;
58622 +
58623 +#if defined(__MWERKS__) && !defined(__GNUC__)
58624 +#pragma pack(pop)
58625 +#endif /* defined(__MWERKS__) && ... */
58626 +
58627 +
58628 +/**************************************************************************//**
58629 + @Description Registers bit fields
58630 +*//***************************************************************************/
58631 +
58632 +/**************************************************************************//**
58633 + @Description BMI defines
58634 +*//***************************************************************************/
58635 +#if (DPAA_VERSION >= 11)
58636 +#define BMI_SP_ID_MASK 0xff000000
58637 +#define BMI_SP_ID_SHIFT 24
58638 +#define BMI_SP_EN 0x01000000
58639 +#endif /* (DPAA_VERSION >= 11) */
58640 +
58641 +#define BMI_PORT_CFG_EN 0x80000000
58642 +#define BMI_PORT_CFG_EN_MACSEC 0x00800000
58643 +#define BMI_PORT_CFG_FDOVR 0x02000000
58644 +#define BMI_PORT_CFG_IM 0x01000000
58645 +#define BMI_PORT_CFG_AM 0x00000040
58646 +#define BMI_PORT_STATUS_BSY 0x80000000
58647 +#define BMI_COUNTERS_EN 0x80000000
58648 +
58649 +#define BMI_PORT_RFNE_FRWD_DCL4C 0x10000000
58650 +#define BMI_PORT_RFNE_FRWD_RPD 0x40000000
58651 +#define BMI_RFNE_FDCS_MASK 0xFF000000
58652 +#define BMI_RFNE_HXS_MASK 0x000000FF
58653 +
58654 +#define BMI_CMD_MR_LEAC 0x00200000
58655 +#define BMI_CMD_MR_SLEAC 0x00100000
58656 +#define BMI_CMD_MR_MA 0x00080000
58657 +#define BMI_CMD_MR_DEAS 0x00040000
58658 +#define BMI_CMD_RX_MR_DEF (BMI_CMD_MR_LEAC | \
58659 + BMI_CMD_MR_SLEAC | \
58660 + BMI_CMD_MR_MA | \
58661 + BMI_CMD_MR_DEAS)
58662 +#define BMI_CMD_ATTR_ORDER 0x80000000
58663 +#define BMI_CMD_ATTR_SYNC 0x02000000
58664 +#define BMI_CMD_ATTR_MODE_MISS_ALLIGN_ADDR_EN 0x00080000
58665 +#define BMI_CMD_ATTR_MACCMD_MASK 0x0000ff00
58666 +#define BMI_CMD_ATTR_MACCMD_OVERRIDE 0x00008000
58667 +#define BMI_CMD_ATTR_MACCMD_SECURED 0x00001000
58668 +#define BMI_CMD_ATTR_MACCMD_SC_MASK 0x00000f00
58669 +
58670 +#define BMI_EXT_BUF_POOL_ID_MASK 0x003F0000
58671 +#define BMI_STATUS_RX_MASK_UNUSED (uint32_t)(~(FM_PORT_FRM_ERR_DMA | \
58672 + FM_PORT_FRM_ERR_PHYSICAL | \
58673 + FM_PORT_FRM_ERR_SIZE | \
58674 + FM_PORT_FRM_ERR_CLS_DISCARD | \
58675 + FM_PORT_FRM_ERR_EXTRACTION | \
58676 + FM_PORT_FRM_ERR_NO_SCHEME | \
58677 + FM_PORT_FRM_ERR_COLOR_RED | \
58678 + FM_PORT_FRM_ERR_COLOR_YELLOW | \
58679 + FM_PORT_FRM_ERR_ILL_PLCR | \
58680 + FM_PORT_FRM_ERR_PLCR_FRAME_LEN | \
58681 + FM_PORT_FRM_ERR_PRS_TIMEOUT | \
58682 + FM_PORT_FRM_ERR_PRS_ILL_INSTRUCT | \
58683 + FM_PORT_FRM_ERR_BLOCK_LIMIT_EXCEEDED | \
58684 + FM_PORT_FRM_ERR_PRS_HDR_ERR | \
58685 + FM_PORT_FRM_ERR_IPRE | \
58686 + FM_PORT_FRM_ERR_IPR_NCSP | \
58687 + FM_PORT_FRM_ERR_KEYSIZE_OVERFLOW))
58688 +
58689 +#define BMI_STATUS_OP_MASK_UNUSED (uint32_t)(BMI_STATUS_RX_MASK_UNUSED & \
58690 + ~(FM_PORT_FRM_ERR_LENGTH | \
58691 + FM_PORT_FRM_ERR_NON_FM | \
58692 + FM_PORT_FRM_ERR_UNSUPPORTED_FORMAT))
58693 +
58694 +#define BMI_RATE_LIMIT_EN 0x80000000
58695 +#define BMI_RATE_LIMIT_BURST_SIZE_GRAN 0x80000000
58696 +#define BMI_RATE_LIMIT_SCALE_BY_2 0x00000001
58697 +#define BMI_RATE_LIMIT_SCALE_BY_4 0x00000002
58698 +#define BMI_RATE_LIMIT_SCALE_BY_8 0x00000003
58699 +
58700 +#define BMI_RX_FIFO_THRESHOLD_BC 0x80000000
58701 +
58702 +#define BMI_PRS_RESULT_HIGH 0x00000000
58703 +#define BMI_PRS_RESULT_LOW 0xFFFFFFFF
58704 +
58705 +
58706 +#define RX_ERRS_TO_ENQ (FM_PORT_FRM_ERR_DMA | \
58707 + FM_PORT_FRM_ERR_PHYSICAL | \
58708 + FM_PORT_FRM_ERR_SIZE | \
58709 + FM_PORT_FRM_ERR_EXTRACTION | \
58710 + FM_PORT_FRM_ERR_NO_SCHEME | \
58711 + FM_PORT_FRM_ERR_ILL_PLCR | \
58712 + FM_PORT_FRM_ERR_PLCR_FRAME_LEN | \
58713 + FM_PORT_FRM_ERR_PRS_TIMEOUT | \
58714 + FM_PORT_FRM_ERR_PRS_ILL_INSTRUCT | \
58715 + FM_PORT_FRM_ERR_BLOCK_LIMIT_EXCEEDED | \
58716 + FM_PORT_FRM_ERR_PRS_HDR_ERR | \
58717 + FM_PORT_FRM_ERR_KEYSIZE_OVERFLOW | \
58718 + FM_PORT_FRM_ERR_IPRE)
58719 +
58720 +#define OP_ERRS_TO_ENQ (RX_ERRS_TO_ENQ | \
58721 + FM_PORT_FRM_ERR_LENGTH | \
58722 + FM_PORT_FRM_ERR_NON_FM | \
58723 + FM_PORT_FRM_ERR_UNSUPPORTED_FORMAT)
58724 +
58725 +
58726 +#define BMI_RX_FIFO_PRI_ELEVATION_MASK 0x03FF0000
58727 +#define BMI_RX_FIFO_THRESHOLD_MASK 0x000003FF
58728 +#define BMI_TX_FIFO_MIN_FILL_MASK 0x03FF0000
58729 +#define BMI_FIFO_PIPELINE_DEPTH_MASK 0x0000F000
58730 +#define BMI_TX_LOW_COMF_MASK 0x000003FF
58731 +
58732 +/* shifts */
58733 +#define BMI_PORT_CFG_MS_SEL_SHIFT 16
58734 +#define BMI_DMA_ATTR_IC_CACHE_SHIFT FMAN_SP_DMA_ATTR_IC_CACHE_SHIFT
58735 +#define BMI_DMA_ATTR_HDR_CACHE_SHIFT FMAN_SP_DMA_ATTR_HDR_CACHE_SHIFT
58736 +#define BMI_DMA_ATTR_SG_CACHE_SHIFT FMAN_SP_DMA_ATTR_SG_CACHE_SHIFT
58737 +
58738 +#define BMI_IM_FOF_SHIFT 28
58739 +#define BMI_PR_PORTID_SHIFT 24
58740 +
58741 +#define BMI_RX_FIFO_PRI_ELEVATION_SHIFT 16
58742 +#define BMI_RX_FIFO_THRESHOLD_SHIFT 0
58743 +
58744 +#define BMI_RX_FRAME_END_CS_IGNORE_SHIFT 24
58745 +#define BMI_RX_FRAME_END_CUT_SHIFT 16
58746 +
58747 +#define BMI_IC_SIZE_SHIFT FMAN_SP_IC_SIZE_SHIFT
58748 +
58749 +#define BMI_INT_BUF_MARG_SHIFT 28
58750 +
58751 +#define BMI_EXT_BUF_MARG_END_SHIFT FMAN_SP_EXT_BUF_MARG_END_SHIFT
58752 +
58753 +#define BMI_CMD_ATTR_COLOR_SHIFT 26
58754 +#define BMI_CMD_ATTR_COM_MODE_SHIFT 16
58755 +#define BMI_CMD_ATTR_MACCMD_SHIFT 8
58756 +#define BMI_CMD_ATTR_MACCMD_OVERRIDE_SHIFT 15
58757 +#define BMI_CMD_ATTR_MACCMD_SECURED_SHIFT 12
58758 +#define BMI_CMD_ATTR_MACCMD_SC_SHIFT 8
58759 +
58760 +#define BMI_POOL_DEP_NUM_OF_POOLS_VECTOR_SHIFT 24
58761 +
58762 +#define BMI_TX_FIFO_MIN_FILL_SHIFT 16
58763 +#define BMI_TX_LOW_COMF_SHIFT 0
58764 +
58765 +#define BMI_PERFORMANCE_TASK_COMP_SHIFT 24
58766 +#define BMI_PERFORMANCE_PORT_COMP_SHIFT 16
58767 +#define BMI_PERFORMANCE_DMA_COMP_SHIFT 12
58768 +#define BMI_PERFORMANCE_FIFO_COMP_SHIFT 0
58769 +
58770 +#define BMI_MAX_BURST_SHIFT 16
58771 +#define BMI_COUNT_RATE_UNIT_SHIFT 16
58772 +
58773 +/* sizes */
58774 +#define FRAME_END_DATA_SIZE 16
58775 +#define FRAME_OFFSET_UNITS 16
58776 +#define MIN_TX_INT_OFFSET 16
58777 +#define MAX_FRAME_OFFSET 64
58778 +#define MAX_FIFO_PIPELINE_DEPTH 8
58779 +#define MAX_PERFORMANCE_TASK_COMP 64
58780 +#define MAX_PERFORMANCE_TX_QUEUE_COMP 8
58781 +#define MAX_PERFORMANCE_RX_QUEUE_COMP 64
58782 +#define MAX_PERFORMANCE_DMA_COMP 16
58783 +#define MAX_NUM_OF_TASKS 64
58784 +#define MAX_NUM_OF_EXTRA_TASKS 8
58785 +#define MAX_NUM_OF_DMAS 16
58786 +#define MAX_NUM_OF_EXTRA_DMAS 8
58787 +#define MAX_BURST_SIZE 1024
58788 +#define MIN_NUM_OF_OP_DMAS 2
58789 +
58790 +
58791 +/**************************************************************************//**
58792 + @Description QMI defines
58793 +*//***************************************************************************/
58794 +/* masks */
58795 +#define QMI_PORT_CFG_EN 0x80000000
58796 +#define QMI_PORT_CFG_EN_COUNTERS 0x10000000
58797 +#define QMI_PORT_STATUS_DEQ_TNUM_BSY 0x80000000
58798 +#define QMI_PORT_STATUS_DEQ_FD_BSY 0x20000000
58799 +
58800 +#define QMI_DEQ_CFG_PREFETCH_NO_TNUM 0x02000000
58801 +#define QMI_DEQ_CFG_PREFETCH_WAITING_TNUM 0
58802 +#define QMI_DEQ_CFG_PREFETCH_1_FRAME 0
58803 +#define QMI_DEQ_CFG_PREFETCH_3_FRAMES 0x01000000
58804 +
58805 +#define QMI_DEQ_CFG_PRI 0x80000000
58806 +#define QMI_DEQ_CFG_TYPE1 0x10000000
58807 +#define QMI_DEQ_CFG_TYPE2 0x20000000
58808 +#define QMI_DEQ_CFG_TYPE3 0x30000000
58809 +
58810 +#define QMI_DEQ_CFG_SUBPORTAL_MASK 0x1f
58811 +#define QMI_DEQ_CFG_SUBPORTAL_SHIFT 20
58812 +
58813 +/**************************************************************************//**
58814 + @Description PARSER defines
58815 +*//***************************************************************************/
58816 +/* masks */
58817 +#define PRS_HDR_ERROR_DIS 0x00000800
58818 +#define PRS_HDR_SW_PRS_EN 0x00000400
58819 +#define PRS_CP_OFFSET_MASK 0x0000000F
58820 +#define PRS_TPID1_MASK 0xFFFF0000
58821 +#define PRS_TPID2_MASK 0x0000FFFF
58822 +#define PRS_TPID_DFLT 0x91009100
58823 +
58824 +#define PRS_HDR_MPLS_LBL_INTER_EN 0x00200000
58825 +#define PRS_HDR_IPV6_ROUTE_HDR_EN 0x00008000
58826 +#define PRS_HDR_PPPOE_MTU_CHECK_EN 0x80000000
58827 +#define PRS_HDR_UDP_PAD_REMOVAL 0x80000000
58828 +#define PRS_HDR_TCP_PAD_REMOVAL 0x80000000
58829 +#define PRS_CAC_STOP 0x00000001
58830 +#define PRS_CAC_ACTIVE 0x00000100
58831 +
58832 +/* shifts */
58833 +#define PRS_PCTPID_SHIFT 16
58834 +#define PRS_HDR_MPLS_NEXT_HDR_SHIFT 22
58835 +#define PRS_HDR_ETH_BC_SHIFT 28
58836 +#define PRS_HDR_ETH_MC_SHIFT 24
58837 +#define PRS_HDR_VLAN_STACKED_SHIFT 16
58838 +#define PRS_HDR_MPLS_STACKED_SHIFT 16
58839 +#define PRS_HDR_IPV4_1_BC_SHIFT 28
58840 +#define PRS_HDR_IPV4_1_MC_SHIFT 24
58841 +#define PRS_HDR_IPV4_2_UC_SHIFT 20
58842 +#define PRS_HDR_IPV4_2_MC_BC_SHIFT 16
58843 +#define PRS_HDR_IPV6_1_MC_SHIFT 24
58844 +#define PRS_HDR_IPV6_2_UC_SHIFT 20
58845 +#define PRS_HDR_IPV6_2_MC_SHIFT 16
58846 +
58847 +#define PRS_HDR_ETH_BC_MASK 0x0fffffff
58848 +#define PRS_HDR_ETH_MC_MASK 0xf0ffffff
58849 +#define PRS_HDR_VLAN_STACKED_MASK 0xfff0ffff
58850 +#define PRS_HDR_MPLS_STACKED_MASK 0xfff0ffff
58851 +#define PRS_HDR_IPV4_1_BC_MASK 0x0fffffff
58852 +#define PRS_HDR_IPV4_1_MC_MASK 0xf0ffffff
58853 +#define PRS_HDR_IPV4_2_UC_MASK 0xff0fffff
58854 +#define PRS_HDR_IPV4_2_MC_BC_MASK 0xfff0ffff
58855 +#define PRS_HDR_IPV6_1_MC_MASK 0xf0ffffff
58856 +#define PRS_HDR_IPV6_2_UC_MASK 0xff0fffff
58857 +#define PRS_HDR_IPV6_2_MC_MASK 0xfff0ffff
58858 +
58859 +/* others */
58860 +#define PRS_HDR_ENTRY_SIZE 8
58861 +#define DEFAULT_CLS_PLAN_VECTOR 0xFFFFFFFF
58862 +
58863 +#define IPSEC_SW_PATCH_START 0x20
58864 +#define SCTP_SW_PATCH_START 0x4D
58865 +#define DCCP_SW_PATCH_START 0x41
58866 +
58867 +/**************************************************************************//**
58868 + @Description IM defines
58869 +*//***************************************************************************/
58870 +#define BD_R_E 0x80000000
58871 +#define BD_L 0x08000000
58872 +
58873 +#define BD_RX_CRE 0x00080000
58874 +#define BD_RX_FTL 0x00040000
58875 +#define BD_RX_FTS 0x00020000
58876 +#define BD_RX_OV 0x00010000
58877 +
58878 +#define BD_RX_ERRORS (BD_RX_CRE | BD_RX_FTL | BD_RX_FTS | BD_RX_OV)
58879 +
58880 +#define FM_IM_SIZEOF_BD sizeof(t_FmImBd)
58881 +
58882 +#define BD_STATUS_MASK 0xffff0000
58883 +#define BD_LENGTH_MASK 0x0000ffff
58884 +
58885 +#define BD_STATUS_AND_LENGTH_SET(bd, val) WRITE_UINT32(*(volatile uint32_t*)(bd), (val))
58886 +
58887 +#define BD_STATUS_AND_LENGTH(bd) GET_UINT32(*(volatile uint32_t*)(bd))
58888 +
58889 +#define BD_GET(id) &p_FmPort->im.p_BdRing[id]
58890 +
58891 +#define IM_ILEGAL_BD_ID 0xffff
58892 +
58893 +/* others */
58894 +#define IM_PRAM_ALIGN 0x100
58895 +
58896 +/* masks */
58897 +#define IM_MODE_GBL 0x20000000
58898 +#define IM_MODE_BO_MASK 0x18000000
58899 +#define IM_MODE_BO_SHIFT 3
58900 +#define IM_MODE_GRC_STP 0x00800000
58901 +
58902 +#define IM_MODE_SET_BO(val) (uint32_t)((val << (31-IM_MODE_BO_SHIFT)) & IM_MODE_BO_MASK)
58903 +
58904 +#define IM_RXQD_BSYINTM 0x0008
58905 +#define IM_RXQD_RXFINTM 0x0010
58906 +#define IM_RXQD_FPMEVT_SEL_MASK 0x0003
58907 +
58908 +#define IM_EV_BSY 0x40000000
58909 +#define IM_EV_RX 0x80000000
58910 +
58911 +
58912 +/**************************************************************************//**
58913 + @Description Additional defines
58914 +*//***************************************************************************/
58915 +
58916 +typedef struct {
58917 + t_Handle h_FmMuram;
58918 + t_FmPortImPram *p_FmPortImPram;
58919 + uint8_t fwExtStructsMemId;
58920 + uint32_t fwExtStructsMemAttr;
58921 + uint16_t bdRingSize;
58922 + t_FmImBd *p_BdRing;
58923 + t_Handle *p_BdShadow;
58924 + uint16_t currBdId;
58925 + uint16_t firstBdOfFrameId;
58926 +
58927 + /* Rx port parameters */
58928 + uint8_t dataMemId; /**< Memory partition ID for data buffers */
58929 + uint32_t dataMemAttributes; /**< Memory attributes for data buffers */
58930 + t_BufferPoolInfo rxPool;
58931 + uint16_t mrblr;
58932 + uint16_t rxFrameAccumLength;
58933 + t_FmPortImRxStoreCallback *f_RxStore;
58934 +
58935 + /* Tx port parameters */
58936 + uint32_t txFirstBdStatus;
58937 + t_FmPortImTxConfCallback *f_TxConf;
58938 +} t_FmMacIm;
58939 +
58940 +
58941 +typedef struct {
58942 + struct fman_port_cfg dfltCfg;
58943 + uint32_t dfltFqid;
58944 + uint32_t confFqid;
58945 + uint32_t errFqid;
58946 + uintptr_t baseAddr;
58947 + uint8_t deqSubPortal;
58948 + bool deqHighPriority;
58949 + e_FmPortDeqType deqType;
58950 + e_FmPortDeqPrefetchOption deqPrefetchOption;
58951 + uint16_t deqByteCnt;
58952 + uint8_t cheksumLastBytesIgnore;
58953 + uint8_t cutBytesFromEnd;
58954 + t_FmBufPoolDepletion bufPoolDepletion;
58955 + uint8_t pipelineDepth;
58956 + uint16_t fifoLowComfLevel;
58957 + bool frmDiscardOverride;
58958 + bool enRateLimit;
58959 + t_FmPortRateLimit rateLimit;
58960 + e_FmPortDualRateLimiterScaleDown rateLimitDivider;
58961 + bool enBufPoolDepletion;
58962 + uint16_t liodnOffset;
58963 + uint16_t liodnBase;
58964 + t_FmExtPools extBufPools;
58965 + e_FmDmaSwapOption dmaSwapData;
58966 + e_FmDmaCacheOption dmaIntContextCacheAttr;
58967 + e_FmDmaCacheOption dmaHeaderCacheAttr;
58968 + e_FmDmaCacheOption dmaScatterGatherCacheAttr;
58969 + bool dmaReadOptimize;
58970 + bool dmaWriteOptimize;
58971 + uint32_t txFifoMinFillLevel;
58972 + uint32_t txFifoLowComfLevel;
58973 + uint32_t rxFifoPriElevationLevel;
58974 + uint32_t rxFifoThreshold;
58975 + t_FmSpBufMargins bufMargins;
58976 + t_FmSpIntContextDataCopy intContext;
58977 + bool syncReq;
58978 + e_FmPortColor color;
58979 + fmPortFrameErrSelect_t errorsToDiscard;
58980 + fmPortFrameErrSelect_t errorsToEnq;
58981 + bool forwardReuseIntContext;
58982 + t_FmBufferPrefixContent bufferPrefixContent;
58983 + t_FmBackupBmPools *p_BackupBmPools;
58984 + bool dontReleaseBuf;
58985 + bool setNumOfTasks;
58986 + bool setNumOfOpenDmas;
58987 + bool setSizeOfFifo;
58988 +#if (DPAA_VERSION >= 11)
58989 + bool noScatherGather;
58990 +#endif /* (DPAA_VERSION >= 11) */
58991 +
58992 +#ifdef FM_HEAVY_TRAFFIC_HANG_ERRATA_FMAN_A005669
58993 + bool bcbWorkaround;
58994 +#endif /* FM_HEAVY_TRAFFIC_HANG_ERRATA_FMAN_A005669 */
58995 +} t_FmPortDriverParam;
58996 +
58997 +
58998 +typedef struct t_FmPortRxPoolsParams
58999 +{
59000 + uint8_t numOfPools;
59001 + uint16_t secondLargestBufSize;
59002 + uint16_t largestBufSize;
59003 +} t_FmPortRxPoolsParams;
59004 +
59005 +typedef struct t_FmPortDsarVars {
59006 + t_Handle *autoResOffsets;
59007 + t_FmPortDsarTablesSizes *autoResMaxSizes;
59008 + uint32_t fmbm_tcfg;
59009 + uint32_t fmbm_tcmne;
59010 + uint32_t fmbm_rfne;
59011 + uint32_t fmbm_rfpne;
59012 + uint32_t fmbm_rcfg;
59013 + bool dsarEnabledParser;
59014 +} t_FmPortDsarVars;
59015 +typedef struct {
59016 + struct fman_port port;
59017 + t_Handle h_Fm;
59018 + t_Handle h_FmPcd;
59019 + t_Handle h_FmMuram;
59020 + t_FmRevisionInfo fmRevInfo;
59021 + uint8_t portId;
59022 + e_FmPortType portType;
59023 + int enabled;
59024 + char name[MODULE_NAME_SIZE];
59025 + uint8_t hardwarePortId;
59026 + uint16_t fmClkFreq;
59027 + t_FmPortQmiRegs *p_FmPortQmiRegs;
59028 + u_FmPortBmiRegs *p_FmPortBmiRegs;
59029 + t_FmPortPrsRegs *p_FmPortPrsRegs;
59030 + fmPcdEngines_t pcdEngines;
59031 + uint32_t savedBmiNia;
59032 + uint8_t netEnvId;
59033 + uint32_t optArray[FM_PCD_MAX_NUM_OF_OPTIONS(FM_PCD_MAX_NUM_OF_CLS_PLANS)];
59034 + uint32_t lcvs[FM_PCD_PRS_NUM_OF_HDRS];
59035 + uint8_t privateInfo;
59036 + uint32_t schemesPerPortVector;
59037 + bool useClsPlan;
59038 + uint8_t clsPlanGrpId;
59039 + t_Handle ccTreeId;
59040 + t_Handle completeArg;
59041 + void (*f_Complete)(t_Handle arg);
59042 + t_FmSpBufferOffsets bufferOffsets;
59043 + /* Independent-Mode parameters support */
59044 + bool imEn;
59045 + t_FmMacIm im;
59046 + volatile bool lock;
59047 + t_Handle h_Spinlock;
59048 + t_FmPortExceptionCallback *f_Exception;
59049 + t_Handle h_App;
59050 + uint8_t internalBufferOffset;
59051 + uint8_t fmanCtrlEventId;
59052 + uint32_t exceptions;
59053 + bool polling;
59054 + t_FmExtPools extBufPools;
59055 + uint32_t requiredAction;
59056 + uint32_t savedQmiPnen;
59057 + uint32_t savedBmiFene;
59058 + uint32_t savedBmiFpne;
59059 + uint32_t savedBmiCmne;
59060 + uint32_t savedBmiOfp;
59061 + uint32_t savedNonRxQmiRegsPndn;
59062 + uint32_t origNonRxQmiRegsPndn;
59063 + int savedPrsStartOffset;
59064 + bool includeInPrsStatistics;
59065 + uint16_t maxFrameLength;
59066 + t_FmFmanCtrl orFmanCtrl;
59067 + t_FmPortRsrc openDmas;
59068 + t_FmPortRsrc tasks;
59069 + t_FmPortRsrc fifoBufs;
59070 + t_FmPortRxPoolsParams rxPoolsParams;
59071 +// bool explicitUserSizeOfFifo;
59072 + t_Handle h_IpReassemblyManip;
59073 + t_Handle h_CapwapReassemblyManip;
59074 + t_Handle h_ReassemblyTree;
59075 + uint64_t fmMuramPhysBaseAddr;
59076 +#if (DPAA_VERSION >= 11)
59077 + bool vspe;
59078 + uint8_t dfltRelativeId;
59079 + e_FmPortGprFuncType gprFunc;
59080 + t_FmPcdCtrlParamsPage *p_ParamsPage;
59081 +#endif /* (DPAA_VERSION >= 11) */
59082 + t_FmPortDsarVars deepSleepVars;
59083 + t_FmPortDriverParam *p_FmPortDriverParam;
59084 +} t_FmPort;
59085 +
59086 +
59087 +void FmPortConfigIM (t_FmPort *p_FmPort, t_FmPortParams *p_FmPortParams);
59088 +t_Error FmPortImCheckInitParameters(t_FmPort *p_FmPort);
59089 +
59090 +t_Error FmPortImInit(t_FmPort *p_FmPort);
59091 +void FmPortImFree(t_FmPort *p_FmPort);
59092 +
59093 +t_Error FmPortImEnable (t_FmPort *p_FmPort);
59094 +t_Error FmPortImDisable (t_FmPort *p_FmPort);
59095 +t_Error FmPortImRx (t_FmPort *p_FmPort);
59096 +
59097 +void FmPortSetMacsecLcv(t_Handle h_FmPort);
59098 +void FmPortSetMacsecCmd(t_Handle h_FmPort, uint8_t dfltSci);
59099 +
59100 +
59101 +t_Error FM_PORT_SetNumOfOpenDmas(t_Handle h_FmPort, t_FmPortRsrc *p_NumOfOpenDmas);
59102 +t_Error FM_PORT_SetNumOfTasks(t_Handle h_FmPort, t_FmPortRsrc *p_NumOfTasks);
59103 +t_Error FM_PORT_SetSizeOfFifo(t_Handle h_FmPort, t_FmPortRsrc *p_SizeOfFifo);
59104 +
59105 +static __inline__ uint8_t * BdBufferGet (t_PhysToVirt *f_PhysToVirt, t_FmImBd *p_Bd)
59106 +{
59107 + uint64_t physAddr = (uint64_t)((uint64_t)GET_UINT8(p_Bd->buff.high) << 32);
59108 + physAddr |= GET_UINT32(p_Bd->buff.low);
59109 +
59110 + return (uint8_t *)f_PhysToVirt((physAddress_t)(physAddr));
59111 +}
59112 +
59113 +static __inline__ void SET_ADDR(volatile t_FmPhysAddr *fmPhysAddr, uint64_t value)
59114 +{
59115 + WRITE_UINT8(fmPhysAddr->high,(uint8_t)((value & 0x000000ff00000000LL) >> 32));
59116 + WRITE_UINT32(fmPhysAddr->low,(uint32_t)value);
59117 +}
59118 +
59119 +static __inline__ void BdBufferSet(t_VirtToPhys *f_VirtToPhys, t_FmImBd *p_Bd, uint8_t *p_Buffer)
59120 +{
59121 + uint64_t physAddr = (uint64_t)(f_VirtToPhys(p_Buffer));
59122 + SET_ADDR(&p_Bd->buff, physAddr);
59123 +}
59124 +
59125 +static __inline__ uint16_t GetNextBdId(t_FmPort *p_FmPort, uint16_t id)
59126 +{
59127 + if (id < p_FmPort->im.bdRingSize-1)
59128 + return (uint16_t)(id+1);
59129 + else
59130 + return 0;
59131 +}
59132 +
59133 +void FM_PORT_Dsar_DumpRegs(void);
59134 +
59135 +
59136 +#endif /* __FM_PORT_H */
59137 --- /dev/null
59138 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Port/fm_port_dsar.h
59139 @@ -0,0 +1,494 @@
59140 +/*
59141 + * Copyright 2008-2012 Freescale Semiconductor Inc.
59142 + *
59143 + * Redistribution and use in source and binary forms, with or without
59144 + * modification, are permitted provided that the following conditions are met:
59145 + * * Redistributions of source code must retain the above copyright
59146 + * notice, this list of conditions and the following disclaimer.
59147 + * * Redistributions in binary form must reproduce the above copyright
59148 + * notice, this list of conditions and the following disclaimer in the
59149 + * documentation and/or other materials provided with the distribution.
59150 + * * Neither the name of Freescale Semiconductor nor the
59151 + * names of its contributors may be used to endorse or promote products
59152 + * derived from this software without specific prior written permission.
59153 + *
59154 + *
59155 + * ALTERNATIVELY, this software may be distributed under the terms of the
59156 + * GNU General Public License ("GPL") as published by the Free Software
59157 + * Foundation, either version 2 of that License or (at your option) any
59158 + * later version.
59159 + *
59160 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
59161 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
59162 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
59163 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
59164 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
59165 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
59166 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
59167 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
59168 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
59169 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
59170 + */
59171 +
59172 +/**************************************************************************//**
59173 + @File fm_port_dsar.h
59174 +
59175 + @Description Deep Sleep Auto Response project - common module header file.
59176 +
59177 + Author - Eyal Harari
59178 +
59179 + @Cautions See the FMan Controller spec and design document for more information.
59180 +*//***************************************************************************/
59181 +
59182 +#ifndef __FM_PORT_DSAR_H_
59183 +#define __FM_PORT_DSAR_H_
59184 +
59185 +#define DSAR_GETSER_MASK 0xFF0000FF
59186 +
59187 +#if defined(__MWERKS__) && !defined(__GNUC__)
59188 +#pragma pack(push,1)
59189 +#endif /* defined(__MWERKS__) && ... */
59190 +
59191 +/**************************************************************************//**
59192 + @Description Deep Sleep Auto Response VLAN-IPv4 Binding Table (for ARP/ICMPv4)
59193 + Refer to the FMan Controller spec for more details.
59194 +*//***************************************************************************/
59195 +typedef _Packed struct
59196 +{
59197 + uint32_t ipv4Addr; /*!< 32 bit IPv4 Address. */
59198 + uint16_t vlanId; /*!< 12 bits VLAN ID. The 4 left-most bits should be cleared */
59199 + /*!< This field should be 0x0000 for an entry with no VLAN tag or a null VLAN ID. */
59200 + uint16_t reserved;
59201 +} _PackedType t_DsarArpBindingEntry;
59202 +
59203 +/**************************************************************************//**
59204 + @Description Deep Sleep Auto Response Address Resolution Protocol Statistics Descriptor
59205 + Refer to the FMan Controller spec for more details.
59206 + 0x00 INVAL_CNT Invalid ARP IPv4-Ethernet counter
59207 + 0x04 ECHO_CNT Echo counter
59208 + 0x08 CD_CNT Conflict Detection counter
59209 + 0x0C AR_CNT Auto-Response counter
59210 + 0x10 RATM_CNT Replies Addressed To Me counter
59211 + 0x14 UKOP_CNT Unknown Operation counter
59212 + 0x18 NMTP_CNT Not my TPA counter
59213 + 0x1C NMVLAN_CNT Not My VLAN counter
59214 +*//***************************************************************************/
59215 +typedef _Packed struct
59216 +{
59217 + uint32_t invalCnt; /**< Invalid ARP IPv4-Ethernet counter. */
59218 + uint32_t echoCnt; /**< Echo counter. */
59219 + uint32_t cdCnt; /**< Conflict Detection counter. */
59220 + uint32_t arCnt; /**< Auto-Response counter. */
59221 + uint32_t ratmCnt; /**< Replies Addressed To Me counter. */
59222 + uint32_t ukopCnt; /**< Unknown Operation counter. */
59223 + uint32_t nmtpCnt; /**< Not my TPA counter. */
59224 + uint32_t nmVlanCnt; /**< Not My VLAN counter */
59225 +} _PackedType t_DsarArpStatistics;
59226 +
59227 +
59228 +/**************************************************************************//**
59229 + @Description Deep Sleep Auto Response Address Resolution Protocol Descriptor
59230 + 0x0 0-15 Control bits [0-15]. Bit 15 = CDEN.
59231 + 0x2 0-15 NumOfBindings Number of entries in the binding list.
59232 + 0x4 0-15 BindingsPointer Bindings Pointer. This points to an IPv4-MAC Addresses Bindings list.
59233 + 0x6 0-15
59234 + 0x8 0-15 StatisticsPointer Statistics Pointer. This field points to the ARP Descriptors statistics data structure.
59235 + 0xA 0-15
59236 + 0xC 0-15 Reserved Reserved. Must be cleared.
59237 + 0xE 015
59238 +
59239 +*//***************************************************************************/
59240 +typedef _Packed struct
59241 +{
59242 + uint16_t control; /** Control bits [0-15]. Bit 15 = CDEN */
59243 + uint16_t numOfBindings; /**< Number of VLAN-IPv4 */
59244 + uint32_t p_Bindings; /**< VLAN-IPv4 Bindings table pointer. */
59245 + uint32_t p_Statistics; /**< Statistics Data Structure pointer. */
59246 + uint32_t reserved1; /**< Reserved. */
59247 +} _PackedType t_DsarArpDescriptor;
59248 +
59249 +
59250 +/**************************************************************************//**
59251 + @Description Deep Sleep Auto Response VLAN-IPv4 Binding Table (for ARP/ICMPv4)
59252 + Refer to the FMan Controller spec for more details.
59253 +*//***************************************************************************/
59254 +typedef _Packed struct
59255 +{
59256 + uint32_t ipv4Addr; /*!< 32 bit IPv4 Address. */
59257 + uint16_t vlanId; /*!< 12 bits VLAN ID. The 4 left-most bits should be cleared */
59258 + /*!< This field should be 0x0000 for an entry with no VLAN tag or a null VLAN ID. */
59259 + uint16_t reserved;
59260 +} _PackedType t_DsarIcmpV4BindingEntry;
59261 +
59262 +/**************************************************************************//**
59263 + @Description Deep Sleep Auto Response ICMPv4 Statistics Descriptor
59264 + Refer to the FMan Controller spec for more details.
59265 + 0x00 INVAL_CNT Invalid ICMPv4 header counter
59266 + 0x04 NMVLAN_CNT Not My VLAN counter
59267 + 0x08 NMIP_CNT Not My IP counter
59268 + 0x0C AR_CNT Auto-Response counter
59269 + 0x10 CSERR_CNT Checksum Error counter
59270 + 0x14 Reserved Reserved
59271 + 0x18 Reserved Reserved
59272 + 0x1C Reserved Reserved
59273 +
59274 +*//***************************************************************************/
59275 +typedef _Packed struct
59276 +{
59277 + uint32_t invalCnt; /**< Invalid ICMPv4 Echo counter. */
59278 + uint32_t nmVlanCnt; /**< Not My VLAN counter */
59279 + uint32_t nmIpCnt; /**< Not My IP counter */
59280 + uint32_t arCnt; /**< Auto-Response counter */
59281 + uint32_t cserrCnt; /**< Checksum Error counter */
59282 + uint32_t reserved0; /**< Reserved */
59283 + uint32_t reserved1; /**< Reserved */
59284 + uint32_t reserved2; /**< Reserved */
59285 +} _PackedType t_DsarIcmpV4Statistics;
59286 +
59287 +
59288 +
59289 +/**************************************************************************//**
59290 + @Description Deep Sleep Auto Response ICMPv4 Descriptor
59291 + 0x0 0-15 Control bits [0-15]
59292 + 0x2 0-15 NumOfBindings Number of entries in the binding list.
59293 + 0x4 0-15 BindingsPointer Bindings Pointer. This points to an VLAN-IPv4 Addresses Bindings list.
59294 + 0x6 0-15
59295 + 0x8 0-15 StatisticsPointer Statistics Pointer. This field points to the ICMPv4 statistics data structure.
59296 + 0xA 0-15
59297 + 0xC 0-15 Reserved Reserved. Must be cleared.
59298 + 0xE 015
59299 +
59300 +*//***************************************************************************/
59301 +typedef _Packed struct
59302 +{
59303 + uint16_t control; /** Control bits [0-15]. */
59304 + uint16_t numOfBindings; /**< Number of VLAN-IPv4 */
59305 + uint32_t p_Bindings; /**< VLAN-IPv4 Bindings table pointer. */
59306 + uint32_t p_Statistics; /**< Statistics Data Structure pointer. */
59307 + uint32_t reserved1; /**< Reserved. */
59308 +} _PackedType t_DsarIcmpV4Descriptor;
59309 +
59310 +/**************************************************************************//**
59311 + @Description Deep Sleep Auto Response VLAN-IPv4 Binding Table (for ARP/ICMPv4)
59312 + The 4 left-most bits (15:12) of the VlanId parameter are control flags.
59313 + Flags[3:1] (VlanId[15:13]): Reserved, should be cleared.
59314 + Flags[0] (VlanId[12]): Temporary address.
59315 + \95 0 - Assigned IP address.
59316 + \95 1- Temporary (tentative) IP address.
59317 + Refer to the FMan Controller spec for more details.
59318 +*//***************************************************************************/
59319 +typedef _Packed struct
59320 +{
59321 + uint32_t ipv6Addr[4]; /*!< 3 * 32 bit IPv4 Address. */
59322 + uint16_t resFlags:4; /*!< reserved flags. should be cleared */
59323 + uint16_t vlanId:12; /*!< 12 bits VLAN ID. */
59324 + /*!< This field should be 0x000 for an entry with no VLAN tag or a null VLAN ID. */
59325 + uint16_t reserved;
59326 +} _PackedType t_DsarIcmpV6BindingEntry;
59327 +
59328 +/**************************************************************************//**
59329 + @Description Deep Sleep Auto Response ICMPv4 Statistics Descriptor
59330 + Refer to the FMan Controller spec for more details.
59331 + 0x00 INVAL_CNT Invalid ICMPv4 header counter
59332 + 0x04 NMVLAN_CNT Not My VLAN counter
59333 + 0x08 NMIP_CNT Not My IP counter
59334 + 0x0C AR_CNT Auto-Response counter
59335 + 0x10 CSERR_CNT Checksum Error counter
59336 + 0x14 MCAST_CNT Multicast counter
59337 + 0x18 Reserved Reserved
59338 + 0x1C Reserved Reserved
59339 +
59340 +*//***************************************************************************/
59341 +typedef _Packed struct
59342 +{
59343 + uint32_t invalCnt; /**< Invalid ICMPv4 Echo counter. */
59344 + uint32_t nmVlanCnt; /**< Not My VLAN counter */
59345 + uint32_t nmIpCnt; /**< Not My IP counter */
59346 + uint32_t arCnt; /**< Auto-Response counter */
59347 + uint32_t reserved1; /**< Reserved */
59348 + uint32_t reserved2; /**< Reserved */
59349 + uint32_t reserved3; /**< Reserved */
59350 + uint32_t reserved4; /**< Reserved */
59351 +} _PackedType t_DsarIcmpV6Statistics;
59352 +
59353 +/**************************************************************************//**
59354 + @Description Deep Sleep Auto Response Neighbor Discovery Statistics Descriptor
59355 + 0x00 INVAL_CNT Invalid Neighbor Discovery message counter
59356 + 0x04 NMVLAN_CNT Not My VLAN counter
59357 + 0x08 NMIP_CNT Not My IP counter
59358 + 0x0C AR_CNT Auto-Response counter
59359 + 0x10 CSERR_CNT Checksum Error counter
59360 + 0x14 USADVERT_CNT Unsolicited Neighbor Advertisements counter
59361 + 0x18 NMMCAST_CNT Not My Multicast group counter
59362 + 0x1C NSLLA_CNT No Source Link-Layer Address counter. Indicates that there was a match on a Target
59363 + Address of a packet that its source IP address is a unicast address, but the ICMPv6
59364 + Source Link-layer Address option is omitted
59365 +*//***************************************************************************/
59366 +typedef _Packed struct
59367 +{
59368 + uint32_t invalCnt; /**< Invalid ICMPv4 Echo counter. */
59369 + uint32_t nmVlanCnt; /**< Not My VLAN counter */
59370 + uint32_t nmIpCnt; /**< Not My IP counter */
59371 + uint32_t arCnt; /**< Auto-Response counter */
59372 + uint32_t reserved1; /**< Reserved */
59373 + uint32_t usadvertCnt; /**< Unsolicited Neighbor Advertisements counter */
59374 + uint32_t nmmcastCnt; /**< Not My Multicast group counter */
59375 + uint32_t nsllaCnt; /**< No Source Link-Layer Address counter */
59376 +} _PackedType t_NdStatistics;
59377 +
59378 +/**************************************************************************//**
59379 + @Description Deep Sleep Auto Response ICMPv6 Descriptor
59380 + 0x0 0-15 Control bits [0-15]
59381 + 0x2 0-15 NumOfBindings Number of entries in the binding list.
59382 + 0x4 0-15 BindingsPointer Bindings Pointer. This points to an VLAN-IPv4 Addresses Bindings list.
59383 + 0x6 0-15
59384 + 0x8 0-15 StatisticsPointer Statistics Pointer. This field points to the ICMPv4 statistics data structure.
59385 + 0xA 0-15
59386 + 0xC 0-15 Reserved Reserved. Must be cleared.
59387 + 0xE 015
59388 +
59389 +*//***************************************************************************/
59390 +typedef _Packed struct
59391 +{
59392 + uint16_t control; /** Control bits [0-15]. */
59393 + uint16_t numOfBindings; /**< Number of VLAN-IPv6 */
59394 + uint32_t p_Bindings; /**< VLAN-IPv4 Bindings table pointer. */
59395 + uint32_t p_Statistics; /**< Statistics Data Structure pointer. */
59396 + uint32_t reserved1; /**< Reserved. */
59397 +} _PackedType t_DsarIcmpV6Descriptor;
59398 +
59399 +
59400 +/**************************************************************************//**
59401 + @Description Internet Control Message Protocol (ICMPv6) Echo message header
59402 + The fields names are taken from RFC 4443.
59403 +*//***************************************************************************/
59404 +/* 0 1 2 3 */
59405 +/* 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 */
59406 +/* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ */
59407 +/* | Type | Code | Checksum | */
59408 +/* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ */
59409 +/* | Identifier | Sequence Number | */
59410 +/* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ */
59411 +/* | Data ... */
59412 +/* +-+-+-+-+- */
59413 +typedef _Packed struct
59414 +{
59415 + uint8_t type;
59416 + uint8_t code;
59417 + uint16_t checksum;
59418 + uint16_t identifier;
59419 + uint16_t sequenceNumber;
59420 +} _PackedType t_IcmpV6EchoHdr;
59421 +
59422 +/**************************************************************************//**
59423 + @Description Internet Control Message Protocol (ICMPv6)
59424 + Neighbor Solicitation/Advertisement header
59425 + The fields names are taken from RFC 4861.
59426 + The R/S/O fields are valid for Neighbor Advertisement only
59427 +*//***************************************************************************/
59428 +/* 0 1 2 3
59429 + * 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
59430 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
59431 + * | Type | Code | Checksum |
59432 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
59433 + * |R|S|O| Reserved |
59434 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
59435 + * | |
59436 + * + +
59437 + * | |
59438 + * + Target Address +
59439 + * | |
59440 + * + +
59441 + * | |
59442 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
59443 + * | Options ...
59444 + * +-+-+-+-+-+-+-+-+-+-+-+-
59445 + *
59446 + * Options Format:
59447 + * 0 1 2 3
59448 + * 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
59449 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
59450 + * | Type | Length | Link-Layer Address ... |
59451 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
59452 + * | Link-Layer Address |
59453 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
59454 +*/
59455 +typedef _Packed struct
59456 +{
59457 + uint8_t type;
59458 + uint8_t code;
59459 + uint16_t checksum;
59460 + uint32_t router:1;
59461 + uint32_t solicited:1;
59462 + uint32_t override:1;
59463 + uint32_t reserved:29;
59464 + uint32_t targetAddr[4];
59465 + uint8_t optionType;
59466 + uint8_t optionLength;
59467 + uint8_t linkLayerAddr[6];
59468 +} _PackedType t_IcmpV6NdHdr;
59469 +
59470 +/**************************************************************************//**
59471 + @Description Deep Sleep Auto Response ICMPv6 Descriptor
59472 + 0x0 0-15 Control bits [0-15]
59473 + 0x2 0-15 NumOfBindings Number of entries in the binding list.
59474 + 0x4 0-15 BindingsPointer Bindings Pointer. This points to an VLAN-IPv4 Addresses Bindings list.
59475 + 0x6 0-15
59476 + 0x8 0-15 StatisticsPointer Statistics Pointer. This field points to the ICMPv4 statistics data structure.
59477 + 0xA 0-15
59478 + 0xC 0-15 Reserved Reserved. Must be cleared.
59479 + 0xE 015
59480 +
59481 +*//***************************************************************************/
59482 +typedef _Packed struct
59483 +{
59484 + uint16_t control; /** Control bits [0-15]. */
59485 + uint16_t numOfBindings; /**< Number of VLAN-IPv6 */
59486 + uint32_t p_Bindings; /**< VLAN-IPv4 Bindings table pointer. */
59487 + uint32_t p_Statistics; /**< Statistics Data Structure pointer. */
59488 + uint32_t solicitedAddr; /**< Solicited Node Multicast Group Address */
59489 +} _PackedType t_DsarNdDescriptor;
59490 +
59491 +/**************************************************************************//**
59492 +@Description Deep Sleep Auto Response SNMP OIDs table entry
59493 +
59494 +*//***************************************************************************/
59495 +typedef struct {
59496 + uint16_t oidSize; /**< Size in octets of the OID. */
59497 + uint16_t resSize; /**< Size in octets of the value that is attached to the OID. */
59498 + uint32_t p_Oid; /**< Pointer to the OID. OID is encoded in BER but type and length are excluded. */
59499 + uint32_t resValOrPtr; /**< Value (for up to 4 octets) or pointer to the Value. Encoded in BER. */
59500 + uint32_t reserved;
59501 +} t_OidsTblEntry;
59502 +
59503 +/**************************************************************************//**
59504 + @Description Deep Sleep Auto Response SNMP IPv4 Addresses Table Entry
59505 + Refer to the FMan Controller spec for more details.
59506 +*//***************************************************************************/
59507 +typedef struct
59508 +{
59509 + uint32_t ipv4Addr; /*!< 32 bit IPv4 Address. */
59510 + uint16_t vlanId; /*!< 12 bits VLAN ID. The 4 left-most bits should be cleared */
59511 + /*!< This field should be 0x0000 for an entry with no VLAN tag or a null VLAN ID. */
59512 + uint16_t reserved;
59513 +} t_DsarSnmpIpv4AddrTblEntry;
59514 +
59515 +/**************************************************************************//**
59516 + @Description Deep Sleep Auto Response SNMP IPv6 Addresses Table Entry
59517 + Refer to the FMan Controller spec for more details.
59518 +*//***************************************************************************/
59519 +#pragma pack(push,1)
59520 +typedef struct
59521 +{
59522 + uint32_t ipv6Addr[4]; /*!< 4 * 32 bit IPv6 Address. */
59523 + uint16_t vlanId; /*!< 12 bits VLAN ID. The 4 left-most bits should be cleared */
59524 + /*!< This field should be 0x0000 for an entry with no VLAN tag or a null VLAN ID. */
59525 + uint16_t reserved;
59526 +} t_DsarSnmpIpv6AddrTblEntry;
59527 +#pragma pack(pop)
59528 +
59529 +/**************************************************************************//**
59530 +@Description Deep Sleep Auto Response SNMP statistics table
59531 +
59532 +*//***************************************************************************/
59533 +typedef struct {
59534 + uint32_t snmpErrCnt; /**< Counts SNMP errors (wrong version, BER encoding, format). */
59535 + uint32_t snmpCommunityErrCnt; /**< Counts messages that were dropped due to insufficient permission. */
59536 + uint32_t snmpTotalDiscardCnt; /**< Counts any message that was dropped. */
59537 + uint32_t snmpGetReqCnt; /**< Counts the number of get-request messages */
59538 + uint32_t snmpGetNextReqCnt; /**< Counts the number of get-next-request messages */
59539 +} t_DsarSnmpStatistics;
59540 +
59541 +/**************************************************************************//**
59542 + @Description Deep Sleep Auto Response SNMP Descriptor
59543 +
59544 +*//***************************************************************************/
59545 +typedef struct
59546 +{
59547 + uint16_t control; /**< Control bits [0-15]. */
59548 + uint16_t maxSnmpMsgLength; /**< Maximal allowed SNMP message length. */
59549 + uint16_t numOfIpv4Addresses; /**< Number of entries in IPv4 addresses table. */
59550 + uint16_t numOfIpv6Addresses; /**< Number of entries in IPv6 addresses table. */
59551 + uint32_t p_Ipv4AddrTbl; /**< Pointer to IPv4 addresses table. */
59552 + uint32_t p_Ipv6AddrTbl; /**< Pointer to IPv6 addresses table. */
59553 + uint32_t p_RdOnlyCommunityStr; /**< Pointer to the Read Only Community String. */
59554 + uint32_t p_RdWrCommunityStr; /**< Pointer to the Read Write Community String. */
59555 + uint32_t p_OidsTbl; /**< Pointer to OIDs table. */
59556 + uint32_t oidsTblSize; /**< Number of entries in OIDs table. */
59557 + uint32_t p_Statistics; /**< Pointer to SNMP statistics table. */
59558 +} t_DsarSnmpDescriptor;
59559 +
59560 +/**************************************************************************//**
59561 +@Description Deep Sleep Auto Response (Common) Statistics
59562 +
59563 +*//***************************************************************************/
59564 +typedef _Packed struct {
59565 + uint32_t dsarDiscarded;
59566 + uint32_t dsarErrDiscarded;
59567 + uint32_t dsarFragDiscarded;
59568 + uint32_t dsarTunnelDiscarded;
59569 + uint32_t dsarArpDiscarded;
59570 + uint32_t dsarIpDiscarded;
59571 + uint32_t dsarTcpDiscarded;
59572 + uint32_t dsarUdpDiscarded;
59573 + uint32_t dsarIcmpV6ChecksumErr; /* ICMPv6 Checksum Error counter */
59574 + uint32_t dsarIcmpV6OtherType; /* ICMPv6 'Other' type (not Echo or Neighbor Solicitaion/Advertisement counter */
59575 + uint32_t dsarIcmpV4OtherType; /* ICMPv4 'Other' type (not Echo) counter */
59576 +} _PackedType t_ArStatistics;
59577 +
59578 +
59579 +/**************************************************************************//**
59580 +@Description Deep Sleep Auto Response TCP/UDP port filter table entry
59581 +
59582 +*//***************************************************************************/
59583 +typedef _Packed struct {
59584 + uint32_t Ports;
59585 + uint32_t PortsMask;
59586 +} _PackedType t_PortTblEntry;
59587 +
59588 +
59589 +
59590 +/**************************************************************************//**
59591 +@Description Deep Sleep Auto Response Common Parameters Descriptor
59592 +
59593 +*//***************************************************************************/
59594 +typedef _Packed struct {
59595 + uint8_t arTxPort; /* 0x00 0-7 Auto Response Transmit Port number */
59596 + uint8_t controlBits; /* 0x00 8-15 Auto Response control bits */
59597 + uint16_t res1; /* 0x00 16-31 Reserved */
59598 + uint32_t activeHPNIA; /* 0x04 0-31 Active mode Hardware Parser NIA */
59599 + uint16_t snmpPort; /* 0x08 0-15 SNMP Port. */
59600 + uint8_t macStationAddr[6]; /* 0x08 16-31 and 0x0C 0-31 MAC Station Address */
59601 + uint8_t res2; /* 0x10 0-7 Reserved */
59602 + uint8_t filterControl; /* 0x10 8-15 Filtering Control Bits. */
59603 + uint16_t tcpControlPass; /* 0x10 16-31 TCP control pass flags */
59604 + uint8_t ipProtocolTblSize; /* 0x14 0-7 IP Protocol Table Size. */
59605 + uint8_t udpPortTblSize; /* 0x14 8-15 UDP Port Table Size. */
59606 + uint8_t tcpPortTblSize; /* 0x14 16-23 TCP Port Table Size. */
59607 + uint8_t res3; /* 0x14 24-31 Reserved */
59608 + uint32_t p_IpProtocolFiltTbl; /* 0x18 0-31 Pointer to IP Protocol Filter Table */
59609 + uint32_t p_UdpPortFiltTbl; /* 0x1C 0-31 Pointer to UDP Port Filter Table */
59610 + uint32_t p_TcpPortFiltTbl; /* 0x20 0-31 Pointer to TCP Port Filter Table */
59611 + uint32_t res4; /* 0x24 Reserved */
59612 + uint32_t p_ArpDescriptor; /* 0x28 0-31 ARP Descriptor Pointer. */
59613 + uint32_t p_NdDescriptor; /* 0x2C 0-31 Neighbor Discovery Descriptor. */
59614 + uint32_t p_IcmpV4Descriptor; /* 0x30 0-31 ICMPv4 Descriptor pointer. */
59615 + uint32_t p_IcmpV6Descriptor; /* 0x34 0-31 ICMPv6 Descriptor pointer. */
59616 + uint32_t p_SnmpDescriptor; /* 0x38 0-31 SNMP Descriptor pointer. */
59617 + uint32_t p_ArStats; /* 0x3C 0-31 Pointer to Auto Response Statistics */
59618 +} _PackedType t_ArCommonDesc;
59619 +
59620 +#if defined(__MWERKS__) && !defined(__GNUC__)
59621 +#pragma pack(pop)
59622 +#endif /* defined(__MWERKS__) && ... */
59623 +
59624 +/* t_ArCommonDesc.filterControl bits */
59625 +#define IP_PROT_TBL_PASS_MASK 0x08
59626 +#define UDP_PORT_TBL_PASS_MASK 0x04
59627 +#define TCP_PORT_TBL_PASS_MASK 0x02
59628 +
59629 +/* Offset of TCF flags within TCP packet */
59630 +#define TCP_FLAGS_OFFSET 12
59631 +
59632 +
59633 +#endif /* __FM_PORT_DSAR_H_ */
59634 --- /dev/null
59635 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Port/fm_port_im.c
59636 @@ -0,0 +1,753 @@
59637 +/*
59638 + * Copyright 2008-2012 Freescale Semiconductor Inc.
59639 + *
59640 + * Redistribution and use in source and binary forms, with or without
59641 + * modification, are permitted provided that the following conditions are met:
59642 + * * Redistributions of source code must retain the above copyright
59643 + * notice, this list of conditions and the following disclaimer.
59644 + * * Redistributions in binary form must reproduce the above copyright
59645 + * notice, this list of conditions and the following disclaimer in the
59646 + * documentation and/or other materials provided with the distribution.
59647 + * * Neither the name of Freescale Semiconductor nor the
59648 + * names of its contributors may be used to endorse or promote products
59649 + * derived from this software without specific prior written permission.
59650 + *
59651 + *
59652 + * ALTERNATIVELY, this software may be distributed under the terms of the
59653 + * GNU General Public License ("GPL") as published by the Free Software
59654 + * Foundation, either version 2 of that License or (at your option) any
59655 + * later version.
59656 + *
59657 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
59658 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
59659 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
59660 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
59661 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
59662 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
59663 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
59664 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
59665 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
59666 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
59667 + */
59668 +
59669 +
59670 +/******************************************************************************
59671 + @File fm_port_im.c
59672 +
59673 + @Description FM Port Independent-Mode ...
59674 +*//***************************************************************************/
59675 +#include "std_ext.h"
59676 +#include "string_ext.h"
59677 +#include "error_ext.h"
59678 +#include "memcpy_ext.h"
59679 +#include "fm_muram_ext.h"
59680 +
59681 +#include "fm_port.h"
59682 +
59683 +
59684 +#define TX_CONF_STATUS_UNSENT 0x1
59685 +
59686 +
59687 +typedef enum e_TxConfType
59688 +{
59689 + e_TX_CONF_TYPE_CHECK = 0 /**< check if all the buffers were touched by the muxator, no confirmation callback */
59690 + ,e_TX_CONF_TYPE_CALLBACK = 1 /**< confirm to user all the available sent buffers */
59691 + ,e_TX_CONF_TYPE_FLUSH = 3 /**< confirm all buffers plus the unsent one with an appropriate status */
59692 +} e_TxConfType;
59693 +
59694 +
59695 +static void ImException(t_Handle h_FmPort, uint32_t event)
59696 +{
59697 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
59698 +
59699 + ASSERT_COND(((event & (IM_EV_RX | IM_EV_BSY)) && FmIsMaster(p_FmPort->h_Fm)) ||
59700 + !FmIsMaster(p_FmPort->h_Fm));
59701 +
59702 + if (event & IM_EV_RX)
59703 + FmPortImRx(p_FmPort);
59704 + if ((event & IM_EV_BSY) && p_FmPort->f_Exception)
59705 + p_FmPort->f_Exception(p_FmPort->h_App, e_FM_PORT_EXCEPTION_IM_BUSY);
59706 +}
59707 +
59708 +
59709 +static t_Error TxConf(t_FmPort *p_FmPort, e_TxConfType confType)
59710 +{
59711 + t_Error retVal = E_BUSY;
59712 + uint32_t bdStatus;
59713 + uint16_t savedStartBdId, confBdId;
59714 +
59715 + ASSERT_COND(p_FmPort);
59716 +
59717 + /*
59718 + if (confType==e_TX_CONF_TYPE_CHECK)
59719 + return (WfqEntryIsQueueEmpty(p_FmPort->im.h_WfqEntry) ? E_OK : E_BUSY);
59720 + */
59721 +
59722 + confBdId = savedStartBdId = p_FmPort->im.currBdId;
59723 + bdStatus = BD_STATUS_AND_LENGTH(BD_GET(confBdId));
59724 +
59725 + /* If R bit is set, we don't enter, or we break.
59726 + we run till we get to R, or complete the loop */
59727 + while ((!(bdStatus & BD_R_E) || (confType == e_TX_CONF_TYPE_FLUSH)) && (retVal != E_OK))
59728 + {
59729 + if (confType & e_TX_CONF_TYPE_CALLBACK) /* if it is confirmation with user callbacks */
59730 + BD_STATUS_AND_LENGTH_SET(BD_GET(confBdId), 0);
59731 +
59732 + /* case 1: R bit is 0 and Length is set -> confirm! */
59733 + if ((confType & e_TX_CONF_TYPE_CALLBACK) && (bdStatus & BD_LENGTH_MASK))
59734 + {
59735 + if (p_FmPort->im.f_TxConf)
59736 + {
59737 + if ((confType == e_TX_CONF_TYPE_FLUSH) && (bdStatus & BD_R_E))
59738 + p_FmPort->im.f_TxConf(p_FmPort->h_App,
59739 + BdBufferGet(XX_PhysToVirt, BD_GET(confBdId)),
59740 + TX_CONF_STATUS_UNSENT,
59741 + p_FmPort->im.p_BdShadow[confBdId]);
59742 + else
59743 + p_FmPort->im.f_TxConf(p_FmPort->h_App,
59744 + BdBufferGet(XX_PhysToVirt, BD_GET(confBdId)),
59745 + 0,
59746 + p_FmPort->im.p_BdShadow[confBdId]);
59747 + }
59748 + }
59749 + /* case 2: R bit is 0 and Length is 0 -> not used yet, nop! */
59750 +
59751 + confBdId = GetNextBdId(p_FmPort, confBdId);
59752 + if (confBdId == savedStartBdId)
59753 + retVal = E_OK;
59754 + bdStatus = BD_STATUS_AND_LENGTH(BD_GET(confBdId));
59755 + }
59756 +
59757 + return retVal;
59758 +}
59759 +
59760 +t_Error FmPortImEnable(t_FmPort *p_FmPort)
59761 +{
59762 + uint32_t tmpReg = GET_UINT32(p_FmPort->im.p_FmPortImPram->mode);
59763 + WRITE_UINT32(p_FmPort->im.p_FmPortImPram->mode, (uint32_t)(tmpReg & ~IM_MODE_GRC_STP));
59764 + return E_OK;
59765 +}
59766 +
59767 +t_Error FmPortImDisable(t_FmPort *p_FmPort)
59768 +{
59769 + uint32_t tmpReg = GET_UINT32(p_FmPort->im.p_FmPortImPram->mode);
59770 + WRITE_UINT32(p_FmPort->im.p_FmPortImPram->mode, (uint32_t)(tmpReg | IM_MODE_GRC_STP));
59771 + return E_OK;
59772 +}
59773 +
59774 +t_Error FmPortImRx(t_FmPort *p_FmPort)
59775 +{
59776 + t_Handle h_CurrUserPriv, h_NewUserPriv;
59777 + uint32_t bdStatus;
59778 + volatile uint8_t buffPos;
59779 + uint16_t length;
59780 + uint16_t errors;
59781 + uint8_t *p_CurData, *p_Data;
59782 + uint32_t flags;
59783 +
59784 + ASSERT_COND(p_FmPort);
59785 +
59786 + flags = XX_LockIntrSpinlock(p_FmPort->h_Spinlock);
59787 + if (p_FmPort->lock)
59788 + {
59789 + XX_UnlockIntrSpinlock(p_FmPort->h_Spinlock, flags);
59790 + return E_OK;
59791 + }
59792 + p_FmPort->lock = TRUE;
59793 + XX_UnlockIntrSpinlock(p_FmPort->h_Spinlock, flags);
59794 +
59795 + bdStatus = BD_STATUS_AND_LENGTH(BD_GET(p_FmPort->im.currBdId));
59796 +
59797 + while (!(bdStatus & BD_R_E)) /* while there is data in the Rx BD */
59798 + {
59799 + if ((p_Data = p_FmPort->im.rxPool.f_GetBuf(p_FmPort->im.rxPool.h_BufferPool, &h_NewUserPriv)) == NULL)
59800 + {
59801 + p_FmPort->lock = FALSE;
59802 + RETURN_ERROR(MAJOR, E_NOT_AVAILABLE, ("Data buffer"));
59803 + }
59804 +
59805 + if (p_FmPort->im.firstBdOfFrameId == IM_ILEGAL_BD_ID)
59806 + p_FmPort->im.firstBdOfFrameId = p_FmPort->im.currBdId;
59807 +
59808 + p_CurData = BdBufferGet(p_FmPort->im.rxPool.f_PhysToVirt, BD_GET(p_FmPort->im.currBdId));
59809 + h_CurrUserPriv = p_FmPort->im.p_BdShadow[p_FmPort->im.currBdId];
59810 + length = (uint16_t)((bdStatus & BD_L) ?
59811 + ((bdStatus & BD_LENGTH_MASK) - p_FmPort->im.rxFrameAccumLength):
59812 + (bdStatus & BD_LENGTH_MASK));
59813 + p_FmPort->im.rxFrameAccumLength += length;
59814 +
59815 + /* determine whether buffer is first, last, first and last (single */
59816 + /* buffer frame) or middle (not first and not last) */
59817 + buffPos = (uint8_t)((p_FmPort->im.currBdId == p_FmPort->im.firstBdOfFrameId) ?
59818 + ((bdStatus & BD_L) ? SINGLE_BUF : FIRST_BUF) :
59819 + ((bdStatus & BD_L) ? LAST_BUF : MIDDLE_BUF));
59820 +
59821 + if (bdStatus & BD_L)
59822 + {
59823 + p_FmPort->im.rxFrameAccumLength = 0;
59824 + p_FmPort->im.firstBdOfFrameId = IM_ILEGAL_BD_ID;
59825 + }
59826 +
59827 + BdBufferSet(p_FmPort->im.rxPool.f_VirtToPhys, BD_GET(p_FmPort->im.currBdId), p_Data);
59828 +
59829 + BD_STATUS_AND_LENGTH_SET(BD_GET(p_FmPort->im.currBdId), BD_R_E);
59830 +
59831 + errors = (uint16_t)((bdStatus & BD_RX_ERRORS) >> 16);
59832 + p_FmPort->im.p_BdShadow[p_FmPort->im.currBdId] = h_NewUserPriv;
59833 +
59834 + p_FmPort->im.currBdId = GetNextBdId(p_FmPort, p_FmPort->im.currBdId);
59835 + WRITE_UINT16(p_FmPort->im.p_FmPortImPram->rxQd.offsetOut, (uint16_t)(p_FmPort->im.currBdId<<4));
59836 + /* Pass the buffer if one of the conditions is true:
59837 + - There are no errors
59838 + - This is a part of a larger frame ( the application has already received some buffers ) */
59839 + if ((buffPos != SINGLE_BUF) || !errors)
59840 + {
59841 + if (p_FmPort->im.f_RxStore(p_FmPort->h_App,
59842 + p_CurData,
59843 + length,
59844 + errors,
59845 + buffPos,
59846 + h_CurrUserPriv) == e_RX_STORE_RESPONSE_PAUSE)
59847 + break;
59848 + }
59849 + else if (p_FmPort->im.rxPool.f_PutBuf(p_FmPort->im.rxPool.h_BufferPool,
59850 + p_CurData,
59851 + h_CurrUserPriv))
59852 + {
59853 + p_FmPort->lock = FALSE;
59854 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Failed freeing data buffer"));
59855 + }
59856 +
59857 + bdStatus = BD_STATUS_AND_LENGTH(BD_GET(p_FmPort->im.currBdId));
59858 + }
59859 + p_FmPort->lock = FALSE;
59860 + return E_OK;
59861 +}
59862 +
59863 +void FmPortConfigIM (t_FmPort *p_FmPort, t_FmPortParams *p_FmPortParams)
59864 +{
59865 + ASSERT_COND(p_FmPort);
59866 +
59867 + SANITY_CHECK_RETURN(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
59868 +
59869 + p_FmPort->im.h_FmMuram = p_FmPortParams->specificParams.imRxTxParams.h_FmMuram;
59870 + p_FmPort->p_FmPortDriverParam->liodnOffset = p_FmPortParams->specificParams.imRxTxParams.liodnOffset;
59871 + p_FmPort->im.dataMemId = p_FmPortParams->specificParams.imRxTxParams.dataMemId;
59872 + p_FmPort->im.dataMemAttributes = p_FmPortParams->specificParams.imRxTxParams.dataMemAttributes;
59873 +
59874 + p_FmPort->im.fwExtStructsMemId = DEFAULT_PORT_ImfwExtStructsMemId;
59875 + p_FmPort->im.fwExtStructsMemAttr = DEFAULT_PORT_ImfwExtStructsMemAttr;
59876 +
59877 + if ((p_FmPort->portType == e_FM_PORT_TYPE_RX) ||
59878 + (p_FmPort->portType == e_FM_PORT_TYPE_RX_10G))
59879 + {
59880 + p_FmPort->im.rxPool.h_BufferPool = p_FmPortParams->specificParams.imRxTxParams.rxPoolParams.h_BufferPool;
59881 + p_FmPort->im.rxPool.f_GetBuf = p_FmPortParams->specificParams.imRxTxParams.rxPoolParams.f_GetBuf;
59882 + p_FmPort->im.rxPool.f_PutBuf = p_FmPortParams->specificParams.imRxTxParams.rxPoolParams.f_PutBuf;
59883 + p_FmPort->im.rxPool.bufferSize = p_FmPortParams->specificParams.imRxTxParams.rxPoolParams.bufferSize;
59884 + p_FmPort->im.rxPool.f_PhysToVirt = p_FmPortParams->specificParams.imRxTxParams.rxPoolParams.f_PhysToVirt;
59885 + if (!p_FmPort->im.rxPool.f_PhysToVirt)
59886 + p_FmPort->im.rxPool.f_PhysToVirt = XX_PhysToVirt;
59887 + p_FmPort->im.rxPool.f_VirtToPhys = p_FmPortParams->specificParams.imRxTxParams.rxPoolParams.f_VirtToPhys;
59888 + if (!p_FmPort->im.rxPool.f_VirtToPhys)
59889 + p_FmPort->im.rxPool.f_VirtToPhys = XX_VirtToPhys;
59890 + p_FmPort->im.f_RxStore = p_FmPortParams->specificParams.imRxTxParams.f_RxStore;
59891 +
59892 + p_FmPort->im.mrblr = 0x8000;
59893 + while (p_FmPort->im.mrblr)
59894 + {
59895 + if (p_FmPort->im.rxPool.bufferSize & p_FmPort->im.mrblr)
59896 + break;
59897 + p_FmPort->im.mrblr >>= 1;
59898 + }
59899 + if (p_FmPort->im.mrblr != p_FmPort->im.rxPool.bufferSize)
59900 + DBG(WARNING, ("Max-Rx-Buffer-Length set to %d", p_FmPort->im.mrblr));
59901 + p_FmPort->im.bdRingSize = DEFAULT_PORT_rxBdRingLength;
59902 + p_FmPort->exceptions = DEFAULT_PORT_exception;
59903 + if (FmIsMaster(p_FmPort->h_Fm))
59904 + p_FmPort->polling = FALSE;
59905 + else
59906 + p_FmPort->polling = TRUE;
59907 + p_FmPort->fmanCtrlEventId = (uint8_t)NO_IRQ;
59908 + }
59909 + else
59910 + {
59911 + p_FmPort->im.f_TxConf = p_FmPortParams->specificParams.imRxTxParams.f_TxConf;
59912 +
59913 + p_FmPort->im.bdRingSize = DEFAULT_PORT_txBdRingLength;
59914 + }
59915 +}
59916 +
59917 +t_Error FmPortImCheckInitParameters(t_FmPort *p_FmPort)
59918 +{
59919 + if ((p_FmPort->portType != e_FM_PORT_TYPE_RX) &&
59920 + (p_FmPort->portType != e_FM_PORT_TYPE_RX_10G) &&
59921 + (p_FmPort->portType != e_FM_PORT_TYPE_TX) &&
59922 + (p_FmPort->portType != e_FM_PORT_TYPE_TX_10G))
59923 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, NO_MSG);
59924 +
59925 + if ((p_FmPort->portType == e_FM_PORT_TYPE_RX) ||
59926 + (p_FmPort->portType == e_FM_PORT_TYPE_RX_10G))
59927 + {
59928 + if (!POWER_OF_2(p_FmPort->im.mrblr))
59929 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("max Rx buffer length must be power of 2!!!"));
59930 + if (p_FmPort->im.mrblr < 256)
59931 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("max Rx buffer length must at least 256!!!"));
59932 + if (p_FmPort->p_FmPortDriverParam->liodnOffset & ~FM_LIODN_OFFSET_MASK)
59933 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("liodnOffset is larger than %d", FM_LIODN_OFFSET_MASK+1));
59934 + }
59935 +
59936 + return E_OK;
59937 +}
59938 +
59939 +t_Error FmPortImInit(t_FmPort *p_FmPort)
59940 +{
59941 + t_FmImBd *p_Bd=NULL;
59942 + t_Handle h_BufContext;
59943 + uint64_t tmpPhysBase;
59944 + uint16_t log2Num;
59945 + uint8_t *p_Data/*, *p_Tmp*/;
59946 + int i;
59947 + t_Error err;
59948 + uint16_t tmpReg16;
59949 + uint32_t tmpReg32;
59950 +
59951 + ASSERT_COND(p_FmPort);
59952 +
59953 + p_FmPort->im.p_FmPortImPram =
59954 + (t_FmPortImPram *)FM_MURAM_AllocMem(p_FmPort->im.h_FmMuram, sizeof(t_FmPortImPram), IM_PRAM_ALIGN);
59955 + if (!p_FmPort->im.p_FmPortImPram)
59956 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("Independent-Mode Parameter-RAM!!!"));
59957 + WRITE_BLOCK(p_FmPort->im.p_FmPortImPram, 0, sizeof(t_FmPortImPram));
59958 +
59959 + if ((p_FmPort->portType == e_FM_PORT_TYPE_RX) ||
59960 + (p_FmPort->portType == e_FM_PORT_TYPE_RX_10G))
59961 + {
59962 + p_FmPort->im.p_BdRing =
59963 + (t_FmImBd *)XX_MallocSmart((uint32_t)(sizeof(t_FmImBd)*p_FmPort->im.bdRingSize),
59964 + p_FmPort->im.fwExtStructsMemId,
59965 + 4);
59966 + if (!p_FmPort->im.p_BdRing)
59967 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("Independent-Mode Rx BD ring!!!"));
59968 + IOMemSet32(p_FmPort->im.p_BdRing, 0, (uint32_t)(sizeof(t_FmImBd)*p_FmPort->im.bdRingSize));
59969 +
59970 + p_FmPort->im.p_BdShadow = (t_Handle *)XX_Malloc((uint32_t)(sizeof(t_Handle)*p_FmPort->im.bdRingSize));
59971 + if (!p_FmPort->im.p_BdShadow)
59972 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("Independent-Mode Rx BD shadow!!!"));
59973 + memset(p_FmPort->im.p_BdShadow, 0, (uint32_t)(sizeof(t_Handle)*p_FmPort->im.bdRingSize));
59974 +
59975 + /* Initialize the Rx-BD ring */
59976 + for (i=0; i<p_FmPort->im.bdRingSize; i++)
59977 + {
59978 + p_Bd = BD_GET(i);
59979 + BD_STATUS_AND_LENGTH_SET (p_Bd, BD_R_E);
59980 +
59981 + if ((p_Data = p_FmPort->im.rxPool.f_GetBuf(p_FmPort->im.rxPool.h_BufferPool, &h_BufContext)) == NULL)
59982 + RETURN_ERROR(MAJOR, E_NOT_AVAILABLE, ("Data buffer"));
59983 + BdBufferSet(p_FmPort->im.rxPool.f_VirtToPhys, p_Bd, p_Data);
59984 + p_FmPort->im.p_BdShadow[i] = h_BufContext;
59985 + }
59986 +
59987 + if ((p_FmPort->im.dataMemAttributes & MEMORY_ATTR_CACHEABLE) ||
59988 + (p_FmPort->im.fwExtStructsMemAttr & MEMORY_ATTR_CACHEABLE))
59989 + WRITE_UINT32(p_FmPort->im.p_FmPortImPram->mode, IM_MODE_GBL | IM_MODE_SET_BO(2));
59990 + else
59991 + WRITE_UINT32(p_FmPort->im.p_FmPortImPram->mode, IM_MODE_SET_BO(2));
59992 +
59993 + WRITE_UINT32(p_FmPort->im.p_FmPortImPram->rxQdPtr,
59994 + (uint32_t)((uint64_t)(XX_VirtToPhys(p_FmPort->im.p_FmPortImPram)) -
59995 + p_FmPort->fmMuramPhysBaseAddr + 0x20));
59996 +
59997 + LOG2((uint64_t)p_FmPort->im.mrblr, log2Num);
59998 + WRITE_UINT16(p_FmPort->im.p_FmPortImPram->mrblr, log2Num);
59999 +
60000 + /* Initialize Rx QD */
60001 + tmpPhysBase = (uint64_t)(XX_VirtToPhys(p_FmPort->im.p_BdRing));
60002 + SET_ADDR(&p_FmPort->im.p_FmPortImPram->rxQd.bdRingBase, tmpPhysBase);
60003 + WRITE_UINT16(p_FmPort->im.p_FmPortImPram->rxQd.bdRingSize, (uint16_t)(sizeof(t_FmImBd)*p_FmPort->im.bdRingSize));
60004 +
60005 + /* Update the IM PRAM address in the BMI */
60006 + WRITE_UINT32(p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rfqid,
60007 + (uint32_t)((uint64_t)(XX_VirtToPhys(p_FmPort->im.p_FmPortImPram)) -
60008 + p_FmPort->fmMuramPhysBaseAddr));
60009 + if (!p_FmPort->polling || p_FmPort->exceptions)
60010 + {
60011 + /* Allocate, configure and register interrupts */
60012 + err = FmAllocFmanCtrlEventReg(p_FmPort->h_Fm, &p_FmPort->fmanCtrlEventId);
60013 + if (err)
60014 + RETURN_ERROR(MAJOR, err, NO_MSG);
60015 +
60016 + ASSERT_COND(!(p_FmPort->fmanCtrlEventId & ~IM_RXQD_FPMEVT_SEL_MASK));
60017 + tmpReg16 = (uint16_t)(p_FmPort->fmanCtrlEventId & IM_RXQD_FPMEVT_SEL_MASK);
60018 + tmpReg32 = 0;
60019 +
60020 + if (p_FmPort->exceptions & IM_EV_BSY)
60021 + {
60022 + tmpReg16 |= IM_RXQD_BSYINTM;
60023 + tmpReg32 |= IM_EV_BSY;
60024 + }
60025 + if (!p_FmPort->polling)
60026 + {
60027 + tmpReg16 |= IM_RXQD_RXFINTM;
60028 + tmpReg32 |= IM_EV_RX;
60029 + }
60030 + WRITE_UINT16(p_FmPort->im.p_FmPortImPram->rxQd.gen, tmpReg16);
60031 +
60032 + FmRegisterFmanCtrlIntr(p_FmPort->h_Fm, p_FmPort->fmanCtrlEventId, ImException , (t_Handle)p_FmPort);
60033 +
60034 + FmSetFmanCtrlIntr(p_FmPort->h_Fm, p_FmPort->fmanCtrlEventId, tmpReg32);
60035 + }
60036 + else
60037 + p_FmPort->fmanCtrlEventId = (uint8_t)NO_IRQ;
60038 + }
60039 + else
60040 + {
60041 + p_FmPort->im.p_BdRing = (t_FmImBd *)XX_MallocSmart((uint32_t)(sizeof(t_FmImBd)*p_FmPort->im.bdRingSize), p_FmPort->im.fwExtStructsMemId, 4);
60042 + if (!p_FmPort->im.p_BdRing)
60043 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("Independent-Mode Tx BD ring!!!"));
60044 + IOMemSet32(p_FmPort->im.p_BdRing, 0, (uint32_t)(sizeof(t_FmImBd)*p_FmPort->im.bdRingSize));
60045 +
60046 + p_FmPort->im.p_BdShadow = (t_Handle *)XX_Malloc((uint32_t)(sizeof(t_Handle)*p_FmPort->im.bdRingSize));
60047 + if (!p_FmPort->im.p_BdShadow)
60048 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("Independent-Mode Rx BD shadow!!!"));
60049 + memset(p_FmPort->im.p_BdShadow, 0, (uint32_t)(sizeof(t_Handle)*p_FmPort->im.bdRingSize));
60050 + p_FmPort->im.firstBdOfFrameId = IM_ILEGAL_BD_ID;
60051 +
60052 + if ((p_FmPort->im.dataMemAttributes & MEMORY_ATTR_CACHEABLE) ||
60053 + (p_FmPort->im.fwExtStructsMemAttr & MEMORY_ATTR_CACHEABLE))
60054 + WRITE_UINT32(p_FmPort->im.p_FmPortImPram->mode, IM_MODE_GBL | IM_MODE_SET_BO(2));
60055 + else
60056 + WRITE_UINT32(p_FmPort->im.p_FmPortImPram->mode, IM_MODE_SET_BO(2));
60057 +
60058 + WRITE_UINT32(p_FmPort->im.p_FmPortImPram->txQdPtr,
60059 + (uint32_t)((uint64_t)(XX_VirtToPhys(p_FmPort->im.p_FmPortImPram)) -
60060 + p_FmPort->fmMuramPhysBaseAddr + 0x40));
60061 +
60062 + /* Initialize Tx QD */
60063 + tmpPhysBase = (uint64_t)(XX_VirtToPhys(p_FmPort->im.p_BdRing));
60064 + SET_ADDR(&p_FmPort->im.p_FmPortImPram->txQd.bdRingBase, tmpPhysBase);
60065 + WRITE_UINT16(p_FmPort->im.p_FmPortImPram->txQd.bdRingSize, (uint16_t)(sizeof(t_FmImBd)*p_FmPort->im.bdRingSize));
60066 +
60067 + /* Update the IM PRAM address in the BMI */
60068 + WRITE_UINT32(p_FmPort->p_FmPortBmiRegs->txPortBmiRegs.fmbm_tcfqid,
60069 + (uint32_t)((uint64_t)(XX_VirtToPhys(p_FmPort->im.p_FmPortImPram)) -
60070 + p_FmPort->fmMuramPhysBaseAddr));
60071 + }
60072 +
60073 +
60074 + return E_OK;
60075 +}
60076 +
60077 +void FmPortImFree(t_FmPort *p_FmPort)
60078 +{
60079 + uint32_t bdStatus;
60080 + uint8_t *p_CurData;
60081 +
60082 + ASSERT_COND(p_FmPort);
60083 + ASSERT_COND(p_FmPort->im.p_FmPortImPram);
60084 +
60085 + if ((p_FmPort->portType == e_FM_PORT_TYPE_RX) ||
60086 + (p_FmPort->portType == e_FM_PORT_TYPE_RX_10G))
60087 + {
60088 + if (!p_FmPort->polling || p_FmPort->exceptions)
60089 + {
60090 + /* Deallocate and unregister interrupts */
60091 + FmSetFmanCtrlIntr(p_FmPort->h_Fm, p_FmPort->fmanCtrlEventId, 0);
60092 +
60093 + FmFreeFmanCtrlEventReg(p_FmPort->h_Fm, p_FmPort->fmanCtrlEventId);
60094 +
60095 + WRITE_UINT16(p_FmPort->im.p_FmPortImPram->rxQd.gen, 0);
60096 +
60097 + FmUnregisterFmanCtrlIntr(p_FmPort->h_Fm, p_FmPort->fmanCtrlEventId);
60098 + }
60099 + /* Try first clean what has received */
60100 + FmPortImRx(p_FmPort);
60101 +
60102 + /* Now, get rid of the the empty buffer! */
60103 + bdStatus = BD_STATUS_AND_LENGTH(BD_GET(p_FmPort->im.currBdId));
60104 +
60105 + while (bdStatus & BD_R_E) /* while there is data in the Rx BD */
60106 + {
60107 + p_CurData = BdBufferGet(p_FmPort->im.rxPool.f_PhysToVirt, BD_GET(p_FmPort->im.currBdId));
60108 +
60109 + BdBufferSet(p_FmPort->im.rxPool.f_VirtToPhys, BD_GET(p_FmPort->im.currBdId), NULL);
60110 + BD_STATUS_AND_LENGTH_SET(BD_GET(p_FmPort->im.currBdId), 0);
60111 +
60112 + p_FmPort->im.rxPool.f_PutBuf(p_FmPort->im.rxPool.h_BufferPool,
60113 + p_CurData,
60114 + p_FmPort->im.p_BdShadow[p_FmPort->im.currBdId]);
60115 +
60116 + p_FmPort->im.currBdId = GetNextBdId(p_FmPort, p_FmPort->im.currBdId);
60117 + bdStatus = BD_STATUS_AND_LENGTH(BD_GET(p_FmPort->im.currBdId));
60118 + }
60119 + }
60120 + else
60121 + TxConf(p_FmPort, e_TX_CONF_TYPE_FLUSH);
60122 +
60123 + FM_MURAM_FreeMem(p_FmPort->im.h_FmMuram, p_FmPort->im.p_FmPortImPram);
60124 +
60125 + if (p_FmPort->im.p_BdShadow)
60126 + XX_Free(p_FmPort->im.p_BdShadow);
60127 +
60128 + if (p_FmPort->im.p_BdRing)
60129 + XX_FreeSmart(p_FmPort->im.p_BdRing);
60130 +}
60131 +
60132 +
60133 +t_Error FM_PORT_ConfigIMMaxRxBufLength(t_Handle h_FmPort, uint16_t newVal)
60134 +{
60135 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
60136 +
60137 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
60138 + SANITY_CHECK_RETURN_ERROR(p_FmPort->imEn, E_INVALID_STATE);
60139 + SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
60140 +
60141 + p_FmPort->im.mrblr = newVal;
60142 +
60143 + return E_OK;
60144 +}
60145 +
60146 +t_Error FM_PORT_ConfigIMRxBdRingLength(t_Handle h_FmPort, uint16_t newVal)
60147 +{
60148 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
60149 +
60150 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
60151 + SANITY_CHECK_RETURN_ERROR(p_FmPort->imEn, E_INVALID_STATE);
60152 + SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
60153 +
60154 + p_FmPort->im.bdRingSize = newVal;
60155 +
60156 + return E_OK;
60157 +}
60158 +
60159 +t_Error FM_PORT_ConfigIMTxBdRingLength(t_Handle h_FmPort, uint16_t newVal)
60160 +{
60161 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
60162 +
60163 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
60164 + SANITY_CHECK_RETURN_ERROR(p_FmPort->imEn, E_INVALID_STATE);
60165 + SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
60166 +
60167 + p_FmPort->im.bdRingSize = newVal;
60168 +
60169 + return E_OK;
60170 +}
60171 +
60172 +t_Error FM_PORT_ConfigIMFmanCtrlExternalStructsMemory(t_Handle h_FmPort,
60173 + uint8_t memId,
60174 + uint32_t memAttributes)
60175 +{
60176 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
60177 +
60178 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
60179 + SANITY_CHECK_RETURN_ERROR(p_FmPort->imEn, E_INVALID_STATE);
60180 + SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
60181 +
60182 + p_FmPort->im.fwExtStructsMemId = memId;
60183 + p_FmPort->im.fwExtStructsMemAttr = memAttributes;
60184 +
60185 + return E_OK;
60186 +}
60187 +
60188 +t_Error FM_PORT_ConfigIMPolling(t_Handle h_FmPort)
60189 +{
60190 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
60191 +
60192 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
60193 + SANITY_CHECK_RETURN_ERROR(p_FmPort->imEn, E_INVALID_STATE);
60194 + SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
60195 +
60196 + if ((p_FmPort->portType != e_FM_PORT_TYPE_RX_10G) && (p_FmPort->portType != e_FM_PORT_TYPE_RX))
60197 + RETURN_ERROR(MAJOR, E_INVALID_OPERATION, ("Available for Rx ports only"));
60198 +
60199 + if (!FmIsMaster(p_FmPort->h_Fm))
60200 + RETURN_ERROR(MAJOR, E_INVALID_OPERATION, ("Available on master-partition only;"
60201 + "in guest-partitions, IM is always in polling!"));
60202 +
60203 + p_FmPort->polling = TRUE;
60204 +
60205 + return E_OK;
60206 +}
60207 +
60208 +t_Error FM_PORT_SetIMExceptions(t_Handle h_FmPort, e_FmPortExceptions exception, bool enable)
60209 +{
60210 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
60211 + t_Error err;
60212 + uint16_t tmpReg16;
60213 + uint32_t tmpReg32;
60214 +
60215 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
60216 + SANITY_CHECK_RETURN_ERROR(p_FmPort->imEn, E_INVALID_STATE);
60217 + SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
60218 +
60219 + if (exception == e_FM_PORT_EXCEPTION_IM_BUSY)
60220 + {
60221 + if (enable)
60222 + {
60223 + p_FmPort->exceptions |= IM_EV_BSY;
60224 + if (p_FmPort->fmanCtrlEventId == (uint8_t)NO_IRQ)
60225 + {
60226 + /* Allocate, configure and register interrupts */
60227 + err = FmAllocFmanCtrlEventReg(p_FmPort->h_Fm, &p_FmPort->fmanCtrlEventId);
60228 + if (err)
60229 + RETURN_ERROR(MAJOR, err, NO_MSG);
60230 + ASSERT_COND(!(p_FmPort->fmanCtrlEventId & ~IM_RXQD_FPMEVT_SEL_MASK));
60231 +
60232 + FmRegisterFmanCtrlIntr(p_FmPort->h_Fm, p_FmPort->fmanCtrlEventId, ImException, (t_Handle)p_FmPort);
60233 + tmpReg16 = (uint16_t)((p_FmPort->fmanCtrlEventId & IM_RXQD_FPMEVT_SEL_MASK) | IM_RXQD_BSYINTM);
60234 + tmpReg32 = IM_EV_BSY;
60235 + }
60236 + else
60237 + {
60238 + tmpReg16 = (uint16_t)(GET_UINT16(p_FmPort->im.p_FmPortImPram->rxQd.gen) | IM_RXQD_BSYINTM);
60239 + tmpReg32 = FmGetFmanCtrlIntr(p_FmPort->h_Fm, p_FmPort->fmanCtrlEventId) | IM_EV_BSY;
60240 + }
60241 +
60242 + WRITE_UINT16(p_FmPort->im.p_FmPortImPram->rxQd.gen, tmpReg16);
60243 + FmSetFmanCtrlIntr(p_FmPort->h_Fm, p_FmPort->fmanCtrlEventId, tmpReg32);
60244 + }
60245 + else
60246 + {
60247 + p_FmPort->exceptions &= ~IM_EV_BSY;
60248 + if (!p_FmPort->exceptions && p_FmPort->polling)
60249 + {
60250 + FmFreeFmanCtrlEventReg(p_FmPort->h_Fm, p_FmPort->fmanCtrlEventId);
60251 + FmUnregisterFmanCtrlIntr(p_FmPort->h_Fm, p_FmPort->fmanCtrlEventId);
60252 + FmSetFmanCtrlIntr(p_FmPort->h_Fm, p_FmPort->fmanCtrlEventId, 0);
60253 + WRITE_UINT16(p_FmPort->im.p_FmPortImPram->rxQd.gen, 0);
60254 + p_FmPort->fmanCtrlEventId = (uint8_t)NO_IRQ;
60255 + }
60256 + else
60257 + {
60258 + tmpReg16 = (uint16_t)(GET_UINT16(p_FmPort->im.p_FmPortImPram->rxQd.gen) & ~IM_RXQD_BSYINTM);
60259 + WRITE_UINT16(p_FmPort->im.p_FmPortImPram->rxQd.gen, tmpReg16);
60260 + tmpReg32 = FmGetFmanCtrlIntr(p_FmPort->h_Fm, p_FmPort->fmanCtrlEventId) & ~IM_EV_BSY;
60261 + FmSetFmanCtrlIntr(p_FmPort->h_Fm, p_FmPort->fmanCtrlEventId, tmpReg32);
60262 + }
60263 + }
60264 + }
60265 + else
60266 + RETURN_ERROR(MINOR, E_INVALID_SELECTION, ("Invalid exception."));
60267 +
60268 + return E_OK;
60269 +}
60270 +
60271 +t_Error FM_PORT_ImTx( t_Handle h_FmPort,
60272 + uint8_t *p_Data,
60273 + uint16_t length,
60274 + bool lastBuffer,
60275 + t_Handle h_BufContext)
60276 +{
60277 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
60278 + uint16_t nextBdId;
60279 + uint32_t bdStatus, nextBdStatus;
60280 + bool firstBuffer;
60281 +
60282 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
60283 + SANITY_CHECK_RETURN_ERROR(p_FmPort->imEn, E_INVALID_STATE);
60284 + SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
60285 +
60286 + bdStatus = BD_STATUS_AND_LENGTH(BD_GET(p_FmPort->im.currBdId));
60287 + nextBdId = GetNextBdId(p_FmPort, p_FmPort->im.currBdId);
60288 + nextBdStatus = BD_STATUS_AND_LENGTH(BD_GET(nextBdId));
60289 +
60290 + if (!(bdStatus & BD_R_E) && !(nextBdStatus & BD_R_E))
60291 + {
60292 + /* Confirm the current BD - BD is available */
60293 + if ((bdStatus & BD_LENGTH_MASK) && (p_FmPort->im.f_TxConf))
60294 + p_FmPort->im.f_TxConf (p_FmPort->h_App,
60295 + BdBufferGet(XX_PhysToVirt, BD_GET(p_FmPort->im.currBdId)),
60296 + 0,
60297 + p_FmPort->im.p_BdShadow[p_FmPort->im.currBdId]);
60298 +
60299 + bdStatus = length;
60300 +
60301 + /* if this is the first BD of a frame */
60302 + if (p_FmPort->im.firstBdOfFrameId == IM_ILEGAL_BD_ID)
60303 + {
60304 + firstBuffer = TRUE;
60305 + p_FmPort->im.txFirstBdStatus = (bdStatus | BD_R_E);
60306 +
60307 + if (!lastBuffer)
60308 + p_FmPort->im.firstBdOfFrameId = p_FmPort->im.currBdId;
60309 + }
60310 + else
60311 + firstBuffer = FALSE;
60312 +
60313 + BdBufferSet(XX_VirtToPhys, BD_GET(p_FmPort->im.currBdId), p_Data);
60314 + p_FmPort->im.p_BdShadow[p_FmPort->im.currBdId] = h_BufContext;
60315 +
60316 + /* deal with last */
60317 + if (lastBuffer)
60318 + {
60319 + /* if single buffer frame */
60320 + if (firstBuffer)
60321 + BD_STATUS_AND_LENGTH_SET(BD_GET(p_FmPort->im.currBdId), p_FmPort->im.txFirstBdStatus | BD_L);
60322 + else
60323 + {
60324 + /* Set the last BD of the frame */
60325 + BD_STATUS_AND_LENGTH_SET (BD_GET(p_FmPort->im.currBdId), (bdStatus | BD_R_E | BD_L));
60326 + /* Set the first BD of the frame */
60327 + BD_STATUS_AND_LENGTH_SET(BD_GET(p_FmPort->im.firstBdOfFrameId), p_FmPort->im.txFirstBdStatus);
60328 + p_FmPort->im.firstBdOfFrameId = IM_ILEGAL_BD_ID;
60329 + }
60330 + WRITE_UINT16(p_FmPort->im.p_FmPortImPram->txQd.offsetIn, (uint16_t)(GetNextBdId(p_FmPort, p_FmPort->im.currBdId)<<4));
60331 + }
60332 + else if (!firstBuffer) /* mid frame buffer */
60333 + BD_STATUS_AND_LENGTH_SET (BD_GET(p_FmPort->im.currBdId), bdStatus | BD_R_E);
60334 +
60335 + p_FmPort->im.currBdId = GetNextBdId(p_FmPort, p_FmPort->im.currBdId);
60336 + }
60337 + else
60338 + {
60339 + /* Discard current frame. Return error. */
60340 + if (p_FmPort->im.firstBdOfFrameId != IM_ILEGAL_BD_ID)
60341 + {
60342 + /* Error: No free BD */
60343 + /* Response: Discard current frame. Return error. */
60344 + uint16_t cleanBdId = p_FmPort->im.firstBdOfFrameId;
60345 +
60346 + ASSERT_COND(p_FmPort->im.firstBdOfFrameId != p_FmPort->im.currBdId);
60347 +
60348 + /* Since firstInFrame is not NULL, one buffer at least has already been
60349 + inserted into the BD ring. Using do-while covers the situation of a
60350 + frame spanned throughout the whole Tx BD ring (p_CleanBd is incremented
60351 + prior to testing whether or not it's equal to TxBd). */
60352 + do
60353 + {
60354 + BD_STATUS_AND_LENGTH_SET(BD_GET(cleanBdId), 0);
60355 + /* Advance BD pointer */
60356 + cleanBdId = GetNextBdId(p_FmPort, cleanBdId);
60357 + } while (cleanBdId != p_FmPort->im.currBdId);
60358 +
60359 + p_FmPort->im.currBdId = cleanBdId;
60360 + p_FmPort->im.firstBdOfFrameId = IM_ILEGAL_BD_ID;
60361 + }
60362 +
60363 + return ERROR_CODE(E_FULL);
60364 + }
60365 +
60366 + return E_OK;
60367 +}
60368 +
60369 +void FM_PORT_ImTxConf(t_Handle h_FmPort)
60370 +{
60371 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
60372 +
60373 + SANITY_CHECK_RETURN(p_FmPort, E_INVALID_HANDLE);
60374 + SANITY_CHECK_RETURN(p_FmPort->imEn, E_INVALID_STATE);
60375 + SANITY_CHECK_RETURN(!p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
60376 +
60377 + TxConf(p_FmPort, e_TX_CONF_TYPE_CALLBACK);
60378 +}
60379 +
60380 +t_Error FM_PORT_ImRx(t_Handle h_FmPort)
60381 +{
60382 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
60383 +
60384 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
60385 + SANITY_CHECK_RETURN_ERROR(p_FmPort->imEn, E_INVALID_STATE);
60386 + SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
60387 +
60388 + return FmPortImRx(p_FmPort);
60389 +}
60390 --- /dev/null
60391 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Port/fman_port.c
60392 @@ -0,0 +1,1568 @@
60393 +/*
60394 + * Copyright 2008-2012 Freescale Semiconductor Inc.
60395 + *
60396 + * Redistribution and use in source and binary forms, with or without
60397 + * modification, are permitted provided that the following conditions are met:
60398 + * * Redistributions of source code must retain the above copyright
60399 + * notice, this list of conditions and the following disclaimer.
60400 + * * Redistributions in binary form must reproduce the above copyright
60401 + * notice, this list of conditions and the following disclaimer in the
60402 + * documentation and/or other materials provided with the distribution.
60403 + * * Neither the name of Freescale Semiconductor nor the
60404 + * names of its contributors may be used to endorse or promote products
60405 + * derived from this software without specific prior written permission.
60406 + *
60407 + *
60408 + * ALTERNATIVELY, this software may be distributed under the terms of the
60409 + * GNU General Public License ("GPL") as published by the Free Software
60410 + * Foundation, either version 2 of that License or (at your option) any
60411 + * later version.
60412 + *
60413 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
60414 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
60415 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
60416 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
60417 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
60418 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
60419 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
60420 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
60421 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
60422 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
60423 + */
60424 +
60425 +
60426 +#include "common/general.h"
60427 +
60428 +#include "fman_common.h"
60429 +#include "fsl_fman_port.h"
60430 +
60431 +
60432 +/* problem Eyal: the following should not be here*/
60433 +#define NIA_FM_CTL_AC_NO_IPACC_PRE_BMI_ENQ_FRAME 0x00000028
60434 +
60435 +static uint32_t get_no_pcd_nia_bmi_ac_enc_frame(struct fman_port_cfg *cfg)
60436 +{
60437 + if (cfg->errata_A006675)
60438 + return NIA_ENG_FM_CTL |
60439 + NIA_FM_CTL_AC_NO_IPACC_PRE_BMI_ENQ_FRAME;
60440 + else
60441 + return NIA_ENG_BMI | NIA_BMI_AC_ENQ_FRAME;
60442 +}
60443 +
60444 +static int init_bmi_rx(struct fman_port *port,
60445 + struct fman_port_cfg *cfg,
60446 + struct fman_port_params *params)
60447 +{
60448 + struct fman_port_rx_bmi_regs *regs = &port->bmi_regs->rx;
60449 + uint32_t tmp;
60450 +
60451 + /* Rx Configuration register */
60452 + tmp = 0;
60453 + if (port->im_en)
60454 + tmp |= BMI_PORT_CFG_IM;
60455 + else if (cfg->discard_override)
60456 + tmp |= BMI_PORT_CFG_FDOVR;
60457 + iowrite32be(tmp, &regs->fmbm_rcfg);
60458 +
60459 + /* DMA attributes */
60460 + tmp = (uint32_t)cfg->dma_swap_data << BMI_DMA_ATTR_SWP_SHIFT;
60461 + if (cfg->dma_ic_stash_on)
60462 + tmp |= BMI_DMA_ATTR_IC_STASH_ON;
60463 + if (cfg->dma_header_stash_on)
60464 + tmp |= BMI_DMA_ATTR_HDR_STASH_ON;
60465 + if (cfg->dma_sg_stash_on)
60466 + tmp |= BMI_DMA_ATTR_SG_STASH_ON;
60467 + if (cfg->dma_write_optimize)
60468 + tmp |= BMI_DMA_ATTR_WRITE_OPTIMIZE;
60469 + iowrite32be(tmp, &regs->fmbm_rda);
60470 +
60471 + /* Rx FIFO parameters */
60472 + tmp = (cfg->rx_pri_elevation / FMAN_PORT_BMI_FIFO_UNITS - 1) <<
60473 + BMI_RX_FIFO_PRI_ELEVATION_SHIFT;
60474 + tmp |= cfg->rx_fifo_thr / FMAN_PORT_BMI_FIFO_UNITS - 1;
60475 + iowrite32be(tmp, &regs->fmbm_rfp);
60476 +
60477 + if (cfg->excessive_threshold_register)
60478 + /* always allow access to the extra resources */
60479 + iowrite32be(BMI_RX_FIFO_THRESHOLD_ETHE, &regs->fmbm_reth);
60480 +
60481 + /* Frame end data */
60482 + tmp = (uint32_t)cfg->checksum_bytes_ignore <<
60483 + BMI_RX_FRAME_END_CS_IGNORE_SHIFT;
60484 + tmp |= (uint32_t)cfg->rx_cut_end_bytes <<
60485 + BMI_RX_FRAME_END_CUT_SHIFT;
60486 + if (cfg->errata_A006320)
60487 + tmp &= 0xffe0ffff;
60488 + iowrite32be(tmp, &regs->fmbm_rfed);
60489 +
60490 + /* Internal context parameters */
60491 + tmp = ((uint32_t)cfg->ic_ext_offset / FMAN_PORT_IC_OFFSET_UNITS) <<
60492 + BMI_IC_TO_EXT_SHIFT;
60493 + tmp |= ((uint32_t)cfg->ic_int_offset / FMAN_PORT_IC_OFFSET_UNITS) <<
60494 + BMI_IC_FROM_INT_SHIFT;
60495 + tmp |= cfg->ic_size / FMAN_PORT_IC_OFFSET_UNITS;
60496 + iowrite32be(tmp, &regs->fmbm_ricp);
60497 +
60498 + /* Internal buffer offset */
60499 + tmp = ((uint32_t)cfg->int_buf_start_margin / FMAN_PORT_IC_OFFSET_UNITS)
60500 + << BMI_INT_BUF_MARG_SHIFT;
60501 + iowrite32be(tmp, &regs->fmbm_rim);
60502 +
60503 + /* External buffer margins */
60504 + if (!port->im_en)
60505 + {
60506 + tmp = (uint32_t)cfg->ext_buf_start_margin <<
60507 + BMI_EXT_BUF_MARG_START_SHIFT;
60508 + tmp |= (uint32_t)cfg->ext_buf_end_margin;
60509 + if (cfg->fmbm_rebm_has_sgd && cfg->no_scatter_gather)
60510 + tmp |= BMI_SG_DISABLE;
60511 + iowrite32be(tmp, &regs->fmbm_rebm);
60512 + }
60513 +
60514 + /* Frame attributes */
60515 + tmp = BMI_CMD_RX_MR_DEF;
60516 + if (!port->im_en)
60517 + {
60518 + tmp |= BMI_CMD_ATTR_ORDER;
60519 + tmp |= (uint32_t)cfg->color << BMI_CMD_ATTR_COLOR_SHIFT;
60520 + if (cfg->sync_req)
60521 + tmp |= BMI_CMD_ATTR_SYNC;
60522 + }
60523 + iowrite32be(tmp, &regs->fmbm_rfca);
60524 +
60525 + /* NIA */
60526 + if (port->im_en)
60527 + tmp = NIA_ENG_FM_CTL | NIA_FM_CTL_AC_IND_MODE_RX;
60528 + else
60529 + {
60530 + tmp = (uint32_t)cfg->rx_fd_bits << BMI_NEXT_ENG_FD_BITS_SHIFT;
60531 + tmp |= get_no_pcd_nia_bmi_ac_enc_frame(cfg);
60532 + }
60533 + iowrite32be(tmp, &regs->fmbm_rfne);
60534 +
60535 + /* Enqueue NIA */
60536 + iowrite32be(NIA_ENG_QMI_ENQ | NIA_ORDER_RESTOR, &regs->fmbm_rfene);
60537 +
60538 + /* Default/error queues */
60539 + if (!port->im_en)
60540 + {
60541 + iowrite32be((params->dflt_fqid & 0x00FFFFFF), &regs->fmbm_rfqid);
60542 + iowrite32be((params->err_fqid & 0x00FFFFFF), &regs->fmbm_refqid);
60543 + }
60544 +
60545 + /* Discard/error masks */
60546 + iowrite32be(params->discard_mask, &regs->fmbm_rfsdm);
60547 + iowrite32be(params->err_mask, &regs->fmbm_rfsem);
60548 +
60549 + /* Statistics counters */
60550 + tmp = 0;
60551 + if (cfg->stats_counters_enable)
60552 + tmp = BMI_COUNTERS_EN;
60553 + iowrite32be(tmp, &regs->fmbm_rstc);
60554 +
60555 + /* Performance counters */
60556 + fman_port_set_perf_cnt_params(port, &cfg->perf_cnt_params);
60557 + tmp = 0;
60558 + if (cfg->perf_counters_enable)
60559 + tmp = BMI_COUNTERS_EN;
60560 + iowrite32be(tmp, &regs->fmbm_rpc);
60561 +
60562 + return 0;
60563 +}
60564 +
60565 +static int init_bmi_tx(struct fman_port *port,
60566 + struct fman_port_cfg *cfg,
60567 + struct fman_port_params *params)
60568 +{
60569 + struct fman_port_tx_bmi_regs *regs = &port->bmi_regs->tx;
60570 + uint32_t tmp;
60571 +
60572 + /* Tx Configuration register */
60573 + tmp = 0;
60574 + if (port->im_en)
60575 + tmp |= BMI_PORT_CFG_IM;
60576 + iowrite32be(tmp, &regs->fmbm_tcfg);
60577 +
60578 + /* DMA attributes */
60579 + tmp = (uint32_t)cfg->dma_swap_data << BMI_DMA_ATTR_SWP_SHIFT;
60580 + if (cfg->dma_ic_stash_on)
60581 + tmp |= BMI_DMA_ATTR_IC_STASH_ON;
60582 + if (cfg->dma_header_stash_on)
60583 + tmp |= BMI_DMA_ATTR_HDR_STASH_ON;
60584 + if (cfg->dma_sg_stash_on)
60585 + tmp |= BMI_DMA_ATTR_SG_STASH_ON;
60586 + iowrite32be(tmp, &regs->fmbm_tda);
60587 +
60588 + /* Tx FIFO parameters */
60589 + tmp = (cfg->tx_fifo_min_level / FMAN_PORT_BMI_FIFO_UNITS) <<
60590 + BMI_TX_FIFO_MIN_FILL_SHIFT;
60591 + tmp |= ((uint32_t)cfg->tx_fifo_deq_pipeline_depth - 1) <<
60592 + BMI_FIFO_PIPELINE_DEPTH_SHIFT;
60593 + tmp |= (uint32_t)(cfg->tx_fifo_low_comf_level /
60594 + FMAN_PORT_BMI_FIFO_UNITS - 1);
60595 + iowrite32be(tmp, &regs->fmbm_tfp);
60596 +
60597 + /* Frame end data */
60598 + tmp = (uint32_t)cfg->checksum_bytes_ignore <<
60599 + BMI_FRAME_END_CS_IGNORE_SHIFT;
60600 + iowrite32be(tmp, &regs->fmbm_tfed);
60601 +
60602 + /* Internal context parameters */
60603 + if (!port->im_en)
60604 + {
60605 + tmp = ((uint32_t)cfg->ic_ext_offset / FMAN_PORT_IC_OFFSET_UNITS) <<
60606 + BMI_IC_TO_EXT_SHIFT;
60607 + tmp |= ((uint32_t)cfg->ic_int_offset / FMAN_PORT_IC_OFFSET_UNITS) <<
60608 + BMI_IC_FROM_INT_SHIFT;
60609 + tmp |= cfg->ic_size / FMAN_PORT_IC_OFFSET_UNITS;
60610 + iowrite32be(tmp, &regs->fmbm_ticp);
60611 + }
60612 + /* Frame attributes */
60613 + tmp = BMI_CMD_TX_MR_DEF;
60614 + if (port->im_en)
60615 + tmp |= BMI_CMD_MR_DEAS;
60616 + else
60617 + {
60618 + tmp |= BMI_CMD_ATTR_ORDER;
60619 + tmp |= (uint32_t)cfg->color << BMI_CMD_ATTR_COLOR_SHIFT;
60620 + }
60621 + iowrite32be(tmp, &regs->fmbm_tfca);
60622 +
60623 + /* Dequeue NIA + enqueue NIA */
60624 + if (port->im_en)
60625 + {
60626 + iowrite32be(NIA_ENG_FM_CTL | NIA_FM_CTL_AC_IND_MODE_TX, &regs->fmbm_tfdne);
60627 + iowrite32be(NIA_ENG_FM_CTL | NIA_FM_CTL_AC_IND_MODE_TX, &regs->fmbm_tfene);
60628 + }
60629 + else
60630 + {
60631 + iowrite32be(NIA_ENG_QMI_DEQ, &regs->fmbm_tfdne);
60632 + iowrite32be(NIA_ENG_QMI_ENQ | NIA_ORDER_RESTOR, &regs->fmbm_tfene);
60633 + if (cfg->fmbm_tfne_has_features)
60634 + iowrite32be(!params->dflt_fqid ?
60635 + BMI_EBD_EN | NIA_BMI_AC_FETCH_ALL_FRAME :
60636 + NIA_BMI_AC_FETCH_ALL_FRAME, &regs->fmbm_tfne);
60637 + if (!params->dflt_fqid && params->dont_release_buf)
60638 + {
60639 + iowrite32be(0x00FFFFFF, &regs->fmbm_tcfqid);
60640 + iowrite32be(NIA_ENG_BMI | NIA_BMI_AC_TX_RELEASE, &regs->fmbm_tfene);
60641 + if (cfg->fmbm_tfne_has_features)
60642 + iowrite32be(ioread32be(&regs->fmbm_tfne) & ~BMI_EBD_EN, &regs->fmbm_tfne);
60643 + }
60644 + }
60645 +
60646 + /* Confirmation/error queues */
60647 + if (!port->im_en)
60648 + {
60649 + if (params->dflt_fqid || !params->dont_release_buf)
60650 + iowrite32be(params->dflt_fqid & 0x00FFFFFF, &regs->fmbm_tcfqid);
60651 + iowrite32be((params->err_fqid & 0x00FFFFFF), &regs->fmbm_tefqid);
60652 + }
60653 + /* Statistics counters */
60654 + tmp = 0;
60655 + if (cfg->stats_counters_enable)
60656 + tmp = BMI_COUNTERS_EN;
60657 + iowrite32be(tmp, &regs->fmbm_tstc);
60658 +
60659 + /* Performance counters */
60660 + fman_port_set_perf_cnt_params(port, &cfg->perf_cnt_params);
60661 + tmp = 0;
60662 + if (cfg->perf_counters_enable)
60663 + tmp = BMI_COUNTERS_EN;
60664 + iowrite32be(tmp, &regs->fmbm_tpc);
60665 +
60666 + return 0;
60667 +}
60668 +
60669 +static int init_bmi_oh(struct fman_port *port,
60670 + struct fman_port_cfg *cfg,
60671 + struct fman_port_params *params)
60672 +{
60673 + struct fman_port_oh_bmi_regs *regs = &port->bmi_regs->oh;
60674 + uint32_t tmp;
60675 +
60676 + /* OP Configuration register */
60677 + tmp = 0;
60678 + if (cfg->discard_override)
60679 + tmp |= BMI_PORT_CFG_FDOVR;
60680 + iowrite32be(tmp, &regs->fmbm_ocfg);
60681 +
60682 + /* DMA attributes */
60683 + tmp = (uint32_t)cfg->dma_swap_data << BMI_DMA_ATTR_SWP_SHIFT;
60684 + if (cfg->dma_ic_stash_on)
60685 + tmp |= BMI_DMA_ATTR_IC_STASH_ON;
60686 + if (cfg->dma_header_stash_on)
60687 + tmp |= BMI_DMA_ATTR_HDR_STASH_ON;
60688 + if (cfg->dma_sg_stash_on)
60689 + tmp |= BMI_DMA_ATTR_SG_STASH_ON;
60690 + if (cfg->dma_write_optimize)
60691 + tmp |= BMI_DMA_ATTR_WRITE_OPTIMIZE;
60692 + iowrite32be(tmp, &regs->fmbm_oda);
60693 +
60694 + /* Tx FIFO parameters */
60695 + tmp = ((uint32_t)cfg->tx_fifo_deq_pipeline_depth - 1) <<
60696 + BMI_FIFO_PIPELINE_DEPTH_SHIFT;
60697 + iowrite32be(tmp, &regs->fmbm_ofp);
60698 +
60699 + /* Internal context parameters */
60700 + tmp = ((uint32_t)cfg->ic_ext_offset / FMAN_PORT_IC_OFFSET_UNITS) <<
60701 + BMI_IC_TO_EXT_SHIFT;
60702 + tmp |= ((uint32_t)cfg->ic_int_offset / FMAN_PORT_IC_OFFSET_UNITS) <<
60703 + BMI_IC_FROM_INT_SHIFT;
60704 + tmp |= cfg->ic_size / FMAN_PORT_IC_OFFSET_UNITS;
60705 + iowrite32be(tmp, &regs->fmbm_oicp);
60706 +
60707 + /* Frame attributes */
60708 + tmp = BMI_CMD_OP_MR_DEF;
60709 + tmp |= (uint32_t)cfg->color << BMI_CMD_ATTR_COLOR_SHIFT;
60710 + if (cfg->sync_req)
60711 + tmp |= BMI_CMD_ATTR_SYNC;
60712 + if (port->type == E_FMAN_PORT_TYPE_OP)
60713 + tmp |= BMI_CMD_ATTR_ORDER;
60714 + iowrite32be(tmp, &regs->fmbm_ofca);
60715 +
60716 + /* Internal buffer offset */
60717 + tmp = ((uint32_t)cfg->int_buf_start_margin / FMAN_PORT_IC_OFFSET_UNITS)
60718 + << BMI_INT_BUF_MARG_SHIFT;
60719 + iowrite32be(tmp, &regs->fmbm_oim);
60720 +
60721 + /* Dequeue NIA */
60722 + iowrite32be(NIA_ENG_QMI_DEQ, &regs->fmbm_ofdne);
60723 +
60724 + /* NIA and Enqueue NIA */
60725 + if (port->type == E_FMAN_PORT_TYPE_HC) {
60726 + iowrite32be(NIA_ENG_FM_CTL | NIA_FM_CTL_AC_HC,
60727 + &regs->fmbm_ofne);
60728 + iowrite32be(NIA_ENG_QMI_ENQ, &regs->fmbm_ofene);
60729 + } else {
60730 + iowrite32be(get_no_pcd_nia_bmi_ac_enc_frame(cfg),
60731 + &regs->fmbm_ofne);
60732 + iowrite32be(NIA_ENG_QMI_ENQ | NIA_ORDER_RESTOR,
60733 + &regs->fmbm_ofene);
60734 + }
60735 +
60736 + /* Default/error queues */
60737 + iowrite32be((params->dflt_fqid & 0x00FFFFFF), &regs->fmbm_ofqid);
60738 + iowrite32be((params->err_fqid & 0x00FFFFFF), &regs->fmbm_oefqid);
60739 +
60740 + /* Discard/error masks */
60741 + if (port->type == E_FMAN_PORT_TYPE_OP) {
60742 + iowrite32be(params->discard_mask, &regs->fmbm_ofsdm);
60743 + iowrite32be(params->err_mask, &regs->fmbm_ofsem);
60744 + }
60745 +
60746 + /* Statistics counters */
60747 + tmp = 0;
60748 + if (cfg->stats_counters_enable)
60749 + tmp = BMI_COUNTERS_EN;
60750 + iowrite32be(tmp, &regs->fmbm_ostc);
60751 +
60752 + /* Performance counters */
60753 + fman_port_set_perf_cnt_params(port, &cfg->perf_cnt_params);
60754 + tmp = 0;
60755 + if (cfg->perf_counters_enable)
60756 + tmp = BMI_COUNTERS_EN;
60757 + iowrite32be(tmp, &regs->fmbm_opc);
60758 +
60759 + return 0;
60760 +}
60761 +
60762 +static int init_qmi(struct fman_port *port,
60763 + struct fman_port_cfg *cfg,
60764 + struct fman_port_params *params)
60765 +{
60766 + struct fman_port_qmi_regs *regs = port->qmi_regs;
60767 + uint32_t tmp;
60768 +
60769 + tmp = 0;
60770 + if (cfg->queue_counters_enable)
60771 + tmp |= QMI_PORT_CFG_EN_COUNTERS;
60772 + iowrite32be(tmp, &regs->fmqm_pnc);
60773 +
60774 + /* Rx port configuration */
60775 + if ((port->type == E_FMAN_PORT_TYPE_RX) ||
60776 + (port->type == E_FMAN_PORT_TYPE_RX_10G)) {
60777 + /* Enqueue NIA */
60778 + iowrite32be(NIA_ENG_BMI | NIA_BMI_AC_RELEASE, &regs->fmqm_pnen);
60779 + return 0;
60780 + }
60781 +
60782 + /* Continue with Tx and O/H port configuration */
60783 + if ((port->type == E_FMAN_PORT_TYPE_TX) ||
60784 + (port->type == E_FMAN_PORT_TYPE_TX_10G)) {
60785 + /* Enqueue NIA */
60786 + iowrite32be(NIA_ENG_BMI | NIA_BMI_AC_TX_RELEASE,
60787 + &regs->fmqm_pnen);
60788 + /* Dequeue NIA */
60789 + iowrite32be(NIA_ENG_BMI | NIA_BMI_AC_TX, &regs->fmqm_pndn);
60790 + } else {
60791 + /* Enqueue NIA */
60792 + iowrite32be(NIA_ENG_BMI | NIA_BMI_AC_RELEASE, &regs->fmqm_pnen);
60793 + /* Dequeue NIA */
60794 + iowrite32be(NIA_ENG_BMI | NIA_BMI_AC_FETCH, &regs->fmqm_pndn);
60795 + }
60796 +
60797 + /* Dequeue Configuration register */
60798 + tmp = 0;
60799 + if (cfg->deq_high_pri)
60800 + tmp |= QMI_DEQ_CFG_PRI;
60801 +
60802 + switch (cfg->deq_type) {
60803 + case E_FMAN_PORT_DEQ_BY_PRI:
60804 + tmp |= QMI_DEQ_CFG_TYPE1;
60805 + break;
60806 + case E_FMAN_PORT_DEQ_ACTIVE_FQ:
60807 + tmp |= QMI_DEQ_CFG_TYPE2;
60808 + break;
60809 + case E_FMAN_PORT_DEQ_ACTIVE_FQ_NO_ICS:
60810 + tmp |= QMI_DEQ_CFG_TYPE3;
60811 + break;
60812 + default:
60813 + return -EINVAL;
60814 + }
60815 +
60816 + if (cfg->qmi_deq_options_support) {
60817 + if ((port->type == E_FMAN_PORT_TYPE_HC) &&
60818 + (cfg->deq_prefetch_opt != E_FMAN_PORT_DEQ_NO_PREFETCH))
60819 + return -EINVAL;
60820 +
60821 + switch (cfg->deq_prefetch_opt) {
60822 + case E_FMAN_PORT_DEQ_NO_PREFETCH:
60823 + break;
60824 + case E_FMAN_PORT_DEQ_PART_PREFETCH:
60825 + tmp |= QMI_DEQ_CFG_PREFETCH_PARTIAL;
60826 + break;
60827 + case E_FMAN_PORT_DEQ_FULL_PREFETCH:
60828 + tmp |= QMI_DEQ_CFG_PREFETCH_FULL;
60829 + break;
60830 + default:
60831 + return -EINVAL;
60832 + }
60833 + }
60834 + tmp |= (uint32_t)(params->deq_sp & QMI_DEQ_CFG_SP_MASK) <<
60835 + QMI_DEQ_CFG_SP_SHIFT;
60836 + tmp |= cfg->deq_byte_cnt;
60837 + iowrite32be(tmp, &regs->fmqm_pndc);
60838 +
60839 + return 0;
60840 +}
60841 +
60842 +static void get_rx_stats_reg(struct fman_port *port,
60843 + enum fman_port_stats_counters counter,
60844 + uint32_t **stats_reg)
60845 +{
60846 + struct fman_port_rx_bmi_regs *regs = &port->bmi_regs->rx;
60847 +
60848 + switch (counter) {
60849 + case E_FMAN_PORT_STATS_CNT_FRAME:
60850 + *stats_reg = &regs->fmbm_rfrc;
60851 + break;
60852 + case E_FMAN_PORT_STATS_CNT_DISCARD:
60853 + *stats_reg = &regs->fmbm_rfdc;
60854 + break;
60855 + case E_FMAN_PORT_STATS_CNT_DEALLOC_BUF:
60856 + *stats_reg = &regs->fmbm_rbdc;
60857 + break;
60858 + case E_FMAN_PORT_STATS_CNT_RX_BAD_FRAME:
60859 + *stats_reg = &regs->fmbm_rfbc;
60860 + break;
60861 + case E_FMAN_PORT_STATS_CNT_RX_LARGE_FRAME:
60862 + *stats_reg = &regs->fmbm_rlfc;
60863 + break;
60864 + case E_FMAN_PORT_STATS_CNT_RX_OUT_OF_BUF:
60865 + *stats_reg = &regs->fmbm_rodc;
60866 + break;
60867 + case E_FMAN_PORT_STATS_CNT_FILTERED_FRAME:
60868 + *stats_reg = &regs->fmbm_rffc;
60869 + break;
60870 + case E_FMAN_PORT_STATS_CNT_DMA_ERR:
60871 + *stats_reg = &regs->fmbm_rfldec;
60872 + break;
60873 + default:
60874 + *stats_reg = NULL;
60875 + }
60876 +}
60877 +
60878 +static void get_tx_stats_reg(struct fman_port *port,
60879 + enum fman_port_stats_counters counter,
60880 + uint32_t **stats_reg)
60881 +{
60882 + struct fman_port_tx_bmi_regs *regs = &port->bmi_regs->tx;
60883 +
60884 + switch (counter) {
60885 + case E_FMAN_PORT_STATS_CNT_FRAME:
60886 + *stats_reg = &regs->fmbm_tfrc;
60887 + break;
60888 + case E_FMAN_PORT_STATS_CNT_DISCARD:
60889 + *stats_reg = &regs->fmbm_tfdc;
60890 + break;
60891 + case E_FMAN_PORT_STATS_CNT_DEALLOC_BUF:
60892 + *stats_reg = &regs->fmbm_tbdc;
60893 + break;
60894 + case E_FMAN_PORT_STATS_CNT_LEN_ERR:
60895 + *stats_reg = &regs->fmbm_tfledc;
60896 + break;
60897 + case E_FMAN_PORT_STATS_CNT_UNSUPPORTED_FORMAT:
60898 + *stats_reg = &regs->fmbm_tfufdc;
60899 + break;
60900 + default:
60901 + *stats_reg = NULL;
60902 + }
60903 +}
60904 +
60905 +static void get_oh_stats_reg(struct fman_port *port,
60906 + enum fman_port_stats_counters counter,
60907 + uint32_t **stats_reg)
60908 +{
60909 + struct fman_port_oh_bmi_regs *regs = &port->bmi_regs->oh;
60910 +
60911 + switch (counter) {
60912 + case E_FMAN_PORT_STATS_CNT_FRAME:
60913 + *stats_reg = &regs->fmbm_ofrc;
60914 + break;
60915 + case E_FMAN_PORT_STATS_CNT_DISCARD:
60916 + *stats_reg = &regs->fmbm_ofdc;
60917 + break;
60918 + case E_FMAN_PORT_STATS_CNT_DEALLOC_BUF:
60919 + *stats_reg = &regs->fmbm_obdc;
60920 + break;
60921 + case E_FMAN_PORT_STATS_CNT_FILTERED_FRAME:
60922 + *stats_reg = &regs->fmbm_offc;
60923 + break;
60924 + case E_FMAN_PORT_STATS_CNT_DMA_ERR:
60925 + *stats_reg = &regs->fmbm_ofldec;
60926 + break;
60927 + case E_FMAN_PORT_STATS_CNT_LEN_ERR:
60928 + *stats_reg = &regs->fmbm_ofledc;
60929 + break;
60930 + case E_FMAN_PORT_STATS_CNT_UNSUPPORTED_FORMAT:
60931 + *stats_reg = &regs->fmbm_ofufdc;
60932 + break;
60933 + case E_FMAN_PORT_STATS_CNT_WRED_DISCARD:
60934 + *stats_reg = &regs->fmbm_ofwdc;
60935 + break;
60936 + default:
60937 + *stats_reg = NULL;
60938 + }
60939 +}
60940 +
60941 +static void get_rx_perf_reg(struct fman_port *port,
60942 + enum fman_port_perf_counters counter,
60943 + uint32_t **perf_reg)
60944 +{
60945 + struct fman_port_rx_bmi_regs *regs = &port->bmi_regs->rx;
60946 +
60947 + switch (counter) {
60948 + case E_FMAN_PORT_PERF_CNT_CYCLE:
60949 + *perf_reg = &regs->fmbm_rccn;
60950 + break;
60951 + case E_FMAN_PORT_PERF_CNT_TASK_UTIL:
60952 + *perf_reg = &regs->fmbm_rtuc;
60953 + break;
60954 + case E_FMAN_PORT_PERF_CNT_QUEUE_UTIL:
60955 + *perf_reg = &regs->fmbm_rrquc;
60956 + break;
60957 + case E_FMAN_PORT_PERF_CNT_DMA_UTIL:
60958 + *perf_reg = &regs->fmbm_rduc;
60959 + break;
60960 + case E_FMAN_PORT_PERF_CNT_FIFO_UTIL:
60961 + *perf_reg = &regs->fmbm_rfuc;
60962 + break;
60963 + case E_FMAN_PORT_PERF_CNT_RX_PAUSE:
60964 + *perf_reg = &regs->fmbm_rpac;
60965 + break;
60966 + default:
60967 + *perf_reg = NULL;
60968 + }
60969 +}
60970 +
60971 +static void get_tx_perf_reg(struct fman_port *port,
60972 + enum fman_port_perf_counters counter,
60973 + uint32_t **perf_reg)
60974 +{
60975 + struct fman_port_tx_bmi_regs *regs = &port->bmi_regs->tx;
60976 +
60977 + switch (counter) {
60978 + case E_FMAN_PORT_PERF_CNT_CYCLE:
60979 + *perf_reg = &regs->fmbm_tccn;
60980 + break;
60981 + case E_FMAN_PORT_PERF_CNT_TASK_UTIL:
60982 + *perf_reg = &regs->fmbm_ttuc;
60983 + break;
60984 + case E_FMAN_PORT_PERF_CNT_QUEUE_UTIL:
60985 + *perf_reg = &regs->fmbm_ttcquc;
60986 + break;
60987 + case E_FMAN_PORT_PERF_CNT_DMA_UTIL:
60988 + *perf_reg = &regs->fmbm_tduc;
60989 + break;
60990 + case E_FMAN_PORT_PERF_CNT_FIFO_UTIL:
60991 + *perf_reg = &regs->fmbm_tfuc;
60992 + break;
60993 + default:
60994 + *perf_reg = NULL;
60995 + }
60996 +}
60997 +
60998 +static void get_oh_perf_reg(struct fman_port *port,
60999 + enum fman_port_perf_counters counter,
61000 + uint32_t **perf_reg)
61001 +{
61002 + struct fman_port_oh_bmi_regs *regs = &port->bmi_regs->oh;
61003 +
61004 + switch (counter) {
61005 + case E_FMAN_PORT_PERF_CNT_CYCLE:
61006 + *perf_reg = &regs->fmbm_occn;
61007 + break;
61008 + case E_FMAN_PORT_PERF_CNT_TASK_UTIL:
61009 + *perf_reg = &regs->fmbm_otuc;
61010 + break;
61011 + case E_FMAN_PORT_PERF_CNT_DMA_UTIL:
61012 + *perf_reg = &regs->fmbm_oduc;
61013 + break;
61014 + case E_FMAN_PORT_PERF_CNT_FIFO_UTIL:
61015 + *perf_reg = &regs->fmbm_ofuc;
61016 + break;
61017 + default:
61018 + *perf_reg = NULL;
61019 + }
61020 +}
61021 +
61022 +static void get_qmi_counter_reg(struct fman_port *port,
61023 + enum fman_port_qmi_counters counter,
61024 + uint32_t **queue_reg)
61025 +{
61026 + struct fman_port_qmi_regs *regs = port->qmi_regs;
61027 +
61028 + switch (counter) {
61029 + case E_FMAN_PORT_ENQ_TOTAL:
61030 + *queue_reg = &regs->fmqm_pnetfc;
61031 + break;
61032 + case E_FMAN_PORT_DEQ_TOTAL:
61033 + if ((port->type == E_FMAN_PORT_TYPE_RX) ||
61034 + (port->type == E_FMAN_PORT_TYPE_RX_10G))
61035 + /* Counter not available for Rx ports */
61036 + *queue_reg = NULL;
61037 + else
61038 + *queue_reg = &regs->fmqm_pndtfc;
61039 + break;
61040 + case E_FMAN_PORT_DEQ_FROM_DFLT:
61041 + if ((port->type == E_FMAN_PORT_TYPE_RX) ||
61042 + (port->type == E_FMAN_PORT_TYPE_RX_10G))
61043 + /* Counter not available for Rx ports */
61044 + *queue_reg = NULL;
61045 + else
61046 + *queue_reg = &regs->fmqm_pndfdc;
61047 + break;
61048 + case E_FMAN_PORT_DEQ_CONFIRM:
61049 + if ((port->type == E_FMAN_PORT_TYPE_RX) ||
61050 + (port->type == E_FMAN_PORT_TYPE_RX_10G))
61051 + /* Counter not available for Rx ports */
61052 + *queue_reg = NULL;
61053 + else
61054 + *queue_reg = &regs->fmqm_pndcc;
61055 + break;
61056 + default:
61057 + *queue_reg = NULL;
61058 + }
61059 +}
61060 +
61061 +void fman_port_defconfig(struct fman_port_cfg *cfg, enum fman_port_type type)
61062 +{
61063 + cfg->dma_swap_data = E_FMAN_PORT_DMA_NO_SWAP;
61064 + cfg->dma_ic_stash_on = FALSE;
61065 + cfg->dma_header_stash_on = FALSE;
61066 + cfg->dma_sg_stash_on = FALSE;
61067 + cfg->dma_write_optimize = TRUE;
61068 + cfg->color = E_FMAN_PORT_COLOR_GREEN;
61069 + cfg->discard_override = FALSE;
61070 + cfg->checksum_bytes_ignore = 0;
61071 + cfg->rx_cut_end_bytes = 4;
61072 + cfg->rx_pri_elevation = ((0x3FF + 1) * FMAN_PORT_BMI_FIFO_UNITS);
61073 + cfg->rx_fifo_thr = ((0x3FF + 1) * FMAN_PORT_BMI_FIFO_UNITS);
61074 + cfg->rx_fd_bits = 0;
61075 + cfg->ic_ext_offset = 0;
61076 + cfg->ic_int_offset = 0;
61077 + cfg->ic_size = 0;
61078 + cfg->int_buf_start_margin = 0;
61079 + cfg->ext_buf_start_margin = 0;
61080 + cfg->ext_buf_end_margin = 0;
61081 + cfg->tx_fifo_min_level = 0;
61082 + cfg->tx_fifo_low_comf_level = (5 * KILOBYTE);
61083 + cfg->stats_counters_enable = TRUE;
61084 + cfg->perf_counters_enable = TRUE;
61085 + cfg->deq_type = E_FMAN_PORT_DEQ_BY_PRI;
61086 +
61087 + if (type == E_FMAN_PORT_TYPE_HC) {
61088 + cfg->sync_req = FALSE;
61089 + cfg->deq_prefetch_opt = E_FMAN_PORT_DEQ_NO_PREFETCH;
61090 + } else {
61091 + cfg->sync_req = TRUE;
61092 + cfg->deq_prefetch_opt = E_FMAN_PORT_DEQ_FULL_PREFETCH;
61093 + }
61094 +
61095 + if (type == E_FMAN_PORT_TYPE_TX_10G) {
61096 + cfg->tx_fifo_deq_pipeline_depth = 4;
61097 + cfg->deq_high_pri = TRUE;
61098 + cfg->deq_byte_cnt = 0x1400;
61099 + } else {
61100 + if ((type == E_FMAN_PORT_TYPE_HC) ||
61101 + (type == E_FMAN_PORT_TYPE_OP))
61102 + cfg->tx_fifo_deq_pipeline_depth = 2;
61103 + else
61104 + cfg->tx_fifo_deq_pipeline_depth = 1;
61105 +
61106 + cfg->deq_high_pri = FALSE;
61107 + cfg->deq_byte_cnt = 0x400;
61108 + }
61109 + cfg->no_scatter_gather = DEFAULT_FMAN_SP_NO_SCATTER_GATHER;
61110 +}
61111 +
61112 +static uint8_t fman_port_find_bpool(struct fman_port *port, uint8_t bpid)
61113 +{
61114 + uint32_t *bp_reg, tmp;
61115 + uint8_t i, id;
61116 +
61117 + /* Find the pool */
61118 + bp_reg = port->bmi_regs->rx.fmbm_ebmpi;
61119 + for (i = 0;
61120 + (i < port->ext_pools_num && (i < FMAN_PORT_MAX_EXT_POOLS_NUM));
61121 + i++) {
61122 + tmp = ioread32be(&bp_reg[i]);
61123 + id = (uint8_t)((tmp & BMI_EXT_BUF_POOL_ID_MASK) >>
61124 + BMI_EXT_BUF_POOL_ID_SHIFT);
61125 +
61126 + if (id == bpid)
61127 + break;
61128 + }
61129 +
61130 + return i;
61131 +}
61132 +
61133 +int fman_port_init(struct fman_port *port,
61134 + struct fman_port_cfg *cfg,
61135 + struct fman_port_params *params)
61136 +{
61137 + int err;
61138 +
61139 + /* Init BMI registers */
61140 + switch (port->type) {
61141 + case E_FMAN_PORT_TYPE_RX:
61142 + case E_FMAN_PORT_TYPE_RX_10G:
61143 + err = init_bmi_rx(port, cfg, params);
61144 + break;
61145 + case E_FMAN_PORT_TYPE_TX:
61146 + case E_FMAN_PORT_TYPE_TX_10G:
61147 + err = init_bmi_tx(port, cfg, params);
61148 + break;
61149 + case E_FMAN_PORT_TYPE_OP:
61150 + case E_FMAN_PORT_TYPE_HC:
61151 + err = init_bmi_oh(port, cfg, params);
61152 + break;
61153 + default:
61154 + return -EINVAL;
61155 + }
61156 +
61157 + if (err)
61158 + return err;
61159 +
61160 + /* Init QMI registers */
61161 + if (!port->im_en)
61162 + {
61163 + err = init_qmi(port, cfg, params);
61164 + return err;
61165 + }
61166 + return 0;
61167 +}
61168 +
61169 +int fman_port_enable(struct fman_port *port)
61170 +{
61171 + uint32_t *bmi_cfg_reg, tmp;
61172 + bool rx_port;
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 + rx_port = TRUE;
61179 + break;
61180 + case E_FMAN_PORT_TYPE_TX:
61181 + case E_FMAN_PORT_TYPE_TX_10G:
61182 + bmi_cfg_reg = &port->bmi_regs->tx.fmbm_tcfg;
61183 + rx_port = FALSE;
61184 + break;
61185 + case E_FMAN_PORT_TYPE_OP:
61186 + case E_FMAN_PORT_TYPE_HC:
61187 + bmi_cfg_reg = &port->bmi_regs->oh.fmbm_ocfg;
61188 + rx_port = FALSE;
61189 + break;
61190 + default:
61191 + return -EINVAL;
61192 + }
61193 +
61194 + /* Enable QMI */
61195 + if (!rx_port) {
61196 + tmp = ioread32be(&port->qmi_regs->fmqm_pnc) | QMI_PORT_CFG_EN;
61197 + iowrite32be(tmp, &port->qmi_regs->fmqm_pnc);
61198 + }
61199 +
61200 + /* Enable BMI */
61201 + tmp = ioread32be(bmi_cfg_reg) | BMI_PORT_CFG_EN;
61202 + iowrite32be(tmp, bmi_cfg_reg);
61203 +
61204 + return 0;
61205 +}
61206 +
61207 +int fman_port_disable(const struct fman_port *port)
61208 +{
61209 + uint32_t *bmi_cfg_reg, *bmi_status_reg, tmp;
61210 + bool rx_port, failure = FALSE;
61211 + int count;
61212 +
61213 + switch (port->type) {
61214 + case E_FMAN_PORT_TYPE_RX:
61215 + case E_FMAN_PORT_TYPE_RX_10G:
61216 + bmi_cfg_reg = &port->bmi_regs->rx.fmbm_rcfg;
61217 + bmi_status_reg = &port->bmi_regs->rx.fmbm_rst;
61218 + rx_port = TRUE;
61219 + break;
61220 + case E_FMAN_PORT_TYPE_TX:
61221 + case E_FMAN_PORT_TYPE_TX_10G:
61222 + bmi_cfg_reg = &port->bmi_regs->tx.fmbm_tcfg;
61223 + bmi_status_reg = &port->bmi_regs->tx.fmbm_tst;
61224 + rx_port = FALSE;
61225 + break;
61226 + case E_FMAN_PORT_TYPE_OP:
61227 + case E_FMAN_PORT_TYPE_HC:
61228 + bmi_cfg_reg = &port->bmi_regs->oh.fmbm_ocfg;
61229 + bmi_status_reg = &port->bmi_regs->oh.fmbm_ost;
61230 + rx_port = FALSE;
61231 + break;
61232 + default:
61233 + return -EINVAL;
61234 + }
61235 +
61236 + /* Disable QMI */
61237 + if (!rx_port) {
61238 + tmp = ioread32be(&port->qmi_regs->fmqm_pnc) & ~QMI_PORT_CFG_EN;
61239 + iowrite32be(tmp, &port->qmi_regs->fmqm_pnc);
61240 +
61241 + /* Wait for QMI to finish FD handling */
61242 + count = 100;
61243 + do {
61244 + udelay(10);
61245 + tmp = ioread32be(&port->qmi_regs->fmqm_pns);
61246 + } while ((tmp & QMI_PORT_STATUS_DEQ_FD_BSY) && --count);
61247 +
61248 + if (count == 0)
61249 + {
61250 + /* Timeout */
61251 + failure = TRUE;
61252 + }
61253 + }
61254 +
61255 + /* Disable BMI */
61256 + tmp = ioread32be(bmi_cfg_reg) & ~BMI_PORT_CFG_EN;
61257 + iowrite32be(tmp, bmi_cfg_reg);
61258 +
61259 + /* Wait for graceful stop end */
61260 + count = 500;
61261 + do {
61262 + udelay(10);
61263 + tmp = ioread32be(bmi_status_reg);
61264 + } while ((tmp & BMI_PORT_STATUS_BSY) && --count);
61265 +
61266 + if (count == 0)
61267 + {
61268 + /* Timeout */
61269 + failure = TRUE;
61270 + }
61271 +
61272 + if (failure)
61273 + return -EBUSY;
61274 +
61275 + return 0;
61276 +}
61277 +
61278 +int fman_port_set_bpools(const struct fman_port *port,
61279 + const struct fman_port_bpools *bp)
61280 +{
61281 + uint32_t tmp, *bp_reg, *bp_depl_reg;
61282 + uint8_t i, max_bp_num;
61283 + bool grp_depl_used = FALSE, rx_port;
61284 +
61285 + switch (port->type) {
61286 + case E_FMAN_PORT_TYPE_RX:
61287 + case E_FMAN_PORT_TYPE_RX_10G:
61288 + max_bp_num = port->ext_pools_num;
61289 + rx_port = TRUE;
61290 + bp_reg = port->bmi_regs->rx.fmbm_ebmpi;
61291 + bp_depl_reg = &port->bmi_regs->rx.fmbm_mpd;
61292 + break;
61293 + case E_FMAN_PORT_TYPE_OP:
61294 + if (port->fm_rev_maj != 4)
61295 + return -EINVAL;
61296 + max_bp_num = FMAN_PORT_OBS_EXT_POOLS_NUM;
61297 + rx_port = FALSE;
61298 + bp_reg = port->bmi_regs->oh.fmbm_oebmpi;
61299 + bp_depl_reg = &port->bmi_regs->oh.fmbm_ompd;
61300 + break;
61301 + default:
61302 + return -EINVAL;
61303 + }
61304 +
61305 + if (rx_port) {
61306 + /* Check buffers are provided in ascending order */
61307 + for (i = 0;
61308 + (i < (bp->count-1) && (i < FMAN_PORT_MAX_EXT_POOLS_NUM - 1));
61309 + i++) {
61310 + if (bp->bpool[i].size > bp->bpool[i+1].size)
61311 + return -EINVAL;
61312 + }
61313 + }
61314 +
61315 + /* Set up external buffers pools */
61316 + for (i = 0; i < bp->count; i++) {
61317 + tmp = BMI_EXT_BUF_POOL_VALID;
61318 + tmp |= ((uint32_t)bp->bpool[i].bpid <<
61319 + BMI_EXT_BUF_POOL_ID_SHIFT) & BMI_EXT_BUF_POOL_ID_MASK;
61320 +
61321 + if (rx_port) {
61322 + if (bp->counters_enable)
61323 + tmp |= BMI_EXT_BUF_POOL_EN_COUNTER;
61324 +
61325 + if (bp->bpool[i].is_backup)
61326 + tmp |= BMI_EXT_BUF_POOL_BACKUP;
61327 +
61328 + tmp |= (uint32_t)bp->bpool[i].size;
61329 + }
61330 +
61331 + iowrite32be(tmp, &bp_reg[i]);
61332 + }
61333 +
61334 + /* Clear unused pools */
61335 + for (i = bp->count; i < max_bp_num; i++)
61336 + iowrite32be(0, &bp_reg[i]);
61337 +
61338 + /* Pools depletion */
61339 + tmp = 0;
61340 + for (i = 0; i < FMAN_PORT_MAX_EXT_POOLS_NUM; i++) {
61341 + if (bp->bpool[i].grp_bp_depleted) {
61342 + grp_depl_used = TRUE;
61343 + tmp |= 0x80000000 >> i;
61344 + }
61345 +
61346 + if (bp->bpool[i].single_bp_depleted)
61347 + tmp |= 0x80 >> i;
61348 +
61349 + if (bp->bpool[i].pfc_priorities_en)
61350 + tmp |= 0x0100 << i;
61351 + }
61352 +
61353 + if (grp_depl_used)
61354 + tmp |= ((uint32_t)bp->grp_bp_depleted_num - 1) <<
61355 + BMI_POOL_DEP_NUM_OF_POOLS_SHIFT;
61356 +
61357 + iowrite32be(tmp, bp_depl_reg);
61358 + return 0;
61359 +}
61360 +
61361 +int fman_port_set_rate_limiter(struct fman_port *port,
61362 + struct fman_port_rate_limiter *rate_limiter)
61363 +{
61364 + uint32_t *rate_limit_reg, *rate_limit_scale_reg;
61365 + uint32_t granularity, tmp;
61366 + uint8_t usec_bit, factor;
61367 +
61368 + switch (port->type) {
61369 + case E_FMAN_PORT_TYPE_TX:
61370 + case E_FMAN_PORT_TYPE_TX_10G:
61371 + rate_limit_reg = &port->bmi_regs->tx.fmbm_trlmt;
61372 + rate_limit_scale_reg = &port->bmi_regs->tx.fmbm_trlmts;
61373 + granularity = BMI_RATE_LIMIT_GRAN_TX;
61374 + break;
61375 + case E_FMAN_PORT_TYPE_OP:
61376 + rate_limit_reg = &port->bmi_regs->oh.fmbm_orlmt;
61377 + rate_limit_scale_reg = &port->bmi_regs->oh.fmbm_orlmts;
61378 + granularity = BMI_RATE_LIMIT_GRAN_OP;
61379 + break;
61380 + default:
61381 + return -EINVAL;
61382 + }
61383 +
61384 + /* Factor is per 1 usec count */
61385 + factor = 1;
61386 + usec_bit = rate_limiter->count_1micro_bit;
61387 +
61388 + /* If rate limit is too small for an 1usec factor, adjust timestamp
61389 + * scale and multiply the factor */
61390 + while (rate_limiter->rate < (granularity / factor)) {
61391 + if (usec_bit == 31)
61392 + /* Can't configure rate limiter - rate is too small */
61393 + return -EINVAL;
61394 +
61395 + usec_bit++;
61396 + factor <<= 1;
61397 + }
61398 +
61399 + /* Figure out register value. The "while" above quarantees that
61400 + * (rate_limiter->rate * factor / granularity) >= 1 */
61401 + tmp = (uint32_t)(rate_limiter->rate * factor / granularity - 1);
61402 +
61403 + /* Check rate limit isn't too large */
61404 + if (tmp >= BMI_RATE_LIMIT_MAX_RATE_IN_GRAN_UNITS)
61405 + return -EINVAL;
61406 +
61407 + /* Check burst size is in allowed range */
61408 + if ((rate_limiter->burst_size == 0) ||
61409 + (rate_limiter->burst_size >
61410 + BMI_RATE_LIMIT_MAX_BURST_SIZE))
61411 + return -EINVAL;
61412 +
61413 + tmp |= (uint32_t)(rate_limiter->burst_size - 1) <<
61414 + BMI_RATE_LIMIT_MAX_BURST_SHIFT;
61415 +
61416 + if ((port->type == E_FMAN_PORT_TYPE_OP) &&
61417 + (port->fm_rev_maj == 4)) {
61418 + if (rate_limiter->high_burst_size_gran)
61419 + tmp |= BMI_RATE_LIMIT_HIGH_BURST_SIZE_GRAN;
61420 + }
61421 +
61422 + iowrite32be(tmp, rate_limit_reg);
61423 +
61424 + /* Set up rate limiter scale register */
61425 + tmp = BMI_RATE_LIMIT_SCALE_EN;
61426 + tmp |= (31 - (uint32_t)usec_bit) << BMI_RATE_LIMIT_SCALE_TSBS_SHIFT;
61427 +
61428 + if ((port->type == E_FMAN_PORT_TYPE_OP) &&
61429 + (port->fm_rev_maj == 4))
61430 + tmp |= rate_limiter->rate_factor;
61431 +
61432 + iowrite32be(tmp, rate_limit_scale_reg);
61433 +
61434 + return 0;
61435 +}
61436 +
61437 +int fman_port_delete_rate_limiter(struct fman_port *port)
61438 +{
61439 + uint32_t *rate_limit_scale_reg;
61440 +
61441 + switch (port->type) {
61442 + case E_FMAN_PORT_TYPE_TX:
61443 + case E_FMAN_PORT_TYPE_TX_10G:
61444 + rate_limit_scale_reg = &port->bmi_regs->tx.fmbm_trlmts;
61445 + break;
61446 + case E_FMAN_PORT_TYPE_OP:
61447 + rate_limit_scale_reg = &port->bmi_regs->oh.fmbm_orlmts;
61448 + break;
61449 + default:
61450 + return -EINVAL;
61451 + }
61452 +
61453 + iowrite32be(0, rate_limit_scale_reg);
61454 + return 0;
61455 +}
61456 +
61457 +int fman_port_set_err_mask(struct fman_port *port, uint32_t err_mask)
61458 +{
61459 + uint32_t *err_mask_reg;
61460 +
61461 + /* Obtain register address */
61462 + switch (port->type) {
61463 + case E_FMAN_PORT_TYPE_RX:
61464 + case E_FMAN_PORT_TYPE_RX_10G:
61465 + err_mask_reg = &port->bmi_regs->rx.fmbm_rfsem;
61466 + break;
61467 + case E_FMAN_PORT_TYPE_OP:
61468 + err_mask_reg = &port->bmi_regs->oh.fmbm_ofsem;
61469 + break;
61470 + default:
61471 + return -EINVAL;
61472 + }
61473 +
61474 + iowrite32be(err_mask, err_mask_reg);
61475 + return 0;
61476 +}
61477 +
61478 +int fman_port_set_discard_mask(struct fman_port *port, uint32_t discard_mask)
61479 +{
61480 + uint32_t *discard_mask_reg;
61481 +
61482 + /* Obtain register address */
61483 + switch (port->type) {
61484 + case E_FMAN_PORT_TYPE_RX:
61485 + case E_FMAN_PORT_TYPE_RX_10G:
61486 + discard_mask_reg = &port->bmi_regs->rx.fmbm_rfsdm;
61487 + break;
61488 + case E_FMAN_PORT_TYPE_OP:
61489 + discard_mask_reg = &port->bmi_regs->oh.fmbm_ofsdm;
61490 + break;
61491 + default:
61492 + return -EINVAL;
61493 + }
61494 +
61495 + iowrite32be(discard_mask, discard_mask_reg);
61496 + return 0;
61497 +}
61498 +
61499 +int fman_port_modify_rx_fd_bits(struct fman_port *port,
61500 + uint8_t rx_fd_bits,
61501 + bool add)
61502 +{
61503 + uint32_t tmp;
61504 +
61505 + switch (port->type) {
61506 + case E_FMAN_PORT_TYPE_RX:
61507 + case E_FMAN_PORT_TYPE_RX_10G:
61508 + break;
61509 + default:
61510 + return -EINVAL;
61511 + }
61512 +
61513 + tmp = ioread32be(&port->bmi_regs->rx.fmbm_rfne);
61514 +
61515 + if (add)
61516 + tmp |= (uint32_t)rx_fd_bits << BMI_NEXT_ENG_FD_BITS_SHIFT;
61517 + else
61518 + tmp &= ~((uint32_t)rx_fd_bits << BMI_NEXT_ENG_FD_BITS_SHIFT);
61519 +
61520 + iowrite32be(tmp, &port->bmi_regs->rx.fmbm_rfne);
61521 + return 0;
61522 +}
61523 +
61524 +int fman_port_set_perf_cnt_params(struct fman_port *port,
61525 + struct fman_port_perf_cnt_params *params)
61526 +{
61527 + uint32_t *pcp_reg, tmp;
61528 +
61529 + /* Obtain register address and check parameters are in range */
61530 + switch (port->type) {
61531 + case E_FMAN_PORT_TYPE_RX:
61532 + case E_FMAN_PORT_TYPE_RX_10G:
61533 + pcp_reg = &port->bmi_regs->rx.fmbm_rpcp;
61534 + if ((params->queue_val == 0) ||
61535 + (params->queue_val > MAX_PERFORMANCE_RX_QUEUE_COMP))
61536 + return -EINVAL;
61537 + break;
61538 + case E_FMAN_PORT_TYPE_TX:
61539 + case E_FMAN_PORT_TYPE_TX_10G:
61540 + pcp_reg = &port->bmi_regs->tx.fmbm_tpcp;
61541 + if ((params->queue_val == 0) ||
61542 + (params->queue_val > MAX_PERFORMANCE_TX_QUEUE_COMP))
61543 + return -EINVAL;
61544 + break;
61545 + case E_FMAN_PORT_TYPE_OP:
61546 + case E_FMAN_PORT_TYPE_HC:
61547 + pcp_reg = &port->bmi_regs->oh.fmbm_opcp;
61548 + if (params->queue_val != 0)
61549 + return -EINVAL;
61550 + break;
61551 + default:
61552 + return -EINVAL;
61553 + }
61554 +
61555 + if ((params->task_val == 0) ||
61556 + (params->task_val > MAX_PERFORMANCE_TASK_COMP))
61557 + return -EINVAL;
61558 + if ((params->dma_val == 0) ||
61559 + (params->dma_val > MAX_PERFORMANCE_DMA_COMP))
61560 + return -EINVAL;
61561 + if ((params->fifo_val == 0) ||
61562 + ((params->fifo_val / FMAN_PORT_BMI_FIFO_UNITS) >
61563 + MAX_PERFORMANCE_FIFO_COMP))
61564 + return -EINVAL;
61565 + tmp = (uint32_t)(params->task_val - 1) <<
61566 + BMI_PERFORMANCE_TASK_COMP_SHIFT;
61567 + tmp |= (uint32_t)(params->dma_val - 1) <<
61568 + BMI_PERFORMANCE_DMA_COMP_SHIFT;
61569 + tmp |= (uint32_t)(params->fifo_val / FMAN_PORT_BMI_FIFO_UNITS - 1);
61570 +
61571 + switch (port->type) {
61572 + case E_FMAN_PORT_TYPE_RX:
61573 + case E_FMAN_PORT_TYPE_RX_10G:
61574 + case E_FMAN_PORT_TYPE_TX:
61575 + case E_FMAN_PORT_TYPE_TX_10G:
61576 + tmp |= (uint32_t)(params->queue_val - 1) <<
61577 + BMI_PERFORMANCE_QUEUE_COMP_SHIFT;
61578 + break;
61579 + default:
61580 + break;
61581 + }
61582 +
61583 +
61584 + iowrite32be(tmp, pcp_reg);
61585 + return 0;
61586 +}
61587 +
61588 +int fman_port_set_stats_cnt_mode(struct fman_port *port, bool enable)
61589 +{
61590 + uint32_t *stats_reg, tmp;
61591 +
61592 + switch (port->type) {
61593 + case E_FMAN_PORT_TYPE_RX:
61594 + case E_FMAN_PORT_TYPE_RX_10G:
61595 + stats_reg = &port->bmi_regs->rx.fmbm_rstc;
61596 + break;
61597 + case E_FMAN_PORT_TYPE_TX:
61598 + case E_FMAN_PORT_TYPE_TX_10G:
61599 + stats_reg = &port->bmi_regs->tx.fmbm_tstc;
61600 + break;
61601 + case E_FMAN_PORT_TYPE_OP:
61602 + case E_FMAN_PORT_TYPE_HC:
61603 + stats_reg = &port->bmi_regs->oh.fmbm_ostc;
61604 + break;
61605 + default:
61606 + return -EINVAL;
61607 + }
61608 +
61609 + tmp = ioread32be(stats_reg);
61610 +
61611 + if (enable)
61612 + tmp |= BMI_COUNTERS_EN;
61613 + else
61614 + tmp &= ~BMI_COUNTERS_EN;
61615 +
61616 + iowrite32be(tmp, stats_reg);
61617 + return 0;
61618 +}
61619 +
61620 +int fman_port_set_perf_cnt_mode(struct fman_port *port, bool enable)
61621 +{
61622 + uint32_t *stats_reg, tmp;
61623 +
61624 + switch (port->type) {
61625 + case E_FMAN_PORT_TYPE_RX:
61626 + case E_FMAN_PORT_TYPE_RX_10G:
61627 + stats_reg = &port->bmi_regs->rx.fmbm_rpc;
61628 + break;
61629 + case E_FMAN_PORT_TYPE_TX:
61630 + case E_FMAN_PORT_TYPE_TX_10G:
61631 + stats_reg = &port->bmi_regs->tx.fmbm_tpc;
61632 + break;
61633 + case E_FMAN_PORT_TYPE_OP:
61634 + case E_FMAN_PORT_TYPE_HC:
61635 + stats_reg = &port->bmi_regs->oh.fmbm_opc;
61636 + break;
61637 + default:
61638 + return -EINVAL;
61639 + }
61640 +
61641 + tmp = ioread32be(stats_reg);
61642 +
61643 + if (enable)
61644 + tmp |= BMI_COUNTERS_EN;
61645 + else
61646 + tmp &= ~BMI_COUNTERS_EN;
61647 +
61648 + iowrite32be(tmp, stats_reg);
61649 + return 0;
61650 +}
61651 +
61652 +int fman_port_set_queue_cnt_mode(struct fman_port *port, bool enable)
61653 +{
61654 + uint32_t tmp;
61655 +
61656 + tmp = ioread32be(&port->qmi_regs->fmqm_pnc);
61657 +
61658 + if (enable)
61659 + tmp |= QMI_PORT_CFG_EN_COUNTERS;
61660 + else
61661 + tmp &= ~QMI_PORT_CFG_EN_COUNTERS;
61662 +
61663 + iowrite32be(tmp, &port->qmi_regs->fmqm_pnc);
61664 + return 0;
61665 +}
61666 +
61667 +int fman_port_set_bpool_cnt_mode(struct fman_port *port,
61668 + uint8_t bpid,
61669 + bool enable)
61670 +{
61671 + uint8_t index;
61672 + uint32_t tmp;
61673 +
61674 + switch (port->type) {
61675 + case E_FMAN_PORT_TYPE_RX:
61676 + case E_FMAN_PORT_TYPE_RX_10G:
61677 + break;
61678 + default:
61679 + return -EINVAL;
61680 + }
61681 +
61682 + /* Find the pool */
61683 + index = fman_port_find_bpool(port, bpid);
61684 + if (index == port->ext_pools_num || index == FMAN_PORT_MAX_EXT_POOLS_NUM)
61685 + /* Not found */
61686 + return -EINVAL;
61687 +
61688 + tmp = ioread32be(&port->bmi_regs->rx.fmbm_ebmpi[index]);
61689 +
61690 + if (enable)
61691 + tmp |= BMI_EXT_BUF_POOL_EN_COUNTER;
61692 + else
61693 + tmp &= ~BMI_EXT_BUF_POOL_EN_COUNTER;
61694 +
61695 + iowrite32be(tmp, &port->bmi_regs->rx.fmbm_ebmpi[index]);
61696 + return 0;
61697 +}
61698 +
61699 +uint32_t fman_port_get_stats_counter(struct fman_port *port,
61700 + enum fman_port_stats_counters counter)
61701 +{
61702 + uint32_t *stats_reg, ret_val;
61703 +
61704 + switch (port->type) {
61705 + case E_FMAN_PORT_TYPE_RX:
61706 + case E_FMAN_PORT_TYPE_RX_10G:
61707 + get_rx_stats_reg(port, counter, &stats_reg);
61708 + break;
61709 + case E_FMAN_PORT_TYPE_TX:
61710 + case E_FMAN_PORT_TYPE_TX_10G:
61711 + get_tx_stats_reg(port, counter, &stats_reg);
61712 + break;
61713 + case E_FMAN_PORT_TYPE_OP:
61714 + case E_FMAN_PORT_TYPE_HC:
61715 + get_oh_stats_reg(port, counter, &stats_reg);
61716 + break;
61717 + default:
61718 + stats_reg = NULL;
61719 + }
61720 +
61721 + if (stats_reg == NULL)
61722 + return 0;
61723 +
61724 + ret_val = ioread32be(stats_reg);
61725 + return ret_val;
61726 +}
61727 +
61728 +void fman_port_set_stats_counter(struct fman_port *port,
61729 + enum fman_port_stats_counters counter,
61730 + uint32_t value)
61731 +{
61732 + uint32_t *stats_reg;
61733 +
61734 + switch (port->type) {
61735 + case E_FMAN_PORT_TYPE_RX:
61736 + case E_FMAN_PORT_TYPE_RX_10G:
61737 + get_rx_stats_reg(port, counter, &stats_reg);
61738 + break;
61739 + case E_FMAN_PORT_TYPE_TX:
61740 + case E_FMAN_PORT_TYPE_TX_10G:
61741 + get_tx_stats_reg(port, counter, &stats_reg);
61742 + break;
61743 + case E_FMAN_PORT_TYPE_OP:
61744 + case E_FMAN_PORT_TYPE_HC:
61745 + get_oh_stats_reg(port, counter, &stats_reg);
61746 + break;
61747 + default:
61748 + stats_reg = NULL;
61749 + }
61750 +
61751 + if (stats_reg == NULL)
61752 + return;
61753 +
61754 + iowrite32be(value, stats_reg);
61755 +}
61756 +
61757 +uint32_t fman_port_get_perf_counter(struct fman_port *port,
61758 + enum fman_port_perf_counters counter)
61759 +{
61760 + uint32_t *perf_reg, ret_val;
61761 +
61762 + switch (port->type) {
61763 + case E_FMAN_PORT_TYPE_RX:
61764 + case E_FMAN_PORT_TYPE_RX_10G:
61765 + get_rx_perf_reg(port, counter, &perf_reg);
61766 + break;
61767 + case E_FMAN_PORT_TYPE_TX:
61768 + case E_FMAN_PORT_TYPE_TX_10G:
61769 + get_tx_perf_reg(port, counter, &perf_reg);
61770 + break;
61771 + case E_FMAN_PORT_TYPE_OP:
61772 + case E_FMAN_PORT_TYPE_HC:
61773 + get_oh_perf_reg(port, counter, &perf_reg);
61774 + break;
61775 + default:
61776 + perf_reg = NULL;
61777 + }
61778 +
61779 + if (perf_reg == NULL)
61780 + return 0;
61781 +
61782 + ret_val = ioread32be(perf_reg);
61783 + return ret_val;
61784 +}
61785 +
61786 +void fman_port_set_perf_counter(struct fman_port *port,
61787 + enum fman_port_perf_counters counter,
61788 + uint32_t value)
61789 +{
61790 + uint32_t *perf_reg;
61791 +
61792 + switch (port->type) {
61793 + case E_FMAN_PORT_TYPE_RX:
61794 + case E_FMAN_PORT_TYPE_RX_10G:
61795 + get_rx_perf_reg(port, counter, &perf_reg);
61796 + break;
61797 + case E_FMAN_PORT_TYPE_TX:
61798 + case E_FMAN_PORT_TYPE_TX_10G:
61799 + get_tx_perf_reg(port, counter, &perf_reg);
61800 + break;
61801 + case E_FMAN_PORT_TYPE_OP:
61802 + case E_FMAN_PORT_TYPE_HC:
61803 + get_oh_perf_reg(port, counter, &perf_reg);
61804 + break;
61805 + default:
61806 + perf_reg = NULL;
61807 + }
61808 +
61809 + if (perf_reg == NULL)
61810 + return;
61811 +
61812 + iowrite32be(value, perf_reg);
61813 +}
61814 +
61815 +uint32_t fman_port_get_qmi_counter(struct fman_port *port,
61816 + enum fman_port_qmi_counters counter)
61817 +{
61818 + uint32_t *queue_reg, ret_val;
61819 +
61820 + get_qmi_counter_reg(port, counter, &queue_reg);
61821 +
61822 + if (queue_reg == NULL)
61823 + return 0;
61824 +
61825 + ret_val = ioread32be(queue_reg);
61826 + return ret_val;
61827 +}
61828 +
61829 +void fman_port_set_qmi_counter(struct fman_port *port,
61830 + enum fman_port_qmi_counters counter,
61831 + uint32_t value)
61832 +{
61833 + uint32_t *queue_reg;
61834 +
61835 + get_qmi_counter_reg(port, counter, &queue_reg);
61836 +
61837 + if (queue_reg == NULL)
61838 + return;
61839 +
61840 + iowrite32be(value, queue_reg);
61841 +}
61842 +
61843 +uint32_t fman_port_get_bpool_counter(struct fman_port *port, uint8_t bpid)
61844 +{
61845 + uint8_t index;
61846 + uint32_t ret_val;
61847 +
61848 + switch (port->type) {
61849 + case E_FMAN_PORT_TYPE_RX:
61850 + case E_FMAN_PORT_TYPE_RX_10G:
61851 + break;
61852 + default:
61853 + return 0;
61854 + }
61855 +
61856 + /* Find the pool */
61857 + index = fman_port_find_bpool(port, bpid);
61858 + if (index == port->ext_pools_num || index == FMAN_PORT_MAX_EXT_POOLS_NUM)
61859 + /* Not found */
61860 + return 0;
61861 +
61862 + ret_val = ioread32be(&port->bmi_regs->rx.fmbm_acnt[index]);
61863 + return ret_val;
61864 +}
61865 +
61866 +void fman_port_set_bpool_counter(struct fman_port *port,
61867 + uint8_t bpid,
61868 + uint32_t value)
61869 +{
61870 + uint8_t index;
61871 +
61872 + switch (port->type) {
61873 + case E_FMAN_PORT_TYPE_RX:
61874 + case E_FMAN_PORT_TYPE_RX_10G:
61875 + break;
61876 + default:
61877 + return;
61878 + }
61879 +
61880 + /* Find the pool */
61881 + index = fman_port_find_bpool(port, bpid);
61882 + if (index == port->ext_pools_num || index == FMAN_PORT_MAX_EXT_POOLS_NUM)
61883 + /* Not found */
61884 + return;
61885 +
61886 + iowrite32be(value, &port->bmi_regs->rx.fmbm_acnt[index]);
61887 +}
61888 +
61889 +int fman_port_add_congestion_grps(struct fman_port *port,
61890 + uint32_t grps_map[FMAN_PORT_CG_MAP_NUM])
61891 +{
61892 + int i;
61893 + uint32_t tmp, *grp_map_reg;
61894 + uint8_t max_grp_map_num;
61895 +
61896 + switch (port->type) {
61897 + case E_FMAN_PORT_TYPE_RX:
61898 + case E_FMAN_PORT_TYPE_RX_10G:
61899 + if (port->fm_rev_maj == 4)
61900 + max_grp_map_num = 1;
61901 + else
61902 + max_grp_map_num = FMAN_PORT_CG_MAP_NUM;
61903 + grp_map_reg = port->bmi_regs->rx.fmbm_rcgm;
61904 + break;
61905 + case E_FMAN_PORT_TYPE_OP:
61906 + max_grp_map_num = 1;
61907 + if (port->fm_rev_maj != 4)
61908 + return -EINVAL;
61909 + grp_map_reg = port->bmi_regs->oh.fmbm_ocgm;
61910 + break;
61911 + default:
61912 + return -EINVAL;
61913 + }
61914 +
61915 + for (i = (max_grp_map_num - 1); i >= 0; i--) {
61916 + if (grps_map[i] == 0)
61917 + continue;
61918 + tmp = ioread32be(&grp_map_reg[i]);
61919 + tmp |= grps_map[i];
61920 + iowrite32be(tmp, &grp_map_reg[i]);
61921 + }
61922 +
61923 + return 0;
61924 +}
61925 +
61926 +int fman_port_remove_congestion_grps(struct fman_port *port,
61927 + uint32_t grps_map[FMAN_PORT_CG_MAP_NUM])
61928 +{
61929 + int i;
61930 + uint32_t tmp, *grp_map_reg;
61931 + uint8_t max_grp_map_num;
61932 +
61933 + switch (port->type) {
61934 + case E_FMAN_PORT_TYPE_RX:
61935 + case E_FMAN_PORT_TYPE_RX_10G:
61936 + if (port->fm_rev_maj == 4)
61937 + max_grp_map_num = 1;
61938 + else
61939 + max_grp_map_num = FMAN_PORT_CG_MAP_NUM;
61940 + grp_map_reg = port->bmi_regs->rx.fmbm_rcgm;
61941 + break;
61942 + case E_FMAN_PORT_TYPE_OP:
61943 + max_grp_map_num = 1;
61944 + if (port->fm_rev_maj != 4)
61945 + return -EINVAL;
61946 + grp_map_reg = port->bmi_regs->oh.fmbm_ocgm;
61947 + break;
61948 + default:
61949 + return -EINVAL;
61950 + }
61951 +
61952 + for (i = (max_grp_map_num - 1); i >= 0; i--) {
61953 + if (grps_map[i] == 0)
61954 + continue;
61955 + tmp = ioread32be(&grp_map_reg[i]);
61956 + tmp &= ~grps_map[i];
61957 + iowrite32be(tmp, &grp_map_reg[i]);
61958 + }
61959 + return 0;
61960 +}
61961 --- /dev/null
61962 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Rtc/Makefile
61963 @@ -0,0 +1,15 @@
61964 +#
61965 +# Makefile for the Freescale Ethernet controllers
61966 +#
61967 +ccflags-y += -DVERSION=\"\"
61968 +#
61969 +#Include netcomm SW specific definitions
61970 +include $(srctree)/drivers/net/ethernet/freescale/sdk_fman/ncsw_config.mk
61971 +
61972 +NCSW_FM_INC = $(srctree)/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/inc
61973 +
61974 +ccflags-y += -I$(NCSW_FM_INC)
61975 +
61976 +obj-y += fsl-ncsw-RTC.o
61977 +
61978 +fsl-ncsw-RTC-objs := fm_rtc.o fman_rtc.o
61979 --- /dev/null
61980 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Rtc/fm_rtc.c
61981 @@ -0,0 +1,692 @@
61982 +/*
61983 + * Copyright 2008-2012 Freescale Semiconductor Inc.
61984 + *
61985 + * Redistribution and use in source and binary forms, with or without
61986 + * modification, are permitted provided that the following conditions are met:
61987 + * * Redistributions of source code must retain the above copyright
61988 + * notice, this list of conditions and the following disclaimer.
61989 + * * Redistributions in binary form must reproduce the above copyright
61990 + * notice, this list of conditions and the following disclaimer in the
61991 + * documentation and/or other materials provided with the distribution.
61992 + * * Neither the name of Freescale Semiconductor nor the
61993 + * names of its contributors may be used to endorse or promote products
61994 + * derived from this software without specific prior written permission.
61995 + *
61996 + *
61997 + * ALTERNATIVELY, this software may be distributed under the terms of the
61998 + * GNU General Public License ("GPL") as published by the Free Software
61999 + * Foundation, either version 2 of that License or (at your option) any
62000 + * later version.
62001 + *
62002 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
62003 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
62004 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
62005 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
62006 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
62007 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
62008 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
62009 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
62010 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
62011 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
62012 + */
62013 +
62014 +
62015 +/******************************************************************************
62016 + @File fm_rtc.c
62017 +
62018 + @Description FM RTC driver implementation.
62019 +
62020 + @Cautions None
62021 +*//***************************************************************************/
62022 +#include <linux/math64.h>
62023 +#include "error_ext.h"
62024 +#include "debug_ext.h"
62025 +#include "string_ext.h"
62026 +#include "part_ext.h"
62027 +#include "xx_ext.h"
62028 +#include "ncsw_ext.h"
62029 +
62030 +#include "fm_rtc.h"
62031 +#include "fm_common.h"
62032 +
62033 +
62034 +
62035 +/*****************************************************************************/
62036 +static t_Error CheckInitParameters(t_FmRtc *p_Rtc)
62037 +{
62038 + struct rtc_cfg *p_RtcDriverParam = p_Rtc->p_RtcDriverParam;
62039 + int i;
62040 +
62041 + if ((p_RtcDriverParam->src_clk != E_FMAN_RTC_SOURCE_CLOCK_EXTERNAL) &&
62042 + (p_RtcDriverParam->src_clk != E_FMAN_RTC_SOURCE_CLOCK_SYSTEM) &&
62043 + (p_RtcDriverParam->src_clk != E_FMAN_RTC_SOURCE_CLOCK_OSCILATOR))
62044 + RETURN_ERROR(MAJOR, E_INVALID_CLOCK, ("Source clock undefined"));
62045 +
62046 + if (p_Rtc->outputClockDivisor == 0)
62047 + {
62048 + RETURN_ERROR(MAJOR, E_INVALID_VALUE,
62049 + ("Divisor for output clock (should be positive)"));
62050 + }
62051 +
62052 + for (i=0; i < FM_RTC_NUM_OF_ALARMS; i++)
62053 + {
62054 + if ((p_RtcDriverParam->alarm_polarity[i] != E_FMAN_RTC_ALARM_POLARITY_ACTIVE_LOW) &&
62055 + (p_RtcDriverParam->alarm_polarity[i] != E_FMAN_RTC_ALARM_POLARITY_ACTIVE_HIGH))
62056 + {
62057 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION, ("Alarm %d signal polarity", i));
62058 + }
62059 + }
62060 + for (i=0; i < FM_RTC_NUM_OF_EXT_TRIGGERS; i++)
62061 + {
62062 + if ((p_RtcDriverParam->trigger_polarity[i] != E_FMAN_RTC_TRIGGER_ON_FALLING_EDGE) &&
62063 + (p_RtcDriverParam->trigger_polarity[i] != E_FMAN_RTC_TRIGGER_ON_RISING_EDGE))
62064 + {
62065 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION, ("Trigger %d signal polarity", i));
62066 + }
62067 + }
62068 +
62069 + return E_OK;
62070 +}
62071 +
62072 +/*****************************************************************************/
62073 +static void RtcExceptions(t_Handle h_FmRtc)
62074 +{
62075 + t_FmRtc *p_Rtc = (t_FmRtc *)h_FmRtc;
62076 + struct rtc_regs *p_MemMap;
62077 + register uint32_t events;
62078 +
62079 + ASSERT_COND(p_Rtc);
62080 + p_MemMap = p_Rtc->p_MemMap;
62081 +
62082 + events = fman_rtc_check_and_clear_event(p_MemMap);
62083 + if (events & FMAN_RTC_TMR_TEVENT_ALM1)
62084 + {
62085 + if (p_Rtc->alarmParams[0].clearOnExpiration)
62086 + {
62087 + fman_rtc_set_timer_alarm_l(p_MemMap, 0, 0);
62088 + fman_rtc_disable_interupt(p_MemMap, FMAN_RTC_TMR_TEVENT_ALM1);
62089 + }
62090 + ASSERT_COND(p_Rtc->alarmParams[0].f_AlarmCallback);
62091 + p_Rtc->alarmParams[0].f_AlarmCallback(p_Rtc->h_App, 0);
62092 + }
62093 + if (events & FMAN_RTC_TMR_TEVENT_ALM2)
62094 + {
62095 + if (p_Rtc->alarmParams[1].clearOnExpiration)
62096 + {
62097 + fman_rtc_set_timer_alarm_l(p_MemMap, 1, 0);
62098 + fman_rtc_disable_interupt(p_MemMap, FMAN_RTC_TMR_TEVENT_ALM2);
62099 + }
62100 + ASSERT_COND(p_Rtc->alarmParams[1].f_AlarmCallback);
62101 + p_Rtc->alarmParams[1].f_AlarmCallback(p_Rtc->h_App, 1);
62102 + }
62103 + if (events & FMAN_RTC_TMR_TEVENT_PP1)
62104 + {
62105 + ASSERT_COND(p_Rtc->periodicPulseParams[0].f_PeriodicPulseCallback);
62106 + p_Rtc->periodicPulseParams[0].f_PeriodicPulseCallback(p_Rtc->h_App, 0);
62107 + }
62108 + if (events & FMAN_RTC_TMR_TEVENT_PP2)
62109 + {
62110 + ASSERT_COND(p_Rtc->periodicPulseParams[1].f_PeriodicPulseCallback);
62111 + p_Rtc->periodicPulseParams[1].f_PeriodicPulseCallback(p_Rtc->h_App, 1);
62112 + }
62113 + if (events & FMAN_RTC_TMR_TEVENT_ETS1)
62114 + {
62115 + ASSERT_COND(p_Rtc->externalTriggerParams[0].f_ExternalTriggerCallback);
62116 + p_Rtc->externalTriggerParams[0].f_ExternalTriggerCallback(p_Rtc->h_App, 0);
62117 + }
62118 + if (events & FMAN_RTC_TMR_TEVENT_ETS2)
62119 + {
62120 + ASSERT_COND(p_Rtc->externalTriggerParams[1].f_ExternalTriggerCallback);
62121 + p_Rtc->externalTriggerParams[1].f_ExternalTriggerCallback(p_Rtc->h_App, 1);
62122 + }
62123 +}
62124 +
62125 +
62126 +/*****************************************************************************/
62127 +t_Handle FM_RTC_Config(t_FmRtcParams *p_FmRtcParam)
62128 +{
62129 + t_FmRtc *p_Rtc;
62130 +
62131 + SANITY_CHECK_RETURN_VALUE(p_FmRtcParam, E_NULL_POINTER, NULL);
62132 +
62133 + /* Allocate memory for the FM RTC driver parameters */
62134 + p_Rtc = (t_FmRtc *)XX_Malloc(sizeof(t_FmRtc));
62135 + if (!p_Rtc)
62136 + {
62137 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FM RTC driver structure"));
62138 + return NULL;
62139 + }
62140 +
62141 + memset(p_Rtc, 0, sizeof(t_FmRtc));
62142 +
62143 + /* Allocate memory for the FM RTC driver parameters */
62144 + p_Rtc->p_RtcDriverParam = (struct rtc_cfg *)XX_Malloc(sizeof(struct rtc_cfg));
62145 + if (!p_Rtc->p_RtcDriverParam)
62146 + {
62147 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FM RTC driver parameters"));
62148 + XX_Free(p_Rtc);
62149 + return NULL;
62150 + }
62151 +
62152 + memset(p_Rtc->p_RtcDriverParam, 0, sizeof(struct rtc_cfg));
62153 +
62154 + /* Store RTC configuration parameters */
62155 + p_Rtc->h_Fm = p_FmRtcParam->h_Fm;
62156 +
62157 + /* Set default RTC configuration parameters */
62158 + fman_rtc_defconfig(p_Rtc->p_RtcDriverParam);
62159 +
62160 + p_Rtc->outputClockDivisor = DEFAULT_OUTPUT_CLOCK_DIVISOR;
62161 + p_Rtc->p_RtcDriverParam->bypass = DEFAULT_BYPASS;
62162 + p_Rtc->clockPeriodNanoSec = DEFAULT_CLOCK_PERIOD; /* 1 usec */
62163 +
62164 +
62165 + /* Store RTC parameters in the RTC control structure */
62166 + p_Rtc->p_MemMap = (struct rtc_regs *)UINT_TO_PTR(p_FmRtcParam->baseAddress);
62167 + p_Rtc->h_App = p_FmRtcParam->h_App;
62168 +
62169 + return p_Rtc;
62170 +}
62171 +
62172 +/*****************************************************************************/
62173 +t_Error FM_RTC_Init(t_Handle h_FmRtc)
62174 +{
62175 + t_FmRtc *p_Rtc = (t_FmRtc *)h_FmRtc;
62176 + struct rtc_cfg *p_RtcDriverParam;
62177 + struct rtc_regs *p_MemMap;
62178 + uint32_t freqCompensation = 0;
62179 + uint64_t tmpDouble;
62180 + bool init_freq_comp = FALSE;
62181 +
62182 + p_RtcDriverParam = p_Rtc->p_RtcDriverParam;
62183 + p_MemMap = p_Rtc->p_MemMap;
62184 +
62185 + if (CheckInitParameters(p_Rtc)!=E_OK)
62186 + RETURN_ERROR(MAJOR, E_CONFLICT,
62187 + ("Init Parameters are not Valid"));
62188 +
62189 + /* TODO check that no timestamping MACs are working in this stage. */
62190 +
62191 + /* find source clock frequency in Mhz */
62192 + if (p_Rtc->p_RtcDriverParam->src_clk != E_FMAN_RTC_SOURCE_CLOCK_SYSTEM)
62193 + p_Rtc->srcClkFreqMhz = p_Rtc->p_RtcDriverParam->ext_src_clk_freq;
62194 + else
62195 + p_Rtc->srcClkFreqMhz = (uint32_t)(FmGetMacClockFreq(p_Rtc->h_Fm));
62196 +
62197 + /* if timer in Master mode Initialize TMR_CTRL */
62198 + /* We want the counter (TMR_CNT) to count in nano-seconds */
62199 + if (!p_RtcDriverParam->timer_slave_mode && p_Rtc->p_RtcDriverParam->bypass)
62200 + p_Rtc->clockPeriodNanoSec = (1000 / p_Rtc->srcClkFreqMhz);
62201 + else
62202 + {
62203 + /* Initialize TMR_ADD with the initial frequency compensation value:
62204 + freqCompensation = (2^32 / frequency ratio) */
62205 + /* frequency ratio = sorce clock/rtc clock =
62206 + * (p_Rtc->srcClkFreqMhz*1000000))/ 1/(p_Rtc->clockPeriodNanoSec * 1000000000) */
62207 + init_freq_comp = TRUE;
62208 + freqCompensation = (uint32_t)DIV_CEIL(ACCUMULATOR_OVERFLOW * 1000,
62209 + p_Rtc->clockPeriodNanoSec * p_Rtc->srcClkFreqMhz);
62210 + }
62211 +
62212 + /* check the legality of the relation between source and destination clocks */
62213 + /* should be larger than 1.0001 */
62214 + tmpDouble = 10000 * (uint64_t)p_Rtc->clockPeriodNanoSec * (uint64_t)p_Rtc->srcClkFreqMhz;
62215 + if ((tmpDouble) <= 10001)
62216 + RETURN_ERROR(MAJOR, E_CONFLICT,
62217 + ("Invalid relation between source and destination clocks. Should be larger than 1.0001"));
62218 +
62219 + fman_rtc_init(p_RtcDriverParam,
62220 + p_MemMap,
62221 + FM_RTC_NUM_OF_ALARMS,
62222 + FM_RTC_NUM_OF_PERIODIC_PULSES,
62223 + FM_RTC_NUM_OF_EXT_TRIGGERS,
62224 + init_freq_comp,
62225 + freqCompensation,
62226 + p_Rtc->outputClockDivisor);
62227 +
62228 + /* Register the FM RTC interrupt */
62229 + FmRegisterIntr(p_Rtc->h_Fm, e_FM_MOD_TMR, 0, e_FM_INTR_TYPE_NORMAL, RtcExceptions , p_Rtc);
62230 +
62231 + /* Free parameters structures */
62232 + XX_Free(p_Rtc->p_RtcDriverParam);
62233 + p_Rtc->p_RtcDriverParam = NULL;
62234 +
62235 + return E_OK;
62236 +}
62237 +
62238 +/*****************************************************************************/
62239 +t_Error FM_RTC_Free(t_Handle h_FmRtc)
62240 +{
62241 + t_FmRtc *p_Rtc = (t_FmRtc *)h_FmRtc;
62242 +
62243 + SANITY_CHECK_RETURN_ERROR(p_Rtc, E_INVALID_HANDLE);
62244 +
62245 + if (p_Rtc->p_RtcDriverParam)
62246 + {
62247 + XX_Free(p_Rtc->p_RtcDriverParam);
62248 + }
62249 + else
62250 + {
62251 + FM_RTC_Disable(h_FmRtc);
62252 + }
62253 +
62254 + /* Unregister FM RTC interrupt */
62255 + FmUnregisterIntr(p_Rtc->h_Fm, e_FM_MOD_TMR, 0, e_FM_INTR_TYPE_NORMAL);
62256 + XX_Free(p_Rtc);
62257 +
62258 + return E_OK;
62259 +}
62260 +
62261 +/*****************************************************************************/
62262 +t_Error FM_RTC_ConfigSourceClock(t_Handle h_FmRtc,
62263 + e_FmSrcClk srcClk,
62264 + uint32_t freqInMhz)
62265 +{
62266 + t_FmRtc *p_Rtc = (t_FmRtc *)h_FmRtc;
62267 +
62268 + SANITY_CHECK_RETURN_ERROR(p_Rtc, E_INVALID_HANDLE);
62269 + SANITY_CHECK_RETURN_ERROR(p_Rtc->p_RtcDriverParam, E_INVALID_STATE);
62270 +
62271 + p_Rtc->p_RtcDriverParam->src_clk = (enum fman_src_clock)srcClk;
62272 + if (srcClk != e_FM_RTC_SOURCE_CLOCK_SYSTEM)
62273 + p_Rtc->p_RtcDriverParam->ext_src_clk_freq = freqInMhz;
62274 +
62275 + return E_OK;
62276 +}
62277 +
62278 +/*****************************************************************************/
62279 +t_Error FM_RTC_ConfigPeriod(t_Handle h_FmRtc, uint32_t period)
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->clockPeriodNanoSec = period;
62287 +
62288 + return E_OK;
62289 +}
62290 +
62291 +/*****************************************************************************/
62292 +t_Error FM_RTC_ConfigFrequencyBypass(t_Handle h_FmRtc, bool enabled)
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->p_RtcDriverParam->bypass = enabled;
62300 +
62301 + return E_OK;
62302 +}
62303 +
62304 +/*****************************************************************************/
62305 +t_Error FM_RTC_ConfigInvertedInputClockPhase(t_Handle h_FmRtc, bool inverted)
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->invert_input_clk_phase = inverted;
62313 +
62314 + return E_OK;
62315 +}
62316 +
62317 +/*****************************************************************************/
62318 +t_Error FM_RTC_ConfigInvertedOutputClockPhase(t_Handle h_FmRtc, bool inverted)
62319 +{
62320 + t_FmRtc *p_Rtc = (t_FmRtc *)h_FmRtc;
62321 +
62322 + SANITY_CHECK_RETURN_ERROR(p_Rtc, E_INVALID_HANDLE);
62323 + SANITY_CHECK_RETURN_ERROR(p_Rtc->p_RtcDriverParam, E_INVALID_STATE);
62324 +
62325 + p_Rtc->p_RtcDriverParam->invert_output_clk_phase = inverted;
62326 +
62327 + return E_OK;
62328 +}
62329 +
62330 +/*****************************************************************************/
62331 +t_Error FM_RTC_ConfigOutputClockDivisor(t_Handle h_FmRtc, uint16_t divisor)
62332 +{
62333 + t_FmRtc *p_Rtc = (t_FmRtc *)h_FmRtc;
62334 +
62335 + SANITY_CHECK_RETURN_ERROR(p_Rtc, E_INVALID_HANDLE);
62336 + SANITY_CHECK_RETURN_ERROR(p_Rtc->p_RtcDriverParam, E_INVALID_STATE);
62337 +
62338 + p_Rtc->outputClockDivisor = divisor;
62339 +
62340 + return E_OK;
62341 +}
62342 +
62343 +/*****************************************************************************/
62344 +t_Error FM_RTC_ConfigPulseRealignment(t_Handle h_FmRtc, bool enable)
62345 +{
62346 + t_FmRtc *p_Rtc = (t_FmRtc *)h_FmRtc;
62347 +
62348 + SANITY_CHECK_RETURN_ERROR(p_Rtc, E_INVALID_HANDLE);
62349 + SANITY_CHECK_RETURN_ERROR(p_Rtc->p_RtcDriverParam, E_INVALID_STATE);
62350 +
62351 + p_Rtc->p_RtcDriverParam->pulse_realign = enable;
62352 +
62353 + return E_OK;
62354 +}
62355 +
62356 +/*****************************************************************************/
62357 +t_Error FM_RTC_ConfigAlarmPolarity(t_Handle h_FmRtc,
62358 + uint8_t alarmId,
62359 + e_FmRtcAlarmPolarity alarmPolarity)
62360 +{
62361 + t_FmRtc *p_Rtc = (t_FmRtc *)h_FmRtc;
62362 +
62363 + SANITY_CHECK_RETURN_ERROR(p_Rtc, E_INVALID_HANDLE);
62364 + SANITY_CHECK_RETURN_ERROR(p_Rtc->p_RtcDriverParam, E_INVALID_STATE);
62365 +
62366 + if (alarmId >= FM_RTC_NUM_OF_ALARMS)
62367 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION, ("Alarm ID"));
62368 +
62369 + p_Rtc->p_RtcDriverParam->alarm_polarity[alarmId] =
62370 + (enum fman_rtc_alarm_polarity)alarmPolarity;
62371 +
62372 + return E_OK;
62373 +}
62374 +
62375 +/*****************************************************************************/
62376 +t_Error FM_RTC_ConfigExternalTriggerPolarity(t_Handle h_FmRtc,
62377 + uint8_t triggerId,
62378 + e_FmRtcTriggerPolarity triggerPolarity)
62379 +{
62380 + t_FmRtc *p_Rtc = (t_FmRtc *)h_FmRtc;
62381 +
62382 + SANITY_CHECK_RETURN_ERROR(p_Rtc, E_INVALID_HANDLE);
62383 + SANITY_CHECK_RETURN_ERROR(p_Rtc->p_RtcDriverParam, E_INVALID_STATE);
62384 +
62385 + if (triggerId >= FM_RTC_NUM_OF_EXT_TRIGGERS)
62386 + {
62387 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION, ("External trigger ID"));
62388 + }
62389 +
62390 + p_Rtc->p_RtcDriverParam->trigger_polarity[triggerId] =
62391 + (enum fman_rtc_trigger_polarity)triggerPolarity;
62392 +
62393 + return E_OK;
62394 +}
62395 +
62396 +/*****************************************************************************/
62397 +t_Error FM_RTC_Enable(t_Handle h_FmRtc, bool resetClock)
62398 +{
62399 + t_FmRtc *p_Rtc = (t_FmRtc *)h_FmRtc;
62400 +
62401 + SANITY_CHECK_RETURN_ERROR(p_Rtc, E_INVALID_HANDLE);
62402 + SANITY_CHECK_RETURN_ERROR(!p_Rtc->p_RtcDriverParam, E_INVALID_STATE);
62403 +
62404 + fman_rtc_enable(p_Rtc->p_MemMap, resetClock);
62405 + return E_OK;
62406 +}
62407 +
62408 +/*****************************************************************************/
62409 +t_Error FM_RTC_Disable(t_Handle h_FmRtc)
62410 +{
62411 + t_FmRtc *p_Rtc = (t_FmRtc *)h_FmRtc;
62412 +
62413 + SANITY_CHECK_RETURN_ERROR(p_Rtc, E_INVALID_HANDLE);
62414 + SANITY_CHECK_RETURN_ERROR(!p_Rtc->p_RtcDriverParam, E_INVALID_STATE);
62415 +
62416 + /* TODO A check must be added here, that no timestamping MAC's
62417 + * are working in this stage. */
62418 + fman_rtc_disable(p_Rtc->p_MemMap);
62419 +
62420 + return E_OK;
62421 +}
62422 +
62423 +/*****************************************************************************/
62424 +t_Error FM_RTC_SetClockOffset(t_Handle h_FmRtc, int64_t offset)
62425 +{
62426 + t_FmRtc *p_Rtc = (t_FmRtc *)h_FmRtc;
62427 +
62428 + SANITY_CHECK_RETURN_ERROR(p_Rtc, E_INVALID_HANDLE);
62429 + SANITY_CHECK_RETURN_ERROR(!p_Rtc->p_RtcDriverParam, E_INVALID_STATE);
62430 +
62431 + fman_rtc_set_timer_offset(p_Rtc->p_MemMap, offset);
62432 + return E_OK;
62433 +}
62434 +
62435 +/*****************************************************************************/
62436 +t_Error FM_RTC_SetAlarm(t_Handle h_FmRtc, t_FmRtcAlarmParams *p_FmRtcAlarmParams)
62437 +{
62438 + t_FmRtc *p_Rtc = (t_FmRtc *)h_FmRtc;
62439 + uint64_t tmpAlarm;
62440 + bool enable = FALSE;
62441 +
62442 + SANITY_CHECK_RETURN_ERROR(p_Rtc, E_INVALID_HANDLE);
62443 + SANITY_CHECK_RETURN_ERROR(!p_Rtc->p_RtcDriverParam, E_INVALID_STATE);
62444 +
62445 + if (p_FmRtcAlarmParams->alarmId >= FM_RTC_NUM_OF_ALARMS)
62446 + {
62447 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION, ("Alarm ID"));
62448 + }
62449 +
62450 + if (p_FmRtcAlarmParams->alarmTime < p_Rtc->clockPeriodNanoSec)
62451 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION,
62452 + ("Alarm time must be equal or larger than RTC period - %d nanoseconds",
62453 + p_Rtc->clockPeriodNanoSec));
62454 + tmpAlarm = p_FmRtcAlarmParams->alarmTime;
62455 + if (do_div(tmpAlarm, p_Rtc->clockPeriodNanoSec))
62456 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION,
62457 + ("Alarm time must be a multiple of RTC period - %d nanoseconds",
62458 + p_Rtc->clockPeriodNanoSec));
62459 +
62460 + if (p_FmRtcAlarmParams->f_AlarmCallback)
62461 + {
62462 + p_Rtc->alarmParams[p_FmRtcAlarmParams->alarmId].f_AlarmCallback = p_FmRtcAlarmParams->f_AlarmCallback;
62463 + p_Rtc->alarmParams[p_FmRtcAlarmParams->alarmId].clearOnExpiration = p_FmRtcAlarmParams->clearOnExpiration;
62464 + enable = TRUE;
62465 + }
62466 +
62467 + fman_rtc_set_alarm(p_Rtc->p_MemMap, p_FmRtcAlarmParams->alarmId, (unsigned long)tmpAlarm, enable);
62468 +
62469 + return E_OK;
62470 +}
62471 +
62472 +/*****************************************************************************/
62473 +t_Error FM_RTC_SetPeriodicPulse(t_Handle h_FmRtc, t_FmRtcPeriodicPulseParams *p_FmRtcPeriodicPulseParams)
62474 +{
62475 + t_FmRtc *p_Rtc = (t_FmRtc *)h_FmRtc;
62476 + bool enable = FALSE;
62477 + uint64_t tmpFiper;
62478 +
62479 + SANITY_CHECK_RETURN_ERROR(p_Rtc, E_INVALID_HANDLE);
62480 + SANITY_CHECK_RETURN_ERROR(!p_Rtc->p_RtcDriverParam, E_INVALID_STATE);
62481 +
62482 + if (p_FmRtcPeriodicPulseParams->periodicPulseId >= FM_RTC_NUM_OF_PERIODIC_PULSES)
62483 + {
62484 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION, ("Periodic pulse ID"));
62485 + }
62486 + if (fman_rtc_is_enabled(p_Rtc->p_MemMap))
62487 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION, ("Can't set Periodic pulse when RTC is enabled."));
62488 + if (p_FmRtcPeriodicPulseParams->periodicPulsePeriod < p_Rtc->clockPeriodNanoSec)
62489 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION,
62490 + ("Periodic pulse must be equal or larger than RTC period - %d nanoseconds",
62491 + p_Rtc->clockPeriodNanoSec));
62492 + tmpFiper = p_FmRtcPeriodicPulseParams->periodicPulsePeriod;
62493 + if (do_div(tmpFiper, p_Rtc->clockPeriodNanoSec))
62494 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION,
62495 + ("Periodic pulse must be a multiple of RTC period - %d nanoseconds",
62496 + p_Rtc->clockPeriodNanoSec));
62497 + if (tmpFiper & 0xffffffff00000000LL)
62498 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION,
62499 + ("Periodic pulse/RTC Period must be smaller than 4294967296",
62500 + p_Rtc->clockPeriodNanoSec));
62501 +
62502 + if (p_FmRtcPeriodicPulseParams->f_PeriodicPulseCallback)
62503 + {
62504 + p_Rtc->periodicPulseParams[p_FmRtcPeriodicPulseParams->periodicPulseId].f_PeriodicPulseCallback =
62505 + p_FmRtcPeriodicPulseParams->f_PeriodicPulseCallback;
62506 + enable = TRUE;
62507 + }
62508 + fman_rtc_set_periodic_pulse(p_Rtc->p_MemMap, p_FmRtcPeriodicPulseParams->periodicPulseId, (uint32_t)tmpFiper, enable);
62509 + return E_OK;
62510 +}
62511 +
62512 +/*****************************************************************************/
62513 +t_Error FM_RTC_ClearPeriodicPulse(t_Handle h_FmRtc, uint8_t periodicPulseId)
62514 +{
62515 + t_FmRtc *p_Rtc = (t_FmRtc *)h_FmRtc;
62516 +
62517 + SANITY_CHECK_RETURN_ERROR(p_Rtc, E_INVALID_HANDLE);
62518 + SANITY_CHECK_RETURN_ERROR(!p_Rtc->p_RtcDriverParam, E_INVALID_STATE);
62519 +
62520 + if (periodicPulseId >= FM_RTC_NUM_OF_PERIODIC_PULSES)
62521 + {
62522 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION, ("Periodic pulse ID"));
62523 + }
62524 +
62525 + p_Rtc->periodicPulseParams[periodicPulseId].f_PeriodicPulseCallback = NULL;
62526 + fman_rtc_clear_periodic_pulse(p_Rtc->p_MemMap, periodicPulseId);
62527 +
62528 + return E_OK;
62529 +}
62530 +
62531 +/*****************************************************************************/
62532 +t_Error FM_RTC_SetExternalTrigger(t_Handle h_FmRtc, t_FmRtcExternalTriggerParams *p_FmRtcExternalTriggerParams)
62533 +{
62534 + t_FmRtc *p_Rtc = (t_FmRtc *)h_FmRtc;
62535 + bool enable = FALSE;
62536 +
62537 + SANITY_CHECK_RETURN_ERROR(p_Rtc, E_INVALID_HANDLE);
62538 + SANITY_CHECK_RETURN_ERROR(!p_Rtc->p_RtcDriverParam, E_INVALID_STATE);
62539 +
62540 + if (p_FmRtcExternalTriggerParams->externalTriggerId >= FM_RTC_NUM_OF_EXT_TRIGGERS)
62541 + {
62542 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION, ("External Trigger ID"));
62543 + }
62544 +
62545 + if (p_FmRtcExternalTriggerParams->f_ExternalTriggerCallback)
62546 + {
62547 + p_Rtc->externalTriggerParams[p_FmRtcExternalTriggerParams->externalTriggerId].f_ExternalTriggerCallback = p_FmRtcExternalTriggerParams->f_ExternalTriggerCallback;
62548 + enable = TRUE;
62549 + }
62550 +
62551 + fman_rtc_set_ext_trigger(p_Rtc->p_MemMap, p_FmRtcExternalTriggerParams->externalTriggerId, enable, p_FmRtcExternalTriggerParams->usePulseAsInput);
62552 + return E_OK;
62553 +}
62554 +
62555 +/*****************************************************************************/
62556 +t_Error FM_RTC_ClearExternalTrigger(t_Handle h_FmRtc, uint8_t externalTriggerId)
62557 +{
62558 + t_FmRtc *p_Rtc = (t_FmRtc *)h_FmRtc;
62559 +
62560 + SANITY_CHECK_RETURN_ERROR(p_Rtc, E_INVALID_HANDLE);
62561 + SANITY_CHECK_RETURN_ERROR(!p_Rtc->p_RtcDriverParam, E_INVALID_STATE);
62562 +
62563 + if (externalTriggerId >= FM_RTC_NUM_OF_EXT_TRIGGERS)
62564 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION, ("External Trigger ID"));
62565 +
62566 + p_Rtc->externalTriggerParams[externalTriggerId].f_ExternalTriggerCallback = NULL;
62567 +
62568 + fman_rtc_clear_external_trigger(p_Rtc->p_MemMap, externalTriggerId);
62569 +
62570 + return E_OK;
62571 +}
62572 +
62573 +/*****************************************************************************/
62574 +t_Error FM_RTC_GetExternalTriggerTimeStamp(t_Handle h_FmRtc,
62575 + uint8_t triggerId,
62576 + uint64_t *p_TimeStamp)
62577 +{
62578 + t_FmRtc *p_Rtc = (t_FmRtc *)h_FmRtc;
62579 +
62580 + SANITY_CHECK_RETURN_ERROR(p_Rtc, E_INVALID_HANDLE);
62581 + SANITY_CHECK_RETURN_ERROR(!p_Rtc->p_RtcDriverParam, E_INVALID_STATE);
62582 +
62583 + if (triggerId >= FM_RTC_NUM_OF_EXT_TRIGGERS)
62584 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION, ("External trigger ID"));
62585 +
62586 + *p_TimeStamp = fman_rtc_get_trigger_stamp(p_Rtc->p_MemMap, triggerId)*p_Rtc->clockPeriodNanoSec;
62587 +
62588 + return E_OK;
62589 +}
62590 +
62591 +/*****************************************************************************/
62592 +t_Error FM_RTC_GetCurrentTime(t_Handle h_FmRtc, uint64_t *p_Ts)
62593 +{
62594 + t_FmRtc *p_Rtc = (t_FmRtc *)h_FmRtc;
62595 +
62596 + SANITY_CHECK_RETURN_ERROR(p_Rtc, E_INVALID_HANDLE);
62597 + SANITY_CHECK_RETURN_ERROR(!p_Rtc->p_RtcDriverParam, E_INVALID_STATE);
62598 +
62599 + *p_Ts = fman_rtc_get_timer(p_Rtc->p_MemMap)*p_Rtc->clockPeriodNanoSec;
62600 +
62601 + return E_OK;
62602 +}
62603 +
62604 +/*****************************************************************************/
62605 +t_Error FM_RTC_SetCurrentTime(t_Handle h_FmRtc, uint64_t ts)
62606 +{
62607 + t_FmRtc *p_Rtc = (t_FmRtc *)h_FmRtc;
62608 +
62609 + SANITY_CHECK_RETURN_ERROR(p_Rtc, E_INVALID_HANDLE);
62610 + SANITY_CHECK_RETURN_ERROR(!p_Rtc->p_RtcDriverParam, E_INVALID_STATE);
62611 +
62612 + do_div(ts, p_Rtc->clockPeriodNanoSec);
62613 + fman_rtc_set_timer(p_Rtc->p_MemMap, (int64_t)ts);
62614 +
62615 + return E_OK;
62616 +}
62617 +
62618 +/*****************************************************************************/
62619 +t_Error FM_RTC_GetFreqCompensation(t_Handle h_FmRtc, uint32_t *p_Compensation)
62620 +{
62621 + t_FmRtc *p_Rtc = (t_FmRtc *)h_FmRtc;
62622 +
62623 + SANITY_CHECK_RETURN_ERROR(p_Rtc, E_INVALID_HANDLE);
62624 + SANITY_CHECK_RETURN_ERROR(!p_Rtc->p_RtcDriverParam, E_INVALID_STATE);
62625 +
62626 + *p_Compensation = fman_rtc_get_frequency_compensation(p_Rtc->p_MemMap);
62627 +
62628 + return E_OK;
62629 +}
62630 +
62631 +/*****************************************************************************/
62632 +t_Error FM_RTC_SetFreqCompensation(t_Handle h_FmRtc, uint32_t freqCompensation)
62633 +{
62634 + t_FmRtc *p_Rtc = (t_FmRtc *)h_FmRtc;
62635 +
62636 + SANITY_CHECK_RETURN_ERROR(p_Rtc, E_INVALID_HANDLE);
62637 + SANITY_CHECK_RETURN_ERROR(!p_Rtc->p_RtcDriverParam, E_INVALID_STATE);
62638 +
62639 + /* set the new freqCompensation */
62640 + fman_rtc_set_frequency_compensation(p_Rtc->p_MemMap, freqCompensation);
62641 +
62642 + return E_OK;
62643 +}
62644 +
62645 +#ifdef CONFIG_PTP_1588_CLOCK_DPAA
62646 +/*****************************************************************************/
62647 +t_Error FM_RTC_EnableInterrupt(t_Handle h_FmRtc, uint32_t events)
62648 +{
62649 + t_FmRtc *p_Rtc = (t_FmRtc *)h_FmRtc;
62650 +
62651 + SANITY_CHECK_RETURN_ERROR(p_Rtc, E_INVALID_HANDLE);
62652 + SANITY_CHECK_RETURN_ERROR(!p_Rtc->p_RtcDriverParam, E_INVALID_STATE);
62653 +
62654 + /* enable interrupt */
62655 + fman_rtc_enable_interupt(p_Rtc->p_MemMap, events);
62656 +
62657 + return E_OK;
62658 +}
62659 +
62660 +/*****************************************************************************/
62661 +t_Error FM_RTC_DisableInterrupt(t_Handle h_FmRtc, uint32_t events)
62662 +{
62663 + t_FmRtc *p_Rtc = (t_FmRtc *)h_FmRtc;
62664 +
62665 + SANITY_CHECK_RETURN_ERROR(p_Rtc, E_INVALID_HANDLE);
62666 + SANITY_CHECK_RETURN_ERROR(!p_Rtc->p_RtcDriverParam, E_INVALID_STATE);
62667 +
62668 + /* disable interrupt */
62669 + fman_rtc_disable_interupt(p_Rtc->p_MemMap, events);
62670 +
62671 + return E_OK;
62672 +}
62673 +#endif
62674 --- /dev/null
62675 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Rtc/fm_rtc.h
62676 @@ -0,0 +1,96 @@
62677 +/*
62678 + * Copyright 2008-2012 Freescale Semiconductor Inc.
62679 + *
62680 + * Redistribution and use in source and binary forms, with or without
62681 + * modification, are permitted provided that the following conditions are met:
62682 + * * Redistributions of source code must retain the above copyright
62683 + * notice, this list of conditions and the following disclaimer.
62684 + * * Redistributions in binary form must reproduce the above copyright
62685 + * notice, this list of conditions and the following disclaimer in the
62686 + * documentation and/or other materials provided with the distribution.
62687 + * * Neither the name of Freescale Semiconductor nor the
62688 + * names of its contributors may be used to endorse or promote products
62689 + * derived from this software without specific prior written permission.
62690 + *
62691 + *
62692 + * ALTERNATIVELY, this software may be distributed under the terms of the
62693 + * GNU General Public License ("GPL") as published by the Free Software
62694 + * Foundation, either version 2 of that License or (at your option) any
62695 + * later version.
62696 + *
62697 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
62698 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
62699 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
62700 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
62701 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
62702 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
62703 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
62704 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
62705 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
62706 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
62707 + */
62708 +
62709 +
62710 +/******************************************************************************
62711 + @File fm_rtc.h
62712 +
62713 + @Description Memory map and internal definitions for FM RTC IEEE1588 Timer driver.
62714 +
62715 + @Cautions None
62716 +*//***************************************************************************/
62717 +
62718 +#ifndef __FM_RTC_H__
62719 +#define __FM_RTC_H__
62720 +
62721 +#include "std_ext.h"
62722 +#include "fm_rtc_ext.h"
62723 +
62724 +
62725 +#define __ERR_MODULE__ MODULE_FM_RTC
62726 +
62727 +/* General definitions */
62728 +
62729 +#define ACCUMULATOR_OVERFLOW ((uint64_t)(1LL << 32))
62730 +#define DEFAULT_OUTPUT_CLOCK_DIVISOR 0x00000002
62731 +#define DEFAULT_BYPASS FALSE
62732 +#define DEFAULT_CLOCK_PERIOD 1000
62733 +
62734 +
62735 +
62736 +typedef struct t_FmRtcAlarm
62737 +{
62738 + t_FmRtcExceptionsCallback *f_AlarmCallback;
62739 + bool clearOnExpiration;
62740 +} t_FmRtcAlarm;
62741 +
62742 +typedef struct t_FmRtcPeriodicPulse
62743 +{
62744 + t_FmRtcExceptionsCallback *f_PeriodicPulseCallback;
62745 +} t_FmRtcPeriodicPulse;
62746 +
62747 +typedef struct t_FmRtcExternalTrigger
62748 +{
62749 + t_FmRtcExceptionsCallback *f_ExternalTriggerCallback;
62750 +} t_FmRtcExternalTrigger;
62751 +
62752 +
62753 +/**************************************************************************//**
62754 + @Description RTC FM driver control structure.
62755 +*//***************************************************************************/
62756 +typedef struct t_FmRtc
62757 +{
62758 + t_Part *p_Part; /**< Pointer to the integration device */
62759 + t_Handle h_Fm;
62760 + t_Handle h_App; /**< Application handle */
62761 + struct rtc_regs *p_MemMap;
62762 + uint32_t clockPeriodNanoSec; /**< RTC clock period in nano-seconds (for FS mode) */
62763 + uint32_t srcClkFreqMhz;
62764 + uint16_t outputClockDivisor; /**< Output clock divisor (for FS mode) */
62765 + t_FmRtcAlarm alarmParams[FM_RTC_NUM_OF_ALARMS];
62766 + t_FmRtcPeriodicPulse periodicPulseParams[FM_RTC_NUM_OF_PERIODIC_PULSES];
62767 + t_FmRtcExternalTrigger externalTriggerParams[FM_RTC_NUM_OF_EXT_TRIGGERS];
62768 + struct rtc_cfg *p_RtcDriverParam; /**< RTC Driver parameters (for Init phase) */
62769 +} t_FmRtc;
62770 +
62771 +
62772 +#endif /* __FM_RTC_H__ */
62773 --- /dev/null
62774 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Rtc/fman_rtc.c
62775 @@ -0,0 +1,334 @@
62776 +/*
62777 + * Copyright 2008-2013 Freescale Semiconductor Inc.
62778 + *
62779 + * Redistribution and use in source and binary forms, with or without
62780 + * modification, are permitted provided that the following conditions are met:
62781 + * * Redistributions of source code must retain the above copyright
62782 + * notice, this list of conditions and the following disclaimer.
62783 + * * Redistributions in binary form must reproduce the above copyright
62784 + * notice, this list of conditions and the following disclaimer in the
62785 + * documentation and/or other materials provided with the distribution.
62786 + * * Neither the name of Freescale Semiconductor nor the
62787 + * names of its contributors may be used to endorse or promote products
62788 + * derived from this software without specific prior written permission.
62789 + *
62790 + *
62791 + * ALTERNATIVELY, this software may be distributed under the terms of the
62792 + * GNU General Public License ("GPL") as published by the Free Software
62793 + * Foundation, either version 2 of that License or (at your option) any
62794 + * later version.
62795 + *
62796 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
62797 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
62798 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
62799 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
62800 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
62801 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
62802 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
62803 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
62804 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
62805 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
62806 + */
62807 +
62808 +#include "fsl_fman_rtc.h"
62809 +
62810 +void fman_rtc_defconfig(struct rtc_cfg *cfg)
62811 +{
62812 + int i;
62813 + cfg->src_clk = DEFAULT_SRC_CLOCK;
62814 + cfg->invert_input_clk_phase = DEFAULT_INVERT_INPUT_CLK_PHASE;
62815 + cfg->invert_output_clk_phase = DEFAULT_INVERT_OUTPUT_CLK_PHASE;
62816 + cfg->pulse_realign = DEFAULT_PULSE_REALIGN;
62817 + for (i = 0; i < FMAN_RTC_MAX_NUM_OF_ALARMS; i++)
62818 + cfg->alarm_polarity[i] = DEFAULT_ALARM_POLARITY;
62819 + for (i = 0; i < FMAN_RTC_MAX_NUM_OF_EXT_TRIGGERS; i++)
62820 + cfg->trigger_polarity[i] = DEFAULT_TRIGGER_POLARITY;
62821 +}
62822 +
62823 +uint32_t fman_rtc_get_events(struct rtc_regs *regs)
62824 +{
62825 + return ioread32be(&regs->tmr_tevent);
62826 +}
62827 +
62828 +uint32_t fman_rtc_get_event(struct rtc_regs *regs, uint32_t ev_mask)
62829 +{
62830 + return ioread32be(&regs->tmr_tevent) & ev_mask;
62831 +}
62832 +
62833 +uint32_t fman_rtc_get_interrupt_mask(struct rtc_regs *regs)
62834 +{
62835 + return ioread32be(&regs->tmr_temask);
62836 +}
62837 +
62838 +void fman_rtc_set_interrupt_mask(struct rtc_regs *regs, uint32_t mask)
62839 +{
62840 + iowrite32be(mask, &regs->tmr_temask);
62841 +}
62842 +
62843 +void fman_rtc_ack_event(struct rtc_regs *regs, uint32_t events)
62844 +{
62845 + iowrite32be(events, &regs->tmr_tevent);
62846 +}
62847 +
62848 +uint32_t fman_rtc_check_and_clear_event(struct rtc_regs *regs)
62849 +{
62850 + uint32_t event;
62851 +
62852 + event = ioread32be(&regs->tmr_tevent);
62853 + event &= ioread32be(&regs->tmr_temask);
62854 +
62855 + if (event)
62856 + iowrite32be(event, &regs->tmr_tevent);
62857 + return event;
62858 +}
62859 +
62860 +uint32_t fman_rtc_get_frequency_compensation(struct rtc_regs *regs)
62861 +{
62862 + return ioread32be(&regs->tmr_add);
62863 +}
62864 +
62865 +void fman_rtc_set_frequency_compensation(struct rtc_regs *regs, uint32_t val)
62866 +{
62867 + iowrite32be(val, &regs->tmr_add);
62868 +}
62869 +
62870 +void fman_rtc_enable_interupt(struct rtc_regs *regs, uint32_t events)
62871 +{
62872 + fman_rtc_set_interrupt_mask(regs, fman_rtc_get_interrupt_mask(regs) | events);
62873 +}
62874 +
62875 +void fman_rtc_disable_interupt(struct rtc_regs *regs, uint32_t events)
62876 +{
62877 + fman_rtc_set_interrupt_mask(regs, fman_rtc_get_interrupt_mask(regs) & ~events);
62878 +}
62879 +
62880 +void fman_rtc_set_timer_alarm_l(struct rtc_regs *regs, int index, uint32_t val)
62881 +{
62882 + iowrite32be(val, &regs->tmr_alarm[index].tmr_alarm_l);
62883 +}
62884 +
62885 +void fman_rtc_set_timer_fiper(struct rtc_regs *regs, int index, uint32_t val)
62886 +{
62887 + iowrite32be(val, &regs->tmr_fiper[index]);
62888 +}
62889 +
62890 +void fman_rtc_set_timer_alarm(struct rtc_regs *regs, int index, int64_t val)
62891 +{
62892 + iowrite32be((uint32_t)val, &regs->tmr_alarm[index].tmr_alarm_l);
62893 + iowrite32be((uint32_t)(val >> 32), &regs->tmr_alarm[index].tmr_alarm_h);
62894 +}
62895 +
62896 +void fman_rtc_set_timer_offset(struct rtc_regs *regs, int64_t val)
62897 +{
62898 + iowrite32be((uint32_t)val, &regs->tmr_off_l);
62899 + iowrite32be((uint32_t)(val >> 32), &regs->tmr_off_h);
62900 +}
62901 +
62902 +uint64_t fman_rtc_get_trigger_stamp(struct rtc_regs *regs, int id)
62903 +{
62904 + uint64_t time;
62905 + /* TMR_CNT_L must be read first to get an accurate value */
62906 + time = (uint64_t)ioread32be(&regs->tmr_etts[id].tmr_etts_l);
62907 + time |= ((uint64_t)ioread32be(&regs->tmr_etts[id].tmr_etts_h)
62908 + << 32);
62909 +
62910 + return time;
62911 +}
62912 +
62913 +uint32_t fman_rtc_get_timer_ctrl(struct rtc_regs *regs)
62914 +{
62915 + return ioread32be(&regs->tmr_ctrl);
62916 +}
62917 +
62918 +void fman_rtc_set_timer_ctrl(struct rtc_regs *regs, uint32_t val)
62919 +{
62920 + iowrite32be(val, &regs->tmr_ctrl);
62921 +}
62922 +
62923 +void fman_rtc_timers_soft_reset(struct rtc_regs *regs)
62924 +{
62925 + fman_rtc_set_timer_ctrl(regs, FMAN_RTC_TMR_CTRL_TMSR);
62926 + udelay(10);
62927 + fman_rtc_set_timer_ctrl(regs, 0);
62928 +}
62929 +
62930 +void fman_rtc_init(struct rtc_cfg *cfg, struct rtc_regs *regs, int num_alarms,
62931 + int num_fipers, int num_ext_triggers, bool init_freq_comp,
62932 + uint32_t freq_compensation, uint32_t output_clock_divisor)
62933 +{
62934 + uint32_t tmr_ctrl;
62935 + int i;
62936 +
62937 + fman_rtc_timers_soft_reset(regs);
62938 +
62939 + /* Set the source clock */
62940 + switch (cfg->src_clk) {
62941 + case E_FMAN_RTC_SOURCE_CLOCK_SYSTEM:
62942 + tmr_ctrl = FMAN_RTC_TMR_CTRL_CKSEL_MAC_CLK;
62943 + break;
62944 + case E_FMAN_RTC_SOURCE_CLOCK_OSCILATOR:
62945 + tmr_ctrl = FMAN_RTC_TMR_CTRL_CKSEL_OSC_CLK;
62946 + break;
62947 + default:
62948 + /* Use a clock from the External TMR reference clock.*/
62949 + tmr_ctrl = FMAN_RTC_TMR_CTRL_CKSEL_EXT_CLK;
62950 + break;
62951 + }
62952 +
62953 + /* whatever period the user picked, the timestamp will advance in '1'
62954 + * every time the period passed. */
62955 + tmr_ctrl |= ((1 << FMAN_RTC_TMR_CTRL_TCLK_PERIOD_SHIFT) &
62956 + FMAN_RTC_TMR_CTRL_TCLK_PERIOD_MASK);
62957 +
62958 + if (cfg->invert_input_clk_phase)
62959 + tmr_ctrl |= FMAN_RTC_TMR_CTRL_CIPH;
62960 + if (cfg->invert_output_clk_phase)
62961 + tmr_ctrl |= FMAN_RTC_TMR_CTRL_COPH;
62962 +
62963 + for (i = 0; i < num_alarms; i++) {
62964 + if (cfg->alarm_polarity[i] ==
62965 + E_FMAN_RTC_ALARM_POLARITY_ACTIVE_LOW)
62966 + tmr_ctrl |= (FMAN_RTC_TMR_CTRL_ALMP1 >> i);
62967 + }
62968 +
62969 + for (i = 0; i < num_ext_triggers; i++)
62970 + if (cfg->trigger_polarity[i] ==
62971 + E_FMAN_RTC_TRIGGER_ON_FALLING_EDGE)
62972 + tmr_ctrl |= (FMAN_RTC_TMR_CTRL_ETEP1 << i);
62973 +
62974 + if (!cfg->timer_slave_mode && cfg->bypass)
62975 + tmr_ctrl |= FMAN_RTC_TMR_CTRL_BYP;
62976 +
62977 + fman_rtc_set_timer_ctrl(regs, tmr_ctrl);
62978 + if (init_freq_comp)
62979 + fman_rtc_set_frequency_compensation(regs, freq_compensation);
62980 +
62981 + /* Clear TMR_ALARM registers */
62982 + for (i = 0; i < num_alarms; i++)
62983 + fman_rtc_set_timer_alarm(regs, i, 0xFFFFFFFFFFFFFFFFLL);
62984 +
62985 + /* Clear TMR_TEVENT */
62986 + fman_rtc_ack_event(regs, FMAN_RTC_TMR_TEVENT_ALL);
62987 +
62988 + /* Initialize TMR_TEMASK */
62989 + fman_rtc_set_interrupt_mask(regs, 0);
62990 +
62991 + /* Clear TMR_FIPER registers */
62992 + for (i = 0; i < num_fipers; i++)
62993 + fman_rtc_set_timer_fiper(regs, i, 0xFFFFFFFF);
62994 +
62995 + /* Initialize TMR_PRSC */
62996 + iowrite32be(output_clock_divisor, &regs->tmr_prsc);
62997 +
62998 + /* Clear TMR_OFF */
62999 + fman_rtc_set_timer_offset(regs, 0);
63000 +}
63001 +
63002 +bool fman_rtc_is_enabled(struct rtc_regs *regs)
63003 +{
63004 + return (bool)(fman_rtc_get_timer_ctrl(regs) & FMAN_RTC_TMR_CTRL_TE);
63005 +}
63006 +
63007 +void fman_rtc_enable(struct rtc_regs *regs, bool reset_clock)
63008 +{
63009 + uint32_t tmr_ctrl = fman_rtc_get_timer_ctrl(regs);
63010 +
63011 + /* TODO check that no timestamping MACs are working in this stage. */
63012 + if (reset_clock) {
63013 + fman_rtc_set_timer_ctrl(regs, (tmr_ctrl | FMAN_RTC_TMR_CTRL_TMSR));
63014 +
63015 + udelay(10);
63016 + /* Clear TMR_OFF */
63017 + fman_rtc_set_timer_offset(regs, 0);
63018 + }
63019 +
63020 + fman_rtc_set_timer_ctrl(regs, (tmr_ctrl | FMAN_RTC_TMR_CTRL_TE));
63021 +}
63022 +
63023 +void fman_rtc_disable(struct rtc_regs *regs)
63024 +{
63025 + fman_rtc_set_timer_ctrl(regs, (fman_rtc_get_timer_ctrl(regs)
63026 + & ~(FMAN_RTC_TMR_CTRL_TE)));
63027 +}
63028 +
63029 +void fman_rtc_clear_periodic_pulse(struct rtc_regs *regs, int id)
63030 +{
63031 + uint32_t tmp_reg;
63032 + if (id == 0)
63033 + tmp_reg = FMAN_RTC_TMR_TEVENT_PP1;
63034 + else
63035 + tmp_reg = FMAN_RTC_TMR_TEVENT_PP2;
63036 + fman_rtc_disable_interupt(regs, tmp_reg);
63037 +
63038 + tmp_reg = fman_rtc_get_timer_ctrl(regs);
63039 + if (tmp_reg & FMAN_RTC_TMR_CTRL_FS)
63040 + fman_rtc_set_timer_ctrl(regs, tmp_reg & ~FMAN_RTC_TMR_CTRL_FS);
63041 +
63042 + fman_rtc_set_timer_fiper(regs, id, 0xFFFFFFFF);
63043 +}
63044 +
63045 +void fman_rtc_clear_external_trigger(struct rtc_regs *regs, int id)
63046 +{
63047 + uint32_t tmpReg, tmp_ctrl;
63048 +
63049 + if (id == 0)
63050 + tmpReg = FMAN_RTC_TMR_TEVENT_ETS1;
63051 + else
63052 + tmpReg = FMAN_RTC_TMR_TEVENT_ETS2;
63053 + fman_rtc_disable_interupt(regs, tmpReg);
63054 +
63055 + if (id == 0)
63056 + tmpReg = FMAN_RTC_TMR_CTRL_PP1L;
63057 + else
63058 + tmpReg = FMAN_RTC_TMR_CTRL_PP2L;
63059 + tmp_ctrl = fman_rtc_get_timer_ctrl(regs);
63060 + if (tmp_ctrl & tmpReg)
63061 + fman_rtc_set_timer_ctrl(regs, tmp_ctrl & ~tmpReg);
63062 +}
63063 +
63064 +void fman_rtc_set_alarm(struct rtc_regs *regs, int id, uint32_t val, bool enable)
63065 +{
63066 + uint32_t tmpReg;
63067 + fman_rtc_set_timer_alarm(regs, id, val);
63068 + if (enable) {
63069 + if (id == 0)
63070 + tmpReg = FMAN_RTC_TMR_TEVENT_ALM1;
63071 + else
63072 + tmpReg = FMAN_RTC_TMR_TEVENT_ALM2;
63073 + fman_rtc_enable_interupt(regs, tmpReg);
63074 + }
63075 +}
63076 +
63077 +void fman_rtc_set_periodic_pulse(struct rtc_regs *regs, int id, uint32_t val,
63078 + bool enable)
63079 +{
63080 + uint32_t tmpReg;
63081 + fman_rtc_set_timer_fiper(regs, id, val);
63082 + if (enable) {
63083 + if (id == 0)
63084 + tmpReg = FMAN_RTC_TMR_TEVENT_PP1;
63085 + else
63086 + tmpReg = FMAN_RTC_TMR_TEVENT_PP2;
63087 + fman_rtc_enable_interupt(regs, tmpReg);
63088 + }
63089 +}
63090 +
63091 +void fman_rtc_set_ext_trigger(struct rtc_regs *regs, int id, bool enable,
63092 + bool use_pulse_as_input)
63093 +{
63094 + uint32_t tmpReg;
63095 + if (enable) {
63096 + if (id == 0)
63097 + tmpReg = FMAN_RTC_TMR_TEVENT_ETS1;
63098 + else
63099 + tmpReg = FMAN_RTC_TMR_TEVENT_ETS2;
63100 + fman_rtc_enable_interupt(regs, tmpReg);
63101 + }
63102 + if (use_pulse_as_input) {
63103 + if (id == 0)
63104 + tmpReg = FMAN_RTC_TMR_CTRL_PP1L;
63105 + else
63106 + tmpReg = FMAN_RTC_TMR_CTRL_PP2L;
63107 + fman_rtc_set_timer_ctrl(regs, fman_rtc_get_timer_ctrl(regs) | tmpReg);
63108 + }
63109 +}
63110 --- /dev/null
63111 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/SP/Makefile
63112 @@ -0,0 +1,15 @@
63113 +#
63114 +# Makefile for the Freescale Ethernet controllers
63115 +#
63116 +ccflags-y += -DVERSION=\"\"
63117 +#
63118 +#Include netcomm SW specific definitions
63119 +include $(srctree)/drivers/net/ethernet/freescale/sdk_fman/ncsw_config.mk
63120 +
63121 +NCSW_FM_INC = $(srctree)/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/inc
63122 +
63123 +ccflags-y += -I$(NCSW_FM_INC)
63124 +
63125 +obj-y += fsl-ncsw-sp.o
63126 +
63127 +fsl-ncsw-sp-objs := fm_sp.o fman_sp.o
63128 --- /dev/null
63129 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/SP/fm_sp.c
63130 @@ -0,0 +1,757 @@
63131 +/*
63132 + * Copyright 2008-2012 Freescale Semiconductor Inc.
63133 + *
63134 + * Redistribution and use in source and binary forms, with or without
63135 + * modification, are permitted provided that the following conditions are met:
63136 + * * Redistributions of source code must retain the above copyright
63137 + * notice, this list of conditions and the following disclaimer.
63138 + * * Redistributions in binary form must reproduce the above copyright
63139 + * notice, this list of conditions and the following disclaimer in the
63140 + * documentation and/or other materials provided with the distribution.
63141 + * * Neither the name of Freescale Semiconductor nor the
63142 + * names of its contributors may be used to endorse or promote products
63143 + * derived from this software without specific prior written permission.
63144 + *
63145 + *
63146 + * ALTERNATIVELY, this software may be distributed under the terms of the
63147 + * GNU General Public License ("GPL") as published by the Free Software
63148 + * Foundation, either version 2 of that License or (at your option) any
63149 + * later version.
63150 + *
63151 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
63152 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
63153 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
63154 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
63155 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
63156 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
63157 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
63158 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
63159 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
63160 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
63161 + */
63162 +
63163 +
63164 +/******************************************************************************
63165 + @File fm_sp.c
63166 +
63167 + @Description FM PCD Storage profile ...
63168 +*//***************************************************************************/
63169 +
63170 +#include "std_ext.h"
63171 +#include "error_ext.h"
63172 +#include "string_ext.h"
63173 +#include "debug_ext.h"
63174 +#include "net_ext.h"
63175 +
63176 +#include "fm_vsp_ext.h"
63177 +#include "fm_sp.h"
63178 +#include "fm_common.h"
63179 +#include "fsl_fman_sp.h"
63180 +
63181 +
63182 +#if (DPAA_VERSION >= 11)
63183 +static t_Error CheckParamsGeneratedInternally(t_FmVspEntry *p_FmVspEntry)
63184 +{
63185 + t_Error err = E_OK;
63186 +
63187 + if ((err = FmSpCheckIntContextParams(&p_FmVspEntry->intContext))!= E_OK)
63188 + RETURN_ERROR(MAJOR, err, NO_MSG);
63189 + if ((err = FmSpCheckBufMargins(&p_FmVspEntry->bufMargins)) != E_OK)
63190 + RETURN_ERROR(MAJOR, err, NO_MSG);
63191 + return err;
63192 +
63193 +}
63194 +
63195 +static t_Error CheckParams(t_FmVspEntry *p_FmVspEntry)
63196 +{
63197 + t_Error err = E_OK;
63198 +
63199 + SANITY_CHECK_RETURN_ERROR(p_FmVspEntry, E_INVALID_HANDLE);
63200 + SANITY_CHECK_RETURN_ERROR(p_FmVspEntry->p_FmVspEntryDriverParams, E_INVALID_HANDLE);
63201 + SANITY_CHECK_RETURN_ERROR(p_FmVspEntry->h_Fm, E_INVALID_HANDLE);
63202 +
63203 + if ((err = FmSpCheckBufPoolsParams(&p_FmVspEntry->p_FmVspEntryDriverParams->extBufPools,
63204 + p_FmVspEntry->p_FmVspEntryDriverParams->p_BackupBmPools,
63205 + p_FmVspEntry->p_FmVspEntryDriverParams->p_BufPoolDepletion)) != E_OK)
63206 +
63207 + RETURN_ERROR(MAJOR, err, NO_MSG);
63208 +
63209 + if (p_FmVspEntry->p_FmVspEntryDriverParams->liodnOffset & ~FM_LIODN_OFFSET_MASK)
63210 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("liodnOffset is larger than %d", FM_LIODN_OFFSET_MASK+1));
63211 +
63212 + err = FmVSPCheckRelativeProfile(p_FmVspEntry->h_Fm,
63213 + p_FmVspEntry->portType,
63214 + p_FmVspEntry->portId,
63215 + p_FmVspEntry->relativeProfileId);
63216 +
63217 + return err;
63218 +}
63219 +#endif /* (DPAA_VERSION >= 11) */
63220 +
63221 +
63222 +/*****************************************************************************/
63223 +/* Inter-module API routines */
63224 +/*****************************************************************************/
63225 +void FmSpSetBufPoolsInAscOrderOfBufSizes(t_FmExtPools *p_FmExtPools,
63226 + uint8_t *orderedArray,
63227 + uint16_t *sizesArray)
63228 +{
63229 + uint16_t bufSize = 0;
63230 + int i=0, j=0, k=0;
63231 +
63232 + /* First we copy the external buffers pools information to an ordered local array */
63233 + for (i=0;i<p_FmExtPools->numOfPoolsUsed;i++)
63234 + {
63235 + /* get pool size */
63236 + bufSize = p_FmExtPools->extBufPool[i].size;
63237 +
63238 + /* keep sizes in an array according to poolId for direct access */
63239 + sizesArray[p_FmExtPools->extBufPool[i].id] = bufSize;
63240 +
63241 + /* save poolId in an ordered array according to size */
63242 + for (j=0;j<=i;j++)
63243 + {
63244 + /* this is the next free place in the array */
63245 + if (j==i)
63246 + orderedArray[i] = p_FmExtPools->extBufPool[i].id;
63247 + else
63248 + {
63249 + /* find the right place for this poolId */
63250 + if (bufSize < sizesArray[orderedArray[j]])
63251 + {
63252 + /* move the poolIds one place ahead to make room for this poolId */
63253 + for (k=i;k>j;k--)
63254 + orderedArray[k] = orderedArray[k-1];
63255 +
63256 + /* now k==j, this is the place for the new size */
63257 + orderedArray[k] = p_FmExtPools->extBufPool[i].id;
63258 + break;
63259 + }
63260 + }
63261 + }
63262 + }
63263 +}
63264 +
63265 +t_Error FmSpCheckBufPoolsParams(t_FmExtPools *p_FmExtPools,
63266 + t_FmBackupBmPools *p_FmBackupBmPools,
63267 + t_FmBufPoolDepletion *p_FmBufPoolDepletion)
63268 +{
63269 +
63270 + int i = 0, j = 0;
63271 + bool found;
63272 + uint8_t count = 0;
63273 +
63274 + if (p_FmExtPools)
63275 + {
63276 + if (p_FmExtPools->numOfPoolsUsed > FM_PORT_MAX_NUM_OF_EXT_POOLS)
63277 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("numOfPoolsUsed can't be larger than %d", FM_PORT_MAX_NUM_OF_EXT_POOLS));
63278 +
63279 + for (i=0;i<p_FmExtPools->numOfPoolsUsed;i++)
63280 + {
63281 + if (p_FmExtPools->extBufPool[i].id >= BM_MAX_NUM_OF_POOLS)
63282 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("extBufPools.extBufPool[%d].id can't be larger than %d", i, BM_MAX_NUM_OF_POOLS));
63283 + if (!p_FmExtPools->extBufPool[i].size)
63284 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("extBufPools.extBufPool[%d].size is 0", i));
63285 + }
63286 + }
63287 + if (!p_FmExtPools && (p_FmBackupBmPools || p_FmBufPoolDepletion))
63288 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("backupBmPools ot bufPoolDepletion can not be defined without external pools"));
63289 +
63290 + /* backup BM pools indication is valid only for some chip derivatives
63291 + (limited by the config routine) */
63292 + if (p_FmBackupBmPools)
63293 + {
63294 + if (p_FmBackupBmPools->numOfBackupPools >= p_FmExtPools->numOfPoolsUsed)
63295 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("p_BackupBmPools must be smaller than extBufPools.numOfPoolsUsed"));
63296 + found = FALSE;
63297 + for (i = 0;i<p_FmBackupBmPools->numOfBackupPools;i++)
63298 + {
63299 +
63300 + for (j=0;j<p_FmExtPools->numOfPoolsUsed;j++)
63301 + {
63302 + if (p_FmBackupBmPools->poolIds[i] == p_FmExtPools->extBufPool[j].id)
63303 + {
63304 + found = TRUE;
63305 + break;
63306 + }
63307 + }
63308 + if (!found)
63309 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("All p_BackupBmPools.poolIds must be included in extBufPools.extBufPool[n].id"));
63310 + else
63311 + found = FALSE;
63312 + }
63313 + }
63314 +
63315 + /* up to extBufPools.numOfPoolsUsed pools may be defined */
63316 + if (p_FmBufPoolDepletion && p_FmBufPoolDepletion->poolsGrpModeEnable)
63317 + {
63318 + if ((p_FmBufPoolDepletion->numOfPools > p_FmExtPools->numOfPoolsUsed))
63319 + 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));
63320 +
63321 + if (!p_FmBufPoolDepletion->numOfPools)
63322 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("bufPoolDepletion.numOfPoolsToConsider can not be 0 when poolsGrpModeEnable=TRUE"));
63323 +
63324 + found = FALSE;
63325 + count = 0;
63326 + /* for each pool that is in poolsToConsider, check if it is defined
63327 + in extBufPool */
63328 + for (i=0;i<BM_MAX_NUM_OF_POOLS;i++)
63329 + {
63330 + if (p_FmBufPoolDepletion->poolsToConsider[i])
63331 + {
63332 + for (j=0;j<p_FmExtPools->numOfPoolsUsed;j++)
63333 + {
63334 + if (i == p_FmExtPools->extBufPool[j].id)
63335 + {
63336 + found = TRUE;
63337 + count++;
63338 + break;
63339 + }
63340 + }
63341 + if (!found)
63342 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Pools selected for depletion are not used."));
63343 + else
63344 + found = FALSE;
63345 + }
63346 + }
63347 + /* check that the number of pools that we have checked is equal to the number announced by the user */
63348 + if (count != p_FmBufPoolDepletion->numOfPools)
63349 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("bufPoolDepletion.numOfPools is larger than the number of pools defined."));
63350 + }
63351 +
63352 + if (p_FmBufPoolDepletion && p_FmBufPoolDepletion->singlePoolModeEnable)
63353 + {
63354 + /* calculate vector for number of pools depletion */
63355 + found = FALSE;
63356 + count = 0;
63357 + for (i=0;i<BM_MAX_NUM_OF_POOLS;i++)
63358 + {
63359 + if (p_FmBufPoolDepletion->poolsToConsiderForSingleMode[i])
63360 + {
63361 + for (j=0;j<p_FmExtPools->numOfPoolsUsed;j++)
63362 + {
63363 + if (i == p_FmExtPools->extBufPool[j].id)
63364 + {
63365 + found = TRUE;
63366 + count++;
63367 + break;
63368 + }
63369 + }
63370 + if (!found)
63371 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Pools selected for depletion are not used."));
63372 + else
63373 + found = FALSE;
63374 + }
63375 + }
63376 + if (!count)
63377 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("No pools defined for single buffer mode pool depletion."));
63378 + }
63379 +
63380 + return E_OK;
63381 +}
63382 +
63383 +t_Error FmSpCheckIntContextParams(t_FmSpIntContextDataCopy *p_FmSpIntContextDataCopy)
63384 +{
63385 + /* Check that divisible by 16 and not larger than 240 */
63386 + if (p_FmSpIntContextDataCopy->intContextOffset >MAX_INT_OFFSET)
63387 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("intContext.intContextOffset can't be larger than %d", MAX_INT_OFFSET));
63388 + if (p_FmSpIntContextDataCopy->intContextOffset % OFFSET_UNITS)
63389 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("intContext.intContextOffset has to be divisible by %d", OFFSET_UNITS));
63390 +
63391 + /* check that ic size+ic internal offset, does not exceed ic block size */
63392 + if (p_FmSpIntContextDataCopy->size + p_FmSpIntContextDataCopy->intContextOffset > MAX_IC_SIZE)
63393 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("intContext.size + intContext.intContextOffset has to be smaller than %d", MAX_IC_SIZE));
63394 + /* Check that divisible by 16 and not larger than 256 */
63395 + if (p_FmSpIntContextDataCopy->size % OFFSET_UNITS)
63396 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("intContext.size has to be divisible by %d", OFFSET_UNITS));
63397 +
63398 + /* Check that divisible by 16 and not larger than 4K */
63399 + if (p_FmSpIntContextDataCopy->extBufOffset > MAX_EXT_OFFSET)
63400 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("intContext.extBufOffset can't be larger than %d", MAX_EXT_OFFSET));
63401 + if (p_FmSpIntContextDataCopy->extBufOffset % OFFSET_UNITS)
63402 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("intContext.extBufOffset has to be divisible by %d", OFFSET_UNITS));
63403 +
63404 + return E_OK;
63405 +}
63406 +
63407 +t_Error FmSpCheckBufMargins(t_FmSpBufMargins *p_FmSpBufMargins)
63408 +{
63409 + /* Check the margin definition */
63410 + if (p_FmSpBufMargins->startMargins > MAX_EXT_BUFFER_OFFSET)
63411 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("bufMargins.startMargins can't be larger than %d", MAX_EXT_BUFFER_OFFSET));
63412 + if (p_FmSpBufMargins->endMargins > MAX_EXT_BUFFER_OFFSET)
63413 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("bufMargins.endMargins can't be larger than %d", MAX_EXT_BUFFER_OFFSET));
63414 +
63415 + return E_OK;
63416 +}
63417 +
63418 +t_Error FmSpBuildBufferStructure(t_FmSpIntContextDataCopy *p_FmSpIntContextDataCopy,
63419 + t_FmBufferPrefixContent *p_BufferPrefixContent,
63420 + t_FmSpBufMargins *p_FmSpBufMargins,
63421 + t_FmSpBufferOffsets *p_FmSpBufferOffsets,
63422 + uint8_t *internalBufferOffset)
63423 +{
63424 + uint32_t tmp;
63425 +
63426 + SANITY_CHECK_RETURN_ERROR(p_FmSpIntContextDataCopy, E_INVALID_VALUE);
63427 + ASSERT_COND(p_FmSpIntContextDataCopy);
63428 + ASSERT_COND(p_BufferPrefixContent);
63429 + ASSERT_COND(p_FmSpBufMargins);
63430 + ASSERT_COND(p_FmSpBufferOffsets);
63431 +
63432 + /* Align start of internal context data to 16 byte */
63433 + p_FmSpIntContextDataCopy->extBufOffset =
63434 + (uint16_t)((p_BufferPrefixContent->privDataSize & (OFFSET_UNITS-1)) ?
63435 + ((p_BufferPrefixContent->privDataSize + OFFSET_UNITS) & ~(uint16_t)(OFFSET_UNITS-1)) :
63436 + p_BufferPrefixContent->privDataSize);
63437 +
63438 + /* Translate margin and intContext params to FM parameters */
63439 + /* Initialize with illegal value. Later we'll set legal values. */
63440 + p_FmSpBufferOffsets->prsResultOffset = (uint32_t)ILLEGAL_BASE;
63441 + p_FmSpBufferOffsets->timeStampOffset = (uint32_t)ILLEGAL_BASE;
63442 + p_FmSpBufferOffsets->hashResultOffset= (uint32_t)ILLEGAL_BASE;
63443 + p_FmSpBufferOffsets->pcdInfoOffset = (uint32_t)ILLEGAL_BASE;
63444 +
63445 + /* Internally the driver supports 4 options
63446 + 1. prsResult/timestamp/hashResult selection (in fact 8 options, but for simplicity we'll
63447 + relate to it as 1).
63448 + 2. All IC context (from AD) not including debug.*/
63449 +
63450 + /* This 'if' covers option 2. We copy from beginning of context. */
63451 + if (p_BufferPrefixContent->passAllOtherPCDInfo)
63452 + {
63453 + p_FmSpIntContextDataCopy->size = 128; /* must be aligned to 16 */
63454 + /* Start copying data after 16 bytes (FD) from the beginning of the internal context */
63455 + p_FmSpIntContextDataCopy->intContextOffset = 16;
63456 +
63457 + if (p_BufferPrefixContent->passAllOtherPCDInfo)
63458 + p_FmSpBufferOffsets->pcdInfoOffset = p_FmSpIntContextDataCopy->extBufOffset;
63459 + if (p_BufferPrefixContent->passPrsResult)
63460 + p_FmSpBufferOffsets->prsResultOffset =
63461 + (uint32_t)(p_FmSpIntContextDataCopy->extBufOffset + 16);
63462 + if (p_BufferPrefixContent->passTimeStamp)
63463 + p_FmSpBufferOffsets->timeStampOffset =
63464 + (uint32_t)(p_FmSpIntContextDataCopy->extBufOffset + 48);
63465 + if (p_BufferPrefixContent->passHashResult)
63466 + p_FmSpBufferOffsets->hashResultOffset =
63467 + (uint32_t)(p_FmSpIntContextDataCopy->extBufOffset + 56);
63468 + }
63469 + else
63470 + {
63471 + /* This case covers the options under 1 */
63472 + /* Copy size must be in 16-byte granularity. */
63473 + p_FmSpIntContextDataCopy->size =
63474 + (uint16_t)((p_BufferPrefixContent->passPrsResult ? 32 : 0) +
63475 + ((p_BufferPrefixContent->passTimeStamp ||
63476 + p_BufferPrefixContent->passHashResult) ? 16 : 0));
63477 +
63478 + /* Align start of internal context data to 16 byte */
63479 + p_FmSpIntContextDataCopy->intContextOffset =
63480 + (uint8_t)(p_BufferPrefixContent->passPrsResult ? 32 :
63481 + ((p_BufferPrefixContent->passTimeStamp ||
63482 + p_BufferPrefixContent->passHashResult) ? 64 : 0));
63483 +
63484 + if (p_BufferPrefixContent->passPrsResult)
63485 + p_FmSpBufferOffsets->prsResultOffset = p_FmSpIntContextDataCopy->extBufOffset;
63486 + if (p_BufferPrefixContent->passTimeStamp)
63487 + p_FmSpBufferOffsets->timeStampOffset = p_BufferPrefixContent->passPrsResult ?
63488 + (p_FmSpIntContextDataCopy->extBufOffset + sizeof(t_FmPrsResult)) :
63489 + p_FmSpIntContextDataCopy->extBufOffset;
63490 + if (p_BufferPrefixContent->passHashResult)
63491 + /* If PR is not requested, whether TS is requested or not, IC will be copied from TS */
63492 + p_FmSpBufferOffsets->hashResultOffset = p_BufferPrefixContent->passPrsResult ?
63493 + (p_FmSpIntContextDataCopy->extBufOffset + sizeof(t_FmPrsResult) + 8) :
63494 + p_FmSpIntContextDataCopy->extBufOffset + 8;
63495 + }
63496 +
63497 + if (p_FmSpIntContextDataCopy->size)
63498 + p_FmSpBufMargins->startMargins =
63499 + (uint16_t)(p_FmSpIntContextDataCopy->extBufOffset +
63500 + p_FmSpIntContextDataCopy->size);
63501 + else
63502 + /* No Internal Context passing, STartMargin is immediately after privateInfo */
63503 + p_FmSpBufMargins->startMargins = p_BufferPrefixContent->privDataSize;
63504 +
63505 + /* save extra space for manip in both external and internal buffers */
63506 + if (p_BufferPrefixContent->manipExtraSpace)
63507 + {
63508 + uint8_t extraSpace;
63509 +#ifdef FM_CAPWAP_SUPPORT
63510 + if ((p_BufferPrefixContent->manipExtraSpace + CAPWAP_FRAG_EXTRA_SPACE) >= 256)
63511 + RETURN_ERROR(MAJOR, E_INVALID_VALUE,
63512 + ("p_BufferPrefixContent->manipExtraSpace should be less than %d",
63513 + 256-CAPWAP_FRAG_EXTRA_SPACE));
63514 + extraSpace = (uint8_t)(p_BufferPrefixContent->manipExtraSpace + CAPWAP_FRAG_EXTRA_SPACE);
63515 +#else
63516 + extraSpace = p_BufferPrefixContent->manipExtraSpace;
63517 +#endif /* FM_CAPWAP_SUPPORT */
63518 + p_FmSpBufferOffsets->manipOffset = p_FmSpBufMargins->startMargins;
63519 + p_FmSpBufMargins->startMargins += extraSpace;
63520 + *internalBufferOffset = extraSpace;
63521 + }
63522 +
63523 + /* align data start */
63524 + tmp = (uint32_t)(p_FmSpBufMargins->startMargins % p_BufferPrefixContent->dataAlign);
63525 + if (tmp)
63526 + p_FmSpBufMargins->startMargins += (p_BufferPrefixContent->dataAlign-tmp);
63527 + p_FmSpBufferOffsets->dataOffset = p_FmSpBufMargins->startMargins;
63528 +
63529 + return E_OK;
63530 +}
63531 +/*********************** End of inter-module routines ************************/
63532 +
63533 +
63534 +#if (DPAA_VERSION >= 11)
63535 +/*****************************************************************************/
63536 +/* API routines */
63537 +/*****************************************************************************/
63538 +t_Handle FM_VSP_Config(t_FmVspParams *p_FmVspParams)
63539 +{
63540 + t_FmVspEntry *p_FmVspEntry = NULL;
63541 + struct fm_storage_profile_params fm_vsp_params;
63542 +
63543 + p_FmVspEntry = (t_FmVspEntry *)XX_Malloc(sizeof(t_FmVspEntry));
63544 + if (!p_FmVspEntry)
63545 + {
63546 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("p_StorageProfile allocation failed"));
63547 + return NULL;
63548 + }
63549 + memset(p_FmVspEntry, 0, sizeof(t_FmVspEntry));
63550 +
63551 + p_FmVspEntry->p_FmVspEntryDriverParams = (t_FmVspEntryDriverParams *)XX_Malloc(sizeof(t_FmVspEntryDriverParams));
63552 + if (!p_FmVspEntry->p_FmVspEntryDriverParams)
63553 + {
63554 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("p_StorageProfile allocation failed"));
63555 + XX_Free(p_FmVspEntry);
63556 + return NULL;
63557 + }
63558 + memset(p_FmVspEntry->p_FmVspEntryDriverParams, 0, sizeof(t_FmVspEntryDriverParams));
63559 + fman_vsp_defconfig(&fm_vsp_params);
63560 + p_FmVspEntry->p_FmVspEntryDriverParams->dmaHeaderCacheAttr = fm_vsp_params.header_cache_attr;
63561 + p_FmVspEntry->p_FmVspEntryDriverParams->dmaIntContextCacheAttr = fm_vsp_params.int_context_cache_attr;
63562 + p_FmVspEntry->p_FmVspEntryDriverParams->dmaScatterGatherCacheAttr = fm_vsp_params.scatter_gather_cache_attr;
63563 + p_FmVspEntry->p_FmVspEntryDriverParams->dmaSwapData = fm_vsp_params.dma_swap_data;
63564 + p_FmVspEntry->p_FmVspEntryDriverParams->dmaWriteOptimize = fm_vsp_params.dma_write_optimize;
63565 + p_FmVspEntry->p_FmVspEntryDriverParams->noScatherGather = fm_vsp_params.no_scather_gather;
63566 + p_FmVspEntry->p_FmVspEntryDriverParams->bufferPrefixContent.privDataSize = DEFAULT_FM_SP_bufferPrefixContent_privDataSize;
63567 + p_FmVspEntry->p_FmVspEntryDriverParams->bufferPrefixContent.passPrsResult= DEFAULT_FM_SP_bufferPrefixContent_passPrsResult;
63568 + p_FmVspEntry->p_FmVspEntryDriverParams->bufferPrefixContent.passTimeStamp= DEFAULT_FM_SP_bufferPrefixContent_passTimeStamp;
63569 + p_FmVspEntry->p_FmVspEntryDriverParams->bufferPrefixContent.passAllOtherPCDInfo
63570 + = DEFAULT_FM_SP_bufferPrefixContent_passTimeStamp;
63571 + p_FmVspEntry->p_FmVspEntryDriverParams->bufferPrefixContent.dataAlign = DEFAULT_FM_SP_bufferPrefixContent_dataAlign;
63572 + p_FmVspEntry->p_FmVspEntryDriverParams->liodnOffset = p_FmVspParams->liodnOffset;
63573 +
63574 + memcpy(&p_FmVspEntry->p_FmVspEntryDriverParams->extBufPools, &p_FmVspParams->extBufPools, sizeof(t_FmExtPools));
63575 + p_FmVspEntry->h_Fm = p_FmVspParams->h_Fm;
63576 + p_FmVspEntry->portType = p_FmVspParams->portParams.portType;
63577 + p_FmVspEntry->portId = p_FmVspParams->portParams.portId;
63578 +
63579 + p_FmVspEntry->relativeProfileId = p_FmVspParams->relativeProfileId;
63580 +
63581 + return p_FmVspEntry;
63582 +}
63583 +
63584 +t_Error FM_VSP_Init(t_Handle h_FmVsp)
63585 +{
63586 +
63587 + t_FmVspEntry *p_FmVspEntry = (t_FmVspEntry *)h_FmVsp;
63588 + struct fm_storage_profile_params fm_vsp_params;
63589 + uint8_t orderedArray[FM_PORT_MAX_NUM_OF_EXT_POOLS];
63590 + uint16_t sizesArray[BM_MAX_NUM_OF_POOLS];
63591 + t_Error err;
63592 + uint16_t absoluteProfileId = 0;
63593 + int i = 0;
63594 +
63595 + SANITY_CHECK_RETURN_ERROR(p_FmVspEntry, E_INVALID_HANDLE);
63596 + SANITY_CHECK_RETURN_ERROR(p_FmVspEntry->p_FmVspEntryDriverParams,E_INVALID_HANDLE);
63597 +
63598 + CHECK_INIT_PARAMETERS(p_FmVspEntry, CheckParams);
63599 +
63600 + memset(&orderedArray, 0, sizeof(uint8_t) * FM_PORT_MAX_NUM_OF_EXT_POOLS);
63601 + memset(&sizesArray, 0, sizeof(uint16_t) * BM_MAX_NUM_OF_POOLS);
63602 +
63603 + err = FmSpBuildBufferStructure(&p_FmVspEntry->intContext,
63604 + &p_FmVspEntry->p_FmVspEntryDriverParams->bufferPrefixContent,
63605 + &p_FmVspEntry->bufMargins,
63606 + &p_FmVspEntry->bufferOffsets,
63607 + &p_FmVspEntry->internalBufferOffset);
63608 + if (err != E_OK)
63609 + RETURN_ERROR(MAJOR, err, NO_MSG);
63610 +
63611 +
63612 + err = CheckParamsGeneratedInternally(p_FmVspEntry);
63613 + if (err != E_OK)
63614 + RETURN_ERROR(MAJOR, err, NO_MSG);
63615 +
63616 +
63617 + p_FmVspEntry->p_FmSpRegsBase =
63618 + (struct fm_pcd_storage_profile_regs *)FmGetVSPBaseAddr(p_FmVspEntry->h_Fm);
63619 + if (!p_FmVspEntry->p_FmSpRegsBase)
63620 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("impossible to initialize SpRegsBase"));
63621 +
63622 + /* order external buffer pools in ascending order of buffer pools sizes */
63623 + FmSpSetBufPoolsInAscOrderOfBufSizes(&(p_FmVspEntry->p_FmVspEntryDriverParams)->extBufPools,
63624 + orderedArray,
63625 + sizesArray);
63626 +
63627 + p_FmVspEntry->extBufPools.numOfPoolsUsed =
63628 + p_FmVspEntry->p_FmVspEntryDriverParams->extBufPools.numOfPoolsUsed;
63629 + for (i = 0; i < p_FmVspEntry->extBufPools.numOfPoolsUsed; i++)
63630 + {
63631 + p_FmVspEntry->extBufPools.extBufPool[i].id = orderedArray[i];
63632 + p_FmVspEntry->extBufPools.extBufPool[i].size = sizesArray[orderedArray[i]];
63633 + }
63634 +
63635 + /* on user responsibility to fill it according requirement */
63636 + memset(&fm_vsp_params, 0, sizeof(struct fm_storage_profile_params));
63637 + fm_vsp_params.dma_swap_data = p_FmVspEntry->p_FmVspEntryDriverParams->dmaSwapData;
63638 + fm_vsp_params.int_context_cache_attr = p_FmVspEntry->p_FmVspEntryDriverParams->dmaIntContextCacheAttr;
63639 + fm_vsp_params.header_cache_attr = p_FmVspEntry->p_FmVspEntryDriverParams->dmaHeaderCacheAttr;
63640 + fm_vsp_params.scatter_gather_cache_attr = p_FmVspEntry->p_FmVspEntryDriverParams->dmaScatterGatherCacheAttr;
63641 + fm_vsp_params.dma_write_optimize = p_FmVspEntry->p_FmVspEntryDriverParams->dmaWriteOptimize;
63642 + fm_vsp_params.liodn_offset = p_FmVspEntry->p_FmVspEntryDriverParams->liodnOffset;
63643 + fm_vsp_params.no_scather_gather = p_FmVspEntry->p_FmVspEntryDriverParams->noScatherGather;
63644 +
63645 + if (p_FmVspEntry->p_FmVspEntryDriverParams->p_BufPoolDepletion)
63646 + {
63647 + fm_vsp_params.buf_pool_depletion.buf_pool_depletion_enabled = TRUE;
63648 + fm_vsp_params.buf_pool_depletion.pools_grp_mode_enable = p_FmVspEntry->p_FmVspEntryDriverParams->p_BufPoolDepletion->poolsGrpModeEnable;
63649 + fm_vsp_params.buf_pool_depletion.num_pools = p_FmVspEntry->p_FmVspEntryDriverParams->p_BufPoolDepletion->numOfPools;
63650 + fm_vsp_params.buf_pool_depletion.pools_to_consider = p_FmVspEntry->p_FmVspEntryDriverParams->p_BufPoolDepletion->poolsToConsider;
63651 + fm_vsp_params.buf_pool_depletion.single_pool_mode_enable = p_FmVspEntry->p_FmVspEntryDriverParams->p_BufPoolDepletion->singlePoolModeEnable;
63652 + fm_vsp_params.buf_pool_depletion.pools_to_consider_for_single_mode = p_FmVspEntry->p_FmVspEntryDriverParams->p_BufPoolDepletion->poolsToConsiderForSingleMode;
63653 + fm_vsp_params.buf_pool_depletion.has_pfc_priorities = TRUE;
63654 + fm_vsp_params.buf_pool_depletion.pfc_priorities_en = p_FmVspEntry->p_FmVspEntryDriverParams->p_BufPoolDepletion->pfcPrioritiesEn;
63655 + }
63656 + else
63657 + fm_vsp_params.buf_pool_depletion.buf_pool_depletion_enabled = FALSE;
63658 +
63659 + if (p_FmVspEntry->p_FmVspEntryDriverParams->p_BackupBmPools)
63660 + {
63661 + fm_vsp_params.backup_pools.num_backup_pools = p_FmVspEntry->p_FmVspEntryDriverParams->p_BackupBmPools->numOfBackupPools;
63662 + fm_vsp_params.backup_pools.pool_ids = p_FmVspEntry->p_FmVspEntryDriverParams->p_BackupBmPools->poolIds;
63663 + }
63664 + else
63665 + fm_vsp_params.backup_pools.num_backup_pools = 0;
63666 +
63667 + fm_vsp_params.fm_ext_pools.num_pools_used = p_FmVspEntry->extBufPools.numOfPoolsUsed;
63668 + fm_vsp_params.fm_ext_pools.ext_buf_pool = (struct fman_ext_pool_params*)&p_FmVspEntry->extBufPools.extBufPool;
63669 + fm_vsp_params.buf_margins = (struct fman_sp_buf_margins*)&p_FmVspEntry->bufMargins;
63670 + fm_vsp_params.int_context = (struct fman_sp_int_context_data_copy*)&p_FmVspEntry->intContext;
63671 +
63672 + /* no check on err - it was checked earlier */
63673 + FmVSPGetAbsoluteProfileId(p_FmVspEntry->h_Fm,
63674 + p_FmVspEntry->portType,
63675 + p_FmVspEntry->portId,
63676 + p_FmVspEntry->relativeProfileId,
63677 + &absoluteProfileId);
63678 +
63679 + ASSERT_COND(p_FmVspEntry->p_FmSpRegsBase);
63680 + ASSERT_COND(fm_vsp_params.int_context);
63681 + ASSERT_COND(fm_vsp_params.buf_margins);
63682 + ASSERT_COND((absoluteProfileId <= FM_VSP_MAX_NUM_OF_ENTRIES));
63683 +
63684 + /* Set all registers related to VSP */
63685 + 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);
63686 +
63687 + p_FmVspEntry->absoluteSpId = absoluteProfileId;
63688 +
63689 + if (p_FmVspEntry->p_FmVspEntryDriverParams)
63690 + XX_Free(p_FmVspEntry->p_FmVspEntryDriverParams);
63691 + p_FmVspEntry->p_FmVspEntryDriverParams = NULL;
63692 +
63693 + return E_OK;
63694 +}
63695 +
63696 +t_Error FM_VSP_Free(t_Handle h_FmVsp)
63697 +{
63698 + t_FmVspEntry *p_FmVspEntry = (t_FmVspEntry *)h_FmVsp;
63699 + SANITY_CHECK_RETURN_ERROR(h_FmVsp, E_INVALID_HANDLE);
63700 + XX_Free(p_FmVspEntry);
63701 + return E_OK;
63702 +}
63703 +
63704 +t_Error FM_VSP_ConfigBufferPrefixContent(t_Handle h_FmVsp, t_FmBufferPrefixContent *p_FmBufferPrefixContent)
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 + memcpy(&p_FmVspEntry->p_FmVspEntryDriverParams->bufferPrefixContent, p_FmBufferPrefixContent, sizeof(t_FmBufferPrefixContent));
63712 + /* if dataAlign was not initialized by user, we return to driver's default */
63713 + if (!p_FmVspEntry->p_FmVspEntryDriverParams->bufferPrefixContent.dataAlign)
63714 + p_FmVspEntry->p_FmVspEntryDriverParams->bufferPrefixContent.dataAlign = DEFAULT_FM_SP_bufferPrefixContent_dataAlign;
63715 +
63716 + return E_OK;
63717 +}
63718 +
63719 +t_Error FM_VSP_ConfigDmaSwapData(t_Handle h_FmVsp, e_FmDmaSwapOption swapData)
63720 +{
63721 + t_FmVspEntry *p_FmVspEntry = (t_FmVspEntry*)h_FmVsp;
63722 +
63723 + SANITY_CHECK_RETURN_ERROR(p_FmVspEntry, E_INVALID_HANDLE);
63724 + SANITY_CHECK_RETURN_ERROR(p_FmVspEntry->p_FmVspEntryDriverParams, E_INVALID_HANDLE);
63725 +
63726 + p_FmVspEntry->p_FmVspEntryDriverParams->dmaSwapData = swapData;
63727 +
63728 + return E_OK;
63729 +}
63730 +
63731 +t_Error FM_VSP_ConfigDmaIcCacheAttr(t_Handle h_FmVsp, e_FmDmaCacheOption intContextCacheAttr)
63732 +{
63733 + t_FmVspEntry *p_FmVspEntry = (t_FmVspEntry*)h_FmVsp;
63734 +
63735 + SANITY_CHECK_RETURN_ERROR(p_FmVspEntry, E_INVALID_HANDLE);
63736 + SANITY_CHECK_RETURN_ERROR(p_FmVspEntry->p_FmVspEntryDriverParams, E_INVALID_HANDLE);
63737 +
63738 + p_FmVspEntry->p_FmVspEntryDriverParams->dmaIntContextCacheAttr = intContextCacheAttr;
63739 +
63740 + return E_OK;
63741 +}
63742 +
63743 +t_Error FM_VSP_ConfigDmaHdrAttr(t_Handle h_FmVsp, e_FmDmaCacheOption headerCacheAttr)
63744 +{
63745 + t_FmVspEntry *p_FmVspEntry = (t_FmVspEntry*)h_FmVsp;
63746 +
63747 + SANITY_CHECK_RETURN_ERROR(p_FmVspEntry, E_INVALID_HANDLE);
63748 + SANITY_CHECK_RETURN_ERROR(p_FmVspEntry->p_FmVspEntryDriverParams, E_INVALID_HANDLE);
63749 +
63750 + p_FmVspEntry->p_FmVspEntryDriverParams->dmaHeaderCacheAttr = headerCacheAttr;
63751 +
63752 + return E_OK;
63753 +}
63754 +
63755 +t_Error FM_VSP_ConfigDmaScatterGatherAttr(t_Handle h_FmVsp, e_FmDmaCacheOption scatterGatherCacheAttr)
63756 +{
63757 + t_FmVspEntry *p_FmVspEntry = (t_FmVspEntry*)h_FmVsp;
63758 +
63759 + SANITY_CHECK_RETURN_ERROR(p_FmVspEntry, E_INVALID_HANDLE);
63760 + SANITY_CHECK_RETURN_ERROR(p_FmVspEntry->p_FmVspEntryDriverParams, E_INVALID_HANDLE);
63761 +
63762 + p_FmVspEntry->p_FmVspEntryDriverParams->dmaScatterGatherCacheAttr = scatterGatherCacheAttr;
63763 +
63764 + return E_OK;
63765 +}
63766 +
63767 +t_Error FM_VSP_ConfigDmaWriteOptimize(t_Handle h_FmVsp, bool optimize)
63768 +{
63769 + t_FmVspEntry *p_FmVspEntry = (t_FmVspEntry*)h_FmVsp;
63770 +
63771 + SANITY_CHECK_RETURN_ERROR(p_FmVspEntry, E_INVALID_HANDLE);
63772 + SANITY_CHECK_RETURN_ERROR(p_FmVspEntry->p_FmVspEntryDriverParams, E_INVALID_HANDLE);
63773 +
63774 +
63775 + p_FmVspEntry->p_FmVspEntryDriverParams->dmaWriteOptimize = optimize;
63776 +
63777 + return E_OK;
63778 +}
63779 +
63780 +t_Error FM_VSP_ConfigNoScatherGather(t_Handle h_FmVsp, bool noScatherGather)
63781 +{
63782 + t_FmVspEntry *p_FmVspEntry = (t_FmVspEntry*)h_FmVsp;
63783 +
63784 + SANITY_CHECK_RETURN_ERROR(p_FmVspEntry, E_INVALID_HANDLE);
63785 + SANITY_CHECK_RETURN_ERROR(p_FmVspEntry->p_FmVspEntryDriverParams, E_INVALID_HANDLE);
63786 +
63787 +
63788 + p_FmVspEntry->p_FmVspEntryDriverParams->noScatherGather = noScatherGather;
63789 +
63790 + return E_OK;
63791 +}
63792 +
63793 +t_Error FM_VSP_ConfigPoolDepletion(t_Handle h_FmVsp, t_FmBufPoolDepletion *p_BufPoolDepletion)
63794 +{
63795 + t_FmVspEntry *p_FmVspEntry = (t_FmVspEntry*)h_FmVsp;
63796 +
63797 + SANITY_CHECK_RETURN_ERROR(h_FmVsp, E_INVALID_HANDLE);
63798 + SANITY_CHECK_RETURN_ERROR(p_FmVspEntry->p_FmVspEntryDriverParams, E_INVALID_HANDLE);
63799 + SANITY_CHECK_RETURN_ERROR(p_BufPoolDepletion, E_INVALID_HANDLE);
63800 +
63801 + p_FmVspEntry->p_FmVspEntryDriverParams->p_BufPoolDepletion = (t_FmBufPoolDepletion *)XX_Malloc(sizeof(t_FmBufPoolDepletion));
63802 + if (!p_FmVspEntry->p_FmVspEntryDriverParams->p_BufPoolDepletion)
63803 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("p_BufPoolDepletion allocation failed"));
63804 + memcpy(p_FmVspEntry->p_FmVspEntryDriverParams->p_BufPoolDepletion, p_BufPoolDepletion, sizeof(t_FmBufPoolDepletion));
63805 +
63806 + return E_OK;
63807 +}
63808 +
63809 +t_Error FM_VSP_ConfigBackupPools(t_Handle h_FmVsp, t_FmBackupBmPools *p_BackupBmPools)
63810 +{
63811 + t_FmVspEntry *p_FmVspEntry = (t_FmVspEntry*)h_FmVsp;
63812 +
63813 + SANITY_CHECK_RETURN_ERROR(h_FmVsp, E_INVALID_HANDLE);
63814 + SANITY_CHECK_RETURN_ERROR(p_FmVspEntry->p_FmVspEntryDriverParams, E_INVALID_HANDLE);
63815 + SANITY_CHECK_RETURN_ERROR(p_BackupBmPools, E_INVALID_HANDLE);
63816 +
63817 + p_FmVspEntry->p_FmVspEntryDriverParams->p_BackupBmPools = (t_FmBackupBmPools *)XX_Malloc(sizeof(t_FmBackupBmPools));
63818 + if (!p_FmVspEntry->p_FmVspEntryDriverParams->p_BackupBmPools)
63819 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("p_BackupBmPools allocation failed"));
63820 + memcpy(p_FmVspEntry->p_FmVspEntryDriverParams->p_BackupBmPools, p_BackupBmPools, sizeof(t_FmBackupBmPools));
63821 +
63822 + return E_OK;
63823 +}
63824 +
63825 +uint32_t FM_VSP_GetBufferDataOffset(t_Handle h_FmVsp)
63826 +{
63827 + t_FmVspEntry *p_FmVspEntry = (t_FmVspEntry*)h_FmVsp;
63828 +
63829 + SANITY_CHECK_RETURN_VALUE(p_FmVspEntry, E_INVALID_HANDLE, 0);
63830 + SANITY_CHECK_RETURN_VALUE(!p_FmVspEntry->p_FmVspEntryDriverParams, E_INVALID_STATE, 0);
63831 +
63832 + return p_FmVspEntry->bufferOffsets.dataOffset;
63833 +}
63834 +
63835 +uint8_t * FM_VSP_GetBufferICInfo(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.pcdInfoOffset == ILLEGAL_BASE)
63843 + return NULL;
63844 +
63845 + return (uint8_t *)PTR_MOVE(p_Data, p_FmVspEntry->bufferOffsets.pcdInfoOffset);
63846 +}
63847 +
63848 +t_FmPrsResult * FM_VSP_GetBufferPrsResult(t_Handle h_FmVsp, char *p_Data)
63849 +{
63850 + t_FmVspEntry *p_FmVspEntry = (t_FmVspEntry*)h_FmVsp;
63851 +
63852 + SANITY_CHECK_RETURN_VALUE(p_FmVspEntry, E_INVALID_HANDLE, NULL);
63853 + SANITY_CHECK_RETURN_VALUE(!p_FmVspEntry->p_FmVspEntryDriverParams, E_INVALID_STATE, NULL);
63854 +
63855 + if (p_FmVspEntry->bufferOffsets.prsResultOffset == ILLEGAL_BASE)
63856 + return NULL;
63857 +
63858 + return (t_FmPrsResult *)PTR_MOVE(p_Data, p_FmVspEntry->bufferOffsets.prsResultOffset);
63859 +}
63860 +
63861 +uint64_t * FM_VSP_GetBufferTimeStamp(t_Handle h_FmVsp, char *p_Data)
63862 +{
63863 + t_FmVspEntry *p_FmVspEntry = (t_FmVspEntry*)h_FmVsp;
63864 +
63865 + SANITY_CHECK_RETURN_VALUE(p_FmVspEntry, E_INVALID_HANDLE, NULL);
63866 + SANITY_CHECK_RETURN_VALUE(!p_FmVspEntry->p_FmVspEntryDriverParams, E_INVALID_STATE, NULL);
63867 +
63868 + if (p_FmVspEntry->bufferOffsets.timeStampOffset == ILLEGAL_BASE)
63869 + return NULL;
63870 +
63871 + return (uint64_t *)PTR_MOVE(p_Data, p_FmVspEntry->bufferOffsets.timeStampOffset);
63872 +}
63873 +
63874 +uint8_t * FM_VSP_GetBufferHashResult(t_Handle h_FmVsp, char *p_Data)
63875 +{
63876 + t_FmVspEntry *p_FmVspEntry = (t_FmVspEntry*)h_FmVsp;
63877 +
63878 + SANITY_CHECK_RETURN_VALUE(p_FmVspEntry, E_INVALID_HANDLE, NULL);
63879 + SANITY_CHECK_RETURN_VALUE(!p_FmVspEntry->p_FmVspEntryDriverParams, E_INVALID_STATE, NULL);
63880 +
63881 + if (p_FmVspEntry->bufferOffsets.hashResultOffset == ILLEGAL_BASE)
63882 + return NULL;
63883 +
63884 + return (uint8_t *)PTR_MOVE(p_Data, p_FmVspEntry->bufferOffsets.hashResultOffset);
63885 +}
63886 +
63887 +#endif /* (DPAA_VERSION >= 11) */
63888 --- /dev/null
63889 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/SP/fm_sp.h
63890 @@ -0,0 +1,85 @@
63891 +/*
63892 + * Copyright 2008-2012 Freescale Semiconductor Inc.
63893 + *
63894 + * Redistribution and use in source and binary forms, with or without
63895 + * modification, are permitted provided that the following conditions are met:
63896 + * * Redistributions of source code must retain the above copyright
63897 + * notice, this list of conditions and the following disclaimer.
63898 + * * Redistributions in binary form must reproduce the above copyright
63899 + * notice, this list of conditions and the following disclaimer in the
63900 + * documentation and/or other materials provided with the distribution.
63901 + * * Neither the name of Freescale Semiconductor nor the
63902 + * names of its contributors may be used to endorse or promote products
63903 + * derived from this software without specific prior written permission.
63904 + *
63905 + *
63906 + * ALTERNATIVELY, this software may be distributed under the terms of the
63907 + * GNU General Public License ("GPL") as published by the Free Software
63908 + * Foundation, either version 2 of that License or (at your option) any
63909 + * later version.
63910 + *
63911 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
63912 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
63913 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
63914 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
63915 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
63916 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
63917 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
63918 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
63919 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
63920 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
63921 + */
63922 +
63923 +
63924 +/******************************************************************************
63925 + @File fm_sp.h
63926 +
63927 + @Description FM SP ...
63928 +*//***************************************************************************/
63929 +#ifndef __FM_SP_H
63930 +#define __FM_SP_H
63931 +
63932 +#include "std_ext.h"
63933 +#include "error_ext.h"
63934 +#include "list_ext.h"
63935 +
63936 +#include "fm_sp_common.h"
63937 +#include "fm_common.h"
63938 +
63939 +
63940 +#define __ERR_MODULE__ MODULE_FM_SP
63941 +
63942 +typedef struct {
63943 + t_FmBufferPrefixContent bufferPrefixContent;
63944 + e_FmDmaSwapOption dmaSwapData;
63945 + e_FmDmaCacheOption dmaIntContextCacheAttr;
63946 + e_FmDmaCacheOption dmaHeaderCacheAttr;
63947 + e_FmDmaCacheOption dmaScatterGatherCacheAttr;
63948 + bool dmaWriteOptimize;
63949 + uint16_t liodnOffset;
63950 + bool noScatherGather;
63951 + t_FmBufPoolDepletion *p_BufPoolDepletion;
63952 + t_FmBackupBmPools *p_BackupBmPools;
63953 + t_FmExtPools extBufPools;
63954 +} t_FmVspEntryDriverParams;
63955 +
63956 +typedef struct {
63957 + bool valid;
63958 + volatile bool lock;
63959 + uint8_t pointedOwners;
63960 + uint16_t absoluteSpId;
63961 + uint8_t internalBufferOffset;
63962 + t_FmSpBufMargins bufMargins;
63963 + t_FmSpIntContextDataCopy intContext;
63964 + t_FmSpBufferOffsets bufferOffsets;
63965 + t_Handle h_Fm;
63966 + e_FmPortType portType; /**< Port type */
63967 + uint8_t portId; /**< Port Id - relative to type */
63968 + uint8_t relativeProfileId;
63969 + struct fm_pcd_storage_profile_regs *p_FmSpRegsBase;
63970 + t_FmExtPools extBufPools;
63971 + t_FmVspEntryDriverParams *p_FmVspEntryDriverParams;
63972 +} t_FmVspEntry;
63973 +
63974 +
63975 +#endif /* __FM_SP_H */
63976 --- /dev/null
63977 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/SP/fman_sp.c
63978 @@ -0,0 +1,197 @@
63979 +/*
63980 + * Copyright 2013 Freescale Semiconductor Inc.
63981 + *
63982 + * Redistribution and use in source and binary forms, with or without
63983 + * modification, are permitted provided that the following conditions are met:
63984 + * * Redistributions of source code must retain the above copyright
63985 + * notice, this list of conditions and the following disclaimer.
63986 + * * Redistributions in binary form must reproduce the above copyright
63987 + * notice, this list of conditions and the following disclaimer in the
63988 + * documentation and/or other materials provided with the distribution.
63989 + * * Neither the name of Freescale Semiconductor nor the
63990 + * names of its contributors may be used to endorse or promote products
63991 + * derived from this software without specific prior written permission.
63992 + *
63993 + *
63994 + * ALTERNATIVELY, this software may be distributed under the terms of the
63995 + * GNU General Public License ("GPL") as published by the Free Software
63996 + * Foundation, either version 2 of that License or (at your option) any
63997 + * later version.
63998 + *
63999 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
64000 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
64001 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
64002 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
64003 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
64004 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
64005 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
64006 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
64007 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
64008 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
64009 + */
64010 +
64011 +#include "fsl_fman_sp.h"
64012 +
64013 +
64014 +uint32_t fman_vsp_get_statistics(struct fm_pcd_storage_profile_regs *regs,
64015 + uint16_t index)
64016 +{
64017 + struct fm_pcd_storage_profile_regs *sp_regs;
64018 + sp_regs = &regs[index];
64019 + return ioread32be(&sp_regs->fm_sp_acnt);
64020 +}
64021 +
64022 +void fman_vsp_set_statistics(struct fm_pcd_storage_profile_regs *regs,
64023 + uint16_t index, uint32_t value)
64024 +{
64025 + struct fm_pcd_storage_profile_regs *sp_regs;
64026 + sp_regs = &regs[index];
64027 + iowrite32be(value, &sp_regs->fm_sp_acnt);
64028 +}
64029 +
64030 +void fman_vsp_defconfig(struct fm_storage_profile_params *cfg)
64031 +{
64032 + cfg->dma_swap_data =
64033 + DEFAULT_FMAN_SP_DMA_SWAP_DATA;
64034 + cfg->int_context_cache_attr =
64035 + DEFAULT_FMAN_SP_DMA_INT_CONTEXT_CACHE_ATTR;
64036 + cfg->header_cache_attr =
64037 + DEFAULT_FMAN_SP_DMA_HEADER_CACHE_ATTR;
64038 + cfg->scatter_gather_cache_attr =
64039 + DEFAULT_FMAN_SP_DMA_SCATTER_GATHER_CACHE_ATTR;
64040 + cfg->dma_write_optimize =
64041 + DEFAULT_FMAN_SP_DMA_WRITE_OPTIMIZE;
64042 + cfg->no_scather_gather =
64043 + DEFAULT_FMAN_SP_NO_SCATTER_GATHER;
64044 +}
64045 +
64046 +static inline uint32_t calc_vec_dep(int max_pools, bool *pools,
64047 + struct fman_ext_pools *ext_buf_pools, uint32_t mask)
64048 +{
64049 + int i, j;
64050 + uint32_t vector = 0;
64051 + for (i = 0; i < max_pools; i++)
64052 + if (pools[i])
64053 + for (j = 0; j < ext_buf_pools->num_pools_used; j++)
64054 + if (i == ext_buf_pools->ext_buf_pool[j].id) {
64055 + vector |= mask >> j;
64056 + break;
64057 + }
64058 + return vector;
64059 +}
64060 +
64061 +void fman_vsp_init(struct fm_pcd_storage_profile_regs *regs,
64062 + uint16_t index, struct fm_storage_profile_params *fm_vsp_params,
64063 + int port_max_num_of_ext_pools, int bm_max_num_of_pools,
64064 + int max_num_of_pfc_priorities)
64065 +{
64066 + int i = 0, j = 0;
64067 + struct fm_pcd_storage_profile_regs *sp_regs;
64068 + uint32_t tmp_reg, vector;
64069 + struct fman_ext_pools *ext_buf_pools = &fm_vsp_params->fm_ext_pools;
64070 + struct fman_buf_pool_depletion *buf_pool_depletion =
64071 + &fm_vsp_params->buf_pool_depletion;
64072 + struct fman_backup_bm_pools *backup_pools =
64073 + &fm_vsp_params->backup_pools;
64074 + struct fman_sp_int_context_data_copy *int_context_data_copy =
64075 + fm_vsp_params->int_context;
64076 + struct fman_sp_buf_margins *external_buffer_margins =
64077 + fm_vsp_params->buf_margins;
64078 + bool no_scather_gather = fm_vsp_params->no_scather_gather;
64079 + uint16_t liodn_offset = fm_vsp_params->liodn_offset;
64080 +
64081 + sp_regs = &regs[index];
64082 +
64083 + /* fill external buffers manager pool information register*/
64084 + for (i = 0; i < ext_buf_pools->num_pools_used; i++) {
64085 + tmp_reg = FMAN_SP_EXT_BUF_POOL_VALID |
64086 + FMAN_SP_EXT_BUF_POOL_EN_COUNTER;
64087 + tmp_reg |= ((uint32_t)ext_buf_pools->ext_buf_pool[i].id <<
64088 + FMAN_SP_EXT_BUF_POOL_ID_SHIFT);
64089 + tmp_reg |= ext_buf_pools->ext_buf_pool[i].size;
64090 + /* functionality available only for some deriviatives
64091 + (limited by config) */
64092 + for (j = 0; j < backup_pools->num_backup_pools; j++)
64093 + if (ext_buf_pools->ext_buf_pool[i].id ==
64094 + backup_pools->pool_ids[j]) {
64095 + tmp_reg |= FMAN_SP_EXT_BUF_POOL_BACKUP;
64096 + break;
64097 + }
64098 + iowrite32be(tmp_reg, &sp_regs->fm_sp_ebmpi[i]);
64099 + }
64100 +
64101 + /* clear unused pools */
64102 + for (i = ext_buf_pools->num_pools_used;
64103 + i < port_max_num_of_ext_pools; i++)
64104 + iowrite32be(0, &sp_regs->fm_sp_ebmpi[i]);
64105 +
64106 + /* fill pool depletion register*/
64107 + tmp_reg = 0;
64108 + if (buf_pool_depletion->buf_pool_depletion_enabled && buf_pool_depletion->pools_grp_mode_enable) {
64109 + /* calculate vector for number of pools depletion */
64110 + vector = calc_vec_dep(bm_max_num_of_pools, buf_pool_depletion->
64111 + pools_to_consider, ext_buf_pools, 0x80000000);
64112 +
64113 + /* configure num of pools and vector for number of pools mode */
64114 + tmp_reg |= (((uint32_t)buf_pool_depletion->num_pools - 1) <<
64115 + FMAN_SP_POOL_DEP_NUM_OF_POOLS_SHIFT);
64116 + tmp_reg |= vector;
64117 + }
64118 +
64119 + if (buf_pool_depletion->buf_pool_depletion_enabled && buf_pool_depletion->single_pool_mode_enable) {
64120 + /* calculate vector for number of pools depletion */
64121 + vector = calc_vec_dep(bm_max_num_of_pools, buf_pool_depletion->
64122 + pools_to_consider_for_single_mode,
64123 + ext_buf_pools, 0x00000080);
64124 +
64125 + /* configure num of pools and vector for number of pools mode */
64126 + tmp_reg |= vector;
64127 + }
64128 +
64129 + /* fill QbbPEV */
64130 + if (buf_pool_depletion->buf_pool_depletion_enabled) {
64131 + vector = 0;
64132 + for (i = 0; i < max_num_of_pfc_priorities; i++)
64133 + if (buf_pool_depletion->pfc_priorities_en[i] == TRUE)
64134 + vector |= 0x00000100 << i;
64135 + tmp_reg |= vector;
64136 + }
64137 + iowrite32be(tmp_reg, &sp_regs->fm_sp_mpd);
64138 +
64139 + /* fill dma attributes register */
64140 + tmp_reg = 0;
64141 + tmp_reg |= (uint32_t)fm_vsp_params->dma_swap_data <<
64142 + FMAN_SP_DMA_ATTR_SWP_SHIFT;
64143 + tmp_reg |= (uint32_t)fm_vsp_params->int_context_cache_attr <<
64144 + FMAN_SP_DMA_ATTR_IC_CACHE_SHIFT;
64145 + tmp_reg |= (uint32_t)fm_vsp_params->header_cache_attr <<
64146 + FMAN_SP_DMA_ATTR_HDR_CACHE_SHIFT;
64147 + tmp_reg |= (uint32_t)fm_vsp_params->scatter_gather_cache_attr <<
64148 + FMAN_SP_DMA_ATTR_SG_CACHE_SHIFT;
64149 + if (fm_vsp_params->dma_write_optimize)
64150 + tmp_reg |= FMAN_SP_DMA_ATTR_WRITE_OPTIMIZE;
64151 + iowrite32be(tmp_reg, &sp_regs->fm_sp_da);
64152 +
64153 + /* IC parameters - fill internal context parameters register */
64154 + tmp_reg = 0;
64155 + tmp_reg |= (((uint32_t)int_context_data_copy->ext_buf_offset/
64156 + OFFSET_UNITS) << FMAN_SP_IC_TO_EXT_SHIFT);
64157 + tmp_reg |= (((uint32_t)int_context_data_copy->int_context_offset/
64158 + OFFSET_UNITS) << FMAN_SP_IC_FROM_INT_SHIFT);
64159 + tmp_reg |= (((uint32_t)int_context_data_copy->size/OFFSET_UNITS) <<
64160 + FMAN_SP_IC_SIZE_SHIFT);
64161 + iowrite32be(tmp_reg, &sp_regs->fm_sp_icp);
64162 +
64163 + /* buffer margins - fill external buffer margins register */
64164 + tmp_reg = 0;
64165 + tmp_reg |= (((uint32_t)external_buffer_margins->start_margins) <<
64166 + FMAN_SP_EXT_BUF_MARG_START_SHIFT);
64167 + tmp_reg |= (((uint32_t)external_buffer_margins->end_margins) <<
64168 + FMAN_SP_EXT_BUF_MARG_END_SHIFT);
64169 + if (no_scather_gather)
64170 + tmp_reg |= FMAN_SP_SG_DISABLE;
64171 + iowrite32be(tmp_reg, &sp_regs->fm_sp_ebm);
64172 +
64173 + /* buffer margins - fill spliodn register */
64174 + iowrite32be(liodn_offset, &sp_regs->fm_sp_spliodn);
64175 +}
64176 --- /dev/null
64177 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/fm.c
64178 @@ -0,0 +1,5216 @@
64179 +/*
64180 + * Copyright 2008-2012 Freescale Semiconductor Inc.
64181 + *
64182 + * Redistribution and use in source and binary forms, with or without
64183 + * modification, are permitted provided that the following conditions are met:
64184 + * * Redistributions of source code must retain the above copyright
64185 + * notice, this list of conditions and the following disclaimer.
64186 + * * Redistributions in binary form must reproduce the above copyright
64187 + * notice, this list of conditions and the following disclaimer in the
64188 + * documentation and/or other materials provided with the distribution.
64189 + * * Neither the name of Freescale Semiconductor nor the
64190 + * names of its contributors may be used to endorse or promote products
64191 + * derived from this software without specific prior written permission.
64192 + *
64193 + *
64194 + * ALTERNATIVELY, this software may be distributed under the terms of the
64195 + * GNU General Public License ("GPL") as published by the Free Software
64196 + * Foundation, either version 2 of that License or (at your option) any
64197 + * later version.
64198 + *
64199 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
64200 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
64201 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
64202 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
64203 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
64204 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
64205 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
64206 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
64207 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
64208 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
64209 + */
64210 +
64211 +
64212 +/******************************************************************************
64213 + @File fm.c
64214 +
64215 + @Description FM driver routines implementation.
64216 +*//***************************************************************************/
64217 +#include "std_ext.h"
64218 +#include "error_ext.h"
64219 +#include "xx_ext.h"
64220 +#include "string_ext.h"
64221 +#include "sprint_ext.h"
64222 +#include "debug_ext.h"
64223 +#include "fm_muram_ext.h"
64224 +#include <linux/math64.h>
64225 +
64226 +#include "fm_common.h"
64227 +#include "fm_ipc.h"
64228 +#include "fm.h"
64229 +#ifndef CONFIG_FMAN_ARM
64230 +#include <linux/fsl/svr.h>
64231 +#endif
64232 +#include "fsl_fman.h"
64233 +
64234 +
64235 +/****************************************/
64236 +/* static functions */
64237 +/****************************************/
64238 +
64239 +static volatile bool blockingFlag = FALSE;
64240 +static void IpcMsgCompletionCB(t_Handle h_Fm,
64241 + uint8_t *p_Msg,
64242 + uint8_t *p_Reply,
64243 + uint32_t replyLength,
64244 + t_Error status)
64245 +{
64246 + UNUSED(h_Fm);UNUSED(p_Msg);UNUSED(p_Reply);UNUSED(replyLength);UNUSED(status);
64247 + blockingFlag = FALSE;
64248 +}
64249 +
64250 +static void FreeInitResources(t_Fm *p_Fm)
64251 +{
64252 + if (p_Fm->camBaseAddr)
64253 + FM_MURAM_FreeMem(p_Fm->h_FmMuram, UINT_TO_PTR(p_Fm->camBaseAddr));
64254 + if (p_Fm->fifoBaseAddr)
64255 + FM_MURAM_FreeMem(p_Fm->h_FmMuram, UINT_TO_PTR(p_Fm->fifoBaseAddr));
64256 + if (p_Fm->resAddr)
64257 + FM_MURAM_FreeMem(p_Fm->h_FmMuram, UINT_TO_PTR(p_Fm->resAddr));
64258 +}
64259 +
64260 +static bool IsFmanCtrlCodeLoaded(t_Fm *p_Fm)
64261 +{
64262 + t_FMIramRegs *p_Iram;
64263 +
64264 + ASSERT_COND(p_Fm);
64265 + p_Iram = (t_FMIramRegs *)UINT_TO_PTR(p_Fm->baseAddr + FM_MM_IMEM);
64266 +
64267 + return (bool)!!(GET_UINT32(p_Iram->iready) & IRAM_READY);
64268 +}
64269 +
64270 +static t_Error CheckFmParameters(t_Fm *p_Fm)
64271 +{
64272 + if (IsFmanCtrlCodeLoaded(p_Fm) && !p_Fm->resetOnInit)
64273 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Old FMan CTRL code is loaded; FM must be reset!"));
64274 +#if (DPAA_VERSION < 11)
64275 + if (!p_Fm->p_FmDriverParam->dma_axi_dbg_num_of_beats ||
64276 + (p_Fm->p_FmDriverParam->dma_axi_dbg_num_of_beats > DMA_MODE_MAX_AXI_DBG_NUM_OF_BEATS))
64277 + RETURN_ERROR(MAJOR, E_INVALID_VALUE,
64278 + ("axiDbgNumOfBeats has to be in the range 1 - %d", DMA_MODE_MAX_AXI_DBG_NUM_OF_BEATS));
64279 +#endif /* (DPAA_VERSION < 11) */
64280 + if (p_Fm->p_FmDriverParam->dma_cam_num_of_entries % DMA_CAM_UNITS)
64281 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("dma_cam_num_of_entries has to be divisble by %d", DMA_CAM_UNITS));
64282 +// 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))
64283 +// 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));
64284 + if (p_Fm->p_FmDriverParam->dma_comm_qtsh_asrt_emer > DMA_THRESH_MAX_COMMQ)
64285 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("dma_comm_qtsh_asrt_emer can not be larger than %d", DMA_THRESH_MAX_COMMQ));
64286 + if (p_Fm->p_FmDriverParam->dma_comm_qtsh_clr_emer > DMA_THRESH_MAX_COMMQ)
64287 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("dma_comm_qtsh_clr_emer can not be larger than %d", DMA_THRESH_MAX_COMMQ));
64288 + if (p_Fm->p_FmDriverParam->dma_comm_qtsh_clr_emer >= p_Fm->p_FmDriverParam->dma_comm_qtsh_asrt_emer)
64289 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("dma_comm_qtsh_clr_emer must be smaller than dma_comm_qtsh_asrt_emer"));
64290 +#if (DPAA_VERSION < 11)
64291 + if (p_Fm->p_FmDriverParam->dma_read_buf_tsh_asrt_emer > DMA_THRESH_MAX_BUF)
64292 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("dma_read_buf_tsh_asrt_emer can not be larger than %d", DMA_THRESH_MAX_BUF));
64293 + if (p_Fm->p_FmDriverParam->dma_read_buf_tsh_clr_emer > DMA_THRESH_MAX_BUF)
64294 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("dma_read_buf_tsh_clr_emer can not be larger than %d", DMA_THRESH_MAX_BUF));
64295 + if (p_Fm->p_FmDriverParam->dma_read_buf_tsh_clr_emer >= p_Fm->p_FmDriverParam->dma_read_buf_tsh_asrt_emer)
64296 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("dma_read_buf_tsh_clr_emer must be smaller than dma_read_buf_tsh_asrt_emer"));
64297 + if (p_Fm->p_FmDriverParam->dma_write_buf_tsh_asrt_emer > DMA_THRESH_MAX_BUF)
64298 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("dma_write_buf_tsh_asrt_emer can not be larger than %d", DMA_THRESH_MAX_BUF));
64299 + if (p_Fm->p_FmDriverParam->dma_write_buf_tsh_clr_emer > DMA_THRESH_MAX_BUF)
64300 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("dma_write_buf_tsh_clr_emer can not be larger than %d", DMA_THRESH_MAX_BUF));
64301 + if (p_Fm->p_FmDriverParam->dma_write_buf_tsh_clr_emer >= p_Fm->p_FmDriverParam->dma_write_buf_tsh_asrt_emer)
64302 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("dma_write_buf_tsh_clr_emer must be smaller than dma_write_buf_tsh_asrt_emer"));
64303 +#else /* (DPAA_VERSION >= 11) */
64304 + if ((p_Fm->p_FmDriverParam->dma_dbg_cnt_mode == E_FMAN_DMA_DBG_CNT_INT_READ_EM)||
64305 + (p_Fm->p_FmDriverParam->dma_dbg_cnt_mode == E_FMAN_DMA_DBG_CNT_INT_WRITE_EM) ||
64306 + (p_Fm->p_FmDriverParam->dma_dbg_cnt_mode == E_FMAN_DMA_DBG_CNT_RAW_WAR_PROT))
64307 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("dma_dbg_cnt_mode value not supported by this integration."));
64308 + if ((p_Fm->p_FmDriverParam->dma_emergency_bus_select == FM_DMA_MURAM_READ_EMERGENCY)||
64309 + (p_Fm->p_FmDriverParam->dma_emergency_bus_select == FM_DMA_MURAM_WRITE_EMERGENCY))
64310 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("emergencyBusSelect value not supported by this integration."));
64311 + if (p_Fm->p_FmDriverParam->dma_stop_on_bus_error)
64312 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("dma_stop_on_bus_error not supported by this integration."));
64313 +#ifdef FM_AID_MODE_NO_TNUM_SW005
64314 + if (p_Fm->p_FmDriverParam->dma_aid_mode != E_FMAN_DMA_AID_OUT_PORT_ID)
64315 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("dma_aid_mode not supported by this integration."));
64316 +#endif /* FM_AID_MODE_NO_TNUM_SW005 */
64317 + if (p_Fm->p_FmDriverParam->dma_axi_dbg_num_of_beats)
64318 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("dma_axi_dbg_num_of_beats not supported by this integration."));
64319 +#endif /* (DPAA_VERSION < 11) */
64320 +
64321 + if (!p_Fm->p_FmStateStruct->fmClkFreq)
64322 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("fmClkFreq must be set."));
64323 + if (USEC_TO_CLK(p_Fm->p_FmDriverParam->dma_watchdog, p_Fm->p_FmStateStruct->fmClkFreq) > DMA_MAX_WATCHDOG)
64324 + RETURN_ERROR(MAJOR, E_INVALID_VALUE,
64325 + ("dma_watchdog depends on FM clock. dma_watchdog(in microseconds) * clk (in Mhz), may not exceed 0x08x", DMA_MAX_WATCHDOG));
64326 +
64327 +#if (DPAA_VERSION >= 11)
64328 + if ((p_Fm->partVSPBase + p_Fm->partNumOfVSPs) > FM_VSP_MAX_NUM_OF_ENTRIES)
64329 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("partVSPBase+partNumOfVSPs out of range!!!"));
64330 +#endif /* (DPAA_VERSION >= 11) */
64331 +
64332 + if (p_Fm->p_FmStateStruct->totalFifoSize % BMI_FIFO_UNITS)
64333 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("totalFifoSize number has to be divisible by %d", BMI_FIFO_UNITS));
64334 + if (!p_Fm->p_FmStateStruct->totalFifoSize ||
64335 + (p_Fm->p_FmStateStruct->totalFifoSize > BMI_MAX_FIFO_SIZE))
64336 + RETURN_ERROR(MAJOR, E_INVALID_VALUE,
64337 + ("totalFifoSize (currently defined as %d) has to be in the range of 256 to %d",
64338 + p_Fm->p_FmStateStruct->totalFifoSize,
64339 + BMI_MAX_FIFO_SIZE));
64340 + if (!p_Fm->p_FmStateStruct->totalNumOfTasks ||
64341 + (p_Fm->p_FmStateStruct->totalNumOfTasks > BMI_MAX_NUM_OF_TASKS))
64342 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("totalNumOfTasks number has to be in the range 1 - %d", BMI_MAX_NUM_OF_TASKS));
64343 +
64344 +#ifdef FM_HAS_TOTAL_DMAS
64345 + if (!p_Fm->p_FmStateStruct->maxNumOfOpenDmas ||
64346 + (p_Fm->p_FmStateStruct->maxNumOfOpenDmas > BMI_MAX_NUM_OF_DMAS))
64347 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("maxNumOfOpenDmas number has to be in the range 1 - %d", BMI_MAX_NUM_OF_DMAS));
64348 +#endif /* FM_HAS_TOTAL_DMAS */
64349 +
64350 + if (p_Fm->p_FmDriverParam->disp_limit_tsh > FPM_MAX_DISP_LIMIT)
64351 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("disp_limit_tsh can't be greater than %d", FPM_MAX_DISP_LIMIT));
64352 +
64353 + if (!p_Fm->f_Exception)
64354 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Exceptions callback not provided"));
64355 + if (!p_Fm->f_BusError)
64356 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Exceptions callback not provided"));
64357 +
64358 +#ifdef FM_NO_WATCHDOG
64359 + if ((p_Fm->p_FmStateStruct->revInfo.majorRev == 2) &&
64360 + (p_Fm->p_FmDriverParam->dma_watchdog))
64361 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("watchdog!"));
64362 +#endif /* FM_NO_WATCHDOG */
64363 +
64364 +#ifdef FM_ECC_HALT_NO_SYNC_ERRATA_10GMAC_A008
64365 + if ((p_Fm->p_FmStateStruct->revInfo.majorRev < 6) &&
64366 + (p_Fm->p_FmDriverParam->halt_on_unrecov_ecc_err))
64367 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("HaltOnEccError!"));
64368 +#endif /* FM_ECC_HALT_NO_SYNC_ERRATA_10GMAC_A008 */
64369 +
64370 +#ifdef FM_NO_TNUM_AGING
64371 + if ((p_Fm->p_FmStateStruct->revInfo.majorRev != 4) &&
64372 + (p_Fm->p_FmStateStruct->revInfo.majorRev < 6))
64373 + if (p_Fm->p_FmDriverParam->tnum_aging_period)
64374 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("Tnum aging!"));
64375 +#endif /* FM_NO_TNUM_AGING */
64376 +
64377 + /* check that user did not set revision-dependent exceptions */
64378 +#ifdef FM_NO_DISPATCH_RAM_ECC
64379 + if ((p_Fm->p_FmStateStruct->revInfo.majorRev != 4) &&
64380 + (p_Fm->p_FmStateStruct->revInfo.majorRev < 6))
64381 + if (p_Fm->userSetExceptions & FM_EX_BMI_DISPATCH_RAM_ECC)
64382 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("exception e_FM_EX_BMI_DISPATCH_RAM_ECC!"));
64383 +#endif /* FM_NO_DISPATCH_RAM_ECC */
64384 +
64385 +#ifdef FM_QMI_NO_ECC_EXCEPTIONS
64386 + if (p_Fm->p_FmStateStruct->revInfo.majorRev == 4)
64387 + if (p_Fm->userSetExceptions & (FM_EX_QMI_SINGLE_ECC | FM_EX_QMI_DOUBLE_ECC))
64388 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("exception e_FM_EX_QMI_SINGLE_ECC/e_FM_EX_QMI_DOUBLE_ECC!"));
64389 +#endif /* FM_QMI_NO_ECC_EXCEPTIONS */
64390 +
64391 +#ifdef FM_QMI_NO_SINGLE_ECC_EXCEPTION
64392 + if (p_Fm->p_FmStateStruct->revInfo.majorRev >= 6)
64393 + if (p_Fm->userSetExceptions & FM_EX_QMI_SINGLE_ECC)
64394 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("exception e_FM_EX_QMI_SINGLE_ECC!"));
64395 +#endif /* FM_QMI_NO_SINGLE_ECC_EXCEPTION */
64396 +
64397 + return E_OK;
64398 +}
64399 +
64400 +
64401 +static void SendIpcIsr(t_Fm *p_Fm, uint32_t macEvent, uint32_t pendingReg)
64402 +{
64403 + ASSERT_COND(p_Fm->guestId == NCSW_MASTER_ID);
64404 +
64405 + if (p_Fm->intrMng[macEvent].guestId == NCSW_MASTER_ID)
64406 + p_Fm->intrMng[macEvent].f_Isr(p_Fm->intrMng[macEvent].h_SrcHandle);
64407 +
64408 + /* If the MAC is running on guest-partition and we have IPC session with it,
64409 + we inform him about the event through IPC; otherwise, we ignore the event. */
64410 + else if (p_Fm->h_IpcSessions[p_Fm->intrMng[macEvent].guestId])
64411 + {
64412 + t_Error err;
64413 + t_FmIpcIsr fmIpcIsr;
64414 + t_FmIpcMsg msg;
64415 +
64416 + memset(&msg, 0, sizeof(msg));
64417 + msg.msgId = FM_GUEST_ISR;
64418 + fmIpcIsr.pendingReg = pendingReg;
64419 + fmIpcIsr.boolErr = FALSE;
64420 + memcpy(msg.msgBody, &fmIpcIsr, sizeof(fmIpcIsr));
64421 + err = XX_IpcSendMessage(p_Fm->h_IpcSessions[p_Fm->intrMng[macEvent].guestId],
64422 + (uint8_t*)&msg,
64423 + sizeof(msg.msgId) + sizeof(fmIpcIsr),
64424 + NULL,
64425 + NULL,
64426 + NULL,
64427 + NULL);
64428 + if (err != E_OK)
64429 + REPORT_ERROR(MINOR, err, NO_MSG);
64430 + }
64431 + else
64432 + DBG(TRACE, ("FM Guest mode, without IPC - can't call ISR!"));
64433 +}
64434 +
64435 +static void BmiErrEvent(t_Fm *p_Fm)
64436 +{
64437 + uint32_t event;
64438 + struct fman_bmi_regs *bmi_rg = p_Fm->p_FmBmiRegs;
64439 +
64440 +
64441 + event = fman_get_bmi_err_event(bmi_rg);
64442 +
64443 + if (event & BMI_ERR_INTR_EN_STORAGE_PROFILE_ECC)
64444 + p_Fm->f_Exception(p_Fm->h_App,e_FM_EX_BMI_STORAGE_PROFILE_ECC);
64445 + if (event & BMI_ERR_INTR_EN_LIST_RAM_ECC)
64446 + p_Fm->f_Exception(p_Fm->h_App,e_FM_EX_BMI_LIST_RAM_ECC);
64447 + if (event & BMI_ERR_INTR_EN_STATISTICS_RAM_ECC)
64448 + p_Fm->f_Exception(p_Fm->h_App,e_FM_EX_BMI_STATISTICS_RAM_ECC);
64449 + if (event & BMI_ERR_INTR_EN_DISPATCH_RAM_ECC)
64450 + p_Fm->f_Exception(p_Fm->h_App,e_FM_EX_BMI_DISPATCH_RAM_ECC);
64451 +}
64452 +
64453 +static void QmiErrEvent(t_Fm *p_Fm)
64454 +{
64455 + uint32_t event;
64456 + struct fman_qmi_regs *qmi_rg = p_Fm->p_FmQmiRegs;
64457 +
64458 + event = fman_get_qmi_err_event(qmi_rg);
64459 +
64460 + if (event & QMI_ERR_INTR_EN_DOUBLE_ECC)
64461 + p_Fm->f_Exception(p_Fm->h_App,e_FM_EX_QMI_DOUBLE_ECC);
64462 + if (event & QMI_ERR_INTR_EN_DEQ_FROM_DEF)
64463 + p_Fm->f_Exception(p_Fm->h_App,e_FM_EX_QMI_DEQ_FROM_UNKNOWN_PORTID);
64464 +}
64465 +
64466 +static void DmaErrEvent(t_Fm *p_Fm)
64467 +{
64468 + uint32_t status, com_id;
64469 + uint8_t tnum;
64470 + uint8_t hardwarePortId;
64471 + uint8_t relativePortId;
64472 + uint16_t liodn;
64473 + struct fman_dma_regs *dma_rg = p_Fm->p_FmDmaRegs;
64474 +
64475 + status = fman_get_dma_err_event(dma_rg);
64476 +
64477 + if (status & DMA_STATUS_BUS_ERR)
64478 + {
64479 + com_id = fman_get_dma_com_id(dma_rg);
64480 + hardwarePortId = (uint8_t)(((com_id & DMA_TRANSFER_PORTID_MASK) >> DMA_TRANSFER_PORTID_SHIFT));
64481 + ASSERT_COND(IN_RANGE(1, hardwarePortId, 63));
64482 + HW_PORT_ID_TO_SW_PORT_ID(relativePortId, hardwarePortId);
64483 + tnum = (uint8_t)((com_id & DMA_TRANSFER_TNUM_MASK) >> DMA_TRANSFER_TNUM_SHIFT);
64484 + liodn = (uint16_t)(com_id & DMA_TRANSFER_LIODN_MASK);
64485 + ASSERT_COND(p_Fm->p_FmStateStruct->portsTypes[hardwarePortId] != e_FM_PORT_TYPE_DUMMY);
64486 + p_Fm->f_BusError(p_Fm->h_App,
64487 + p_Fm->p_FmStateStruct->portsTypes[hardwarePortId],
64488 + relativePortId,
64489 + fman_get_dma_addr(dma_rg),
64490 + tnum,
64491 + liodn);
64492 + }
64493 + if (status & DMA_STATUS_FM_SPDAT_ECC)
64494 + p_Fm->f_Exception(p_Fm->h_App, e_FM_EX_DMA_SINGLE_PORT_ECC);
64495 + if (status & DMA_STATUS_READ_ECC)
64496 + p_Fm->f_Exception(p_Fm->h_App, e_FM_EX_DMA_READ_ECC);
64497 + if (status & DMA_STATUS_SYSTEM_WRITE_ECC)
64498 + p_Fm->f_Exception(p_Fm->h_App, e_FM_EX_DMA_SYSTEM_WRITE_ECC);
64499 + if (status & DMA_STATUS_FM_WRITE_ECC)
64500 + p_Fm->f_Exception(p_Fm->h_App, e_FM_EX_DMA_FM_WRITE_ECC);
64501 + }
64502 +
64503 +static void FpmErrEvent(t_Fm *p_Fm)
64504 +{
64505 + uint32_t event;
64506 + struct fman_fpm_regs *fpm_rg = p_Fm->p_FmFpmRegs;
64507 +
64508 + event = fman_get_fpm_err_event(fpm_rg);
64509 +
64510 + if ((event & FPM_EV_MASK_DOUBLE_ECC) && (event & FPM_EV_MASK_DOUBLE_ECC_EN))
64511 + p_Fm->f_Exception(p_Fm->h_App,e_FM_EX_FPM_DOUBLE_ECC);
64512 + if ((event & FPM_EV_MASK_STALL) && (event & FPM_EV_MASK_STALL_EN))
64513 + p_Fm->f_Exception(p_Fm->h_App,e_FM_EX_FPM_STALL_ON_TASKS);
64514 + if ((event & FPM_EV_MASK_SINGLE_ECC) && (event & FPM_EV_MASK_SINGLE_ECC_EN))
64515 + p_Fm->f_Exception(p_Fm->h_App,e_FM_EX_FPM_SINGLE_ECC);
64516 +}
64517 +
64518 +static void MuramErrIntr(t_Fm *p_Fm)
64519 +{
64520 + uint32_t event;
64521 + struct fman_fpm_regs *fpm_rg = p_Fm->p_FmFpmRegs;
64522 +
64523 + event = fman_get_muram_err_event(fpm_rg);
64524 +
64525 + if (event & FPM_RAM_MURAM_ECC)
64526 + p_Fm->f_Exception(p_Fm->h_App, e_FM_EX_MURAM_ECC);
64527 +}
64528 +
64529 +static void IramErrIntr(t_Fm *p_Fm)
64530 +{
64531 + uint32_t event;
64532 + struct fman_fpm_regs *fpm_rg = p_Fm->p_FmFpmRegs;
64533 +
64534 + event = fman_get_iram_err_event(fpm_rg);
64535 +
64536 + if (event & FPM_RAM_IRAM_ECC)
64537 + p_Fm->f_Exception(p_Fm->h_App, e_FM_EX_IRAM_ECC);
64538 +}
64539 +
64540 +static void QmiEvent(t_Fm *p_Fm)
64541 +{
64542 + uint32_t event;
64543 + struct fman_qmi_regs *qmi_rg = p_Fm->p_FmQmiRegs;
64544 +
64545 + event = fman_get_qmi_event(qmi_rg);
64546 +
64547 + if (event & QMI_INTR_EN_SINGLE_ECC)
64548 + p_Fm->f_Exception(p_Fm->h_App,e_FM_EX_QMI_SINGLE_ECC);
64549 +}
64550 +
64551 +static void UnimplementedIsr(t_Handle h_Arg)
64552 +{
64553 + UNUSED(h_Arg);
64554 +
64555 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Unimplemented ISR!"));
64556 +}
64557 +
64558 +static void UnimplementedFmanCtrlIsr(t_Handle h_Arg, uint32_t event)
64559 +{
64560 + UNUSED(h_Arg); UNUSED(event);
64561 +
64562 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Unimplemented FmCtl ISR!"));
64563 +}
64564 +
64565 +static void EnableTimeStamp(t_Fm *p_Fm)
64566 +{
64567 + struct fman_fpm_regs *fpm_rg = p_Fm->p_FmFpmRegs;
64568 +
64569 + ASSERT_COND(p_Fm->p_FmStateStruct);
64570 + ASSERT_COND(p_Fm->p_FmStateStruct->count1MicroBit);
64571 +
64572 + fman_enable_time_stamp(fpm_rg, p_Fm->p_FmStateStruct->count1MicroBit, p_Fm->p_FmStateStruct->fmClkFreq);
64573 +
64574 + p_Fm->p_FmStateStruct->enabledTimeStamp = TRUE;
64575 +}
64576 +
64577 +static t_Error ClearIRam(t_Fm *p_Fm)
64578 +{
64579 + t_FMIramRegs *p_Iram;
64580 + int i;
64581 + int iram_size;
64582 +
64583 + ASSERT_COND(p_Fm);
64584 + p_Iram = (t_FMIramRegs *)UINT_TO_PTR(p_Fm->baseAddr + FM_MM_IMEM);
64585 + iram_size = FM_IRAM_SIZE(p_Fm->p_FmStateStruct->revInfo.majorRev,p_Fm->p_FmStateStruct->revInfo.minorRev);
64586 +
64587 + /* Enable the auto-increment */
64588 + WRITE_UINT32(p_Iram->iadd, IRAM_IADD_AIE);
64589 + while (GET_UINT32(p_Iram->iadd) != IRAM_IADD_AIE) ;
64590 +
64591 + for (i=0; i < (iram_size/4); i++)
64592 + WRITE_UINT32(p_Iram->idata, 0xffffffff);
64593 +
64594 + WRITE_UINT32(p_Iram->iadd, iram_size - 4);
64595 + CORE_MemoryBarrier();
64596 + while (GET_UINT32(p_Iram->idata) != 0xffffffff) ;
64597 +
64598 + return E_OK;
64599 +}
64600 +
64601 +static t_Error LoadFmanCtrlCode(t_Fm *p_Fm)
64602 +{
64603 + t_FMIramRegs *p_Iram;
64604 + int i;
64605 + uint32_t tmp;
64606 + uint8_t compTo16;
64607 +
64608 + ASSERT_COND(p_Fm);
64609 + p_Iram = (t_FMIramRegs *)UINT_TO_PTR(p_Fm->baseAddr + FM_MM_IMEM);
64610 +
64611 + /* Enable the auto-increment */
64612 + WRITE_UINT32(p_Iram->iadd, IRAM_IADD_AIE);
64613 + while (GET_UINT32(p_Iram->iadd) != IRAM_IADD_AIE) ;
64614 +
64615 + for (i=0; i < (p_Fm->firmware.size / 4); i++)
64616 + WRITE_UINT32(p_Iram->idata, p_Fm->firmware.p_Code[i]);
64617 +
64618 + compTo16 = (uint8_t)(p_Fm->firmware.size % 16);
64619 + if (compTo16)
64620 + for (i=0; i < ((16-compTo16) / 4); i++)
64621 + WRITE_UINT32(p_Iram->idata, 0xffffffff);
64622 +
64623 + WRITE_UINT32(p_Iram->iadd,p_Fm->firmware.size-4);
64624 + while (GET_UINT32(p_Iram->iadd) != (p_Fm->firmware.size-4)) ;
64625 +
64626 + /* verify that writing has completed */
64627 + while (GET_UINT32(p_Iram->idata) != p_Fm->firmware.p_Code[(p_Fm->firmware.size / 4)-1]) ;
64628 +
64629 + if (p_Fm->fwVerify)
64630 + {
64631 + WRITE_UINT32(p_Iram->iadd, IRAM_IADD_AIE);
64632 + while (GET_UINT32(p_Iram->iadd) != IRAM_IADD_AIE) ;
64633 + for (i=0; i < (p_Fm->firmware.size / 4); i++)
64634 + {
64635 + tmp = GET_UINT32(p_Iram->idata);
64636 + if (tmp != p_Fm->firmware.p_Code[i])
64637 + RETURN_ERROR(MAJOR, E_WRITE_FAILED,
64638 + ("UCode write error : write 0x%x, read 0x%x",
64639 + p_Fm->firmware.p_Code[i],tmp));
64640 + }
64641 + WRITE_UINT32(p_Iram->iadd, 0x0);
64642 + }
64643 +
64644 + /* Enable patch from IRAM */
64645 + WRITE_UINT32(p_Iram->iready, IRAM_READY);
64646 + XX_UDelay(1000);
64647 +
64648 + DBG(INFO, ("FMan-Controller code (ver %d.%d.%d) loaded to IRAM.",
64649 + ((uint16_t *)p_Fm->firmware.p_Code)[2],
64650 + ((uint8_t *)p_Fm->firmware.p_Code)[6],
64651 + ((uint8_t *)p_Fm->firmware.p_Code)[7]));
64652 +
64653 + return E_OK;
64654 +}
64655 +
64656 +#ifdef FM_UCODE_NOT_RESET_ERRATA_BUGZILLA6173
64657 +static t_Error FwNotResetErratumBugzilla6173WA(t_Fm *p_Fm)
64658 +{
64659 + t_FMIramRegs *p_Iram = (t_FMIramRegs *)UINT_TO_PTR(p_Fm->baseAddr + FM_MM_IMEM);
64660 + uint32_t tmpReg;
64661 + uint32_t savedSpliodn[63];
64662 +
64663 + /* write to IRAM first location the debug instruction */
64664 + WRITE_UINT32(p_Iram->iadd, 0);
64665 + while (GET_UINT32(p_Iram->iadd) != 0) ;
64666 + WRITE_UINT32(p_Iram->idata, FM_FW_DEBUG_INSTRUCTION);
64667 +
64668 + WRITE_UINT32(p_Iram->iadd, 0);
64669 + while (GET_UINT32(p_Iram->iadd) != 0) ;
64670 + while (GET_UINT32(p_Iram->idata) != FM_FW_DEBUG_INSTRUCTION) ;
64671 +
64672 + /* Enable patch from IRAM */
64673 + WRITE_UINT32(p_Iram->iready, IRAM_READY);
64674 + CORE_MemoryBarrier();
64675 + XX_UDelay(100);
64676 + IO2MemCpy32((uint8_t *)savedSpliodn,
64677 + (uint8_t *)p_Fm->p_FmBmiRegs->fmbm_spliodn,
64678 + 63*sizeof(uint32_t));
64679 +
64680 + /* reset FMAN */
64681 + WRITE_UINT32(p_Fm->p_FmFpmRegs->fm_rstc, FPM_RSTC_FM_RESET);
64682 + CORE_MemoryBarrier();
64683 + XX_UDelay(100);
64684 +
64685 + /* verify breakpoint debug status register */
64686 + tmpReg = GET_UINT32(*(uint32_t *)UINT_TO_PTR(p_Fm->baseAddr + FM_DEBUG_STATUS_REGISTER_OFFSET));
64687 + if (!tmpReg)
64688 + REPORT_ERROR(MAJOR, E_INVALID_STATE, ("Invalid debug status register value is '0'"));
64689 +
64690 + /*************************************/
64691 + /* Load FMan-Controller code to IRAM */
64692 + /*************************************/
64693 + ClearIRam(p_Fm);
64694 + if (p_Fm->firmware.p_Code &&
64695 + (LoadFmanCtrlCode(p_Fm) != E_OK))
64696 + RETURN_ERROR(MAJOR, E_INVALID_STATE, NO_MSG);
64697 + XX_UDelay(100);
64698 +
64699 + /* reset FMAN again to start the microcode */
64700 + WRITE_UINT32(p_Fm->p_FmFpmRegs->fm_rstc, FPM_RSTC_FM_RESET);
64701 + CORE_MemoryBarrier();
64702 + XX_UDelay(100);
64703 + Mem2IOCpy32((uint8_t *)p_Fm->p_FmBmiRegs->fmbm_spliodn,
64704 + (uint8_t *)savedSpliodn,
64705 + 63*sizeof(uint32_t));
64706 +
64707 + if (fman_is_qmi_halt_not_busy_state(p_Fm->p_FmQmiRegs))
64708 + {
64709 + fman_resume(p_Fm->p_FmFpmRegs);
64710 + CORE_MemoryBarrier();
64711 + XX_UDelay(100);
64712 + }
64713 +
64714 + return E_OK;
64715 +}
64716 +#endif /* FM_UCODE_NOT_RESET_ERRATA_BUGZILLA6173 */
64717 +
64718 +static void GuestErrorIsr(t_Fm *p_Fm, uint32_t pending)
64719 +{
64720 +#define FM_G_CALL_1G_MAC_ERR_ISR(_id) \
64721 +do { \
64722 + 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);\
64723 +} while (0)
64724 +#define FM_G_CALL_10G_MAC_ERR_ISR(_id) \
64725 +do { \
64726 + 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);\
64727 +} while (0)
64728 +
64729 + /* error interrupts */
64730 + if (pending & ERR_INTR_EN_1G_MAC0)
64731 + FM_G_CALL_1G_MAC_ERR_ISR(0);
64732 + if (pending & ERR_INTR_EN_1G_MAC1)
64733 + FM_G_CALL_1G_MAC_ERR_ISR(1);
64734 + if (pending & ERR_INTR_EN_1G_MAC2)
64735 + FM_G_CALL_1G_MAC_ERR_ISR(2);
64736 + if (pending & ERR_INTR_EN_1G_MAC3)
64737 + FM_G_CALL_1G_MAC_ERR_ISR(3);
64738 + if (pending & ERR_INTR_EN_1G_MAC4)
64739 + FM_G_CALL_1G_MAC_ERR_ISR(4);
64740 + if (pending & ERR_INTR_EN_1G_MAC5)
64741 + FM_G_CALL_1G_MAC_ERR_ISR(5);
64742 + if (pending & ERR_INTR_EN_1G_MAC6)
64743 + FM_G_CALL_1G_MAC_ERR_ISR(6);
64744 + if (pending & ERR_INTR_EN_1G_MAC7)
64745 + FM_G_CALL_1G_MAC_ERR_ISR(7);
64746 + if (pending & ERR_INTR_EN_10G_MAC0)
64747 + FM_G_CALL_10G_MAC_ERR_ISR(0);
64748 + if (pending & ERR_INTR_EN_10G_MAC1)
64749 + FM_G_CALL_10G_MAC_ERR_ISR(1);
64750 +}
64751 +
64752 +static void GuestEventIsr(t_Fm *p_Fm, uint32_t pending)
64753 +{
64754 +#define FM_G_CALL_1G_MAC_ISR(_id) \
64755 +do { \
64756 + 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);\
64757 +} while (0)
64758 +#define FM_G_CALL_10G_MAC_ISR(_id) \
64759 +do { \
64760 + 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);\
64761 +} while (0)
64762 +
64763 + if (pending & INTR_EN_1G_MAC0)
64764 + FM_G_CALL_1G_MAC_ISR(0);
64765 + if (pending & INTR_EN_1G_MAC1)
64766 + FM_G_CALL_1G_MAC_ISR(1);
64767 + if (pending & INTR_EN_1G_MAC2)
64768 + FM_G_CALL_1G_MAC_ISR(2);
64769 + if (pending & INTR_EN_1G_MAC3)
64770 + FM_G_CALL_1G_MAC_ISR(3);
64771 + if (pending & INTR_EN_1G_MAC4)
64772 + FM_G_CALL_1G_MAC_ISR(4);
64773 + if (pending & INTR_EN_1G_MAC5)
64774 + FM_G_CALL_1G_MAC_ISR(5);
64775 + if (pending & INTR_EN_1G_MAC6)
64776 + FM_G_CALL_1G_MAC_ISR(6);
64777 + if (pending & INTR_EN_1G_MAC7)
64778 + FM_G_CALL_1G_MAC_ISR(7);
64779 + if (pending & INTR_EN_10G_MAC0)
64780 + FM_G_CALL_10G_MAC_ISR(0);
64781 + if (pending & INTR_EN_10G_MAC1)
64782 + FM_G_CALL_10G_MAC_ISR(1);
64783 + if (pending & INTR_EN_TMR)
64784 + p_Fm->intrMng[e_FM_EV_TMR].f_Isr(p_Fm->intrMng[e_FM_EV_TMR].h_SrcHandle);
64785 +}
64786 +
64787 +#if (DPAA_VERSION >= 11)
64788 +static t_Error SetVSPWindow(t_Handle h_Fm,
64789 + uint8_t hardwarePortId,
64790 + uint8_t baseStorageProfile,
64791 + uint8_t log2NumOfProfiles)
64792 +{
64793 + t_Fm *p_Fm = (t_Fm *)h_Fm;
64794 +
64795 + ASSERT_COND(h_Fm);
64796 + ASSERT_COND(IN_RANGE(1, hardwarePortId, 63));
64797 +
64798 + if ((p_Fm->guestId != NCSW_MASTER_ID) &&
64799 + !p_Fm->p_FmBmiRegs &&
64800 + p_Fm->h_IpcSessions[0])
64801 + {
64802 + t_FmIpcVspSetPortWindow fmIpcVspSetPortWindow;
64803 + t_FmIpcMsg msg;
64804 + t_Error err = E_OK;
64805 +
64806 + memset(&msg, 0, sizeof(msg));
64807 + memset(&fmIpcVspSetPortWindow, 0, sizeof(t_FmIpcVspSetPortWindow));
64808 + fmIpcVspSetPortWindow.hardwarePortId = hardwarePortId;
64809 + fmIpcVspSetPortWindow.baseStorageProfile = baseStorageProfile;
64810 + fmIpcVspSetPortWindow.log2NumOfProfiles = log2NumOfProfiles;
64811 + msg.msgId = FM_VSP_SET_PORT_WINDOW;
64812 + memcpy(msg.msgBody, &fmIpcVspSetPortWindow, sizeof(t_FmIpcVspSetPortWindow));
64813 +
64814 + err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0],
64815 + (uint8_t*)&msg,
64816 + sizeof(msg.msgId),
64817 + NULL,
64818 + NULL,
64819 + NULL,
64820 + NULL);
64821 + if (err != E_OK)
64822 + RETURN_ERROR(MINOR, err, NO_MSG);
64823 + return E_OK;
64824 + }
64825 + else if (!p_Fm->p_FmBmiRegs)
64826 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED,
64827 + ("Either IPC or 'baseAddress' is required!"));
64828 +
64829 + fman_set_vsp_window(p_Fm->p_FmBmiRegs,
64830 + hardwarePortId,
64831 + baseStorageProfile,
64832 + log2NumOfProfiles);
64833 +
64834 + return E_OK;
64835 +}
64836 +
64837 +static uint8_t AllocVSPsForPartition(t_Handle h_Fm, uint8_t base, uint8_t numOfProfiles, uint8_t guestId)
64838 +{
64839 + t_Fm *p_Fm = (t_Fm *)h_Fm;
64840 + uint8_t profilesFound = 0;
64841 + int i = 0;
64842 + uint32_t intFlags;
64843 +
64844 + if (!numOfProfiles)
64845 + return E_OK;
64846 +
64847 + if ((numOfProfiles > FM_VSP_MAX_NUM_OF_ENTRIES) ||
64848 + (base + numOfProfiles > FM_VSP_MAX_NUM_OF_ENTRIES))
64849 + return (uint8_t)ILLEGAL_BASE;
64850 +
64851 + if (p_Fm->h_IpcSessions[0])
64852 + {
64853 + t_FmIpcResourceAllocParams ipcAllocParams;
64854 + t_FmIpcMsg msg;
64855 + t_FmIpcReply reply;
64856 + t_Error err;
64857 + uint32_t replyLength;
64858 +
64859 + memset(&msg, 0, sizeof(msg));
64860 + memset(&reply, 0, sizeof(reply));
64861 + memset(&ipcAllocParams, 0, sizeof(t_FmIpcResourceAllocParams));
64862 + ipcAllocParams.guestId = p_Fm->guestId;
64863 + ipcAllocParams.num = p_Fm->partNumOfVSPs;
64864 + ipcAllocParams.base = p_Fm->partVSPBase;
64865 + msg.msgId = FM_VSP_ALLOC;
64866 + memcpy(msg.msgBody, &ipcAllocParams, sizeof(t_FmIpcResourceAllocParams));
64867 + replyLength = sizeof(uint32_t) + sizeof(uint8_t);
64868 + err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0],
64869 + (uint8_t*)&msg,
64870 + sizeof(msg.msgId) + sizeof(t_FmIpcResourceAllocParams),
64871 + (uint8_t*)&reply,
64872 + &replyLength,
64873 + NULL,
64874 + NULL);
64875 + if ((err != E_OK) ||
64876 + (replyLength != (sizeof(uint32_t) + sizeof(uint8_t))))
64877 + RETURN_ERROR(MAJOR, err, NO_MSG);
64878 + else
64879 + memcpy((uint8_t*)&p_Fm->partVSPBase, reply.replyBody, sizeof(uint8_t));
64880 + if (p_Fm->partVSPBase == (uint8_t)(ILLEGAL_BASE))
64881 + RETURN_ERROR(MAJOR, err, NO_MSG);
64882 + }
64883 + if (p_Fm->guestId != NCSW_MASTER_ID)
64884 + {
64885 + DBG(WARNING, ("FM Guest mode, without IPC - can't validate VSP range!"));
64886 + return (uint8_t)ILLEGAL_BASE;
64887 + }
64888 +
64889 + intFlags = XX_LockIntrSpinlock(p_Fm->h_Spinlock);
64890 + for (i = base; i < base + numOfProfiles; i++)
64891 + if (p_Fm->p_FmSp->profiles[i].profilesMng.ownerId == (uint8_t)ILLEGAL_BASE)
64892 + profilesFound++;
64893 + else
64894 + break;
64895 +
64896 + if (profilesFound == numOfProfiles)
64897 + for (i = base; i<base + numOfProfiles; i++)
64898 + p_Fm->p_FmSp->profiles[i].profilesMng.ownerId = guestId;
64899 + else
64900 + {
64901 + XX_UnlockIntrSpinlock(p_Fm->h_Spinlock, intFlags);
64902 + return (uint8_t)ILLEGAL_BASE;
64903 + }
64904 + XX_UnlockIntrSpinlock(p_Fm->h_Spinlock, intFlags);
64905 +
64906 + return base;
64907 +}
64908 +
64909 +static void FreeVSPsForPartition(t_Handle h_Fm, uint8_t base, uint8_t numOfProfiles, uint8_t guestId)
64910 +{
64911 + t_Fm *p_Fm = (t_Fm *)h_Fm;
64912 + int i = 0;
64913 +
64914 + ASSERT_COND(p_Fm);
64915 +
64916 + if (p_Fm->h_IpcSessions[0])
64917 + {
64918 + t_FmIpcResourceAllocParams ipcAllocParams;
64919 + t_FmIpcMsg msg;
64920 + t_FmIpcReply reply;
64921 + uint32_t replyLength;
64922 + t_Error err;
64923 +
64924 + memset(&msg, 0, sizeof(msg));
64925 + memset(&reply, 0, sizeof(reply));
64926 + memset(&ipcAllocParams, 0, sizeof(t_FmIpcResourceAllocParams));
64927 + ipcAllocParams.guestId = p_Fm->guestId;
64928 + ipcAllocParams.num = p_Fm->partNumOfVSPs;
64929 + ipcAllocParams.base = p_Fm->partVSPBase;
64930 + msg.msgId = FM_VSP_FREE;
64931 + memcpy(msg.msgBody, &ipcAllocParams, sizeof(t_FmIpcResourceAllocParams));
64932 + replyLength = sizeof(uint32_t) + sizeof(uint8_t);
64933 + err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0],
64934 + (uint8_t*)&msg,
64935 + sizeof(msg.msgId) + sizeof(t_FmIpcResourceAllocParams),
64936 + (uint8_t*)&reply,
64937 + &replyLength,
64938 + NULL,
64939 + NULL);
64940 + if (err != E_OK)
64941 + REPORT_ERROR(MAJOR, err, NO_MSG);
64942 + return;
64943 + }
64944 + if (p_Fm->guestId != NCSW_MASTER_ID)
64945 + {
64946 + DBG(WARNING, ("FM Guest mode, without IPC - can't validate VSP range!"));
64947 + return;
64948 + }
64949 +
64950 + ASSERT_COND(p_Fm->p_FmSp);
64951 +
64952 + for (i=base; i<numOfProfiles; i++)
64953 + {
64954 + if (p_Fm->p_FmSp->profiles[i].profilesMng.ownerId == guestId)
64955 + p_Fm->p_FmSp->profiles[i].profilesMng.ownerId = (uint8_t)ILLEGAL_BASE;
64956 + else
64957 + DBG(WARNING, ("Request for freeing storage profile window which wasn't allocated to this partition"));
64958 + }
64959 +}
64960 +#endif /* (DPAA_VERSION >= 11) */
64961 +
64962 +static t_Error FmGuestHandleIpcMsgCB(t_Handle h_Fm,
64963 + uint8_t *p_Msg,
64964 + uint32_t msgLength,
64965 + uint8_t *p_Reply,
64966 + uint32_t *p_ReplyLength)
64967 +{
64968 + t_Fm *p_Fm = (t_Fm*)h_Fm;
64969 + t_FmIpcMsg *p_IpcMsg = (t_FmIpcMsg*)p_Msg;
64970 +
64971 + UNUSED(p_Reply);
64972 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
64973 + SANITY_CHECK_RETURN_ERROR((msgLength > sizeof(uint32_t)), E_INVALID_VALUE);
64974 +
64975 +#ifdef DISABLE_SANITY_CHECKS
64976 + UNUSED(msgLength);
64977 +#endif /* DISABLE_SANITY_CHECKS */
64978 +
64979 + ASSERT_COND(p_Msg);
64980 +
64981 + *p_ReplyLength = 0;
64982 +
64983 + switch (p_IpcMsg->msgId)
64984 + {
64985 + case (FM_GUEST_ISR):
64986 + {
64987 + t_FmIpcIsr ipcIsr;
64988 +
64989 + memcpy((uint8_t*)&ipcIsr, p_IpcMsg->msgBody, sizeof(t_FmIpcIsr));
64990 + if (ipcIsr.boolErr)
64991 + GuestErrorIsr(p_Fm, ipcIsr.pendingReg);
64992 + else
64993 + GuestEventIsr(p_Fm, ipcIsr.pendingReg);
64994 + break;
64995 + }
64996 + default:
64997 + *p_ReplyLength = 0;
64998 + RETURN_ERROR(MINOR, E_INVALID_SELECTION, ("command not found!!!"));
64999 + }
65000 + return E_OK;
65001 +}
65002 +
65003 +static t_Error FmHandleIpcMsgCB(t_Handle h_Fm,
65004 + uint8_t *p_Msg,
65005 + uint32_t msgLength,
65006 + uint8_t *p_Reply,
65007 + uint32_t *p_ReplyLength)
65008 +{
65009 + t_Error err;
65010 + t_Fm *p_Fm = (t_Fm*)h_Fm;
65011 + t_FmIpcMsg *p_IpcMsg = (t_FmIpcMsg*)p_Msg;
65012 + t_FmIpcReply *p_IpcReply = (t_FmIpcReply*)p_Reply;
65013 +
65014 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
65015 + SANITY_CHECK_RETURN_ERROR((msgLength >= sizeof(uint32_t)), E_INVALID_VALUE);
65016 +
65017 +#ifdef DISABLE_SANITY_CHECKS
65018 + UNUSED(msgLength);
65019 +#endif /* DISABLE_SANITY_CHECKS */
65020 +
65021 + ASSERT_COND(p_IpcMsg);
65022 +
65023 + memset(p_IpcReply, 0, (sizeof(uint8_t) * FM_IPC_MAX_REPLY_SIZE));
65024 + *p_ReplyLength = 0;
65025 +
65026 + switch (p_IpcMsg->msgId)
65027 + {
65028 + case (FM_GET_SET_PORT_PARAMS):
65029 + {
65030 + t_FmIpcPortInInitParams ipcInitParams;
65031 + t_FmInterModulePortInitParams initParams;
65032 + t_FmIpcPortOutInitParams ipcOutInitParams;
65033 +
65034 + memcpy((uint8_t*)&ipcInitParams, p_IpcMsg->msgBody, sizeof(t_FmIpcPortInInitParams));
65035 + initParams.hardwarePortId = ipcInitParams.hardwarePortId;
65036 + initParams.portType = (e_FmPortType)ipcInitParams.enumPortType;
65037 + initParams.independentMode = (bool)(ipcInitParams.boolIndependentMode);
65038 + initParams.liodnOffset = ipcInitParams.liodnOffset;
65039 + initParams.numOfTasks = ipcInitParams.numOfTasks;
65040 + initParams.numOfExtraTasks = ipcInitParams.numOfExtraTasks;
65041 + initParams.numOfOpenDmas = ipcInitParams.numOfOpenDmas;
65042 + initParams.numOfExtraOpenDmas = ipcInitParams.numOfExtraOpenDmas;
65043 + initParams.sizeOfFifo = ipcInitParams.sizeOfFifo;
65044 + initParams.extraSizeOfFifo = ipcInitParams.extraSizeOfFifo;
65045 + initParams.deqPipelineDepth = ipcInitParams.deqPipelineDepth;
65046 + initParams.maxFrameLength = ipcInitParams.maxFrameLength;
65047 + initParams.liodnBase = ipcInitParams.liodnBase;
65048 +
65049 + p_IpcReply->error = (uint32_t)FmGetSetPortParams(h_Fm, &initParams);
65050 +
65051 + ipcOutInitParams.ipcPhysAddr.high = initParams.fmMuramPhysBaseAddr.high;
65052 + ipcOutInitParams.ipcPhysAddr.low = initParams.fmMuramPhysBaseAddr.low;
65053 + ipcOutInitParams.sizeOfFifo = initParams.sizeOfFifo;
65054 + ipcOutInitParams.extraSizeOfFifo = initParams.extraSizeOfFifo;
65055 + ipcOutInitParams.numOfTasks = initParams.numOfTasks;
65056 + ipcOutInitParams.numOfExtraTasks = initParams.numOfExtraTasks;
65057 + ipcOutInitParams.numOfOpenDmas = initParams.numOfOpenDmas;
65058 + ipcOutInitParams.numOfExtraOpenDmas = initParams.numOfExtraOpenDmas;
65059 + memcpy(p_IpcReply->replyBody, (uint8_t*)&ipcOutInitParams, sizeof(ipcOutInitParams));
65060 + *p_ReplyLength = sizeof(uint32_t) + sizeof(t_FmIpcPortOutInitParams);
65061 + break;
65062 + }
65063 + case (FM_SET_SIZE_OF_FIFO):
65064 + {
65065 + t_FmIpcPortRsrcParams ipcPortRsrcParams;
65066 +
65067 + memcpy((uint8_t*)&ipcPortRsrcParams, p_IpcMsg->msgBody, sizeof(t_FmIpcPortRsrcParams));
65068 + p_IpcReply->error = (uint32_t)FmSetSizeOfFifo(h_Fm,
65069 + ipcPortRsrcParams.hardwarePortId,
65070 + &ipcPortRsrcParams.val,
65071 + &ipcPortRsrcParams.extra,
65072 + (bool)ipcPortRsrcParams.boolInitialConfig);
65073 + *p_ReplyLength = sizeof(uint32_t);
65074 + break;
65075 + }
65076 + case (FM_SET_NUM_OF_TASKS):
65077 + {
65078 + t_FmIpcPortRsrcParams ipcPortRsrcParams;
65079 +
65080 + memcpy((uint8_t*)&ipcPortRsrcParams, p_IpcMsg->msgBody, sizeof(t_FmIpcPortRsrcParams));
65081 + p_IpcReply->error = (uint32_t)FmSetNumOfTasks(h_Fm, ipcPortRsrcParams.hardwarePortId,
65082 + (uint8_t*)&ipcPortRsrcParams.val,
65083 + (uint8_t*)&ipcPortRsrcParams.extra,
65084 + (bool)ipcPortRsrcParams.boolInitialConfig);
65085 + *p_ReplyLength = sizeof(uint32_t);
65086 + break;
65087 + }
65088 + case (FM_SET_NUM_OF_OPEN_DMAS):
65089 + {
65090 + t_FmIpcPortRsrcParams ipcPortRsrcParams;
65091 +
65092 + memcpy((uint8_t*)&ipcPortRsrcParams, p_IpcMsg->msgBody, sizeof(t_FmIpcPortRsrcParams));
65093 + p_IpcReply->error = (uint32_t)FmSetNumOfOpenDmas(h_Fm, ipcPortRsrcParams.hardwarePortId,
65094 + (uint8_t*)&ipcPortRsrcParams.val,
65095 + (uint8_t*)&ipcPortRsrcParams.extra,
65096 + (bool)ipcPortRsrcParams.boolInitialConfig);
65097 + *p_ReplyLength = sizeof(uint32_t);
65098 + break;
65099 + }
65100 + case (FM_RESUME_STALLED_PORT):
65101 + *p_ReplyLength = sizeof(uint32_t);
65102 + p_IpcReply->error = (uint32_t)FmResumeStalledPort(h_Fm, p_IpcMsg->msgBody[0]);
65103 + break;
65104 + case (FM_MASTER_IS_ALIVE):
65105 + {
65106 + uint8_t guestId = p_IpcMsg->msgBody[0];
65107 + /* build the FM master partition IPC address */
65108 + memset(p_Fm->fmIpcHandlerModuleName[guestId], 0, (sizeof(char)) * MODULE_NAME_SIZE);
65109 + if (Sprint (p_Fm->fmIpcHandlerModuleName[guestId], "FM_%d_%d",p_Fm->p_FmStateStruct->fmId, guestId) != (guestId<10 ? 6:7))
65110 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Sprint failed"));
65111 + p_Fm->h_IpcSessions[guestId] = XX_IpcInitSession(p_Fm->fmIpcHandlerModuleName[guestId], p_Fm->fmModuleName);
65112 + if (p_Fm->h_IpcSessions[guestId] == NULL)
65113 + RETURN_ERROR(MAJOR, E_NOT_AVAILABLE, ("FM Master IPC session for guest %d", guestId));
65114 + *(uint8_t*)(p_IpcReply->replyBody) = 1;
65115 + *p_ReplyLength = sizeof(uint32_t) + sizeof(uint8_t);
65116 + break;
65117 + }
65118 + case (FM_IS_PORT_STALLED):
65119 + {
65120 + bool tmp;
65121 +
65122 + p_IpcReply->error = (uint32_t)FmIsPortStalled(h_Fm, p_IpcMsg->msgBody[0], &tmp);
65123 + *(uint8_t*)(p_IpcReply->replyBody) = (uint8_t)tmp;
65124 + *p_ReplyLength = sizeof(uint32_t) + sizeof(uint8_t);
65125 + break;
65126 + }
65127 + case (FM_RESET_MAC):
65128 + {
65129 + t_FmIpcMacParams ipcMacParams;
65130 +
65131 + memcpy((uint8_t*)&ipcMacParams, p_IpcMsg->msgBody, sizeof(t_FmIpcMacParams));
65132 + p_IpcReply->error = (uint32_t)FmResetMac(p_Fm,
65133 + (e_FmMacType)(ipcMacParams.enumType),
65134 + ipcMacParams.id);
65135 + *p_ReplyLength = sizeof(uint32_t);
65136 + break;
65137 + }
65138 + case (FM_SET_MAC_MAX_FRAME):
65139 + {
65140 + t_FmIpcMacMaxFrameParams ipcMacMaxFrameParams;
65141 +
65142 + memcpy((uint8_t*)&ipcMacMaxFrameParams, p_IpcMsg->msgBody, sizeof(t_FmIpcMacMaxFrameParams));
65143 + err = FmSetMacMaxFrame(p_Fm,
65144 + (e_FmMacType)(ipcMacMaxFrameParams.macParams.enumType),
65145 + ipcMacMaxFrameParams.macParams.id,
65146 + ipcMacMaxFrameParams.maxFrameLength);
65147 + if (err != E_OK)
65148 + REPORT_ERROR(MINOR, err, NO_MSG);
65149 + break;
65150 + }
65151 +#if (DPAA_VERSION >= 11)
65152 + case (FM_VSP_ALLOC) :
65153 + {
65154 + t_FmIpcResourceAllocParams ipcAllocParams;
65155 + uint8_t vspBase;
65156 + memcpy(&ipcAllocParams, p_IpcMsg->msgBody, sizeof(t_FmIpcResourceAllocParams));
65157 + vspBase = AllocVSPsForPartition(h_Fm, (uint8_t)ipcAllocParams.base, (uint8_t)ipcAllocParams.num, ipcAllocParams.guestId);
65158 + memcpy(p_IpcReply->replyBody, (uint8_t*)&vspBase, sizeof(uint8_t));
65159 + *p_ReplyLength = sizeof(uint32_t) + sizeof(uint8_t);
65160 + break;
65161 + }
65162 + case (FM_VSP_FREE) :
65163 + {
65164 + t_FmIpcResourceAllocParams ipcAllocParams;
65165 + memcpy(&ipcAllocParams, p_IpcMsg->msgBody, sizeof(t_FmIpcResourceAllocParams));
65166 + FreeVSPsForPartition(h_Fm, (uint8_t)ipcAllocParams.base, (uint8_t)ipcAllocParams.num, ipcAllocParams.guestId);
65167 + break;
65168 + }
65169 + case (FM_VSP_SET_PORT_WINDOW) :
65170 + {
65171 + t_FmIpcVspSetPortWindow ipcVspSetPortWindow;
65172 + memcpy(&ipcVspSetPortWindow, p_IpcMsg->msgBody, sizeof(t_FmIpcVspSetPortWindow));
65173 + err = SetVSPWindow(h_Fm,
65174 + ipcVspSetPortWindow.hardwarePortId,
65175 + ipcVspSetPortWindow.baseStorageProfile,
65176 + ipcVspSetPortWindow.log2NumOfProfiles);
65177 + return err;
65178 + }
65179 + case (FM_SET_CONG_GRP_PFC_PRIO) :
65180 + {
65181 + t_FmIpcSetCongestionGroupPfcPriority fmIpcSetCongestionGroupPfcPriority;
65182 + memcpy(&fmIpcSetCongestionGroupPfcPriority, p_IpcMsg->msgBody, sizeof(t_FmIpcSetCongestionGroupPfcPriority));
65183 + err = FmSetCongestionGroupPFCpriority(h_Fm,
65184 + fmIpcSetCongestionGroupPfcPriority.congestionGroupId,
65185 + fmIpcSetCongestionGroupPfcPriority.priorityBitMap);
65186 + return err;
65187 + }
65188 +#endif /* (DPAA_VERSION >= 11) */
65189 +
65190 + case (FM_FREE_PORT):
65191 + {
65192 + t_FmInterModulePortFreeParams portParams;
65193 + t_FmIpcPortFreeParams ipcPortParams;
65194 +
65195 + memcpy((uint8_t*)&ipcPortParams, p_IpcMsg->msgBody, sizeof(t_FmIpcPortFreeParams));
65196 + portParams.hardwarePortId = ipcPortParams.hardwarePortId;
65197 + portParams.portType = (e_FmPortType)(ipcPortParams.enumPortType);
65198 + portParams.deqPipelineDepth = ipcPortParams.deqPipelineDepth;
65199 + FmFreePortParams(h_Fm, &portParams);
65200 + break;
65201 + }
65202 + case (FM_REGISTER_INTR):
65203 + {
65204 + t_FmIpcRegisterIntr ipcRegIntr;
65205 +
65206 + memcpy((uint8_t*)&ipcRegIntr, p_IpcMsg->msgBody, sizeof(ipcRegIntr));
65207 + p_Fm->intrMng[ipcRegIntr.event].guestId = ipcRegIntr.guestId;
65208 + break;
65209 + }
65210 + case (FM_GET_PARAMS):
65211 + {
65212 + t_FmIpcParams ipcParams;
65213 +
65214 + /* Get clock frequency */
65215 + ipcParams.fmClkFreq = p_Fm->p_FmStateStruct->fmClkFreq;
65216 + ipcParams.fmMacClkFreq = p_Fm->p_FmStateStruct->fmMacClkFreq;
65217 +
65218 + fman_get_revision(p_Fm->p_FmFpmRegs,&ipcParams.majorRev,&ipcParams.minorRev);
65219 +
65220 + memcpy(p_IpcReply->replyBody, (uint8_t*)&ipcParams, sizeof(t_FmIpcParams));
65221 + *p_ReplyLength = sizeof(uint32_t) + sizeof(t_FmIpcParams);
65222 + break;
65223 + }
65224 + case (FM_GET_FMAN_CTRL_CODE_REV):
65225 + {
65226 + t_FmCtrlCodeRevisionInfo fmanCtrlRevInfo;
65227 + t_FmIpcFmanCtrlCodeRevisionInfo ipcRevInfo;
65228 +
65229 + p_IpcReply->error = (uint32_t)FM_GetFmanCtrlCodeRevision(h_Fm, &fmanCtrlRevInfo);
65230 + ipcRevInfo.packageRev = fmanCtrlRevInfo.packageRev;
65231 + ipcRevInfo.majorRev = fmanCtrlRevInfo.majorRev;
65232 + ipcRevInfo.minorRev = fmanCtrlRevInfo.minorRev;
65233 + memcpy(p_IpcReply->replyBody, (uint8_t*)&ipcRevInfo, sizeof(t_FmIpcFmanCtrlCodeRevisionInfo));
65234 + *p_ReplyLength = sizeof(uint32_t) + sizeof(t_FmIpcFmanCtrlCodeRevisionInfo);
65235 + break;
65236 + }
65237 +
65238 + case (FM_DMA_STAT):
65239 + {
65240 + t_FmDmaStatus dmaStatus;
65241 + t_FmIpcDmaStatus ipcDmaStatus;
65242 +
65243 + FM_GetDmaStatus(h_Fm, &dmaStatus);
65244 + ipcDmaStatus.boolCmqNotEmpty = (uint8_t)dmaStatus.cmqNotEmpty;
65245 + ipcDmaStatus.boolBusError = (uint8_t)dmaStatus.busError;
65246 + ipcDmaStatus.boolReadBufEccError = (uint8_t)dmaStatus.readBufEccError;
65247 + ipcDmaStatus.boolWriteBufEccSysError = (uint8_t)dmaStatus.writeBufEccSysError;
65248 + ipcDmaStatus.boolWriteBufEccFmError = (uint8_t)dmaStatus.writeBufEccFmError;
65249 + ipcDmaStatus.boolSinglePortEccError = (uint8_t)dmaStatus.singlePortEccError;
65250 + memcpy(p_IpcReply->replyBody, (uint8_t*)&ipcDmaStatus, sizeof(t_FmIpcDmaStatus));
65251 + *p_ReplyLength = sizeof(uint32_t) + sizeof(t_FmIpcDmaStatus);
65252 + break;
65253 + }
65254 + case (FM_ALLOC_FMAN_CTRL_EVENT_REG):
65255 + p_IpcReply->error = (uint32_t)FmAllocFmanCtrlEventReg(h_Fm, (uint8_t*)p_IpcReply->replyBody);
65256 + *p_ReplyLength = sizeof(uint32_t) + sizeof(uint8_t);
65257 + break;
65258 + case (FM_FREE_FMAN_CTRL_EVENT_REG):
65259 + FmFreeFmanCtrlEventReg(h_Fm, p_IpcMsg->msgBody[0]);
65260 + break;
65261 + case (FM_GET_TIMESTAMP_SCALE):
65262 + {
65263 + uint32_t timeStamp = FmGetTimeStampScale(h_Fm);
65264 +
65265 + memcpy(p_IpcReply->replyBody, (uint8_t*)&timeStamp, sizeof(uint32_t));
65266 + *p_ReplyLength = sizeof(uint32_t) + sizeof(uint32_t);
65267 + break;
65268 + }
65269 + case (FM_GET_COUNTER):
65270 + {
65271 + e_FmCounters inCounter;
65272 + uint32_t outCounter;
65273 +
65274 + memcpy((uint8_t*)&inCounter, p_IpcMsg->msgBody, sizeof(uint32_t));
65275 + outCounter = FM_GetCounter(h_Fm, inCounter);
65276 + memcpy(p_IpcReply->replyBody, (uint8_t*)&outCounter, sizeof(uint32_t));
65277 + *p_ReplyLength = sizeof(uint32_t) + sizeof(uint32_t);
65278 + break;
65279 + }
65280 + case (FM_SET_FMAN_CTRL_EVENTS_ENABLE):
65281 + {
65282 + t_FmIpcFmanEvents ipcFmanEvents;
65283 +
65284 + memcpy((uint8_t*)&ipcFmanEvents, p_IpcMsg->msgBody, sizeof(t_FmIpcFmanEvents));
65285 + FmSetFmanCtrlIntr(h_Fm,
65286 + ipcFmanEvents.eventRegId,
65287 + ipcFmanEvents.enableEvents);
65288 + break;
65289 + }
65290 + case (FM_GET_FMAN_CTRL_EVENTS_ENABLE):
65291 + {
65292 + uint32_t tmp = FmGetFmanCtrlIntr(h_Fm, p_IpcMsg->msgBody[0]);
65293 +
65294 + memcpy(p_IpcReply->replyBody, (uint8_t*)&tmp, sizeof(uint32_t));
65295 + *p_ReplyLength = sizeof(uint32_t) + sizeof(uint32_t);
65296 + break;
65297 + }
65298 + case (FM_GET_PHYS_MURAM_BASE):
65299 + {
65300 + t_FmPhysAddr physAddr;
65301 + t_FmIpcPhysAddr ipcPhysAddr;
65302 +
65303 + FmGetPhysicalMuramBase(h_Fm, &physAddr);
65304 + ipcPhysAddr.high = physAddr.high;
65305 + ipcPhysAddr.low = physAddr.low;
65306 + memcpy(p_IpcReply->replyBody, (uint8_t*)&ipcPhysAddr, sizeof(t_FmIpcPhysAddr));
65307 + *p_ReplyLength = sizeof(uint32_t) + sizeof(t_FmIpcPhysAddr);
65308 + break;
65309 + }
65310 + case (FM_ENABLE_RAM_ECC):
65311 + {
65312 + if (((err = FM_EnableRamsEcc(h_Fm)) != E_OK) ||
65313 + ((err = FM_SetException(h_Fm, e_FM_EX_IRAM_ECC, TRUE)) != E_OK) ||
65314 + ((err = FM_SetException(h_Fm, e_FM_EX_MURAM_ECC, TRUE)) != E_OK))
65315 +#if (!(defined(DEBUG_ERRORS)) || (DEBUG_ERRORS == 0))
65316 + UNUSED(err);
65317 +#else
65318 + REPORT_ERROR(MINOR, err, NO_MSG);
65319 +#endif /* (!(defined(DEBUG_ERRORS)) || (DEBUG_ERRORS == 0)) */
65320 + break;
65321 + }
65322 + case (FM_DISABLE_RAM_ECC):
65323 + {
65324 +
65325 + if (((err = FM_SetException(h_Fm, e_FM_EX_IRAM_ECC, FALSE)) != E_OK) ||
65326 + ((err = FM_SetException(h_Fm, e_FM_EX_MURAM_ECC, FALSE)) != E_OK) ||
65327 + ((err = FM_DisableRamsEcc(h_Fm)) != E_OK))
65328 +#if (!(defined(DEBUG_ERRORS)) || (DEBUG_ERRORS == 0))
65329 + UNUSED(err);
65330 +#else
65331 + REPORT_ERROR(MINOR, err, NO_MSG);
65332 +#endif /* (!(defined(DEBUG_ERRORS)) || (DEBUG_ERRORS == 0)) */
65333 + break;
65334 + }
65335 + case (FM_SET_NUM_OF_FMAN_CTRL):
65336 + {
65337 + t_FmIpcPortNumOfFmanCtrls ipcPortNumOfFmanCtrls;
65338 +
65339 + memcpy((uint8_t*)&ipcPortNumOfFmanCtrls, p_IpcMsg->msgBody, sizeof(t_FmIpcPortNumOfFmanCtrls));
65340 + err = FmSetNumOfRiscsPerPort(h_Fm,
65341 + ipcPortNumOfFmanCtrls.hardwarePortId,
65342 + ipcPortNumOfFmanCtrls.numOfFmanCtrls,
65343 + ipcPortNumOfFmanCtrls.orFmanCtrl);
65344 + if (err != E_OK)
65345 + REPORT_ERROR(MINOR, err, NO_MSG);
65346 + break;
65347 + }
65348 +#ifdef FM_TX_ECC_FRMS_ERRATA_10GMAC_A004
65349 + case (FM_10G_TX_ECC_WA):
65350 + p_IpcReply->error = (uint32_t)Fm10GTxEccWorkaround(h_Fm, p_IpcMsg->msgBody[0]);
65351 + *p_ReplyLength = sizeof(uint32_t);
65352 + break;
65353 +#endif /* FM_TX_ECC_FRMS_ERRATA_10GMAC_A004 */
65354 + default:
65355 + *p_ReplyLength = 0;
65356 + RETURN_ERROR(MINOR, E_INVALID_SELECTION, ("command not found!!!"));
65357 + }
65358 + return E_OK;
65359 +}
65360 +
65361 +
65362 +/****************************************/
65363 +/* Inter-Module functions */
65364 +/****************************************/
65365 +#ifdef FM_TX_ECC_FRMS_ERRATA_10GMAC_A004
65366 +t_Error Fm10GTxEccWorkaround(t_Handle h_Fm, uint8_t macId)
65367 +{
65368 + t_Fm *p_Fm = (t_Fm*)h_Fm;
65369 + t_Error err = E_OK;
65370 + t_FmIpcMsg msg;
65371 + t_FmIpcReply reply;
65372 + uint32_t replyLength;
65373 + uint8_t rxHardwarePortId, txHardwarePortId;
65374 + struct fman_fpm_regs *fpm_rg = p_Fm->p_FmFpmRegs;
65375 +
65376 + if (p_Fm->guestId != NCSW_MASTER_ID)
65377 + {
65378 + memset(&msg, 0, sizeof(msg));
65379 + memset(&reply, 0, sizeof(reply));
65380 + msg.msgId = FM_10G_TX_ECC_WA;
65381 + msg.msgBody[0] = macId;
65382 + replyLength = sizeof(uint32_t);
65383 + if ((err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0],
65384 + (uint8_t*)&msg,
65385 + sizeof(msg.msgId)+sizeof(macId),
65386 + (uint8_t*)&reply,
65387 + &replyLength,
65388 + NULL,
65389 + NULL)) != E_OK)
65390 + RETURN_ERROR(MINOR, err, NO_MSG);
65391 + if (replyLength != sizeof(uint32_t))
65392 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch"));
65393 + return (t_Error)(reply.error);
65394 + }
65395 +
65396 + SANITY_CHECK_RETURN_ERROR((macId == 0), E_NOT_SUPPORTED);
65397 + SANITY_CHECK_RETURN_ERROR(IsFmanCtrlCodeLoaded(p_Fm), E_INVALID_STATE);
65398 +
65399 + rxHardwarePortId = SwPortIdToHwPortId(e_FM_PORT_TYPE_RX_10G,
65400 + macId,
65401 + p_Fm->p_FmStateStruct->revInfo.majorRev,
65402 + p_Fm->p_FmStateStruct->revInfo.minorRev);
65403 + txHardwarePortId = SwPortIdToHwPortId(e_FM_PORT_TYPE_TX_10G,
65404 + macId,
65405 + p_Fm->p_FmStateStruct->revInfo.majorRev,
65406 + p_Fm->p_FmStateStruct->revInfo.minorRev);
65407 + if ((p_Fm->p_FmStateStruct->portsTypes[rxHardwarePortId] != e_FM_PORT_TYPE_DUMMY) ||
65408 + (p_Fm->p_FmStateStruct->portsTypes[txHardwarePortId] != e_FM_PORT_TYPE_DUMMY))
65409 + RETURN_ERROR(MAJOR, E_INVALID_STATE,
65410 + ("MAC should be initialized prior to Rx and Tx ports!"));
65411 +
65412 + return fman_set_erratum_10gmac_a004_wa(fpm_rg);
65413 +}
65414 +#endif /* FM_TX_ECC_FRMS_ERRATA_10GMAC_A004 */
65415 +
65416 +uint16_t FmGetTnumAgingPeriod(t_Handle h_Fm)
65417 +{
65418 + t_Fm *p_Fm = (t_Fm *)h_Fm;
65419 +
65420 + SANITY_CHECK_RETURN_VALUE(p_Fm, E_INVALID_HANDLE, 0);
65421 + SANITY_CHECK_RETURN_VALUE(!p_Fm->p_FmDriverParam, E_INVALID_STATE, 0);
65422 +
65423 + return p_Fm->tnumAgingPeriod;
65424 +}
65425 +
65426 +t_Error FmSetPortPreFetchConfiguration(t_Handle h_Fm,
65427 + uint8_t portNum,
65428 + bool preFetchConfigured)
65429 +{
65430 + t_Fm *p_Fm = (t_Fm*)h_Fm;
65431 +
65432 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
65433 + SANITY_CHECK_RETURN_ERROR(!p_Fm->p_FmDriverParam, E_INVALID_STATE);
65434 +
65435 + p_Fm->portsPreFetchConfigured[portNum] = TRUE;
65436 + p_Fm->portsPreFetchValue[portNum] = preFetchConfigured;
65437 +
65438 + return E_OK;
65439 +}
65440 +
65441 +t_Error FmGetPortPreFetchConfiguration(t_Handle h_Fm,
65442 + uint8_t portNum,
65443 + bool *p_PortConfigured,
65444 + bool *p_PreFetchConfigured)
65445 +{
65446 + t_Fm *p_Fm = (t_Fm*)h_Fm;
65447 +
65448 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
65449 + SANITY_CHECK_RETURN_ERROR(!p_Fm->p_FmDriverParam, E_INVALID_STATE);
65450 +
65451 + /* If the prefetch wasn't configured yet (not enable or disabled)
65452 + we return the value TRUE as it was already configured */
65453 + if (!p_Fm->portsPreFetchConfigured[portNum])
65454 + {
65455 + *p_PortConfigured = FALSE;
65456 + *p_PreFetchConfigured = FALSE;
65457 + }
65458 + else
65459 + {
65460 + *p_PortConfigured = TRUE;
65461 + *p_PreFetchConfigured = (p_Fm->portsPreFetchConfigured[portNum]);
65462 + }
65463 +
65464 + return E_OK;
65465 +}
65466 +
65467 +t_Error FmSetCongestionGroupPFCpriority(t_Handle h_Fm,
65468 + uint32_t congestionGroupId,
65469 + uint8_t priorityBitMap)
65470 +{
65471 + t_Fm *p_Fm = (t_Fm *)h_Fm;
65472 + uint32_t regNum;
65473 +
65474 + ASSERT_COND(h_Fm);
65475 +
65476 + if (congestionGroupId > FM_PORT_NUM_OF_CONGESTION_GRPS)
65477 + RETURN_ERROR(MAJOR, E_INVALID_VALUE,
65478 + ("Congestion group ID bigger than %d",
65479 + FM_PORT_NUM_OF_CONGESTION_GRPS));
65480 +
65481 + if (p_Fm->guestId == NCSW_MASTER_ID)
65482 + {
65483 + ASSERT_COND(p_Fm->baseAddr);
65484 + regNum = (FM_PORT_NUM_OF_CONGESTION_GRPS - 1 - congestionGroupId) / 4;
65485 + fman_set_congestion_group_pfc_priority((uint32_t *)((p_Fm->baseAddr+FM_MM_CGP)),
65486 + congestionGroupId,
65487 + priorityBitMap,
65488 + regNum);
65489 + }
65490 + else if (p_Fm->h_IpcSessions[0])
65491 + {
65492 + t_Error err;
65493 + t_FmIpcMsg msg;
65494 + t_FmIpcSetCongestionGroupPfcPriority fmIpcSetCongestionGroupPfcPriority;
65495 +
65496 + memset(&msg, 0, sizeof(msg));
65497 + memset(&fmIpcSetCongestionGroupPfcPriority, 0, sizeof(t_FmIpcSetCongestionGroupPfcPriority));
65498 + fmIpcSetCongestionGroupPfcPriority.congestionGroupId = congestionGroupId;
65499 + fmIpcSetCongestionGroupPfcPriority.priorityBitMap = priorityBitMap;
65500 +
65501 + msg.msgId = FM_SET_CONG_GRP_PFC_PRIO;
65502 + memcpy(msg.msgBody, &fmIpcSetCongestionGroupPfcPriority, sizeof(t_FmIpcSetCongestionGroupPfcPriority));
65503 +
65504 + err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0],
65505 + (uint8_t*)&msg,
65506 + sizeof(msg.msgId),
65507 + NULL,
65508 + NULL,
65509 + NULL,
65510 + NULL);
65511 + if (err != E_OK)
65512 + RETURN_ERROR(MINOR, err, NO_MSG);
65513 + }
65514 + else
65515 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("guest without IPC!"));
65516 +
65517 + return E_OK;
65518 +}
65519 +
65520 +uintptr_t FmGetPcdPrsBaseAddr(t_Handle h_Fm)
65521 +{
65522 + t_Fm *p_Fm = (t_Fm*)h_Fm;
65523 +
65524 + SANITY_CHECK_RETURN_VALUE(p_Fm, E_INVALID_HANDLE, 0);
65525 +
65526 + if (!p_Fm->baseAddr)
65527 + {
65528 + REPORT_ERROR(MAJOR, E_INVALID_STATE,
65529 + ("No base-addr; probably Guest with IPC!"));
65530 + return 0;
65531 + }
65532 +
65533 + return (p_Fm->baseAddr + FM_MM_PRS);
65534 +}
65535 +
65536 +uintptr_t FmGetPcdKgBaseAddr(t_Handle h_Fm)
65537 +{
65538 + t_Fm *p_Fm = (t_Fm*)h_Fm;
65539 +
65540 + SANITY_CHECK_RETURN_VALUE(p_Fm, E_INVALID_HANDLE, 0);
65541 +
65542 + if (!p_Fm->baseAddr)
65543 + {
65544 + REPORT_ERROR(MAJOR, E_INVALID_STATE,
65545 + ("No base-addr; probably Guest with IPC!"));
65546 + return 0;
65547 + }
65548 +
65549 + return (p_Fm->baseAddr + FM_MM_KG);
65550 +}
65551 +
65552 +uintptr_t FmGetPcdPlcrBaseAddr(t_Handle h_Fm)
65553 +{
65554 + t_Fm *p_Fm = (t_Fm*)h_Fm;
65555 +
65556 + SANITY_CHECK_RETURN_VALUE(p_Fm, E_INVALID_HANDLE, 0);
65557 +
65558 + if (!p_Fm->baseAddr)
65559 + {
65560 + REPORT_ERROR(MAJOR, E_INVALID_STATE,
65561 + ("No base-addr; probably Guest with IPC!"));
65562 + return 0;
65563 + }
65564 +
65565 + return (p_Fm->baseAddr + FM_MM_PLCR);
65566 +}
65567 +
65568 +#if (DPAA_VERSION >= 11)
65569 +uintptr_t FmGetVSPBaseAddr(t_Handle h_Fm)
65570 +{
65571 + t_Fm *p_Fm = (t_Fm*)h_Fm;
65572 +
65573 + SANITY_CHECK_RETURN_VALUE(p_Fm, E_INVALID_HANDLE, 0);
65574 +
65575 + return p_Fm->vspBaseAddr;
65576 +}
65577 +#endif /* (DPAA_VERSION >= 11) */
65578 +
65579 +t_Handle FmGetMuramHandle(t_Handle h_Fm)
65580 +{
65581 + t_Fm *p_Fm = (t_Fm*)h_Fm;
65582 +
65583 + SANITY_CHECK_RETURN_VALUE(p_Fm, E_INVALID_HANDLE, NULL);
65584 +
65585 + return (p_Fm->h_FmMuram);
65586 +}
65587 +
65588 +void FmGetPhysicalMuramBase(t_Handle h_Fm, t_FmPhysAddr *p_FmPhysAddr)
65589 +{
65590 + t_Fm *p_Fm = (t_Fm*)h_Fm;
65591 +
65592 + if (p_Fm->fmMuramPhysBaseAddr)
65593 + {
65594 + /* General FM driver initialization */
65595 + p_FmPhysAddr->low = (uint32_t)p_Fm->fmMuramPhysBaseAddr;
65596 + p_FmPhysAddr->high = (uint8_t)((p_Fm->fmMuramPhysBaseAddr & 0x000000ff00000000LL) >> 32);
65597 + return;
65598 + }
65599 +
65600 + ASSERT_COND(p_Fm->guestId != NCSW_MASTER_ID);
65601 +
65602 + if (p_Fm->h_IpcSessions[0])
65603 + {
65604 + t_Error err;
65605 + t_FmIpcMsg msg;
65606 + t_FmIpcReply reply;
65607 + uint32_t replyLength;
65608 + t_FmIpcPhysAddr ipcPhysAddr;
65609 +
65610 + memset(&msg, 0, sizeof(msg));
65611 + memset(&reply, 0, sizeof(reply));
65612 + msg.msgId = FM_GET_PHYS_MURAM_BASE;
65613 + replyLength = sizeof(uint32_t) + sizeof(t_FmPhysAddr);
65614 + err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0],
65615 + (uint8_t*)&msg,
65616 + sizeof(msg.msgId),
65617 + (uint8_t*)&reply,
65618 + &replyLength,
65619 + NULL,
65620 + NULL);
65621 + if (err != E_OK)
65622 + {
65623 + REPORT_ERROR(MINOR, err, NO_MSG);
65624 + return;
65625 + }
65626 + if (replyLength != (sizeof(uint32_t) + sizeof(t_FmPhysAddr)))
65627 + {
65628 + REPORT_ERROR(MINOR, E_INVALID_VALUE,("IPC reply length mismatch"));
65629 + return;
65630 + }
65631 + memcpy((uint8_t*)&ipcPhysAddr, reply.replyBody, sizeof(t_FmIpcPhysAddr));
65632 + p_FmPhysAddr->high = ipcPhysAddr.high;
65633 + p_FmPhysAddr->low = ipcPhysAddr.low;
65634 + }
65635 + else
65636 + REPORT_ERROR(MINOR, E_NOT_SUPPORTED,
65637 + ("running in guest-mode without neither IPC nor mapped register!"));
65638 +}
65639 +
65640 +#if (DPAA_VERSION >= 11)
65641 +t_Error FmVSPAllocForPort (t_Handle h_Fm,
65642 + e_FmPortType portType,
65643 + uint8_t portId,
65644 + uint8_t numOfVSPs)
65645 +{
65646 + t_Fm *p_Fm = (t_Fm *)h_Fm;
65647 + t_Error err = E_OK;
65648 + uint32_t profilesFound, intFlags;
65649 + uint8_t first, i;
65650 + uint8_t log2Num;
65651 + uint8_t swPortIndex=0, hardwarePortId;
65652 +
65653 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
65654 +
65655 + if (!numOfVSPs)
65656 + return E_OK;
65657 +
65658 + if (numOfVSPs > FM_VSP_MAX_NUM_OF_ENTRIES)
65659 + RETURN_ERROR(MINOR, E_INVALID_VALUE, ("numProfiles can not be bigger than %d.",FM_VSP_MAX_NUM_OF_ENTRIES));
65660 +
65661 + if (!POWER_OF_2(numOfVSPs))
65662 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("numProfiles must be a power of 2."));
65663 +
65664 + LOG2((uint64_t)numOfVSPs, log2Num);
65665 +
65666 + if ((log2Num == 0) || (p_Fm->partVSPBase == 0))
65667 + first = 0;
65668 + else
65669 + first = 1<<log2Num;
65670 +
65671 + if (first > (p_Fm->partVSPBase + p_Fm->partNumOfVSPs))
65672 + RETURN_ERROR(MINOR, E_INVALID_VALUE, ("can not allocate storage profile port window"));
65673 +
65674 + if (first < p_Fm->partVSPBase)
65675 + while (first < p_Fm->partVSPBase)
65676 + first = first + numOfVSPs;
65677 +
65678 + if ((first + numOfVSPs) > (p_Fm->partVSPBase + p_Fm->partNumOfVSPs))
65679 + RETURN_ERROR(MINOR, E_INVALID_VALUE, ("can not allocate storage profile port window"));
65680 +
65681 + intFlags = XX_LockIntrSpinlock(p_Fm->h_Spinlock);
65682 + profilesFound = 0;
65683 + for (i=first; i < p_Fm->partVSPBase + p_Fm->partNumOfVSPs; )
65684 + {
65685 + if (!p_Fm->p_FmSp->profiles[i].profilesMng.allocated)
65686 + {
65687 + profilesFound++;
65688 + i++;
65689 + if (profilesFound == numOfVSPs)
65690 + break;
65691 + }
65692 + else
65693 + {
65694 + profilesFound = 0;
65695 + /* advance i to the next aligned address */
65696 + first = i = (uint8_t)(first + numOfVSPs);
65697 + }
65698 + }
65699 + if (profilesFound == numOfVSPs)
65700 + for (i = first; i<first + numOfVSPs; i++)
65701 + p_Fm->p_FmSp->profiles[i].profilesMng.allocated = TRUE;
65702 + else
65703 + {
65704 + XX_UnlockIntrSpinlock(p_Fm->h_Spinlock, intFlags);
65705 + RETURN_ERROR(MINOR, E_FULL, ("No profiles."));
65706 + }
65707 +
65708 + hardwarePortId = SwPortIdToHwPortId(portType,
65709 + portId,
65710 + p_Fm->p_FmStateStruct->revInfo.majorRev,
65711 + p_Fm->p_FmStateStruct->revInfo.minorRev);
65712 + HW_PORT_ID_TO_SW_PORT_INDX(swPortIndex, hardwarePortId);
65713 +
65714 + p_Fm->p_FmSp->portsMapping[swPortIndex].numOfProfiles = numOfVSPs;
65715 + p_Fm->p_FmSp->portsMapping[swPortIndex].profilesBase = first;
65716 +
65717 + if ((err = SetVSPWindow(h_Fm,hardwarePortId, first,log2Num)) != E_OK)
65718 + for (i = first; i < first + numOfVSPs; i++)
65719 + p_Fm->p_FmSp->profiles[i].profilesMng.allocated = FALSE;
65720 +
65721 + XX_UnlockIntrSpinlock(p_Fm->h_Spinlock, intFlags);
65722 +
65723 + return err;
65724 +}
65725 +
65726 +t_Error FmVSPFreeForPort(t_Handle h_Fm,
65727 + e_FmPortType portType,
65728 + uint8_t portId)
65729 +{
65730 + t_Fm *p_Fm = (t_Fm *)h_Fm;
65731 + uint8_t swPortIndex=0, hardwarePortId, first, numOfVSPs, i;
65732 + uint32_t intFlags;
65733 +
65734 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
65735 +
65736 + hardwarePortId = SwPortIdToHwPortId(portType,
65737 + portId,
65738 + p_Fm->p_FmStateStruct->revInfo.majorRev,
65739 + p_Fm->p_FmStateStruct->revInfo.minorRev);
65740 + HW_PORT_ID_TO_SW_PORT_INDX(swPortIndex, hardwarePortId);
65741 +
65742 + numOfVSPs = (uint8_t)p_Fm->p_FmSp->portsMapping[swPortIndex].numOfProfiles;
65743 + first = (uint8_t)p_Fm->p_FmSp->portsMapping[swPortIndex].profilesBase;
65744 +
65745 + intFlags = XX_LockIntrSpinlock(p_Fm->h_Spinlock);
65746 + for (i = first; i < first + numOfVSPs; i++)
65747 + p_Fm->p_FmSp->profiles[i].profilesMng.allocated = FALSE;
65748 + XX_UnlockIntrSpinlock(p_Fm->h_Spinlock, intFlags);
65749 +
65750 + p_Fm->p_FmSp->portsMapping[swPortIndex].numOfProfiles = 0;
65751 + p_Fm->p_FmSp->portsMapping[swPortIndex].profilesBase = 0;
65752 +
65753 + return E_OK;
65754 +}
65755 +#endif /* (DPAA_VERSION >= 11) */
65756 +
65757 +t_Error FmAllocFmanCtrlEventReg(t_Handle h_Fm, uint8_t *p_EventId)
65758 +{
65759 + t_Fm *p_Fm = (t_Fm*)h_Fm;
65760 + uint8_t i;
65761 +
65762 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
65763 +
65764 + if ((p_Fm->guestId != NCSW_MASTER_ID) &&
65765 + p_Fm->h_IpcSessions[0])
65766 + {
65767 + t_Error err;
65768 + t_FmIpcMsg msg;
65769 + t_FmIpcReply reply;
65770 + uint32_t replyLength;
65771 +
65772 + memset(&msg, 0, sizeof(msg));
65773 + memset(&reply, 0, sizeof(reply));
65774 + msg.msgId = FM_ALLOC_FMAN_CTRL_EVENT_REG;
65775 + replyLength = sizeof(uint32_t) + sizeof(uint8_t);
65776 + if ((err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0],
65777 + (uint8_t*)&msg,
65778 + sizeof(msg.msgId),
65779 + (uint8_t*)&reply,
65780 + &replyLength,
65781 + NULL,
65782 + NULL)) != E_OK)
65783 + RETURN_ERROR(MAJOR, err, NO_MSG);
65784 +
65785 + if (replyLength != (sizeof(uint32_t) + sizeof(uint8_t)))
65786 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch"));
65787 +
65788 + *p_EventId = *(uint8_t*)(reply.replyBody);
65789 +
65790 + return (t_Error)(reply.error);
65791 + }
65792 + else if (p_Fm->guestId != NCSW_MASTER_ID)
65793 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED,
65794 + ("running in guest-mode without IPC!"));
65795 +
65796 + for (i=0;i<FM_NUM_OF_FMAN_CTRL_EVENT_REGS;i++)
65797 + if (!p_Fm->usedEventRegs[i])
65798 + {
65799 + p_Fm->usedEventRegs[i] = TRUE;
65800 + *p_EventId = i;
65801 + break;
65802 + }
65803 +
65804 + if (i==FM_NUM_OF_FMAN_CTRL_EVENT_REGS)
65805 + RETURN_ERROR(MAJOR, E_BUSY, ("No resource - FMan controller event register."));
65806 +
65807 + return E_OK;
65808 +}
65809 +
65810 +void FmFreeFmanCtrlEventReg(t_Handle h_Fm, uint8_t eventId)
65811 +{
65812 + t_Fm *p_Fm = (t_Fm*)h_Fm;
65813 +
65814 + SANITY_CHECK_RETURN(p_Fm, E_INVALID_HANDLE);
65815 +
65816 + if ((p_Fm->guestId != NCSW_MASTER_ID) &&
65817 + p_Fm->h_IpcSessions[0])
65818 + {
65819 + t_Error err;
65820 + t_FmIpcMsg msg;
65821 +
65822 + memset(&msg, 0, sizeof(msg));
65823 + msg.msgId = FM_FREE_FMAN_CTRL_EVENT_REG;
65824 + msg.msgBody[0] = eventId;
65825 + err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0],
65826 + (uint8_t*)&msg,
65827 + sizeof(msg.msgId)+sizeof(eventId),
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->guestId != NCSW_MASTER_ID)
65837 + {
65838 + REPORT_ERROR(MINOR, E_NOT_SUPPORTED,
65839 + ("running in guest-mode without IPC!"));
65840 + return;
65841 + }
65842 +
65843 + ((t_Fm*)h_Fm)->usedEventRegs[eventId] = FALSE;
65844 +}
65845 +
65846 +void FmSetFmanCtrlIntr(t_Handle h_Fm, uint8_t eventRegId, uint32_t enableEvents)
65847 +{
65848 + t_Fm *p_Fm = (t_Fm*)h_Fm;
65849 + struct fman_fpm_regs *fpm_rg = p_Fm->p_FmFpmRegs;
65850 +
65851 + if ((p_Fm->guestId != NCSW_MASTER_ID) &&
65852 + !p_Fm->p_FmFpmRegs &&
65853 + p_Fm->h_IpcSessions[0])
65854 + {
65855 + t_FmIpcFmanEvents fmanCtrl;
65856 + t_Error err;
65857 + t_FmIpcMsg msg;
65858 +
65859 + fmanCtrl.eventRegId = eventRegId;
65860 + fmanCtrl.enableEvents = enableEvents;
65861 + memset(&msg, 0, sizeof(msg));
65862 + msg.msgId = FM_SET_FMAN_CTRL_EVENTS_ENABLE;
65863 + memcpy(msg.msgBody, &fmanCtrl, sizeof(fmanCtrl));
65864 + err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0],
65865 + (uint8_t*)&msg,
65866 + sizeof(msg.msgId)+sizeof(fmanCtrl),
65867 + NULL,
65868 + NULL,
65869 + NULL,
65870 + NULL);
65871 + if (err != E_OK)
65872 + REPORT_ERROR(MINOR, err, NO_MSG);
65873 + return;
65874 + }
65875 + else if (!p_Fm->p_FmFpmRegs)
65876 + {
65877 + REPORT_ERROR(MINOR, E_NOT_SUPPORTED,
65878 + ("Either IPC or 'baseAddress' is required!"));
65879 + return;
65880 + }
65881 +
65882 + ASSERT_COND(eventRegId < FM_NUM_OF_FMAN_CTRL_EVENT_REGS);
65883 + fman_set_ctrl_intr(fpm_rg, eventRegId, enableEvents);
65884 +}
65885 +
65886 +uint32_t FmGetFmanCtrlIntr(t_Handle h_Fm, uint8_t eventRegId)
65887 +{
65888 + t_Fm *p_Fm = (t_Fm*)h_Fm;
65889 + struct fman_fpm_regs *fpm_rg = p_Fm->p_FmFpmRegs;
65890 +
65891 + if ((p_Fm->guestId != NCSW_MASTER_ID) &&
65892 + !p_Fm->p_FmFpmRegs &&
65893 + p_Fm->h_IpcSessions[0])
65894 + {
65895 + t_Error err;
65896 + t_FmIpcMsg msg;
65897 + t_FmIpcReply reply;
65898 + uint32_t replyLength, ctrlIntr;
65899 +
65900 + memset(&msg, 0, sizeof(msg));
65901 + memset(&reply, 0, sizeof(reply));
65902 + msg.msgId = FM_GET_FMAN_CTRL_EVENTS_ENABLE;
65903 + msg.msgBody[0] = eventRegId;
65904 + replyLength = sizeof(uint32_t) + sizeof(uint32_t);
65905 + err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0],
65906 + (uint8_t*)&msg,
65907 + sizeof(msg.msgId)+sizeof(eventRegId),
65908 + (uint8_t*)&reply,
65909 + &replyLength,
65910 + NULL,
65911 + NULL);
65912 + if (err != E_OK)
65913 + {
65914 + REPORT_ERROR(MINOR, err, NO_MSG);
65915 + return 0;
65916 + }
65917 + if (replyLength != (sizeof(uint32_t) + sizeof(uint32_t)))
65918 + {
65919 + REPORT_ERROR(MINOR, E_INVALID_VALUE, ("IPC reply length mismatch"));
65920 + return 0;
65921 + }
65922 + memcpy((uint8_t*)&ctrlIntr, reply.replyBody, sizeof(uint32_t));
65923 + return ctrlIntr;
65924 + }
65925 + else if (!p_Fm->p_FmFpmRegs)
65926 + {
65927 + REPORT_ERROR(MINOR, E_NOT_SUPPORTED,
65928 + ("Either IPC or 'baseAddress' is required!"));
65929 + return 0;
65930 + }
65931 +
65932 + return fman_get_ctrl_intr(fpm_rg, eventRegId);
65933 +}
65934 +
65935 +void FmRegisterIntr(t_Handle h_Fm,
65936 + e_FmEventModules module,
65937 + uint8_t modId,
65938 + e_FmIntrType intrType,
65939 + void (*f_Isr) (t_Handle h_Arg),
65940 + t_Handle h_Arg)
65941 +{
65942 + t_Fm *p_Fm = (t_Fm*)h_Fm;
65943 + int event = 0;
65944 +
65945 + ASSERT_COND(h_Fm);
65946 +
65947 + GET_FM_MODULE_EVENT(module, modId, intrType, event);
65948 + ASSERT_COND(event < e_FM_EV_DUMMY_LAST);
65949 +
65950 + /* register in local FM structure */
65951 + p_Fm->intrMng[event].f_Isr = f_Isr;
65952 + p_Fm->intrMng[event].h_SrcHandle = h_Arg;
65953 +
65954 + if ((p_Fm->guestId != NCSW_MASTER_ID) &&
65955 + p_Fm->h_IpcSessions[0])
65956 + {
65957 + t_FmIpcRegisterIntr fmIpcRegisterIntr;
65958 + t_Error err;
65959 + t_FmIpcMsg msg;
65960 +
65961 + /* register in Master FM structure */
65962 + fmIpcRegisterIntr.event = (uint32_t)event;
65963 + fmIpcRegisterIntr.guestId = p_Fm->guestId;
65964 + memset(&msg, 0, sizeof(msg));
65965 + msg.msgId = FM_REGISTER_INTR;
65966 + memcpy(msg.msgBody, &fmIpcRegisterIntr, sizeof(fmIpcRegisterIntr));
65967 + err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0],
65968 + (uint8_t*)&msg,
65969 + sizeof(msg.msgId) + sizeof(fmIpcRegisterIntr),
65970 + NULL,
65971 + NULL,
65972 + NULL,
65973 + NULL);
65974 + if (err != E_OK)
65975 + REPORT_ERROR(MINOR, err, NO_MSG);
65976 + }
65977 + else if (p_Fm->guestId != NCSW_MASTER_ID)
65978 + REPORT_ERROR(MINOR, E_NOT_SUPPORTED,
65979 + ("running in guest-mode without IPC!"));
65980 +}
65981 +
65982 +void FmUnregisterIntr(t_Handle h_Fm,
65983 + e_FmEventModules module,
65984 + uint8_t modId,
65985 + e_FmIntrType intrType)
65986 +{
65987 + t_Fm *p_Fm = (t_Fm*)h_Fm;
65988 + int event = 0;
65989 +
65990 + ASSERT_COND(h_Fm);
65991 +
65992 + GET_FM_MODULE_EVENT(module, modId,intrType, event);
65993 + ASSERT_COND(event < e_FM_EV_DUMMY_LAST);
65994 +
65995 + p_Fm->intrMng[event].f_Isr = UnimplementedIsr;
65996 + p_Fm->intrMng[event].h_SrcHandle = NULL;
65997 +}
65998 +
65999 +void FmRegisterFmanCtrlIntr(t_Handle h_Fm, uint8_t eventRegId, void (*f_Isr) (t_Handle h_Arg, uint32_t event), t_Handle h_Arg)
66000 +{
66001 + t_Fm *p_Fm = (t_Fm*)h_Fm;
66002 +
66003 + ASSERT_COND(eventRegId<FM_NUM_OF_FMAN_CTRL_EVENT_REGS);
66004 +
66005 + if (p_Fm->guestId != NCSW_MASTER_ID)
66006 + {
66007 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("FM in guest-mode"));
66008 + return;
66009 + }
66010 +
66011 + p_Fm->fmanCtrlIntr[eventRegId].f_Isr = f_Isr;
66012 + p_Fm->fmanCtrlIntr[eventRegId].h_SrcHandle = h_Arg;
66013 +}
66014 +
66015 +void FmUnregisterFmanCtrlIntr(t_Handle h_Fm, uint8_t eventRegId)
66016 +{
66017 + t_Fm *p_Fm = (t_Fm*)h_Fm;
66018 +
66019 + ASSERT_COND(eventRegId<FM_NUM_OF_FMAN_CTRL_EVENT_REGS);
66020 +
66021 + if (p_Fm->guestId != NCSW_MASTER_ID)
66022 + {
66023 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("FM in guest-mode"));
66024 + return;
66025 + }
66026 +
66027 + p_Fm->fmanCtrlIntr[eventRegId].f_Isr = UnimplementedFmanCtrlIsr;
66028 + p_Fm->fmanCtrlIntr[eventRegId].h_SrcHandle = NULL;
66029 +}
66030 +
66031 +void FmRegisterPcd(t_Handle h_Fm, t_Handle h_FmPcd)
66032 +{
66033 + t_Fm *p_Fm = (t_Fm*)h_Fm;
66034 +
66035 + if (p_Fm->h_Pcd)
66036 + REPORT_ERROR(MAJOR, E_ALREADY_EXISTS, ("PCD already set"));
66037 +
66038 + p_Fm->h_Pcd = h_FmPcd;
66039 +}
66040 +
66041 +void FmUnregisterPcd(t_Handle h_Fm)
66042 +{
66043 + t_Fm *p_Fm = (t_Fm*)h_Fm;
66044 +
66045 + if (!p_Fm->h_Pcd)
66046 + REPORT_ERROR(MAJOR, E_NOT_FOUND, ("PCD handle!"));
66047 +
66048 + p_Fm->h_Pcd = NULL;
66049 +}
66050 +
66051 +t_Handle FmGetPcdHandle(t_Handle h_Fm)
66052 +{
66053 + t_Fm *p_Fm = (t_Fm*)h_Fm;
66054 +
66055 + return p_Fm->h_Pcd;
66056 +}
66057 +
66058 +uint8_t FmGetId(t_Handle h_Fm)
66059 +{
66060 + t_Fm *p_Fm = (t_Fm*)h_Fm;
66061 +
66062 + SANITY_CHECK_RETURN_VALUE(p_Fm, E_INVALID_HANDLE, 0xff);
66063 +
66064 + return p_Fm->p_FmStateStruct->fmId;
66065 +}
66066 +
66067 +t_Error FmReset(t_Handle h_Fm)
66068 +{
66069 + t_Fm *p_Fm = (t_Fm*)h_Fm;
66070 +
66071 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
66072 +
66073 + WRITE_UINT32(p_Fm->p_FmFpmRegs->fm_rstc, FPM_RSTC_FM_RESET);
66074 + CORE_MemoryBarrier();
66075 + XX_UDelay(100);
66076 +
66077 + return E_OK;
66078 +}
66079 +
66080 +t_Error FmSetNumOfRiscsPerPort(t_Handle h_Fm,
66081 + uint8_t hardwarePortId,
66082 + uint8_t numOfFmanCtrls,
66083 + t_FmFmanCtrl orFmanCtrl)
66084 +{
66085 +
66086 + t_Fm *p_Fm = (t_Fm*)h_Fm;
66087 + struct fman_fpm_regs *fpm_rg;
66088 +
66089 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
66090 + SANITY_CHECK_RETURN_ERROR(((numOfFmanCtrls > 0) && (numOfFmanCtrls < 3)) , E_INVALID_HANDLE);
66091 +
66092 + fpm_rg = p_Fm->p_FmFpmRegs;
66093 + if ((p_Fm->guestId != NCSW_MASTER_ID) &&
66094 + !p_Fm->p_FmFpmRegs &&
66095 + p_Fm->h_IpcSessions[0])
66096 + {
66097 + t_Error err;
66098 + t_FmIpcPortNumOfFmanCtrls params;
66099 + t_FmIpcMsg msg;
66100 +
66101 + memset(&msg, 0, sizeof(msg));
66102 + params.hardwarePortId = hardwarePortId;
66103 + params.numOfFmanCtrls = numOfFmanCtrls;
66104 + params.orFmanCtrl = orFmanCtrl;
66105 + msg.msgId = FM_SET_NUM_OF_FMAN_CTRL;
66106 + memcpy(msg.msgBody, &params, sizeof(params));
66107 + err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0],
66108 + (uint8_t*)&msg,
66109 + sizeof(msg.msgId) +sizeof(params),
66110 + NULL,
66111 + NULL,
66112 + NULL,
66113 + NULL);
66114 + if (err != E_OK)
66115 + RETURN_ERROR(MINOR, err, NO_MSG);
66116 + return E_OK;
66117 + }
66118 + else if (!p_Fm->p_FmFpmRegs)
66119 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED,
66120 + ("Either IPC or 'baseAddress' is required!"));
66121 +
66122 + fman_set_num_of_riscs_per_port(fpm_rg, hardwarePortId, numOfFmanCtrls, orFmanCtrl);
66123 +
66124 + return E_OK;
66125 +}
66126 +
66127 +t_Error FmGetSetPortParams(t_Handle h_Fm, t_FmInterModulePortInitParams *p_PortParams)
66128 +{
66129 + t_Fm *p_Fm = (t_Fm*)h_Fm;
66130 + t_Error err;
66131 + uint32_t intFlags;
66132 + uint8_t hardwarePortId = p_PortParams->hardwarePortId, macId;
66133 + struct fman_rg fman_rg;
66134 +
66135 + fman_rg.bmi_rg = p_Fm->p_FmBmiRegs;
66136 + fman_rg.qmi_rg = p_Fm->p_FmQmiRegs;
66137 + fman_rg.fpm_rg = p_Fm->p_FmFpmRegs;
66138 + fman_rg.dma_rg = p_Fm->p_FmDmaRegs;
66139 +
66140 + if (p_Fm->guestId != NCSW_MASTER_ID)
66141 + {
66142 + t_FmIpcPortInInitParams portInParams;
66143 + t_FmIpcPortOutInitParams portOutParams;
66144 + t_FmIpcMsg msg;
66145 + t_FmIpcReply reply;
66146 + uint32_t replyLength;
66147 +
66148 + portInParams.hardwarePortId = p_PortParams->hardwarePortId;
66149 + portInParams.enumPortType = (uint32_t)p_PortParams->portType;
66150 + portInParams.boolIndependentMode= (uint8_t)p_PortParams->independentMode;
66151 + portInParams.liodnOffset = p_PortParams->liodnOffset;
66152 + portInParams.numOfTasks = p_PortParams->numOfTasks;
66153 + portInParams.numOfExtraTasks = p_PortParams->numOfExtraTasks;
66154 + portInParams.numOfOpenDmas = p_PortParams->numOfOpenDmas;
66155 + portInParams.numOfExtraOpenDmas = p_PortParams->numOfExtraOpenDmas;
66156 + portInParams.sizeOfFifo = p_PortParams->sizeOfFifo;
66157 + portInParams.extraSizeOfFifo = p_PortParams->extraSizeOfFifo;
66158 + portInParams.deqPipelineDepth = p_PortParams->deqPipelineDepth;
66159 + portInParams.maxFrameLength = p_PortParams->maxFrameLength;
66160 + portInParams.liodnBase = p_PortParams->liodnBase;
66161 +
66162 + memset(&msg, 0, sizeof(msg));
66163 + memset(&reply, 0, sizeof(reply));
66164 + msg.msgId = FM_GET_SET_PORT_PARAMS;
66165 + memcpy(msg.msgBody, &portInParams, sizeof(portInParams));
66166 + replyLength = (sizeof(uint32_t) + sizeof(t_FmIpcPortOutInitParams));
66167 + if ((err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0],
66168 + (uint8_t*)&msg,
66169 + sizeof(msg.msgId) +sizeof(portInParams),
66170 + (uint8_t*)&reply,
66171 + &replyLength,
66172 + NULL,
66173 + NULL)) != E_OK)
66174 + RETURN_ERROR(MINOR, err, NO_MSG);
66175 + if (replyLength != (sizeof(uint32_t) + sizeof(t_FmIpcPortOutInitParams)))
66176 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch"));
66177 + memcpy((uint8_t*)&portOutParams, reply.replyBody, sizeof(t_FmIpcPortOutInitParams));
66178 +
66179 + p_PortParams->fmMuramPhysBaseAddr.high = portOutParams.ipcPhysAddr.high;
66180 + p_PortParams->fmMuramPhysBaseAddr.low = portOutParams.ipcPhysAddr.low;
66181 + p_PortParams->numOfTasks = portOutParams.numOfTasks;
66182 + p_PortParams->numOfExtraTasks = portOutParams.numOfExtraTasks;
66183 + p_PortParams->numOfOpenDmas = portOutParams.numOfOpenDmas;
66184 + p_PortParams->numOfExtraOpenDmas = portOutParams.numOfExtraOpenDmas;
66185 + p_PortParams->sizeOfFifo = portOutParams.sizeOfFifo;
66186 + p_PortParams->extraSizeOfFifo = portOutParams.extraSizeOfFifo;
66187 +
66188 + return (t_Error)(reply.error);
66189 + }
66190 +
66191 + ASSERT_COND(IN_RANGE(1, hardwarePortId, 63));
66192 +
66193 + intFlags = XX_LockIntrSpinlock(p_Fm->h_Spinlock);
66194 + if (p_PortParams->independentMode)
66195 + {
66196 + /* set port parameters */
66197 + p_Fm->independentMode = p_PortParams->independentMode;
66198 + /* disable dispatch limit */
66199 + fman_qmi_disable_dispatch_limit(fman_rg.fpm_rg);
66200 + }
66201 +
66202 + if (p_PortParams->portType == e_FM_PORT_TYPE_OH_HOST_COMMAND)
66203 + {
66204 + if (p_Fm->hcPortInitialized)
66205 + {
66206 + XX_UnlockIntrSpinlock(p_Fm->h_Spinlock, intFlags);
66207 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Only one host command port is allowed."));
66208 + }
66209 + else
66210 + p_Fm->hcPortInitialized = TRUE;
66211 + }
66212 + p_Fm->p_FmStateStruct->portsTypes[hardwarePortId] = p_PortParams->portType;
66213 +
66214 + err = FmSetNumOfTasks(p_Fm, hardwarePortId, &p_PortParams->numOfTasks, &p_PortParams->numOfExtraTasks, TRUE);
66215 + if (err)
66216 + {
66217 + XX_UnlockIntrSpinlock(p_Fm->h_Spinlock, intFlags);
66218 + RETURN_ERROR(MAJOR, err, NO_MSG);
66219 + }
66220 +
66221 +#ifdef FM_QMI_NO_DEQ_OPTIONS_SUPPORT
66222 + if (p_Fm->p_FmStateStruct->revInfo.majorRev != 4)
66223 +#endif /* FM_QMI_NO_DEQ_OPTIONS_SUPPORT */
66224 + if ((p_PortParams->portType != e_FM_PORT_TYPE_RX) &&
66225 + (p_PortParams->portType != e_FM_PORT_TYPE_RX_10G))
66226 + /* for transmit & O/H ports */
66227 + {
66228 + uint8_t enqTh;
66229 + uint8_t deqTh;
66230 +
66231 + /* update qmi ENQ/DEQ threshold */
66232 + p_Fm->p_FmStateStruct->accumulatedNumOfDeqTnums += p_PortParams->deqPipelineDepth;
66233 + enqTh = fman_get_qmi_enq_th(fman_rg.qmi_rg);
66234 + /* if enqTh is too big, we reduce it to the max value that is still OK */
66235 + if (enqTh >= (QMI_MAX_NUM_OF_TNUMS - p_Fm->p_FmStateStruct->accumulatedNumOfDeqTnums))
66236 + {
66237 + enqTh = (uint8_t)(QMI_MAX_NUM_OF_TNUMS - p_Fm->p_FmStateStruct->accumulatedNumOfDeqTnums - 1);
66238 + fman_set_qmi_enq_th(fman_rg.qmi_rg, enqTh);
66239 + }
66240 +
66241 + deqTh = fman_get_qmi_deq_th(fman_rg.qmi_rg);
66242 + /* if deqTh is too small, we enlarge it to the min value that is still OK.
66243 + deqTh may not be larger than 63 (QMI_MAX_NUM_OF_TNUMS-1). */
66244 + if ((deqTh <= p_Fm->p_FmStateStruct->accumulatedNumOfDeqTnums) && (deqTh < QMI_MAX_NUM_OF_TNUMS-1))
66245 + {
66246 + deqTh = (uint8_t)(p_Fm->p_FmStateStruct->accumulatedNumOfDeqTnums + 1);
66247 + fman_set_qmi_deq_th(fman_rg.qmi_rg, deqTh);
66248 + }
66249 + }
66250 +
66251 +#ifdef FM_LOW_END_RESTRICTION
66252 + if ((hardwarePortId==0x1) || (hardwarePortId==0x29))
66253 + {
66254 + if (p_Fm->p_FmStateStruct->lowEndRestriction)
66255 + {
66256 + XX_UnlockIntrSpinlock(p_Fm->h_Spinlock, intFlags);
66257 + RETURN_ERROR(MAJOR, E_NOT_AVAILABLE, ("OP #0 cannot work with Tx Port #1."));
66258 + }
66259 + else
66260 + p_Fm->p_FmStateStruct->lowEndRestriction = TRUE;
66261 + }
66262 +#endif /* FM_LOW_END_RESTRICTION */
66263 +
66264 + err = FmSetSizeOfFifo(p_Fm,
66265 + hardwarePortId,
66266 + &p_PortParams->sizeOfFifo,
66267 + &p_PortParams->extraSizeOfFifo,
66268 + TRUE);
66269 + if (err)
66270 + {
66271 + XX_UnlockIntrSpinlock(p_Fm->h_Spinlock, intFlags);
66272 + RETURN_ERROR(MAJOR, err, NO_MSG);
66273 + }
66274 +
66275 + err = FmSetNumOfOpenDmas(p_Fm,
66276 + hardwarePortId,
66277 + &p_PortParams->numOfOpenDmas,
66278 + &p_PortParams->numOfExtraOpenDmas,
66279 + TRUE);
66280 + if (err)
66281 + {
66282 + XX_UnlockIntrSpinlock(p_Fm->h_Spinlock, intFlags);
66283 + RETURN_ERROR(MAJOR, err, NO_MSG);
66284 + }
66285 +
66286 + fman_set_liodn_per_port(&fman_rg,
66287 + hardwarePortId,
66288 + p_PortParams->liodnBase,
66289 + p_PortParams->liodnOffset);
66290 +
66291 + if (p_Fm->p_FmStateStruct->revInfo.majorRev < 6)
66292 + fman_set_order_restoration_per_port(fman_rg.fpm_rg,
66293 + hardwarePortId,
66294 + p_PortParams->independentMode,
66295 + !!((p_PortParams->portType==e_FM_PORT_TYPE_RX) || (p_PortParams->portType==e_FM_PORT_TYPE_RX_10G)));
66296 +
66297 + HW_PORT_ID_TO_SW_PORT_ID(macId, hardwarePortId);
66298 +
66299 +#if defined(FM_MAX_NUM_OF_10G_MACS) && (FM_MAX_NUM_OF_10G_MACS)
66300 + if ((p_PortParams->portType == e_FM_PORT_TYPE_TX_10G) ||
66301 + (p_PortParams->portType == e_FM_PORT_TYPE_RX_10G))
66302 + {
66303 + ASSERT_COND(macId < FM_MAX_NUM_OF_10G_MACS);
66304 + if (p_PortParams->maxFrameLength >= p_Fm->p_FmStateStruct->macMaxFrameLengths10G[macId])
66305 + p_Fm->p_FmStateStruct->portMaxFrameLengths10G[macId] = p_PortParams->maxFrameLength;
66306 + else
66307 + RETURN_ERROR(MINOR, E_INVALID_VALUE, ("Port maxFrameLength is smaller than MAC current MTU"));
66308 + }
66309 + else
66310 +#endif /* defined(FM_MAX_NUM_OF_10G_MACS) && ... */
66311 + if ((p_PortParams->portType == e_FM_PORT_TYPE_TX) ||
66312 + (p_PortParams->portType == e_FM_PORT_TYPE_RX))
66313 + {
66314 + ASSERT_COND(macId < FM_MAX_NUM_OF_1G_MACS);
66315 + if (p_PortParams->maxFrameLength >= p_Fm->p_FmStateStruct->macMaxFrameLengths1G[macId])
66316 + p_Fm->p_FmStateStruct->portMaxFrameLengths1G[macId] = p_PortParams->maxFrameLength;
66317 + else
66318 + RETURN_ERROR(MINOR, E_INVALID_VALUE, ("Port maxFrameLength is smaller than MAC current MTU"));
66319 + }
66320 +
66321 + FmGetPhysicalMuramBase(p_Fm, &p_PortParams->fmMuramPhysBaseAddr);
66322 + XX_UnlockIntrSpinlock(p_Fm->h_Spinlock, intFlags);
66323 +
66324 + return E_OK;
66325 +}
66326 +
66327 +void FmFreePortParams(t_Handle h_Fm,t_FmInterModulePortFreeParams *p_PortParams)
66328 +{
66329 + t_Fm *p_Fm = (t_Fm*)h_Fm;
66330 + uint32_t intFlags;
66331 + uint8_t hardwarePortId = p_PortParams->hardwarePortId;
66332 + uint8_t numOfTasks, numOfDmas, macId;
66333 + uint16_t sizeOfFifo;
66334 + t_Error err;
66335 + t_FmIpcPortFreeParams portParams;
66336 + t_FmIpcMsg msg;
66337 + struct fman_qmi_regs *qmi_rg = p_Fm->p_FmQmiRegs;
66338 + struct fman_bmi_regs *bmi_rg = p_Fm->p_FmBmiRegs;
66339 +
66340 + if (p_Fm->guestId != NCSW_MASTER_ID)
66341 + {
66342 + portParams.hardwarePortId = p_PortParams->hardwarePortId;
66343 + portParams.enumPortType = (uint32_t)p_PortParams->portType;
66344 + portParams.deqPipelineDepth = p_PortParams->deqPipelineDepth;
66345 + memset(&msg, 0, sizeof(msg));
66346 + msg.msgId = FM_FREE_PORT;
66347 + memcpy(msg.msgBody, &portParams, sizeof(portParams));
66348 + err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0],
66349 + (uint8_t*)&msg,
66350 + sizeof(msg.msgId)+sizeof(portParams),
66351 + NULL,
66352 + NULL,
66353 + NULL,
66354 + NULL);
66355 + if (err != E_OK)
66356 + REPORT_ERROR(MINOR, err, NO_MSG);
66357 + return;
66358 + }
66359 +
66360 + ASSERT_COND(IN_RANGE(1, hardwarePortId, 63));
66361 +
66362 + intFlags = XX_LockIntrSpinlock(p_Fm->h_Spinlock);
66363 +
66364 + if (p_PortParams->portType == e_FM_PORT_TYPE_OH_HOST_COMMAND)
66365 + {
66366 + ASSERT_COND(p_Fm->hcPortInitialized);
66367 + p_Fm->hcPortInitialized = FALSE;
66368 + }
66369 +
66370 + p_Fm->p_FmStateStruct->portsTypes[hardwarePortId] = e_FM_PORT_TYPE_DUMMY;
66371 +
66372 + /* free numOfTasks */
66373 + numOfTasks = fman_get_num_of_tasks(bmi_rg, hardwarePortId);
66374 + ASSERT_COND(p_Fm->p_FmStateStruct->accumulatedNumOfTasks >= numOfTasks);
66375 + p_Fm->p_FmStateStruct->accumulatedNumOfTasks -= numOfTasks;
66376 +
66377 + /* free numOfOpenDmas */
66378 + numOfDmas = fman_get_num_of_dmas(bmi_rg, hardwarePortId);
66379 + ASSERT_COND(p_Fm->p_FmStateStruct->accumulatedNumOfOpenDmas >= numOfDmas);
66380 + p_Fm->p_FmStateStruct->accumulatedNumOfOpenDmas -= numOfDmas;
66381 +
66382 +#ifdef FM_HAS_TOTAL_DMAS
66383 + if (p_Fm->p_FmStateStruct->revInfo.majorRev < 6)
66384 + {
66385 + /* update total num of DMA's with committed number of open DMAS, and max uncommitted pool. */
66386 + fman_set_num_of_open_dmas(bmi_rg,
66387 + hardwarePortId,
66388 + 1,
66389 + 0,
66390 + (uint8_t)(p_Fm->p_FmStateStruct->accumulatedNumOfOpenDmas + p_Fm->p_FmStateStruct->extraOpenDmasPoolSize));
66391 + }
66392 +#endif /* FM_HAS_TOTAL_DMAS */
66393 +
66394 + /* free sizeOfFifo */
66395 + sizeOfFifo = fman_get_size_of_fifo(bmi_rg, hardwarePortId);
66396 + ASSERT_COND(p_Fm->p_FmStateStruct->accumulatedFifoSize >= (sizeOfFifo * BMI_FIFO_UNITS));
66397 + p_Fm->p_FmStateStruct->accumulatedFifoSize -= (sizeOfFifo * BMI_FIFO_UNITS);
66398 +
66399 +#ifdef FM_QMI_NO_DEQ_OPTIONS_SUPPORT
66400 + if (p_Fm->p_FmStateStruct->revInfo.majorRev != 4)
66401 +#endif /* FM_QMI_NO_DEQ_OPTIONS_SUPPORT */
66402 + if ((p_PortParams->portType != e_FM_PORT_TYPE_RX) &&
66403 + (p_PortParams->portType != e_FM_PORT_TYPE_RX_10G))
66404 + /* for transmit & O/H ports */
66405 + {
66406 + uint8_t enqTh;
66407 + uint8_t deqTh;
66408 +
66409 + /* update qmi ENQ/DEQ threshold */
66410 + p_Fm->p_FmStateStruct->accumulatedNumOfDeqTnums -= p_PortParams->deqPipelineDepth;
66411 +
66412 + /* p_Fm->p_FmStateStruct->accumulatedNumOfDeqTnums is now smaller,
66413 + so we can enlarge enqTh */
66414 + enqTh = (uint8_t)(QMI_MAX_NUM_OF_TNUMS - p_Fm->p_FmStateStruct->accumulatedNumOfDeqTnums - 1);
66415 +
66416 + /* p_Fm->p_FmStateStruct->accumulatedNumOfDeqTnums is now smaller,
66417 + so we can reduce deqTh */
66418 + deqTh = (uint8_t)(p_Fm->p_FmStateStruct->accumulatedNumOfDeqTnums + 1);
66419 +
66420 + fman_set_qmi_enq_th(qmi_rg, enqTh);
66421 + fman_set_qmi_deq_th(qmi_rg, deqTh);
66422 + }
66423 +
66424 + HW_PORT_ID_TO_SW_PORT_ID(macId, hardwarePortId);
66425 +
66426 +#if defined(FM_MAX_NUM_OF_10G_MACS) && (FM_MAX_NUM_OF_10G_MACS)
66427 + if ((p_PortParams->portType == e_FM_PORT_TYPE_TX_10G) ||
66428 + (p_PortParams->portType == e_FM_PORT_TYPE_RX_10G))
66429 + {
66430 + ASSERT_COND(macId < FM_MAX_NUM_OF_10G_MACS);
66431 + p_Fm->p_FmStateStruct->portMaxFrameLengths10G[macId] = 0;
66432 + }
66433 + else
66434 +#endif /* defined(FM_MAX_NUM_OF_10G_MACS) && ... */
66435 + if ((p_PortParams->portType == e_FM_PORT_TYPE_TX) ||
66436 + (p_PortParams->portType == e_FM_PORT_TYPE_RX))
66437 + {
66438 + ASSERT_COND(macId < FM_MAX_NUM_OF_1G_MACS);
66439 + p_Fm->p_FmStateStruct->portMaxFrameLengths1G[macId] = 0;
66440 + }
66441 +
66442 +#ifdef FM_LOW_END_RESTRICTION
66443 + if ((hardwarePortId==0x1) || (hardwarePortId==0x29))
66444 + p_Fm->p_FmStateStruct->lowEndRestriction = FALSE;
66445 +#endif /* FM_LOW_END_RESTRICTION */
66446 + XX_UnlockIntrSpinlock(p_Fm->h_Spinlock, intFlags);
66447 +}
66448 +
66449 +t_Error FmIsPortStalled(t_Handle h_Fm, uint8_t hardwarePortId, bool *p_IsStalled)
66450 +{
66451 + t_Fm *p_Fm = (t_Fm*)h_Fm;
66452 + t_Error err;
66453 + t_FmIpcMsg msg;
66454 + t_FmIpcReply reply;
66455 + uint32_t replyLength;
66456 + struct fman_fpm_regs *fpm_rg = p_Fm->p_FmFpmRegs;
66457 +
66458 + if ((p_Fm->guestId != NCSW_MASTER_ID) &&
66459 + !p_Fm->baseAddr &&
66460 + p_Fm->h_IpcSessions[0])
66461 + {
66462 + memset(&msg, 0, sizeof(msg));
66463 + memset(&reply, 0, sizeof(reply));
66464 + msg.msgId = FM_IS_PORT_STALLED;
66465 + msg.msgBody[0] = hardwarePortId;
66466 + replyLength = sizeof(uint32_t) + sizeof(uint8_t);
66467 + err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0],
66468 + (uint8_t*)&msg,
66469 + sizeof(msg.msgId)+sizeof(hardwarePortId),
66470 + (uint8_t*)&reply,
66471 + &replyLength,
66472 + NULL,
66473 + NULL);
66474 + if (err != E_OK)
66475 + RETURN_ERROR(MINOR, err, NO_MSG);
66476 + if (replyLength != (sizeof(uint32_t) + sizeof(uint8_t)))
66477 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch"));
66478 +
66479 + *p_IsStalled = (bool)!!(*(uint8_t*)(reply.replyBody));
66480 +
66481 + return (t_Error)(reply.error);
66482 + }
66483 + else if (!p_Fm->baseAddr)
66484 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED,
66485 + ("Either IPC or 'baseAddress' is required!"));
66486 +
66487 + *p_IsStalled = fman_is_port_stalled(fpm_rg, hardwarePortId);
66488 +
66489 + return E_OK;
66490 +}
66491 +
66492 +t_Error FmResumeStalledPort(t_Handle h_Fm, uint8_t hardwarePortId)
66493 +{
66494 + t_Fm *p_Fm = (t_Fm*)h_Fm;
66495 + t_Error err;
66496 + bool isStalled;
66497 + struct fman_fpm_regs *fpm_rg = p_Fm->p_FmFpmRegs;
66498 +
66499 + if ((p_Fm->guestId != NCSW_MASTER_ID) &&
66500 + !p_Fm->baseAddr &&
66501 + p_Fm->h_IpcSessions[0])
66502 + {
66503 + t_FmIpcMsg msg;
66504 + t_FmIpcReply reply;
66505 + uint32_t replyLength;
66506 +
66507 + memset(&msg, 0, sizeof(msg));
66508 + memset(&reply, 0, sizeof(reply));
66509 + msg.msgId = FM_RESUME_STALLED_PORT;
66510 + msg.msgBody[0] = hardwarePortId;
66511 + replyLength = sizeof(uint32_t);
66512 + err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0],
66513 + (uint8_t*)&msg,
66514 + sizeof(msg.msgId) + sizeof(hardwarePortId),
66515 + (uint8_t*)&reply,
66516 + &replyLength,
66517 + NULL,
66518 + NULL);
66519 + if (err != E_OK)
66520 + RETURN_ERROR(MINOR, err, NO_MSG);
66521 + if (replyLength != sizeof(uint32_t))
66522 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch"));
66523 + return (t_Error)(reply.error);
66524 + }
66525 + else if (!p_Fm->baseAddr)
66526 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED,
66527 + ("Either IPC or 'baseAddress' is required!"));
66528 +
66529 + if (p_Fm->p_FmStateStruct->revInfo.majorRev >= 6)
66530 + RETURN_ERROR(MINOR, E_NOT_AVAILABLE, ("Not available for this FM revision!"));
66531 +
66532 + /* Get port status */
66533 + err = FmIsPortStalled(h_Fm, hardwarePortId, &isStalled);
66534 + if (err)
66535 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Can't get port status"));
66536 + if (!isStalled)
66537 + return E_OK;
66538 +
66539 + fman_resume_stalled_port(fpm_rg, hardwarePortId);
66540 +
66541 + return E_OK;
66542 +}
66543 +
66544 +t_Error FmResetMac(t_Handle h_Fm, e_FmMacType type, uint8_t macId)
66545 +{
66546 + t_Fm *p_Fm = (t_Fm*)h_Fm;
66547 + t_Error err;
66548 + struct fman_fpm_regs *fpm_rg = p_Fm->p_FmFpmRegs;
66549 +
66550 +#if (DPAA_VERSION >= 11)
66551 + if (p_Fm->p_FmStateStruct->revInfo.majorRev >= 6)
66552 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED,
66553 + ("FMan MAC reset!"));
66554 +#endif /*(DPAA_VERSION >= 11)*/
66555 +
66556 + if ((p_Fm->guestId != NCSW_MASTER_ID) &&
66557 + !p_Fm->baseAddr &&
66558 + p_Fm->h_IpcSessions[0])
66559 + {
66560 + t_FmIpcMacParams macParams;
66561 + t_FmIpcMsg msg;
66562 + t_FmIpcReply reply;
66563 + uint32_t replyLength;
66564 +
66565 + memset(&msg, 0, sizeof(msg));
66566 + memset(&reply, 0, sizeof(reply));
66567 + macParams.id = macId;
66568 + macParams.enumType = (uint32_t)type;
66569 + msg.msgId = FM_RESET_MAC;
66570 + memcpy(msg.msgBody, &macParams, sizeof(macParams));
66571 + replyLength = sizeof(uint32_t);
66572 + err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0],
66573 + (uint8_t*)&msg,
66574 + sizeof(msg.msgId)+sizeof(macParams),
66575 + (uint8_t*)&reply,
66576 + &replyLength,
66577 + NULL,
66578 + NULL);
66579 + if (err != E_OK)
66580 + RETURN_ERROR(MINOR, err, NO_MSG);
66581 + if (replyLength != sizeof(uint32_t))
66582 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch"));
66583 + return (t_Error)(reply.error);
66584 + }
66585 + else if (!p_Fm->baseAddr)
66586 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED,
66587 + ("Either IPC or 'baseAddress' is required!"));
66588 +
66589 + err = (t_Error)fman_reset_mac(fpm_rg, macId, !!(type == e_FM_MAC_10G));
66590 +
66591 + if (err == -EBUSY)
66592 + return ERROR_CODE(E_TIMEOUT);
66593 + else if (err)
66594 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Illegal MAC ID"));
66595 +
66596 + return E_OK;
66597 +}
66598 +
66599 +t_Error FmSetMacMaxFrame(t_Handle h_Fm, e_FmMacType type, uint8_t macId, uint16_t mtu)
66600 +{
66601 + t_Fm *p_Fm = (t_Fm*)h_Fm;
66602 +
66603 + if ((p_Fm->guestId != NCSW_MASTER_ID) &&
66604 + p_Fm->h_IpcSessions[0])
66605 + {
66606 + t_FmIpcMacMaxFrameParams macMaxFrameLengthParams;
66607 + t_Error err;
66608 + t_FmIpcMsg msg;
66609 +
66610 + memset(&msg, 0, sizeof(msg));
66611 + macMaxFrameLengthParams.macParams.id = macId;
66612 + macMaxFrameLengthParams.macParams.enumType = (uint32_t)type;
66613 + macMaxFrameLengthParams.maxFrameLength = (uint16_t)mtu;
66614 + msg.msgId = FM_SET_MAC_MAX_FRAME;
66615 + memcpy(msg.msgBody, &macMaxFrameLengthParams, sizeof(macMaxFrameLengthParams));
66616 + err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0],
66617 + (uint8_t*)&msg,
66618 + sizeof(msg.msgId)+sizeof(macMaxFrameLengthParams),
66619 + NULL,
66620 + NULL,
66621 + NULL,
66622 + NULL);
66623 + if (err != E_OK)
66624 + RETURN_ERROR(MINOR, err, NO_MSG);
66625 + return E_OK;
66626 + }
66627 + else if (p_Fm->guestId != NCSW_MASTER_ID)
66628 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED,
66629 + ("running in guest-mode without IPC!"));
66630 +
66631 + /* if port is already initialized, check that MaxFrameLength is smaller
66632 + * or equal to the port's max */
66633 +#if (defined(FM_MAX_NUM_OF_10G_MACS) && (FM_MAX_NUM_OF_10G_MACS))
66634 + if (type == e_FM_MAC_10G)
66635 + {
66636 + if ((!p_Fm->p_FmStateStruct->portMaxFrameLengths10G[macId])
66637 + || (p_Fm->p_FmStateStruct->portMaxFrameLengths10G[macId] &&
66638 + (mtu <= p_Fm->p_FmStateStruct->portMaxFrameLengths10G[macId])))
66639 + p_Fm->p_FmStateStruct->macMaxFrameLengths10G[macId] = mtu;
66640 + else
66641 + RETURN_ERROR(MINOR, E_INVALID_VALUE, ("MAC maxFrameLength is larger than Port maxFrameLength"));
66642 +
66643 + }
66644 + else
66645 +#else
66646 + UNUSED(type);
66647 +#endif /* (defined(FM_MAX_NUM_OF_10G_MACS) && ... */
66648 + if ((!p_Fm->p_FmStateStruct->portMaxFrameLengths1G[macId])
66649 + || (p_Fm->p_FmStateStruct->portMaxFrameLengths1G[macId] &&
66650 + (mtu <= p_Fm->p_FmStateStruct->portMaxFrameLengths1G[macId])))
66651 + p_Fm->p_FmStateStruct->macMaxFrameLengths1G[macId] = mtu;
66652 + else
66653 + RETURN_ERROR(MINOR, E_INVALID_VALUE, ("MAC maxFrameLength is larger than Port maxFrameLength"));
66654 +
66655 + return E_OK;
66656 +}
66657 +
66658 +uint16_t FmGetClockFreq(t_Handle h_Fm)
66659 +{
66660 + t_Fm *p_Fm = (t_Fm*)h_Fm;
66661 +
66662 + /* for multicore environment: this depends on the
66663 + * fact that fmClkFreq was properly initialized at "init". */
66664 + return p_Fm->p_FmStateStruct->fmClkFreq;
66665 +}
66666 +
66667 +uint16_t FmGetMacClockFreq(t_Handle h_Fm)
66668 +{
66669 + t_Fm *p_Fm = (t_Fm*)h_Fm;
66670 +
66671 + return p_Fm->p_FmStateStruct->fmMacClkFreq;
66672 +}
66673 +
66674 +uint32_t FmGetTimeStampScale(t_Handle h_Fm)
66675 +{
66676 + t_Fm *p_Fm = (t_Fm*)h_Fm;
66677 +
66678 + if ((p_Fm->guestId != NCSW_MASTER_ID) &&
66679 + !p_Fm->baseAddr &&
66680 + p_Fm->h_IpcSessions[0])
66681 + {
66682 + t_Error err;
66683 + t_FmIpcMsg msg;
66684 + t_FmIpcReply reply;
66685 + uint32_t replyLength, timeStamp;
66686 +
66687 + memset(&msg, 0, sizeof(msg));
66688 + memset(&reply, 0, sizeof(reply));
66689 + msg.msgId = FM_GET_TIMESTAMP_SCALE;
66690 + replyLength = sizeof(uint32_t) + sizeof(uint32_t);
66691 + if ((err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0],
66692 + (uint8_t*)&msg,
66693 + sizeof(msg.msgId),
66694 + (uint8_t*)&reply,
66695 + &replyLength,
66696 + NULL,
66697 + NULL)) != E_OK)
66698 + {
66699 + REPORT_ERROR(MAJOR, err, NO_MSG);
66700 + return 0;
66701 + }
66702 + if (replyLength != (sizeof(uint32_t) + sizeof(uint32_t)))
66703 + {
66704 + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch"));
66705 + return 0;
66706 + }
66707 +
66708 + memcpy((uint8_t*)&timeStamp, reply.replyBody, sizeof(uint32_t));
66709 + return timeStamp;
66710 + }
66711 + else if ((p_Fm->guestId != NCSW_MASTER_ID) &&
66712 + p_Fm->baseAddr)
66713 + {
66714 + if (!(GET_UINT32(p_Fm->p_FmFpmRegs->fmfp_tsc1) & FPM_TS_CTL_EN))
66715 + {
66716 + REPORT_ERROR(MAJOR, E_INVALID_STATE, ("timestamp is not enabled!"));
66717 + return 0;
66718 + }
66719 + }
66720 + else if (p_Fm->guestId != NCSW_MASTER_ID)
66721 + DBG(WARNING, ("No IPC - can't validate FM if timestamp enabled."));
66722 +
66723 + return p_Fm->p_FmStateStruct->count1MicroBit;
66724 +}
66725 +
66726 +t_Error FmEnableRamsEcc(t_Handle h_Fm)
66727 +{
66728 + t_Fm *p_Fm = (t_Fm*)h_Fm;
66729 +
66730 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
66731 +
66732 + p_Fm->p_FmStateStruct->ramsEccOwners++;
66733 + p_Fm->p_FmStateStruct->internalCall = TRUE;
66734 +
66735 + return FM_EnableRamsEcc(p_Fm);
66736 +}
66737 +
66738 +t_Error FmDisableRamsEcc(t_Handle h_Fm)
66739 +{
66740 + t_Fm *p_Fm = (t_Fm*)h_Fm;
66741 +
66742 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
66743 +
66744 + ASSERT_COND(p_Fm->p_FmStateStruct->ramsEccOwners);
66745 + p_Fm->p_FmStateStruct->ramsEccOwners--;
66746 +
66747 + if (p_Fm->p_FmStateStruct->ramsEccOwners==0)
66748 + {
66749 + p_Fm->p_FmStateStruct->internalCall = TRUE;
66750 + return FM_DisableRamsEcc(p_Fm);
66751 + }
66752 +
66753 + return E_OK;
66754 +}
66755 +
66756 +uint8_t FmGetGuestId(t_Handle h_Fm)
66757 +{
66758 + t_Fm *p_Fm = (t_Fm*)h_Fm;
66759 +
66760 + return p_Fm->guestId;
66761 +}
66762 +
66763 +bool FmIsMaster(t_Handle h_Fm)
66764 +{
66765 + t_Fm *p_Fm = (t_Fm*)h_Fm;
66766 +
66767 + return (p_Fm->guestId == NCSW_MASTER_ID);
66768 +}
66769 +
66770 +t_Error FmSetSizeOfFifo(t_Handle h_Fm,
66771 + uint8_t hardwarePortId,
66772 + uint32_t *p_SizeOfFifo,
66773 + uint32_t *p_ExtraSizeOfFifo,
66774 + bool initialConfig)
66775 +{
66776 + t_Fm *p_Fm = (t_Fm*)h_Fm;
66777 + t_FmIpcPortRsrcParams rsrcParams;
66778 + t_Error err;
66779 + struct fman_bmi_regs *bmi_rg = p_Fm->p_FmBmiRegs;
66780 + uint32_t sizeOfFifo = *p_SizeOfFifo, extraSizeOfFifo = *p_ExtraSizeOfFifo;
66781 + uint16_t currentVal = 0, currentExtraVal = 0;
66782 +
66783 + if ((p_Fm->guestId != NCSW_MASTER_ID) &&
66784 + !p_Fm->baseAddr &&
66785 + p_Fm->h_IpcSessions[0])
66786 + {
66787 + t_FmIpcMsg msg;
66788 + t_FmIpcReply reply;
66789 + uint32_t replyLength;
66790 +
66791 + rsrcParams.hardwarePortId = hardwarePortId;
66792 + rsrcParams.val = sizeOfFifo;
66793 + rsrcParams.extra = extraSizeOfFifo;
66794 + rsrcParams.boolInitialConfig = (uint8_t)initialConfig;
66795 +
66796 + memset(&msg, 0, sizeof(msg));
66797 + memset(&reply, 0, sizeof(reply));
66798 + msg.msgId = FM_SET_SIZE_OF_FIFO;
66799 + memcpy(msg.msgBody, &rsrcParams, sizeof(rsrcParams));
66800 + replyLength = sizeof(uint32_t);
66801 + if ((err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0],
66802 + (uint8_t*)&msg,
66803 + sizeof(msg.msgId) + sizeof(rsrcParams),
66804 + (uint8_t*)&reply,
66805 + &replyLength,
66806 + NULL,
66807 + NULL)) != E_OK)
66808 + RETURN_ERROR(MINOR, err, NO_MSG);
66809 + if (replyLength != sizeof(uint32_t))
66810 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch"));
66811 + return (t_Error)(reply.error);
66812 + }
66813 + else if ((p_Fm->guestId != NCSW_MASTER_ID) &&
66814 + p_Fm->baseAddr)
66815 + {
66816 + DBG(WARNING, ("No IPC - can't validate FM total-fifo size."));
66817 + fman_set_size_of_fifo(bmi_rg, hardwarePortId, sizeOfFifo, extraSizeOfFifo);
66818 + }
66819 + else if (p_Fm->guestId != NCSW_MASTER_ID)
66820 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED,
66821 + ("running in guest-mode without neither IPC nor mapped register!"));
66822 +
66823 + if (!initialConfig)
66824 + {
66825 + /* !initialConfig - runtime change of existing value.
66826 + * - read the current FIFO and extra FIFO size */
66827 + currentExtraVal = fman_get_size_of_extra_fifo(bmi_rg, hardwarePortId);
66828 + currentVal = fman_get_size_of_fifo(bmi_rg, hardwarePortId);
66829 + }
66830 +
66831 + if (extraSizeOfFifo > currentExtraVal)
66832 + {
66833 + if (extraSizeOfFifo && !p_Fm->p_FmStateStruct->extraFifoPoolSize)
66834 + /* if this is the first time a port requires extraFifoPoolSize, the total extraFifoPoolSize
66835 + * must be initialized to 1 buffer per port
66836 + */
66837 + p_Fm->p_FmStateStruct->extraFifoPoolSize = FM_MAX_NUM_OF_RX_PORTS*BMI_FIFO_UNITS;
66838 +
66839 + p_Fm->p_FmStateStruct->extraFifoPoolSize = MAX(p_Fm->p_FmStateStruct->extraFifoPoolSize, extraSizeOfFifo);
66840 + }
66841 +
66842 + /* check that there are enough uncommitted fifo size */
66843 + if ((p_Fm->p_FmStateStruct->accumulatedFifoSize - currentVal + sizeOfFifo) >
66844 + (p_Fm->p_FmStateStruct->totalFifoSize - p_Fm->p_FmStateStruct->extraFifoPoolSize)){
66845 + REPORT_ERROR(MAJOR, E_INVALID_VALUE,
66846 + ("Port request fifo size + accumulated size > total FIFO size:"));
66847 + RETURN_ERROR(MAJOR, E_INVALID_VALUE,
66848 + ("port 0x%x requested %d bytes, extra size = %d, accumulated size = %d total size = %d",
66849 + hardwarePortId, sizeOfFifo, p_Fm->p_FmStateStruct->extraFifoPoolSize,
66850 + p_Fm->p_FmStateStruct->accumulatedFifoSize,
66851 + p_Fm->p_FmStateStruct->totalFifoSize));
66852 + }
66853 + else
66854 + {
66855 + /* update accumulated */
66856 + ASSERT_COND(p_Fm->p_FmStateStruct->accumulatedFifoSize >= currentVal);
66857 + p_Fm->p_FmStateStruct->accumulatedFifoSize -= currentVal;
66858 + p_Fm->p_FmStateStruct->accumulatedFifoSize += sizeOfFifo;
66859 + fman_set_size_of_fifo(bmi_rg, hardwarePortId, sizeOfFifo, extraSizeOfFifo);
66860 + }
66861 +
66862 + return E_OK;
66863 +}
66864 +
66865 +t_Error FmSetNumOfTasks(t_Handle h_Fm,
66866 + uint8_t hardwarePortId,
66867 + uint8_t *p_NumOfTasks,
66868 + uint8_t *p_NumOfExtraTasks,
66869 + bool initialConfig)
66870 +{
66871 + t_Fm *p_Fm = (t_Fm *)h_Fm;
66872 + t_Error err;
66873 + struct fman_bmi_regs *bmi_rg = p_Fm->p_FmBmiRegs;
66874 + uint8_t currentVal = 0, currentExtraVal = 0, numOfTasks = *p_NumOfTasks, numOfExtraTasks = *p_NumOfExtraTasks;
66875 +
66876 + ASSERT_COND(IN_RANGE(1, hardwarePortId, 63));
66877 +
66878 + if ((p_Fm->guestId != NCSW_MASTER_ID) &&
66879 + !p_Fm->baseAddr &&
66880 + p_Fm->h_IpcSessions[0])
66881 + {
66882 + t_FmIpcPortRsrcParams rsrcParams;
66883 + t_FmIpcMsg msg;
66884 + t_FmIpcReply reply;
66885 + uint32_t replyLength;
66886 +
66887 + rsrcParams.hardwarePortId = hardwarePortId;
66888 + rsrcParams.val = numOfTasks;
66889 + rsrcParams.extra = numOfExtraTasks;
66890 + rsrcParams.boolInitialConfig = (uint8_t)initialConfig;
66891 +
66892 + memset(&msg, 0, sizeof(msg));
66893 + memset(&reply, 0, sizeof(reply));
66894 + msg.msgId = FM_SET_NUM_OF_TASKS;
66895 + memcpy(msg.msgBody, &rsrcParams, sizeof(rsrcParams));
66896 + replyLength = sizeof(uint32_t);
66897 + if ((err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0],
66898 + (uint8_t*)&msg,
66899 + sizeof(msg.msgId) + sizeof(rsrcParams),
66900 + (uint8_t*)&reply,
66901 + &replyLength,
66902 + NULL,
66903 + NULL)) != E_OK)
66904 + RETURN_ERROR(MINOR, err, NO_MSG);
66905 + if (replyLength != sizeof(uint32_t))
66906 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch"));
66907 + return (t_Error)(reply.error);
66908 + }
66909 + else if ((p_Fm->guestId != NCSW_MASTER_ID) &&
66910 + p_Fm->baseAddr)
66911 + {
66912 + DBG(WARNING, ("No IPC - can't validate FM total-num-of-tasks."));
66913 + fman_set_num_of_tasks(bmi_rg, hardwarePortId, numOfTasks, numOfExtraTasks);
66914 + }
66915 + else if (p_Fm->guestId != NCSW_MASTER_ID)
66916 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED,
66917 + ("running in guest-mode without neither IPC nor mapped register!"));
66918 +
66919 + if (!initialConfig)
66920 + {
66921 + /* !initialConfig - runtime change of existing value.
66922 + * - read the current number of tasks */
66923 + currentVal = fman_get_num_of_tasks(bmi_rg, hardwarePortId);
66924 + currentExtraVal = fman_get_num_extra_tasks(bmi_rg, hardwarePortId);
66925 + }
66926 +
66927 + if (numOfExtraTasks > currentExtraVal)
66928 + p_Fm->p_FmStateStruct->extraTasksPoolSize =
66929 + (uint8_t)MAX(p_Fm->p_FmStateStruct->extraTasksPoolSize, numOfExtraTasks);
66930 +
66931 + /* check that there are enough uncommitted tasks */
66932 + if ((p_Fm->p_FmStateStruct->accumulatedNumOfTasks - currentVal + numOfTasks) >
66933 + (p_Fm->p_FmStateStruct->totalNumOfTasks - p_Fm->p_FmStateStruct->extraTasksPoolSize))
66934 + RETURN_ERROR(MAJOR, E_NOT_AVAILABLE,
66935 + ("Requested numOfTasks and extra tasks pool for fm%d exceed total numOfTasks.",
66936 + p_Fm->p_FmStateStruct->fmId));
66937 + else
66938 + {
66939 + ASSERT_COND(p_Fm->p_FmStateStruct->accumulatedNumOfTasks >= currentVal);
66940 + /* update accumulated */
66941 + p_Fm->p_FmStateStruct->accumulatedNumOfTasks -= currentVal;
66942 + p_Fm->p_FmStateStruct->accumulatedNumOfTasks += numOfTasks;
66943 + fman_set_num_of_tasks(bmi_rg, hardwarePortId, numOfTasks, numOfExtraTasks);
66944 + }
66945 +
66946 + return E_OK;
66947 +}
66948 +
66949 +t_Error FmSetNumOfOpenDmas(t_Handle h_Fm,
66950 + uint8_t hardwarePortId,
66951 + uint8_t *p_NumOfOpenDmas,
66952 + uint8_t *p_NumOfExtraOpenDmas,
66953 + bool initialConfig)
66954 +
66955 +{
66956 + t_Fm *p_Fm = (t_Fm *)h_Fm;
66957 + t_Error err;
66958 + struct fman_bmi_regs *bmi_rg = p_Fm->p_FmBmiRegs;
66959 + uint8_t numOfOpenDmas = *p_NumOfOpenDmas, numOfExtraOpenDmas = *p_NumOfExtraOpenDmas;
66960 + uint8_t totalNumDmas = 0, currentVal = 0, currentExtraVal = 0;
66961 +
66962 + ASSERT_COND(IN_RANGE(1, hardwarePortId, 63));
66963 +
66964 + if ((p_Fm->guestId != NCSW_MASTER_ID) &&
66965 + !p_Fm->baseAddr &&
66966 + p_Fm->h_IpcSessions[0])
66967 + {
66968 + t_FmIpcPortRsrcParams rsrcParams;
66969 + t_FmIpcMsg msg;
66970 + t_FmIpcReply reply;
66971 + uint32_t replyLength;
66972 +
66973 + rsrcParams.hardwarePortId = hardwarePortId;
66974 + rsrcParams.val = numOfOpenDmas;
66975 + rsrcParams.extra = numOfExtraOpenDmas;
66976 + rsrcParams.boolInitialConfig = (uint8_t)initialConfig;
66977 +
66978 + memset(&msg, 0, sizeof(msg));
66979 + memset(&reply, 0, sizeof(reply));
66980 + msg.msgId = FM_SET_NUM_OF_OPEN_DMAS;
66981 + memcpy(msg.msgBody, &rsrcParams, sizeof(rsrcParams));
66982 + replyLength = sizeof(uint32_t);
66983 + if ((err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0],
66984 + (uint8_t*)&msg,
66985 + sizeof(msg.msgId) + sizeof(rsrcParams),
66986 + (uint8_t*)&reply,
66987 + &replyLength,
66988 + NULL,
66989 + NULL)) != E_OK)
66990 + RETURN_ERROR(MINOR, err, NO_MSG);
66991 + if (replyLength != sizeof(uint32_t))
66992 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch"));
66993 + return (t_Error)(reply.error);
66994 + }
66995 +#ifdef FM_HAS_TOTAL_DMAS
66996 + else if (p_Fm->guestId != NCSW_MASTER_ID)
66997 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("running in guest-mode without IPC!"));
66998 +#else
66999 + else if ((p_Fm->guestId != NCSW_MASTER_ID) &&
67000 + p_Fm->baseAddr &&
67001 + (p_Fm->p_FmStateStruct->revInfo.majorRev >= 6))
67002 + {
67003 + /*DBG(WARNING, ("No IPC - can't validate FM total-num-of-dmas."));*/
67004 +
67005 + if (!numOfOpenDmas)
67006 + {
67007 + /* first config without explic it value: Do Nothing - reset value shouldn't be
67008 + changed, read register for port save */
67009 + *p_NumOfOpenDmas = fman_get_num_of_dmas(bmi_rg, hardwarePortId);
67010 + *p_NumOfExtraOpenDmas = fman_get_num_extra_dmas(bmi_rg, hardwarePortId);
67011 + }
67012 + else
67013 + /* whether it is the first time with explicit value, or runtime "set" - write register */
67014 + fman_set_num_of_open_dmas(bmi_rg,
67015 + hardwarePortId,
67016 + numOfOpenDmas,
67017 + numOfExtraOpenDmas,
67018 + p_Fm->p_FmStateStruct->accumulatedNumOfOpenDmas + p_Fm->p_FmStateStruct->extraOpenDmasPoolSize);
67019 + }
67020 + else if (p_Fm->guestId != NCSW_MASTER_ID)
67021 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED,
67022 + ("running in guest-mode without neither IPC nor mapped register!"));
67023 +#endif /* FM_HAS_TOTAL_DMAS */
67024 +
67025 + if (!initialConfig)
67026 + {
67027 + /* !initialConfig - runtime change of existing value.
67028 + * - read the current number of open Dma's */
67029 + currentExtraVal = fman_get_num_extra_dmas(bmi_rg, hardwarePortId);
67030 + currentVal = fman_get_num_of_dmas(bmi_rg, hardwarePortId);
67031 + }
67032 +
67033 +#ifdef FM_NO_GUARANTEED_RESET_VALUES
67034 + /* it's illegal to be in a state where this is not the first set and no value is specified */
67035 + ASSERT_COND(initialConfig || numOfOpenDmas);
67036 + if (!numOfOpenDmas)
67037 + {
67038 + /* !numOfOpenDmas - first configuration according to values in regs.
67039 + * - read the current number of open Dma's */
67040 + currentExtraVal = fman_get_num_extra_dmas(bmi_rg, hardwarePortId);
67041 + currentVal = fman_get_num_of_dmas(bmi_rg, hardwarePortId);
67042 + /* This is the first configuration and user did not specify value (!numOfOpenDmas),
67043 + * reset values will be used and we just save these values for resource management */
67044 + p_Fm->p_FmStateStruct->extraOpenDmasPoolSize =
67045 + (uint8_t)MAX(p_Fm->p_FmStateStruct->extraOpenDmasPoolSize, currentExtraVal);
67046 + p_Fm->p_FmStateStruct->accumulatedNumOfOpenDmas += currentVal;
67047 + *p_NumOfOpenDmas = currentVal;
67048 + *p_NumOfExtraOpenDmas = currentExtraVal;
67049 + return E_OK;
67050 + }
67051 +#endif /* FM_NO_GUARANTEED_RESET_VALUES */
67052 +
67053 + if (numOfExtraOpenDmas > currentExtraVal)
67054 + p_Fm->p_FmStateStruct->extraOpenDmasPoolSize =
67055 + (uint8_t)MAX(p_Fm->p_FmStateStruct->extraOpenDmasPoolSize, numOfExtraOpenDmas);
67056 +
67057 +#ifdef FM_HAS_TOTAL_DMAS
67058 + if ((p_Fm->p_FmStateStruct->revInfo.majorRev < 6) &&
67059 + (p_Fm->p_FmStateStruct->accumulatedNumOfOpenDmas - currentVal + numOfOpenDmas >
67060 + p_Fm->p_FmStateStruct->maxNumOfOpenDmas))
67061 + RETURN_ERROR(MAJOR, E_NOT_AVAILABLE,
67062 + ("Requested numOfOpenDmas for fm%d exceeds total numOfOpenDmas.",
67063 + p_Fm->p_FmStateStruct->fmId));
67064 +#else
67065 + if ((p_Fm->p_FmStateStruct->revInfo.majorRev >= 6) &&
67066 +#ifdef FM_HEAVY_TRAFFIC_SEQUENCER_HANG_ERRATA_FMAN_A006981
67067 + !((p_Fm->p_FmStateStruct->revInfo.majorRev == 6) &&
67068 + (p_Fm->p_FmStateStruct->revInfo.minorRev == 0)) &&
67069 +#endif /* FM_HEAVY_TRAFFIC_SEQUENCER_HANG_ERRATA_FMAN_A006981 */
67070 + (p_Fm->p_FmStateStruct->accumulatedNumOfOpenDmas - currentVal + numOfOpenDmas > DMA_THRESH_MAX_COMMQ + 1))
67071 + RETURN_ERROR(MAJOR, E_NOT_AVAILABLE,
67072 + ("Requested numOfOpenDmas for fm%d exceeds DMA Command queue (%d)",
67073 + p_Fm->p_FmStateStruct->fmId, DMA_THRESH_MAX_COMMQ+1));
67074 +#endif /* FM_HAS_TOTAL_DMAS */
67075 + else
67076 + {
67077 + ASSERT_COND(p_Fm->p_FmStateStruct->accumulatedNumOfOpenDmas >= currentVal);
67078 + /* update acummulated */
67079 + p_Fm->p_FmStateStruct->accumulatedNumOfOpenDmas -= currentVal;
67080 + p_Fm->p_FmStateStruct->accumulatedNumOfOpenDmas += numOfOpenDmas;
67081 +
67082 +#ifdef FM_HAS_TOTAL_DMAS
67083 + if (p_Fm->p_FmStateStruct->revInfo.majorRev < 6)
67084 + totalNumDmas = (uint8_t)(p_Fm->p_FmStateStruct->accumulatedNumOfOpenDmas + p_Fm->p_FmStateStruct->extraOpenDmasPoolSize);
67085 +#endif /* FM_HAS_TOTAL_DMAS */
67086 + fman_set_num_of_open_dmas(bmi_rg,
67087 + hardwarePortId,
67088 + numOfOpenDmas,
67089 + numOfExtraOpenDmas,
67090 + totalNumDmas);
67091 + }
67092 +
67093 + return E_OK;
67094 +}
67095 +
67096 +#if (DPAA_VERSION >= 11)
67097 +t_Error FmVSPCheckRelativeProfile(t_Handle h_Fm,
67098 + e_FmPortType portType,
67099 + uint8_t portId,
67100 + uint16_t relativeProfile)
67101 +{
67102 + t_Fm *p_Fm;
67103 + t_FmSp *p_FmPcdSp;
67104 + uint8_t swPortIndex=0, hardwarePortId;
67105 +
67106 + ASSERT_COND(h_Fm);
67107 + p_Fm = (t_Fm*)h_Fm;
67108 +
67109 + hardwarePortId = SwPortIdToHwPortId(portType,
67110 + portId,
67111 + p_Fm->p_FmStateStruct->revInfo.majorRev,
67112 + p_Fm->p_FmStateStruct->revInfo.minorRev);
67113 + ASSERT_COND(hardwarePortId);
67114 + HW_PORT_ID_TO_SW_PORT_INDX(swPortIndex, hardwarePortId);
67115 +
67116 + p_FmPcdSp = p_Fm->p_FmSp;
67117 + ASSERT_COND(p_FmPcdSp);
67118 +
67119 + if (!p_FmPcdSp->portsMapping[swPortIndex].numOfProfiles)
67120 + RETURN_ERROR(MAJOR, E_INVALID_STATE , ("Port has no allocated profiles"));
67121 + if (relativeProfile >= p_FmPcdSp->portsMapping[swPortIndex].numOfProfiles)
67122 + RETURN_ERROR(MAJOR, E_NOT_IN_RANGE , ("Profile id is out of range"));
67123 +
67124 + return E_OK;
67125 +}
67126 +
67127 +t_Error FmVSPGetAbsoluteProfileId(t_Handle h_Fm,
67128 + e_FmPortType portType,
67129 + uint8_t portId,
67130 + uint16_t relativeProfile,
67131 + uint16_t *p_AbsoluteId)
67132 +{
67133 + t_Fm *p_Fm;
67134 + t_FmSp *p_FmPcdSp;
67135 + uint8_t swPortIndex=0, hardwarePortId;
67136 + t_Error err;
67137 +
67138 + ASSERT_COND(h_Fm);
67139 + p_Fm = (t_Fm*)h_Fm;
67140 +
67141 + err = FmVSPCheckRelativeProfile(h_Fm, portType, portId, relativeProfile);
67142 + if (err != E_OK)
67143 + return err;
67144 +
67145 + hardwarePortId = SwPortIdToHwPortId(portType,
67146 + portId,
67147 + p_Fm->p_FmStateStruct->revInfo.majorRev,
67148 + p_Fm->p_FmStateStruct->revInfo.minorRev);
67149 + ASSERT_COND(hardwarePortId);
67150 + HW_PORT_ID_TO_SW_PORT_INDX(swPortIndex, hardwarePortId);
67151 +
67152 + p_FmPcdSp = p_Fm->p_FmSp;
67153 + ASSERT_COND(p_FmPcdSp);
67154 +
67155 + *p_AbsoluteId = (uint16_t)(p_FmPcdSp->portsMapping[swPortIndex].profilesBase + relativeProfile);
67156 +
67157 + return E_OK;
67158 +}
67159 +#endif /* (DPAA_VERSION >= 11) */
67160 +
67161 +static t_Error InitFmDma(t_Fm *p_Fm)
67162 +{
67163 + t_Error err;
67164 +
67165 + err = (t_Error)fman_dma_init(p_Fm->p_FmDmaRegs, p_Fm->p_FmDriverParam);
67166 + if (err != E_OK)
67167 + return err;
67168 +
67169 + /* Allocate MURAM for CAM */
67170 + p_Fm->camBaseAddr = PTR_TO_UINT(FM_MURAM_AllocMem(p_Fm->h_FmMuram,
67171 + (uint32_t)(p_Fm->p_FmDriverParam->dma_cam_num_of_entries*DMA_CAM_SIZEOF_ENTRY),
67172 + DMA_CAM_ALIGN));
67173 + if (!p_Fm->camBaseAddr)
67174 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("MURAM alloc for DMA CAM failed"));
67175 +
67176 + WRITE_BLOCK(UINT_TO_PTR(p_Fm->camBaseAddr),
67177 + 0,
67178 + (uint32_t)(p_Fm->p_FmDriverParam->dma_cam_num_of_entries*DMA_CAM_SIZEOF_ENTRY));
67179 +
67180 + if (p_Fm->p_FmStateStruct->revInfo.majorRev == 2)
67181 + {
67182 + FM_MURAM_FreeMem(p_Fm->h_FmMuram, UINT_TO_PTR(p_Fm->camBaseAddr));
67183 +
67184 + p_Fm->camBaseAddr = PTR_TO_UINT(FM_MURAM_AllocMem(p_Fm->h_FmMuram,
67185 + (uint32_t)(p_Fm->p_FmDriverParam->dma_cam_num_of_entries*72 + 128),
67186 + 64));
67187 + if (!p_Fm->camBaseAddr)
67188 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("MURAM alloc for DMA CAM failed"));
67189 +
67190 + WRITE_BLOCK(UINT_TO_PTR(p_Fm->camBaseAddr),
67191 + 0,
67192 + (uint32_t)(p_Fm->p_FmDriverParam->dma_cam_num_of_entries*72 + 128));
67193 +
67194 + switch(p_Fm->p_FmDriverParam->dma_cam_num_of_entries)
67195 + {
67196 + case (8):
67197 + WRITE_UINT32(*(uint32_t*)p_Fm->camBaseAddr, 0xff000000);
67198 + break;
67199 + case (16):
67200 + WRITE_UINT32(*(uint32_t*)p_Fm->camBaseAddr, 0xffff0000);
67201 + break;
67202 + case (24):
67203 + WRITE_UINT32(*(uint32_t*)p_Fm->camBaseAddr, 0xffffff00);
67204 + break;
67205 + case (32):
67206 + WRITE_UINT32(*(uint32_t*)p_Fm->camBaseAddr, 0xffffffff);
67207 + break;
67208 + default:
67209 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("wrong dma_cam_num_of_entries"));
67210 + }
67211 + }
67212 +
67213 + p_Fm->p_FmDriverParam->cam_base_addr =
67214 + (uint32_t)(XX_VirtToPhys(UINT_TO_PTR(p_Fm->camBaseAddr)) - p_Fm->fmMuramPhysBaseAddr);
67215 +
67216 + return E_OK;
67217 +}
67218 +
67219 +static t_Error InitFmFpm(t_Fm *p_Fm)
67220 +{
67221 + return (t_Error)fman_fpm_init(p_Fm->p_FmFpmRegs, p_Fm->p_FmDriverParam);
67222 +}
67223 +
67224 +static t_Error InitFmBmi(t_Fm *p_Fm)
67225 +{
67226 + return (t_Error)fman_bmi_init(p_Fm->p_FmBmiRegs, p_Fm->p_FmDriverParam);
67227 +}
67228 +
67229 +static t_Error InitFmQmi(t_Fm *p_Fm)
67230 +{
67231 + return (t_Error)fman_qmi_init(p_Fm->p_FmQmiRegs, p_Fm->p_FmDriverParam);
67232 +}
67233 +
67234 +static t_Error InitGuestMode(t_Fm *p_Fm)
67235 +{
67236 + t_Error err = E_OK;
67237 + int i;
67238 + t_FmIpcMsg msg;
67239 + t_FmIpcReply reply;
67240 + uint32_t replyLength;
67241 +
67242 + ASSERT_COND(p_Fm);
67243 + ASSERT_COND(p_Fm->guestId != NCSW_MASTER_ID);
67244 +
67245 + /* build the FM guest partition IPC address */
67246 + if (Sprint (p_Fm->fmModuleName, "FM_%d_%d",p_Fm->p_FmStateStruct->fmId, p_Fm->guestId) != (p_Fm->guestId<10 ? 6:7))
67247 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Sprint failed"));
67248 +
67249 + /* build the FM master partition IPC address */
67250 + memset(p_Fm->fmIpcHandlerModuleName, 0, (sizeof(char)) * MODULE_NAME_SIZE);
67251 + if (Sprint (p_Fm->fmIpcHandlerModuleName[0], "FM_%d_%d",p_Fm->p_FmStateStruct->fmId, NCSW_MASTER_ID) != 6)
67252 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Sprint failed"));
67253 +
67254 + for (i=0;i<e_FM_EV_DUMMY_LAST;i++)
67255 + p_Fm->intrMng[i].f_Isr = UnimplementedIsr;
67256 +
67257 + p_Fm->h_IpcSessions[0] = XX_IpcInitSession(p_Fm->fmIpcHandlerModuleName[0], p_Fm->fmModuleName);
67258 + if (p_Fm->h_IpcSessions[0])
67259 + {
67260 + uint8_t isMasterAlive;
67261 + t_FmIpcParams ipcParams;
67262 +
67263 + err = XX_IpcRegisterMsgHandler(p_Fm->fmModuleName, FmGuestHandleIpcMsgCB, p_Fm, FM_IPC_MAX_REPLY_SIZE);
67264 + if (err)
67265 + RETURN_ERROR(MAJOR, err, NO_MSG);
67266 +
67267 + memset(&msg, 0, sizeof(msg));
67268 + memset(&reply, 0, sizeof(reply));
67269 + msg.msgId = FM_MASTER_IS_ALIVE;
67270 + msg.msgBody[0] = p_Fm->guestId;
67271 + replyLength = sizeof(uint32_t) + sizeof(uint8_t);
67272 + do
67273 + {
67274 + blockingFlag = TRUE;
67275 + if ((err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0],
67276 + (uint8_t*)&msg,
67277 + sizeof(msg.msgId)+sizeof(p_Fm->guestId),
67278 + (uint8_t*)&reply,
67279 + &replyLength,
67280 + IpcMsgCompletionCB,
67281 + p_Fm)) != E_OK)
67282 + REPORT_ERROR(MINOR, err, NO_MSG);
67283 + while (blockingFlag) ;
67284 + if (replyLength != (sizeof(uint32_t) + sizeof(uint8_t)))
67285 + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch"));
67286 + isMasterAlive = *(uint8_t*)(reply.replyBody);
67287 + } while (!isMasterAlive);
67288 +
67289 + /* read FM parameters and save */
67290 + memset(&msg, 0, sizeof(msg));
67291 + memset(&reply, 0, sizeof(reply));
67292 + msg.msgId = FM_GET_PARAMS;
67293 + replyLength = sizeof(uint32_t) + sizeof(t_FmIpcParams);
67294 + if ((err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0],
67295 + (uint8_t*)&msg,
67296 + sizeof(msg.msgId),
67297 + (uint8_t*)&reply,
67298 + &replyLength,
67299 + NULL,
67300 + NULL)) != E_OK)
67301 + RETURN_ERROR(MAJOR, err, NO_MSG);
67302 + if (replyLength != (sizeof(uint32_t) + sizeof(t_FmIpcParams)))
67303 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch"));
67304 + memcpy((uint8_t*)&ipcParams, reply.replyBody, sizeof(t_FmIpcParams));
67305 +
67306 + p_Fm->p_FmStateStruct->fmClkFreq = ipcParams.fmClkFreq;
67307 + p_Fm->p_FmStateStruct->fmMacClkFreq = ipcParams.fmMacClkFreq;
67308 + p_Fm->p_FmStateStruct->revInfo.majorRev = ipcParams.majorRev;
67309 + p_Fm->p_FmStateStruct->revInfo.minorRev = ipcParams.minorRev;
67310 + }
67311 + else
67312 + {
67313 + DBG(WARNING, ("FM Guest mode - without IPC"));
67314 + if (!p_Fm->p_FmStateStruct->fmClkFreq)
67315 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("No fmClkFreq configured for guest without IPC"));
67316 + if (p_Fm->baseAddr)
67317 + {
67318 + fman_get_revision(p_Fm->p_FmFpmRegs,
67319 + &p_Fm->p_FmStateStruct->revInfo.majorRev,
67320 + &p_Fm->p_FmStateStruct->revInfo.minorRev);
67321 +
67322 + }
67323 + }
67324 +
67325 +#if (DPAA_VERSION >= 11)
67326 + p_Fm->partVSPBase = AllocVSPsForPartition(p_Fm, p_Fm->partVSPBase, p_Fm->partNumOfVSPs, p_Fm->guestId);
67327 + if (p_Fm->partVSPBase == (uint8_t)(ILLEGAL_BASE))
67328 + DBG(WARNING, ("partition VSPs allocation is FAILED"));
67329 +#endif /* (DPAA_VERSION >= 11) */
67330 +
67331 + /* General FM driver initialization */
67332 + if (p_Fm->baseAddr)
67333 + p_Fm->fmMuramPhysBaseAddr =
67334 + (uint64_t)(XX_VirtToPhys(UINT_TO_PTR(p_Fm->baseAddr + FM_MM_MURAM)));
67335 +
67336 + XX_Free(p_Fm->p_FmDriverParam);
67337 + p_Fm->p_FmDriverParam = NULL;
67338 +
67339 + if ((p_Fm->guestId == NCSW_MASTER_ID) ||
67340 + (p_Fm->h_IpcSessions[0]))
67341 + {
67342 + FM_DisableRamsEcc(p_Fm);
67343 + FmMuramClear(p_Fm->h_FmMuram);
67344 + FM_EnableRamsEcc(p_Fm);
67345 + }
67346 +
67347 + return E_OK;
67348 +}
67349 +
67350 +static __inline__ enum fman_exceptions FmanExceptionTrans(e_FmExceptions exception)
67351 +{
67352 + switch (exception) {
67353 + case e_FM_EX_DMA_BUS_ERROR:
67354 + return E_FMAN_EX_DMA_BUS_ERROR;
67355 + case e_FM_EX_DMA_READ_ECC:
67356 + return E_FMAN_EX_DMA_READ_ECC;
67357 + case e_FM_EX_DMA_SYSTEM_WRITE_ECC:
67358 + return E_FMAN_EX_DMA_SYSTEM_WRITE_ECC;
67359 + case e_FM_EX_DMA_FM_WRITE_ECC:
67360 + return E_FMAN_EX_DMA_FM_WRITE_ECC;
67361 + case e_FM_EX_FPM_STALL_ON_TASKS:
67362 + return E_FMAN_EX_FPM_STALL_ON_TASKS;
67363 + case e_FM_EX_FPM_SINGLE_ECC:
67364 + return E_FMAN_EX_FPM_SINGLE_ECC;
67365 + case e_FM_EX_FPM_DOUBLE_ECC:
67366 + return E_FMAN_EX_FPM_DOUBLE_ECC;
67367 + case e_FM_EX_QMI_SINGLE_ECC:
67368 + return E_FMAN_EX_QMI_SINGLE_ECC;
67369 + case e_FM_EX_QMI_DOUBLE_ECC:
67370 + return E_FMAN_EX_QMI_DOUBLE_ECC;
67371 + case e_FM_EX_QMI_DEQ_FROM_UNKNOWN_PORTID:
67372 + return E_FMAN_EX_QMI_DEQ_FROM_UNKNOWN_PORTID;
67373 + case e_FM_EX_BMI_LIST_RAM_ECC:
67374 + return E_FMAN_EX_BMI_LIST_RAM_ECC;
67375 + case e_FM_EX_BMI_STORAGE_PROFILE_ECC:
67376 + return E_FMAN_EX_BMI_STORAGE_PROFILE_ECC;
67377 + case e_FM_EX_BMI_STATISTICS_RAM_ECC:
67378 + return E_FMAN_EX_BMI_STATISTICS_RAM_ECC;
67379 + case e_FM_EX_BMI_DISPATCH_RAM_ECC:
67380 + return E_FMAN_EX_BMI_DISPATCH_RAM_ECC;
67381 + case e_FM_EX_IRAM_ECC:
67382 + return E_FMAN_EX_IRAM_ECC;
67383 + case e_FM_EX_MURAM_ECC:
67384 + return E_FMAN_EX_MURAM_ECC;
67385 + default:
67386 + return E_FMAN_EX_DMA_BUS_ERROR;
67387 + }
67388 +}
67389 +
67390 +uint8_t SwPortIdToHwPortId(e_FmPortType type, uint8_t relativePortId, uint8_t majorRev, uint8_t minorRev)
67391 +{
67392 + switch (type)
67393 + {
67394 + case (e_FM_PORT_TYPE_OH_OFFLINE_PARSING):
67395 + case (e_FM_PORT_TYPE_OH_HOST_COMMAND):
67396 + CHECK_PORT_ID_OH_PORTS(relativePortId);
67397 + return (uint8_t)(BASE_OH_PORTID + (relativePortId));
67398 + case (e_FM_PORT_TYPE_RX):
67399 + CHECK_PORT_ID_1G_RX_PORTS(relativePortId);
67400 + return (uint8_t)(BASE_1G_RX_PORTID + (relativePortId));
67401 + case (e_FM_PORT_TYPE_RX_10G):
67402 + /* The 10G port in T1024 (FMan Version 6.4) is the first port.
67403 + * This is the reason why the 1G port offset is used.
67404 + */
67405 + if (majorRev == 6 && minorRev == 4)
67406 + {
67407 + CHECK_PORT_ID_1G_RX_PORTS(relativePortId);
67408 + return (uint8_t)(BASE_1G_RX_PORTID + (relativePortId));
67409 + }
67410 + else
67411 + {
67412 + CHECK_PORT_ID_10G_RX_PORTS(relativePortId);
67413 + return (uint8_t)(BASE_10G_RX_PORTID + (relativePortId));
67414 + }
67415 + case (e_FM_PORT_TYPE_TX):
67416 + CHECK_PORT_ID_1G_TX_PORTS(relativePortId);
67417 + return (uint8_t)(BASE_1G_TX_PORTID + (relativePortId));
67418 + case (e_FM_PORT_TYPE_TX_10G):
67419 + /* The 10G port in T1024 (FMan Version 6.4) is the first port.
67420 + * This is the reason why the 1G port offset is used.
67421 + */
67422 + if (majorRev == 6 && minorRev == 4)
67423 + {
67424 + CHECK_PORT_ID_1G_TX_PORTS(relativePortId);
67425 + return (uint8_t)(BASE_1G_TX_PORTID + (relativePortId));
67426 + }
67427 + else
67428 + {
67429 + CHECK_PORT_ID_10G_TX_PORTS(relativePortId);
67430 + return (uint8_t)(BASE_10G_TX_PORTID + (relativePortId));
67431 + }
67432 + default:
67433 + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("Illegal port type"));
67434 + return 0;
67435 + }
67436 +}
67437 +
67438 +#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
67439 +t_Error FmDumpPortRegs (t_Handle h_Fm, uint8_t hardwarePortId)
67440 +{
67441 + t_Fm *p_Fm = (t_Fm *)h_Fm;
67442 +
67443 + DECLARE_DUMP;
67444 +
67445 + ASSERT_COND(IN_RANGE(1, hardwarePortId, 63));
67446 +
67447 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
67448 + SANITY_CHECK_RETURN_ERROR(((p_Fm->guestId == NCSW_MASTER_ID) ||
67449 + p_Fm->baseAddr), E_INVALID_OPERATION);
67450 +
67451 + DUMP_TITLE(&p_Fm->p_FmBmiRegs->fmbm_pp[hardwarePortId-1], ("fmbm_pp for port %u", (hardwarePortId)));
67452 + DUMP_MEMORY(&p_Fm->p_FmBmiRegs->fmbm_pp[hardwarePortId-1], sizeof(uint32_t));
67453 +
67454 + DUMP_TITLE(&p_Fm->p_FmBmiRegs->fmbm_pfs[hardwarePortId-1], ("fmbm_pfs for port %u", (hardwarePortId )));
67455 + DUMP_MEMORY(&p_Fm->p_FmBmiRegs->fmbm_pfs[hardwarePortId-1], sizeof(uint32_t));
67456 +
67457 + DUMP_TITLE(&p_Fm->p_FmBmiRegs->fmbm_spliodn[hardwarePortId-1], ("fmbm_spliodn for port %u", (hardwarePortId)));
67458 + DUMP_MEMORY(&p_Fm->p_FmBmiRegs->fmbm_spliodn[hardwarePortId-1], sizeof(uint32_t));
67459 +
67460 + DUMP_TITLE(&p_Fm->p_FmFpmRegs->fmfp_ps[hardwarePortId], ("fmfp_ps for port %u", (hardwarePortId)));
67461 + DUMP_MEMORY(&p_Fm->p_FmFpmRegs->fmfp_ps[hardwarePortId], sizeof(uint32_t));
67462 +
67463 + DUMP_TITLE(&p_Fm->p_FmDmaRegs->fmdmplr[hardwarePortId/2], ("fmdmplr for port %u", (hardwarePortId)));
67464 + DUMP_MEMORY(&p_Fm->p_FmDmaRegs->fmdmplr[hardwarePortId/2], sizeof(uint32_t));
67465 +
67466 + return E_OK;
67467 +}
67468 +#endif /* (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0)) */
67469 +
67470 +
67471 +/*****************************************************************************/
67472 +/* API Init unit functions */
67473 +/*****************************************************************************/
67474 +t_Handle FM_Config(t_FmParams *p_FmParam)
67475 +{
67476 + t_Fm *p_Fm;
67477 + uint8_t i;
67478 + uintptr_t baseAddr;
67479 +
67480 + SANITY_CHECK_RETURN_VALUE(p_FmParam, E_NULL_POINTER, NULL);
67481 + SANITY_CHECK_RETURN_VALUE(((p_FmParam->firmware.p_Code && p_FmParam->firmware.size) ||
67482 + (!p_FmParam->firmware.p_Code && !p_FmParam->firmware.size)),
67483 + E_INVALID_VALUE, NULL);
67484 +
67485 + baseAddr = p_FmParam->baseAddr;
67486 +
67487 + /* Allocate FM structure */
67488 + p_Fm = (t_Fm *) XX_Malloc(sizeof(t_Fm));
67489 + if (!p_Fm)
67490 + {
67491 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FM driver structure"));
67492 + return NULL;
67493 + }
67494 + memset(p_Fm, 0, sizeof(t_Fm));
67495 +
67496 + p_Fm->p_FmStateStruct = (t_FmStateStruct *) XX_Malloc(sizeof(t_FmStateStruct));
67497 + if (!p_Fm->p_FmStateStruct)
67498 + {
67499 + XX_Free(p_Fm);
67500 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FM Status structure"));
67501 + return NULL;
67502 + }
67503 + memset(p_Fm->p_FmStateStruct, 0, sizeof(t_FmStateStruct));
67504 +
67505 + /* Initialize FM parameters which will be kept by the driver */
67506 + p_Fm->p_FmStateStruct->fmId = p_FmParam->fmId;
67507 + p_Fm->guestId = p_FmParam->guestId;
67508 +
67509 + for (i=0; i<FM_MAX_NUM_OF_HW_PORT_IDS; i++)
67510 + p_Fm->p_FmStateStruct->portsTypes[i] = e_FM_PORT_TYPE_DUMMY;
67511 +
67512 + /* Allocate the FM driver's parameters structure */
67513 + p_Fm->p_FmDriverParam = (struct fman_cfg *)XX_Malloc(sizeof(struct fman_cfg));
67514 + if (!p_Fm->p_FmDriverParam)
67515 + {
67516 + XX_Free(p_Fm->p_FmStateStruct);
67517 + XX_Free(p_Fm);
67518 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FM driver parameters"));
67519 + return NULL;
67520 + }
67521 + memset(p_Fm->p_FmDriverParam, 0, sizeof(struct fman_cfg));
67522 +
67523 +#if (DPAA_VERSION >= 11)
67524 + p_Fm->p_FmSp = (t_FmSp *)XX_Malloc(sizeof(t_FmSp));
67525 + if (!p_Fm->p_FmSp)
67526 + {
67527 + XX_Free(p_Fm->p_FmDriverParam);
67528 + XX_Free(p_Fm->p_FmStateStruct);
67529 + XX_Free(p_Fm);
67530 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("allocation for internal data structure failed"));
67531 + return NULL;
67532 + }
67533 + memset(p_Fm->p_FmSp, 0, sizeof(t_FmSp));
67534 +
67535 + for (i=0; i<FM_VSP_MAX_NUM_OF_ENTRIES; i++)
67536 + p_Fm->p_FmSp->profiles[i].profilesMng.ownerId = (uint8_t)ILLEGAL_BASE;
67537 +#endif /* (DPAA_VERSION >= 11) */
67538 +
67539 + /* Initialize FM parameters which will be kept by the driver */
67540 + p_Fm->p_FmStateStruct->fmId = p_FmParam->fmId;
67541 + p_Fm->h_FmMuram = p_FmParam->h_FmMuram;
67542 + p_Fm->h_App = p_FmParam->h_App;
67543 + p_Fm->p_FmStateStruct->fmClkFreq = p_FmParam->fmClkFreq;
67544 + p_Fm->p_FmStateStruct->fmMacClkFreq = p_FmParam->fmClkFreq / ((!p_FmParam->fmMacClkRatio)? 2: p_FmParam->fmMacClkRatio);
67545 + p_Fm->f_Exception = p_FmParam->f_Exception;
67546 + p_Fm->f_BusError = p_FmParam->f_BusError;
67547 + p_Fm->p_FmFpmRegs = (struct fman_fpm_regs *)UINT_TO_PTR(baseAddr + FM_MM_FPM);
67548 + p_Fm->p_FmBmiRegs = (struct fman_bmi_regs *)UINT_TO_PTR(baseAddr + FM_MM_BMI);
67549 + p_Fm->p_FmQmiRegs = (struct fman_qmi_regs *)UINT_TO_PTR(baseAddr + FM_MM_QMI);
67550 + p_Fm->p_FmDmaRegs = (struct fman_dma_regs *)UINT_TO_PTR(baseAddr + FM_MM_DMA);
67551 + p_Fm->p_FmRegs = (struct fman_regs *)UINT_TO_PTR(baseAddr + FM_MM_BMI);
67552 + p_Fm->baseAddr = baseAddr;
67553 + p_Fm->p_FmStateStruct->irq = p_FmParam->irq;
67554 + p_Fm->p_FmStateStruct->errIrq = p_FmParam->errIrq;
67555 + p_Fm->hcPortInitialized = FALSE;
67556 + p_Fm->independentMode = FALSE;
67557 +
67558 + p_Fm->h_Spinlock = XX_InitSpinlock();
67559 + if (!p_Fm->h_Spinlock)
67560 + {
67561 + XX_Free(p_Fm->p_FmDriverParam);
67562 + XX_Free(p_Fm->p_FmStateStruct);
67563 + XX_Free(p_Fm);
67564 + REPORT_ERROR(MAJOR, E_INVALID_STATE, ("can't allocate spinlock!"));
67565 + return NULL;
67566 + }
67567 +
67568 +#if (DPAA_VERSION >= 11)
67569 + p_Fm->partVSPBase = p_FmParam->partVSPBase;
67570 + p_Fm->partNumOfVSPs = p_FmParam->partNumOfVSPs;
67571 + p_Fm->vspBaseAddr = p_FmParam->vspBaseAddr;
67572 +#endif /* (DPAA_VERSION >= 11) */
67573 +
67574 + fman_defconfig(p_Fm->p_FmDriverParam,
67575 + !!(p_Fm->guestId == NCSW_MASTER_ID));
67576 +/* overide macros dependent parameters */
67577 +#ifdef FM_PEDANTIC_DMA
67578 + p_Fm->p_FmDriverParam->pedantic_dma = TRUE;
67579 + p_Fm->p_FmDriverParam->dma_aid_override = TRUE;
67580 +#endif /* FM_PEDANTIC_DMA */
67581 +#ifndef FM_QMI_NO_DEQ_OPTIONS_SUPPORT
67582 + p_Fm->p_FmDriverParam->qmi_deq_option_support = TRUE;
67583 +#endif /* !FM_QMI_NO_DEQ_OPTIONS_SUPPORT */
67584 +
67585 + p_Fm->p_FmStateStruct->ramsEccEnable = FALSE;
67586 + p_Fm->p_FmStateStruct->extraFifoPoolSize = 0;
67587 + p_Fm->p_FmStateStruct->exceptions = DEFAULT_exceptions;
67588 + p_Fm->resetOnInit = DEFAULT_resetOnInit;
67589 + p_Fm->f_ResetOnInitOverride = DEFAULT_resetOnInitOverrideCallback;
67590 + p_Fm->fwVerify = DEFAULT_VerifyUcode;
67591 + p_Fm->firmware.size = p_FmParam->firmware.size;
67592 + if (p_Fm->firmware.size)
67593 + {
67594 + p_Fm->firmware.p_Code = (uint32_t *)XX_Malloc(p_Fm->firmware.size);
67595 + if (!p_Fm->firmware.p_Code)
67596 + {
67597 + XX_FreeSpinlock(p_Fm->h_Spinlock);
67598 + XX_Free(p_Fm->p_FmStateStruct);
67599 + XX_Free(p_Fm->p_FmDriverParam);
67600 + XX_Free(p_Fm);
67601 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FM firmware code"));
67602 + return NULL;
67603 + }
67604 + memcpy(p_Fm->firmware.p_Code, p_FmParam->firmware.p_Code ,p_Fm->firmware.size);
67605 + }
67606 +
67607 + if (p_Fm->guestId != NCSW_MASTER_ID)
67608 + return p_Fm;
67609 +
67610 + /* read revision */
67611 + /* Chip dependent, will be configured in Init */
67612 + fman_get_revision(p_Fm->p_FmFpmRegs,
67613 + &p_Fm->p_FmStateStruct->revInfo.majorRev,
67614 + &p_Fm->p_FmStateStruct->revInfo.minorRev);
67615 +
67616 +#ifdef FM_AID_MODE_NO_TNUM_SW005
67617 + if (p_Fm->p_FmStateStruct->revInfo.majorRev >= 6)
67618 + p_Fm->p_FmDriverParam->dma_aid_mode = e_FM_DMA_AID_OUT_PORT_ID;
67619 +#endif /* FM_AID_MODE_NO_TNUM_SW005 */
67620 +#ifndef FM_QMI_NO_DEQ_OPTIONS_SUPPORT
67621 + if (p_Fm->p_FmStateStruct->revInfo.majorRev != 4)
67622 + p_Fm->p_FmDriverParam->qmi_def_tnums_thresh = QMI_DEF_TNUMS_THRESH;
67623 +#endif /* FM_QMI_NO_DEQ_OPTIONS_SUPPORT */
67624 +
67625 + p_Fm->p_FmStateStruct->totalFifoSize = 0;
67626 + p_Fm->p_FmStateStruct->totalNumOfTasks =
67627 + DEFAULT_totalNumOfTasks(p_Fm->p_FmStateStruct->revInfo.majorRev,
67628 + p_Fm->p_FmStateStruct->revInfo.minorRev);
67629 +
67630 +#ifdef FM_HAS_TOTAL_DMAS
67631 + p_Fm->p_FmStateStruct->maxNumOfOpenDmas = BMI_MAX_NUM_OF_DMAS;
67632 +#endif /* FM_HAS_TOTAL_DMAS */
67633 +#if (DPAA_VERSION < 11)
67634 + p_Fm->p_FmDriverParam->dma_comm_qtsh_clr_emer = DEFAULT_dmaCommQLow;
67635 + p_Fm->p_FmDriverParam->dma_comm_qtsh_asrt_emer = DEFAULT_dmaCommQHigh;
67636 + p_Fm->p_FmDriverParam->dma_cam_num_of_entries = DEFAULT_dmaCamNumOfEntries;
67637 + p_Fm->p_FmDriverParam->dma_read_buf_tsh_clr_emer = DEFAULT_dmaReadIntBufLow;
67638 + p_Fm->p_FmDriverParam->dma_read_buf_tsh_asrt_emer = DEFAULT_dmaReadIntBufHigh;
67639 + p_Fm->p_FmDriverParam->dma_write_buf_tsh_clr_emer = DEFAULT_dmaWriteIntBufLow;
67640 + p_Fm->p_FmDriverParam->dma_write_buf_tsh_asrt_emer = DEFAULT_dmaWriteIntBufHigh;
67641 + p_Fm->p_FmDriverParam->dma_axi_dbg_num_of_beats = DEFAULT_axiDbgNumOfBeats;
67642 +#endif /* (DPAA_VERSION < 11) */
67643 +#ifdef FM_NO_TNUM_AGING
67644 + p_Fm->p_FmDriverParam->tnum_aging_period = 0;
67645 +#endif
67646 + p_Fm->tnumAgingPeriod = p_Fm->p_FmDriverParam->tnum_aging_period;
67647 +
67648 + return p_Fm;
67649 +}
67650 +
67651 +/**************************************************************************//**
67652 + @Function FM_Init
67653 +
67654 + @Description Initializes the FM module
67655 +
67656 + @Param[in] h_Fm - FM module descriptor
67657 +
67658 + @Return E_OK on success; Error code otherwise.
67659 +*//***************************************************************************/
67660 +t_Error FM_Init(t_Handle h_Fm)
67661 +{
67662 + t_Fm *p_Fm = (t_Fm*)h_Fm;
67663 + struct fman_cfg *p_FmDriverParam = NULL;
67664 + t_Error err = E_OK;
67665 + int i;
67666 + t_FmRevisionInfo revInfo;
67667 + struct fman_rg fman_rg;
67668 +
67669 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
67670 + SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE);
67671 +
67672 + fman_rg.bmi_rg = p_Fm->p_FmBmiRegs;
67673 + fman_rg.qmi_rg = p_Fm->p_FmQmiRegs;
67674 + fman_rg.fpm_rg = p_Fm->p_FmFpmRegs;
67675 + fman_rg.dma_rg = p_Fm->p_FmDmaRegs;
67676 +
67677 + p_Fm->p_FmStateStruct->count1MicroBit = FM_TIMESTAMP_1_USEC_BIT;
67678 + p_Fm->p_FmDriverParam->num_of_fman_ctrl_evnt_regs = FM_NUM_OF_FMAN_CTRL_EVENT_REGS;
67679 +
67680 + if (p_Fm->guestId != NCSW_MASTER_ID)
67681 + return InitGuestMode(p_Fm);
67682 +
67683 + /* if user didn't configured totalFifoSize - (totalFifoSize=0) we configure default
67684 + * according to chip. otherwise, we use user's configuration.
67685 + */
67686 + if (p_Fm->p_FmStateStruct->totalFifoSize == 0)
67687 + p_Fm->p_FmStateStruct->totalFifoSize = DEFAULT_totalFifoSize(p_Fm->p_FmStateStruct->revInfo.majorRev,
67688 + p_Fm->p_FmStateStruct->revInfo.minorRev);
67689 +
67690 + CHECK_INIT_PARAMETERS(p_Fm, CheckFmParameters);
67691 +
67692 + p_FmDriverParam = p_Fm->p_FmDriverParam;
67693 +
67694 + FM_GetRevision(p_Fm, &revInfo);
67695 +
67696 + /* clear revision-dependent non existing exception */
67697 +#ifdef FM_NO_DISPATCH_RAM_ECC
67698 + if ((revInfo.majorRev != 4) &&
67699 + (revInfo.majorRev < 6))
67700 + p_Fm->p_FmStateStruct->exceptions &= ~FM_EX_BMI_DISPATCH_RAM_ECC;
67701 +#endif /* FM_NO_DISPATCH_RAM_ECC */
67702 +
67703 +#ifdef FM_QMI_NO_ECC_EXCEPTIONS
67704 + if (revInfo.majorRev == 4)
67705 + p_Fm->p_FmStateStruct->exceptions &= ~(FM_EX_QMI_SINGLE_ECC | FM_EX_QMI_DOUBLE_ECC);
67706 +#endif /* FM_QMI_NO_ECC_EXCEPTIONS */
67707 +
67708 +#ifdef FM_QMI_NO_SINGLE_ECC_EXCEPTION
67709 + if (revInfo.majorRev >= 6)
67710 + p_Fm->p_FmStateStruct->exceptions &= ~FM_EX_QMI_SINGLE_ECC;
67711 +#endif /* FM_QMI_NO_SINGLE_ECC_EXCEPTION */
67712 +
67713 + FmMuramClear(p_Fm->h_FmMuram);
67714 +
67715 + /* clear CPG */
67716 + IOMemSet32(UINT_TO_PTR(p_Fm->baseAddr + FM_MM_CGP), 0, FM_PORT_NUM_OF_CONGESTION_GRPS);
67717 +
67718 + /* add to the default exceptions the user's definitions */
67719 + p_Fm->p_FmStateStruct->exceptions |= p_Fm->userSetExceptions;
67720 +
67721 + /* Reset the FM if required */
67722 + if (p_Fm->resetOnInit)
67723 + {
67724 +#ifdef FM_UCODE_NOT_RESET_ERRATA_BUGZILLA6173
67725 + if ((err = FwNotResetErratumBugzilla6173WA(p_Fm)) != E_OK)
67726 + RETURN_ERROR(MAJOR, err, NO_MSG);
67727 +#else /* not FM_UCODE_NOT_RESET_ERRATA_BUGZILLA6173 */
67728 +
67729 + if (p_Fm->f_ResetOnInitOverride)
67730 + {
67731 + /* Perform user specific FMan reset */
67732 + p_Fm->f_ResetOnInitOverride(h_Fm);
67733 + }
67734 + else
67735 + {
67736 + /* Perform FMan reset */
67737 + FmReset(h_Fm);
67738 + }
67739 +
67740 + if (fman_is_qmi_halt_not_busy_state(p_Fm->p_FmQmiRegs))
67741 + {
67742 + fman_resume(p_Fm->p_FmFpmRegs);
67743 + XX_UDelay(100);
67744 + }
67745 +#endif /* not FM_UCODE_NOT_RESET_ERRATA_BUGZILLA6173 */
67746 + }
67747 +
67748 +#ifdef FM_UCODE_NOT_RESET_ERRATA_BUGZILLA6173
67749 + if (!p_Fm->resetOnInit) /* Skip operations done in errata workaround */
67750 + {
67751 +#endif /* FM_UCODE_NOT_RESET_ERRATA_BUGZILLA6173 */
67752 + /* Load FMan-Controller code to IRAM */
67753 +
67754 + ClearIRam(p_Fm);
67755 +
67756 + if (p_Fm->firmware.p_Code && (LoadFmanCtrlCode(p_Fm) != E_OK))
67757 + RETURN_ERROR(MAJOR, E_INVALID_STATE, NO_MSG);
67758 +#ifdef FM_UCODE_NOT_RESET_ERRATA_BUGZILLA6173
67759 + }
67760 +#endif /* FM_UCODE_NOT_RESET_ERRATA_BUGZILLA6173 */
67761 +
67762 +#ifdef FM_CAPWAP_SUPPORT
67763 + /* save first 256 byte in MURAM */
67764 + p_Fm->resAddr = PTR_TO_UINT(FM_MURAM_AllocMem(p_Fm->h_FmMuram, 256, 0));
67765 + if (!p_Fm->resAddr)
67766 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("MURAM alloc for reserved Area failed"));
67767 +
67768 + WRITE_BLOCK(UINT_TO_PTR(p_Fm->resAddr), 0, 256);
67769 +#endif /* FM_CAPWAP_SUPPORT */
67770 +
67771 +#if (DPAA_VERSION >= 11)
67772 + p_Fm->partVSPBase = AllocVSPsForPartition(h_Fm, p_Fm->partVSPBase, p_Fm->partNumOfVSPs, p_Fm->guestId);
67773 + if (p_Fm->partVSPBase == (uint8_t)(ILLEGAL_BASE))
67774 + DBG(WARNING, ("partition VSPs allocation is FAILED"));
67775 +#endif /* (DPAA_VERSION >= 11) */
67776 +
67777 + /* General FM driver initialization */
67778 + p_Fm->fmMuramPhysBaseAddr =
67779 + (uint64_t)(XX_VirtToPhys(UINT_TO_PTR(p_Fm->baseAddr + FM_MM_MURAM)));
67780 +
67781 + for (i=0;i<e_FM_EV_DUMMY_LAST;i++)
67782 + p_Fm->intrMng[i].f_Isr = UnimplementedIsr;
67783 + for (i=0;i<FM_NUM_OF_FMAN_CTRL_EVENT_REGS;i++)
67784 + p_Fm->fmanCtrlIntr[i].f_Isr = UnimplementedFmanCtrlIsr;
67785 +
67786 + p_FmDriverParam->exceptions = p_Fm->p_FmStateStruct->exceptions;
67787 +
67788 + /**********************/
67789 + /* Init DMA Registers */
67790 + /**********************/
67791 + err = InitFmDma(p_Fm);
67792 + if (err != E_OK)
67793 + {
67794 + FreeInitResources(p_Fm);
67795 + RETURN_ERROR(MAJOR, err, NO_MSG);
67796 + }
67797 +
67798 + /**********************/
67799 + /* Init FPM Registers */
67800 + /**********************/
67801 + err = InitFmFpm(p_Fm);
67802 + if (err != E_OK)
67803 + {
67804 + FreeInitResources(p_Fm);
67805 + RETURN_ERROR(MAJOR, err, NO_MSG);
67806 + }
67807 +
67808 + /* define common resources */
67809 + /* allocate MURAM for FIFO according to total size */
67810 + p_Fm->fifoBaseAddr = PTR_TO_UINT(FM_MURAM_AllocMem(p_Fm->h_FmMuram,
67811 + p_Fm->p_FmStateStruct->totalFifoSize,
67812 + BMI_FIFO_ALIGN));
67813 + if (!p_Fm->fifoBaseAddr)
67814 + {
67815 + FreeInitResources(p_Fm);
67816 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("MURAM alloc for BMI FIFO failed"));
67817 + }
67818 +
67819 + p_FmDriverParam->fifo_base_addr = (uint32_t)(XX_VirtToPhys(UINT_TO_PTR(p_Fm->fifoBaseAddr)) - p_Fm->fmMuramPhysBaseAddr);
67820 + p_FmDriverParam->total_fifo_size = p_Fm->p_FmStateStruct->totalFifoSize;
67821 + p_FmDriverParam->total_num_of_tasks = p_Fm->p_FmStateStruct->totalNumOfTasks;
67822 + p_FmDriverParam->clk_freq = p_Fm->p_FmStateStruct->fmClkFreq;
67823 +
67824 + /**********************/
67825 + /* Init BMI Registers */
67826 + /**********************/
67827 + err = InitFmBmi(p_Fm);
67828 + if (err != E_OK)
67829 + {
67830 + FreeInitResources(p_Fm);
67831 + RETURN_ERROR(MAJOR, err, NO_MSG);
67832 + }
67833 +
67834 + /**********************/
67835 + /* Init QMI Registers */
67836 + /**********************/
67837 + err = InitFmQmi(p_Fm);
67838 + if (err != E_OK)
67839 + {
67840 + FreeInitResources(p_Fm);
67841 + RETURN_ERROR(MAJOR, err, NO_MSG);
67842 + }
67843 +
67844 + /* build the FM master partition IPC address */
67845 + if (Sprint (p_Fm->fmModuleName, "FM_%d_%d",p_Fm->p_FmStateStruct->fmId, NCSW_MASTER_ID) != 6)
67846 + {
67847 + FreeInitResources(p_Fm);
67848 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Sprint failed"));
67849 + }
67850 +
67851 + err = XX_IpcRegisterMsgHandler(p_Fm->fmModuleName, FmHandleIpcMsgCB, p_Fm, FM_IPC_MAX_REPLY_SIZE);
67852 + if (err)
67853 + {
67854 + FreeInitResources(p_Fm);
67855 + RETURN_ERROR(MAJOR, err, NO_MSG);
67856 + }
67857 +
67858 + /* Register the FM interrupts handlers */
67859 + if (p_Fm->p_FmStateStruct->irq != NO_IRQ)
67860 + {
67861 + XX_SetIntr(p_Fm->p_FmStateStruct->irq, FM_EventIsr, p_Fm);
67862 + XX_EnableIntr(p_Fm->p_FmStateStruct->irq);
67863 + }
67864 +
67865 + if (p_Fm->p_FmStateStruct->errIrq != NO_IRQ)
67866 + {
67867 + XX_SetIntr(p_Fm->p_FmStateStruct->errIrq, (void (*) (t_Handle))FM_ErrorIsr, p_Fm);
67868 + XX_EnableIntr(p_Fm->p_FmStateStruct->errIrq);
67869 + }
67870 +
67871 + err = (t_Error)fman_enable(&fman_rg , p_FmDriverParam);
67872 + if (err != E_OK)
67873 + return err; /* FIXME */
67874 +
67875 + EnableTimeStamp(p_Fm);
67876 +
67877 + if (p_Fm->firmware.p_Code)
67878 + {
67879 + XX_Free(p_Fm->firmware.p_Code);
67880 + p_Fm->firmware.p_Code = NULL;
67881 + }
67882 +
67883 + XX_Free(p_Fm->p_FmDriverParam);
67884 + p_Fm->p_FmDriverParam = NULL;
67885 +
67886 + return E_OK;
67887 +}
67888 +
67889 +/**************************************************************************//**
67890 + @Function FM_Free
67891 +
67892 + @Description Frees all resources that were assigned to FM module.
67893 +
67894 + Calling this routine invalidates the descriptor.
67895 +
67896 + @Param[in] h_Fm - FM module descriptor
67897 +
67898 + @Return E_OK on success; Error code otherwise.
67899 +*//***************************************************************************/
67900 +t_Error FM_Free(t_Handle h_Fm)
67901 +{
67902 + t_Fm *p_Fm = (t_Fm*)h_Fm;
67903 + struct fman_rg fman_rg;
67904 +
67905 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
67906 +
67907 + fman_rg.bmi_rg = p_Fm->p_FmBmiRegs;
67908 + fman_rg.qmi_rg = p_Fm->p_FmQmiRegs;
67909 + fman_rg.fpm_rg = p_Fm->p_FmFpmRegs;
67910 + fman_rg.dma_rg = p_Fm->p_FmDmaRegs;
67911 +
67912 + if (p_Fm->guestId != NCSW_MASTER_ID)
67913 + {
67914 +#if (DPAA_VERSION >= 11)
67915 + FreeVSPsForPartition(h_Fm, p_Fm->partVSPBase, p_Fm->partNumOfVSPs, p_Fm->guestId);
67916 +
67917 + if (p_Fm->p_FmSp)
67918 + {
67919 + XX_Free(p_Fm->p_FmSp);
67920 + p_Fm->p_FmSp = NULL;
67921 + }
67922 +#endif /* (DPAA_VERSION >= 11) */
67923 +
67924 + if (p_Fm->fmModuleName[0] != 0)
67925 + XX_IpcUnregisterMsgHandler(p_Fm->fmModuleName);
67926 +
67927 + if (!p_Fm->recoveryMode)
67928 + XX_Free(p_Fm->p_FmStateStruct);
67929 +
67930 + XX_Free(p_Fm);
67931 +
67932 + return E_OK;
67933 + }
67934 +
67935 + fman_free_resources(&fman_rg);
67936 +
67937 + if ((p_Fm->guestId == NCSW_MASTER_ID) && (p_Fm->fmModuleName[0] != 0))
67938 + XX_IpcUnregisterMsgHandler(p_Fm->fmModuleName);
67939 +
67940 + if (p_Fm->p_FmStateStruct)
67941 + {
67942 + if (p_Fm->p_FmStateStruct->irq != NO_IRQ)
67943 + {
67944 + XX_DisableIntr(p_Fm->p_FmStateStruct->irq);
67945 + XX_FreeIntr(p_Fm->p_FmStateStruct->irq);
67946 + }
67947 + if (p_Fm->p_FmStateStruct->errIrq != NO_IRQ)
67948 + {
67949 + XX_DisableIntr(p_Fm->p_FmStateStruct->errIrq);
67950 + XX_FreeIntr(p_Fm->p_FmStateStruct->errIrq);
67951 + }
67952 + }
67953 +
67954 +#if (DPAA_VERSION >= 11)
67955 + FreeVSPsForPartition(h_Fm, p_Fm->partVSPBase, p_Fm->partNumOfVSPs, p_Fm->guestId);
67956 +
67957 + if (p_Fm->p_FmSp)
67958 + {
67959 + XX_Free(p_Fm->p_FmSp);
67960 + p_Fm->p_FmSp = NULL;
67961 + }
67962 +#endif /* (DPAA_VERSION >= 11) */
67963 +
67964 + if (p_Fm->h_Spinlock)
67965 + XX_FreeSpinlock(p_Fm->h_Spinlock);
67966 +
67967 + if (p_Fm->p_FmDriverParam)
67968 + {
67969 + if (p_Fm->firmware.p_Code)
67970 + XX_Free(p_Fm->firmware.p_Code);
67971 + XX_Free(p_Fm->p_FmDriverParam);
67972 + p_Fm->p_FmDriverParam = NULL;
67973 + }
67974 +
67975 + FreeInitResources(p_Fm);
67976 +
67977 + if (!p_Fm->recoveryMode && p_Fm->p_FmStateStruct)
67978 + XX_Free(p_Fm->p_FmStateStruct);
67979 +
67980 + XX_Free(p_Fm);
67981 +
67982 + return E_OK;
67983 +}
67984 +
67985 +/*************************************************/
67986 +/* API Advanced Init unit functions */
67987 +/*************************************************/
67988 +
67989 +t_Error FM_ConfigResetOnInit(t_Handle h_Fm, bool enable)
67990 +{
67991 + t_Fm *p_Fm = (t_Fm*)h_Fm;
67992 +
67993 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
67994 + SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE);
67995 + SANITY_CHECK_RETURN_ERROR((p_Fm->guestId == NCSW_MASTER_ID), E_NOT_SUPPORTED);
67996 +
67997 + p_Fm->resetOnInit = enable;
67998 +
67999 + return E_OK;
68000 +}
68001 +
68002 +t_Error FM_ConfigResetOnInitOverrideCallback(t_Handle h_Fm, t_FmResetOnInitOverrideCallback *f_ResetOnInitOverride)
68003 +{
68004 + t_Fm *p_Fm = (t_Fm*)h_Fm;
68005 +
68006 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
68007 + SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE);
68008 + SANITY_CHECK_RETURN_ERROR((p_Fm->guestId == NCSW_MASTER_ID), E_NOT_SUPPORTED);
68009 +
68010 + p_Fm->f_ResetOnInitOverride = f_ResetOnInitOverride;
68011 +
68012 + return E_OK;
68013 +}
68014 +
68015 +t_Error FM_ConfigTotalFifoSize(t_Handle h_Fm, uint32_t totalFifoSize)
68016 +{
68017 + t_Fm *p_Fm = (t_Fm*)h_Fm;
68018 +
68019 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
68020 + SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE);
68021 + SANITY_CHECK_RETURN_ERROR((p_Fm->guestId == NCSW_MASTER_ID), E_NOT_SUPPORTED);
68022 +
68023 + p_Fm->p_FmStateStruct->totalFifoSize = totalFifoSize;
68024 +
68025 + return E_OK;
68026 +}
68027 +
68028 +t_Error FM_ConfigDmaCacheOverride(t_Handle h_Fm, e_FmDmaCacheOverride cacheOverride)
68029 +{
68030 + t_Fm *p_Fm = (t_Fm*)h_Fm;
68031 + enum fman_dma_cache_override fsl_cache_override;
68032 +
68033 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
68034 + SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE);
68035 + SANITY_CHECK_RETURN_ERROR((p_Fm->guestId == NCSW_MASTER_ID), E_NOT_SUPPORTED);
68036 +
68037 + FMAN_CACHE_OVERRIDE_TRANS(fsl_cache_override, cacheOverride)
68038 + p_Fm->p_FmDriverParam->dma_cache_override = fsl_cache_override;
68039 +
68040 + return E_OK;
68041 +}
68042 +
68043 +t_Error FM_ConfigDmaAidOverride(t_Handle h_Fm, bool aidOverride)
68044 +{
68045 + t_Fm *p_Fm = (t_Fm*)h_Fm;
68046 +
68047 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
68048 + SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE);
68049 + SANITY_CHECK_RETURN_ERROR((p_Fm->guestId == NCSW_MASTER_ID), E_NOT_SUPPORTED);
68050 +
68051 + p_Fm->p_FmDriverParam->dma_aid_override = aidOverride;
68052 +
68053 + return E_OK;
68054 +}
68055 +
68056 +t_Error FM_ConfigDmaAidMode(t_Handle h_Fm, e_FmDmaAidMode aidMode)
68057 +{
68058 + t_Fm *p_Fm = (t_Fm*)h_Fm;
68059 + enum fman_dma_aid_mode fsl_aid_mode;
68060 +
68061 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
68062 + SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE);
68063 + SANITY_CHECK_RETURN_ERROR((p_Fm->guestId == NCSW_MASTER_ID), E_NOT_SUPPORTED);
68064 +
68065 + FMAN_AID_MODE_TRANS(fsl_aid_mode, aidMode);
68066 + p_Fm->p_FmDriverParam->dma_aid_mode = fsl_aid_mode;
68067 +
68068 + return E_OK;
68069 +}
68070 +
68071 +t_Error FM_ConfigDmaAxiDbgNumOfBeats(t_Handle h_Fm, uint8_t axiDbgNumOfBeats)
68072 +{
68073 + t_Fm *p_Fm = (t_Fm*)h_Fm;
68074 +
68075 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
68076 + SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE);
68077 + SANITY_CHECK_RETURN_ERROR((p_Fm->guestId == NCSW_MASTER_ID), E_NOT_SUPPORTED);
68078 +
68079 +#if (DPAA_VERSION >= 11)
68080 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("Not available for this FM revision!"));
68081 +#else
68082 + p_Fm->p_FmDriverParam->dma_axi_dbg_num_of_beats = axiDbgNumOfBeats;
68083 +
68084 + return E_OK;
68085 +#endif /* (DPAA_VERSION >= 11) */
68086 +}
68087 +
68088 +t_Error FM_ConfigDmaCamNumOfEntries(t_Handle h_Fm, uint8_t numOfEntries)
68089 +{
68090 + t_Fm *p_Fm = (t_Fm*)h_Fm;
68091 +
68092 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
68093 + SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE);
68094 + SANITY_CHECK_RETURN_ERROR((p_Fm->guestId == NCSW_MASTER_ID), E_NOT_SUPPORTED);
68095 +
68096 + p_Fm->p_FmDriverParam->dma_cam_num_of_entries = numOfEntries;
68097 +
68098 + return E_OK;
68099 +}
68100 +
68101 +t_Error FM_ConfigDmaDbgCounter(t_Handle h_Fm, e_FmDmaDbgCntMode fmDmaDbgCntMode)
68102 +{
68103 + t_Fm *p_Fm = (t_Fm*)h_Fm;
68104 + enum fman_dma_dbg_cnt_mode fsl_dma_dbg_cnt;
68105 +
68106 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
68107 + SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE);
68108 + SANITY_CHECK_RETURN_ERROR((p_Fm->guestId == NCSW_MASTER_ID), E_NOT_SUPPORTED);
68109 +
68110 + FMAN_DMA_DBG_CNT_TRANS(fsl_dma_dbg_cnt, fmDmaDbgCntMode);
68111 + p_Fm->p_FmDriverParam->dma_dbg_cnt_mode = fsl_dma_dbg_cnt;
68112 +
68113 + return E_OK;
68114 +}
68115 +
68116 +t_Error FM_ConfigDmaStopOnBusErr(t_Handle h_Fm, bool stop)
68117 +{
68118 + t_Fm *p_Fm = (t_Fm*)h_Fm;
68119 +
68120 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
68121 + SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE);
68122 + SANITY_CHECK_RETURN_ERROR((p_Fm->guestId == NCSW_MASTER_ID), E_NOT_SUPPORTED);
68123 +
68124 + p_Fm->p_FmDriverParam->dma_stop_on_bus_error = stop;
68125 +
68126 + return E_OK;
68127 +}
68128 +
68129 +t_Error FM_ConfigDmaEmergency(t_Handle h_Fm, t_FmDmaEmergency *p_Emergency)
68130 +{
68131 + t_Fm *p_Fm = (t_Fm*)h_Fm;
68132 + enum fman_dma_emergency_level fsl_dma_emer;
68133 +
68134 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
68135 + SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE);
68136 + SANITY_CHECK_RETURN_ERROR((p_Fm->guestId == NCSW_MASTER_ID), E_NOT_SUPPORTED);
68137 +
68138 + FMAN_DMA_EMER_TRANS(fsl_dma_emer, p_Emergency->emergencyLevel);
68139 + p_Fm->p_FmDriverParam->dma_en_emergency = TRUE;
68140 + p_Fm->p_FmDriverParam->dma_emergency_bus_select = (uint32_t)p_Emergency->emergencyBusSelect;
68141 + p_Fm->p_FmDriverParam->dma_emergency_level = fsl_dma_emer;
68142 +
68143 + return E_OK;
68144 +}
68145 +
68146 +t_Error FM_ConfigDmaEmergencySmoother(t_Handle h_Fm, uint32_t emergencyCnt)
68147 +{
68148 + t_Fm *p_Fm = (t_Fm*)h_Fm;
68149 +
68150 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
68151 + SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE);
68152 + SANITY_CHECK_RETURN_ERROR((p_Fm->guestId == NCSW_MASTER_ID), E_NOT_SUPPORTED);
68153 +
68154 + p_Fm->p_FmDriverParam->dma_en_emergency_smoother = TRUE;
68155 + p_Fm->p_FmDriverParam->dma_emergency_switch_counter = emergencyCnt;
68156 +
68157 + return E_OK;
68158 +}
68159 +
68160 +t_Error FM_ConfigDmaErr(t_Handle h_Fm, e_FmDmaErr dmaErr)
68161 +{
68162 + t_Fm *p_Fm = (t_Fm*)h_Fm;
68163 + enum fman_dma_err fsl_dma_err;
68164 +
68165 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
68166 + SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE);
68167 + SANITY_CHECK_RETURN_ERROR((p_Fm->guestId == NCSW_MASTER_ID), E_NOT_SUPPORTED);
68168 +
68169 + FMAN_DMA_ERR_TRANS(fsl_dma_err, dmaErr);
68170 + p_Fm->p_FmDriverParam->dma_err = fsl_dma_err;
68171 +
68172 + return E_OK;
68173 +}
68174 +
68175 +t_Error FM_ConfigCatastrophicErr(t_Handle h_Fm, e_FmCatastrophicErr catastrophicErr)
68176 +{
68177 + t_Fm *p_Fm = (t_Fm*)h_Fm;
68178 + enum fman_catastrophic_err fsl_catastrophic_err;
68179 +
68180 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
68181 + SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE);
68182 + SANITY_CHECK_RETURN_ERROR((p_Fm->guestId == NCSW_MASTER_ID), E_NOT_SUPPORTED);
68183 +
68184 + FMAN_CATASTROPHIC_ERR_TRANS(fsl_catastrophic_err, catastrophicErr);
68185 + p_Fm->p_FmDriverParam->catastrophic_err = fsl_catastrophic_err;
68186 +
68187 + return E_OK;
68188 +}
68189 +
68190 +t_Error FM_ConfigEnableMuramTestMode(t_Handle h_Fm)
68191 +{
68192 + t_Fm *p_Fm = (t_Fm*)h_Fm;
68193 +
68194 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
68195 + SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE);
68196 + SANITY_CHECK_RETURN_ERROR((p_Fm->guestId == NCSW_MASTER_ID), E_NOT_SUPPORTED);
68197 +
68198 + if (p_Fm->p_FmStateStruct->revInfo.majorRev >= 6)
68199 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("Not available for this FM revision!"));
68200 +
68201 + p_Fm->p_FmDriverParam->en_muram_test_mode = TRUE;
68202 +
68203 + return E_OK;
68204 +}
68205 +
68206 +t_Error FM_ConfigEnableIramTestMode(t_Handle h_Fm)
68207 +{
68208 + t_Fm *p_Fm = (t_Fm*)h_Fm;
68209 +
68210 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE );
68211 + SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE);
68212 + SANITY_CHECK_RETURN_ERROR((p_Fm->guestId == NCSW_MASTER_ID), E_NOT_SUPPORTED);
68213 +
68214 + if (p_Fm->p_FmStateStruct->revInfo.majorRev >= 6)
68215 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("Not available for this FM revision!"));
68216 +
68217 + p_Fm->p_FmDriverParam->en_iram_test_mode = TRUE;
68218 +
68219 + return E_OK;
68220 +}
68221 +
68222 +t_Error FM_ConfigHaltOnExternalActivation(t_Handle h_Fm, bool enable)
68223 +{
68224 + t_Fm *p_Fm = (t_Fm*)h_Fm;
68225 +
68226 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
68227 + SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE);
68228 + SANITY_CHECK_RETURN_ERROR((p_Fm->guestId == NCSW_MASTER_ID), E_NOT_SUPPORTED);
68229 +
68230 + p_Fm->p_FmDriverParam->halt_on_external_activ = enable;
68231 +
68232 + return E_OK;
68233 +}
68234 +
68235 +t_Error FM_ConfigHaltOnUnrecoverableEccError(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 + if (p_Fm->p_FmStateStruct->revInfo.majorRev >= 6)
68244 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("Not available for this FM revision!"));
68245 +
68246 + p_Fm->p_FmDriverParam->halt_on_unrecov_ecc_err = enable;
68247 +
68248 + return E_OK;
68249 +}
68250 +
68251 +t_Error FM_ConfigException(t_Handle h_Fm, e_FmExceptions exception, bool enable)
68252 +{
68253 + t_Fm *p_Fm = (t_Fm*)h_Fm;
68254 + uint32_t bitMask = 0;
68255 +
68256 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
68257 + SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE);
68258 + SANITY_CHECK_RETURN_ERROR((p_Fm->guestId == NCSW_MASTER_ID), E_NOT_SUPPORTED);
68259 +
68260 + GET_EXCEPTION_FLAG(bitMask, exception);
68261 + if (bitMask)
68262 + {
68263 + if (enable)
68264 + p_Fm->userSetExceptions |= bitMask;
68265 + else
68266 + p_Fm->p_FmStateStruct->exceptions &= ~bitMask;
68267 + }
68268 + else
68269 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Undefined exception"));
68270 +
68271 + return E_OK;
68272 +}
68273 +
68274 +t_Error FM_ConfigExternalEccRamsEnable(t_Handle h_Fm, bool enable)
68275 +{
68276 + t_Fm *p_Fm = (t_Fm*)h_Fm;
68277 +
68278 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
68279 + SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE);
68280 + SANITY_CHECK_RETURN_ERROR((p_Fm->guestId == NCSW_MASTER_ID), E_NOT_SUPPORTED);
68281 +
68282 + p_Fm->p_FmDriverParam->external_ecc_rams_enable = enable;
68283 +
68284 + return E_OK;
68285 +}
68286 +
68287 +t_Error FM_ConfigTnumAgingPeriod(t_Handle h_Fm, uint16_t tnumAgingPeriod)
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->tnum_aging_period = tnumAgingPeriod;
68296 + p_Fm->tnumAgingPeriod = p_Fm->p_FmDriverParam->tnum_aging_period;
68297 +
68298 + return E_OK;
68299 +}
68300 +
68301 +/****************************************************/
68302 +/* Hidden-DEBUG Only API */
68303 +/****************************************************/
68304 +
68305 +t_Error FM_ConfigThresholds(t_Handle h_Fm, t_FmThresholds *p_FmThresholds)
68306 +{
68307 + t_Fm *p_Fm = (t_Fm*)h_Fm;
68308 +
68309 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
68310 + SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE);
68311 + SANITY_CHECK_RETURN_ERROR((p_Fm->guestId == NCSW_MASTER_ID), E_NOT_SUPPORTED);
68312 +
68313 + p_Fm->p_FmDriverParam->disp_limit_tsh = p_FmThresholds->dispLimit;
68314 + p_Fm->p_FmDriverParam->prs_disp_tsh = p_FmThresholds->prsDispTh;
68315 + p_Fm->p_FmDriverParam->plcr_disp_tsh = p_FmThresholds->plcrDispTh;
68316 + p_Fm->p_FmDriverParam->kg_disp_tsh = p_FmThresholds->kgDispTh;
68317 + p_Fm->p_FmDriverParam->bmi_disp_tsh = p_FmThresholds->bmiDispTh;
68318 + p_Fm->p_FmDriverParam->qmi_enq_disp_tsh = p_FmThresholds->qmiEnqDispTh;
68319 + p_Fm->p_FmDriverParam->qmi_deq_disp_tsh = p_FmThresholds->qmiDeqDispTh;
68320 + p_Fm->p_FmDriverParam->fm_ctl1_disp_tsh = p_FmThresholds->fmCtl1DispTh;
68321 + p_Fm->p_FmDriverParam->fm_ctl2_disp_tsh = p_FmThresholds->fmCtl2DispTh;
68322 +
68323 + return E_OK;
68324 +}
68325 +
68326 +t_Error FM_ConfigDmaSosEmergencyThreshold(t_Handle h_Fm, uint32_t dmaSosEmergency)
68327 +{
68328 + t_Fm *p_Fm = (t_Fm*)h_Fm;
68329 +
68330 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
68331 + SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE);
68332 + SANITY_CHECK_RETURN_ERROR((p_Fm->guestId == NCSW_MASTER_ID), E_NOT_SUPPORTED);
68333 +
68334 + p_Fm->p_FmDriverParam->dma_sos_emergency = dmaSosEmergency;
68335 +
68336 + return E_OK;
68337 +}
68338 +
68339 +t_Error FM_ConfigDmaWriteBufThresholds(t_Handle h_Fm, t_FmDmaThresholds *p_FmDmaThresholds)
68340 +
68341 +{
68342 + t_Fm *p_Fm = (t_Fm*)h_Fm;
68343 +
68344 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
68345 + SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE);
68346 + SANITY_CHECK_RETURN_ERROR((p_Fm->guestId == NCSW_MASTER_ID), E_NOT_SUPPORTED);
68347 +
68348 +#if (DPAA_VERSION >= 11)
68349 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("Not available for this FM revision!"));
68350 +#else
68351 + p_Fm->p_FmDriverParam->dma_write_buf_tsh_asrt_emer = p_FmDmaThresholds->assertEmergency;
68352 + p_Fm->p_FmDriverParam->dma_write_buf_tsh_clr_emer = p_FmDmaThresholds->clearEmergency;
68353 +
68354 + return E_OK;
68355 +#endif
68356 +}
68357 +
68358 +t_Error FM_ConfigDmaCommQThresholds(t_Handle h_Fm, t_FmDmaThresholds *p_FmDmaThresholds)
68359 +{
68360 + t_Fm *p_Fm = (t_Fm*)h_Fm;
68361 +
68362 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
68363 + SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE);
68364 + SANITY_CHECK_RETURN_ERROR((p_Fm->guestId == NCSW_MASTER_ID), E_NOT_SUPPORTED);
68365 +
68366 + p_Fm->p_FmDriverParam->dma_comm_qtsh_asrt_emer = p_FmDmaThresholds->assertEmergency;
68367 + p_Fm->p_FmDriverParam->dma_comm_qtsh_clr_emer = p_FmDmaThresholds->clearEmergency;
68368 +
68369 + return E_OK;
68370 +}
68371 +
68372 +t_Error FM_ConfigDmaReadBufThresholds(t_Handle h_Fm, t_FmDmaThresholds *p_FmDmaThresholds)
68373 +{
68374 + t_Fm *p_Fm = (t_Fm*)h_Fm;
68375 +
68376 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
68377 + SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE);
68378 + SANITY_CHECK_RETURN_ERROR((p_Fm->guestId == NCSW_MASTER_ID), E_NOT_SUPPORTED);
68379 +
68380 +#if (DPAA_VERSION >= 11)
68381 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("Not available for this FM revision!"));
68382 +#else
68383 + p_Fm->p_FmDriverParam->dma_read_buf_tsh_clr_emer = p_FmDmaThresholds->clearEmergency;
68384 + p_Fm->p_FmDriverParam->dma_read_buf_tsh_asrt_emer = p_FmDmaThresholds->assertEmergency;
68385 +
68386 + return E_OK;
68387 +#endif
68388 +}
68389 +
68390 +t_Error FM_ConfigDmaWatchdog(t_Handle h_Fm, uint32_t watchdogValue)
68391 +{
68392 + t_Fm *p_Fm = (t_Fm*)h_Fm;
68393 +
68394 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
68395 + SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE);
68396 + SANITY_CHECK_RETURN_ERROR((p_Fm->guestId == NCSW_MASTER_ID), E_NOT_SUPPORTED);
68397 +
68398 + p_Fm->p_FmDriverParam->dma_watchdog = watchdogValue;
68399 +
68400 + return E_OK;
68401 +}
68402 +
68403 +t_Error FM_ConfigEnableCounters(t_Handle h_Fm)
68404 +{
68405 + t_Fm *p_Fm = (t_Fm*)h_Fm;
68406 +
68407 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
68408 + SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE);
68409 +UNUSED(p_Fm);
68410 +
68411 + return E_OK;
68412 +}
68413 +
68414 +t_Error FmGetSetParams(t_Handle h_Fm, t_FmGetSetParams *p_Params)
68415 +{
68416 + t_Fm* p_Fm = (t_Fm*)h_Fm;
68417 + if (p_Params->setParams.type & UPDATE_FM_CLD)
68418 + {
68419 + WRITE_UINT32(p_Fm->p_FmFpmRegs->fm_cld, GET_UINT32(
68420 + p_Fm->p_FmFpmRegs->fm_cld) | 0x00000800);
68421 + }
68422 + if (p_Params->setParams.type & CLEAR_IRAM_READY)
68423 + {
68424 + t_FMIramRegs *p_Iram = (t_FMIramRegs *)UINT_TO_PTR(p_Fm->baseAddr + FM_MM_IMEM);
68425 + WRITE_UINT32(p_Iram->iready,GET_UINT32(p_Iram->iready) & ~IRAM_READY);
68426 + }
68427 + if (p_Params->setParams.type & UPDATE_FPM_EXTC)
68428 + WRITE_UINT32(p_Fm->p_FmFpmRegs->fmfp_extc,0x80000000);
68429 + if (p_Params->setParams.type & UPDATE_FPM_EXTC_CLEAR)
68430 + WRITE_UINT32(p_Fm->p_FmFpmRegs->fmfp_extc,0x00800000);
68431 + if (p_Params->setParams.type & UPDATE_FPM_BRKC_SLP)
68432 + {
68433 + if (p_Params->setParams.sleep)
68434 + WRITE_UINT32(p_Fm->p_FmFpmRegs->fmfp_brkc, GET_UINT32(
68435 + p_Fm->p_FmFpmRegs->fmfp_brkc) | FPM_BRKC_SLP);
68436 + else
68437 + WRITE_UINT32(p_Fm->p_FmFpmRegs->fmfp_brkc, GET_UINT32(
68438 + p_Fm->p_FmFpmRegs->fmfp_brkc) & ~FPM_BRKC_SLP);
68439 + }
68440 + if (p_Params->getParams.type & GET_FM_CLD)
68441 + p_Params->getParams.fm_cld = GET_UINT32(p_Fm->p_FmFpmRegs->fm_cld);
68442 + if (p_Params->getParams.type & GET_FMQM_GS)
68443 + p_Params->getParams.fmqm_gs = GET_UINT32(p_Fm->p_FmQmiRegs->fmqm_gs);
68444 + if (p_Params->getParams.type & GET_FM_NPI)
68445 + p_Params->getParams.fm_npi = GET_UINT32(p_Fm->p_FmFpmRegs->fm_npi);
68446 + if (p_Params->getParams.type & GET_FMFP_EXTC)
68447 + p_Params->getParams.fmfp_extc = GET_UINT32(p_Fm->p_FmFpmRegs->fmfp_extc);
68448 + return E_OK;
68449 +}
68450 +
68451 +
68452 +/****************************************************/
68453 +/* API Run-time Control uint functions */
68454 +/****************************************************/
68455 +void FM_EventIsr(t_Handle h_Fm)
68456 +{
68457 +#define FM_M_CALL_1G_MAC_ISR(_id) \
68458 + { \
68459 + if (p_Fm->guestId != p_Fm->intrMng[(e_FmInterModuleEvent)(e_FM_EV_1G_MAC0+_id)].guestId) \
68460 + SendIpcIsr(p_Fm, (e_FmInterModuleEvent)(e_FM_EV_1G_MAC0+_id), pending); \
68461 + else \
68462 + 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);\
68463 + }
68464 +#define FM_M_CALL_10G_MAC_ISR(_id) \
68465 + { \
68466 + if (p_Fm->guestId != p_Fm->intrMng[(e_FmInterModuleEvent)(e_FM_EV_10G_MAC0+_id)].guestId) \
68467 + SendIpcIsr(p_Fm, (e_FmInterModuleEvent)(e_FM_EV_10G_MAC0+_id), pending); \
68468 + else \
68469 + 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);\
68470 + }
68471 + t_Fm *p_Fm = (t_Fm*)h_Fm;
68472 + uint32_t pending, event;
68473 + struct fman_fpm_regs *fpm_rg;
68474 +
68475 + SANITY_CHECK_RETURN(p_Fm, E_INVALID_HANDLE);
68476 + SANITY_CHECK_RETURN(!p_Fm->p_FmDriverParam, E_INVALID_HANDLE);
68477 + SANITY_CHECK_RETURN((p_Fm->guestId == NCSW_MASTER_ID), E_NOT_SUPPORTED);
68478 +
68479 + fpm_rg = p_Fm->p_FmFpmRegs;
68480 +
68481 + /* normal interrupts */
68482 + pending = fman_get_normal_pending(fpm_rg);
68483 + if (!pending)
68484 + return;
68485 + if (pending & INTR_EN_WAKEUP) // this is a wake up from sleep interrupt
68486 + {
68487 + t_FmGetSetParams fmGetSetParams;
68488 + memset(&fmGetSetParams, 0, sizeof (t_FmGetSetParams));
68489 + fmGetSetParams.setParams.type = UPDATE_FPM_BRKC_SLP;
68490 + fmGetSetParams.setParams.sleep = 0;
68491 + FmGetSetParams(h_Fm, &fmGetSetParams);
68492 + }
68493 + if (pending & INTR_EN_QMI)
68494 + QmiEvent(p_Fm);
68495 + if (pending & INTR_EN_PRS)
68496 + p_Fm->intrMng[e_FM_EV_PRS].f_Isr(p_Fm->intrMng[e_FM_EV_PRS].h_SrcHandle);
68497 + if (pending & INTR_EN_PLCR)
68498 + p_Fm->intrMng[e_FM_EV_PLCR].f_Isr(p_Fm->intrMng[e_FM_EV_PLCR].h_SrcHandle);
68499 + if (pending & INTR_EN_TMR)
68500 + p_Fm->intrMng[e_FM_EV_TMR].f_Isr(p_Fm->intrMng[e_FM_EV_TMR].h_SrcHandle);
68501 +
68502 + /* MAC events may belong to different partitions */
68503 + if (pending & INTR_EN_1G_MAC0)
68504 + FM_M_CALL_1G_MAC_ISR(0);
68505 + if (pending & INTR_EN_1G_MAC1)
68506 + FM_M_CALL_1G_MAC_ISR(1);
68507 + if (pending & INTR_EN_1G_MAC2)
68508 + FM_M_CALL_1G_MAC_ISR(2);
68509 + if (pending & INTR_EN_1G_MAC3)
68510 + FM_M_CALL_1G_MAC_ISR(3);
68511 + if (pending & INTR_EN_1G_MAC4)
68512 + FM_M_CALL_1G_MAC_ISR(4);
68513 + if (pending & INTR_EN_1G_MAC5)
68514 + FM_M_CALL_1G_MAC_ISR(5);
68515 + if (pending & INTR_EN_1G_MAC6)
68516 + FM_M_CALL_1G_MAC_ISR(6);
68517 + if (pending & INTR_EN_1G_MAC7)
68518 + FM_M_CALL_1G_MAC_ISR(7);
68519 + if (pending & INTR_EN_10G_MAC0)
68520 + FM_M_CALL_10G_MAC_ISR(0);
68521 + if (pending & INTR_EN_10G_MAC1)
68522 + FM_M_CALL_10G_MAC_ISR(1);
68523 +
68524 + /* IM port events may belong to different partitions */
68525 + if (pending & INTR_EN_REV0)
68526 + {
68527 + event = fman_get_controller_event(fpm_rg, 0);
68528 + if (p_Fm->guestId != p_Fm->intrMng[e_FM_EV_FMAN_CTRL_0].guestId)
68529 + /*TODO IPC ISR For Fman Ctrl */
68530 + ASSERT_COND(0);
68531 + /* SendIpcIsr(p_Fm, e_FM_EV_FMAN_CTRL_0, pending); */
68532 + else
68533 + p_Fm->fmanCtrlIntr[0].f_Isr(p_Fm->fmanCtrlIntr[0].h_SrcHandle, event);
68534 +
68535 + }
68536 + if (pending & INTR_EN_REV1)
68537 + {
68538 + event = fman_get_controller_event(fpm_rg, 1);
68539 + if (p_Fm->guestId != p_Fm->intrMng[e_FM_EV_FMAN_CTRL_1].guestId)
68540 + /*TODO IPC ISR For Fman Ctrl */
68541 + ASSERT_COND(0);
68542 + /* SendIpcIsr(p_Fm, e_FM_EV_FMAN_CTRL_1, pending); */
68543 + else
68544 + p_Fm->fmanCtrlIntr[1].f_Isr(p_Fm->fmanCtrlIntr[1].h_SrcHandle, event);
68545 + }
68546 + if (pending & INTR_EN_REV2)
68547 + {
68548 + event = fman_get_controller_event(fpm_rg, 2);
68549 + if (p_Fm->guestId != p_Fm->intrMng[e_FM_EV_FMAN_CTRL_2].guestId)
68550 + /*TODO IPC ISR For Fman Ctrl */
68551 + ASSERT_COND(0);
68552 + /* SendIpcIsr(p_Fm, e_FM_EV_FMAN_CTRL_2, pending); */
68553 + else
68554 + p_Fm->fmanCtrlIntr[2].f_Isr(p_Fm->fmanCtrlIntr[2].h_SrcHandle, event);
68555 + }
68556 + if (pending & INTR_EN_REV3)
68557 + {
68558 + event = fman_get_controller_event(fpm_rg, 3);
68559 + if (p_Fm->guestId != p_Fm->intrMng[e_FM_EV_FMAN_CTRL_3].guestId)
68560 + /*TODO IPC ISR For Fman Ctrl */
68561 + ASSERT_COND(0);
68562 + /* SendIpcIsr(p_Fm, e_FM_EV_FMAN_CTRL_2, pendin3); */
68563 + else
68564 + p_Fm->fmanCtrlIntr[3].f_Isr(p_Fm->fmanCtrlIntr[3].h_SrcHandle, event);
68565 + }
68566 +#ifdef FM_MACSEC_SUPPORT
68567 + if (pending & INTR_EN_MACSEC_MAC0)
68568 + {
68569 + if (p_Fm->guestId != p_Fm->intrMng[e_FM_EV_MACSEC_MAC0].guestId)
68570 + SendIpcIsr(p_Fm, e_FM_EV_MACSEC_MAC0, pending);
68571 + else
68572 + p_Fm->intrMng[e_FM_EV_MACSEC_MAC0].f_Isr(p_Fm->intrMng[e_FM_EV_MACSEC_MAC0].h_SrcHandle);
68573 + }
68574 +#endif /* FM_MACSEC_SUPPORT */
68575 +}
68576 +
68577 +t_Error FM_ErrorIsr(t_Handle h_Fm)
68578 +{
68579 +#define FM_M_CALL_1G_MAC_ERR_ISR(_id) \
68580 + { \
68581 + if (p_Fm->guestId != p_Fm->intrMng[(e_FmInterModuleEvent)(e_FM_EV_ERR_1G_MAC0+_id)].guestId) \
68582 + SendIpcIsr(p_Fm, (e_FmInterModuleEvent)(e_FM_EV_ERR_1G_MAC0+_id), pending); \
68583 + else \
68584 + 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);\
68585 + }
68586 +#define FM_M_CALL_10G_MAC_ERR_ISR(_id) \
68587 + { \
68588 + if (p_Fm->guestId != p_Fm->intrMng[(e_FmInterModuleEvent)(e_FM_EV_ERR_10G_MAC0+_id)].guestId) \
68589 + SendIpcIsr(p_Fm, (e_FmInterModuleEvent)(e_FM_EV_ERR_10G_MAC0+_id), pending); \
68590 + else \
68591 + 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);\
68592 + }
68593 + t_Fm *p_Fm = (t_Fm*)h_Fm;
68594 + uint32_t pending;
68595 + struct fman_fpm_regs *fpm_rg;
68596 +
68597 + SANITY_CHECK_RETURN_ERROR(h_Fm, E_INVALID_HANDLE);
68598 + SANITY_CHECK_RETURN_ERROR(!p_Fm->p_FmDriverParam, E_INVALID_STATE);
68599 + SANITY_CHECK_RETURN_ERROR((p_Fm->guestId == NCSW_MASTER_ID), E_NOT_SUPPORTED);
68600 +
68601 + fpm_rg = p_Fm->p_FmFpmRegs;
68602 +
68603 + /* error interrupts */
68604 + pending = fman_get_fpm_error_interrupts(fpm_rg);
68605 + if (!pending)
68606 + return ERROR_CODE(E_EMPTY);
68607 +
68608 + if (pending & ERR_INTR_EN_BMI)
68609 + BmiErrEvent(p_Fm);
68610 + if (pending & ERR_INTR_EN_QMI)
68611 + QmiErrEvent(p_Fm);
68612 + if (pending & ERR_INTR_EN_FPM)
68613 + FpmErrEvent(p_Fm);
68614 + if (pending & ERR_INTR_EN_DMA)
68615 + DmaErrEvent(p_Fm);
68616 + if (pending & ERR_INTR_EN_IRAM)
68617 + IramErrIntr(p_Fm);
68618 + if (pending & ERR_INTR_EN_MURAM)
68619 + MuramErrIntr(p_Fm);
68620 + if (pending & ERR_INTR_EN_PRS)
68621 + p_Fm->intrMng[e_FM_EV_ERR_PRS].f_Isr(p_Fm->intrMng[e_FM_EV_ERR_PRS].h_SrcHandle);
68622 + if (pending & ERR_INTR_EN_PLCR)
68623 + p_Fm->intrMng[e_FM_EV_ERR_PLCR].f_Isr(p_Fm->intrMng[e_FM_EV_ERR_PLCR].h_SrcHandle);
68624 + if (pending & ERR_INTR_EN_KG)
68625 + p_Fm->intrMng[e_FM_EV_ERR_KG].f_Isr(p_Fm->intrMng[e_FM_EV_ERR_KG].h_SrcHandle);
68626 +
68627 + /* MAC events may belong to different partitions */
68628 + if (pending & ERR_INTR_EN_1G_MAC0)
68629 + FM_M_CALL_1G_MAC_ERR_ISR(0);
68630 + if (pending & ERR_INTR_EN_1G_MAC1)
68631 + FM_M_CALL_1G_MAC_ERR_ISR(1);
68632 + if (pending & ERR_INTR_EN_1G_MAC2)
68633 + FM_M_CALL_1G_MAC_ERR_ISR(2);
68634 + if (pending & ERR_INTR_EN_1G_MAC3)
68635 + FM_M_CALL_1G_MAC_ERR_ISR(3);
68636 + if (pending & ERR_INTR_EN_1G_MAC4)
68637 + FM_M_CALL_1G_MAC_ERR_ISR(4);
68638 + if (pending & ERR_INTR_EN_1G_MAC5)
68639 + FM_M_CALL_1G_MAC_ERR_ISR(5);
68640 + if (pending & ERR_INTR_EN_1G_MAC6)
68641 + FM_M_CALL_1G_MAC_ERR_ISR(6);
68642 + if (pending & ERR_INTR_EN_1G_MAC7)
68643 + FM_M_CALL_1G_MAC_ERR_ISR(7);
68644 + if (pending & ERR_INTR_EN_10G_MAC0)
68645 + FM_M_CALL_10G_MAC_ERR_ISR(0);
68646 + if (pending & ERR_INTR_EN_10G_MAC1)
68647 + FM_M_CALL_10G_MAC_ERR_ISR(1);
68648 +
68649 +#ifdef FM_MACSEC_SUPPORT
68650 + if (pending & ERR_INTR_EN_MACSEC_MAC0)
68651 + {
68652 + if (p_Fm->guestId != p_Fm->intrMng[e_FM_EV_ERR_MACSEC_MAC0].guestId)
68653 + SendIpcIsr(p_Fm, e_FM_EV_ERR_MACSEC_MAC0, pending);
68654 + else
68655 + p_Fm->intrMng[e_FM_EV_ERR_MACSEC_MAC0].f_Isr(p_Fm->intrMng[e_FM_EV_ERR_MACSEC_MAC0].h_SrcHandle);
68656 + }
68657 +#endif /* FM_MACSEC_SUPPORT */
68658 +
68659 + return E_OK;
68660 +}
68661 +
68662 +t_Error FM_SetPortsBandwidth(t_Handle h_Fm, t_FmPortsBandwidthParams *p_PortsBandwidth)
68663 +{
68664 + t_Fm *p_Fm = (t_Fm*)h_Fm;
68665 + int i;
68666 + uint8_t sum;
68667 + uint8_t hardwarePortId;
68668 + uint8_t weights[64];
68669 + uint8_t weight, maxPercent = 0;
68670 + struct fman_bmi_regs *bmi_rg;
68671 +
68672 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
68673 + SANITY_CHECK_RETURN_ERROR(!p_Fm->p_FmDriverParam, E_INVALID_STATE);
68674 + SANITY_CHECK_RETURN_ERROR((p_Fm->guestId == NCSW_MASTER_ID), E_NOT_SUPPORTED);
68675 +
68676 + bmi_rg = p_Fm->p_FmBmiRegs;
68677 +
68678 + memset(weights, 0, (sizeof(uint8_t) * 64));
68679 +
68680 + /* check that all ports add up to 100% */
68681 + sum = 0;
68682 + for (i=0; i < p_PortsBandwidth->numOfPorts; i++)
68683 + sum +=p_PortsBandwidth->portsBandwidths[i].bandwidth;
68684 + if (sum != 100)
68685 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Sum of ports bandwidth differ from 100%"));
68686 +
68687 + /* find highest percent */
68688 + for (i=0; i < p_PortsBandwidth->numOfPorts; i++)
68689 + {
68690 + if (p_PortsBandwidth->portsBandwidths[i].bandwidth > maxPercent)
68691 + maxPercent = p_PortsBandwidth->portsBandwidths[i].bandwidth;
68692 + }
68693 +
68694 + ASSERT_COND(maxPercent > 0); /* guaranteed by sum = 100 */
68695 +
68696 + /* calculate weight for each port */
68697 + for (i=0; i < p_PortsBandwidth->numOfPorts; i++)
68698 + {
68699 + weight = (uint8_t)((p_PortsBandwidth->portsBandwidths[i].bandwidth * PORT_MAX_WEIGHT ) / maxPercent);
68700 + /* we want even division between 1-to-PORT_MAX_WEIGHT. so if exact division
68701 + is not reached, we round up so that:
68702 + 0 until maxPercent/PORT_MAX_WEIGHT get "1"
68703 + maxPercent/PORT_MAX_WEIGHT+1 until (maxPercent/PORT_MAX_WEIGHT)*2 get "2"
68704 + ...
68705 + maxPercent - maxPercent/PORT_MAX_WEIGHT until maxPercent get "PORT_MAX_WEIGHT: */
68706 + if ((uint8_t)((p_PortsBandwidth->portsBandwidths[i].bandwidth * PORT_MAX_WEIGHT ) % maxPercent))
68707 + weight++;
68708 +
68709 + /* find the location of this port within the register */
68710 + hardwarePortId =
68711 + SwPortIdToHwPortId(p_PortsBandwidth->portsBandwidths[i].type,
68712 + p_PortsBandwidth->portsBandwidths[i].relativePortId,
68713 + p_Fm->p_FmStateStruct->revInfo.majorRev,
68714 + p_Fm->p_FmStateStruct->revInfo.minorRev);
68715 +
68716 + ASSERT_COND(IN_RANGE(1, hardwarePortId, 63));
68717 + weights[hardwarePortId] = weight;
68718 + }
68719 +
68720 + fman_set_ports_bandwidth(bmi_rg, weights);
68721 +
68722 + return E_OK;
68723 +}
68724 +
68725 +t_Error FM_EnableRamsEcc(t_Handle h_Fm)
68726 +{
68727 + t_Fm *p_Fm = (t_Fm*)h_Fm;
68728 + struct fman_fpm_regs *fpm_rg;
68729 +
68730 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
68731 +
68732 + fpm_rg = p_Fm->p_FmFpmRegs;
68733 +
68734 + if (p_Fm->guestId != NCSW_MASTER_ID)
68735 + {
68736 + t_FmIpcMsg msg;
68737 + t_Error err;
68738 +
68739 + memset(&msg, 0, sizeof(msg));
68740 + msg.msgId = FM_ENABLE_RAM_ECC;
68741 + err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0],
68742 + (uint8_t*)&msg,
68743 + sizeof(msg.msgId),
68744 + NULL,
68745 + NULL,
68746 + NULL,
68747 + NULL);
68748 + if (err != E_OK)
68749 + RETURN_ERROR(MINOR, err, NO_MSG);
68750 + return E_OK;
68751 + }
68752 +
68753 + if (!p_Fm->p_FmStateStruct->internalCall)
68754 + p_Fm->p_FmStateStruct->explicitEnable = TRUE;
68755 + p_Fm->p_FmStateStruct->internalCall = FALSE;
68756 +
68757 + if (p_Fm->p_FmStateStruct->ramsEccEnable)
68758 + return E_OK;
68759 + else
68760 + {
68761 + fman_enable_rams_ecc(fpm_rg);
68762 + p_Fm->p_FmStateStruct->ramsEccEnable = TRUE;
68763 + }
68764 +
68765 + return E_OK;
68766 +}
68767 +
68768 +t_Error FM_DisableRamsEcc(t_Handle h_Fm)
68769 +{
68770 + t_Fm *p_Fm = (t_Fm*)h_Fm;
68771 + bool explicitDisable = FALSE;
68772 + struct fman_fpm_regs *fpm_rg;
68773 +
68774 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
68775 + SANITY_CHECK_RETURN_ERROR(!p_Fm->p_FmDriverParam, E_INVALID_HANDLE);
68776 +
68777 + fpm_rg = p_Fm->p_FmFpmRegs;
68778 +
68779 + if (p_Fm->guestId != NCSW_MASTER_ID)
68780 + {
68781 + t_Error err;
68782 + t_FmIpcMsg msg;
68783 +
68784 + memset(&msg, 0, sizeof(msg));
68785 + msg.msgId = FM_DISABLE_RAM_ECC;
68786 + if ((err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0],
68787 + (uint8_t*)&msg,
68788 + sizeof(msg.msgId),
68789 + NULL,
68790 + NULL,
68791 + NULL,
68792 + NULL)) != E_OK)
68793 + RETURN_ERROR(MINOR, err, NO_MSG);
68794 + return E_OK;
68795 + }
68796 +
68797 + if (!p_Fm->p_FmStateStruct->internalCall)
68798 + explicitDisable = TRUE;
68799 + p_Fm->p_FmStateStruct->internalCall = FALSE;
68800 +
68801 + /* if rams are already disabled, or if rams were explicitly enabled and are
68802 + currently called indirectly (not explicitly), ignore this call. */
68803 + if (!p_Fm->p_FmStateStruct->ramsEccEnable ||
68804 + (p_Fm->p_FmStateStruct->explicitEnable && !explicitDisable))
68805 + return E_OK;
68806 + else
68807 + {
68808 + if (p_Fm->p_FmStateStruct->explicitEnable)
68809 + /* This is the case were both explicit are TRUE.
68810 + Turn off this flag for cases were following ramsEnable
68811 + routines are called */
68812 + p_Fm->p_FmStateStruct->explicitEnable = FALSE;
68813 +
68814 + fman_enable_rams_ecc(fpm_rg);
68815 + p_Fm->p_FmStateStruct->ramsEccEnable = FALSE;
68816 + }
68817 +
68818 + return E_OK;
68819 +}
68820 +
68821 +t_Error FM_SetException(t_Handle h_Fm, e_FmExceptions exception, bool enable)
68822 +{
68823 + t_Fm *p_Fm = (t_Fm*)h_Fm;
68824 + uint32_t bitMask = 0;
68825 + enum fman_exceptions fslException;
68826 + struct fman_rg fman_rg;
68827 +
68828 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
68829 + SANITY_CHECK_RETURN_ERROR(!p_Fm->p_FmDriverParam, E_INVALID_STATE);
68830 +
68831 + fman_rg.bmi_rg = p_Fm->p_FmBmiRegs;
68832 + fman_rg.qmi_rg = p_Fm->p_FmQmiRegs;
68833 + fman_rg.fpm_rg = p_Fm->p_FmFpmRegs;
68834 + fman_rg.dma_rg = p_Fm->p_FmDmaRegs;
68835 +
68836 + GET_EXCEPTION_FLAG(bitMask, exception);
68837 + if (bitMask)
68838 + {
68839 + if (enable)
68840 + p_Fm->p_FmStateStruct->exceptions |= bitMask;
68841 + else
68842 + p_Fm->p_FmStateStruct->exceptions &= ~bitMask;
68843 +
68844 + fslException = FmanExceptionTrans(exception);
68845 +
68846 + return (t_Error)fman_set_exception(&fman_rg,
68847 + fslException,
68848 + enable);
68849 + }
68850 + else
68851 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Undefined exception"));
68852 +
68853 + return E_OK;
68854 +}
68855 +
68856 +t_Error FM_GetRevision(t_Handle h_Fm, t_FmRevisionInfo *p_FmRevisionInfo)
68857 +{
68858 + t_Fm *p_Fm = (t_Fm*)h_Fm;
68859 +
68860 + p_FmRevisionInfo->majorRev = p_Fm->p_FmStateStruct->revInfo.majorRev;
68861 + p_FmRevisionInfo->minorRev = p_Fm->p_FmStateStruct->revInfo.minorRev;
68862 +
68863 + return E_OK;
68864 +}
68865 +
68866 +t_Error FM_GetFmanCtrlCodeRevision(t_Handle h_Fm, t_FmCtrlCodeRevisionInfo *p_RevisionInfo)
68867 +{
68868 + t_Fm *p_Fm = (t_Fm*)h_Fm;
68869 + t_FMIramRegs *p_Iram;
68870 + uint32_t revInfo;
68871 +
68872 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
68873 + SANITY_CHECK_RETURN_ERROR(p_RevisionInfo, E_NULL_POINTER);
68874 +
68875 + if ((p_Fm->guestId != NCSW_MASTER_ID) &&
68876 + p_Fm->h_IpcSessions[0])
68877 + {
68878 + t_Error err;
68879 + t_FmIpcMsg msg;
68880 + t_FmIpcReply reply;
68881 + uint32_t replyLength;
68882 + t_FmIpcFmanCtrlCodeRevisionInfo ipcRevInfo;
68883 +
68884 + memset(&msg, 0, sizeof(msg));
68885 + memset(&reply, 0, sizeof(reply));
68886 + msg.msgId = FM_GET_FMAN_CTRL_CODE_REV;
68887 + replyLength = sizeof(uint32_t) + sizeof(t_FmCtrlCodeRevisionInfo);
68888 + if ((err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0],
68889 + (uint8_t*)&msg,
68890 + sizeof(msg.msgId),
68891 + (uint8_t*)&reply,
68892 + &replyLength,
68893 + NULL,
68894 + NULL)) != E_OK)
68895 + RETURN_ERROR(MINOR, err, NO_MSG);
68896 + if (replyLength != (sizeof(uint32_t) + sizeof(t_FmCtrlCodeRevisionInfo)))
68897 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch"));
68898 + memcpy((uint8_t*)&ipcRevInfo, reply.replyBody, sizeof(t_FmCtrlCodeRevisionInfo));
68899 + p_RevisionInfo->packageRev = ipcRevInfo.packageRev;
68900 + p_RevisionInfo->majorRev = ipcRevInfo.majorRev;
68901 + p_RevisionInfo->minorRev = ipcRevInfo.minorRev;
68902 + return (t_Error)(reply.error);
68903 + }
68904 + else if (p_Fm->guestId != NCSW_MASTER_ID)
68905 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED,
68906 + ("running in guest-mode without IPC!"));
68907 +
68908 + p_Iram = (t_FMIramRegs *)UINT_TO_PTR(p_Fm->baseAddr + FM_MM_IMEM);
68909 + WRITE_UINT32(p_Iram->iadd, 0x4);
68910 + while (GET_UINT32(p_Iram->iadd) != 0x4) ;
68911 + revInfo = GET_UINT32(p_Iram->idata);
68912 + p_RevisionInfo->packageRev = (uint16_t)((revInfo & 0xFFFF0000) >> 16);
68913 + p_RevisionInfo->majorRev = (uint8_t)((revInfo & 0x0000FF00) >> 8);
68914 + p_RevisionInfo->minorRev = (uint8_t)(revInfo & 0x000000FF);
68915 +
68916 + return E_OK;
68917 +}
68918 +
68919 +uint32_t FM_GetCounter(t_Handle h_Fm, e_FmCounters counter)
68920 +{
68921 + t_Fm *p_Fm = (t_Fm*)h_Fm;
68922 + t_Error err;
68923 + uint32_t counterValue;
68924 + struct fman_rg fman_rg;
68925 + enum fman_counters fsl_counter;
68926 +
68927 + SANITY_CHECK_RETURN_VALUE(p_Fm, E_INVALID_HANDLE, 0);
68928 + SANITY_CHECK_RETURN_VALUE(!p_Fm->p_FmDriverParam, E_INVALID_STATE, 0);
68929 +
68930 + fman_rg.bmi_rg = p_Fm->p_FmBmiRegs;
68931 + fman_rg.qmi_rg = p_Fm->p_FmQmiRegs;
68932 + fman_rg.fpm_rg = p_Fm->p_FmFpmRegs;
68933 + fman_rg.dma_rg = p_Fm->p_FmDmaRegs;
68934 +
68935 + if ((p_Fm->guestId != NCSW_MASTER_ID) &&
68936 + !p_Fm->baseAddr &&
68937 + p_Fm->h_IpcSessions[0])
68938 + {
68939 + t_FmIpcMsg msg;
68940 + t_FmIpcReply reply;
68941 + uint32_t replyLength, outCounter;
68942 +
68943 + memset(&msg, 0, sizeof(msg));
68944 + memset(&reply, 0, sizeof(reply));
68945 + msg.msgId = FM_GET_COUNTER;
68946 + memcpy(msg.msgBody, (uint8_t *)&counter, sizeof(uint32_t));
68947 + replyLength = sizeof(uint32_t) + sizeof(uint32_t);
68948 + err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0],
68949 + (uint8_t*)&msg,
68950 + sizeof(msg.msgId) +sizeof(counterValue),
68951 + (uint8_t*)&reply,
68952 + &replyLength,
68953 + NULL,
68954 + NULL);
68955 + if (err != E_OK)
68956 + {
68957 + REPORT_ERROR(MAJOR, err, NO_MSG);
68958 + return 0;
68959 + }
68960 + if (replyLength != (sizeof(uint32_t) + sizeof(uint32_t)))
68961 + {
68962 + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch"));
68963 + return 0;
68964 + }
68965 +
68966 + memcpy((uint8_t*)&outCounter, reply.replyBody, sizeof(uint32_t));
68967 + return outCounter;
68968 + }
68969 + else if (!p_Fm->baseAddr)
68970 + {
68971 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Either IPC or 'baseAddress' is required!"));
68972 + return 0;
68973 + }
68974 +
68975 + /* When applicable (when there is an 'enable counters' bit,
68976 + check that counters are enabled */
68977 + switch (counter)
68978 + {
68979 + case (e_FM_COUNTERS_DEQ_1):
68980 + case (e_FM_COUNTERS_DEQ_2):
68981 + case (e_FM_COUNTERS_DEQ_3):
68982 + if ((p_Fm->p_FmStateStruct->revInfo.majorRev == 4) ||
68983 + (p_Fm->p_FmStateStruct->revInfo.majorRev >= 6))
68984 + {
68985 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Requested counter not supported"));
68986 + return 0;
68987 + }
68988 + case (e_FM_COUNTERS_ENQ_TOTAL_FRAME):
68989 + case (e_FM_COUNTERS_DEQ_TOTAL_FRAME):
68990 + case (e_FM_COUNTERS_DEQ_0):
68991 + case (e_FM_COUNTERS_DEQ_FROM_DEFAULT):
68992 + case (e_FM_COUNTERS_DEQ_FROM_CONTEXT):
68993 + case (e_FM_COUNTERS_DEQ_FROM_FD):
68994 + case (e_FM_COUNTERS_DEQ_CONFIRM):
68995 + if (!(GET_UINT32(p_Fm->p_FmQmiRegs->fmqm_gc) & QMI_CFG_EN_COUNTERS))
68996 + {
68997 + REPORT_ERROR(MAJOR, E_INVALID_STATE, ("Requested counter was not enabled"));
68998 + return 0;
68999 + }
69000 + break;
69001 + default:
69002 + break;
69003 + }
69004 +
69005 + FMAN_COUNTERS_TRANS(fsl_counter, counter);
69006 + return fman_get_counter(&fman_rg, fsl_counter);
69007 +}
69008 +
69009 +t_Error FM_ModifyCounter(t_Handle h_Fm, e_FmCounters counter, uint32_t val)
69010 +{
69011 + t_Fm *p_Fm = (t_Fm*)h_Fm;
69012 + struct fman_rg fman_rg;
69013 + enum fman_counters fsl_counter;
69014 +
69015 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
69016 + SANITY_CHECK_RETURN_ERROR(!p_Fm->p_FmDriverParam, E_INVALID_STATE);
69017 +
69018 + fman_rg.bmi_rg = p_Fm->p_FmBmiRegs;
69019 + fman_rg.qmi_rg = p_Fm->p_FmQmiRegs;
69020 + fman_rg.fpm_rg = p_Fm->p_FmFpmRegs;
69021 + fman_rg.dma_rg = p_Fm->p_FmDmaRegs;
69022 +
69023 + FMAN_COUNTERS_TRANS(fsl_counter, counter);
69024 + return (t_Error)fman_modify_counter(&fman_rg, fsl_counter, val);
69025 +}
69026 +
69027 +void FM_SetDmaEmergency(t_Handle h_Fm, e_FmDmaMuramPort muramPort, bool enable)
69028 +{
69029 + t_Fm *p_Fm = (t_Fm*)h_Fm;
69030 + struct fman_dma_regs *dma_rg;
69031 +
69032 + SANITY_CHECK_RETURN(p_Fm, E_INVALID_HANDLE);
69033 + SANITY_CHECK_RETURN(!p_Fm->p_FmDriverParam, E_INVALID_STATE);
69034 +
69035 + dma_rg = p_Fm->p_FmDmaRegs;
69036 +
69037 + fman_set_dma_emergency(dma_rg, !!(muramPort==e_FM_DMA_MURAM_PORT_WRITE), enable);
69038 +}
69039 +
69040 +void FM_SetDmaExtBusPri(t_Handle h_Fm, e_FmDmaExtBusPri pri)
69041 +{
69042 + t_Fm *p_Fm = (t_Fm*)h_Fm;
69043 + struct fman_dma_regs *dma_rg;
69044 +
69045 + SANITY_CHECK_RETURN(p_Fm, E_INVALID_HANDLE);
69046 + SANITY_CHECK_RETURN(!p_Fm->p_FmDriverParam, E_INVALID_STATE);
69047 +
69048 + dma_rg = p_Fm->p_FmDmaRegs;
69049 +
69050 + fman_set_dma_ext_bus_pri(dma_rg, pri);
69051 +}
69052 +
69053 +void FM_GetDmaStatus(t_Handle h_Fm, t_FmDmaStatus *p_FmDmaStatus)
69054 +{
69055 + t_Fm *p_Fm = (t_Fm*)h_Fm;
69056 + uint32_t dmaStatus;
69057 + struct fman_dma_regs *dma_rg;
69058 +
69059 + SANITY_CHECK_RETURN(p_Fm, E_INVALID_HANDLE);
69060 + SANITY_CHECK_RETURN(!p_Fm->p_FmDriverParam, E_INVALID_STATE);
69061 +
69062 + dma_rg = p_Fm->p_FmDmaRegs;
69063 +
69064 + if ((p_Fm->guestId != NCSW_MASTER_ID) &&
69065 + !p_Fm->baseAddr &&
69066 + p_Fm->h_IpcSessions[0])
69067 + {
69068 + t_FmIpcDmaStatus ipcDmaStatus;
69069 + t_FmIpcMsg msg;
69070 + t_FmIpcReply reply;
69071 + t_Error err;
69072 + uint32_t replyLength;
69073 +
69074 + memset(&msg, 0, sizeof(msg));
69075 + memset(&reply, 0, sizeof(reply));
69076 + msg.msgId = FM_DMA_STAT;
69077 + replyLength = sizeof(uint32_t) + sizeof(t_FmIpcDmaStatus);
69078 + err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0],
69079 + (uint8_t*)&msg,
69080 + sizeof(msg.msgId),
69081 + (uint8_t*)&reply,
69082 + &replyLength,
69083 + NULL,
69084 + NULL);
69085 + if (err != E_OK)
69086 + {
69087 + REPORT_ERROR(MINOR, err, NO_MSG);
69088 + return;
69089 + }
69090 + if (replyLength != (sizeof(uint32_t) + sizeof(t_FmIpcDmaStatus)))
69091 + {
69092 + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch"));
69093 + return;
69094 + }
69095 + memcpy((uint8_t*)&ipcDmaStatus, reply.replyBody, sizeof(t_FmIpcDmaStatus));
69096 +
69097 + p_FmDmaStatus->cmqNotEmpty = (bool)ipcDmaStatus.boolCmqNotEmpty; /**< Command queue is not empty */
69098 + p_FmDmaStatus->busError = (bool)ipcDmaStatus.boolBusError; /**< Bus error occurred */
69099 + p_FmDmaStatus->readBufEccError = (bool)ipcDmaStatus.boolReadBufEccError; /**< Double ECC error on buffer Read */
69100 + p_FmDmaStatus->writeBufEccSysError =(bool)ipcDmaStatus.boolWriteBufEccSysError; /**< Double ECC error on buffer write from system side */
69101 + p_FmDmaStatus->writeBufEccFmError = (bool)ipcDmaStatus.boolWriteBufEccFmError; /**< Double ECC error on buffer write from FM side */
69102 + p_FmDmaStatus->singlePortEccError = (bool)ipcDmaStatus.boolSinglePortEccError; /**< Double ECC error on buffer write from FM side */
69103 + return;
69104 + }
69105 + else if (!p_Fm->baseAddr)
69106 + {
69107 + REPORT_ERROR(MINOR, E_NOT_SUPPORTED,
69108 + ("Either IPC or 'baseAddress' is required!"));
69109 + return;
69110 + }
69111 +
69112 + dmaStatus = fman_get_dma_status(dma_rg);
69113 +
69114 + p_FmDmaStatus->cmqNotEmpty = (bool)(dmaStatus & DMA_STATUS_CMD_QUEUE_NOT_EMPTY);
69115 + p_FmDmaStatus->busError = (bool)(dmaStatus & DMA_STATUS_BUS_ERR);
69116 + if (p_Fm->p_FmStateStruct->revInfo.majorRev >= 6)
69117 + p_FmDmaStatus->singlePortEccError = (bool)(dmaStatus & DMA_STATUS_FM_SPDAT_ECC);
69118 + else
69119 + {
69120 + p_FmDmaStatus->readBufEccError = (bool)(dmaStatus & DMA_STATUS_READ_ECC);
69121 + p_FmDmaStatus->writeBufEccSysError = (bool)(dmaStatus & DMA_STATUS_SYSTEM_WRITE_ECC);
69122 + p_FmDmaStatus->writeBufEccFmError = (bool)(dmaStatus & DMA_STATUS_FM_WRITE_ECC);
69123 + }
69124 +}
69125 +
69126 +void FM_Resume(t_Handle h_Fm)
69127 +{
69128 + t_Fm *p_Fm = (t_Fm*)h_Fm;
69129 + struct fman_fpm_regs *fpm_rg;
69130 +
69131 + SANITY_CHECK_RETURN(p_Fm, E_INVALID_HANDLE);
69132 + SANITY_CHECK_RETURN(!p_Fm->p_FmDriverParam, E_INVALID_STATE);
69133 + SANITY_CHECK_RETURN((p_Fm->guestId == NCSW_MASTER_ID), E_NOT_SUPPORTED);
69134 +
69135 + fpm_rg = p_Fm->p_FmFpmRegs;
69136 +
69137 + fman_resume(fpm_rg);
69138 +}
69139 +
69140 +t_Error FM_GetSpecialOperationCoding(t_Handle h_Fm,
69141 + fmSpecialOperations_t spOper,
69142 + uint8_t *p_SpOperCoding)
69143 +{
69144 + t_Fm *p_Fm = (t_Fm*)h_Fm;
69145 + t_FmCtrlCodeRevisionInfo revInfo;
69146 + t_Error err;
69147 +
69148 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
69149 + SANITY_CHECK_RETURN_ERROR(!p_Fm->p_FmDriverParam, E_INVALID_STATE);
69150 + SANITY_CHECK_RETURN_ERROR(p_SpOperCoding, E_NULL_POINTER);
69151 +
69152 + if (!spOper)
69153 + {
69154 + *p_SpOperCoding = 0;
69155 + return E_OK;
69156 + }
69157 +
69158 + if ((err = FM_GetFmanCtrlCodeRevision(p_Fm, &revInfo)) != E_OK)
69159 + {
69160 + DBG(WARNING, ("FM in guest-mode without IPC, can't validate firmware revision."));
69161 + revInfo.packageRev = IP_OFFLOAD_PACKAGE_NUMBER;
69162 + }
69163 + else if (!IS_OFFLOAD_PACKAGE(revInfo.packageRev))
69164 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("Fman ctrl code package"));
69165 +
69166 + switch (spOper)
69167 + {
69168 + case (FM_SP_OP_CAPWAP_DTLS_DEC):
69169 + *p_SpOperCoding = 9;
69170 + break;
69171 + case (FM_SP_OP_CAPWAP_DTLS_ENC):
69172 + *p_SpOperCoding = 10;
69173 + break;
69174 + case (FM_SP_OP_IPSEC|FM_SP_OP_IPSEC_UPDATE_UDP_LEN|FM_SP_OP_IPSEC_MANIP):
69175 + case (FM_SP_OP_IPSEC|FM_SP_OP_IPSEC_UPDATE_UDP_LEN|FM_SP_OP_IPSEC_MANIP|FM_SP_OP_RPD):
69176 + *p_SpOperCoding = 5;
69177 + break;
69178 + case (FM_SP_OP_IPSEC|FM_SP_OP_IPSEC_MANIP):
69179 + case (FM_SP_OP_IPSEC|FM_SP_OP_IPSEC_MANIP|FM_SP_OP_RPD):
69180 + *p_SpOperCoding = 6;
69181 + break;
69182 + case (FM_SP_OP_IPSEC|FM_SP_OP_IPSEC_UPDATE_UDP_LEN|FM_SP_OP_RPD):
69183 + *p_SpOperCoding = 3;
69184 + break;
69185 + case (FM_SP_OP_IPSEC|FM_SP_OP_IPSEC_UPDATE_UDP_LEN):
69186 + *p_SpOperCoding = 1;
69187 + break;
69188 + case (FM_SP_OP_IPSEC|FM_SP_OP_IPSEC_UPDATE_UDP_LEN|FM_SP_OP_IPSEC_NO_ETH_HDR):
69189 + *p_SpOperCoding = 12;
69190 + break;
69191 + case (FM_SP_OP_IPSEC|FM_SP_OP_RPD):
69192 + *p_SpOperCoding = 4;
69193 + break;
69194 + case (FM_SP_OP_IPSEC):
69195 + *p_SpOperCoding = 2;
69196 + break;
69197 + case (FM_SP_OP_DCL4C):
69198 + *p_SpOperCoding = 7;
69199 + break;
69200 + case (FM_SP_OP_CLEAR_RPD):
69201 + *p_SpOperCoding = 8;
69202 + break;
69203 + default:
69204 + RETURN_ERROR(MINOR, E_INVALID_VALUE, NO_MSG);
69205 + }
69206 +
69207 + return E_OK;
69208 +}
69209 +
69210 +t_Error FM_CtrlMonStart(t_Handle h_Fm)
69211 +{
69212 + t_Fm *p_Fm = (t_Fm *)h_Fm;
69213 + t_FmTrbRegs *p_MonRegs;
69214 + uint8_t i;
69215 +
69216 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
69217 + SANITY_CHECK_RETURN_ERROR(!p_Fm->p_FmDriverParam, E_INVALID_STATE);
69218 + SANITY_CHECK_RETURN_ERROR((p_Fm->guestId == NCSW_MASTER_ID), E_NOT_SUPPORTED);
69219 +
69220 + WRITE_UINT32(p_Fm->p_FmFpmRegs->fmfp_brkc,
69221 + GET_UINT32(p_Fm->p_FmFpmRegs->fmfp_brkc) | FPM_BRKC_RDBG);
69222 +
69223 + for (i = 0; i < FM_NUM_OF_CTRL; i++)
69224 + {
69225 + p_MonRegs = (t_FmTrbRegs *)UINT_TO_PTR(p_Fm->baseAddr + FM_MM_TRB(i));
69226 +
69227 + /* Reset control registers */
69228 + WRITE_UINT32(p_MonRegs->tcrh, TRB_TCRH_RESET);
69229 + WRITE_UINT32(p_MonRegs->tcrl, TRB_TCRL_RESET);
69230 +
69231 + /* Configure: counter #1 counts all stalls in risc - ldsched stall
69232 + counter #2 counts all stalls in risc - other stall*/
69233 + WRITE_UINT32(p_MonRegs->tcrl, TRB_TCRL_RESET | TRB_TCRL_UTIL);
69234 +
69235 + /* Enable monitoring */
69236 + WRITE_UINT32(p_MonRegs->tcrh, TRB_TCRH_ENABLE_COUNTERS);
69237 + }
69238 +
69239 + return E_OK;
69240 +}
69241 +
69242 +t_Error FM_CtrlMonStop(t_Handle h_Fm)
69243 +{
69244 + t_Fm *p_Fm = (t_Fm *)h_Fm;
69245 + t_FmTrbRegs *p_MonRegs;
69246 + uint8_t i;
69247 +
69248 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
69249 + SANITY_CHECK_RETURN_ERROR(!p_Fm->p_FmDriverParam, E_INVALID_STATE);
69250 + SANITY_CHECK_RETURN_ERROR((p_Fm->guestId == NCSW_MASTER_ID), E_NOT_SUPPORTED);
69251 +
69252 + for (i = 0; i < FM_NUM_OF_CTRL; i++)
69253 + {
69254 + p_MonRegs = (t_FmTrbRegs *)UINT_TO_PTR(p_Fm->baseAddr + FM_MM_TRB(i));
69255 + WRITE_UINT32(p_MonRegs->tcrh, TRB_TCRH_DISABLE_COUNTERS);
69256 + }
69257 +
69258 + WRITE_UINT32(p_Fm->p_FmFpmRegs->fmfp_brkc,
69259 + GET_UINT32(p_Fm->p_FmFpmRegs->fmfp_brkc) & ~FPM_BRKC_RDBG);
69260 +
69261 + return E_OK;
69262 +}
69263 +
69264 +t_Error FM_CtrlMonGetCounters(t_Handle h_Fm, uint8_t fmCtrlIndex, t_FmCtrlMon *p_Mon)
69265 +{
69266 + t_Fm *p_Fm = (t_Fm *)h_Fm;
69267 + t_FmTrbRegs *p_MonRegs;
69268 + uint64_t clkCnt, utilValue, effValue;
69269 +
69270 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
69271 + SANITY_CHECK_RETURN_ERROR(!p_Fm->p_FmDriverParam, E_INVALID_STATE);
69272 + SANITY_CHECK_RETURN_ERROR((p_Fm->guestId == NCSW_MASTER_ID), E_NOT_SUPPORTED);
69273 + SANITY_CHECK_RETURN_ERROR(p_Mon, E_NULL_POINTER);
69274 +
69275 + if (fmCtrlIndex >= FM_NUM_OF_CTRL)
69276 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("FM Controller index"));
69277 +
69278 + p_MonRegs = (t_FmTrbRegs *)UINT_TO_PTR(p_Fm->baseAddr + FM_MM_TRB(fmCtrlIndex));
69279 +
69280 + clkCnt = (uint64_t)
69281 + ((uint64_t)GET_UINT32(p_MonRegs->tpcch) << 32 | GET_UINT32(p_MonRegs->tpccl));
69282 +
69283 + utilValue = (uint64_t)
69284 + ((uint64_t)GET_UINT32(p_MonRegs->tpc1h) << 32 | GET_UINT32(p_MonRegs->tpc1l));
69285 +
69286 + effValue = (uint64_t)
69287 + ((uint64_t)GET_UINT32(p_MonRegs->tpc2h) << 32 | GET_UINT32(p_MonRegs->tpc2l));
69288 +
69289 + p_Mon->percentCnt[0] = (uint8_t)div64_u64((clkCnt - utilValue) * 100, clkCnt);
69290 + if (clkCnt != utilValue)
69291 + p_Mon->percentCnt[1] = (uint8_t)div64_u64(((clkCnt - utilValue) - effValue) * 100, clkCnt - utilValue);
69292 + else
69293 + p_Mon->percentCnt[1] = 0;
69294 +
69295 + return E_OK;
69296 +}
69297 +
69298 +t_Handle FM_GetMuramHandle(t_Handle h_Fm)
69299 +{
69300 + t_Fm *p_Fm = (t_Fm*)h_Fm;
69301 +
69302 + SANITY_CHECK_RETURN_VALUE(p_Fm, E_INVALID_HANDLE, NULL);
69303 +
69304 + return (p_Fm->h_FmMuram);
69305 +}
69306 +
69307 +/****************************************************/
69308 +/* Hidden-DEBUG Only API */
69309 +/****************************************************/
69310 +t_Error FM_ForceIntr (t_Handle h_Fm, e_FmExceptions exception)
69311 +{
69312 + t_Fm *p_Fm = (t_Fm*)h_Fm;
69313 + enum fman_exceptions fslException;
69314 + struct fman_rg fman_rg;
69315 +
69316 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
69317 + SANITY_CHECK_RETURN_ERROR(!p_Fm->p_FmDriverParam, E_INVALID_STATE);
69318 +
69319 + fman_rg.bmi_rg = p_Fm->p_FmBmiRegs;
69320 + fman_rg.qmi_rg = p_Fm->p_FmQmiRegs;
69321 + fman_rg.fpm_rg = p_Fm->p_FmFpmRegs;
69322 + fman_rg.dma_rg = p_Fm->p_FmDmaRegs;
69323 +
69324 + switch (exception)
69325 + {
69326 + case e_FM_EX_QMI_DEQ_FROM_UNKNOWN_PORTID:
69327 + if (!(p_Fm->p_FmStateStruct->exceptions & FM_EX_QMI_DEQ_FROM_UNKNOWN_PORTID))
69328 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("The selected exception is masked"));
69329 + break;
69330 + case e_FM_EX_QMI_SINGLE_ECC:
69331 + if (p_Fm->p_FmStateStruct->revInfo.majorRev >= 6)
69332 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("e_FM_EX_QMI_SINGLE_ECC not supported on this integration."));
69333 +
69334 + if (!(p_Fm->p_FmStateStruct->exceptions & FM_EX_QMI_SINGLE_ECC))
69335 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("The selected exception is masked"));
69336 + break;
69337 + case e_FM_EX_QMI_DOUBLE_ECC:
69338 + if (!(p_Fm->p_FmStateStruct->exceptions & FM_EX_QMI_DOUBLE_ECC))
69339 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("The selected exception is masked"));
69340 + break;
69341 + case e_FM_EX_BMI_LIST_RAM_ECC:
69342 + if (!(p_Fm->p_FmStateStruct->exceptions & FM_EX_BMI_LIST_RAM_ECC))
69343 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("The selected exception is masked"));
69344 + break;
69345 + case e_FM_EX_BMI_STORAGE_PROFILE_ECC:
69346 + if (!(p_Fm->p_FmStateStruct->exceptions & FM_EX_BMI_STORAGE_PROFILE_ECC))
69347 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("The selected exception is masked"));
69348 + break;
69349 + case e_FM_EX_BMI_STATISTICS_RAM_ECC:
69350 + if (!(p_Fm->p_FmStateStruct->exceptions & FM_EX_BMI_STATISTICS_RAM_ECC))
69351 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("The selected exception is masked"));
69352 + break;
69353 + case e_FM_EX_BMI_DISPATCH_RAM_ECC:
69354 + if (!(p_Fm->p_FmStateStruct->exceptions & FM_EX_BMI_DISPATCH_RAM_ECC))
69355 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("The selected exception is masked"));
69356 + break;
69357 + default:
69358 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("The selected exception may not be forced"));
69359 + }
69360 +
69361 + fslException = FmanExceptionTrans(exception);
69362 + fman_force_intr (&fman_rg, fslException);
69363 +
69364 + return E_OK;
69365 +}
69366 +
69367 +t_Handle FmGetPcd(t_Handle h_Fm)
69368 +{
69369 + return ((t_Fm*)h_Fm)->h_Pcd;
69370 +}
69371 +#if (DPAA_VERSION >= 11)
69372 +extern void *g_MemacRegs;
69373 +void fm_clk_down(void);
69374 +uint32_t fman_memac_get_event(void *regs, uint32_t ev_mask);
69375 +void FM_ChangeClock(t_Handle h_Fm, int hardwarePortId)
69376 +{
69377 + int macId;
69378 + uint32_t event, rcr;
69379 + t_Fm *p_Fm = (t_Fm*)h_Fm;
69380 + rcr = GET_UINT32(p_Fm->p_FmFpmRegs->fm_rcr);
69381 + rcr |= 0x04000000;
69382 + WRITE_UINT32(p_Fm->p_FmFpmRegs->fm_rcr, rcr);
69383 +
69384 + HW_PORT_ID_TO_SW_PORT_ID(macId, hardwarePortId);
69385 + do
69386 + {
69387 + event = fman_memac_get_event(g_MemacRegs, 0xFFFFFFFF);
69388 + } while ((event & 0x00000020) == 0);
69389 + fm_clk_down();
69390 + rcr = GET_UINT32(p_Fm->p_FmFpmRegs->fm_rcr);
69391 + rcr &= ~0x04000000;
69392 + WRITE_UINT32(p_Fm->p_FmFpmRegs->fm_rcr, rcr);
69393 +}
69394 +#endif
69395 --- /dev/null
69396 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/fm.h
69397 @@ -0,0 +1,648 @@
69398 +/*
69399 + * Copyright 2008-2012 Freescale Semiconductor Inc.
69400 + *
69401 + * Redistribution and use in source and binary forms, with or without
69402 + * modification, are permitted provided that the following conditions are met:
69403 + * * Redistributions of source code must retain the above copyright
69404 + * notice, this list of conditions and the following disclaimer.
69405 + * * Redistributions in binary form must reproduce the above copyright
69406 + * notice, this list of conditions and the following disclaimer in the
69407 + * documentation and/or other materials provided with the distribution.
69408 + * * Neither the name of Freescale Semiconductor nor the
69409 + * names of its contributors may be used to endorse or promote products
69410 + * derived from this software without specific prior written permission.
69411 + *
69412 + *
69413 + * ALTERNATIVELY, this software may be distributed under the terms of the
69414 + * GNU General Public License ("GPL") as published by the Free Software
69415 + * Foundation, either version 2 of that License or (at your option) any
69416 + * later version.
69417 + *
69418 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
69419 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
69420 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
69421 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
69422 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
69423 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
69424 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
69425 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
69426 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
69427 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
69428 + */
69429 +
69430 +
69431 +/******************************************************************************
69432 + @File fm.h
69433 +
69434 + @Description FM internal structures and definitions.
69435 +*//***************************************************************************/
69436 +#ifndef __FM_H
69437 +#define __FM_H
69438 +
69439 +#include "error_ext.h"
69440 +#include "std_ext.h"
69441 +#include "fm_ext.h"
69442 +#include "fm_ipc.h"
69443 +
69444 +#include "fsl_fman.h"
69445 +
69446 +#define __ERR_MODULE__ MODULE_FM
69447 +
69448 +#define FM_MAX_NUM_OF_HW_PORT_IDS 64
69449 +#define FM_MAX_NUM_OF_GUESTS 100
69450 +
69451 +/**************************************************************************//**
69452 + @Description Exceptions
69453 +*//***************************************************************************/
69454 +#define FM_EX_DMA_BUS_ERROR 0x80000000 /**< DMA bus error. */
69455 +#define FM_EX_DMA_READ_ECC 0x40000000
69456 +#define FM_EX_DMA_SYSTEM_WRITE_ECC 0x20000000
69457 +#define FM_EX_DMA_FM_WRITE_ECC 0x10000000
69458 +#define FM_EX_FPM_STALL_ON_TASKS 0x08000000 /**< Stall of tasks on FPM */
69459 +#define FM_EX_FPM_SINGLE_ECC 0x04000000 /**< Single ECC on FPM */
69460 +#define FM_EX_FPM_DOUBLE_ECC 0x02000000
69461 +#define FM_EX_QMI_SINGLE_ECC 0x01000000 /**< Single ECC on FPM */
69462 +#define FM_EX_QMI_DEQ_FROM_UNKNOWN_PORTID 0x00800000 /**< Dequeu from default queue id */
69463 +#define FM_EX_QMI_DOUBLE_ECC 0x00400000
69464 +#define FM_EX_BMI_LIST_RAM_ECC 0x00200000
69465 +#define FM_EX_BMI_STORAGE_PROFILE_ECC 0x00100000
69466 +#define FM_EX_BMI_STATISTICS_RAM_ECC 0x00080000
69467 +#define FM_EX_IRAM_ECC 0x00040000
69468 +#define FM_EX_MURAM_ECC 0x00020000
69469 +#define FM_EX_BMI_DISPATCH_RAM_ECC 0x00010000
69470 +#define FM_EX_DMA_SINGLE_PORT_ECC 0x00008000
69471 +
69472 +#define DMA_EMSR_EMSTR_MASK 0x0000FFFF
69473 +
69474 +#define DMA_THRESH_COMMQ_MASK 0xFF000000
69475 +#define DMA_THRESH_READ_INT_BUF_MASK 0x007F0000
69476 +#define DMA_THRESH_WRITE_INT_BUF_MASK 0x0000007F
69477 +
69478 +#define GET_EXCEPTION_FLAG(bitMask, exception) \
69479 +switch (exception){ \
69480 + case e_FM_EX_DMA_BUS_ERROR: \
69481 + bitMask = FM_EX_DMA_BUS_ERROR; break; \
69482 + case e_FM_EX_DMA_SINGLE_PORT_ECC: \
69483 + bitMask = FM_EX_DMA_SINGLE_PORT_ECC; break; \
69484 + case e_FM_EX_DMA_READ_ECC: \
69485 + bitMask = FM_EX_DMA_READ_ECC; break; \
69486 + case e_FM_EX_DMA_SYSTEM_WRITE_ECC: \
69487 + bitMask = FM_EX_DMA_SYSTEM_WRITE_ECC; break; \
69488 + case e_FM_EX_DMA_FM_WRITE_ECC: \
69489 + bitMask = FM_EX_DMA_FM_WRITE_ECC; break; \
69490 + case e_FM_EX_FPM_STALL_ON_TASKS: \
69491 + bitMask = FM_EX_FPM_STALL_ON_TASKS; break; \
69492 + case e_FM_EX_FPM_SINGLE_ECC: \
69493 + bitMask = FM_EX_FPM_SINGLE_ECC; break; \
69494 + case e_FM_EX_FPM_DOUBLE_ECC: \
69495 + bitMask = FM_EX_FPM_DOUBLE_ECC; break; \
69496 + case e_FM_EX_QMI_SINGLE_ECC: \
69497 + bitMask = FM_EX_QMI_SINGLE_ECC; break; \
69498 + case e_FM_EX_QMI_DOUBLE_ECC: \
69499 + bitMask = FM_EX_QMI_DOUBLE_ECC; break; \
69500 + case e_FM_EX_QMI_DEQ_FROM_UNKNOWN_PORTID: \
69501 + bitMask = FM_EX_QMI_DEQ_FROM_UNKNOWN_PORTID; break; \
69502 + case e_FM_EX_BMI_LIST_RAM_ECC: \
69503 + bitMask = FM_EX_BMI_LIST_RAM_ECC; break; \
69504 + case e_FM_EX_BMI_STORAGE_PROFILE_ECC: \
69505 + bitMask = FM_EX_BMI_STORAGE_PROFILE_ECC; break; \
69506 + case e_FM_EX_BMI_STATISTICS_RAM_ECC: \
69507 + bitMask = FM_EX_BMI_STATISTICS_RAM_ECC; break; \
69508 + case e_FM_EX_BMI_DISPATCH_RAM_ECC: \
69509 + bitMask = FM_EX_BMI_DISPATCH_RAM_ECC; break; \
69510 + case e_FM_EX_IRAM_ECC: \
69511 + bitMask = FM_EX_IRAM_ECC; break; \
69512 + case e_FM_EX_MURAM_ECC: \
69513 + bitMask = FM_EX_MURAM_ECC; break; \
69514 + default: bitMask = 0;break; \
69515 +}
69516 +
69517 +#define GET_FM_MODULE_EVENT(_mod, _id, _intrType, _event) \
69518 + switch (_mod) { \
69519 + case e_FM_MOD_PRS: \
69520 + if (_id) _event = e_FM_EV_DUMMY_LAST; \
69521 + else _event = (_intrType == e_FM_INTR_TYPE_ERR) ? e_FM_EV_ERR_PRS : e_FM_EV_PRS; \
69522 + break; \
69523 + case e_FM_MOD_KG: \
69524 + if (_id) _event = e_FM_EV_DUMMY_LAST; \
69525 + else _event = (_intrType == e_FM_INTR_TYPE_ERR) ? e_FM_EV_ERR_KG : e_FM_EV_DUMMY_LAST; \
69526 + break; \
69527 + case e_FM_MOD_PLCR: \
69528 + if (_id) _event = e_FM_EV_DUMMY_LAST; \
69529 + else _event = (_intrType == e_FM_INTR_TYPE_ERR) ? e_FM_EV_ERR_PLCR : e_FM_EV_PLCR; \
69530 + break; \
69531 + case e_FM_MOD_TMR: \
69532 + if (_id) _event = e_FM_EV_DUMMY_LAST; \
69533 + else _event = (_intrType == e_FM_INTR_TYPE_ERR) ? e_FM_EV_DUMMY_LAST : e_FM_EV_TMR; \
69534 + break; \
69535 + case e_FM_MOD_10G_MAC: \
69536 + if (_id >= FM_MAX_NUM_OF_10G_MACS) _event = e_FM_EV_DUMMY_LAST; \
69537 + else _event = (_intrType == e_FM_INTR_TYPE_ERR) ? (e_FM_EV_ERR_10G_MAC0 + _id) : (e_FM_EV_10G_MAC0 + _id); \
69538 + break; \
69539 + case e_FM_MOD_1G_MAC: \
69540 + if (_id >= FM_MAX_NUM_OF_1G_MACS) _event = e_FM_EV_DUMMY_LAST; \
69541 + else _event = (_intrType == e_FM_INTR_TYPE_ERR) ? (e_FM_EV_ERR_1G_MAC0 + _id) : (e_FM_EV_1G_MAC0 + _id); \
69542 + break; \
69543 + case e_FM_MOD_MACSEC: \
69544 + switch (_id){ \
69545 + case (0): _event = (_intrType == e_FM_INTR_TYPE_ERR) ? e_FM_EV_ERR_MACSEC_MAC0:e_FM_EV_MACSEC_MAC0; \
69546 + break; \
69547 + } \
69548 + break; \
69549 + case e_FM_MOD_FMAN_CTRL: \
69550 + if (_intrType == e_FM_INTR_TYPE_ERR) _event = e_FM_EV_DUMMY_LAST; \
69551 + else _event = (e_FM_EV_FMAN_CTRL_0 + _id); \
69552 + break; \
69553 + default: _event = e_FM_EV_DUMMY_LAST; \
69554 + break; \
69555 + }
69556 +
69557 +#define FMAN_CACHE_OVERRIDE_TRANS(fsl_cache_override, _cache_override) \
69558 + switch (_cache_override){ \
69559 + case e_FM_DMA_NO_CACHE_OR: \
69560 + fsl_cache_override = E_FMAN_DMA_NO_CACHE_OR; break; \
69561 + case e_FM_DMA_NO_STASH_DATA: \
69562 + fsl_cache_override = E_FMAN_DMA_NO_STASH_DATA; break; \
69563 + case e_FM_DMA_MAY_STASH_DATA: \
69564 + fsl_cache_override = E_FMAN_DMA_MAY_STASH_DATA; break; \
69565 + case e_FM_DMA_STASH_DATA: \
69566 + fsl_cache_override = E_FMAN_DMA_STASH_DATA; break; \
69567 + default: \
69568 + fsl_cache_override = E_FMAN_DMA_NO_CACHE_OR; break; \
69569 + }
69570 +
69571 +#define FMAN_AID_MODE_TRANS(fsl_aid_mode, _aid_mode) \
69572 + switch (_aid_mode){ \
69573 + case e_FM_DMA_AID_OUT_PORT_ID: \
69574 + fsl_aid_mode = E_FMAN_DMA_AID_OUT_PORT_ID; break; \
69575 + case e_FM_DMA_AID_OUT_TNUM: \
69576 + fsl_aid_mode = E_FMAN_DMA_AID_OUT_TNUM; break; \
69577 + default: \
69578 + fsl_aid_mode = E_FMAN_DMA_AID_OUT_PORT_ID; break; \
69579 + }
69580 +
69581 +#define FMAN_DMA_DBG_CNT_TRANS(fsl_dma_dbg_cnt, _dma_dbg_cnt) \
69582 + switch (_dma_dbg_cnt){ \
69583 + case e_FM_DMA_DBG_NO_CNT: \
69584 + fsl_dma_dbg_cnt = E_FMAN_DMA_DBG_NO_CNT; break; \
69585 + case e_FM_DMA_DBG_CNT_DONE: \
69586 + fsl_dma_dbg_cnt = E_FMAN_DMA_DBG_CNT_DONE; break; \
69587 + case e_FM_DMA_DBG_CNT_COMM_Q_EM: \
69588 + fsl_dma_dbg_cnt = E_FMAN_DMA_DBG_CNT_COMM_Q_EM; break; \
69589 + case e_FM_DMA_DBG_CNT_INT_READ_EM: \
69590 + fsl_dma_dbg_cnt = E_FMAN_DMA_DBG_CNT_INT_READ_EM; break; \
69591 + case e_FM_DMA_DBG_CNT_INT_WRITE_EM: \
69592 + fsl_dma_dbg_cnt = E_FMAN_DMA_DBG_CNT_INT_WRITE_EM ; break; \
69593 + case e_FM_DMA_DBG_CNT_FPM_WAIT: \
69594 + fsl_dma_dbg_cnt = E_FMAN_DMA_DBG_CNT_FPM_WAIT ; break; \
69595 + case e_FM_DMA_DBG_CNT_SIGLE_BIT_ECC: \
69596 + fsl_dma_dbg_cnt = E_FMAN_DMA_DBG_CNT_SIGLE_BIT_ECC ; break; \
69597 + case e_FM_DMA_DBG_CNT_RAW_WAR_PROT: \
69598 + fsl_dma_dbg_cnt = E_FMAN_DMA_DBG_CNT_RAW_WAR_PROT ; break; \
69599 + default: \
69600 + fsl_dma_dbg_cnt = E_FMAN_DMA_DBG_NO_CNT; break; \
69601 + }
69602 +
69603 +#define FMAN_DMA_EMER_TRANS(fsl_dma_emer, _dma_emer) \
69604 + switch (_dma_emer){ \
69605 + case e_FM_DMA_EM_EBS: \
69606 + fsl_dma_emer = E_FMAN_DMA_EM_EBS; break; \
69607 + case e_FM_DMA_EM_SOS: \
69608 + fsl_dma_emer = E_FMAN_DMA_EM_SOS; break; \
69609 + default: \
69610 + fsl_dma_emer = E_FMAN_DMA_EM_EBS; break; \
69611 + }
69612 +
69613 +#define FMAN_DMA_ERR_TRANS(fsl_dma_err, _dma_err) \
69614 + switch (_dma_err){ \
69615 + case e_FM_DMA_ERR_CATASTROPHIC: \
69616 + fsl_dma_err = E_FMAN_DMA_ERR_CATASTROPHIC; break; \
69617 + case e_FM_DMA_ERR_REPORT: \
69618 + fsl_dma_err = E_FMAN_DMA_ERR_REPORT; break; \
69619 + default: \
69620 + fsl_dma_err = E_FMAN_DMA_ERR_CATASTROPHIC; break; \
69621 + }
69622 +
69623 +#define FMAN_CATASTROPHIC_ERR_TRANS(fsl_catastrophic_err, _catastrophic_err) \
69624 + switch (_catastrophic_err){ \
69625 + case e_FM_CATASTROPHIC_ERR_STALL_PORT: \
69626 + fsl_catastrophic_err = E_FMAN_CATAST_ERR_STALL_PORT; break; \
69627 + case e_FM_CATASTROPHIC_ERR_STALL_TASK: \
69628 + fsl_catastrophic_err = E_FMAN_CATAST_ERR_STALL_TASK; break; \
69629 + default: \
69630 + fsl_catastrophic_err = E_FMAN_CATAST_ERR_STALL_PORT; break; \
69631 + }
69632 +
69633 +#define FMAN_COUNTERS_TRANS(fsl_counters, _counters) \
69634 + switch (_counters){ \
69635 + case e_FM_COUNTERS_ENQ_TOTAL_FRAME: \
69636 + fsl_counters = E_FMAN_COUNTERS_ENQ_TOTAL_FRAME; break; \
69637 + case e_FM_COUNTERS_DEQ_TOTAL_FRAME: \
69638 + fsl_counters = E_FMAN_COUNTERS_DEQ_TOTAL_FRAME; break; \
69639 + case e_FM_COUNTERS_DEQ_0: \
69640 + fsl_counters = E_FMAN_COUNTERS_DEQ_0; break; \
69641 + case e_FM_COUNTERS_DEQ_1: \
69642 + fsl_counters = E_FMAN_COUNTERS_DEQ_1; break; \
69643 + case e_FM_COUNTERS_DEQ_2: \
69644 + fsl_counters = E_FMAN_COUNTERS_DEQ_2; break; \
69645 + case e_FM_COUNTERS_DEQ_3: \
69646 + fsl_counters = E_FMAN_COUNTERS_DEQ_3; break; \
69647 + case e_FM_COUNTERS_DEQ_FROM_DEFAULT: \
69648 + fsl_counters = E_FMAN_COUNTERS_DEQ_FROM_DEFAULT; break; \
69649 + case e_FM_COUNTERS_DEQ_FROM_CONTEXT: \
69650 + fsl_counters = E_FMAN_COUNTERS_DEQ_FROM_CONTEXT; break; \
69651 + case e_FM_COUNTERS_DEQ_FROM_FD: \
69652 + fsl_counters = E_FMAN_COUNTERS_DEQ_FROM_FD; break; \
69653 + case e_FM_COUNTERS_DEQ_CONFIRM: \
69654 + fsl_counters = E_FMAN_COUNTERS_DEQ_CONFIRM; break; \
69655 + default: \
69656 + fsl_counters = E_FMAN_COUNTERS_ENQ_TOTAL_FRAME; break; \
69657 + }
69658 +
69659 +/**************************************************************************//**
69660 + @Description defaults
69661 +*//***************************************************************************/
69662 +#define DEFAULT_exceptions (FM_EX_DMA_BUS_ERROR |\
69663 + FM_EX_DMA_READ_ECC |\
69664 + FM_EX_DMA_SYSTEM_WRITE_ECC |\
69665 + FM_EX_DMA_FM_WRITE_ECC |\
69666 + FM_EX_FPM_STALL_ON_TASKS |\
69667 + FM_EX_FPM_SINGLE_ECC |\
69668 + FM_EX_FPM_DOUBLE_ECC |\
69669 + FM_EX_QMI_DEQ_FROM_UNKNOWN_PORTID|\
69670 + FM_EX_BMI_LIST_RAM_ECC |\
69671 + FM_EX_BMI_STORAGE_PROFILE_ECC |\
69672 + FM_EX_BMI_STATISTICS_RAM_ECC |\
69673 + FM_EX_IRAM_ECC |\
69674 + FM_EX_MURAM_ECC |\
69675 + FM_EX_BMI_DISPATCH_RAM_ECC |\
69676 + FM_EX_QMI_DOUBLE_ECC |\
69677 + FM_EX_QMI_SINGLE_ECC)
69678 +
69679 +#define DEFAULT_eccEnable FALSE
69680 +#ifdef FM_PEDANTIC_DMA
69681 +#define DEFAULT_aidOverride TRUE
69682 +#else
69683 +#define DEFAULT_aidOverride FALSE
69684 +#endif /* FM_PEDANTIC_DMA */
69685 +#define DEFAULT_aidMode e_FM_DMA_AID_OUT_TNUM
69686 +#define DEFAULT_dmaStopOnBusError FALSE
69687 +#define DEFAULT_stopAtBusError FALSE
69688 +#define DEFAULT_axiDbgNumOfBeats 1
69689 +#define DEFAULT_dmaReadIntBufLow ((DMA_THRESH_MAX_BUF+1)/2)
69690 +#define DEFAULT_dmaReadIntBufHigh ((DMA_THRESH_MAX_BUF+1)*3/4)
69691 +#define DEFAULT_dmaWriteIntBufLow ((DMA_THRESH_MAX_BUF+1)/2)
69692 +#define DEFAULT_dmaWriteIntBufHigh ((DMA_THRESH_MAX_BUF+1)*3/4)
69693 +#define DEFAULT_catastrophicErr e_FM_CATASTROPHIC_ERR_STALL_PORT
69694 +#define DEFAULT_dmaErr e_FM_DMA_ERR_CATASTROPHIC
69695 +#define DEFAULT_resetOnInit FALSE
69696 +#define DEFAULT_resetOnInitOverrideCallback NULL
69697 +#define DEFAULT_haltOnExternalActivation FALSE /* do not change! if changed, must be disabled for rev1 ! */
69698 +#define DEFAULT_haltOnUnrecoverableEccError FALSE /* do not change! if changed, must be disabled for rev1 ! */
69699 +#define DEFAULT_externalEccRamsEnable FALSE
69700 +#define DEFAULT_VerifyUcode FALSE
69701 +
69702 +#if (DPAA_VERSION < 11)
69703 +#define DEFAULT_totalFifoSize(major, minor) \
69704 + (((major == 2) || (major == 5)) ? \
69705 + (100*KILOBYTE) : ((major == 4) ? \
69706 + (49*KILOBYTE) : (122*KILOBYTE)))
69707 +#define DEFAULT_totalNumOfTasks(major, minor) \
69708 + BMI_MAX_NUM_OF_TASKS
69709 +
69710 +#define DEFAULT_dmaCommQLow ((DMA_THRESH_MAX_COMMQ+1)/2)
69711 +#define DEFAULT_dmaCommQHigh ((DMA_THRESH_MAX_COMMQ+1)*3/4)
69712 +#define DEFAULT_cacheOverride e_FM_DMA_NO_CACHE_OR
69713 +#define DEFAULT_dmaCamNumOfEntries 32
69714 +#define DEFAULT_dmaDbgCntMode e_FM_DMA_DBG_NO_CNT
69715 +#define DEFAULT_dmaEnEmergency FALSE
69716 +#define DEFAULT_dmaSosEmergency 0
69717 +#define DEFAULT_dmaWatchdog 0 /* disabled */
69718 +#define DEFAULT_dmaEnEmergencySmoother FALSE
69719 +#define DEFAULT_dmaEmergencySwitchCounter 0
69720 +
69721 +#define DEFAULT_dispLimit 0
69722 +#define DEFAULT_prsDispTh 16
69723 +#define DEFAULT_plcrDispTh 16
69724 +#define DEFAULT_kgDispTh 16
69725 +#define DEFAULT_bmiDispTh 16
69726 +#define DEFAULT_qmiEnqDispTh 16
69727 +#define DEFAULT_qmiDeqDispTh 16
69728 +#define DEFAULT_fmCtl1DispTh 16
69729 +#define DEFAULT_fmCtl2DispTh 16
69730 +
69731 +#else /* (DPAA_VERSION < 11) */
69732 +/* Defaults are registers' reset values */
69733 +#define DEFAULT_totalFifoSize(major, minor) \
69734 + (((major == 6) && ((minor == 1) || (minor == 4))) ? \
69735 + (156*KILOBYTE) : (295*KILOBYTE))
69736 +
69737 +/* According to the default value of FMBM_CFG2[TNTSKS] */
69738 +#define DEFAULT_totalNumOfTasks(major, minor) \
69739 + (((major == 6) && ((minor == 1) || (minor == 4))) ? 59 : 124)
69740 +
69741 +#define DEFAULT_dmaCommQLow 0x2A
69742 +#define DEFAULT_dmaCommQHigh 0x3F
69743 +#define DEFAULT_cacheOverride e_FM_DMA_NO_CACHE_OR
69744 +#define DEFAULT_dmaCamNumOfEntries 64
69745 +#define DEFAULT_dmaDbgCntMode e_FM_DMA_DBG_NO_CNT
69746 +#define DEFAULT_dmaEnEmergency FALSE
69747 +#define DEFAULT_dmaSosEmergency 0
69748 +#define DEFAULT_dmaWatchdog 0 /* disabled */
69749 +#define DEFAULT_dmaEnEmergencySmoother FALSE
69750 +#define DEFAULT_dmaEmergencySwitchCounter 0
69751 +
69752 +#define DEFAULT_dispLimit 0
69753 +#define DEFAULT_prsDispTh 16
69754 +#define DEFAULT_plcrDispTh 16
69755 +#define DEFAULT_kgDispTh 16
69756 +#define DEFAULT_bmiDispTh 16
69757 +#define DEFAULT_qmiEnqDispTh 16
69758 +#define DEFAULT_qmiDeqDispTh 16
69759 +#define DEFAULT_fmCtl1DispTh 16
69760 +#define DEFAULT_fmCtl2DispTh 16
69761 +#endif /* (DPAA_VERSION < 11) */
69762 +
69763 +#define FM_TIMESTAMP_1_USEC_BIT 8
69764 +
69765 +/**************************************************************************//**
69766 + @Collection Defines used for enabling/disabling FM interrupts
69767 + @{
69768 +*//***************************************************************************/
69769 +#define ERR_INTR_EN_DMA 0x00010000
69770 +#define ERR_INTR_EN_FPM 0x80000000
69771 +#define ERR_INTR_EN_BMI 0x00800000
69772 +#define ERR_INTR_EN_QMI 0x00400000
69773 +#define ERR_INTR_EN_PRS 0x00200000
69774 +#define ERR_INTR_EN_KG 0x00100000
69775 +#define ERR_INTR_EN_PLCR 0x00080000
69776 +#define ERR_INTR_EN_MURAM 0x00040000
69777 +#define ERR_INTR_EN_IRAM 0x00020000
69778 +#define ERR_INTR_EN_10G_MAC0 0x00008000
69779 +#define ERR_INTR_EN_10G_MAC1 0x00000040
69780 +#define ERR_INTR_EN_1G_MAC0 0x00004000
69781 +#define ERR_INTR_EN_1G_MAC1 0x00002000
69782 +#define ERR_INTR_EN_1G_MAC2 0x00001000
69783 +#define ERR_INTR_EN_1G_MAC3 0x00000800
69784 +#define ERR_INTR_EN_1G_MAC4 0x00000400
69785 +#define ERR_INTR_EN_1G_MAC5 0x00000200
69786 +#define ERR_INTR_EN_1G_MAC6 0x00000100
69787 +#define ERR_INTR_EN_1G_MAC7 0x00000080
69788 +#define ERR_INTR_EN_MACSEC_MAC0 0x00000001
69789 +
69790 +#define INTR_EN_QMI 0x40000000
69791 +#define INTR_EN_PRS 0x20000000
69792 +#define INTR_EN_WAKEUP 0x10000000
69793 +#define INTR_EN_PLCR 0x08000000
69794 +#define INTR_EN_1G_MAC0 0x00080000
69795 +#define INTR_EN_1G_MAC1 0x00040000
69796 +#define INTR_EN_1G_MAC2 0x00020000
69797 +#define INTR_EN_1G_MAC3 0x00010000
69798 +#define INTR_EN_1G_MAC4 0x00000040
69799 +#define INTR_EN_1G_MAC5 0x00000020
69800 +#define INTR_EN_1G_MAC6 0x00000008
69801 +#define INTR_EN_1G_MAC7 0x00000002
69802 +#define INTR_EN_10G_MAC0 0x00200000
69803 +#define INTR_EN_10G_MAC1 0x00100000
69804 +#define INTR_EN_REV0 0x00008000
69805 +#define INTR_EN_REV1 0x00004000
69806 +#define INTR_EN_REV2 0x00002000
69807 +#define INTR_EN_REV3 0x00001000
69808 +#define INTR_EN_BRK 0x00000080
69809 +#define INTR_EN_TMR 0x01000000
69810 +#define INTR_EN_MACSEC_MAC0 0x00000001
69811 +/* @} */
69812 +
69813 +/**************************************************************************//**
69814 + @Description Memory Mapped Registers
69815 +*//***************************************************************************/
69816 +
69817 +#if defined(__MWERKS__) && !defined(__GNUC__)
69818 +#pragma pack(push,1)
69819 +#endif /* defined(__MWERKS__) && ... */
69820 +
69821 +typedef struct
69822 +{
69823 + volatile uint32_t iadd; /**< FM IRAM instruction address register */
69824 + volatile uint32_t idata; /**< FM IRAM instruction data register */
69825 + volatile uint32_t itcfg; /**< FM IRAM timing config register */
69826 + volatile uint32_t iready; /**< FM IRAM ready register */
69827 + volatile uint32_t res[0x1FFFC];
69828 +} t_FMIramRegs;
69829 +
69830 +/* Trace buffer registers -
69831 + each FM Controller has its own trace buffer residing at FM_MM_TRB(fmCtrlIndex) offset */
69832 +typedef struct t_FmTrbRegs
69833 +{
69834 + volatile uint32_t tcrh;
69835 + volatile uint32_t tcrl;
69836 + volatile uint32_t tesr;
69837 + volatile uint32_t tecr0h;
69838 + volatile uint32_t tecr0l;
69839 + volatile uint32_t terf0h;
69840 + volatile uint32_t terf0l;
69841 + volatile uint32_t tecr1h;
69842 + volatile uint32_t tecr1l;
69843 + volatile uint32_t terf1h;
69844 + volatile uint32_t terf1l;
69845 + volatile uint32_t tpcch;
69846 + volatile uint32_t tpccl;
69847 + volatile uint32_t tpc1h;
69848 + volatile uint32_t tpc1l;
69849 + volatile uint32_t tpc2h;
69850 + volatile uint32_t tpc2l;
69851 + volatile uint32_t twdimr;
69852 + volatile uint32_t twicvr;
69853 + volatile uint32_t tar;
69854 + volatile uint32_t tdr;
69855 + volatile uint32_t tsnum1;
69856 + volatile uint32_t tsnum2;
69857 + volatile uint32_t tsnum3;
69858 + volatile uint32_t tsnum4;
69859 +} t_FmTrbRegs;
69860 +
69861 +#if defined(__MWERKS__) && !defined(__GNUC__)
69862 +#pragma pack(pop)
69863 +#endif /* defined(__MWERKS__) && ... */
69864 +
69865 +/**************************************************************************//**
69866 + @Description General defines
69867 +*//***************************************************************************/
69868 +#define FM_DEBUG_STATUS_REGISTER_OFFSET 0x000d1084UL
69869 +#define FM_FW_DEBUG_INSTRUCTION 0x6ffff805UL
69870 +
69871 +/**************************************************************************//**
69872 + @Description FPM defines
69873 +*//***************************************************************************/
69874 +/* masks */
69875 +#define FPM_BRKC_RDBG 0x00000200
69876 +#define FPM_BRKC_SLP 0x00000800
69877 +/**************************************************************************//**
69878 + @Description BMI defines
69879 +*//***************************************************************************/
69880 +/* masks */
69881 +#define BMI_INIT_START 0x80000000
69882 +#define BMI_ERR_INTR_EN_STORAGE_PROFILE_ECC 0x80000000
69883 +#define BMI_ERR_INTR_EN_LIST_RAM_ECC 0x40000000
69884 +#define BMI_ERR_INTR_EN_STATISTICS_RAM_ECC 0x20000000
69885 +#define BMI_ERR_INTR_EN_DISPATCH_RAM_ECC 0x10000000
69886 +/**************************************************************************//**
69887 + @Description QMI defines
69888 +*//***************************************************************************/
69889 +/* masks */
69890 +#define QMI_ERR_INTR_EN_DOUBLE_ECC 0x80000000
69891 +#define QMI_ERR_INTR_EN_DEQ_FROM_DEF 0x40000000
69892 +#define QMI_INTR_EN_SINGLE_ECC 0x80000000
69893 +
69894 +/**************************************************************************//**
69895 + @Description IRAM defines
69896 +*//***************************************************************************/
69897 +/* masks */
69898 +#define IRAM_IADD_AIE 0x80000000
69899 +#define IRAM_READY 0x80000000
69900 +
69901 +/**************************************************************************//**
69902 + @Description TRB defines
69903 +*//***************************************************************************/
69904 +/* masks */
69905 +#define TRB_TCRH_RESET 0x04000000
69906 +#define TRB_TCRH_ENABLE_COUNTERS 0x84008000
69907 +#define TRB_TCRH_DISABLE_COUNTERS 0x8400C000
69908 +#define TRB_TCRL_RESET 0x20000000
69909 +#define TRB_TCRL_UTIL 0x00000460
69910 +typedef struct {
69911 + void (*f_Isr) (t_Handle h_Arg, uint32_t event);
69912 + t_Handle h_SrcHandle;
69913 +} t_FmanCtrlIntrSrc;
69914 +
69915 +
69916 +typedef void (t_FmanCtrlIsr)( t_Handle h_Fm, uint32_t event);
69917 +
69918 +typedef struct
69919 +{
69920 +/***************************/
69921 +/* Master/Guest parameters */
69922 +/***************************/
69923 + uint8_t fmId;
69924 + e_FmPortType portsTypes[FM_MAX_NUM_OF_HW_PORT_IDS];
69925 + uint16_t fmClkFreq;
69926 + uint16_t fmMacClkFreq;
69927 + t_FmRevisionInfo revInfo;
69928 +/**************************/
69929 +/* Master Only parameters */
69930 +/**************************/
69931 + bool enabledTimeStamp;
69932 + uint8_t count1MicroBit;
69933 + uint8_t totalNumOfTasks;
69934 + uint32_t totalFifoSize;
69935 + uint8_t maxNumOfOpenDmas;
69936 + uint8_t accumulatedNumOfTasks;
69937 + uint32_t accumulatedFifoSize;
69938 + uint8_t accumulatedNumOfOpenDmas;
69939 + uint8_t accumulatedNumOfDeqTnums;
69940 +#ifdef FM_LOW_END_RESTRICTION
69941 + bool lowEndRestriction;
69942 +#endif /* FM_LOW_END_RESTRICTION */
69943 + uint32_t exceptions;
69944 + int irq;
69945 + int errIrq;
69946 + bool ramsEccEnable;
69947 + bool explicitEnable;
69948 + bool internalCall;
69949 + uint8_t ramsEccOwners;
69950 + uint32_t extraFifoPoolSize;
69951 + uint8_t extraTasksPoolSize;
69952 + uint8_t extraOpenDmasPoolSize;
69953 +#if defined(FM_MAX_NUM_OF_10G_MACS) && (FM_MAX_NUM_OF_10G_MACS)
69954 + uint16_t portMaxFrameLengths10G[FM_MAX_NUM_OF_10G_MACS];
69955 + uint16_t macMaxFrameLengths10G[FM_MAX_NUM_OF_10G_MACS];
69956 +#endif /* defined(FM_MAX_NUM_OF_10G_MACS) && ... */
69957 + uint16_t portMaxFrameLengths1G[FM_MAX_NUM_OF_1G_MACS];
69958 + uint16_t macMaxFrameLengths1G[FM_MAX_NUM_OF_1G_MACS];
69959 +} t_FmStateStruct;
69960 +
69961 +#if (DPAA_VERSION >= 11)
69962 +typedef struct t_FmMapParam {
69963 + uint16_t profilesBase;
69964 + uint16_t numOfProfiles;
69965 + t_Handle h_FmPort;
69966 +} t_FmMapParam;
69967 +
69968 +typedef struct t_FmAllocMng {
69969 + bool allocated;
69970 + uint8_t ownerId; /* guestId for KG in multi-partition only,
69971 + portId for PLCR in any environment */
69972 +} t_FmAllocMng;
69973 +
69974 +typedef struct t_FmPcdSpEntry {
69975 + bool valid;
69976 + t_FmAllocMng profilesMng;
69977 +} t_FmPcdSpEntry;
69978 +
69979 +typedef struct t_FmSp {
69980 + void *p_FmPcdStoragePrflRegs;
69981 + t_FmPcdSpEntry profiles[FM_VSP_MAX_NUM_OF_ENTRIES];
69982 + t_FmMapParam portsMapping[FM_MAX_NUM_OF_PORTS];
69983 +} t_FmSp;
69984 +#endif /* (DPAA_VERSION >= 11) */
69985 +
69986 +typedef struct t_Fm
69987 +{
69988 +/***************************/
69989 +/* Master/Guest parameters */
69990 +/***************************/
69991 +/* locals for recovery */
69992 + uintptr_t baseAddr;
69993 +
69994 +/* un-needed for recovery */
69995 + t_Handle h_Pcd;
69996 + char fmModuleName[MODULE_NAME_SIZE];
69997 + char fmIpcHandlerModuleName[FM_MAX_NUM_OF_GUESTS][MODULE_NAME_SIZE];
69998 + t_Handle h_IpcSessions[FM_MAX_NUM_OF_GUESTS];
69999 + t_FmIntrSrc intrMng[e_FM_EV_DUMMY_LAST]; /* FM exceptions user callback */
70000 + uint8_t guestId;
70001 +/**************************/
70002 +/* Master Only parameters */
70003 +/**************************/
70004 +/* locals for recovery */
70005 + struct fman_fpm_regs *p_FmFpmRegs;
70006 + struct fman_bmi_regs *p_FmBmiRegs;
70007 + struct fman_qmi_regs *p_FmQmiRegs;
70008 + struct fman_dma_regs *p_FmDmaRegs;
70009 + struct fman_regs *p_FmRegs;
70010 + t_FmExceptionsCallback *f_Exception;
70011 + t_FmBusErrorCallback *f_BusError;
70012 + t_Handle h_App; /* Application handle */
70013 + t_Handle h_Spinlock;
70014 + bool recoveryMode;
70015 + t_FmStateStruct *p_FmStateStruct;
70016 + uint16_t tnumAgingPeriod;
70017 +#if (DPAA_VERSION >= 11)
70018 + t_FmSp *p_FmSp;
70019 + uint8_t partNumOfVSPs;
70020 + uint8_t partVSPBase;
70021 + uintptr_t vspBaseAddr;
70022 +#endif /* (DPAA_VERSION >= 11) */
70023 + bool portsPreFetchConfigured[FM_MAX_NUM_OF_HW_PORT_IDS]; /* Prefetch configration per Tx-port */
70024 + bool portsPreFetchValue[FM_MAX_NUM_OF_HW_PORT_IDS]; /* Prefetch configration per Tx-port */
70025 +
70026 +/* un-needed for recovery */
70027 + struct fman_cfg *p_FmDriverParam;
70028 + t_Handle h_FmMuram;
70029 + uint64_t fmMuramPhysBaseAddr;
70030 + bool independentMode;
70031 + bool hcPortInitialized;
70032 + uintptr_t camBaseAddr; /* save for freeing */
70033 + uintptr_t resAddr;
70034 + uintptr_t fifoBaseAddr; /* save for freeing */
70035 + t_FmanCtrlIntrSrc fmanCtrlIntr[FM_NUM_OF_FMAN_CTRL_EVENT_REGS]; /* FM exceptions user callback */
70036 + bool usedEventRegs[FM_NUM_OF_FMAN_CTRL_EVENT_REGS];
70037 + t_FmFirmwareParams firmware;
70038 + bool fwVerify;
70039 + bool resetOnInit;
70040 + t_FmResetOnInitOverrideCallback *f_ResetOnInitOverride;
70041 + uint32_t userSetExceptions;
70042 +} t_Fm;
70043 +
70044 +
70045 +#endif /* __FM_H */
70046 --- /dev/null
70047 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/fm_ipc.h
70048 @@ -0,0 +1,465 @@
70049 +/*
70050 + * Copyright 2008-2012 Freescale Semiconductor Inc.
70051 + *
70052 + * Redistribution and use in source and binary forms, with or without
70053 + * modification, are permitted provided that the following conditions are met:
70054 + * * Redistributions of source code must retain the above copyright
70055 + * notice, this list of conditions and the following disclaimer.
70056 + * * Redistributions in binary form must reproduce the above copyright
70057 + * notice, this list of conditions and the following disclaimer in the
70058 + * documentation and/or other materials provided with the distribution.
70059 + * * Neither the name of Freescale Semiconductor nor the
70060 + * names of its contributors may be used to endorse or promote products
70061 + * derived from this software without specific prior written permission.
70062 + *
70063 + *
70064 + * ALTERNATIVELY, this software may be distributed under the terms of the
70065 + * GNU General Public License ("GPL") as published by the Free Software
70066 + * Foundation, either version 2 of that License or (at your option) any
70067 + * later version.
70068 + *
70069 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
70070 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
70071 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
70072 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
70073 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
70074 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
70075 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
70076 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
70077 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
70078 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
70079 + */
70080 +
70081 +
70082 +/**************************************************************************//**
70083 + @File fm_ipc.h
70084 +
70085 + @Description FM Inter-Partition prototypes, structures and definitions.
70086 +*//***************************************************************************/
70087 +#ifndef __FM_IPC_H
70088 +#define __FM_IPC_H
70089 +
70090 +#include "error_ext.h"
70091 +#include "std_ext.h"
70092 +
70093 +
70094 +/**************************************************************************//**
70095 + @Group FM_grp Frame Manager API
70096 +
70097 + @Description FM API functions, definitions and enums
70098 +
70099 + @{
70100 +*//***************************************************************************/
70101 +
70102 +/**************************************************************************//**
70103 + @Group FM_IPC_grp FM Inter-Partition messaging Unit
70104 +
70105 + @Description FM Inter-Partition messaging unit API definitions and enums.
70106 +
70107 + @{
70108 +*//***************************************************************************/
70109 +
70110 +#if defined(__MWERKS__) && !defined(__GNUC__)
70111 +#pragma pack(push,1)
70112 +#endif /* defined(__MWERKS__) && ... */
70113 +
70114 +/**************************************************************************//**
70115 + @Description enum for defining MAC types
70116 +*//***************************************************************************/
70117 +
70118 +/**************************************************************************//**
70119 + @Description A structure of parameters for specifying a MAC.
70120 +*//***************************************************************************/
70121 +typedef _Packed struct
70122 +{
70123 + uint8_t id;
70124 + uint32_t enumType;
70125 +} _PackedType t_FmIpcMacParams;
70126 +
70127 +/**************************************************************************//**
70128 + @Description A structure of parameters for specifying a MAC.
70129 +*//***************************************************************************/
70130 +typedef _Packed struct
70131 +{
70132 + t_FmIpcMacParams macParams;
70133 + uint16_t maxFrameLength;
70134 +} _PackedType t_FmIpcMacMaxFrameParams;
70135 +
70136 +/**************************************************************************//**
70137 + @Description FM physical Address
70138 +*//***************************************************************************/
70139 +typedef _Packed struct t_FmIpcPhysAddr
70140 +{
70141 + volatile uint8_t high;
70142 + volatile uint32_t low;
70143 +} _PackedType t_FmIpcPhysAddr;
70144 +
70145 +
70146 +typedef _Packed struct t_FmIpcPortOutInitParams {
70147 + uint8_t numOfTasks; /**< OUT */
70148 + uint8_t numOfExtraTasks; /**< OUT */
70149 + uint8_t numOfOpenDmas; /**< OUT */
70150 + uint8_t numOfExtraOpenDmas; /**< OUT */
70151 + uint32_t sizeOfFifo; /**< OUT */
70152 + uint32_t extraSizeOfFifo; /**< OUT */
70153 + t_FmIpcPhysAddr ipcPhysAddr; /**< OUT */
70154 +} _PackedType t_FmIpcPortOutInitParams;
70155 +
70156 +/**************************************************************************//**
70157 + @Description Structure for IPC communication during FM_PORT_Init.
70158 +*//***************************************************************************/
70159 +typedef _Packed struct t_FmIpcPortInInitParams {
70160 + uint8_t hardwarePortId; /**< IN. port Id */
70161 + uint32_t enumPortType; /**< IN. Port type */
70162 + uint8_t boolIndependentMode;/**< IN. TRUE if FM Port operates in independent mode */
70163 + uint16_t liodnOffset; /**< IN. Port's requested resource */
70164 + uint8_t numOfTasks; /**< IN. Port's requested resource */
70165 + uint8_t numOfExtraTasks; /**< IN. Port's requested resource */
70166 + uint8_t numOfOpenDmas; /**< IN. Port's requested resource */
70167 + uint8_t numOfExtraOpenDmas; /**< IN. Port's requested resource */
70168 + uint32_t sizeOfFifo; /**< IN. Port's requested resource */
70169 + uint32_t extraSizeOfFifo; /**< IN. Port's requested resource */
70170 + uint8_t deqPipelineDepth; /**< IN. Port's requested resource */
70171 + uint16_t maxFrameLength; /**< IN. Port's max frame length. */
70172 + uint16_t liodnBase; /**< IN. Irrelevant for P4080 rev 1.
70173 + LIODN base for this port, to be
70174 + used together with LIODN offset. */
70175 +} _PackedType t_FmIpcPortInInitParams;
70176 +
70177 +
70178 +/**************************************************************************//**
70179 + @Description Structure for IPC communication between port and FM
70180 + regarding tasks and open DMA resources management.
70181 +*//***************************************************************************/
70182 +typedef _Packed struct t_FmIpcPortRsrcParams {
70183 + uint8_t hardwarePortId; /**< IN. port Id */
70184 + uint32_t val; /**< IN. Port's requested resource */
70185 + uint32_t extra; /**< IN. Port's requested resource */
70186 + uint8_t boolInitialConfig;
70187 +} _PackedType t_FmIpcPortRsrcParams;
70188 +
70189 +
70190 +/**************************************************************************//**
70191 + @Description Structure for IPC communication between port and FM
70192 + regarding tasks and open DMA resources management.
70193 +*//***************************************************************************/
70194 +typedef _Packed struct t_FmIpcPortFifoParams {
70195 + t_FmIpcPortRsrcParams rsrcParams;
70196 + uint32_t enumPortType;
70197 + uint8_t boolIndependentMode;
70198 + uint8_t deqPipelineDepth;
70199 + uint8_t numOfPools;
70200 + uint16_t secondLargestBufSize;
70201 + uint16_t largestBufSize;
70202 + uint8_t boolInitialConfig;
70203 +} _PackedType t_FmIpcPortFifoParams;
70204 +
70205 +/**************************************************************************//**
70206 + @Description Structure for port-FM communication during FM_PORT_Free.
70207 +*//***************************************************************************/
70208 +typedef _Packed struct t_FmIpcPortFreeParams {
70209 + uint8_t hardwarePortId; /**< IN. port Id */
70210 + uint32_t enumPortType; /**< IN. Port type */
70211 + uint8_t deqPipelineDepth; /**< IN. Port's requested resource */
70212 +} _PackedType t_FmIpcPortFreeParams;
70213 +
70214 +/**************************************************************************//**
70215 + @Description Structure for defining DMA status
70216 +*//***************************************************************************/
70217 +typedef _Packed struct t_FmIpcDmaStatus {
70218 + uint8_t boolCmqNotEmpty; /**< Command queue is not empty */
70219 + uint8_t boolBusError; /**< Bus error occurred */
70220 + uint8_t boolReadBufEccError; /**< Double ECC error on buffer Read */
70221 + uint8_t boolWriteBufEccSysError; /**< Double ECC error on buffer write from system side */
70222 + uint8_t boolWriteBufEccFmError; /**< Double ECC error on buffer write from FM side */
70223 + uint8_t boolSinglePortEccError; /**< Single port ECC error from FM side */
70224 +} _PackedType t_FmIpcDmaStatus;
70225 +
70226 +typedef _Packed struct t_FmIpcRegisterIntr
70227 +{
70228 + uint8_t guestId; /* IN */
70229 + uint32_t event; /* IN */
70230 +} _PackedType t_FmIpcRegisterIntr;
70231 +
70232 +typedef _Packed struct t_FmIpcIsr
70233 +{
70234 + uint8_t boolErr; /* IN */
70235 + uint32_t pendingReg; /* IN */
70236 +} _PackedType t_FmIpcIsr;
70237 +
70238 +/**************************************************************************//**
70239 + @Description structure for returning FM parameters
70240 +*//***************************************************************************/
70241 +typedef _Packed struct t_FmIpcParams {
70242 + uint16_t fmClkFreq; /**< OUT: FM Clock frequency */
70243 + uint16_t fmMacClkFreq; /**< OUT: FM MAC clock frequence */
70244 + uint8_t majorRev; /**< OUT: FM Major revision */
70245 + uint8_t minorRev; /**< OUT: FM Minor revision */
70246 +} _PackedType t_FmIpcParams;
70247 +
70248 +
70249 +/**************************************************************************//**
70250 + @Description structure for returning Fman Ctrl Code revision information
70251 +*//***************************************************************************/
70252 +typedef _Packed struct t_FmIpcFmanCtrlCodeRevisionInfo {
70253 + uint16_t packageRev; /**< OUT: Package revision */
70254 + uint8_t majorRev; /**< OUT: Major revision */
70255 + uint8_t minorRev; /**< OUT: Minor revision */
70256 +} _PackedType t_FmIpcFmanCtrlCodeRevisionInfo;
70257 +
70258 +/**************************************************************************//**
70259 + @Description Structure for defining Fm number of Fman controlers
70260 +*//***************************************************************************/
70261 +typedef _Packed struct t_FmIpcPortNumOfFmanCtrls {
70262 + uint8_t hardwarePortId; /**< IN. port Id */
70263 + uint8_t numOfFmanCtrls; /**< IN. Port type */
70264 + t_FmFmanCtrl orFmanCtrl; /**< IN. fman controller for order restoration*/
70265 +} t_FmIpcPortNumOfFmanCtrls;
70266 +
70267 +/**************************************************************************//**
70268 + @Description structure for setting Fman contriller events
70269 +*//***************************************************************************/
70270 +typedef _Packed struct t_FmIpcFmanEvents {
70271 + uint8_t eventRegId; /**< IN: Fman controller event register id */
70272 + uint32_t enableEvents; /**< IN/OUT: required enabled events mask */
70273 +} _PackedType t_FmIpcFmanEvents;
70274 +
70275 +typedef _Packed struct t_FmIpcResourceAllocParams {
70276 + uint8_t guestId;
70277 + uint16_t base;
70278 + uint16_t num;
70279 +}_PackedType t_FmIpcResourceAllocParams;
70280 +
70281 +typedef _Packed struct t_FmIpcVspSetPortWindow {
70282 + uint8_t hardwarePortId;
70283 + uint8_t baseStorageProfile;
70284 + uint8_t log2NumOfProfiles;
70285 +}_PackedType t_FmIpcVspSetPortWindow;
70286 +
70287 +typedef _Packed struct t_FmIpcSetCongestionGroupPfcPriority {
70288 + uint32_t congestionGroupId;
70289 + uint8_t priorityBitMap;
70290 +}_PackedType t_FmIpcSetCongestionGroupPfcPriority;
70291 +
70292 +#define FM_IPC_MAX_REPLY_BODY_SIZE 20
70293 +#define FM_IPC_MAX_REPLY_SIZE (FM_IPC_MAX_REPLY_BODY_SIZE + sizeof(uint32_t))
70294 +#define FM_IPC_MAX_MSG_SIZE 30
70295 +
70296 +typedef _Packed struct t_FmIpcMsg
70297 +{
70298 + uint32_t msgId;
70299 + uint8_t msgBody[FM_IPC_MAX_MSG_SIZE];
70300 +} _PackedType t_FmIpcMsg;
70301 +
70302 +typedef _Packed struct t_FmIpcReply
70303 +{
70304 + uint32_t error;
70305 + uint8_t replyBody[FM_IPC_MAX_REPLY_BODY_SIZE];
70306 +} _PackedType t_FmIpcReply;
70307 +
70308 +#if defined(__MWERKS__) && !defined(__GNUC__)
70309 +#pragma pack(pop)
70310 +#endif /* defined(__MWERKS__) && ... */
70311 +
70312 +
70313 +/***************************************************************************/
70314 +/************************ FRONT-END-TO-BACK-END*****************************/
70315 +/***************************************************************************/
70316 +
70317 +/**************************************************************************//**
70318 + @Function FM_GET_TIMESTAMP_SCALE
70319 +
70320 + @Description Used by FM front-end.
70321 +
70322 + @Param[out] uint32_t Pointer
70323 +*//***************************************************************************/
70324 +#define FM_GET_TIMESTAMP_SCALE 1
70325 +
70326 +/**************************************************************************//**
70327 + @Function FM_GET_COUNTER
70328 +
70329 + @Description Used by FM front-end.
70330 +
70331 + @Param[in/out] t_FmIpcGetCounter Pointer
70332 +*//***************************************************************************/
70333 +#define FM_GET_COUNTER 2
70334 +
70335 +/**************************************************************************//**
70336 + @Function FM_GET_SET_PORT_PARAMS
70337 +
70338 + @Description Used by FM front-end for the PORT module in order to set and get
70339 + parameters in/from master FM module on FM PORT initialization time.
70340 +
70341 + @Param[in/out] t_FmIcPortInitParams Pointer
70342 +*//***************************************************************************/
70343 +#define FM_GET_SET_PORT_PARAMS 4
70344 +
70345 +/**************************************************************************//**
70346 + @Function FM_FREE_PORT
70347 +
70348 + @Description Used by FM front-end for the PORT module when a port is freed
70349 + to free all FM PORT resources.
70350 +
70351 + @Param[in] uint8_t Pointer
70352 +*//***************************************************************************/
70353 +#define FM_FREE_PORT 5
70354 +
70355 +/**************************************************************************//**
70356 + @Function FM_RESET_MAC
70357 +
70358 + @Description Used by front-end for the MAC module to reset the MAC registers
70359 +
70360 + @Param[in] t_FmIpcMacParams Pointer .
70361 +*//***************************************************************************/
70362 +#define FM_RESET_MAC 6
70363 +
70364 +/**************************************************************************//**
70365 + @Function FM_RESUME_STALLED_PORT
70366 +
70367 + @Description Used by FM front-end for the PORT module in order to
70368 + release a stalled FM Port.
70369 +
70370 + @Param[in] uint8_t Pointer
70371 +*//***************************************************************************/
70372 +#define FM_RESUME_STALLED_PORT 7
70373 +
70374 +/**************************************************************************//**
70375 + @Function FM_IS_PORT_STALLED
70376 +
70377 + @Description Used by FM front-end for the PORT module in order to check whether
70378 + an FM port is stalled.
70379 +
70380 + @Param[in/out] t_FmIcPortIsStalled Pointer
70381 +*//***************************************************************************/
70382 +#define FM_IS_PORT_STALLED 8
70383 +
70384 +/**************************************************************************//**
70385 + @Function FM_GET_PARAMS
70386 +
70387 + @Description Used by FM front-end for the PORT module in order to dump
70388 + return FM parameters.
70389 +
70390 + @Param[in] uint8_t Pointer
70391 +*//***************************************************************************/
70392 +#define FM_GET_PARAMS 10
70393 +
70394 +/**************************************************************************//**
70395 + @Function FM_REGISTER_INTR
70396 +
70397 + @Description Used by FM front-end to register an interrupt handler to
70398 + be called upon interrupt for guest.
70399 +
70400 + @Param[out] t_FmIpcRegisterIntr Pointer
70401 +*//***************************************************************************/
70402 +#define FM_REGISTER_INTR 11
70403 +
70404 +/**************************************************************************//**
70405 + @Function FM_DMA_STAT
70406 +
70407 + @Description Used by FM front-end to read the FM DMA status.
70408 +
70409 + @Param[out] t_FmIpcDmaStatus Pointer
70410 +*//***************************************************************************/
70411 +#define FM_DMA_STAT 13
70412 +
70413 +/**************************************************************************//**
70414 + @Function FM_ALLOC_FMAN_CTRL_EVENT_REG
70415 +
70416 + @Description Used by FM front-end to allocate event register.
70417 +
70418 + @Param[out] Event register id Pointer
70419 +*//***************************************************************************/
70420 +#define FM_ALLOC_FMAN_CTRL_EVENT_REG 14
70421 +
70422 +/**************************************************************************//**
70423 + @Function FM_FREE_FMAN_CTRL_EVENT_REG
70424 +
70425 + @Description Used by FM front-end to free locate event register.
70426 +
70427 + @Param[in] uint8_t Pointer - Event register id
70428 +*//***************************************************************************/
70429 +#define FM_FREE_FMAN_CTRL_EVENT_REG 15
70430 +
70431 +/**************************************************************************//**
70432 + @Function FM_SET_FMAN_CTRL_EVENTS_ENABLE
70433 +
70434 + @Description Used by FM front-end to enable events in the FPM
70435 + Fman controller event register.
70436 +
70437 + @Param[in] t_FmIpcFmanEvents Pointer
70438 +*//***************************************************************************/
70439 +#define FM_SET_FMAN_CTRL_EVENTS_ENABLE 16
70440 +
70441 +/**************************************************************************//**
70442 + @Function FM_SET_FMAN_CTRL_EVENTS_ENABLE
70443 +
70444 + @Description Used by FM front-end to enable events in the FPM
70445 + Fman controller event register.
70446 +
70447 + @Param[in/out] t_FmIpcFmanEvents Pointer
70448 +*//***************************************************************************/
70449 +#define FM_GET_FMAN_CTRL_EVENTS_ENABLE 17
70450 +
70451 +/**************************************************************************//**
70452 + @Function FM_SET_MAC_MAX_FRAME
70453 +
70454 + @Description Used by FM front-end to set MAC's MTU/RTU's in
70455 + back-end.
70456 +
70457 + @Param[in/out] t_FmIpcMacMaxFrameParams Pointer
70458 +*//***************************************************************************/
70459 +#define FM_SET_MAC_MAX_FRAME 18
70460 +
70461 +/**************************************************************************//**
70462 + @Function FM_GET_PHYS_MURAM_BASE
70463 +
70464 + @Description Used by FM front-end in order to get MURAM base address
70465 +
70466 + @Param[in/out] t_FmIpcPhysAddr Pointer
70467 +*//***************************************************************************/
70468 +#define FM_GET_PHYS_MURAM_BASE 19
70469 +
70470 +/**************************************************************************//**
70471 + @Function FM_MASTER_IS_ALIVE
70472 +
70473 + @Description Used by FM front-end in order to verify Master is up
70474 +
70475 + @Param[in/out] bool
70476 +*//***************************************************************************/
70477 +#define FM_MASTER_IS_ALIVE 20
70478 +
70479 +#define FM_ENABLE_RAM_ECC 21
70480 +#define FM_DISABLE_RAM_ECC 22
70481 +#define FM_SET_NUM_OF_FMAN_CTRL 23
70482 +#define FM_SET_SIZE_OF_FIFO 24
70483 +#define FM_SET_NUM_OF_TASKS 25
70484 +#define FM_SET_NUM_OF_OPEN_DMAS 26
70485 +#define FM_VSP_ALLOC 27
70486 +#define FM_VSP_FREE 28
70487 +#define FM_VSP_SET_PORT_WINDOW 29
70488 +#define FM_GET_FMAN_CTRL_CODE_REV 30
70489 +#define FM_SET_CONG_GRP_PFC_PRIO 31
70490 +#ifdef FM_TX_ECC_FRMS_ERRATA_10GMAC_A004
70491 +#define FM_10G_TX_ECC_WA 100
70492 +#endif /* FM_TX_ECC_FRMS_ERRATA_10GMAC_A004 */
70493 +
70494 +/***************************************************************************/
70495 +/************************ BACK-END-TO-FRONT-END*****************************/
70496 +/***************************************************************************/
70497 +
70498 +/**************************************************************************//**
70499 + @Function FM_GUEST_ISR
70500 +
70501 + @Description Used by FM back-end to report an interrupt to the front-end.
70502 +
70503 + @Param[out] t_FmIpcIsr Pointer
70504 +*//***************************************************************************/
70505 +#define FM_GUEST_ISR 1
70506 +
70507 +
70508 +
70509 +/** @} */ /* end of FM_IPC_grp group */
70510 +/** @} */ /* end of FM_grp group */
70511 +
70512 +
70513 +#endif /* __FM_IPC_H */
70514 --- /dev/null
70515 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/fm_muram.c
70516 @@ -0,0 +1,174 @@
70517 +/*
70518 + * Copyright 2008-2012 Freescale Semiconductor Inc.
70519 + *
70520 + * Redistribution and use in source and binary forms, with or without
70521 + * modification, are permitted provided that the following conditions are met:
70522 + * * Redistributions of source code must retain the above copyright
70523 + * notice, this list of conditions and the following disclaimer.
70524 + * * Redistributions in binary form must reproduce the above copyright
70525 + * notice, this list of conditions and the following disclaimer in the
70526 + * documentation and/or other materials provided with the distribution.
70527 + * * Neither the name of Freescale Semiconductor nor the
70528 + * names of its contributors may be used to endorse or promote products
70529 + * derived from this software without specific prior written permission.
70530 + *
70531 + *
70532 + * ALTERNATIVELY, this software may be distributed under the terms of the
70533 + * GNU General Public License ("GPL") as published by the Free Software
70534 + * Foundation, either version 2 of that License or (at your option) any
70535 + * later version.
70536 + *
70537 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
70538 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
70539 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
70540 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
70541 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
70542 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
70543 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
70544 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
70545 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
70546 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
70547 + */
70548 +
70549 +
70550 +/******************************************************************************
70551 + @File FM_muram.c
70552 +
70553 + @Description FM MURAM ...
70554 +*//***************************************************************************/
70555 +#include "error_ext.h"
70556 +#include "std_ext.h"
70557 +#include "mm_ext.h"
70558 +#include "string_ext.h"
70559 +#include "sprint_ext.h"
70560 +#include "fm_muram_ext.h"
70561 +#include "fm_common.h"
70562 +
70563 +#define __ERR_MODULE__ MODULE_FM_MURAM
70564 +
70565 +
70566 +typedef struct
70567 +{
70568 + t_Handle h_Mem;
70569 + uintptr_t baseAddr;
70570 + uint32_t size;
70571 +} t_FmMuram;
70572 +
70573 +
70574 +void FmMuramClear(t_Handle h_FmMuram)
70575 +{
70576 + t_FmMuram *p_FmMuram = ( t_FmMuram *)h_FmMuram;
70577 +
70578 + SANITY_CHECK_RETURN(h_FmMuram, E_INVALID_HANDLE);
70579 + IOMemSet32(UINT_TO_PTR(p_FmMuram->baseAddr), 0, p_FmMuram->size);
70580 +}
70581 +
70582 +
70583 +t_Handle FM_MURAM_ConfigAndInit(uintptr_t baseAddress, uint32_t size)
70584 +{
70585 + t_Handle h_Mem;
70586 + t_FmMuram *p_FmMuram;
70587 +
70588 + if (!baseAddress)
70589 + {
70590 + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("baseAddress 0 is not supported"));
70591 + return NULL;
70592 + }
70593 +
70594 + if (baseAddress%4)
70595 + {
70596 + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("baseAddress not 4 bytes aligned!"));
70597 + return NULL;
70598 + }
70599 +
70600 + /* Allocate FM MURAM structure */
70601 + p_FmMuram = (t_FmMuram *) XX_Malloc(sizeof(t_FmMuram));
70602 + if (!p_FmMuram)
70603 + {
70604 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FM MURAM driver structure"));
70605 + return NULL;
70606 + }
70607 + memset(p_FmMuram, 0, sizeof(t_FmMuram));
70608 +
70609 +
70610 + if ((MM_Init(&h_Mem, baseAddress, size) != E_OK) || (!h_Mem))
70611 + {
70612 + XX_Free(p_FmMuram);
70613 + REPORT_ERROR(MAJOR, E_INVALID_HANDLE, ("FM-MURAM partition!!!"));
70614 + return NULL;
70615 + }
70616 +
70617 + /* Initialize FM MURAM parameters which will be kept by the driver */
70618 + p_FmMuram->baseAddr = baseAddress;
70619 + p_FmMuram->size = size;
70620 + p_FmMuram->h_Mem = h_Mem;
70621 +
70622 + return p_FmMuram;
70623 +}
70624 +
70625 +t_Error FM_MURAM_Free(t_Handle h_FmMuram)
70626 +{
70627 + t_FmMuram *p_FmMuram = ( t_FmMuram *)h_FmMuram;
70628 +
70629 + if (p_FmMuram->h_Mem)
70630 + MM_Free(p_FmMuram->h_Mem);
70631 +
70632 + XX_Free(h_FmMuram);
70633 +
70634 + return E_OK;
70635 +}
70636 +
70637 +void * FM_MURAM_AllocMem(t_Handle h_FmMuram, uint32_t size, uint32_t align)
70638 +{
70639 + t_FmMuram *p_FmMuram = ( t_FmMuram *)h_FmMuram;
70640 + uintptr_t addr;
70641 +
70642 + SANITY_CHECK_RETURN_VALUE(h_FmMuram, E_INVALID_HANDLE, NULL);
70643 + SANITY_CHECK_RETURN_VALUE(p_FmMuram->h_Mem, E_INVALID_HANDLE, NULL);
70644 +
70645 + addr = (uintptr_t)MM_Get(p_FmMuram->h_Mem, size, align ,"FM MURAM");
70646 +
70647 + if (addr == ILLEGAL_BASE)
70648 + return NULL;
70649 +
70650 + return UINT_TO_PTR(addr);
70651 +}
70652 +
70653 +void * FM_MURAM_AllocMemForce(t_Handle h_FmMuram, uint64_t base, uint32_t size)
70654 +{
70655 + t_FmMuram *p_FmMuram = ( t_FmMuram *)h_FmMuram;
70656 + uintptr_t addr;
70657 +
70658 + SANITY_CHECK_RETURN_VALUE(h_FmMuram, E_INVALID_HANDLE, NULL);
70659 + SANITY_CHECK_RETURN_VALUE(p_FmMuram->h_Mem, E_INVALID_HANDLE, NULL);
70660 +
70661 + addr = (uintptr_t)MM_GetForce(p_FmMuram->h_Mem, base, size, "FM MURAM");
70662 +
70663 + if (addr == ILLEGAL_BASE)
70664 + return NULL;
70665 +
70666 + return UINT_TO_PTR(addr);
70667 +}
70668 +
70669 +t_Error FM_MURAM_FreeMem(t_Handle h_FmMuram, void *ptr)
70670 +{
70671 + t_FmMuram *p_FmMuram = ( t_FmMuram *)h_FmMuram;
70672 +
70673 + SANITY_CHECK_RETURN_ERROR(h_FmMuram, E_INVALID_HANDLE);
70674 + SANITY_CHECK_RETURN_ERROR(p_FmMuram->h_Mem, E_INVALID_HANDLE);
70675 +
70676 + if (MM_Put(p_FmMuram->h_Mem, PTR_TO_UINT(ptr)) == 0)
70677 + RETURN_ERROR(MINOR, E_INVALID_ADDRESS, ("memory pointer!!!"));
70678 +
70679 + return E_OK;
70680 +}
70681 +
70682 +uint64_t FM_MURAM_GetFreeMemSize(t_Handle h_FmMuram)
70683 +{
70684 + t_FmMuram *p_FmMuram = ( t_FmMuram *)h_FmMuram;
70685 +
70686 + SANITY_CHECK_RETURN_VALUE(h_FmMuram, E_INVALID_HANDLE, 0);
70687 + SANITY_CHECK_RETURN_VALUE(p_FmMuram->h_Mem, E_INVALID_HANDLE, 0);
70688 +
70689 + return MM_GetFreeMemSize(p_FmMuram->h_Mem);
70690 +}
70691 --- /dev/null
70692 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/fman.c
70693 @@ -0,0 +1,1398 @@
70694 +/*
70695 + * Copyright 2008-2012 Freescale Semiconductor Inc.
70696 + *
70697 + * Redistribution and use in source and binary forms, with or without
70698 + * modification, are permitted provided that the following conditions are met:
70699 + * * Redistributions of source code must retain the above copyright
70700 + * notice, this list of conditions and the following disclaimer.
70701 + * * Redistributions in binary form must reproduce the above copyright
70702 + * notice, this list of conditions and the following disclaimer in the
70703 + * documentation and/or other materials provided with the distribution.
70704 + * * Neither the name of Freescale Semiconductor nor the
70705 + * names of its contributors may be used to endorse or promote products
70706 + * derived from this software without specific prior written permission.
70707 + *
70708 + *
70709 + * ALTERNATIVELY, this software may be distributed under the terms of the
70710 + * GNU General Public License ("GPL") as published by the Free Software
70711 + * Foundation, either version 2 of that License or (at your option) any
70712 + * later version.
70713 + *
70714 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
70715 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
70716 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
70717 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
70718 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
70719 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
70720 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
70721 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
70722 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
70723 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
70724 + */
70725 +
70726 +
70727 +#include <linux/math64.h>
70728 +#include "fsl_fman.h"
70729 +#include "dpaa_integration_ext.h"
70730 +
70731 +uint32_t fman_get_bmi_err_event(struct fman_bmi_regs *bmi_rg)
70732 +{
70733 + uint32_t event, mask, force;
70734 +
70735 + event = ioread32be(&bmi_rg->fmbm_ievr);
70736 + mask = ioread32be(&bmi_rg->fmbm_ier);
70737 + event &= mask;
70738 + /* clear the forced events */
70739 + force = ioread32be(&bmi_rg->fmbm_ifr);
70740 + if (force & event)
70741 + iowrite32be(force & ~event, &bmi_rg->fmbm_ifr);
70742 + /* clear the acknowledged events */
70743 + iowrite32be(event, &bmi_rg->fmbm_ievr);
70744 + return event;
70745 +}
70746 +
70747 +uint32_t fman_get_qmi_err_event(struct fman_qmi_regs *qmi_rg)
70748 +{
70749 + uint32_t event, mask, force;
70750 +
70751 + event = ioread32be(&qmi_rg->fmqm_eie);
70752 + mask = ioread32be(&qmi_rg->fmqm_eien);
70753 + event &= mask;
70754 +
70755 + /* clear the forced events */
70756 + force = ioread32be(&qmi_rg->fmqm_eif);
70757 + if (force & event)
70758 + iowrite32be(force & ~event, &qmi_rg->fmqm_eif);
70759 + /* clear the acknowledged events */
70760 + iowrite32be(event, &qmi_rg->fmqm_eie);
70761 + return event;
70762 +}
70763 +
70764 +uint32_t fman_get_dma_com_id(struct fman_dma_regs *dma_rg)
70765 +{
70766 + return ioread32be(&dma_rg->fmdmtcid);
70767 +}
70768 +
70769 +uint64_t fman_get_dma_addr(struct fman_dma_regs *dma_rg)
70770 +{
70771 + uint64_t addr;
70772 +
70773 + addr = (uint64_t)ioread32be(&dma_rg->fmdmtal);
70774 + addr |= ((uint64_t)(ioread32be(&dma_rg->fmdmtah)) << 32);
70775 +
70776 + return addr;
70777 +}
70778 +
70779 +uint32_t fman_get_dma_err_event(struct fman_dma_regs *dma_rg)
70780 +{
70781 + uint32_t status, mask;
70782 +
70783 + status = ioread32be(&dma_rg->fmdmsr);
70784 + mask = ioread32be(&dma_rg->fmdmmr);
70785 +
70786 + /* clear DMA_STATUS_BUS_ERR if mask has no DMA_MODE_BER */
70787 + if ((mask & DMA_MODE_BER) != DMA_MODE_BER)
70788 + status &= ~DMA_STATUS_BUS_ERR;
70789 +
70790 + /* clear relevant bits if mask has no DMA_MODE_ECC */
70791 + if ((mask & DMA_MODE_ECC) != DMA_MODE_ECC)
70792 + status &= ~(DMA_STATUS_FM_SPDAT_ECC |
70793 + DMA_STATUS_READ_ECC |
70794 + DMA_STATUS_SYSTEM_WRITE_ECC |
70795 + DMA_STATUS_FM_WRITE_ECC);
70796 +
70797 + /* clear set events */
70798 + iowrite32be(status, &dma_rg->fmdmsr);
70799 +
70800 + return status;
70801 +}
70802 +
70803 +uint32_t fman_get_fpm_err_event(struct fman_fpm_regs *fpm_rg)
70804 +{
70805 + uint32_t event;
70806 +
70807 + event = ioread32be(&fpm_rg->fmfp_ee);
70808 + /* clear the all occurred events */
70809 + iowrite32be(event, &fpm_rg->fmfp_ee);
70810 + return event;
70811 +}
70812 +
70813 +uint32_t fman_get_muram_err_event(struct fman_fpm_regs *fpm_rg)
70814 +{
70815 + uint32_t event, mask;
70816 +
70817 + event = ioread32be(&fpm_rg->fm_rcr);
70818 + mask = ioread32be(&fpm_rg->fm_rie);
70819 +
70820 + /* clear MURAM event bit (do not clear IRAM event) */
70821 + iowrite32be(event & ~FPM_RAM_IRAM_ECC, &fpm_rg->fm_rcr);
70822 +
70823 + if ((mask & FPM_MURAM_ECC_ERR_EX_EN))
70824 + return event;
70825 + else
70826 + return 0;
70827 +}
70828 +
70829 +uint32_t fman_get_iram_err_event(struct fman_fpm_regs *fpm_rg)
70830 +{
70831 + uint32_t event, mask;
70832 +
70833 + event = ioread32be(&fpm_rg->fm_rcr) ;
70834 + mask = ioread32be(&fpm_rg->fm_rie);
70835 + /* clear IRAM event bit (do not clear MURAM event) */
70836 + iowrite32be(event & ~FPM_RAM_MURAM_ECC,
70837 + &fpm_rg->fm_rcr);
70838 +
70839 + if ((mask & FPM_IRAM_ECC_ERR_EX_EN))
70840 + return event;
70841 + else
70842 + return 0;
70843 +}
70844 +
70845 +uint32_t fman_get_qmi_event(struct fman_qmi_regs *qmi_rg)
70846 +{
70847 + uint32_t event, mask, force;
70848 +
70849 + event = ioread32be(&qmi_rg->fmqm_ie);
70850 + mask = ioread32be(&qmi_rg->fmqm_ien);
70851 + event &= mask;
70852 + /* clear the forced events */
70853 + force = ioread32be(&qmi_rg->fmqm_if);
70854 + if (force & event)
70855 + iowrite32be(force & ~event, &qmi_rg->fmqm_if);
70856 + /* clear the acknowledged events */
70857 + iowrite32be(event, &qmi_rg->fmqm_ie);
70858 + return event;
70859 +}
70860 +
70861 +void fman_enable_time_stamp(struct fman_fpm_regs *fpm_rg,
70862 + uint8_t count1ubit,
70863 + uint16_t fm_clk_freq)
70864 +{
70865 + uint32_t tmp;
70866 + uint64_t frac;
70867 + uint32_t intgr;
70868 + uint32_t ts_freq = (uint32_t)(1 << count1ubit); /* in Mhz */
70869 +
70870 + /* configure timestamp so that bit 8 will count 1 microsecond
70871 + * Find effective count rate at TIMESTAMP least significant bits:
70872 + * Effective_Count_Rate = 1MHz x 2^8 = 256MHz
70873 + * Find frequency ratio between effective count rate and the clock:
70874 + * Effective_Count_Rate / CLK e.g. for 600 MHz clock:
70875 + * 256/600 = 0.4266666... */
70876 +
70877 + intgr = ts_freq / fm_clk_freq;
70878 + /* we multiply by 2^16 to keep the fraction of the division
70879 + * we do not div back, since we write this value as a fraction
70880 + * see spec */
70881 +
70882 + frac = ((uint64_t)ts_freq << 16) - ((uint64_t)intgr << 16) * fm_clk_freq;
70883 + /* we check remainder of the division in order to round up if not int */
70884 + if (do_div(frac, fm_clk_freq))
70885 + frac++;
70886 +
70887 + tmp = (intgr << FPM_TS_INT_SHIFT) | (uint16_t)frac;
70888 + iowrite32be(tmp, &fpm_rg->fmfp_tsc2);
70889 +
70890 + /* enable timestamp with original clock */
70891 + iowrite32be(FPM_TS_CTL_EN, &fpm_rg->fmfp_tsc1);
70892 +}
70893 +
70894 +uint32_t fman_get_fpm_error_interrupts(struct fman_fpm_regs *fpm_rg)
70895 +{
70896 + return ioread32be(&fpm_rg->fm_epi);
70897 +}
70898 +
70899 +
70900 +int fman_set_erratum_10gmac_a004_wa(struct fman_fpm_regs *fpm_rg)
70901 +{
70902 + int timeout = 100;
70903 +
70904 + iowrite32be(0x40000000, &fpm_rg->fmfp_extc);
70905 +
70906 + while ((ioread32be(&fpm_rg->fmfp_extc) & 0x40000000) && --timeout)
70907 + udelay(10);
70908 +
70909 + if (!timeout)
70910 + return -EBUSY;
70911 + return 0;
70912 +}
70913 +
70914 +void fman_set_ctrl_intr(struct fman_fpm_regs *fpm_rg,
70915 + uint8_t event_reg_id,
70916 + uint32_t enable_events)
70917 +{
70918 + iowrite32be(enable_events, &fpm_rg->fmfp_cee[event_reg_id]);
70919 +}
70920 +
70921 +uint32_t fman_get_ctrl_intr(struct fman_fpm_regs *fpm_rg, uint8_t event_reg_id)
70922 +{
70923 + return ioread32be(&fpm_rg->fmfp_cee[event_reg_id]);
70924 +}
70925 +
70926 +void fman_set_num_of_riscs_per_port(struct fman_fpm_regs *fpm_rg,
70927 + uint8_t port_id,
70928 + uint8_t num_fman_ctrls,
70929 + uint32_t or_fman_ctrl)
70930 +{
70931 + uint32_t tmp = 0;
70932 +
70933 + tmp = (uint32_t)(port_id << FPM_PORT_FM_CTL_PORTID_SHIFT);
70934 + /*TODO - maybe to put CTL# according to another criteria*/
70935 + if (num_fman_ctrls == 2)
70936 + tmp = FPM_PRT_FM_CTL2 | FPM_PRT_FM_CTL1;
70937 + /* order restoration */
70938 + tmp |= (or_fman_ctrl << FPM_PRC_ORA_FM_CTL_SEL_SHIFT) | or_fman_ctrl;
70939 +
70940 + iowrite32be(tmp, &fpm_rg->fmfp_prc);
70941 +}
70942 +
70943 +void fman_set_order_restoration_per_port(struct fman_fpm_regs *fpm_rg,
70944 + uint8_t port_id,
70945 + bool independent_mode,
70946 + bool is_rx_port)
70947 +{
70948 + uint32_t tmp = 0;
70949 +
70950 + tmp = (uint32_t)(port_id << FPM_PORT_FM_CTL_PORTID_SHIFT);
70951 + if (independent_mode) {
70952 + if (is_rx_port)
70953 + tmp |= (FPM_PRT_FM_CTL1 <<
70954 + FPM_PRC_ORA_FM_CTL_SEL_SHIFT) | FPM_PRT_FM_CTL1;
70955 + else
70956 + tmp |= (FPM_PRT_FM_CTL2 <<
70957 + FPM_PRC_ORA_FM_CTL_SEL_SHIFT) | FPM_PRT_FM_CTL2;
70958 + } else {
70959 + tmp |= (FPM_PRT_FM_CTL2|FPM_PRT_FM_CTL1);
70960 +
70961 + /* order restoration */
70962 + if (port_id % 2)
70963 + tmp |= (FPM_PRT_FM_CTL1 <<
70964 + FPM_PRC_ORA_FM_CTL_SEL_SHIFT);
70965 + else
70966 + tmp |= (FPM_PRT_FM_CTL2 <<
70967 + FPM_PRC_ORA_FM_CTL_SEL_SHIFT);
70968 + }
70969 + iowrite32be(tmp, &fpm_rg->fmfp_prc);
70970 +}
70971 +
70972 +uint8_t fman_get_qmi_deq_th(struct fman_qmi_regs *qmi_rg)
70973 +{
70974 + return (uint8_t)ioread32be(&qmi_rg->fmqm_gc);
70975 +}
70976 +
70977 +uint8_t fman_get_qmi_enq_th(struct fman_qmi_regs *qmi_rg)
70978 +{
70979 + return (uint8_t)(ioread32be(&qmi_rg->fmqm_gc) >> 8);
70980 +}
70981 +
70982 +void fman_set_qmi_enq_th(struct fman_qmi_regs *qmi_rg, uint8_t val)
70983 +{
70984 + uint32_t tmp_reg;
70985 +
70986 + tmp_reg = ioread32be(&qmi_rg->fmqm_gc);
70987 + tmp_reg &= ~QMI_CFG_ENQ_MASK;
70988 + tmp_reg |= ((uint32_t)val << 8);
70989 + iowrite32be(tmp_reg, &qmi_rg->fmqm_gc);
70990 +}
70991 +
70992 +void fman_set_qmi_deq_th(struct fman_qmi_regs *qmi_rg, uint8_t val)
70993 +{
70994 + uint32_t tmp_reg;
70995 +
70996 + tmp_reg = ioread32be(&qmi_rg->fmqm_gc);
70997 + tmp_reg &= ~QMI_CFG_DEQ_MASK;
70998 + tmp_reg |= (uint32_t)val;
70999 + iowrite32be(tmp_reg, &qmi_rg->fmqm_gc);
71000 +}
71001 +
71002 +void fman_qmi_disable_dispatch_limit(struct fman_fpm_regs *fpm_rg)
71003 +{
71004 + iowrite32be(0, &fpm_rg->fmfp_mxd);
71005 +}
71006 +
71007 +void fman_set_liodn_per_port(struct fman_rg *fman_rg, uint8_t port_id,
71008 + uint16_t liodn_base,
71009 + uint16_t liodn_ofst)
71010 +{
71011 + uint32_t tmp;
71012 +
71013 + if ((port_id > 63) || (port_id < 1))
71014 + return;
71015 +
71016 + /* set LIODN base for this port */
71017 + tmp = ioread32be(&fman_rg->dma_rg->fmdmplr[port_id / 2]);
71018 + if (port_id % 2) {
71019 + tmp &= ~FM_LIODN_BASE_MASK;
71020 + tmp |= (uint32_t)liodn_base;
71021 + } else {
71022 + tmp &= ~(FM_LIODN_BASE_MASK << DMA_LIODN_SHIFT);
71023 + tmp |= (uint32_t)liodn_base << DMA_LIODN_SHIFT;
71024 + }
71025 + iowrite32be(tmp, &fman_rg->dma_rg->fmdmplr[port_id / 2]);
71026 + iowrite32be((uint32_t)liodn_ofst,
71027 + &fman_rg->bmi_rg->fmbm_spliodn[port_id - 1]);
71028 +}
71029 +
71030 +bool fman_is_port_stalled(struct fman_fpm_regs *fpm_rg, uint8_t port_id)
71031 +{
71032 + return (bool)!!(ioread32be(&fpm_rg->fmfp_ps[port_id]) & FPM_PS_STALLED);
71033 +}
71034 +
71035 +void fman_resume_stalled_port(struct fman_fpm_regs *fpm_rg, uint8_t port_id)
71036 +{
71037 + uint32_t tmp;
71038 +
71039 + tmp = (uint32_t)((port_id << FPM_PORT_FM_CTL_PORTID_SHIFT) |
71040 + FPM_PRC_REALSE_STALLED);
71041 + iowrite32be(tmp, &fpm_rg->fmfp_prc);
71042 +}
71043 +
71044 +int fman_reset_mac(struct fman_fpm_regs *fpm_rg, uint8_t mac_id, bool is_10g)
71045 +{
71046 + uint32_t msk, timeout = 100;
71047 +
71048 + /* Get the relevant bit mask */
71049 + if (is_10g) {
71050 + switch (mac_id) {
71051 + case(0):
71052 + msk = FPM_RSTC_10G0_RESET;
71053 + break;
71054 + case(1):
71055 + msk = FPM_RSTC_10G1_RESET;
71056 + break;
71057 + default:
71058 + return -EINVAL;
71059 + }
71060 + } else {
71061 + switch (mac_id) {
71062 + case(0):
71063 + msk = FPM_RSTC_1G0_RESET;
71064 + break;
71065 + case(1):
71066 + msk = FPM_RSTC_1G1_RESET;
71067 + break;
71068 + case(2):
71069 + msk = FPM_RSTC_1G2_RESET;
71070 + break;
71071 + case(3):
71072 + msk = FPM_RSTC_1G3_RESET;
71073 + break;
71074 + case(4):
71075 + msk = FPM_RSTC_1G4_RESET;
71076 + break;
71077 + case (5):
71078 + msk = FPM_RSTC_1G5_RESET;
71079 + break;
71080 + case (6):
71081 + msk = FPM_RSTC_1G6_RESET;
71082 + break;
71083 + case (7):
71084 + msk = FPM_RSTC_1G7_RESET;
71085 + break;
71086 + default:
71087 + return -EINVAL;
71088 + }
71089 + }
71090 + /* reset */
71091 + iowrite32be(msk, &fpm_rg->fm_rstc);
71092 + while ((ioread32be(&fpm_rg->fm_rstc) & msk) && --timeout)
71093 + udelay(10);
71094 +
71095 + if (!timeout)
71096 + return -EBUSY;
71097 + return 0;
71098 +}
71099 +
71100 +uint16_t fman_get_size_of_fifo(struct fman_bmi_regs *bmi_rg, uint8_t port_id)
71101 +{
71102 + uint32_t tmp_reg;
71103 +
71104 + if ((port_id > 63) || (port_id < 1))
71105 + return 0;
71106 +
71107 + tmp_reg = ioread32be(&bmi_rg->fmbm_pfs[port_id - 1]);
71108 + return (uint16_t)((tmp_reg & BMI_FIFO_SIZE_MASK) + 1);
71109 +}
71110 +
71111 +uint32_t fman_get_total_fifo_size(struct fman_bmi_regs *bmi_rg)
71112 +{
71113 + uint32_t reg, res;
71114 +
71115 + reg = ioread32be(&bmi_rg->fmbm_cfg1);
71116 + res = (reg >> BMI_CFG1_FIFO_SIZE_SHIFT) & 0x3ff;
71117 + return res * FMAN_BMI_FIFO_UNITS;
71118 +}
71119 +
71120 +uint16_t fman_get_size_of_extra_fifo(struct fman_bmi_regs *bmi_rg,
71121 + uint8_t port_id)
71122 +{
71123 + uint32_t tmp_reg;
71124 +
71125 + if ((port_id > 63) || (port_id < 1))
71126 + return 0;
71127 +
71128 + tmp_reg = ioread32be(&bmi_rg->fmbm_pfs[port_id-1]);
71129 + return (uint16_t)((tmp_reg & BMI_EXTRA_FIFO_SIZE_MASK) >>
71130 + BMI_EXTRA_FIFO_SIZE_SHIFT);
71131 +}
71132 +
71133 +void fman_set_size_of_fifo(struct fman_bmi_regs *bmi_rg,
71134 + uint8_t port_id,
71135 + uint32_t sz_fifo,
71136 + uint32_t extra_sz_fifo)
71137 +{
71138 + uint32_t tmp;
71139 +
71140 + if ((port_id > 63) || (port_id < 1))
71141 + return;
71142 +
71143 + /* calculate reg */
71144 + tmp = (uint32_t)((sz_fifo / FMAN_BMI_FIFO_UNITS - 1) |
71145 + ((extra_sz_fifo / FMAN_BMI_FIFO_UNITS) <<
71146 + BMI_EXTRA_FIFO_SIZE_SHIFT));
71147 + iowrite32be(tmp, &bmi_rg->fmbm_pfs[port_id - 1]);
71148 +}
71149 +
71150 +uint8_t fman_get_num_of_tasks(struct fman_bmi_regs *bmi_rg, uint8_t port_id)
71151 +{
71152 + uint32_t tmp;
71153 +
71154 + if ((port_id > 63) || (port_id < 1))
71155 + return 0;
71156 +
71157 + tmp = ioread32be(&bmi_rg->fmbm_pp[port_id - 1]);
71158 + return (uint8_t)(((tmp & BMI_NUM_OF_TASKS_MASK) >>
71159 + BMI_NUM_OF_TASKS_SHIFT) + 1);
71160 +}
71161 +
71162 +uint8_t fman_get_num_extra_tasks(struct fman_bmi_regs *bmi_rg, uint8_t port_id)
71163 +{
71164 + uint32_t tmp;
71165 +
71166 + if ((port_id > 63) || (port_id < 1))
71167 + return 0;
71168 +
71169 + tmp = ioread32be(&bmi_rg->fmbm_pp[port_id - 1]);
71170 + return (uint8_t)((tmp & BMI_NUM_OF_EXTRA_TASKS_MASK) >>
71171 + BMI_EXTRA_NUM_OF_TASKS_SHIFT);
71172 +}
71173 +
71174 +void fman_set_num_of_tasks(struct fman_bmi_regs *bmi_rg,
71175 + uint8_t port_id,
71176 + uint8_t num_tasks,
71177 + uint8_t num_extra_tasks)
71178 +{
71179 + uint32_t tmp;
71180 +
71181 + if ((port_id > 63) || (port_id < 1))
71182 + return;
71183 +
71184 + /* calculate reg */
71185 + tmp = ioread32be(&bmi_rg->fmbm_pp[port_id - 1]) &
71186 + ~(BMI_NUM_OF_TASKS_MASK | BMI_NUM_OF_EXTRA_TASKS_MASK);
71187 + tmp |= (uint32_t)(((num_tasks - 1) << BMI_NUM_OF_TASKS_SHIFT) |
71188 + (num_extra_tasks << BMI_EXTRA_NUM_OF_TASKS_SHIFT));
71189 + iowrite32be(tmp, &bmi_rg->fmbm_pp[port_id - 1]);
71190 +}
71191 +
71192 +uint8_t fman_get_num_of_dmas(struct fman_bmi_regs *bmi_rg, uint8_t port_id)
71193 +{
71194 + uint32_t tmp;
71195 +
71196 + if ((port_id > 63) || (port_id < 1))
71197 + return 0;
71198 +
71199 + tmp = ioread32be(&bmi_rg->fmbm_pp[port_id - 1]);
71200 + return (uint8_t)(((tmp & BMI_NUM_OF_DMAS_MASK) >>
71201 + BMI_NUM_OF_DMAS_SHIFT) + 1);
71202 +}
71203 +
71204 +uint8_t fman_get_num_extra_dmas(struct fman_bmi_regs *bmi_rg, uint8_t port_id)
71205 +{
71206 + uint32_t tmp;
71207 +
71208 + if ((port_id > 63) || (port_id < 1))
71209 + return 0;
71210 +
71211 + tmp = ioread32be(&bmi_rg->fmbm_pp[port_id - 1]);
71212 + return (uint8_t)((tmp & BMI_NUM_OF_EXTRA_DMAS_MASK) >>
71213 + BMI_EXTRA_NUM_OF_DMAS_SHIFT);
71214 +}
71215 +
71216 +void fman_set_num_of_open_dmas(struct fman_bmi_regs *bmi_rg,
71217 + uint8_t port_id,
71218 + uint8_t num_open_dmas,
71219 + uint8_t num_extra_open_dmas,
71220 + uint8_t total_num_dmas)
71221 +{
71222 + uint32_t tmp = 0;
71223 +
71224 + if ((port_id > 63) || (port_id < 1))
71225 + return;
71226 +
71227 + /* calculate reg */
71228 + tmp = ioread32be(&bmi_rg->fmbm_pp[port_id - 1]) &
71229 + ~(BMI_NUM_OF_DMAS_MASK | BMI_NUM_OF_EXTRA_DMAS_MASK);
71230 + tmp |= (uint32_t)(((num_open_dmas-1) << BMI_NUM_OF_DMAS_SHIFT) |
71231 + (num_extra_open_dmas << BMI_EXTRA_NUM_OF_DMAS_SHIFT));
71232 + iowrite32be(tmp, &bmi_rg->fmbm_pp[port_id - 1]);
71233 +
71234 + /* update total num of DMA's with committed number of open DMAS,
71235 + * and max uncommitted pool. */
71236 + if (total_num_dmas)
71237 + {
71238 + tmp = ioread32be(&bmi_rg->fmbm_cfg2) & ~BMI_CFG2_DMAS_MASK;
71239 + tmp |= (uint32_t)(total_num_dmas - 1) << BMI_CFG2_DMAS_SHIFT;
71240 + iowrite32be(tmp, &bmi_rg->fmbm_cfg2);
71241 + }
71242 +}
71243 +
71244 +void fman_set_vsp_window(struct fman_bmi_regs *bmi_rg,
71245 + uint8_t port_id,
71246 + uint8_t base_storage_profile,
71247 + uint8_t log2_num_of_profiles)
71248 +{
71249 + uint32_t tmp = 0;
71250 + if ((port_id > 63) || (port_id < 1))
71251 + return;
71252 +
71253 + tmp = ioread32be(&bmi_rg->fmbm_spliodn[port_id-1]);
71254 + tmp |= (uint32_t)((uint32_t)base_storage_profile & 0x3f) << 16;
71255 + tmp |= (uint32_t)log2_num_of_profiles << 28;
71256 + iowrite32be(tmp, &bmi_rg->fmbm_spliodn[port_id-1]);
71257 +}
71258 +
71259 +void fman_set_congestion_group_pfc_priority(uint32_t *cpg_rg,
71260 + uint32_t congestion_group_id,
71261 + uint8_t priority_bit_map,
71262 + uint32_t reg_num)
71263 +{
71264 + uint32_t offset, tmp = 0;
71265 +
71266 + offset = (congestion_group_id%4)*8;
71267 +
71268 + tmp = ioread32be(&cpg_rg[reg_num]);
71269 + tmp &= ~(0xFF<<offset);
71270 + tmp |= (uint32_t)priority_bit_map << offset;
71271 +
71272 + iowrite32be(tmp,&cpg_rg[reg_num]);
71273 +}
71274 +
71275 +/*****************************************************************************/
71276 +/* API Init unit functions */
71277 +/*****************************************************************************/
71278 +void fman_defconfig(struct fman_cfg *cfg, bool is_master)
71279 +{
71280 + memset(cfg, 0, sizeof(struct fman_cfg));
71281 +
71282 + cfg->catastrophic_err = DEFAULT_CATASTROPHIC_ERR;
71283 + cfg->dma_err = DEFAULT_DMA_ERR;
71284 + cfg->halt_on_external_activ = DEFAULT_HALT_ON_EXTERNAL_ACTIVATION;
71285 + cfg->halt_on_unrecov_ecc_err = DEFAULT_HALT_ON_UNRECOVERABLE_ECC_ERROR;
71286 + cfg->en_iram_test_mode = FALSE;
71287 + cfg->en_muram_test_mode = FALSE;
71288 + cfg->external_ecc_rams_enable = DEFAULT_EXTERNAL_ECC_RAMS_ENABLE;
71289 +
71290 + if (!is_master)
71291 + return;
71292 +
71293 + cfg->dma_aid_override = DEFAULT_AID_OVERRIDE;
71294 + cfg->dma_aid_mode = DEFAULT_AID_MODE;
71295 + cfg->dma_comm_qtsh_clr_emer = DEFAULT_DMA_COMM_Q_LOW;
71296 + cfg->dma_comm_qtsh_asrt_emer = DEFAULT_DMA_COMM_Q_HIGH;
71297 + cfg->dma_cache_override = DEFAULT_CACHE_OVERRIDE;
71298 + cfg->dma_cam_num_of_entries = DEFAULT_DMA_CAM_NUM_OF_ENTRIES;
71299 + cfg->dma_dbg_cnt_mode = DEFAULT_DMA_DBG_CNT_MODE;
71300 + cfg->dma_en_emergency = DEFAULT_DMA_EN_EMERGENCY;
71301 + cfg->dma_sos_emergency = DEFAULT_DMA_SOS_EMERGENCY;
71302 + cfg->dma_watchdog = DEFAULT_DMA_WATCHDOG;
71303 + cfg->dma_en_emergency_smoother = DEFAULT_DMA_EN_EMERGENCY_SMOOTHER;
71304 + cfg->dma_emergency_switch_counter = DEFAULT_DMA_EMERGENCY_SWITCH_COUNTER;
71305 + cfg->disp_limit_tsh = DEFAULT_DISP_LIMIT;
71306 + cfg->prs_disp_tsh = DEFAULT_PRS_DISP_TH;
71307 + cfg->plcr_disp_tsh = DEFAULT_PLCR_DISP_TH;
71308 + cfg->kg_disp_tsh = DEFAULT_KG_DISP_TH;
71309 + cfg->bmi_disp_tsh = DEFAULT_BMI_DISP_TH;
71310 + cfg->qmi_enq_disp_tsh = DEFAULT_QMI_ENQ_DISP_TH;
71311 + cfg->qmi_deq_disp_tsh = DEFAULT_QMI_DEQ_DISP_TH;
71312 + cfg->fm_ctl1_disp_tsh = DEFAULT_FM_CTL1_DISP_TH;
71313 + cfg->fm_ctl2_disp_tsh = DEFAULT_FM_CTL2_DISP_TH;
71314 +
71315 + cfg->pedantic_dma = FALSE;
71316 + cfg->tnum_aging_period = DEFAULT_TNUM_AGING_PERIOD;
71317 + cfg->dma_stop_on_bus_error = FALSE;
71318 + cfg->qmi_deq_option_support = FALSE;
71319 +}
71320 +
71321 +void fman_regconfig(struct fman_rg *fman_rg, struct fman_cfg *cfg)
71322 +{
71323 + uint32_t tmp_reg;
71324 +
71325 + /* read the values from the registers as they are initialized by the HW with
71326 + * the required values.
71327 + */
71328 + tmp_reg = ioread32be(&fman_rg->bmi_rg->fmbm_cfg1);
71329 + cfg->total_fifo_size =
71330 + (((tmp_reg & BMI_TOTAL_FIFO_SIZE_MASK) >> BMI_CFG1_FIFO_SIZE_SHIFT) + 1) * FMAN_BMI_FIFO_UNITS;
71331 +
71332 + tmp_reg = ioread32be(&fman_rg->bmi_rg->fmbm_cfg2);
71333 + cfg->total_num_of_tasks =
71334 + (uint8_t)(((tmp_reg & BMI_TOTAL_NUM_OF_TASKS_MASK) >> BMI_CFG2_TASKS_SHIFT) + 1);
71335 +
71336 + tmp_reg = ioread32be(&fman_rg->dma_rg->fmdmtr);
71337 + cfg->dma_comm_qtsh_asrt_emer = (uint8_t)(tmp_reg >> DMA_THRESH_COMMQ_SHIFT);
71338 +
71339 + tmp_reg = ioread32be(&fman_rg->dma_rg->fmdmhy);
71340 + cfg->dma_comm_qtsh_clr_emer = (uint8_t)(tmp_reg >> DMA_THRESH_COMMQ_SHIFT);
71341 +
71342 + tmp_reg = ioread32be(&fman_rg->dma_rg->fmdmmr);
71343 + cfg->dma_cache_override = (enum fman_dma_cache_override)((tmp_reg & DMA_MODE_CACHE_OR_MASK) >> DMA_MODE_CACHE_OR_SHIFT);
71344 + cfg->dma_cam_num_of_entries = (uint8_t)((((tmp_reg & DMA_MODE_CEN_MASK) >> DMA_MODE_CEN_SHIFT) +1)*DMA_CAM_UNITS);
71345 + cfg->dma_aid_override = (bool)((tmp_reg & DMA_MODE_AID_OR)? TRUE:FALSE);
71346 + cfg->dma_dbg_cnt_mode = (enum fman_dma_dbg_cnt_mode)((tmp_reg & DMA_MODE_DBG_MASK) >> DMA_MODE_DBG_SHIFT);
71347 + cfg->dma_en_emergency = (bool)((tmp_reg & DMA_MODE_EB)? TRUE : FALSE);
71348 +
71349 + tmp_reg = ioread32be(&fman_rg->fpm_rg->fmfp_mxd);
71350 + cfg->disp_limit_tsh = (uint8_t)((tmp_reg & FPM_DISP_LIMIT_MASK) >> FPM_DISP_LIMIT_SHIFT);
71351 +
71352 + tmp_reg = ioread32be(&fman_rg->fpm_rg->fmfp_dist1);
71353 + cfg->prs_disp_tsh = (uint8_t)((tmp_reg & FPM_THR1_PRS_MASK ) >> FPM_THR1_PRS_SHIFT);
71354 + cfg->plcr_disp_tsh = (uint8_t)((tmp_reg & FPM_THR1_KG_MASK ) >> FPM_THR1_KG_SHIFT);
71355 + cfg->kg_disp_tsh = (uint8_t)((tmp_reg & FPM_THR1_PLCR_MASK ) >> FPM_THR1_PLCR_SHIFT);
71356 + cfg->bmi_disp_tsh = (uint8_t)((tmp_reg & FPM_THR1_BMI_MASK ) >> FPM_THR1_BMI_SHIFT);
71357 +
71358 + tmp_reg = ioread32be(&fman_rg->fpm_rg->fmfp_dist2);
71359 + cfg->qmi_enq_disp_tsh = (uint8_t)((tmp_reg & FPM_THR2_QMI_ENQ_MASK ) >> FPM_THR2_QMI_ENQ_SHIFT);
71360 + cfg->qmi_deq_disp_tsh = (uint8_t)((tmp_reg & FPM_THR2_QMI_DEQ_MASK ) >> FPM_THR2_QMI_DEQ_SHIFT);
71361 + cfg->fm_ctl1_disp_tsh = (uint8_t)((tmp_reg & FPM_THR2_FM_CTL1_MASK ) >> FPM_THR2_FM_CTL1_SHIFT);
71362 + cfg->fm_ctl2_disp_tsh = (uint8_t)((tmp_reg & FPM_THR2_FM_CTL2_MASK ) >> FPM_THR2_FM_CTL2_SHIFT);
71363 +
71364 + tmp_reg = ioread32be(&fman_rg->dma_rg->fmdmsetr);
71365 + cfg->dma_sos_emergency = tmp_reg;
71366 +
71367 + tmp_reg = ioread32be(&fman_rg->dma_rg->fmdmwcr);
71368 + cfg->dma_watchdog = tmp_reg/cfg->clk_freq;
71369 +
71370 + tmp_reg = ioread32be(&fman_rg->dma_rg->fmdmemsr);
71371 + cfg->dma_en_emergency_smoother = (bool)((tmp_reg & DMA_EMSR_EMSTR_MASK)? TRUE : FALSE);
71372 + cfg->dma_emergency_switch_counter = (tmp_reg & DMA_EMSR_EMSTR_MASK);
71373 +}
71374 +
71375 +void fman_reset(struct fman_fpm_regs *fpm_rg)
71376 +{
71377 + iowrite32be(FPM_RSTC_FM_RESET, &fpm_rg->fm_rstc);
71378 +}
71379 +
71380 +/**************************************************************************//**
71381 + @Function FM_Init
71382 +
71383 + @Description Initializes the FM module
71384 +
71385 + @Param[in] h_Fm - FM module descriptor
71386 +
71387 + @Return E_OK on success; Error code otherwise.
71388 +*//***************************************************************************/
71389 +int fman_dma_init(struct fman_dma_regs *dma_rg, struct fman_cfg *cfg)
71390 +{
71391 + uint32_t tmp_reg;
71392 +
71393 + /**********************/
71394 + /* Init DMA Registers */
71395 + /**********************/
71396 + /* clear status reg events */
71397 + /* oren - check!!! */
71398 + tmp_reg = (DMA_STATUS_BUS_ERR | DMA_STATUS_READ_ECC |
71399 + DMA_STATUS_SYSTEM_WRITE_ECC | DMA_STATUS_FM_WRITE_ECC);
71400 + iowrite32be(ioread32be(&dma_rg->fmdmsr) | tmp_reg,
71401 + &dma_rg->fmdmsr);
71402 +
71403 + /* configure mode register */
71404 + tmp_reg = 0;
71405 + tmp_reg |= cfg->dma_cache_override << DMA_MODE_CACHE_OR_SHIFT;
71406 + if (cfg->dma_aid_override)
71407 + tmp_reg |= DMA_MODE_AID_OR;
71408 + if (cfg->exceptions & FMAN_EX_DMA_BUS_ERROR)
71409 + tmp_reg |= DMA_MODE_BER;
71410 + if ((cfg->exceptions & FMAN_EX_DMA_SYSTEM_WRITE_ECC) |
71411 + (cfg->exceptions & FMAN_EX_DMA_READ_ECC) |
71412 + (cfg->exceptions & FMAN_EX_DMA_FM_WRITE_ECC))
71413 + tmp_reg |= DMA_MODE_ECC;
71414 + if (cfg->dma_stop_on_bus_error)
71415 + tmp_reg |= DMA_MODE_SBER;
71416 + if(cfg->dma_axi_dbg_num_of_beats)
71417 + tmp_reg |= (uint32_t)(DMA_MODE_AXI_DBG_MASK &
71418 + ((cfg->dma_axi_dbg_num_of_beats - 1) << DMA_MODE_AXI_DBG_SHIFT));
71419 +
71420 + if (cfg->dma_en_emergency) {
71421 + tmp_reg |= cfg->dma_emergency_bus_select;
71422 + tmp_reg |= cfg->dma_emergency_level << DMA_MODE_EMER_LVL_SHIFT;
71423 + if (cfg->dma_en_emergency_smoother)
71424 + iowrite32be(cfg->dma_emergency_switch_counter,
71425 + &dma_rg->fmdmemsr);
71426 + }
71427 + tmp_reg |= ((cfg->dma_cam_num_of_entries / DMA_CAM_UNITS) - 1) <<
71428 + DMA_MODE_CEN_SHIFT;
71429 + tmp_reg |= DMA_MODE_SECURE_PROT;
71430 + tmp_reg |= cfg->dma_dbg_cnt_mode << DMA_MODE_DBG_SHIFT;
71431 + tmp_reg |= cfg->dma_aid_mode << DMA_MODE_AID_MODE_SHIFT;
71432 +
71433 + if (cfg->pedantic_dma)
71434 + tmp_reg |= DMA_MODE_EMER_READ;
71435 +
71436 + iowrite32be(tmp_reg, &dma_rg->fmdmmr);
71437 +
71438 + /* configure thresholds register */
71439 + tmp_reg = ((uint32_t)cfg->dma_comm_qtsh_asrt_emer <<
71440 + DMA_THRESH_COMMQ_SHIFT) |
71441 + ((uint32_t)cfg->dma_read_buf_tsh_asrt_emer <<
71442 + DMA_THRESH_READ_INT_BUF_SHIFT) |
71443 + ((uint32_t)cfg->dma_write_buf_tsh_asrt_emer);
71444 +
71445 + iowrite32be(tmp_reg, &dma_rg->fmdmtr);
71446 +
71447 + /* configure hysteresis register */
71448 + tmp_reg = ((uint32_t)cfg->dma_comm_qtsh_clr_emer <<
71449 + DMA_THRESH_COMMQ_SHIFT) |
71450 + ((uint32_t)cfg->dma_read_buf_tsh_clr_emer <<
71451 + DMA_THRESH_READ_INT_BUF_SHIFT) |
71452 + ((uint32_t)cfg->dma_write_buf_tsh_clr_emer);
71453 +
71454 + iowrite32be(tmp_reg, &dma_rg->fmdmhy);
71455 +
71456 + /* configure emergency threshold */
71457 + iowrite32be(cfg->dma_sos_emergency, &dma_rg->fmdmsetr);
71458 +
71459 + /* configure Watchdog */
71460 + iowrite32be((cfg->dma_watchdog * cfg->clk_freq),
71461 + &dma_rg->fmdmwcr);
71462 +
71463 + iowrite32be(cfg->cam_base_addr, &dma_rg->fmdmebcr);
71464 +
71465 + return 0;
71466 +}
71467 +
71468 +int fman_fpm_init(struct fman_fpm_regs *fpm_rg, struct fman_cfg *cfg)
71469 +{
71470 + uint32_t tmp_reg;
71471 + int i;
71472 +
71473 + /**********************/
71474 + /* Init FPM Registers */
71475 + /**********************/
71476 + tmp_reg = (uint32_t)(cfg->disp_limit_tsh << FPM_DISP_LIMIT_SHIFT);
71477 + iowrite32be(tmp_reg, &fpm_rg->fmfp_mxd);
71478 +
71479 + tmp_reg = (((uint32_t)cfg->prs_disp_tsh << FPM_THR1_PRS_SHIFT) |
71480 + ((uint32_t)cfg->kg_disp_tsh << FPM_THR1_KG_SHIFT) |
71481 + ((uint32_t)cfg->plcr_disp_tsh << FPM_THR1_PLCR_SHIFT) |
71482 + ((uint32_t)cfg->bmi_disp_tsh << FPM_THR1_BMI_SHIFT));
71483 + iowrite32be(tmp_reg, &fpm_rg->fmfp_dist1);
71484 +
71485 + tmp_reg = (((uint32_t)cfg->qmi_enq_disp_tsh << FPM_THR2_QMI_ENQ_SHIFT) |
71486 + ((uint32_t)cfg->qmi_deq_disp_tsh << FPM_THR2_QMI_DEQ_SHIFT) |
71487 + ((uint32_t)cfg->fm_ctl1_disp_tsh << FPM_THR2_FM_CTL1_SHIFT) |
71488 + ((uint32_t)cfg->fm_ctl2_disp_tsh << FPM_THR2_FM_CTL2_SHIFT));
71489 + iowrite32be(tmp_reg, &fpm_rg->fmfp_dist2);
71490 +
71491 + /* define exceptions and error behavior */
71492 + tmp_reg = 0;
71493 + /* Clear events */
71494 + tmp_reg |= (FPM_EV_MASK_STALL | FPM_EV_MASK_DOUBLE_ECC |
71495 + FPM_EV_MASK_SINGLE_ECC);
71496 + /* enable interrupts */
71497 + if (cfg->exceptions & FMAN_EX_FPM_STALL_ON_TASKS)
71498 + tmp_reg |= FPM_EV_MASK_STALL_EN;
71499 + if (cfg->exceptions & FMAN_EX_FPM_SINGLE_ECC)
71500 + tmp_reg |= FPM_EV_MASK_SINGLE_ECC_EN;
71501 + if (cfg->exceptions & FMAN_EX_FPM_DOUBLE_ECC)
71502 + tmp_reg |= FPM_EV_MASK_DOUBLE_ECC_EN;
71503 + tmp_reg |= (cfg->catastrophic_err << FPM_EV_MASK_CAT_ERR_SHIFT);
71504 + tmp_reg |= (cfg->dma_err << FPM_EV_MASK_DMA_ERR_SHIFT);
71505 + if (!cfg->halt_on_external_activ)
71506 + tmp_reg |= FPM_EV_MASK_EXTERNAL_HALT;
71507 + if (!cfg->halt_on_unrecov_ecc_err)
71508 + tmp_reg |= FPM_EV_MASK_ECC_ERR_HALT;
71509 + iowrite32be(tmp_reg, &fpm_rg->fmfp_ee);
71510 +
71511 + /* clear all fmCtls event registers */
71512 + for (i = 0; i < cfg->num_of_fman_ctrl_evnt_regs; i++)
71513 + iowrite32be(0xFFFFFFFF, &fpm_rg->fmfp_cev[i]);
71514 +
71515 + /* RAM ECC - enable and clear events*/
71516 + /* first we need to clear all parser memory,
71517 + * as it is uninitialized and may cause ECC errors */
71518 + /* event bits */
71519 + tmp_reg = (FPM_RAM_MURAM_ECC | FPM_RAM_IRAM_ECC);
71520 + /* Rams enable not effected by RCR bit, but by a COP configuration */
71521 + if (cfg->external_ecc_rams_enable)
71522 + tmp_reg |= FPM_RAM_RAMS_ECC_EN_SRC_SEL;
71523 +
71524 + /* enable test mode */
71525 + if (cfg->en_muram_test_mode)
71526 + tmp_reg |= FPM_RAM_MURAM_TEST_ECC;
71527 + if (cfg->en_iram_test_mode)
71528 + tmp_reg |= FPM_RAM_IRAM_TEST_ECC;
71529 + iowrite32be(tmp_reg, &fpm_rg->fm_rcr);
71530 +
71531 + tmp_reg = 0;
71532 + if (cfg->exceptions & FMAN_EX_IRAM_ECC) {
71533 + tmp_reg |= FPM_IRAM_ECC_ERR_EX_EN;
71534 + fman_enable_rams_ecc(fpm_rg);
71535 + }
71536 + if (cfg->exceptions & FMAN_EX_NURAM_ECC) {
71537 + tmp_reg |= FPM_MURAM_ECC_ERR_EX_EN;
71538 + fman_enable_rams_ecc(fpm_rg);
71539 + }
71540 + iowrite32be(tmp_reg, &fpm_rg->fm_rie);
71541 +
71542 + return 0;
71543 +}
71544 +
71545 +int fman_bmi_init(struct fman_bmi_regs *bmi_rg, struct fman_cfg *cfg)
71546 +{
71547 + uint32_t tmp_reg;
71548 +
71549 + /**********************/
71550 + /* Init BMI Registers */
71551 + /**********************/
71552 +
71553 + /* define common resources */
71554 + tmp_reg = cfg->fifo_base_addr;
71555 + tmp_reg = tmp_reg / BMI_FIFO_ALIGN;
71556 +
71557 + tmp_reg |= ((cfg->total_fifo_size / FMAN_BMI_FIFO_UNITS - 1) <<
71558 + BMI_CFG1_FIFO_SIZE_SHIFT);
71559 + iowrite32be(tmp_reg, &bmi_rg->fmbm_cfg1);
71560 +
71561 + tmp_reg = ((uint32_t)(cfg->total_num_of_tasks - 1) <<
71562 + BMI_CFG2_TASKS_SHIFT);
71563 + /* num of DMA's will be dynamically updated when each port is set */
71564 + iowrite32be(tmp_reg, &bmi_rg->fmbm_cfg2);
71565 +
71566 + /* define unmaskable exceptions, enable and clear events */
71567 + tmp_reg = 0;
71568 + iowrite32be(BMI_ERR_INTR_EN_LIST_RAM_ECC |
71569 + BMI_ERR_INTR_EN_STORAGE_PROFILE_ECC |
71570 + BMI_ERR_INTR_EN_STATISTICS_RAM_ECC |
71571 + BMI_ERR_INTR_EN_DISPATCH_RAM_ECC,
71572 + &bmi_rg->fmbm_ievr);
71573 +
71574 + if (cfg->exceptions & FMAN_EX_BMI_LIST_RAM_ECC)
71575 + tmp_reg |= BMI_ERR_INTR_EN_LIST_RAM_ECC;
71576 + if (cfg->exceptions & FMAN_EX_BMI_PIPELINE_ECC)
71577 + tmp_reg |= BMI_ERR_INTR_EN_STORAGE_PROFILE_ECC;
71578 + if (cfg->exceptions & FMAN_EX_BMI_STATISTICS_RAM_ECC)
71579 + tmp_reg |= BMI_ERR_INTR_EN_STATISTICS_RAM_ECC;
71580 + if (cfg->exceptions & FMAN_EX_BMI_DISPATCH_RAM_ECC)
71581 + tmp_reg |= BMI_ERR_INTR_EN_DISPATCH_RAM_ECC;
71582 + iowrite32be(tmp_reg, &bmi_rg->fmbm_ier);
71583 +
71584 + return 0;
71585 +}
71586 +
71587 +int fman_qmi_init(struct fman_qmi_regs *qmi_rg, struct fman_cfg *cfg)
71588 +{
71589 + uint32_t tmp_reg;
71590 + uint16_t period_in_fm_clocks;
71591 + uint8_t remainder;
71592 + /**********************/
71593 + /* Init QMI Registers */
71594 + /**********************/
71595 + /* Clear error interrupt events */
71596 +
71597 + iowrite32be(QMI_ERR_INTR_EN_DOUBLE_ECC | QMI_ERR_INTR_EN_DEQ_FROM_DEF,
71598 + &qmi_rg->fmqm_eie);
71599 + tmp_reg = 0;
71600 + if (cfg->exceptions & FMAN_EX_QMI_DEQ_FROM_UNKNOWN_PORTID)
71601 + tmp_reg |= QMI_ERR_INTR_EN_DEQ_FROM_DEF;
71602 + if (cfg->exceptions & FMAN_EX_QMI_DOUBLE_ECC)
71603 + tmp_reg |= QMI_ERR_INTR_EN_DOUBLE_ECC;
71604 + /* enable events */
71605 + iowrite32be(tmp_reg, &qmi_rg->fmqm_eien);
71606 +
71607 + if (cfg->tnum_aging_period) {
71608 + /* tnum_aging_period is in units of usec, p_FmClockFreq in Mhz */
71609 + period_in_fm_clocks = (uint16_t)
71610 + (cfg->tnum_aging_period * cfg->clk_freq);
71611 + /* period_in_fm_clocks must be a 64 multiply */
71612 + remainder = (uint8_t)(period_in_fm_clocks % 64);
71613 + if (remainder)
71614 + tmp_reg = (uint32_t)((period_in_fm_clocks / 64) + 1);
71615 + else{
71616 + tmp_reg = (uint32_t)(period_in_fm_clocks / 64);
71617 + if (!tmp_reg)
71618 + tmp_reg = 1;
71619 + }
71620 + tmp_reg <<= QMI_TAPC_TAP;
71621 + iowrite32be(tmp_reg, &qmi_rg->fmqm_tapc);
71622 + }
71623 + tmp_reg = 0;
71624 + /* Clear interrupt events */
71625 + iowrite32be(QMI_INTR_EN_SINGLE_ECC, &qmi_rg->fmqm_ie);
71626 + if (cfg->exceptions & FMAN_EX_QMI_SINGLE_ECC)
71627 + tmp_reg |= QMI_INTR_EN_SINGLE_ECC;
71628 + /* enable events */
71629 + iowrite32be(tmp_reg, &qmi_rg->fmqm_ien);
71630 +
71631 + return 0;
71632 +}
71633 +
71634 +int fman_enable(struct fman_rg *fman_rg, struct fman_cfg *cfg)
71635 +{
71636 + uint32_t cfg_reg = 0;
71637 +
71638 + /**********************/
71639 + /* Enable all modules */
71640 + /**********************/
71641 + /* clear & enable global counters - calculate reg and save for later,
71642 + because it's the same reg for QMI enable */
71643 + cfg_reg = QMI_CFG_EN_COUNTERS;
71644 + if (cfg->qmi_deq_option_support)
71645 + cfg_reg |= (uint32_t)(((cfg->qmi_def_tnums_thresh) << 8) |
71646 + (uint32_t)cfg->qmi_def_tnums_thresh);
71647 +
71648 + iowrite32be(BMI_INIT_START, &fman_rg->bmi_rg->fmbm_init);
71649 + iowrite32be(cfg_reg | QMI_CFG_ENQ_EN | QMI_CFG_DEQ_EN,
71650 + &fman_rg->qmi_rg->fmqm_gc);
71651 +
71652 + return 0;
71653 +}
71654 +
71655 +void fman_free_resources(struct fman_rg *fman_rg)
71656 +{
71657 + /* disable BMI and QMI */
71658 + iowrite32be(0, &fman_rg->bmi_rg->fmbm_init);
71659 + iowrite32be(0, &fman_rg->qmi_rg->fmqm_gc);
71660 +
71661 + /* release BMI resources */
71662 + iowrite32be(0, &fman_rg->bmi_rg->fmbm_cfg2);
71663 + iowrite32be(0, &fman_rg->bmi_rg->fmbm_cfg1);
71664 +
71665 + /* disable ECC */
71666 + iowrite32be(0, &fman_rg->fpm_rg->fm_rcr);
71667 +}
71668 +
71669 +/****************************************************/
71670 +/* API Run-time Control uint functions */
71671 +/****************************************************/
71672 +uint32_t fman_get_normal_pending(struct fman_fpm_regs *fpm_rg)
71673 +{
71674 + return ioread32be(&fpm_rg->fm_npi);
71675 +}
71676 +
71677 +uint32_t fman_get_controller_event(struct fman_fpm_regs *fpm_rg, uint8_t reg_id)
71678 +{
71679 + uint32_t event;
71680 +
71681 + event = ioread32be(&fpm_rg->fmfp_fcev[reg_id]) &
71682 + ioread32be(&fpm_rg->fmfp_cee[reg_id]);
71683 + iowrite32be(event, &fpm_rg->fmfp_cev[reg_id]);
71684 +
71685 + return event;
71686 +}
71687 +
71688 +uint32_t fman_get_error_pending(struct fman_fpm_regs *fpm_rg)
71689 +{
71690 + return ioread32be(&fpm_rg->fm_epi);
71691 +}
71692 +
71693 +void fman_set_ports_bandwidth(struct fman_bmi_regs *bmi_rg, uint8_t *weights)
71694 +{
71695 + int i;
71696 + uint8_t shift;
71697 + uint32_t tmp = 0;
71698 +
71699 + for (i = 0; i < 64; i++) {
71700 + if (weights[i] > 1) { /* no need to write 1 since it is 0 */
71701 + /* Add this port to tmp_reg */
71702 + /* (each 8 ports result in one register)*/
71703 + shift = (uint8_t)(32 - 4 * ((i % 8) + 1));
71704 + tmp |= ((weights[i] - 1) << shift);
71705 + }
71706 + if (i % 8 == 7) { /* last in this set */
71707 + iowrite32be(tmp, &bmi_rg->fmbm_arb[i / 8]);
71708 + tmp = 0;
71709 + }
71710 + }
71711 +}
71712 +
71713 +void fman_enable_rams_ecc(struct fman_fpm_regs *fpm_rg)
71714 +{
71715 + uint32_t tmp;
71716 +
71717 + tmp = ioread32be(&fpm_rg->fm_rcr);
71718 + if (tmp & FPM_RAM_RAMS_ECC_EN_SRC_SEL)
71719 + iowrite32be(tmp | FPM_RAM_IRAM_ECC_EN,
71720 + &fpm_rg->fm_rcr);
71721 + else
71722 + iowrite32be(tmp | FPM_RAM_RAMS_ECC_EN |
71723 + FPM_RAM_IRAM_ECC_EN,
71724 + &fpm_rg->fm_rcr);
71725 +}
71726 +
71727 +void fman_disable_rams_ecc(struct fman_fpm_regs *fpm_rg)
71728 +{
71729 + uint32_t tmp;
71730 +
71731 + tmp = ioread32be(&fpm_rg->fm_rcr);
71732 + if (tmp & FPM_RAM_RAMS_ECC_EN_SRC_SEL)
71733 + iowrite32be(tmp & ~FPM_RAM_IRAM_ECC_EN,
71734 + &fpm_rg->fm_rcr);
71735 + else
71736 + iowrite32be(tmp & ~(FPM_RAM_RAMS_ECC_EN | FPM_RAM_IRAM_ECC_EN),
71737 + &fpm_rg->fm_rcr);
71738 +}
71739 +
71740 +int fman_set_exception(struct fman_rg *fman_rg,
71741 + enum fman_exceptions exception,
71742 + bool enable)
71743 +{
71744 + uint32_t tmp;
71745 +
71746 + switch (exception) {
71747 + case(E_FMAN_EX_DMA_BUS_ERROR):
71748 + tmp = ioread32be(&fman_rg->dma_rg->fmdmmr);
71749 + if (enable)
71750 + tmp |= DMA_MODE_BER;
71751 + else
71752 + tmp &= ~DMA_MODE_BER;
71753 + /* disable bus error */
71754 + iowrite32be(tmp, &fman_rg->dma_rg->fmdmmr);
71755 + break;
71756 + case(E_FMAN_EX_DMA_READ_ECC):
71757 + case(E_FMAN_EX_DMA_SYSTEM_WRITE_ECC):
71758 + case(E_FMAN_EX_DMA_FM_WRITE_ECC):
71759 + tmp = ioread32be(&fman_rg->dma_rg->fmdmmr);
71760 + if (enable)
71761 + tmp |= DMA_MODE_ECC;
71762 + else
71763 + tmp &= ~DMA_MODE_ECC;
71764 + iowrite32be(tmp, &fman_rg->dma_rg->fmdmmr);
71765 + break;
71766 + case(E_FMAN_EX_FPM_STALL_ON_TASKS):
71767 + tmp = ioread32be(&fman_rg->fpm_rg->fmfp_ee);
71768 + if (enable)
71769 + tmp |= FPM_EV_MASK_STALL_EN;
71770 + else
71771 + tmp &= ~FPM_EV_MASK_STALL_EN;
71772 + iowrite32be(tmp, &fman_rg->fpm_rg->fmfp_ee);
71773 + break;
71774 + case(E_FMAN_EX_FPM_SINGLE_ECC):
71775 + tmp = ioread32be(&fman_rg->fpm_rg->fmfp_ee);
71776 + if (enable)
71777 + tmp |= FPM_EV_MASK_SINGLE_ECC_EN;
71778 + else
71779 + tmp &= ~FPM_EV_MASK_SINGLE_ECC_EN;
71780 + iowrite32be(tmp, &fman_rg->fpm_rg->fmfp_ee);
71781 + break;
71782 + case(E_FMAN_EX_FPM_DOUBLE_ECC):
71783 + tmp = ioread32be(&fman_rg->fpm_rg->fmfp_ee);
71784 + if (enable)
71785 + tmp |= FPM_EV_MASK_DOUBLE_ECC_EN;
71786 + else
71787 + tmp &= ~FPM_EV_MASK_DOUBLE_ECC_EN;
71788 + iowrite32be(tmp, &fman_rg->fpm_rg->fmfp_ee);
71789 + break;
71790 + case(E_FMAN_EX_QMI_SINGLE_ECC):
71791 + tmp = ioread32be(&fman_rg->qmi_rg->fmqm_ien);
71792 + if (enable)
71793 + tmp |= QMI_INTR_EN_SINGLE_ECC;
71794 + else
71795 + tmp &= ~QMI_INTR_EN_SINGLE_ECC;
71796 + iowrite32be(tmp, &fman_rg->qmi_rg->fmqm_ien);
71797 + break;
71798 + case(E_FMAN_EX_QMI_DOUBLE_ECC):
71799 + tmp = ioread32be(&fman_rg->qmi_rg->fmqm_eien);
71800 + if (enable)
71801 + tmp |= QMI_ERR_INTR_EN_DOUBLE_ECC;
71802 + else
71803 + tmp &= ~QMI_ERR_INTR_EN_DOUBLE_ECC;
71804 + iowrite32be(tmp, &fman_rg->qmi_rg->fmqm_eien);
71805 + break;
71806 + case(E_FMAN_EX_QMI_DEQ_FROM_UNKNOWN_PORTID):
71807 + tmp = ioread32be(&fman_rg->qmi_rg->fmqm_eien);
71808 + if (enable)
71809 + tmp |= QMI_ERR_INTR_EN_DEQ_FROM_DEF;
71810 + else
71811 + tmp &= ~QMI_ERR_INTR_EN_DEQ_FROM_DEF;
71812 + iowrite32be(tmp, &fman_rg->qmi_rg->fmqm_eien);
71813 + break;
71814 + case(E_FMAN_EX_BMI_LIST_RAM_ECC):
71815 + tmp = ioread32be(&fman_rg->bmi_rg->fmbm_ier);
71816 + if (enable)
71817 + tmp |= BMI_ERR_INTR_EN_LIST_RAM_ECC;
71818 + else
71819 + tmp &= ~BMI_ERR_INTR_EN_LIST_RAM_ECC;
71820 + iowrite32be(tmp, &fman_rg->bmi_rg->fmbm_ier);
71821 + break;
71822 + case(E_FMAN_EX_BMI_STORAGE_PROFILE_ECC):
71823 + tmp = ioread32be(&fman_rg->bmi_rg->fmbm_ier);
71824 + if (enable)
71825 + tmp |= BMI_ERR_INTR_EN_STORAGE_PROFILE_ECC;
71826 + else
71827 + tmp &= ~BMI_ERR_INTR_EN_STORAGE_PROFILE_ECC;
71828 + iowrite32be(tmp, &fman_rg->bmi_rg->fmbm_ier);
71829 + break;
71830 + case(E_FMAN_EX_BMI_STATISTICS_RAM_ECC):
71831 + tmp = ioread32be(&fman_rg->bmi_rg->fmbm_ier);
71832 + if (enable)
71833 + tmp |= BMI_ERR_INTR_EN_STATISTICS_RAM_ECC;
71834 + else
71835 + tmp &= ~BMI_ERR_INTR_EN_STATISTICS_RAM_ECC;
71836 + iowrite32be(tmp, &fman_rg->bmi_rg->fmbm_ier);
71837 + break;
71838 + case(E_FMAN_EX_BMI_DISPATCH_RAM_ECC):
71839 + tmp = ioread32be(&fman_rg->bmi_rg->fmbm_ier);
71840 + if (enable)
71841 + tmp |= BMI_ERR_INTR_EN_DISPATCH_RAM_ECC;
71842 + else
71843 + tmp &= ~BMI_ERR_INTR_EN_DISPATCH_RAM_ECC;
71844 + iowrite32be(tmp, &fman_rg->bmi_rg->fmbm_ier);
71845 + break;
71846 + case(E_FMAN_EX_IRAM_ECC):
71847 + tmp = ioread32be(&fman_rg->fpm_rg->fm_rie);
71848 + if (enable) {
71849 + /* enable ECC if not enabled */
71850 + fman_enable_rams_ecc(fman_rg->fpm_rg);
71851 + /* enable ECC interrupts */
71852 + tmp |= FPM_IRAM_ECC_ERR_EX_EN;
71853 + } else {
71854 + /* ECC mechanism may be disabled,
71855 + * depending on driver status */
71856 + fman_disable_rams_ecc(fman_rg->fpm_rg);
71857 + tmp &= ~FPM_IRAM_ECC_ERR_EX_EN;
71858 + }
71859 + iowrite32be(tmp, &fman_rg->fpm_rg->fm_rie);
71860 + break;
71861 + case(E_FMAN_EX_MURAM_ECC):
71862 + tmp = ioread32be(&fman_rg->fpm_rg->fm_rie);
71863 + if (enable) {
71864 + /* enable ECC if not enabled */
71865 + fman_enable_rams_ecc(fman_rg->fpm_rg);
71866 + /* enable ECC interrupts */
71867 + tmp |= FPM_MURAM_ECC_ERR_EX_EN;
71868 + } else {
71869 + /* ECC mechanism may be disabled,
71870 + * depending on driver status */
71871 + fman_disable_rams_ecc(fman_rg->fpm_rg);
71872 + tmp &= ~FPM_MURAM_ECC_ERR_EX_EN;
71873 + }
71874 + iowrite32be(tmp, &fman_rg->fpm_rg->fm_rie);
71875 + break;
71876 + default:
71877 + return -EINVAL;
71878 + }
71879 + return 0;
71880 +}
71881 +
71882 +void fman_get_revision(struct fman_fpm_regs *fpm_rg,
71883 + uint8_t *major,
71884 + uint8_t *minor)
71885 +{
71886 + uint32_t tmp;
71887 +
71888 + tmp = ioread32be(&fpm_rg->fm_ip_rev_1);
71889 + *major = (uint8_t)((tmp & FPM_REV1_MAJOR_MASK) >> FPM_REV1_MAJOR_SHIFT);
71890 + *minor = (uint8_t)((tmp & FPM_REV1_MINOR_MASK) >> FPM_REV1_MINOR_SHIFT);
71891 +
71892 +}
71893 +
71894 +uint32_t fman_get_counter(struct fman_rg *fman_rg,
71895 + enum fman_counters reg_name)
71896 +{
71897 + uint32_t ret_val;
71898 +
71899 + switch (reg_name) {
71900 + case(E_FMAN_COUNTERS_ENQ_TOTAL_FRAME):
71901 + ret_val = ioread32be(&fman_rg->qmi_rg->fmqm_etfc);
71902 + break;
71903 + case(E_FMAN_COUNTERS_DEQ_TOTAL_FRAME):
71904 + ret_val = ioread32be(&fman_rg->qmi_rg->fmqm_dtfc);
71905 + break;
71906 + case(E_FMAN_COUNTERS_DEQ_0):
71907 + ret_val = ioread32be(&fman_rg->qmi_rg->fmqm_dc0);
71908 + break;
71909 + case(E_FMAN_COUNTERS_DEQ_1):
71910 + ret_val = ioread32be(&fman_rg->qmi_rg->fmqm_dc1);
71911 + break;
71912 + case(E_FMAN_COUNTERS_DEQ_2):
71913 + ret_val = ioread32be(&fman_rg->qmi_rg->fmqm_dc2);
71914 + break;
71915 + case(E_FMAN_COUNTERS_DEQ_3):
71916 + ret_val = ioread32be(&fman_rg->qmi_rg->fmqm_dc3);
71917 + break;
71918 + case(E_FMAN_COUNTERS_DEQ_FROM_DEFAULT):
71919 + ret_val = ioread32be(&fman_rg->qmi_rg->fmqm_dfdc);
71920 + break;
71921 + case(E_FMAN_COUNTERS_DEQ_FROM_CONTEXT):
71922 + ret_val = ioread32be(&fman_rg->qmi_rg->fmqm_dfcc);
71923 + break;
71924 + case(E_FMAN_COUNTERS_DEQ_FROM_FD):
71925 + ret_val = ioread32be(&fman_rg->qmi_rg->fmqm_dffc);
71926 + break;
71927 + case(E_FMAN_COUNTERS_DEQ_CONFIRM):
71928 + ret_val = ioread32be(&fman_rg->qmi_rg->fmqm_dcc);
71929 + break;
71930 + default:
71931 + ret_val = 0;
71932 + }
71933 + return ret_val;
71934 +}
71935 +
71936 +int fman_modify_counter(struct fman_rg *fman_rg,
71937 + enum fman_counters reg_name,
71938 + uint32_t val)
71939 +{
71940 + /* When applicable (when there is an 'enable counters' bit,
71941 + * check that counters are enabled */
71942 + switch (reg_name) {
71943 + case(E_FMAN_COUNTERS_ENQ_TOTAL_FRAME):
71944 + case(E_FMAN_COUNTERS_DEQ_TOTAL_FRAME):
71945 + case(E_FMAN_COUNTERS_DEQ_0):
71946 + case(E_FMAN_COUNTERS_DEQ_1):
71947 + case(E_FMAN_COUNTERS_DEQ_2):
71948 + case(E_FMAN_COUNTERS_DEQ_3):
71949 + case(E_FMAN_COUNTERS_DEQ_FROM_DEFAULT):
71950 + case(E_FMAN_COUNTERS_DEQ_FROM_CONTEXT):
71951 + case(E_FMAN_COUNTERS_DEQ_FROM_FD):
71952 + case(E_FMAN_COUNTERS_DEQ_CONFIRM):
71953 + if (!(ioread32be(&fman_rg->qmi_rg->fmqm_gc) &
71954 + QMI_CFG_EN_COUNTERS))
71955 + return -EINVAL;
71956 + break;
71957 + default:
71958 + break;
71959 + }
71960 + /* Set counter */
71961 + switch (reg_name) {
71962 + case(E_FMAN_COUNTERS_ENQ_TOTAL_FRAME):
71963 + iowrite32be(val, &fman_rg->qmi_rg->fmqm_etfc);
71964 + break;
71965 + case(E_FMAN_COUNTERS_DEQ_TOTAL_FRAME):
71966 + iowrite32be(val, &fman_rg->qmi_rg->fmqm_dtfc);
71967 + break;
71968 + case(E_FMAN_COUNTERS_DEQ_0):
71969 + iowrite32be(val, &fman_rg->qmi_rg->fmqm_dc0);
71970 + break;
71971 + case(E_FMAN_COUNTERS_DEQ_1):
71972 + iowrite32be(val, &fman_rg->qmi_rg->fmqm_dc1);
71973 + break;
71974 + case(E_FMAN_COUNTERS_DEQ_2):
71975 + iowrite32be(val, &fman_rg->qmi_rg->fmqm_dc2);
71976 + break;
71977 + case(E_FMAN_COUNTERS_DEQ_3):
71978 + iowrite32be(val, &fman_rg->qmi_rg->fmqm_dc3);
71979 + break;
71980 + case(E_FMAN_COUNTERS_DEQ_FROM_DEFAULT):
71981 + iowrite32be(val, &fman_rg->qmi_rg->fmqm_dfdc);
71982 + break;
71983 + case(E_FMAN_COUNTERS_DEQ_FROM_CONTEXT):
71984 + iowrite32be(val, &fman_rg->qmi_rg->fmqm_dfcc);
71985 + break;
71986 + case(E_FMAN_COUNTERS_DEQ_FROM_FD):
71987 + iowrite32be(val, &fman_rg->qmi_rg->fmqm_dffc);
71988 + break;
71989 + case(E_FMAN_COUNTERS_DEQ_CONFIRM):
71990 + iowrite32be(val, &fman_rg->qmi_rg->fmqm_dcc);
71991 + break;
71992 + case(E_FMAN_COUNTERS_SEMAPHOR_ENTRY_FULL_REJECT):
71993 + iowrite32be(val, &fman_rg->dma_rg->fmdmsefrc);
71994 + break;
71995 + case(E_FMAN_COUNTERS_SEMAPHOR_QUEUE_FULL_REJECT):
71996 + iowrite32be(val, &fman_rg->dma_rg->fmdmsqfrc);
71997 + break;
71998 + case(E_FMAN_COUNTERS_SEMAPHOR_SYNC_REJECT):
71999 + iowrite32be(val, &fman_rg->dma_rg->fmdmssrc);
72000 + break;
72001 + default:
72002 + break;
72003 + }
72004 + return 0;
72005 +}
72006 +
72007 +void fman_set_dma_emergency(struct fman_dma_regs *dma_rg,
72008 + bool is_write,
72009 + bool enable)
72010 +{
72011 + uint32_t msk;
72012 +
72013 + msk = (uint32_t)(is_write ? DMA_MODE_EMER_WRITE : DMA_MODE_EMER_READ);
72014 +
72015 + if (enable)
72016 + iowrite32be(ioread32be(&dma_rg->fmdmmr) | msk,
72017 + &dma_rg->fmdmmr);
72018 + else /* disable */
72019 + iowrite32be(ioread32be(&dma_rg->fmdmmr) & ~msk,
72020 + &dma_rg->fmdmmr);
72021 +}
72022 +
72023 +void fman_set_dma_ext_bus_pri(struct fman_dma_regs *dma_rg, uint32_t pri)
72024 +{
72025 + uint32_t tmp;
72026 +
72027 + tmp = ioread32be(&dma_rg->fmdmmr) |
72028 + (pri << DMA_MODE_BUS_PRI_SHIFT);
72029 +
72030 + iowrite32be(tmp, &dma_rg->fmdmmr);
72031 +}
72032 +
72033 +uint32_t fman_get_dma_status(struct fman_dma_regs *dma_rg)
72034 +{
72035 + return ioread32be(&dma_rg->fmdmsr);
72036 +}
72037 +
72038 +void fman_force_intr(struct fman_rg *fman_rg,
72039 + enum fman_exceptions exception)
72040 +{
72041 + switch (exception) {
72042 + case E_FMAN_EX_QMI_DEQ_FROM_UNKNOWN_PORTID:
72043 + iowrite32be(QMI_ERR_INTR_EN_DEQ_FROM_DEF,
72044 + &fman_rg->qmi_rg->fmqm_eif);
72045 + break;
72046 + case E_FMAN_EX_QMI_SINGLE_ECC:
72047 + iowrite32be(QMI_INTR_EN_SINGLE_ECC,
72048 + &fman_rg->qmi_rg->fmqm_if);
72049 + break;
72050 + case E_FMAN_EX_QMI_DOUBLE_ECC:
72051 + iowrite32be(QMI_ERR_INTR_EN_DOUBLE_ECC,
72052 + &fman_rg->qmi_rg->fmqm_eif);
72053 + break;
72054 + case E_FMAN_EX_BMI_LIST_RAM_ECC:
72055 + iowrite32be(BMI_ERR_INTR_EN_LIST_RAM_ECC,
72056 + &fman_rg->bmi_rg->fmbm_ifr);
72057 + break;
72058 + case E_FMAN_EX_BMI_STORAGE_PROFILE_ECC:
72059 + iowrite32be(BMI_ERR_INTR_EN_STORAGE_PROFILE_ECC,
72060 + &fman_rg->bmi_rg->fmbm_ifr);
72061 + break;
72062 + case E_FMAN_EX_BMI_STATISTICS_RAM_ECC:
72063 + iowrite32be(BMI_ERR_INTR_EN_STATISTICS_RAM_ECC,
72064 + &fman_rg->bmi_rg->fmbm_ifr);
72065 + break;
72066 + case E_FMAN_EX_BMI_DISPATCH_RAM_ECC:
72067 + iowrite32be(BMI_ERR_INTR_EN_DISPATCH_RAM_ECC,
72068 + &fman_rg->bmi_rg->fmbm_ifr);
72069 + break;
72070 + default:
72071 + break;
72072 + }
72073 +}
72074 +
72075 +bool fman_is_qmi_halt_not_busy_state(struct fman_qmi_regs *qmi_rg)
72076 +{
72077 + return (bool)!!(ioread32be(&qmi_rg->fmqm_gs) & QMI_GS_HALT_NOT_BUSY);
72078 +}
72079 +void fman_resume(struct fman_fpm_regs *fpm_rg)
72080 +{
72081 + uint32_t tmp;
72082 +
72083 + tmp = ioread32be(&fpm_rg->fmfp_ee);
72084 + /* clear tmp_reg event bits in order not to clear standing events */
72085 + tmp &= ~(FPM_EV_MASK_DOUBLE_ECC |
72086 + FPM_EV_MASK_STALL |
72087 + FPM_EV_MASK_SINGLE_ECC);
72088 + tmp |= FPM_EV_MASK_RELEASE_FM;
72089 +
72090 + iowrite32be(tmp, &fpm_rg->fmfp_ee);
72091 +}
72092 --- /dev/null
72093 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/inc/fm_common.h
72094 @@ -0,0 +1,1214 @@
72095 +/*
72096 + * Copyright 2008-2012 Freescale Semiconductor Inc.
72097 + *
72098 + * Redistribution and use in source and binary forms, with or without
72099 + * modification, are permitted provided that the following conditions are met:
72100 + * * Redistributions of source code must retain the above copyright
72101 + * notice, this list of conditions and the following disclaimer.
72102 + * * Redistributions in binary form must reproduce the above copyright
72103 + * notice, this list of conditions and the following disclaimer in the
72104 + * documentation and/or other materials provided with the distribution.
72105 + * * Neither the name of Freescale Semiconductor nor the
72106 + * names of its contributors may be used to endorse or promote products
72107 + * derived from this software without specific prior written permission.
72108 + *
72109 + *
72110 + * ALTERNATIVELY, this software may be distributed under the terms of the
72111 + * GNU General Public License ("GPL") as published by the Free Software
72112 + * Foundation, either version 2 of that License or (at your option) any
72113 + * later version.
72114 + *
72115 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
72116 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
72117 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
72118 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
72119 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
72120 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
72121 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
72122 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
72123 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
72124 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
72125 + */
72126 +
72127 +
72128 +/******************************************************************************
72129 + @File fm_common.h
72130 +
72131 + @Description FM internal structures and definitions.
72132 +*//***************************************************************************/
72133 +#ifndef __FM_COMMON_H
72134 +#define __FM_COMMON_H
72135 +
72136 +#include "error_ext.h"
72137 +#include "std_ext.h"
72138 +#include "fm_pcd_ext.h"
72139 +#include "fm_ext.h"
72140 +#include "fm_port_ext.h"
72141 +
72142 +
72143 +#define e_FM_PORT_TYPE_OH_HOST_COMMAND e_FM_PORT_TYPE_DUMMY
72144 +
72145 +#define CLS_PLAN_NUM_PER_GRP 8
72146 +
72147 +#define IP_OFFLOAD_PACKAGE_NUMBER 106
72148 +#define CAPWAP_OFFLOAD_PACKAGE_NUMBER 108
72149 +#define IS_OFFLOAD_PACKAGE(num) ((num == IP_OFFLOAD_PACKAGE_NUMBER) || (num == CAPWAP_OFFLOAD_PACKAGE_NUMBER))
72150 +
72151 +
72152 +
72153 +/**************************************************************************//**
72154 + @Description Modules registers offsets
72155 +*//***************************************************************************/
72156 +#define FM_MM_MURAM 0x00000000
72157 +#define FM_MM_BMI 0x00080000
72158 +#define FM_MM_QMI 0x00080400
72159 +#define FM_MM_PRS 0x000c7000
72160 +#define FM_MM_KG 0x000C1000
72161 +#define FM_MM_DMA 0x000C2000
72162 +#define FM_MM_FPM 0x000C3000
72163 +#define FM_MM_PLCR 0x000C0000
72164 +#define FM_MM_IMEM 0x000C4000
72165 +#define FM_MM_CGP 0x000DB000
72166 +#define FM_MM_TRB(i) (0x000D0200 + 0x400 * (i))
72167 +#if (DPAA_VERSION >= 11)
72168 +#define FM_MM_SP 0x000dc000
72169 +#endif /* (DPAA_VERSION >= 11) */
72170 +
72171 +
72172 +/**************************************************************************//**
72173 + @Description Enum for inter-module interrupts registration
72174 +*//***************************************************************************/
72175 +typedef enum e_FmEventModules{
72176 + e_FM_MOD_PRS, /**< Parser event */
72177 + e_FM_MOD_KG, /**< Keygen event */
72178 + e_FM_MOD_PLCR, /**< Policer event */
72179 + e_FM_MOD_10G_MAC, /**< 10G MAC event */
72180 + e_FM_MOD_1G_MAC, /**< 1G MAC event */
72181 + e_FM_MOD_TMR, /**< Timer event */
72182 + e_FM_MOD_FMAN_CTRL, /**< FMAN Controller Timer event */
72183 + e_FM_MOD_MACSEC,
72184 + e_FM_MOD_DUMMY_LAST
72185 +} e_FmEventModules;
72186 +
72187 +/**************************************************************************//**
72188 + @Description Enum for interrupts types
72189 +*//***************************************************************************/
72190 +typedef enum e_FmIntrType {
72191 + e_FM_INTR_TYPE_ERR,
72192 + e_FM_INTR_TYPE_NORMAL
72193 +} e_FmIntrType;
72194 +
72195 +/**************************************************************************//**
72196 + @Description Enum for inter-module interrupts registration
72197 +*//***************************************************************************/
72198 +typedef enum e_FmInterModuleEvent
72199 +{
72200 + e_FM_EV_PRS = 0, /**< Parser event */
72201 + e_FM_EV_ERR_PRS, /**< Parser error event */
72202 + e_FM_EV_KG, /**< Keygen event */
72203 + e_FM_EV_ERR_KG, /**< Keygen error event */
72204 + e_FM_EV_PLCR, /**< Policer event */
72205 + e_FM_EV_ERR_PLCR, /**< Policer error event */
72206 + e_FM_EV_ERR_10G_MAC0, /**< 10G MAC 0 error event */
72207 + e_FM_EV_ERR_10G_MAC1, /**< 10G MAC 1 error event */
72208 + e_FM_EV_ERR_1G_MAC0, /**< 1G MAC 0 error event */
72209 + e_FM_EV_ERR_1G_MAC1, /**< 1G MAC 1 error event */
72210 + e_FM_EV_ERR_1G_MAC2, /**< 1G MAC 2 error event */
72211 + e_FM_EV_ERR_1G_MAC3, /**< 1G MAC 3 error event */
72212 + e_FM_EV_ERR_1G_MAC4, /**< 1G MAC 4 error event */
72213 + e_FM_EV_ERR_1G_MAC5, /**< 1G MAC 5 error event */
72214 + e_FM_EV_ERR_1G_MAC6, /**< 1G MAC 6 error event */
72215 + e_FM_EV_ERR_1G_MAC7, /**< 1G MAC 7 error event */
72216 + e_FM_EV_ERR_MACSEC_MAC0,
72217 + e_FM_EV_TMR, /**< Timer event */
72218 + e_FM_EV_10G_MAC0, /**< 10G MAC 0 event (Magic packet detection)*/
72219 + e_FM_EV_10G_MAC1, /**< 10G MAC 1 event (Magic packet detection)*/
72220 + e_FM_EV_1G_MAC0, /**< 1G MAC 0 event (Magic packet detection)*/
72221 + e_FM_EV_1G_MAC1, /**< 1G MAC 1 event (Magic packet detection)*/
72222 + e_FM_EV_1G_MAC2, /**< 1G MAC 2 (Magic packet detection)*/
72223 + e_FM_EV_1G_MAC3, /**< 1G MAC 3 (Magic packet detection)*/
72224 + e_FM_EV_1G_MAC4, /**< 1G MAC 4 (Magic packet detection)*/
72225 + e_FM_EV_1G_MAC5, /**< 1G MAC 5 (Magic packet detection)*/
72226 + e_FM_EV_1G_MAC6, /**< 1G MAC 6 (Magic packet detection)*/
72227 + e_FM_EV_1G_MAC7, /**< 1G MAC 7 (Magic packet detection)*/
72228 + e_FM_EV_MACSEC_MAC0, /**< MACSEC MAC 0 event */
72229 + e_FM_EV_FMAN_CTRL_0, /**< Fman controller event 0 */
72230 + e_FM_EV_FMAN_CTRL_1, /**< Fman controller event 1 */
72231 + e_FM_EV_FMAN_CTRL_2, /**< Fman controller event 2 */
72232 + e_FM_EV_FMAN_CTRL_3, /**< Fman controller event 3 */
72233 + e_FM_EV_DUMMY_LAST
72234 +} e_FmInterModuleEvent;
72235 +
72236 +
72237 +#if defined(__MWERKS__) && !defined(__GNUC__)
72238 +#pragma pack(push,1)
72239 +#endif /* defined(__MWERKS__) && ... */
72240 +
72241 +/**************************************************************************//**
72242 + @Description PCD KG scheme registers
72243 +*//***************************************************************************/
72244 +typedef _Packed struct t_FmPcdPlcrProfileRegs {
72245 + volatile uint32_t fmpl_pemode; /* 0x090 FMPL_PEMODE - FM Policer Profile Entry Mode*/
72246 + volatile uint32_t fmpl_pegnia; /* 0x094 FMPL_PEGNIA - FM Policer Profile Entry GREEN Next Invoked Action*/
72247 + volatile uint32_t fmpl_peynia; /* 0x098 FMPL_PEYNIA - FM Policer Profile Entry YELLOW Next Invoked Action*/
72248 + volatile uint32_t fmpl_pernia; /* 0x09C FMPL_PERNIA - FM Policer Profile Entry RED Next Invoked Action*/
72249 + volatile uint32_t fmpl_pecir; /* 0x0A0 FMPL_PECIR - FM Policer Profile Entry Committed Information Rate*/
72250 + volatile uint32_t fmpl_pecbs; /* 0x0A4 FMPL_PECBS - FM Policer Profile Entry Committed Burst Size*/
72251 + volatile uint32_t fmpl_pepepir_eir; /* 0x0A8 FMPL_PEPIR_EIR - FM Policer Profile Entry Peak/Excess Information Rate*/
72252 + volatile uint32_t fmpl_pepbs_ebs; /* 0x0AC FMPL_PEPBS_EBS - FM Policer Profile Entry Peak/Excess Information Rate*/
72253 + volatile uint32_t fmpl_pelts; /* 0x0B0 FMPL_PELTS - FM Policer Profile Entry Last TimeStamp*/
72254 + volatile uint32_t fmpl_pects; /* 0x0B4 FMPL_PECTS - FM Policer Profile Entry Committed Token Status*/
72255 + volatile uint32_t fmpl_pepts_ets; /* 0x0B8 FMPL_PEPTS_ETS - FM Policer Profile Entry Peak/Excess Token Status*/
72256 + volatile uint32_t fmpl_pegpc; /* 0x0BC FMPL_PEGPC - FM Policer Profile Entry GREEN Packet Counter*/
72257 + volatile uint32_t fmpl_peypc; /* 0x0C0 FMPL_PEYPC - FM Policer Profile Entry YELLOW Packet Counter*/
72258 + volatile uint32_t fmpl_perpc; /* 0x0C4 FMPL_PERPC - FM Policer Profile Entry RED Packet Counter */
72259 + volatile uint32_t fmpl_perypc; /* 0x0C8 FMPL_PERYPC - FM Policer Profile Entry Recolored YELLOW Packet Counter*/
72260 + volatile uint32_t fmpl_perrpc; /* 0x0CC FMPL_PERRPC - FM Policer Profile Entry Recolored RED Packet Counter*/
72261 + volatile uint32_t fmpl_res1[12]; /* 0x0D0-0x0FF Reserved */
72262 +} _PackedType t_FmPcdPlcrProfileRegs;
72263 +
72264 +
72265 +typedef _Packed struct t_FmPcdCcCapwapReassmTimeoutParams {
72266 + volatile uint32_t portIdAndCapwapReassmTbl;
72267 + volatile uint32_t fqidForTimeOutFrames;
72268 + volatile uint32_t timeoutRequestTime;
72269 +}_PackedType t_FmPcdCcCapwapReassmTimeoutParams;
72270 +
72271 +/**************************************************************************//**
72272 + @Description PCD CTRL Parameters Page
72273 +*//***************************************************************************/
72274 +typedef _Packed struct t_FmPcdCtrlParamsPage {
72275 + volatile uint8_t reserved0[16];
72276 + volatile uint32_t iprIpv4Nia;
72277 + volatile uint32_t iprIpv6Nia;
72278 + volatile uint8_t reserved1[24];
72279 + volatile uint32_t ipfOptionsCounter;
72280 + volatile uint8_t reserved2[12];
72281 + volatile uint32_t misc;
72282 + volatile uint32_t errorsDiscardMask;
72283 + volatile uint32_t discardMask;
72284 + volatile uint8_t reserved3[4];
72285 + volatile uint32_t postBmiFetchNia;
72286 + volatile uint8_t reserved4[172];
72287 +} _PackedType t_FmPcdCtrlParamsPage;
72288 +
72289 +
72290 +
72291 +#if defined(__MWERKS__) && !defined(__GNUC__)
72292 +#pragma pack(pop)
72293 +#endif /* defined(__MWERKS__) && ... */
72294 +
72295 +
72296 +/*for UNDER_CONSTRUCTION_FM_RMU_USE_SEC its defined in fm_ext.h*/
72297 +typedef uint32_t t_FmFmanCtrl;
72298 +
72299 +#define FPM_PORT_FM_CTL1 0x00000001
72300 +#define FPM_PORT_FM_CTL2 0x00000002
72301 +
72302 +
72303 +
72304 +typedef struct t_FmPcdCcFragScratchPoolCmdParams {
72305 + uint32_t numOfBuffers;
72306 + uint8_t bufferPoolId;
72307 +} t_FmPcdCcFragScratchPoolCmdParams;
72308 +
72309 +typedef struct t_FmPcdCcReassmTimeoutParams {
72310 + bool activate;
72311 + uint8_t tsbs;
72312 + uint32_t iprcpt;
72313 +} t_FmPcdCcReassmTimeoutParams;
72314 +
72315 +typedef struct {
72316 + uint8_t baseEntry;
72317 + uint16_t numOfClsPlanEntries;
72318 + uint32_t vectors[FM_PCD_MAX_NUM_OF_CLS_PLANS];
72319 +} t_FmPcdKgInterModuleClsPlanSet;
72320 +
72321 +/**************************************************************************//**
72322 + @Description Structure for binding a port to keygen schemes.
72323 +*//***************************************************************************/
72324 +typedef struct t_FmPcdKgInterModuleBindPortToSchemes {
72325 + uint8_t hardwarePortId;
72326 + uint8_t netEnvId;
72327 + bool useClsPlan; /**< TRUE if this port uses the clsPlan mechanism */
72328 + uint8_t numOfSchemes;
72329 + uint8_t schemesIds[FM_PCD_KG_NUM_OF_SCHEMES];
72330 +} t_FmPcdKgInterModuleBindPortToSchemes;
72331 +
72332 +typedef struct {
72333 + uint32_t nextCcNodeInfo;
72334 + t_List node;
72335 +} t_CcNodeInfo;
72336 +
72337 +typedef struct
72338 +{
72339 + t_Handle h_CcNode;
72340 + uint16_t index;
72341 + t_List node;
72342 +}t_CcNodeInformation;
72343 +#define CC_NODE_F_OBJECT(ptr) LIST_OBJECT(ptr, t_CcNodeInformation, node)
72344 +
72345 +typedef enum e_ModifyState
72346 +{
72347 + e_MODIFY_STATE_ADD = 0,
72348 + e_MODIFY_STATE_REMOVE,
72349 + e_MODIFY_STATE_CHANGE
72350 +} e_ModifyState;
72351 +
72352 +typedef struct
72353 +{
72354 + t_Handle h_Manip;
72355 + t_List node;
72356 +}t_ManipInfo;
72357 +#define CC_NEXT_NODE_F_OBJECT(ptr) LIST_OBJECT(ptr, t_CcNodeInfo, node)
72358 +
72359 +typedef struct {
72360 + uint32_t type;
72361 + uint8_t prOffset;
72362 + uint16_t dataOffset;
72363 + uint8_t internalBufferOffset;
72364 + uint8_t numOfTasks;
72365 + uint8_t numOfExtraTasks;
72366 + uint8_t hardwarePortId;
72367 + t_FmRevisionInfo revInfo;
72368 + uint32_t nia;
72369 + uint32_t discardMask;
72370 +} t_GetCcParams;
72371 +
72372 +typedef struct {
72373 + uint32_t type;
72374 + int psoSize;
72375 + uint32_t nia;
72376 + t_FmFmanCtrl orFmanCtrl;
72377 + bool overwrite;
72378 + uint8_t ofpDpde;
72379 +} t_SetCcParams;
72380 +
72381 +typedef struct {
72382 + t_GetCcParams getCcParams;
72383 + t_SetCcParams setCcParams;
72384 +} t_FmPortGetSetCcParams;
72385 +
72386 +typedef struct {
72387 + uint32_t type;
72388 + bool sleep;
72389 +} t_FmSetParams;
72390 +
72391 +typedef struct {
72392 + uint32_t type;
72393 + uint32_t fmqm_gs;
72394 + uint32_t fm_npi;
72395 + uint32_t fm_cld;
72396 + uint32_t fmfp_extc;
72397 +} t_FmGetParams;
72398 +
72399 +typedef struct {
72400 + t_FmSetParams setParams;
72401 + t_FmGetParams getParams;
72402 +} t_FmGetSetParams;
72403 +
72404 +t_Error FmGetSetParams(t_Handle h_Fm, t_FmGetSetParams *p_Params);
72405 +
72406 +static __inline__ bool TRY_LOCK(t_Handle h_Spinlock, volatile bool *p_Flag)
72407 +{
72408 + uint32_t intFlags;
72409 + if (h_Spinlock)
72410 + intFlags = XX_LockIntrSpinlock(h_Spinlock);
72411 + else
72412 + intFlags = XX_DisableAllIntr();
72413 +
72414 + if (*p_Flag)
72415 + {
72416 + if (h_Spinlock)
72417 + XX_UnlockIntrSpinlock(h_Spinlock, intFlags);
72418 + else
72419 + XX_RestoreAllIntr(intFlags);
72420 + return FALSE;
72421 + }
72422 + *p_Flag = TRUE;
72423 +
72424 + if (h_Spinlock)
72425 + XX_UnlockIntrSpinlock(h_Spinlock, intFlags);
72426 + else
72427 + XX_RestoreAllIntr(intFlags);
72428 +
72429 + return TRUE;
72430 +}
72431 +
72432 +#define RELEASE_LOCK(_flag) _flag = FALSE;
72433 +
72434 +/**************************************************************************//**
72435 + @Collection Defines used for manipulation CC and BMI
72436 + @{
72437 +*//***************************************************************************/
72438 +#define INTERNAL_CONTEXT_OFFSET 0x80000000
72439 +#define OFFSET_OF_PR 0x40000000
72440 +#define MANIP_EXTRA_SPACE 0x20000000
72441 +#define NUM_OF_TASKS 0x10000000
72442 +#define OFFSET_OF_DATA 0x08000000
72443 +#define HW_PORT_ID 0x04000000
72444 +#define FM_REV 0x02000000
72445 +#define GET_NIA_FPNE 0x01000000
72446 +#define GET_NIA_PNDN 0x00800000
72447 +#define NUM_OF_EXTRA_TASKS 0x00400000
72448 +#define DISCARD_MASK 0x00200000
72449 +
72450 +#define UPDATE_NIA_PNEN 0x80000000
72451 +#define UPDATE_PSO 0x40000000
72452 +#define UPDATE_NIA_PNDN 0x20000000
72453 +#define UPDATE_FMFP_PRC_WITH_ONE_RISC_ONLY 0x10000000
72454 +#define UPDATE_OFP_DPTE 0x08000000
72455 +#define UPDATE_NIA_FENE 0x04000000
72456 +#define UPDATE_NIA_CMNE 0x02000000
72457 +#define UPDATE_NIA_FPNE 0x01000000
72458 +/* @} */
72459 +
72460 +/**************************************************************************//**
72461 + @Collection Defines used for manipulation CC and CC
72462 + @{
72463 +*//***************************************************************************/
72464 +#define UPDATE_NIA_ENQ_WITHOUT_DMA 0x80000000
72465 +#define UPDATE_CC_WITH_TREE 0x40000000
72466 +#define UPDATE_CC_WITH_DELETE_TREE 0x20000000
72467 +#define UPDATE_KG_NIA_CC_WA 0x10000000
72468 +#define UPDATE_KG_OPT_MODE 0x08000000
72469 +#define UPDATE_KG_NIA 0x04000000
72470 +#define UPDATE_CC_SHADOW_CLEAR 0x02000000
72471 +/* @} */
72472 +
72473 +#define UPDATE_FPM_BRKC_SLP 0x80000000
72474 +#define UPDATE_FPM_EXTC 0x40000000
72475 +#define UPDATE_FPM_EXTC_CLEAR 0x20000000
72476 +#define GET_FMQM_GS 0x10000000
72477 +#define GET_FM_NPI 0x08000000
72478 +#define GET_FMFP_EXTC 0x04000000
72479 +#define CLEAR_IRAM_READY 0x02000000
72480 +#define UPDATE_FM_CLD 0x01000000
72481 +#define GET_FM_CLD 0x00800000
72482 +#define FM_MAX_NUM_OF_PORTS (FM_MAX_NUM_OF_OH_PORTS + \
72483 + FM_MAX_NUM_OF_1G_RX_PORTS + \
72484 + FM_MAX_NUM_OF_10G_RX_PORTS + \
72485 + FM_MAX_NUM_OF_1G_TX_PORTS + \
72486 + FM_MAX_NUM_OF_10G_TX_PORTS)
72487 +
72488 +#define MODULE_NAME_SIZE 30
72489 +#define DUMMY_PORT_ID 0
72490 +
72491 +#define FM_LIODN_OFFSET_MASK 0x3FF
72492 +
72493 +/**************************************************************************//**
72494 + @Description NIA Description
72495 +*//***************************************************************************/
72496 +#define NIA_ENG_MASK 0x007C0000
72497 +#define NIA_AC_MASK 0x0003ffff
72498 +
72499 +#define NIA_ORDER_RESTOR 0x00800000
72500 +#define NIA_ENG_FM_CTL 0x00000000
72501 +#define NIA_ENG_PRS 0x00440000
72502 +#define NIA_ENG_KG 0x00480000
72503 +#define NIA_ENG_PLCR 0x004C0000
72504 +#define NIA_ENG_BMI 0x00500000
72505 +#define NIA_ENG_QMI_ENQ 0x00540000
72506 +#define NIA_ENG_QMI_DEQ 0x00580000
72507 +
72508 +#define NIA_FM_CTL_AC_CC 0x00000006
72509 +#define NIA_FM_CTL_AC_HC 0x0000000C
72510 +#define NIA_FM_CTL_AC_IND_MODE_TX 0x00000008
72511 +#define NIA_FM_CTL_AC_IND_MODE_RX 0x0000000A
72512 +#define NIA_FM_CTL_AC_POP_TO_N_STEP 0x0000000e
72513 +#define NIA_FM_CTL_AC_PRE_BMI_FETCH_HEADER 0x00000010
72514 +#define NIA_FM_CTL_AC_PRE_BMI_FETCH_FULL_FRAME 0x00000018
72515 +#define NIA_FM_CTL_AC_POST_BMI_FETCH 0x00000012
72516 +#define NIA_FM_CTL_AC_PRE_BMI_ENQ_FRAME 0x0000001A
72517 +#define NIA_FM_CTL_AC_PRE_BMI_DISCARD_FRAME 0x0000001E
72518 +#define NIA_FM_CTL_AC_POST_BMI_ENQ_ORR 0x00000014
72519 +#define NIA_FM_CTL_AC_POST_BMI_ENQ 0x00000022
72520 +#define NIA_FM_CTL_AC_PRE_CC 0x00000020
72521 +#define NIA_FM_CTL_AC_POST_TX 0x00000024
72522 +/* V3 only */
72523 +#define NIA_FM_CTL_AC_NO_IPACC_PRE_BMI_ENQ_FRAME 0x00000028
72524 +#define NIA_FM_CTL_AC_NO_IPACC_PRE_BMI_DISCARD_FRAME 0x0000002A
72525 +#define NIA_FM_CTL_AC_NO_IPACC_POP_TO_N_STEP 0x0000002C
72526 +
72527 +#define NIA_BMI_AC_ENQ_FRAME 0x00000002
72528 +#define NIA_BMI_AC_TX_RELEASE 0x000002C0
72529 +#define NIA_BMI_AC_RELEASE 0x000000C0
72530 +#define NIA_BMI_AC_DISCARD 0x000000C1
72531 +#define NIA_BMI_AC_TX 0x00000274
72532 +#define NIA_BMI_AC_FETCH 0x00000208
72533 +#define NIA_BMI_AC_MASK 0x000003FF
72534 +
72535 +#define NIA_KG_DIRECT 0x00000100
72536 +#define NIA_KG_CC_EN 0x00000200
72537 +#define NIA_PLCR_ABSOLUTE 0x00008000
72538 +
72539 +#define NIA_BMI_AC_ENQ_FRAME_WITHOUT_DMA 0x00000202
72540 +
72541 +#if defined(FM_OP_NO_VSP_NO_RELEASE_ERRATA_FMAN_A006675) || defined(FM_ERROR_VSP_NO_MATCH_SW006)
72542 +#define GET_NIA_BMI_AC_ENQ_FRAME(h_FmPcd) \
72543 + (uint32_t)((FmPcdIsAdvancedOffloadSupported(h_FmPcd)) ? \
72544 + (NIA_ENG_FM_CTL | NIA_FM_CTL_AC_PRE_BMI_ENQ_FRAME) : \
72545 + (NIA_ENG_FM_CTL | NIA_FM_CTL_AC_NO_IPACC_PRE_BMI_ENQ_FRAME))
72546 +#define GET_NIA_BMI_AC_DISCARD_FRAME(h_FmPcd) \
72547 + (uint32_t)((FmPcdIsAdvancedOffloadSupported(h_FmPcd)) ? \
72548 + (NIA_ENG_FM_CTL | NIA_FM_CTL_AC_PRE_BMI_DISCARD_FRAME) : \
72549 + (NIA_ENG_FM_CTL | NIA_FM_CTL_AC_NO_IPACC_PRE_BMI_DISCARD_FRAME))
72550 +#define GET_NO_PCD_NIA_BMI_AC_ENQ_FRAME() \
72551 + (NIA_ENG_FM_CTL | NIA_FM_CTL_AC_NO_IPACC_PRE_BMI_ENQ_FRAME)
72552 +#else
72553 +#define GET_NIA_BMI_AC_ENQ_FRAME(h_FmPcd) \
72554 + (uint32_t)((FmPcdIsAdvancedOffloadSupported(h_FmPcd)) ? \
72555 + (NIA_ENG_FM_CTL | NIA_FM_CTL_AC_PRE_BMI_ENQ_FRAME) : \
72556 + (NIA_ENG_BMI | NIA_BMI_AC_ENQ_FRAME))
72557 +#define GET_NIA_BMI_AC_DISCARD_FRAME(h_FmPcd) \
72558 + (uint32_t)((FmPcdIsAdvancedOffloadSupported(h_FmPcd)) ? \
72559 + (NIA_ENG_FM_CTL | NIA_FM_CTL_AC_PRE_BMI_DISCARD_FRAME) : \
72560 + (NIA_ENG_BMI | NIA_BMI_AC_DISCARD))
72561 +#define GET_NO_PCD_NIA_BMI_AC_ENQ_FRAME() \
72562 + (NIA_ENG_BMI | NIA_BMI_AC_ENQ_FRAME)
72563 +#endif /* defined(FM_OP_NO_VSP_NO_RELEASE_ERRATA_FMAN_A006675) || ... */
72564 +
72565 +/**************************************************************************//**
72566 + @Description CTRL Parameters Page defines
72567 +*//***************************************************************************/
72568 +#define FM_CTL_PARAMS_PAGE_OP_FIX_EN 0x80000000
72569 +#define FM_CTL_PARAMS_PAGE_OFFLOAD_SUPPORT_EN 0x40000000
72570 +#define FM_CTL_PARAMS_PAGE_ALWAYS_ON 0x00000100
72571 +
72572 +#define FM_CTL_PARAMS_PAGE_ERROR_VSP_MASK 0x0000003f
72573 +
72574 +/**************************************************************************//**
72575 + @Description Port Id defines
72576 +*//***************************************************************************/
72577 +#if (DPAA_VERSION == 10)
72578 +#define BASE_OH_PORTID 1
72579 +#else
72580 +#define BASE_OH_PORTID 2
72581 +#endif /* (DPAA_VERSION == 10) */
72582 +#define BASE_1G_RX_PORTID 8
72583 +#define BASE_10G_RX_PORTID 0x10
72584 +#define BASE_1G_TX_PORTID 0x28
72585 +#define BASE_10G_TX_PORTID 0x30
72586 +
72587 +#define FM_PCD_PORT_OH_BASE_INDX 0
72588 +#define FM_PCD_PORT_1G_RX_BASE_INDX (FM_PCD_PORT_OH_BASE_INDX+FM_MAX_NUM_OF_OH_PORTS)
72589 +#define FM_PCD_PORT_10G_RX_BASE_INDX (FM_PCD_PORT_1G_RX_BASE_INDX+FM_MAX_NUM_OF_1G_RX_PORTS)
72590 +#define FM_PCD_PORT_1G_TX_BASE_INDX (FM_PCD_PORT_10G_RX_BASE_INDX+FM_MAX_NUM_OF_10G_RX_PORTS)
72591 +#define FM_PCD_PORT_10G_TX_BASE_INDX (FM_PCD_PORT_1G_TX_BASE_INDX+FM_MAX_NUM_OF_1G_TX_PORTS)
72592 +
72593 +#if (FM_MAX_NUM_OF_OH_PORTS > 0)
72594 +#define CHECK_PORT_ID_OH_PORTS(_relativePortId) \
72595 + if ((_relativePortId) >= FM_MAX_NUM_OF_OH_PORTS) \
72596 + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("Illegal OH_PORT port id"))
72597 +#else
72598 +#define CHECK_PORT_ID_OH_PORTS(_relativePortId) \
72599 + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("Illegal OH_PORT port id"))
72600 +#endif
72601 +#if (FM_MAX_NUM_OF_1G_RX_PORTS > 0)
72602 +#define CHECK_PORT_ID_1G_RX_PORTS(_relativePortId) \
72603 + if ((_relativePortId) >= FM_MAX_NUM_OF_1G_RX_PORTS) \
72604 + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("Illegal 1G_RX_PORT port id"))
72605 +#else
72606 +#define CHECK_PORT_ID_1G_RX_PORTS(_relativePortId) \
72607 + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("Illegal 1G_RX_PORT port id"))
72608 +#endif
72609 +#if (FM_MAX_NUM_OF_10G_RX_PORTS > 0)
72610 +#define CHECK_PORT_ID_10G_RX_PORTS(_relativePortId) \
72611 + if ((_relativePortId) >= FM_MAX_NUM_OF_10G_RX_PORTS) \
72612 + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("Illegal 10G_RX_PORT port id"))
72613 +#else
72614 +#define CHECK_PORT_ID_10G_RX_PORTS(_relativePortId) \
72615 + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("Illegal 10G_RX_PORT port id"))
72616 +#endif
72617 +#if (FM_MAX_NUM_OF_1G_TX_PORTS > 0)
72618 +#define CHECK_PORT_ID_1G_TX_PORTS(_relativePortId) \
72619 + if ((_relativePortId) >= FM_MAX_NUM_OF_1G_TX_PORTS) \
72620 + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("Illegal 1G_TX_PORT port id"))
72621 +#else
72622 +#define CHECK_PORT_ID_1G_TX_PORTS(_relativePortId) \
72623 + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("Illegal 1G_TX_PORT port id"))
72624 +#endif
72625 +#if (FM_MAX_NUM_OF_10G_TX_PORTS > 0)
72626 +#define CHECK_PORT_ID_10G_TX_PORTS(_relativePortId) \
72627 + if ((_relativePortId) >= FM_MAX_NUM_OF_10G_TX_PORTS) \
72628 + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("Illegal 10G_TX_PORT port id"))
72629 +#else
72630 +#define CHECK_PORT_ID_10G_TX_PORTS(_relativePortId) \
72631 + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("Illegal 10G_TX_PORT port id"))
72632 +#endif
72633 +
72634 +uint8_t SwPortIdToHwPortId(e_FmPortType type, uint8_t relativePortId, uint8_t majorRev, uint8_t minorRev);
72635 +
72636 +#define HW_PORT_ID_TO_SW_PORT_ID(_relativePortId, hardwarePortId) \
72637 +{ if (((hardwarePortId) >= BASE_OH_PORTID) && \
72638 + ((hardwarePortId) < BASE_OH_PORTID+FM_MAX_NUM_OF_OH_PORTS)) \
72639 + _relativePortId = (uint8_t)((hardwarePortId)-BASE_OH_PORTID); \
72640 + else if (((hardwarePortId) >= BASE_10G_TX_PORTID) && \
72641 + ((hardwarePortId) < BASE_10G_TX_PORTID+FM_MAX_NUM_OF_10G_TX_PORTS)) \
72642 + _relativePortId = (uint8_t)((hardwarePortId)-BASE_10G_TX_PORTID); \
72643 + else if (((hardwarePortId) >= BASE_1G_TX_PORTID) && \
72644 + ((hardwarePortId) < BASE_1G_TX_PORTID+FM_MAX_NUM_OF_1G_TX_PORTS)) \
72645 + _relativePortId = (uint8_t)((hardwarePortId)-BASE_1G_TX_PORTID); \
72646 + else if (((hardwarePortId) >= BASE_10G_RX_PORTID) && \
72647 + ((hardwarePortId) < BASE_10G_RX_PORTID+FM_MAX_NUM_OF_10G_RX_PORTS)) \
72648 + _relativePortId = (uint8_t)((hardwarePortId)-BASE_10G_RX_PORTID); \
72649 + else if (((hardwarePortId) >= BASE_1G_RX_PORTID) && \
72650 + ((hardwarePortId) < BASE_1G_RX_PORTID+FM_MAX_NUM_OF_1G_RX_PORTS)) \
72651 + _relativePortId = (uint8_t)((hardwarePortId)-BASE_1G_RX_PORTID); \
72652 + else { \
72653 + _relativePortId = (uint8_t)DUMMY_PORT_ID; \
72654 + ASSERT_COND(TRUE); \
72655 + } \
72656 +}
72657 +
72658 +#define HW_PORT_ID_TO_SW_PORT_INDX(swPortIndex, hardwarePortId) \
72659 +do { \
72660 + if (((hardwarePortId) >= BASE_OH_PORTID) && ((hardwarePortId) < BASE_OH_PORTID+FM_MAX_NUM_OF_OH_PORTS)) \
72661 + swPortIndex = (uint8_t)((hardwarePortId)-BASE_OH_PORTID+FM_PCD_PORT_OH_BASE_INDX); \
72662 + else if (((hardwarePortId) >= BASE_1G_RX_PORTID) && \
72663 + ((hardwarePortId) < BASE_1G_RX_PORTID+FM_MAX_NUM_OF_1G_RX_PORTS)) \
72664 + swPortIndex = (uint8_t)((hardwarePortId)-BASE_1G_RX_PORTID+FM_PCD_PORT_1G_RX_BASE_INDX); \
72665 + else if (((hardwarePortId) >= BASE_10G_RX_PORTID) && \
72666 + ((hardwarePortId) < BASE_10G_RX_PORTID+FM_MAX_NUM_OF_10G_RX_PORTS)) \
72667 + swPortIndex = (uint8_t)((hardwarePortId)-BASE_10G_RX_PORTID+FM_PCD_PORT_10G_RX_BASE_INDX); \
72668 + else if (((hardwarePortId) >= BASE_1G_TX_PORTID) && \
72669 + ((hardwarePortId) < BASE_1G_TX_PORTID+FM_MAX_NUM_OF_1G_TX_PORTS)) \
72670 + swPortIndex = (uint8_t)((hardwarePortId)-BASE_1G_TX_PORTID+FM_PCD_PORT_1G_TX_BASE_INDX); \
72671 + else if (((hardwarePortId) >= BASE_10G_TX_PORTID) && \
72672 + ((hardwarePortId) < BASE_10G_TX_PORTID+FM_MAX_NUM_OF_10G_TX_PORTS)) \
72673 + swPortIndex = (uint8_t)((hardwarePortId)-BASE_10G_TX_PORTID+FM_PCD_PORT_10G_TX_BASE_INDX); \
72674 + else ASSERT_COND(FALSE); \
72675 +} while (0)
72676 +
72677 +#define SW_PORT_INDX_TO_HW_PORT_ID(hardwarePortId, swPortIndex) \
72678 +do { \
72679 + if (((swPortIndex) >= FM_PCD_PORT_OH_BASE_INDX) && ((swPortIndex) < FM_PCD_PORT_1G_RX_BASE_INDX)) \
72680 + hardwarePortId = (uint8_t)((swPortIndex)-FM_PCD_PORT_OH_BASE_INDX+BASE_OH_PORTID); \
72681 + else if (((swPortIndex) >= FM_PCD_PORT_1G_RX_BASE_INDX) && ((swPortIndex) < FM_PCD_PORT_10G_RX_BASE_INDX)) \
72682 + hardwarePortId = (uint8_t)((swPortIndex)-FM_PCD_PORT_1G_RX_BASE_INDX+BASE_1G_RX_PORTID); \
72683 + else if (((swPortIndex) >= FM_PCD_PORT_10G_RX_BASE_INDX) && ((swPortIndex) < FM_MAX_NUM_OF_PORTS)) \
72684 + hardwarePortId = (uint8_t)((swPortIndex)-FM_PCD_PORT_10G_RX_BASE_INDX+BASE_10G_RX_PORTID); \
72685 + else if (((swPortIndex) >= FM_PCD_PORT_1G_TX_BASE_INDX) && ((swPortIndex) < FM_PCD_PORT_10G_TX_BASE_INDX)) \
72686 + hardwarePortId = (uint8_t)((swPortIndex)-FM_PCD_PORT_1G_TX_BASE_INDX+BASE_1G_TX_PORTID); \
72687 + else if (((swPortIndex) >= FM_PCD_PORT_10G_TX_BASE_INDX) && ((swPortIndex) < FM_MAX_NUM_OF_PORTS)) \
72688 + hardwarePortId = (uint8_t)((swPortIndex)-FM_PCD_PORT_10G_TX_BASE_INDX+BASE_10G_TX_PORTID); \
72689 + else ASSERT_COND(FALSE); \
72690 +} while (0)
72691 +
72692 +#define BMI_MAX_FIFO_SIZE (FM_MURAM_SIZE)
72693 +#define BMI_FIFO_UNITS 0x100
72694 +
72695 +typedef struct {
72696 + void (*f_Isr) (t_Handle h_Arg);
72697 + t_Handle h_SrcHandle;
72698 + uint8_t guestId;
72699 +} t_FmIntrSrc;
72700 +
72701 +#define ILLEGAL_HDR_NUM 0xFF
72702 +#define NO_HDR_NUM FM_PCD_PRS_NUM_OF_HDRS
72703 +
72704 +#define IS_PRIVATE_HEADER(hdr) (((hdr) == HEADER_TYPE_USER_DEFINED_SHIM1) || \
72705 + ((hdr) == HEADER_TYPE_USER_DEFINED_SHIM2))
72706 +#define IS_SPECIAL_HEADER(hdr) ((hdr) == HEADER_TYPE_MACSEC)
72707 +
72708 +static __inline__ uint8_t GetPrsHdrNum(e_NetHeaderType hdr)
72709 +{
72710 + switch (hdr)
72711 + { case (HEADER_TYPE_ETH): return 0;
72712 + case (HEADER_TYPE_LLC_SNAP): return 1;
72713 + case (HEADER_TYPE_VLAN): return 2;
72714 + case (HEADER_TYPE_PPPoE): return 3;
72715 + case (HEADER_TYPE_PPP): return 3;
72716 + case (HEADER_TYPE_MPLS): return 4;
72717 + case (HEADER_TYPE_IPv4): return 5;
72718 + case (HEADER_TYPE_IPv6): return 6;
72719 + case (HEADER_TYPE_GRE): return 7;
72720 + case (HEADER_TYPE_MINENCAP): return 8;
72721 + case (HEADER_TYPE_USER_DEFINED_L3): return 9;
72722 + case (HEADER_TYPE_TCP): return 10;
72723 + case (HEADER_TYPE_UDP): return 11;
72724 + case (HEADER_TYPE_IPSEC_AH):
72725 + case (HEADER_TYPE_IPSEC_ESP): return 12;
72726 + case (HEADER_TYPE_SCTP): return 13;
72727 + case (HEADER_TYPE_DCCP): return 14;
72728 + case (HEADER_TYPE_USER_DEFINED_L4): return 15;
72729 + case (HEADER_TYPE_USER_DEFINED_SHIM1):
72730 + case (HEADER_TYPE_USER_DEFINED_SHIM2):
72731 + case (HEADER_TYPE_MACSEC): return NO_HDR_NUM;
72732 + default:
72733 + return ILLEGAL_HDR_NUM;
72734 + }
72735 +}
72736 +
72737 +#define FM_PCD_MAX_NUM_OF_OPTIONS(clsPlanEntries) ((clsPlanEntries==256)? 8:((clsPlanEntries==128)? 7: ((clsPlanEntries==64)? 6: ((clsPlanEntries==32)? 5:0))))
72738 +
72739 +
72740 +/**************************************************************************//**
72741 + @Description A structure for initializing a keygen classification plan group
72742 +*//***************************************************************************/
72743 +typedef struct t_FmPcdKgInterModuleClsPlanGrpParams {
72744 + uint8_t netEnvId; /* IN */
72745 + bool grpExists; /* OUT (unused in FmPcdKgBuildClsPlanGrp)*/
72746 + uint8_t clsPlanGrpId; /* OUT */
72747 + bool emptyClsPlanGrp; /* OUT */
72748 + uint8_t numOfOptions; /* OUT in FmPcdGetSetClsPlanGrpParams IN in FmPcdKgBuildClsPlanGrp*/
72749 + protocolOpt_t options[FM_PCD_MAX_NUM_OF_OPTIONS(FM_PCD_MAX_NUM_OF_CLS_PLANS)];
72750 + /* OUT in FmPcdGetSetClsPlanGrpParams IN in FmPcdKgBuildClsPlanGrp*/
72751 + uint32_t optVectors[FM_PCD_MAX_NUM_OF_OPTIONS(FM_PCD_MAX_NUM_OF_CLS_PLANS)];
72752 + /* OUT in FmPcdGetSetClsPlanGrpParams IN in FmPcdKgBuildClsPlanGrp*/
72753 +} t_FmPcdKgInterModuleClsPlanGrpParams;
72754 +
72755 +typedef struct t_FmPcdLock {
72756 + t_Handle h_Spinlock;
72757 + volatile bool flag;
72758 + t_List node;
72759 +} t_FmPcdLock;
72760 +#define FM_PCD_LOCK_OBJ(ptr) LIST_OBJECT(ptr, t_FmPcdLock, node)
72761 +
72762 +
72763 +typedef t_Error (t_FmPortGetSetCcParamsCallback) (t_Handle h_FmPort,
72764 + t_FmPortGetSetCcParams *p_FmPortGetSetCcParams);
72765 +
72766 +
72767 +/***********************************************************************/
72768 +/* Common API for FM-PCD module */
72769 +/***********************************************************************/
72770 +t_Handle FmPcdGetHcHandle(t_Handle h_FmPcd);
72771 +uint32_t FmPcdGetSwPrsOffset(t_Handle h_FmPcd, e_NetHeaderType hdr, uint8_t indexPerHdr);
72772 +uint32_t FmPcdGetLcv(t_Handle h_FmPcd, uint32_t netEnvId, uint8_t hdrNum);
72773 +uint32_t FmPcdGetMacsecLcv(t_Handle h_FmPcd, uint32_t netEnvId);
72774 +void FmPcdIncNetEnvOwners(t_Handle h_FmPcd, uint8_t netEnvId);
72775 +void FmPcdDecNetEnvOwners(t_Handle h_FmPcd, uint8_t netEnvId);
72776 +uint8_t FmPcdGetNetEnvId(t_Handle h_NetEnv);
72777 +void FmPcdPortRegister(t_Handle h_FmPcd, t_Handle h_FmPort, uint8_t hardwarePortId);
72778 +uint32_t FmPcdLock(t_Handle h_FmPcd);
72779 +void FmPcdUnlock(t_Handle h_FmPcd, uint32_t intFlags);
72780 +bool FmPcdNetEnvIsHdrExist(t_Handle h_FmPcd, uint8_t netEnvId, e_NetHeaderType hdr);
72781 +t_Error FmPcdFragHcScratchPoolInit(t_Handle h_FmPcd, uint8_t scratchBpid);
72782 +t_Error FmPcdRegisterReassmPort(t_Handle h_FmPcd, t_Handle h_IpReasmCommonPramTbl);
72783 +t_Error FmPcdUnregisterReassmPort(t_Handle h_FmPcd, t_Handle h_IpReasmCommonPramTbl);
72784 +bool FmPcdIsAdvancedOffloadSupported(t_Handle h_FmPcd);
72785 +bool FmPcdLockTryLockAll(t_Handle h_FmPcd);
72786 +void FmPcdLockUnlockAll(t_Handle h_FmPcd);
72787 +t_Error FmPcdHcSync(t_Handle h_FmPcd);
72788 +t_Handle FmGetPcd(t_Handle h_Fm);
72789 +/***********************************************************************/
72790 +/* Common API for FM-PCD KG module */
72791 +/***********************************************************************/
72792 +uint8_t FmPcdKgGetClsPlanGrpBase(t_Handle h_FmPcd, uint8_t clsPlanGrp);
72793 +uint16_t FmPcdKgGetClsPlanGrpSize(t_Handle h_FmPcd, uint8_t clsPlanGrp);
72794 +t_Error FmPcdKgBuildClsPlanGrp(t_Handle h_FmPcd, t_FmPcdKgInterModuleClsPlanGrpParams *p_Grp, t_FmPcdKgInterModuleClsPlanSet *p_ClsPlanSet);
72795 +
72796 +uint8_t FmPcdKgGetSchemeId(t_Handle h_Scheme);
72797 +#if (DPAA_VERSION >= 11)
72798 +bool FmPcdKgGetVspe(t_Handle h_Scheme);
72799 +#endif /* (DPAA_VERSION >= 11) */
72800 +uint8_t FmPcdKgGetRelativeSchemeId(t_Handle h_FmPcd, uint8_t schemeId);
72801 +void FmPcdKgDestroyClsPlanGrp(t_Handle h_FmPcd, uint8_t grpId);
72802 +t_Error FmPcdKgCheckInvalidateSchemeSw(t_Handle h_Scheme);
72803 +t_Error FmPcdKgBuildBindPortToSchemes(t_Handle h_FmPcd , t_FmPcdKgInterModuleBindPortToSchemes *p_BindPortToSchemes, uint32_t *p_SpReg, bool add);
72804 +bool FmPcdKgHwSchemeIsValid(uint32_t schemeModeReg);
72805 +uint32_t FmPcdKgBuildWriteSchemeActionReg(uint8_t schemeId, bool updateCounter);
72806 +uint32_t FmPcdKgBuildReadSchemeActionReg(uint8_t schemeId);
72807 +uint32_t FmPcdKgBuildWriteClsPlanBlockActionReg(uint8_t grpId);
72808 +uint32_t FmPcdKgBuildWritePortSchemeBindActionReg(uint8_t hardwarePortId);
72809 +uint32_t FmPcdKgBuildReadPortSchemeBindActionReg(uint8_t hardwarePortId);
72810 +uint32_t FmPcdKgBuildWritePortClsPlanBindActionReg(uint8_t hardwarePortId);
72811 +bool FmPcdKgIsSchemeValidSw(t_Handle h_Scheme);
72812 +
72813 +t_Error FmPcdKgBindPortToSchemes(t_Handle h_FmPcd , t_FmPcdKgInterModuleBindPortToSchemes *p_SchemeBind);
72814 +t_Error FmPcdKgUnbindPortToSchemes(t_Handle h_FmPcd , t_FmPcdKgInterModuleBindPortToSchemes *p_SchemeBind);
72815 +uint32_t FmPcdKgGetRequiredAction(t_Handle h_FmPcd, uint8_t schemeId);
72816 +uint32_t FmPcdKgGetRequiredActionFlag(t_Handle h_FmPcd, uint8_t schemeId);
72817 +e_FmPcdDoneAction FmPcdKgGetDoneAction(t_Handle h_FmPcd, uint8_t schemeId);
72818 +e_FmPcdEngine FmPcdKgGetNextEngine(t_Handle h_FmPcd, uint8_t schemeId);
72819 +void FmPcdKgUpdateRequiredAction(t_Handle h_Scheme, uint32_t requiredAction);
72820 +bool FmPcdKgIsDirectPlcr(t_Handle h_FmPcd, uint8_t schemeId);
72821 +bool FmPcdKgIsDistrOnPlcrProfile(t_Handle h_FmPcd, uint8_t schemeId);
72822 +uint16_t FmPcdKgGetRelativeProfileId(t_Handle h_FmPcd, uint8_t schemeId);
72823 +t_Handle FmPcdKgGetSchemeHandle(t_Handle h_FmPcd, uint8_t relativeSchemeId);
72824 +bool FmPcdKgIsSchemeHasOwners(t_Handle h_Scheme);
72825 +t_Error FmPcdKgCcGetSetParams(t_Handle h_FmPcd, t_Handle h_Scheme, uint32_t requiredAction, uint32_t value);
72826 +t_Error FmPcdKgSetOrBindToClsPlanGrp(t_Handle h_FmPcd, uint8_t hardwarePortId, uint8_t netEnvId, protocolOpt_t *p_OptArray, uint8_t *p_ClsPlanGrpId, bool *p_IsEmptyClsPlanGrp);
72827 +t_Error FmPcdKgDeleteOrUnbindPortToClsPlanGrp(t_Handle h_FmPcd, uint8_t hardwarePortId, uint8_t clsPlanGrpId);
72828 +
72829 +/***********************************************************************/
72830 +/* Common API for FM-PCD parser module */
72831 +/***********************************************************************/
72832 +t_Error FmPcdPrsIncludePortInStatistics(t_Handle p_FmPcd, uint8_t hardwarePortId, bool include);
72833 +
72834 +/***********************************************************************/
72835 +/* Common API for FM-PCD policer module */
72836 +/***********************************************************************/
72837 +t_Error FmPcdPlcrAllocProfiles(t_Handle h_FmPcd, uint8_t hardwarePortId, uint16_t numOfProfiles);
72838 +t_Error FmPcdPlcrFreeProfiles(t_Handle h_FmPcd, uint8_t hardwarePortId);
72839 +bool FmPcdPlcrIsProfileValid(t_Handle h_FmPcd, uint16_t absoluteProfileId);
72840 +uint16_t FmPcdPlcrGetPortProfilesBase(t_Handle h_FmPcd, uint8_t hardwarePortId);
72841 +uint16_t FmPcdPlcrGetPortNumOfProfiles(t_Handle h_FmPcd, uint8_t hardwarePortId);
72842 +uint32_t FmPcdPlcrBuildWritePlcrActionRegs(uint16_t absoluteProfileId);
72843 +uint32_t FmPcdPlcrBuildCounterProfileReg(e_FmPcdPlcrProfileCounters counter);
72844 +uint32_t FmPcdPlcrBuildWritePlcrActionReg(uint16_t absoluteProfileId);
72845 +uint32_t FmPcdPlcrBuildReadPlcrActionReg(uint16_t absoluteProfileId);
72846 +uint16_t FmPcdPlcrProfileGetAbsoluteId(t_Handle h_Profile);
72847 +t_Error FmPcdPlcrGetAbsoluteIdByProfileParams(t_Handle h_FmPcd,
72848 + e_FmPcdProfileTypeSelection profileType,
72849 + t_Handle h_FmPort,
72850 + uint16_t relativeProfile,
72851 + uint16_t *p_AbsoluteId);
72852 +void FmPcdPlcrInvalidateProfileSw(t_Handle h_FmPcd, uint16_t absoluteProfileId);
72853 +void FmPcdPlcrValidateProfileSw(t_Handle h_FmPcd, uint16_t absoluteProfileId);
72854 +bool FmPcdPlcrHwProfileIsValid(uint32_t profileModeReg);
72855 +uint32_t FmPcdPlcrGetRequiredAction(t_Handle h_FmPcd, uint16_t absoluteProfileId);
72856 +uint32_t FmPcdPlcrGetRequiredActionFlag(t_Handle h_FmPcd, uint16_t absoluteProfileId);
72857 +uint32_t FmPcdPlcrBuildNiaProfileReg(bool green, bool yellow, bool red);
72858 +void FmPcdPlcrUpdateRequiredAction(t_Handle h_FmPcd, uint16_t absoluteProfileId, uint32_t requiredAction);
72859 +t_Error FmPcdPlcrCcGetSetParams(t_Handle h_FmPcd, uint16_t profileIndx,uint32_t requiredAction);
72860 +
72861 +/***********************************************************************/
72862 +/* Common API for FM-PCD CC module */
72863 +/***********************************************************************/
72864 +uint8_t FmPcdCcGetParseCode(t_Handle h_CcNode);
72865 +uint8_t FmPcdCcGetOffset(t_Handle h_CcNode);
72866 +t_Error FmPcdCcRemoveKey(t_Handle h_FmPcd, t_Handle h_FmPcdCcNode, uint16_t keyIndex);
72867 +t_Error FmPcdCcAddKey(t_Handle h_FmPcd, t_Handle h_CcNode, uint16_t keyIndex, uint8_t keySize, t_FmPcdCcKeyParams *p_FmPCdCcKeyParams);
72868 +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);
72869 +t_Error FmPcdCcModifyKeyAndNextEngine(t_Handle h_FmPcd, t_Handle h_FmPcdCcNode, uint16_t keyIndex, uint8_t keySize, t_FmPcdCcKeyParams *p_FmPcdCcKeyParams);
72870 +t_Error FmPcdCcModifyMissNextEngineParamNode(t_Handle h_FmPcd,t_Handle h_FmPcdCcNode, t_FmPcdCcNextEngineParams *p_FmPcdCcNextEngineParams);
72871 +t_Error FmPcdCcModifyNextEngineParamTree(t_Handle h_FmPcd, t_Handle h_FmPcdCcTree, uint8_t grpId, uint8_t index, t_FmPcdCcNextEngineParams *p_FmPcdCcNextEngineParams);
72872 +uint32_t FmPcdCcGetNodeAddrOffsetFromNodeInfo(t_Handle h_FmPcd, t_Handle h_Pointer);
72873 +t_Handle FmPcdCcTreeGetSavedManipParams(t_Handle h_FmTree);
72874 +void FmPcdCcTreeSetSavedManipParams(t_Handle h_FmTree, t_Handle h_SavedManipParams);
72875 +t_Error FmPcdCcTreeAddIPR(t_Handle h_FmPcd, t_Handle h_FmTree, t_Handle h_NetEnv, t_Handle h_ReassemblyManip, bool schemes);
72876 +t_Error FmPcdCcTreeAddCPR(t_Handle h_FmPcd, t_Handle h_FmTree, t_Handle h_NetEnv, t_Handle h_ReassemblyManip, bool schemes);
72877 +t_Error FmPcdCcBindTree(t_Handle h_FmPcd, t_Handle h_PcdParams, t_Handle h_CcTree, uint32_t *p_Offset,t_Handle h_FmPort);
72878 +t_Error FmPcdCcUnbindTree(t_Handle h_FmPcd, t_Handle h_CcTree);
72879 +
72880 +/***********************************************************************/
72881 +/* Common API for FM-PCD Manip module */
72882 +/***********************************************************************/
72883 +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);
72884 +
72885 +/***********************************************************************/
72886 +/* Common API for FM-Port module */
72887 +/***********************************************************************/
72888 +#if (DPAA_VERSION >= 11)
72889 +typedef enum e_FmPortGprFuncType
72890 +{
72891 + e_FM_PORT_GPR_EMPTY = 0,
72892 + e_FM_PORT_GPR_MURAM_PAGE
72893 +} e_FmPortGprFuncType;
72894 +
72895 +t_Error FmPortSetGprFunc(t_Handle h_FmPort, e_FmPortGprFuncType gprFunc, void **p_Value);
72896 +#endif /* DPAA_VERSION >= 11) */
72897 +t_Error FmGetSetParams(t_Handle h_Fm, t_FmGetSetParams *p_FmGetSetParams);
72898 +t_Error FmPortGetSetCcParams(t_Handle h_FmPort, t_FmPortGetSetCcParams *p_FmPortGetSetCcParams);
72899 +uint8_t FmPortGetNetEnvId(t_Handle h_FmPort);
72900 +uint8_t FmPortGetHardwarePortId(t_Handle h_FmPort);
72901 +uint32_t FmPortGetPcdEngines(t_Handle h_FmPort);
72902 +void FmPortPcdKgSwUnbindClsPlanGrp (t_Handle h_FmPort);
72903 +
72904 +
72905 +#if (DPAA_VERSION >= 11)
72906 +t_Error FmPcdFrmReplicUpdate(t_Handle h_FmPcd, t_Handle h_FmPort, t_Handle h_FrmReplic);
72907 +#endif /* (DPAA_VERSION >= 11) */
72908 +
72909 +/**************************************************************************//**
72910 + @Function FmRegisterIntr
72911 +
72912 + @Description Used to register an inter-module event handler to be processed by FM
72913 +
72914 + @Param[in] h_Fm A handle to an FM Module.
72915 + @Param[in] mod The module that causes the event
72916 + @Param[in] modId Module id - if more than 1 instansiation of this
72917 + mode exists,0 otherwise.
72918 + @Param[in] intrType Interrupt type (error/normal) selection.
72919 + @Param[in] f_Isr The interrupt service routine.
72920 + @Param[in] h_Arg Argument to be passed to f_Isr.
72921 +
72922 + @Return None.
72923 +*//***************************************************************************/
72924 +void FmRegisterIntr(t_Handle h_Fm,
72925 + e_FmEventModules mod,
72926 + uint8_t modId,
72927 + e_FmIntrType intrType,
72928 + void (*f_Isr) (t_Handle h_Arg),
72929 + t_Handle h_Arg);
72930 +
72931 +/**************************************************************************//**
72932 + @Function FmUnregisterIntr
72933 +
72934 + @Description Used to un-register an inter-module event handler that was processed by FM
72935 +
72936 + @Param[in] h_Fm A handle to an FM Module.
72937 + @Param[in] mod The module that causes the event
72938 + @Param[in] modId Module id - if more than 1 instansiation of this
72939 + mode exists,0 otherwise.
72940 + @Param[in] intrType Interrupt type (error/normal) selection.
72941 +
72942 + @Return None.
72943 +*//***************************************************************************/
72944 +void FmUnregisterIntr(t_Handle h_Fm,
72945 + e_FmEventModules mod,
72946 + uint8_t modId,
72947 + e_FmIntrType intrType);
72948 +
72949 +/**************************************************************************//**
72950 + @Function FmRegisterFmCtlIntr
72951 +
72952 + @Description Used to register to one of the fmCtl events in the FM module
72953 +
72954 + @Param[in] h_Fm A handle to an FM Module.
72955 + @Param[in] eventRegId FmCtl event id (0-7).
72956 + @Param[in] f_Isr The interrupt service routine.
72957 +
72958 + @Return E_OK on success; Error code otherwise.
72959 +
72960 + @Cautions Allowed only following FM_Init().
72961 +*//***************************************************************************/
72962 +void FmRegisterFmCtlIntr(t_Handle h_Fm, uint8_t eventRegId, void (*f_Isr) (t_Handle h_Fm, uint32_t event));
72963 +
72964 +
72965 +/**************************************************************************//**
72966 + @Description enum for defining MAC types
72967 +*//***************************************************************************/
72968 +typedef enum e_FmMacType {
72969 + e_FM_MAC_10G = 0, /**< 10G MAC */
72970 + e_FM_MAC_1G /**< 1G MAC */
72971 +} e_FmMacType;
72972 +
72973 +/**************************************************************************//**
72974 + @Description Structure for port-FM communication during FM_PORT_Init.
72975 + Fields commented 'IN' are passed by the port module to be used
72976 + by the FM module.
72977 + Fields commented 'OUT' will be filled by FM before returning to port.
72978 + Some fields are optional (depending on configuration) and
72979 + will be analized by the port and FM modules accordingly.
72980 +*//***************************************************************************/
72981 +typedef struct t_FmInterModulePortInitParams {
72982 + uint8_t hardwarePortId; /**< IN. port Id */
72983 + e_FmPortType portType; /**< IN. Port type */
72984 + bool independentMode; /**< IN. TRUE if FM Port operates in independent mode */
72985 + uint16_t liodnOffset; /**< IN. Port's requested resource */
72986 + uint8_t numOfTasks; /**< IN. Port's requested resource */
72987 + uint8_t numOfExtraTasks; /**< IN. Port's requested resource */
72988 + uint8_t numOfOpenDmas; /**< IN. Port's requested resource */
72989 + uint8_t numOfExtraOpenDmas; /**< IN. Port's requested resource */
72990 + uint32_t sizeOfFifo; /**< IN. Port's requested resource */
72991 + uint32_t extraSizeOfFifo; /**< IN. Port's requested resource */
72992 + uint8_t deqPipelineDepth; /**< IN. Port's requested resource */
72993 + uint16_t maxFrameLength; /**< IN. Port's max frame length. */
72994 + uint16_t liodnBase; /**< IN. Irrelevant for P4080 rev 1.
72995 + LIODN base for this port, to be
72996 + used together with LIODN offset. */
72997 + t_FmPhysAddr fmMuramPhysBaseAddr;/**< OUT. FM-MURAM physical address*/
72998 +} t_FmInterModulePortInitParams;
72999 +
73000 +/**************************************************************************//**
73001 + @Description Structure for port-FM communication during FM_PORT_Free.
73002 +*//***************************************************************************/
73003 +typedef struct t_FmInterModulePortFreeParams {
73004 + uint8_t hardwarePortId; /**< IN. port Id */
73005 + e_FmPortType portType; /**< IN. Port type */
73006 + uint8_t deqPipelineDepth; /**< IN. Port's requested resource */
73007 +} t_FmInterModulePortFreeParams;
73008 +
73009 +/**************************************************************************//**
73010 + @Function FmGetPcdPrsBaseAddr
73011 +
73012 + @Description Get the base address of the Parser from the FM module
73013 +
73014 + @Param[in] h_Fm A handle to an FM Module.
73015 +
73016 + @Return Base address.
73017 +*//***************************************************************************/
73018 +uintptr_t FmGetPcdPrsBaseAddr(t_Handle h_Fm);
73019 +
73020 +/**************************************************************************//**
73021 + @Function FmGetPcdKgBaseAddr
73022 +
73023 + @Description Get the base address of the Keygen from the FM module
73024 +
73025 + @Param[in] h_Fm A handle to an FM Module.
73026 +
73027 + @Return Base address.
73028 +*//***************************************************************************/
73029 +uintptr_t FmGetPcdKgBaseAddr(t_Handle h_Fm);
73030 +
73031 +/**************************************************************************//**
73032 + @Function FmGetPcdPlcrBaseAddr
73033 +
73034 + @Description Get the base address of the Policer from the FM module
73035 +
73036 + @Param[in] h_Fm A handle to an FM Module.
73037 +
73038 + @Return Base address.
73039 +*//***************************************************************************/
73040 +uintptr_t FmGetPcdPlcrBaseAddr(t_Handle h_Fm);
73041 +
73042 +/**************************************************************************//**
73043 + @Function FmGetMuramHandle
73044 +
73045 + @Description Get the handle of the MURAM from the FM module
73046 +
73047 + @Param[in] h_Fm A handle to an FM Module.
73048 +
73049 + @Return MURAM module handle.
73050 +*//***************************************************************************/
73051 +t_Handle FmGetMuramHandle(t_Handle h_Fm);
73052 +
73053 +/**************************************************************************//**
73054 + @Function FmGetPhysicalMuramBase
73055 +
73056 + @Description Get the physical base address of the MURAM from the FM module
73057 +
73058 + @Param[in] h_Fm A handle to an FM Module.
73059 + @Param[in] fmPhysAddr Physical MURAM base
73060 +
73061 + @Return Physical base address.
73062 +*//***************************************************************************/
73063 +void FmGetPhysicalMuramBase(t_Handle h_Fm, t_FmPhysAddr *fmPhysAddr);
73064 +
73065 +/**************************************************************************//**
73066 + @Function FmGetTimeStampScale
73067 +
73068 + @Description Used internally by other modules in order to get the timeStamp
73069 + period as requested by the application.
73070 +
73071 + This function returns bit number that is incremented every 1 usec.
73072 + To calculate timestamp period in nsec, use
73073 + 1000 / (1 << FmGetTimeStampScale()).
73074 +
73075 + @Param[in] h_Fm A handle to an FM Module.
73076 +
73077 + @Return Bit that counts 1 usec.
73078 +
73079 + @Cautions Allowed only following FM_Init().
73080 +*//***************************************************************************/
73081 +uint32_t FmGetTimeStampScale(t_Handle h_Fm);
73082 +
73083 +/**************************************************************************//**
73084 + @Function FmResumeStalledPort
73085 +
73086 + @Description Used internally by FM port to release a stalled port.
73087 +
73088 + @Param[in] h_Fm A handle to an FM Module.
73089 + @Param[in] hardwarePortId HW port id.
73090 +
73091 + @Return E_OK on success; Error code otherwise.
73092 +
73093 + @Cautions Allowed only following FM_Init().
73094 +*//***************************************************************************/
73095 +t_Error FmResumeStalledPort(t_Handle h_Fm, uint8_t hardwarePortId);
73096 +
73097 +/**************************************************************************//**
73098 + @Function FmIsPortStalled
73099 +
73100 + @Description Used internally by FM port to read the port's status.
73101 +
73102 + @Param[in] h_Fm A handle to an FM Module.
73103 + @Param[in] hardwarePortId HW port id.
73104 + @Param[in] p_IsStalled A pointer to the boolean port stalled state
73105 +
73106 + @Return E_OK on success; Error code otherwise.
73107 +
73108 + @Cautions Allowed only following FM_Init().
73109 +*//***************************************************************************/
73110 +t_Error FmIsPortStalled(t_Handle h_Fm, uint8_t hardwarePortId, bool *p_IsStalled);
73111 +
73112 +/**************************************************************************//**
73113 + @Function FmResetMac
73114 +
73115 + @Description Used by MAC driver to reset the MAC registers
73116 +
73117 + @Param[in] h_Fm A handle to an FM Module.
73118 + @Param[in] type MAC type.
73119 + @Param[in] macId MAC id - according to type.
73120 +
73121 + @Return E_OK on success; Error code otherwise.
73122 +
73123 + @Cautions Allowed only following FM_Init().
73124 +*//***************************************************************************/
73125 +t_Error FmResetMac(t_Handle h_Fm, e_FmMacType type, uint8_t macId);
73126 +
73127 +/**************************************************************************//**
73128 + @Function FmGetClockFreq
73129 +
73130 + @Description Used by MAC driver to get the FM clock frequency
73131 +
73132 + @Param[in] h_Fm A handle to an FM Module.
73133 +
73134 + @Return clock-freq on success; 0 otherwise.
73135 +
73136 + @Cautions Allowed only following FM_Init().
73137 +*//***************************************************************************/
73138 +uint16_t FmGetClockFreq(t_Handle h_Fm);
73139 +
73140 +/**************************************************************************//**
73141 + @Function FmGetMacClockFreq
73142 +
73143 + @Description Used by MAC driver to get the MAC clock frequency
73144 +
73145 + @Param[in] h_Fm A handle to an FM Module.
73146 +
73147 + @Return clock-freq on success; 0 otherwise.
73148 +
73149 + @Cautions Allowed only following FM_Init().
73150 +*//***************************************************************************/
73151 +uint16_t FmGetMacClockFreq(t_Handle h_Fm);
73152 +
73153 +/**************************************************************************//**
73154 + @Function FmGetId
73155 +
73156 + @Description Used by PCD driver to read rhe FM id
73157 +
73158 + @Param[in] h_Fm A handle to an FM Module.
73159 +
73160 + @Return E_OK on success; Error code otherwise.
73161 +
73162 + @Cautions Allowed only following FM_Init().
73163 +*//***************************************************************************/
73164 +uint8_t FmGetId(t_Handle h_Fm);
73165 +
73166 +/**************************************************************************//**
73167 + @Function FmReset
73168 +
73169 + @Description Used to reset the FM
73170 +
73171 + @Param[in] h_Fm A handle to an FM Module.
73172 +
73173 + @Return E_OK on success; Error code otherwise.
73174 +*//***************************************************************************/
73175 +t_Error FmReset(t_Handle h_Fm);
73176 +
73177 +/**************************************************************************//**
73178 + @Function FmGetSetPortParams
73179 +
73180 + @Description Used by FM-PORT driver to pass and receive parameters between
73181 + PORT and FM modules.
73182 +
73183 + @Param[in] h_Fm A handle to an FM Module.
73184 + @Param[in,out] p_PortParams A structure of FM Port parameters.
73185 +
73186 + @Return E_OK on success; Error code otherwise.
73187 +
73188 + @Cautions Allowed only following FM_Init().
73189 +*//***************************************************************************/
73190 +t_Error FmGetSetPortParams(t_Handle h_Fm,t_FmInterModulePortInitParams *p_PortParams);
73191 +
73192 +/**************************************************************************//**
73193 + @Function FmFreePortParams
73194 +
73195 + @Description Used by FM-PORT driver to free port's resources within the FM.
73196 +
73197 + @Param[in] h_Fm A handle to an FM Module.
73198 + @Param[in,out] p_PortParams A structure of FM Port parameters.
73199 +
73200 + @Return None.
73201 +
73202 + @Cautions Allowed only following FM_Init().
73203 +*//***************************************************************************/
73204 +void FmFreePortParams(t_Handle h_Fm,t_FmInterModulePortFreeParams *p_PortParams);
73205 +
73206 +/**************************************************************************//**
73207 + @Function FmSetNumOfRiscsPerPort
73208 +
73209 + @Description Used by FM-PORT driver to pass parameter between
73210 + PORT and FM modules for working with number of RISC..
73211 +
73212 + @Param[in] h_Fm A handle to an FM Module.
73213 + @Param[in] hardwarePortId hardware port Id.
73214 + @Param[in] numOfFmanCtrls number of Fman Controllers.
73215 + @Param[in] orFmanCtrl Fman Controller for order restoration.
73216 +
73217 + @Return None.
73218 +
73219 + @Cautions Allowed only following FM_Init().
73220 +*//***************************************************************************/
73221 +t_Error FmSetNumOfRiscsPerPort(t_Handle h_Fm, uint8_t hardwarePortId, uint8_t numOfFmanCtrls, t_FmFmanCtrl orFmanCtrl);
73222 +
73223 +#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
73224 +/**************************************************************************//*
73225 + @Function FmDumpPortRegs
73226 +
73227 + @Description Dumps FM port registers which are part of FM common registers
73228 +
73229 + @Param[in] h_Fm A handle to an FM Module.
73230 + @Param[in] hardwarePortId HW port id.
73231 +
73232 + @Return E_OK on success; Error code otherwise.
73233 +
73234 + @Cautions Allowed only FM_Init().
73235 +*//***************************************************************************/
73236 +t_Error FmDumpPortRegs(t_Handle h_Fm,uint8_t hardwarePortId);
73237 +#endif /* (defined(DEBUG_ERRORS) && ... */
73238 +
73239 +void FmRegisterPcd(t_Handle h_Fm, t_Handle h_FmPcd);
73240 +void FmUnregisterPcd(t_Handle h_Fm);
73241 +t_Handle FmGetPcdHandle(t_Handle h_Fm);
73242 +t_Error FmEnableRamsEcc(t_Handle h_Fm);
73243 +t_Error FmDisableRamsEcc(t_Handle h_Fm);
73244 +void FmGetRevision(t_Handle h_Fm, t_FmRevisionInfo *p_FmRevisionInfo);
73245 +t_Error FmAllocFmanCtrlEventReg(t_Handle h_Fm, uint8_t *p_EventId);
73246 +void FmFreeFmanCtrlEventReg(t_Handle h_Fm, uint8_t eventId);
73247 +void FmSetFmanCtrlIntr(t_Handle h_Fm, uint8_t eventRegId, uint32_t enableEvents);
73248 +uint32_t FmGetFmanCtrlIntr(t_Handle h_Fm, uint8_t eventRegId);
73249 +void FmRegisterFmanCtrlIntr(t_Handle h_Fm, uint8_t eventRegId, void (*f_Isr) (t_Handle h_Fm, uint32_t event), t_Handle h_Arg);
73250 +void FmUnregisterFmanCtrlIntr(t_Handle h_Fm, uint8_t eventRegId);
73251 +t_Error FmSetMacMaxFrame(t_Handle h_Fm, e_FmMacType type, uint8_t macId, uint16_t mtu);
73252 +bool FmIsMaster(t_Handle h_Fm);
73253 +uint8_t FmGetGuestId(t_Handle h_Fm);
73254 +uint16_t FmGetTnumAgingPeriod(t_Handle h_Fm);
73255 +t_Error FmSetPortPreFetchConfiguration(t_Handle h_Fm, uint8_t portNum, bool preFetchConfigured);
73256 +t_Error FmGetPortPreFetchConfiguration(t_Handle h_Fm, uint8_t portNum, bool *p_PortConfigured, bool *p_PreFetchConfigured);
73257 +
73258 +
73259 +#ifdef FM_TX_ECC_FRMS_ERRATA_10GMAC_A004
73260 +t_Error Fm10GTxEccWorkaround(t_Handle h_Fm, uint8_t macId);
73261 +#endif /* FM_TX_ECC_FRMS_ERRATA_10GMAC_A004 */
73262 +
73263 +void FmMuramClear(t_Handle h_FmMuram);
73264 +t_Error FmSetNumOfOpenDmas(t_Handle h_Fm,
73265 + uint8_t hardwarePortId,
73266 + uint8_t *p_NumOfOpenDmas,
73267 + uint8_t *p_NumOfExtraOpenDmas,
73268 + bool initialConfig);
73269 +t_Error FmSetNumOfTasks(t_Handle h_Fm,
73270 + uint8_t hardwarePortId,
73271 + uint8_t *p_NumOfTasks,
73272 + uint8_t *p_NumOfExtraTasks,
73273 + bool initialConfig);
73274 +t_Error FmSetSizeOfFifo(t_Handle h_Fm,
73275 + uint8_t hardwarePortId,
73276 + uint32_t *p_SizeOfFifo,
73277 + uint32_t *p_ExtraSizeOfFifo,
73278 + bool initialConfig);
73279 +
73280 +t_Error FmSetCongestionGroupPFCpriority(t_Handle h_Fm,
73281 + uint32_t congestionGroupId,
73282 + uint8_t priorityBitMap);
73283 +
73284 +#if (DPAA_VERSION >= 11)
73285 +t_Error FmVSPAllocForPort(t_Handle h_Fm,
73286 + e_FmPortType portType,
73287 + uint8_t portId,
73288 + uint8_t numOfStorageProfiles);
73289 +
73290 +t_Error FmVSPFreeForPort(t_Handle h_Fm,
73291 + e_FmPortType portType,
73292 + uint8_t portId);
73293 +
73294 +t_Error FmVSPGetAbsoluteProfileId(t_Handle h_Fm,
73295 + e_FmPortType portType,
73296 + uint8_t portId,
73297 + uint16_t relativeProfile,
73298 + uint16_t *p_AbsoluteId);
73299 +t_Error FmVSPCheckRelativeProfile(t_Handle h_Fm,
73300 + e_FmPortType portType,
73301 + uint8_t portId,
73302 + uint16_t relativeProfile);
73303 +
73304 +uintptr_t FmGetVSPBaseAddr(t_Handle h_Fm);
73305 +#endif /* (DPAA_VERSION >= 11) */
73306 +
73307 +
73308 +#endif /* __FM_COMMON_H */
73309 --- /dev/null
73310 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/inc/fm_hc.h
73311 @@ -0,0 +1,93 @@
73312 +/*
73313 + * Copyright 2008-2012 Freescale Semiconductor Inc.
73314 + *
73315 + * Redistribution and use in source and binary forms, with or without
73316 + * modification, are permitted provided that the following conditions are met:
73317 + * * Redistributions of source code must retain the above copyright
73318 + * notice, this list of conditions and the following disclaimer.
73319 + * * Redistributions in binary form must reproduce the above copyright
73320 + * notice, this list of conditions and the following disclaimer in the
73321 + * documentation and/or other materials provided with the distribution.
73322 + * * Neither the name of Freescale Semiconductor nor the
73323 + * names of its contributors may be used to endorse or promote products
73324 + * derived from this software without specific prior written permission.
73325 + *
73326 + *
73327 + * ALTERNATIVELY, this software may be distributed under the terms of the
73328 + * GNU General Public License ("GPL") as published by the Free Software
73329 + * Foundation, either version 2 of that License or (at your option) any
73330 + * later version.
73331 + *
73332 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
73333 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
73334 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
73335 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
73336 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
73337 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
73338 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
73339 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
73340 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
73341 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
73342 + */
73343 +
73344 +
73345 +#ifndef __FM_HC_H
73346 +#define __FM_HC_H
73347 +
73348 +#include "std_ext.h"
73349 +#include "error_ext.h"
73350 +#include "fsl_fman_kg.h"
73351 +
73352 +#define __ERR_MODULE__ MODULE_FM_PCD
73353 +
73354 +
73355 +typedef struct t_FmHcParams {
73356 + t_Handle h_Fm;
73357 + t_Handle h_FmPcd;
73358 + t_FmPcdHcParams params;
73359 +} t_FmHcParams;
73360 +
73361 +
73362 +t_Handle FmHcConfigAndInit(t_FmHcParams *p_FmHcParams);
73363 +void FmHcFree(t_Handle h_FmHc);
73364 +t_Error FmHcSetFramesDataMemory(t_Handle h_FmHc,
73365 + uint8_t memId);
73366 +t_Error FmHcDumpRegs(t_Handle h_FmHc);
73367 +
73368 +void FmHcTxConf(t_Handle h_FmHc, t_DpaaFD *p_Fd);
73369 +
73370 +t_Error FmHcPcdKgSetScheme(t_Handle h_FmHc,
73371 + t_Handle h_Scheme,
73372 + struct fman_kg_scheme_regs *p_SchemeRegs,
73373 + bool updateCounter);
73374 +t_Error FmHcPcdKgDeleteScheme(t_Handle h_FmHc, t_Handle h_Scheme);
73375 +t_Error FmHcPcdCcCapwapTimeoutReassm(t_Handle h_FmHc, t_FmPcdCcCapwapReassmTimeoutParams *p_CcCapwapReassmTimeoutParams );
73376 +t_Error FmHcPcdCcIpFragScratchPollCmd(t_Handle h_FmHc, bool fill, t_FmPcdCcFragScratchPoolCmdParams *p_FmPcdCcFragScratchPoolCmdParams);
73377 +t_Error FmHcPcdCcTimeoutReassm(t_Handle h_FmHc, t_FmPcdCcReassmTimeoutParams *p_CcReassmTimeoutParams, uint8_t *p_Result);
73378 +t_Error FmHcPcdKgSetClsPlan(t_Handle h_FmHc, t_FmPcdKgInterModuleClsPlanSet *p_Set);
73379 +t_Error FmHcPcdKgDeleteClsPlan(t_Handle h_FmHc, uint8_t clsPlanGrpId);
73380 +
73381 +t_Error FmHcPcdKgSetSchemeCounter(t_Handle h_FmHc, t_Handle h_Scheme, uint32_t value);
73382 +uint32_t FmHcPcdKgGetSchemeCounter(t_Handle h_FmHc, t_Handle h_Scheme);
73383 +
73384 +t_Error FmHcPcdCcDoDynamicChange(t_Handle h_FmHc, uint32_t oldAdAddrOffset, uint32_t newAdAddrOffset);
73385 +
73386 +t_Error FmHcPcdPlcrSetProfile(t_Handle h_FmHc, t_Handle h_Profile, t_FmPcdPlcrProfileRegs *p_PlcrRegs);
73387 +t_Error FmHcPcdPlcrDeleteProfile(t_Handle h_FmHc, t_Handle h_Profile);
73388 +
73389 +t_Error FmHcPcdPlcrSetProfileCounter(t_Handle h_FmHc, t_Handle h_Profile, e_FmPcdPlcrProfileCounters counter, uint32_t value);
73390 +uint32_t FmHcPcdPlcrGetProfileCounter(t_Handle h_FmHc, t_Handle h_Profile, e_FmPcdPlcrProfileCounters counter);
73391 +
73392 +t_Error FmHcKgWriteSp(t_Handle h_FmHc, uint8_t hardwarePortId, uint32_t spReg, bool add);
73393 +t_Error FmHcKgWriteCpp(t_Handle h_FmHc, uint8_t hardwarePortId, uint32_t cppReg);
73394 +
73395 +t_Error FmHcPcdKgCcGetSetParams(t_Handle h_FmHc, t_Handle h_Scheme, uint32_t requiredAction, uint32_t value);
73396 +t_Error FmHcPcdPlcrCcGetSetParams(t_Handle h_FmHc,uint16_t absoluteProfileId, uint32_t requiredAction);
73397 +
73398 +t_Error FmHcPcdSync(t_Handle h_FmHc);
73399 +t_Handle FmHcGetPort(t_Handle h_FmHc);
73400 +
73401 +
73402 +
73403 +
73404 +#endif /* __FM_HC_H */
73405 --- /dev/null
73406 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/inc/fm_sp_common.h
73407 @@ -0,0 +1,117 @@
73408 +/*
73409 + * Copyright 2008-2012 Freescale Semiconductor Inc.
73410 + *
73411 + * Redistribution and use in source and binary forms, with or without
73412 + * modification, are permitted provided that the following conditions are met:
73413 + * * Redistributions of source code must retain the above copyright
73414 + * notice, this list of conditions and the following disclaimer.
73415 + * * Redistributions in binary form must reproduce the above copyright
73416 + * notice, this list of conditions and the following disclaimer in the
73417 + * documentation and/or other materials provided with the distribution.
73418 + * * Neither the name of Freescale Semiconductor nor the
73419 + * names of its contributors may be used to endorse or promote products
73420 + * derived from this software without specific prior written permission.
73421 + *
73422 + *
73423 + * ALTERNATIVELY, this software may be distributed under the terms of the
73424 + * GNU General Public License ("GPL") as published by the Free Software
73425 + * Foundation, either version 2 of that License or (at your option) any
73426 + * later version.
73427 + *
73428 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
73429 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
73430 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
73431 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
73432 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
73433 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
73434 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
73435 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
73436 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
73437 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
73438 + */
73439 +
73440 +
73441 +/******************************************************************************
73442 + @File fm_sp_common.h
73443 +
73444 + @Description FM SP ...
73445 +*//***************************************************************************/
73446 +#ifndef __FM_SP_COMMON_H
73447 +#define __FM_SP_COMMON_H
73448 +
73449 +#include "std_ext.h"
73450 +#include "error_ext.h"
73451 +#include "list_ext.h"
73452 +
73453 +#include "fm_ext.h"
73454 +#include "fm_pcd_ext.h"
73455 +#include "fsl_fman.h"
73456 +
73457 +/**************************************************************************//**
73458 + @Description defaults
73459 +*//***************************************************************************/
73460 +#define DEFAULT_FM_SP_bufferPrefixContent_privDataSize 0
73461 +#define DEFAULT_FM_SP_bufferPrefixContent_passPrsResult FALSE
73462 +#define DEFAULT_FM_SP_bufferPrefixContent_passTimeStamp FALSE
73463 +#define DEFAULT_FM_SP_bufferPrefixContent_allOtherPCDInfo FALSE
73464 +#define DEFAULT_FM_SP_bufferPrefixContent_dataAlign 64
73465 +
73466 +/**************************************************************************//**
73467 + @Description structure for defining internal context copying
73468 +*//***************************************************************************/
73469 +typedef struct
73470 +{
73471 + uint16_t extBufOffset; /**< Offset in External buffer to which internal
73472 + context is copied to (Rx) or taken from (Tx, Op). */
73473 + uint8_t intContextOffset; /**< Offset within internal context to copy from
73474 + (Rx) or to copy to (Tx, Op). */
73475 + uint16_t size; /**< Internal offset size to be copied */
73476 +} t_FmSpIntContextDataCopy;
73477 +
73478 +/**************************************************************************//**
73479 + @Description struct for defining external buffer margins
73480 +*//***************************************************************************/
73481 +typedef struct {
73482 + uint16_t startMargins; /**< Number of bytes to be left at the beginning
73483 + of the external buffer (must be divisible by 16) */
73484 + uint16_t endMargins; /**< number of bytes to be left at the end
73485 + of the external buffer(must be divisible by 16) */
73486 +} t_FmSpBufMargins;
73487 +
73488 +typedef struct {
73489 + uint32_t dataOffset;
73490 + uint32_t prsResultOffset;
73491 + uint32_t timeStampOffset;
73492 + uint32_t hashResultOffset;
73493 + uint32_t pcdInfoOffset;
73494 + uint32_t manipOffset;
73495 +} t_FmSpBufferOffsets;
73496 +
73497 +
73498 +t_Error FmSpBuildBufferStructure(t_FmSpIntContextDataCopy *p_FmPortIntContextDataCopy,
73499 + t_FmBufferPrefixContent *p_BufferPrefixContent,
73500 + t_FmSpBufMargins *p_FmPortBufMargins,
73501 + t_FmSpBufferOffsets *p_FmPortBufferOffsets,
73502 + uint8_t *internalBufferOffset);
73503 +
73504 +t_Error FmSpCheckIntContextParams(t_FmSpIntContextDataCopy *p_FmSpIntContextDataCopy);
73505 +t_Error FmSpCheckBufPoolsParams(t_FmExtPools *p_FmExtPools,
73506 + t_FmBackupBmPools *p_FmBackupBmPools,
73507 + t_FmBufPoolDepletion *p_FmBufPoolDepletion);
73508 +t_Error FmSpCheckBufMargins(t_FmSpBufMargins *p_FmSpBufMargins);
73509 +void FmSpSetBufPoolsInAscOrderOfBufSizes(t_FmExtPools *p_FmExtPools, uint8_t *orderedArray, uint16_t *sizesArray);
73510 +
73511 +t_Error FmPcdSpAllocProfiles(t_Handle h_FmPcd,
73512 + uint8_t hardwarePortId,
73513 + uint16_t numOfStorageProfiles,
73514 + uint16_t *base,
73515 + uint8_t *log2Num);
73516 +t_Error FmPcdSpGetAbsoluteProfileId(t_Handle h_FmPcd,
73517 + t_Handle h_FmPort,
73518 + uint16_t relativeProfile,
73519 + uint16_t *p_AbsoluteId);
73520 +void SpInvalidateProfileSw(t_Handle h_FmPcd, uint16_t absoluteProfileId);
73521 +void SpValidateProfileSw(t_Handle h_FmPcd, uint16_t absoluteProfileId);
73522 +
73523 +
73524 +#endif /* __FM_SP_COMMON_H */
73525 --- /dev/null
73526 +++ b/drivers/net/ethernet/freescale/sdk_fman/etc/Makefile
73527 @@ -0,0 +1,12 @@
73528 +#
73529 +# Makefile for the Freescale Ethernet controllers
73530 +#
73531 +ccflags-y += -DVERSION=\"\"
73532 +#
73533 +#Include netcomm SW specific definitions
73534 +
73535 +include $(srctree)/drivers/net/ethernet/freescale/sdk_fman/ncsw_config.mk
73536 +
73537 +obj-y += fsl-ncsw-etc.o
73538 +
73539 +fsl-ncsw-etc-objs := mm.o memcpy.o sprint.o list.o error.o
73540 --- /dev/null
73541 +++ b/drivers/net/ethernet/freescale/sdk_fman/etc/error.c
73542 @@ -0,0 +1,95 @@
73543 +/*
73544 + * Copyright 2008-2012 Freescale Semiconductor Inc.
73545 + *
73546 + * Redistribution and use in source and binary forms, with or without
73547 + * modification, are permitted provided that the following conditions are met:
73548 + * * Redistributions of source code must retain the above copyright
73549 + * notice, this list of conditions and the following disclaimer.
73550 + * * Redistributions in binary form must reproduce the above copyright
73551 + * notice, this list of conditions and the following disclaimer in the
73552 + * documentation and/or other materials provided with the distribution.
73553 + * * Neither the name of Freescale Semiconductor nor the
73554 + * names of its contributors may be used to endorse or promote products
73555 + * derived from this software without specific prior written permission.
73556 + *
73557 + *
73558 + * ALTERNATIVELY, this software may be distributed under the terms of the
73559 + * GNU General Public License ("GPL") as published by the Free Software
73560 + * Foundation, either version 2 of that License or (at your option) any
73561 + * later version.
73562 + *
73563 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
73564 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
73565 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
73566 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
73567 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
73568 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
73569 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
73570 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
73571 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
73572 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
73573 + */
73574 +
73575 +
73576 +/*
73577 +
73578 + @File error.c
73579 +
73580 + @Description General errors and events reporting utilities.
73581 +*//***************************************************************************/
73582 +#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
73583 +#include "error_ext.h"
73584 +
73585 +
73586 +const char *dbgLevelStrings[] =
73587 +{
73588 + "CRITICAL"
73589 + ,"MAJOR"
73590 + ,"MINOR"
73591 + ,"WARNING"
73592 + ,"INFO"
73593 + ,"TRACE"
73594 +};
73595 +
73596 +
73597 +char * ErrTypeStrings (e_ErrorType err)
73598 +{
73599 + switch (err)
73600 + {
73601 + case (E_OK): return "OK";
73602 + case (E_WRITE_FAILED): return "Write Access Failed";
73603 + case (E_NO_DEVICE): return "No Device";
73604 + case (E_NOT_AVAILABLE): return "Resource Is Unavailable";
73605 + case (E_NO_MEMORY): return "Memory Allocation Failed";
73606 + case (E_INVALID_ADDRESS): return "Invalid Address";
73607 + case (E_BUSY): return "Resource Is Busy";
73608 + case (E_ALREADY_EXISTS): return "Resource Already Exists";
73609 + case (E_INVALID_OPERATION): return "Invalid Operation";
73610 + case (E_INVALID_VALUE): return "Invalid Value";
73611 + case (E_NOT_IN_RANGE): return "Value Out Of Range";
73612 + case (E_NOT_SUPPORTED): return "Unsupported Operation";
73613 + case (E_INVALID_STATE): return "Invalid State";
73614 + case (E_INVALID_HANDLE): return "Invalid Handle";
73615 + case (E_INVALID_ID): return "Invalid ID";
73616 + case (E_NULL_POINTER): return "Unexpected NULL Pointer";
73617 + case (E_INVALID_SELECTION): return "Invalid Selection";
73618 + case (E_INVALID_COMM_MODE): return "Invalid Communication Mode";
73619 + case (E_INVALID_MEMORY_TYPE): return "Invalid Memory Type";
73620 + case (E_INVALID_CLOCK): return "Invalid Clock";
73621 + case (E_CONFLICT): return "Conflict In Settings";
73622 + case (E_NOT_ALIGNED): return "Incorrect Alignment";
73623 + case (E_NOT_FOUND): return "Resource Not Found";
73624 + case (E_FULL): return "Resource Is Full";
73625 + case (E_EMPTY): return "Resource Is Empty";
73626 + case (E_ALREADY_FREE): return "Resource Already Free";
73627 + case (E_READ_FAILED): return "Read Access Failed";
73628 + case (E_INVALID_FRAME): return "Invalid Frame";
73629 + case (E_SEND_FAILED): return "Send Operation Failed";
73630 + case (E_RECEIVE_FAILED): return "Receive Operation Failed";
73631 + case (E_TIMEOUT): return "Operation Timed Out";
73632 + default:
73633 + break;
73634 + }
73635 + return NULL;
73636 +}
73637 +#endif /* (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0)) */
73638 --- /dev/null
73639 +++ b/drivers/net/ethernet/freescale/sdk_fman/etc/list.c
73640 @@ -0,0 +1,71 @@
73641 +/*
73642 + * Copyright 2008-2012 Freescale Semiconductor Inc.
73643 + *
73644 + * Redistribution and use in source and binary forms, with or without
73645 + * modification, are permitted provided that the following conditions are met:
73646 + * * Redistributions of source code must retain the above copyright
73647 + * notice, this list of conditions and the following disclaimer.
73648 + * * Redistributions in binary form must reproduce the above copyright
73649 + * notice, this list of conditions and the following disclaimer in the
73650 + * documentation and/or other materials provided with the distribution.
73651 + * * Neither the name of Freescale Semiconductor nor the
73652 + * names of its contributors may be used to endorse or promote products
73653 + * derived from this software without specific prior written permission.
73654 + *
73655 + *
73656 + * ALTERNATIVELY, this software may be distributed under the terms of the
73657 + * GNU General Public License ("GPL") as published by the Free Software
73658 + * Foundation, either version 2 of that License or (at your option) any
73659 + * later version.
73660 + *
73661 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
73662 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
73663 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
73664 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
73665 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
73666 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
73667 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
73668 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
73669 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
73670 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
73671 + */
73672 +
73673 +
73674 +/**************************************************************************//**
73675 +
73676 + @File list.c
73677 +
73678 + @Description Implementation of list.
73679 +*//***************************************************************************/
73680 +#include "std_ext.h"
73681 +#include "list_ext.h"
73682 +
73683 +
73684 +void LIST_Append(t_List *p_NewList, t_List *p_Head)
73685 +{
73686 + t_List *p_First = LIST_FIRST(p_NewList);
73687 +
73688 + if (p_First != p_NewList)
73689 + {
73690 + t_List *p_Last = LIST_LAST(p_NewList);
73691 + t_List *p_Cur = LIST_NEXT(p_Head);
73692 +
73693 + LIST_PREV(p_First) = p_Head;
73694 + LIST_FIRST(p_Head) = p_First;
73695 + LIST_NEXT(p_Last) = p_Cur;
73696 + LIST_LAST(p_Cur) = p_Last;
73697 + }
73698 +}
73699 +
73700 +
73701 +int LIST_NumOfObjs(t_List *p_List)
73702 +{
73703 + t_List *p_Tmp;
73704 + int numOfObjs = 0;
73705 +
73706 + if (!LIST_IsEmpty(p_List))
73707 + LIST_FOR_EACH(p_Tmp, p_List)
73708 + numOfObjs++;
73709 +
73710 + return numOfObjs;
73711 +}
73712 --- /dev/null
73713 +++ b/drivers/net/ethernet/freescale/sdk_fman/etc/memcpy.c
73714 @@ -0,0 +1,620 @@
73715 +/*
73716 + * Copyright 2008-2012 Freescale Semiconductor Inc.
73717 + *
73718 + * Redistribution and use in source and binary forms, with or without
73719 + * modification, are permitted provided that the following conditions are met:
73720 + * * Redistributions of source code must retain the above copyright
73721 + * notice, this list of conditions and the following disclaimer.
73722 + * * Redistributions in binary form must reproduce the above copyright
73723 + * notice, this list of conditions and the following disclaimer in the
73724 + * documentation and/or other materials provided with the distribution.
73725 + * * Neither the name of Freescale Semiconductor nor the
73726 + * names of its contributors may be used to endorse or promote products
73727 + * derived from this software without specific prior written permission.
73728 + *
73729 + *
73730 + * ALTERNATIVELY, this software may be distributed under the terms of the
73731 + * GNU General Public License ("GPL") as published by the Free Software
73732 + * Foundation, either version 2 of that License or (at your option) any
73733 + * later version.
73734 + *
73735 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
73736 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
73737 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
73738 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
73739 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
73740 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
73741 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
73742 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
73743 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
73744 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
73745 + */
73746 +
73747 +
73748 +
73749 +#include "std_ext.h"
73750 +#include "xx_ext.h"
73751 +#include "memcpy_ext.h"
73752 +
73753 +void * MemCpy8(void* pDst, void* pSrc, uint32_t size)
73754 +{
73755 + int i;
73756 +
73757 + for(i = 0; i < size; ++i)
73758 + *(((uint8_t*)(pDst)) + i) = *(((uint8_t*)(pSrc)) + i);
73759 +
73760 + return pDst;
73761 +}
73762 +
73763 +void * MemSet8(void* pDst, int c, uint32_t size)
73764 +{
73765 + int i;
73766 +
73767 + for(i = 0; i < size; ++i)
73768 + *(((uint8_t*)(pDst)) + i) = (uint8_t)(c);
73769 +
73770 + return pDst;
73771 +}
73772 +
73773 +void * MemCpy32(void* pDst,void* pSrc, uint32_t size)
73774 +{
73775 + uint32_t leftAlign;
73776 + uint32_t rightAlign;
73777 + uint32_t lastWord;
73778 + uint32_t currWord;
73779 + uint32_t *p_Src32;
73780 + uint32_t *p_Dst32;
73781 + uint8_t *p_Src8;
73782 + uint8_t *p_Dst8;
73783 +
73784 + p_Src8 = (uint8_t*)(pSrc);
73785 + p_Dst8 = (uint8_t*)(pDst);
73786 + /* first copy byte by byte till the source first alignment
73787 + * this step is necessary to ensure we do not even try to access
73788 + * data which is before the source buffer, hence it is not ours.
73789 + */
73790 + while((PTR_TO_UINT(p_Src8) & 3) && size) /* (pSrc mod 4) > 0 and size > 0 */
73791 + {
73792 + *p_Dst8++ = *p_Src8++;
73793 + size--;
73794 + }
73795 +
73796 + /* align destination (possibly disaligning source)*/
73797 + while((PTR_TO_UINT(p_Dst8) & 3) && size) /* (pDst mod 4) > 0 and size > 0 */
73798 + {
73799 + *p_Dst8++ = *p_Src8++;
73800 + size--;
73801 + }
73802 +
73803 + /* dest is aligned and source is not necessarily aligned */
73804 + leftAlign = (uint32_t)((PTR_TO_UINT(p_Src8) & 3) << 3); /* leftAlign = (pSrc mod 4)*8 */
73805 + rightAlign = 32 - leftAlign;
73806 +
73807 +
73808 + if (leftAlign == 0)
73809 + {
73810 + /* source is also aligned */
73811 + p_Src32 = (uint32_t*)(p_Src8);
73812 + p_Dst32 = (uint32_t*)(p_Dst8);
73813 + while (size >> 2) /* size >= 4 */
73814 + {
73815 + *p_Dst32++ = *p_Src32++;
73816 + size -= 4;
73817 + }
73818 + p_Src8 = (uint8_t*)(p_Src32);
73819 + p_Dst8 = (uint8_t*)(p_Dst32);
73820 + }
73821 + else
73822 + {
73823 + /* source is not aligned (destination is aligned)*/
73824 + p_Src32 = (uint32_t*)(p_Src8 - (leftAlign >> 3));
73825 + p_Dst32 = (uint32_t*)(p_Dst8);
73826 + lastWord = *p_Src32++;
73827 + while(size >> 3) /* size >= 8 */
73828 + {
73829 + currWord = *p_Src32;
73830 + *p_Dst32 = (lastWord << leftAlign) | (currWord >> rightAlign);
73831 + lastWord = currWord;
73832 + p_Src32++;
73833 + p_Dst32++;
73834 + size -= 4;
73835 + }
73836 + p_Dst8 = (uint8_t*)(p_Dst32);
73837 + p_Src8 = (uint8_t*)(p_Src32) - 4 + (leftAlign >> 3);
73838 + }
73839 +
73840 + /* complete the left overs */
73841 + while (size--)
73842 + *p_Dst8++ = *p_Src8++;
73843 +
73844 + return pDst;
73845 +}
73846 +
73847 +void * IO2IOCpy32(void* pDst,void* pSrc, uint32_t size)
73848 +{
73849 + uint32_t leftAlign;
73850 + uint32_t rightAlign;
73851 + uint32_t lastWord;
73852 + uint32_t currWord;
73853 + uint32_t *p_Src32;
73854 + uint32_t *p_Dst32;
73855 + uint8_t *p_Src8;
73856 + uint8_t *p_Dst8;
73857 +
73858 + p_Src8 = (uint8_t*)(pSrc);
73859 + p_Dst8 = (uint8_t*)(pDst);
73860 + /* first copy byte by byte till the source first alignment
73861 + * this step is necessary to ensure we do not even try to access
73862 + * data which is before the source buffer, hence it is not ours.
73863 + */
73864 + while((PTR_TO_UINT(p_Src8) & 3) && size) /* (pSrc mod 4) > 0 and size > 0 */
73865 + {
73866 + WRITE_UINT8(*p_Dst8, GET_UINT8(*p_Src8));
73867 + p_Dst8++;p_Src8++;
73868 + size--;
73869 + }
73870 +
73871 + /* align destination (possibly disaligning source)*/
73872 + while((PTR_TO_UINT(p_Dst8) & 3) && size) /* (pDst mod 4) > 0 and size > 0 */
73873 + {
73874 + WRITE_UINT8(*p_Dst8, GET_UINT8(*p_Src8));
73875 + p_Dst8++;p_Src8++;
73876 + size--;
73877 + }
73878 +
73879 + /* dest is aligned and source is not necessarily aligned */
73880 + leftAlign = (uint32_t)((PTR_TO_UINT(p_Src8) & 3) << 3); /* leftAlign = (pSrc mod 4)*8 */
73881 + rightAlign = 32 - leftAlign;
73882 +
73883 + if (leftAlign == 0)
73884 + {
73885 + /* source is also aligned */
73886 + p_Src32 = (uint32_t*)(p_Src8);
73887 + p_Dst32 = (uint32_t*)(p_Dst8);
73888 + while (size >> 2) /* size >= 4 */
73889 + {
73890 + WRITE_UINT32(*p_Dst32, GET_UINT32(*p_Src32));
73891 + p_Dst32++;p_Src32++;
73892 + size -= 4;
73893 + }
73894 + p_Src8 = (uint8_t*)(p_Src32);
73895 + p_Dst8 = (uint8_t*)(p_Dst32);
73896 + }
73897 + else
73898 + {
73899 + /* source is not aligned (destination is aligned)*/
73900 + p_Src32 = (uint32_t*)(p_Src8 - (leftAlign >> 3));
73901 + p_Dst32 = (uint32_t*)(p_Dst8);
73902 + lastWord = GET_UINT32(*p_Src32);
73903 + p_Src32++;
73904 + while(size >> 3) /* size >= 8 */
73905 + {
73906 + currWord = GET_UINT32(*p_Src32);
73907 + WRITE_UINT32(*p_Dst32, (lastWord << leftAlign) | (currWord >> rightAlign));
73908 + lastWord = currWord;
73909 + p_Src32++;p_Dst32++;
73910 + size -= 4;
73911 + }
73912 + p_Dst8 = (uint8_t*)(p_Dst32);
73913 + p_Src8 = (uint8_t*)(p_Src32) - 4 + (leftAlign >> 3);
73914 + }
73915 +
73916 + /* complete the left overs */
73917 + while (size--)
73918 + {
73919 + WRITE_UINT8(*p_Dst8, GET_UINT8(*p_Src8));
73920 + p_Dst8++;p_Src8++;
73921 + }
73922 +
73923 + return pDst;
73924 +}
73925 +
73926 +void * Mem2IOCpy32(void* pDst,void* pSrc, uint32_t size)
73927 +{
73928 + uint32_t leftAlign;
73929 + uint32_t rightAlign;
73930 + uint32_t lastWord;
73931 + uint32_t currWord;
73932 + uint32_t *p_Src32;
73933 + uint32_t *p_Dst32;
73934 + uint8_t *p_Src8;
73935 + uint8_t *p_Dst8;
73936 +
73937 + p_Src8 = (uint8_t*)(pSrc);
73938 + p_Dst8 = (uint8_t*)(pDst);
73939 + /* first copy byte by byte till the source first alignment
73940 + * this step is necessary to ensure we do not even try to access
73941 + * data which is before the source buffer, hence it is not ours.
73942 + */
73943 + while((PTR_TO_UINT(p_Src8) & 3) && size) /* (pSrc mod 4) > 0 and size > 0 */
73944 + {
73945 + WRITE_UINT8(*p_Dst8, *p_Src8);
73946 + p_Dst8++;p_Src8++;
73947 + size--;
73948 + }
73949 +
73950 + /* align destination (possibly disaligning source)*/
73951 + while((PTR_TO_UINT(p_Dst8) & 3) && size) /* (pDst mod 4) > 0 and size > 0 */
73952 + {
73953 + WRITE_UINT8(*p_Dst8, *p_Src8);
73954 + p_Dst8++;p_Src8++;
73955 + size--;
73956 + }
73957 +
73958 + /* dest is aligned and source is not necessarily aligned */
73959 + leftAlign = (uint32_t)((PTR_TO_UINT(p_Src8) & 3) << 3); /* leftAlign = (pSrc mod 4)*8 */
73960 + rightAlign = 32 - leftAlign;
73961 +
73962 + if (leftAlign == 0)
73963 + {
73964 + /* source is also aligned */
73965 + p_Src32 = (uint32_t*)(p_Src8);
73966 + p_Dst32 = (uint32_t*)(p_Dst8);
73967 + while (size >> 2) /* size >= 4 */
73968 + {
73969 + WRITE_UINT32(*p_Dst32, *p_Src32);
73970 + p_Dst32++;p_Src32++;
73971 + size -= 4;
73972 + }
73973 + p_Src8 = (uint8_t*)(p_Src32);
73974 + p_Dst8 = (uint8_t*)(p_Dst32);
73975 + }
73976 + else
73977 + {
73978 + /* source is not aligned (destination is aligned)*/
73979 + p_Src32 = (uint32_t*)(p_Src8 - (leftAlign >> 3));
73980 + p_Dst32 = (uint32_t*)(p_Dst8);
73981 + lastWord = *p_Src32++;
73982 + while(size >> 3) /* size >= 8 */
73983 + {
73984 + currWord = *p_Src32;
73985 + WRITE_UINT32(*p_Dst32, (lastWord << leftAlign) | (currWord >> rightAlign));
73986 + lastWord = currWord;
73987 + p_Src32++;p_Dst32++;
73988 + size -= 4;
73989 + }
73990 + p_Dst8 = (uint8_t*)(p_Dst32);
73991 + p_Src8 = (uint8_t*)(p_Src32) - 4 + (leftAlign >> 3);
73992 + }
73993 +
73994 + /* complete the left overs */
73995 + while (size--)
73996 + {
73997 + WRITE_UINT8(*p_Dst8, *p_Src8);
73998 + p_Dst8++;p_Src8++;
73999 + }
74000 +
74001 + return pDst;
74002 +}
74003 +
74004 +void * IO2MemCpy32(void* pDst,void* pSrc, uint32_t size)
74005 +{
74006 + uint32_t leftAlign;
74007 + uint32_t rightAlign;
74008 + uint32_t lastWord;
74009 + uint32_t currWord;
74010 + uint32_t *p_Src32;
74011 + uint32_t *p_Dst32;
74012 + uint8_t *p_Src8;
74013 + uint8_t *p_Dst8;
74014 +
74015 + p_Src8 = (uint8_t*)(pSrc);
74016 + p_Dst8 = (uint8_t*)(pDst);
74017 + /* first copy byte by byte till the source first alignment
74018 + * this step is necessary to ensure we do not even try to access
74019 + * data which is before the source buffer, hence it is not ours.
74020 + */
74021 + while((PTR_TO_UINT(p_Src8) & 3) && size) /* (pSrc mod 4) > 0 and size > 0 */
74022 + {
74023 + *p_Dst8 = GET_UINT8(*p_Src8);
74024 + p_Dst8++;p_Src8++;
74025 + size--;
74026 + }
74027 +
74028 + /* align destination (possibly disaligning source)*/
74029 + while((PTR_TO_UINT(p_Dst8) & 3) && size) /* (pDst mod 4) > 0 and size > 0 */
74030 + {
74031 + *p_Dst8 = GET_UINT8(*p_Src8);
74032 + p_Dst8++;p_Src8++;
74033 + size--;
74034 + }
74035 +
74036 + /* dest is aligned and source is not necessarily aligned */
74037 + leftAlign = (uint32_t)((PTR_TO_UINT(p_Src8) & 3) << 3); /* leftAlign = (pSrc mod 4)*8 */
74038 + rightAlign = 32 - leftAlign;
74039 +
74040 + if (leftAlign == 0)
74041 + {
74042 + /* source is also aligned */
74043 + p_Src32 = (uint32_t*)(p_Src8);
74044 + p_Dst32 = (uint32_t*)(p_Dst8);
74045 + while (size >> 2) /* size >= 4 */
74046 + {
74047 + *p_Dst32 = GET_UINT32(*p_Src32);
74048 + p_Dst32++;p_Src32++;
74049 + size -= 4;
74050 + }
74051 + p_Src8 = (uint8_t*)(p_Src32);
74052 + p_Dst8 = (uint8_t*)(p_Dst32);
74053 + }
74054 + else
74055 + {
74056 + /* source is not aligned (destination is aligned)*/
74057 + p_Src32 = (uint32_t*)(p_Src8 - (leftAlign >> 3));
74058 + p_Dst32 = (uint32_t*)(p_Dst8);
74059 + lastWord = GET_UINT32(*p_Src32);
74060 + p_Src32++;
74061 + while(size >> 3) /* size >= 8 */
74062 + {
74063 + currWord = GET_UINT32(*p_Src32);
74064 + *p_Dst32 = (lastWord << leftAlign) | (currWord >> rightAlign);
74065 + lastWord = currWord;
74066 + p_Src32++;p_Dst32++;
74067 + size -= 4;
74068 + }
74069 + p_Dst8 = (uint8_t*)(p_Dst32);
74070 + p_Src8 = (uint8_t*)(p_Src32) - 4 + (leftAlign >> 3);
74071 + }
74072 +
74073 + /* complete the left overs */
74074 + while (size--)
74075 + {
74076 + *p_Dst8 = GET_UINT8(*p_Src8);
74077 + p_Dst8++;p_Src8++;
74078 + }
74079 +
74080 + return pDst;
74081 +}
74082 +
74083 +void * MemCpy64(void* pDst,void* pSrc, uint32_t size)
74084 +{
74085 + uint32_t leftAlign;
74086 + uint32_t rightAlign;
74087 + uint64_t lastWord;
74088 + uint64_t currWord;
74089 + uint64_t *pSrc64;
74090 + uint64_t *pDst64;
74091 + uint8_t *p_Src8;
74092 + uint8_t *p_Dst8;
74093 +
74094 + p_Src8 = (uint8_t*)(pSrc);
74095 + p_Dst8 = (uint8_t*)(pDst);
74096 + /* first copy byte by byte till the source first alignment
74097 + * this step is necessarily to ensure we do not even try to access
74098 + * data which is before the source buffer, hence it is not ours.
74099 + */
74100 + while((PTR_TO_UINT(p_Src8) & 7) && size) /* (pSrc mod 8) > 0 and size > 0 */
74101 + {
74102 + *p_Dst8++ = *p_Src8++;
74103 + size--;
74104 + }
74105 +
74106 + /* align destination (possibly disaligning source)*/
74107 + while((PTR_TO_UINT(p_Dst8) & 7) && size) /* (pDst mod 8) > 0 and size > 0 */
74108 + {
74109 + *p_Dst8++ = *p_Src8++;
74110 + size--;
74111 + }
74112 +
74113 + /* dest is aligned and source is not necessarily aligned */
74114 + leftAlign = (uint32_t)((PTR_TO_UINT(p_Src8) & 7) << 3); /* leftAlign = (pSrc mod 8)*8 */
74115 + rightAlign = 64 - leftAlign;
74116 +
74117 +
74118 + if (leftAlign == 0)
74119 + {
74120 + /* source is also aligned */
74121 + pSrc64 = (uint64_t*)(p_Src8);
74122 + pDst64 = (uint64_t*)(p_Dst8);
74123 + while (size >> 3) /* size >= 8 */
74124 + {
74125 + *pDst64++ = *pSrc64++;
74126 + size -= 8;
74127 + }
74128 + p_Src8 = (uint8_t*)(pSrc64);
74129 + p_Dst8 = (uint8_t*)(pDst64);
74130 + }
74131 + else
74132 + {
74133 + /* source is not aligned (destination is aligned)*/
74134 + pSrc64 = (uint64_t*)(p_Src8 - (leftAlign >> 3));
74135 + pDst64 = (uint64_t*)(p_Dst8);
74136 + lastWord = *pSrc64++;
74137 + while(size >> 4) /* size >= 16 */
74138 + {
74139 + currWord = *pSrc64;
74140 + *pDst64 = (lastWord << leftAlign) | (currWord >> rightAlign);
74141 + lastWord = currWord;
74142 + pSrc64++;
74143 + pDst64++;
74144 + size -= 8;
74145 + }
74146 + p_Dst8 = (uint8_t*)(pDst64);
74147 + p_Src8 = (uint8_t*)(pSrc64) - 8 + (leftAlign >> 3);
74148 + }
74149 +
74150 + /* complete the left overs */
74151 + while (size--)
74152 + *p_Dst8++ = *p_Src8++;
74153 +
74154 + return pDst;
74155 +}
74156 +
74157 +void * MemSet32(void* pDst, uint8_t val, uint32_t size)
74158 +{
74159 + uint32_t val32;
74160 + uint32_t *p_Dst32;
74161 + uint8_t *p_Dst8;
74162 +
74163 + p_Dst8 = (uint8_t*)(pDst);
74164 +
74165 + /* generate four 8-bit val's in 32-bit container */
74166 + val32 = (uint32_t) val;
74167 + val32 |= (val32 << 8);
74168 + val32 |= (val32 << 16);
74169 +
74170 + /* align destination to 32 */
74171 + while((PTR_TO_UINT(p_Dst8) & 3) && size) /* (pDst mod 4) > 0 and size > 0 */
74172 + {
74173 + *p_Dst8++ = val;
74174 + size--;
74175 + }
74176 +
74177 + /* 32-bit chunks */
74178 + p_Dst32 = (uint32_t*)(p_Dst8);
74179 + while (size >> 2) /* size >= 4 */
74180 + {
74181 + *p_Dst32++ = val32;
74182 + size -= 4;
74183 + }
74184 +
74185 + /* complete the leftovers */
74186 + p_Dst8 = (uint8_t*)(p_Dst32);
74187 + while (size--)
74188 + *p_Dst8++ = val;
74189 +
74190 + return pDst;
74191 +}
74192 +
74193 +void * IOMemSet32(void* pDst, uint8_t val, uint32_t size)
74194 +{
74195 + uint32_t val32;
74196 + uint32_t *p_Dst32;
74197 + uint8_t *p_Dst8;
74198 +
74199 + p_Dst8 = (uint8_t*)(pDst);
74200 +
74201 + /* generate four 8-bit val's in 32-bit container */
74202 + val32 = (uint32_t) val;
74203 + val32 |= (val32 << 8);
74204 + val32 |= (val32 << 16);
74205 +
74206 + /* align destination to 32 */
74207 + while((PTR_TO_UINT(p_Dst8) & 3) && size) /* (pDst mod 4) > 0 and size > 0 */
74208 + {
74209 + WRITE_UINT8(*p_Dst8, val);
74210 + p_Dst8++;
74211 + size--;
74212 + }
74213 +
74214 + /* 32-bit chunks */
74215 + p_Dst32 = (uint32_t*)(p_Dst8);
74216 + while (size >> 2) /* size >= 4 */
74217 + {
74218 + WRITE_UINT32(*p_Dst32, val32);
74219 + p_Dst32++;
74220 + size -= 4;
74221 + }
74222 +
74223 + /* complete the leftovers */
74224 + p_Dst8 = (uint8_t*)(p_Dst32);
74225 + while (size--)
74226 + {
74227 + WRITE_UINT8(*p_Dst8, val);
74228 + p_Dst8++;
74229 + }
74230 +
74231 + return pDst;
74232 +}
74233 +
74234 +void * MemSet64(void* pDst, uint8_t val, uint32_t size)
74235 +{
74236 + uint64_t val64;
74237 + uint64_t *pDst64;
74238 + uint8_t *p_Dst8;
74239 +
74240 + p_Dst8 = (uint8_t*)(pDst);
74241 +
74242 + /* generate four 8-bit val's in 32-bit container */
74243 + val64 = (uint64_t) val;
74244 + val64 |= (val64 << 8);
74245 + val64 |= (val64 << 16);
74246 + val64 |= (val64 << 24);
74247 + val64 |= (val64 << 32);
74248 +
74249 + /* align destination to 64 */
74250 + while((PTR_TO_UINT(p_Dst8) & 7) && size) /* (pDst mod 8) > 0 and size > 0 */
74251 + {
74252 + *p_Dst8++ = val;
74253 + size--;
74254 + }
74255 +
74256 + /* 64-bit chunks */
74257 + pDst64 = (uint64_t*)(p_Dst8);
74258 + while (size >> 4) /* size >= 8 */
74259 + {
74260 + *pDst64++ = val64;
74261 + size -= 8;
74262 + }
74263 +
74264 + /* complete the leftovers */
74265 + p_Dst8 = (uint8_t*)(pDst64);
74266 + while (size--)
74267 + *p_Dst8++ = val;
74268 +
74269 + return pDst;
74270 +}
74271 +
74272 +void MemDisp(uint8_t *p, int size)
74273 +{
74274 + uint32_t space = (uint32_t)(PTR_TO_UINT(p) & 0x3);
74275 + uint8_t *p_Limit;
74276 +
74277 + if (space)
74278 + {
74279 + p_Limit = (p - space + 4);
74280 +
74281 + XX_Print("0x%08X: ", (p - space));
74282 +
74283 + while (space--)
74284 + {
74285 + XX_Print("--");
74286 + }
74287 + while (size && (p < p_Limit))
74288 + {
74289 + XX_Print("%02x", *(uint8_t*)p);
74290 + size--;
74291 + p++;
74292 + }
74293 +
74294 + XX_Print(" ");
74295 + p_Limit += 12;
74296 +
74297 + while ((size > 3) && (p < p_Limit))
74298 + {
74299 + XX_Print("%08x ", *(uint32_t*)p);
74300 + size -= 4;
74301 + p += 4;
74302 + }
74303 + XX_Print("\r\n");
74304 + }
74305 +
74306 + while (size > 15)
74307 + {
74308 + XX_Print("0x%08X: %08x %08x %08x %08x\r\n",
74309 + p, *(uint32_t *)p, *(uint32_t *)(p + 4),
74310 + *(uint32_t *)(p + 8), *(uint32_t *)(p + 12));
74311 + size -= 16;
74312 + p += 16;
74313 + }
74314 +
74315 + if (size)
74316 + {
74317 + XX_Print("0x%08X: ", p);
74318 +
74319 + while (size > 3)
74320 + {
74321 + XX_Print("%08x ", *(uint32_t *)p);
74322 + size -= 4;
74323 + p += 4;
74324 + }
74325 + while (size)
74326 + {
74327 + XX_Print("%02x", *(uint8_t *)p);
74328 + size--;
74329 + p++;
74330 + }
74331 +
74332 + XX_Print("\r\n");
74333 + }
74334 +}
74335 --- /dev/null
74336 +++ b/drivers/net/ethernet/freescale/sdk_fman/etc/mm.c
74337 @@ -0,0 +1,1155 @@
74338 +/*
74339 + * Copyright 2008-2012 Freescale Semiconductor Inc.
74340 + *
74341 + * Redistribution and use in source and binary forms, with or without
74342 + * modification, are permitted provided that the following conditions are met:
74343 + * * Redistributions of source code must retain the above copyright
74344 + * notice, this list of conditions and the following disclaimer.
74345 + * * Redistributions in binary form must reproduce the above copyright
74346 + * notice, this list of conditions and the following disclaimer in the
74347 + * documentation and/or other materials provided with the distribution.
74348 + * * Neither the name of Freescale Semiconductor nor the
74349 + * names of its contributors may be used to endorse or promote products
74350 + * derived from this software without specific prior written permission.
74351 + *
74352 + *
74353 + * ALTERNATIVELY, this software may be distributed under the terms of the
74354 + * GNU General Public License ("GPL") as published by the Free Software
74355 + * Foundation, either version 2 of that License or (at your option) any
74356 + * later version.
74357 + *
74358 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
74359 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
74360 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
74361 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
74362 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
74363 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
74364 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
74365 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
74366 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
74367 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
74368 + */
74369 +
74370 +
74371 +#include "string_ext.h"
74372 +#include "error_ext.h"
74373 +#include "std_ext.h"
74374 +#include "part_ext.h"
74375 +#include "xx_ext.h"
74376 +
74377 +#include "mm.h"
74378 +
74379 +
74380 +
74381 +
74382 +/**********************************************************************
74383 + * MM internal routines set *
74384 + **********************************************************************/
74385 +
74386 +/****************************************************************
74387 + * Routine: CreateBusyBlock
74388 + *
74389 + * Description:
74390 + * Initializes a new busy block of "size" bytes and started
74391 + * rom "base" address. Each busy block has a name that
74392 + * specified the purpose of the memory allocation.
74393 + *
74394 + * Arguments:
74395 + * base - base address of the busy block
74396 + * size - size of the busy block
74397 + * name - name that specified the busy block
74398 + *
74399 + * Return value:
74400 + * A pointer to new created structure returned on success;
74401 + * Otherwise, NULL.
74402 + ****************************************************************/
74403 +static t_BusyBlock * CreateBusyBlock(uint64_t base, uint64_t size, char *name)
74404 +{
74405 + t_BusyBlock *p_BusyBlock;
74406 + uint32_t n;
74407 +
74408 + p_BusyBlock = (t_BusyBlock *)XX_Malloc(sizeof(t_BusyBlock));
74409 + if ( !p_BusyBlock )
74410 + {
74411 + REPORT_ERROR(MAJOR, E_NO_MEMORY, NO_MSG);
74412 + return NULL;
74413 + }
74414 +
74415 + p_BusyBlock->base = base;
74416 + p_BusyBlock->end = base + size;
74417 +
74418 + n = strlen(name);
74419 + if (n >= MM_MAX_NAME_LEN)
74420 + n = MM_MAX_NAME_LEN - 1;
74421 + strncpy(p_BusyBlock->name, name, MM_MAX_NAME_LEN-1);
74422 + p_BusyBlock->name[n] = '\0';
74423 + p_BusyBlock->p_Next = 0;
74424 +
74425 + return p_BusyBlock;
74426 +}
74427 +
74428 +/****************************************************************
74429 + * Routine: CreateNewBlock
74430 + *
74431 + * Description:
74432 + * Initializes a new memory block of "size" bytes and started
74433 + * from "base" address.
74434 + *
74435 + * Arguments:
74436 + * base - base address of the memory block
74437 + * size - size of the memory block
74438 + *
74439 + * Return value:
74440 + * A pointer to new created structure returned on success;
74441 + * Otherwise, NULL.
74442 + ****************************************************************/
74443 +static t_MemBlock * CreateNewBlock(uint64_t base, uint64_t size)
74444 +{
74445 + t_MemBlock *p_MemBlock;
74446 +
74447 + p_MemBlock = (t_MemBlock *)XX_Malloc(sizeof(t_MemBlock));
74448 + if ( !p_MemBlock )
74449 + {
74450 + REPORT_ERROR(MAJOR, E_NO_MEMORY, NO_MSG);
74451 + return NULL;
74452 + }
74453 +
74454 + p_MemBlock->base = base;
74455 + p_MemBlock->end = base+size;
74456 + p_MemBlock->p_Next = 0;
74457 +
74458 + return p_MemBlock;
74459 +}
74460 +
74461 +/****************************************************************
74462 + * Routine: CreateFreeBlock
74463 + *
74464 + * Description:
74465 + * Initializes a new free block of of "size" bytes and
74466 + * started from "base" address.
74467 + *
74468 + * Arguments:
74469 + * base - base address of the free block
74470 + * size - size of the free block
74471 + *
74472 + * Return value:
74473 + * A pointer to new created structure returned on success;
74474 + * Otherwise, NULL.
74475 + ****************************************************************/
74476 +static t_FreeBlock * CreateFreeBlock(uint64_t base, uint64_t size)
74477 +{
74478 + t_FreeBlock *p_FreeBlock;
74479 +
74480 + p_FreeBlock = (t_FreeBlock *)XX_Malloc(sizeof(t_FreeBlock));
74481 + if ( !p_FreeBlock )
74482 + {
74483 + REPORT_ERROR(MAJOR, E_NO_MEMORY, NO_MSG);
74484 + return NULL;
74485 + }
74486 +
74487 + p_FreeBlock->base = base;
74488 + p_FreeBlock->end = base + size;
74489 + p_FreeBlock->p_Next = 0;
74490 +
74491 + return p_FreeBlock;
74492 +}
74493 +
74494 +/****************************************************************
74495 + * Routine: AddFree
74496 + *
74497 + * Description:
74498 + * Adds a new free block to the free lists. It updates each
74499 + * free list to include a new free block.
74500 + * Note, that all free block in each free list are ordered
74501 + * by their base address.
74502 + *
74503 + * Arguments:
74504 + * p_MM - pointer to the MM object
74505 + * base - base address of a given free block
74506 + * end - end address of a given free block
74507 + *
74508 + * Return value:
74509 + *
74510 + *
74511 + ****************************************************************/
74512 +static t_Error AddFree(t_MM *p_MM, uint64_t base, uint64_t end)
74513 +{
74514 + t_FreeBlock *p_PrevB, *p_CurrB, *p_NewB;
74515 + uint64_t alignment;
74516 + uint64_t alignBase;
74517 + int i;
74518 +
74519 + /* Updates free lists to include a just released block */
74520 + for (i=0; i <= MM_MAX_ALIGNMENT; i++)
74521 + {
74522 + p_PrevB = p_NewB = 0;
74523 + p_CurrB = p_MM->freeBlocks[i];
74524 +
74525 + alignment = (uint64_t)(0x1 << i);
74526 + alignBase = MAKE_ALIGNED(base, alignment);
74527 +
74528 + /* Goes to the next free list if there is no block to free */
74529 + if (alignBase >= end)
74530 + continue;
74531 +
74532 + /* Looks for a free block that should be updated */
74533 + while ( p_CurrB )
74534 + {
74535 + if ( alignBase <= p_CurrB->end )
74536 + {
74537 + if ( end > p_CurrB->end )
74538 + {
74539 + t_FreeBlock *p_NextB;
74540 + while ( p_CurrB->p_Next && end > p_CurrB->p_Next->end )
74541 + {
74542 + p_NextB = p_CurrB->p_Next;
74543 + p_CurrB->p_Next = p_CurrB->p_Next->p_Next;
74544 + XX_Free(p_NextB);
74545 + }
74546 +
74547 + p_NextB = p_CurrB->p_Next;
74548 + if ( !p_NextB || (p_NextB && end < p_NextB->base) )
74549 + {
74550 + p_CurrB->end = end;
74551 + }
74552 + else
74553 + {
74554 + p_CurrB->end = p_NextB->end;
74555 + p_CurrB->p_Next = p_NextB->p_Next;
74556 + XX_Free(p_NextB);
74557 + }
74558 + }
74559 + else if ( (end < p_CurrB->base) && ((end-alignBase) >= alignment) )
74560 + {
74561 + if ((p_NewB = CreateFreeBlock(alignBase, end-alignBase)) == NULL)
74562 + RETURN_ERROR(MAJOR, E_NO_MEMORY, NO_MSG);
74563 +
74564 + p_NewB->p_Next = p_CurrB;
74565 + if (p_PrevB)
74566 + p_PrevB->p_Next = p_NewB;
74567 + else
74568 + p_MM->freeBlocks[i] = p_NewB;
74569 + break;
74570 + }
74571 +
74572 + if ((alignBase < p_CurrB->base) && (end >= p_CurrB->base))
74573 + {
74574 + p_CurrB->base = alignBase;
74575 + }
74576 +
74577 + /* if size of the free block is less then alignment
74578 + * deletes that free block from the free list. */
74579 + if ( (p_CurrB->end - p_CurrB->base) < alignment)
74580 + {
74581 + if ( p_PrevB )
74582 + p_PrevB->p_Next = p_CurrB->p_Next;
74583 + else
74584 + p_MM->freeBlocks[i] = p_CurrB->p_Next;
74585 + XX_Free(p_CurrB);
74586 + p_CurrB = NULL;
74587 + }
74588 + break;
74589 + }
74590 + else
74591 + {
74592 + p_PrevB = p_CurrB;
74593 + p_CurrB = p_CurrB->p_Next;
74594 + }
74595 + }
74596 +
74597 + /* If no free block found to be updated, insert a new free block
74598 + * to the end of the free list.
74599 + */
74600 + if ( !p_CurrB && ((((uint64_t)(end-base)) & ((uint64_t)(alignment-1))) == 0) )
74601 + {
74602 + if ((p_NewB = CreateFreeBlock(alignBase, end-base)) == NULL)
74603 + RETURN_ERROR(MAJOR, E_NO_MEMORY, NO_MSG);
74604 +
74605 + if (p_PrevB)
74606 + p_PrevB->p_Next = p_NewB;
74607 + else
74608 + p_MM->freeBlocks[i] = p_NewB;
74609 + }
74610 +
74611 + /* Update boundaries of the new free block */
74612 + if ((alignment == 1) && !p_NewB)
74613 + {
74614 + if ( p_CurrB && base > p_CurrB->base )
74615 + base = p_CurrB->base;
74616 + if ( p_CurrB && end < p_CurrB->end )
74617 + end = p_CurrB->end;
74618 + }
74619 + }
74620 +
74621 + return (E_OK);
74622 +}
74623 +
74624 +/****************************************************************
74625 + * Routine: CutFree
74626 + *
74627 + * Description:
74628 + * Cuts a free block from holdBase to holdEnd from the free lists.
74629 + * That is, it updates all free lists of the MM object do
74630 + * not include a block of memory from holdBase to holdEnd.
74631 + * For each free lists it seek for a free block that holds
74632 + * either holdBase or holdEnd. If such block is found it updates it.
74633 + *
74634 + * Arguments:
74635 + * p_MM - pointer to the MM object
74636 + * holdBase - base address of the allocated block
74637 + * holdEnd - end address of the allocated block
74638 + *
74639 + * Return value:
74640 + * E_OK is returned on success,
74641 + * otherwise returns an error code.
74642 + *
74643 + ****************************************************************/
74644 +static t_Error CutFree(t_MM *p_MM, uint64_t holdBase, uint64_t holdEnd)
74645 +{
74646 + t_FreeBlock *p_PrevB, *p_CurrB, *p_NewB;
74647 + uint64_t alignBase, base, end;
74648 + uint64_t alignment;
74649 + int i;
74650 +
74651 + for (i=0; i <= MM_MAX_ALIGNMENT; i++)
74652 + {
74653 + p_PrevB = p_NewB = 0;
74654 + p_CurrB = p_MM->freeBlocks[i];
74655 +
74656 + alignment = (uint64_t)(0x1 << i);
74657 + alignBase = MAKE_ALIGNED(holdEnd, alignment);
74658 +
74659 + while ( p_CurrB )
74660 + {
74661 + base = p_CurrB->base;
74662 + end = p_CurrB->end;
74663 +
74664 + if ( (holdBase <= base) && (holdEnd <= end) && (holdEnd > base) )
74665 + {
74666 + if ( alignBase >= end ||
74667 + (alignBase < end && ((end-alignBase) < alignment)) )
74668 + {
74669 + if (p_PrevB)
74670 + p_PrevB->p_Next = p_CurrB->p_Next;
74671 + else
74672 + p_MM->freeBlocks[i] = p_CurrB->p_Next;
74673 + XX_Free(p_CurrB);
74674 + }
74675 + else
74676 + {
74677 + p_CurrB->base = alignBase;
74678 + }
74679 + break;
74680 + }
74681 + else if ( (holdBase > base) && (holdEnd <= end) )
74682 + {
74683 + if ( (holdBase-base) >= alignment )
74684 + {
74685 + if ( (alignBase < end) && ((end-alignBase) >= alignment) )
74686 + {
74687 + if ((p_NewB = CreateFreeBlock(alignBase, end-alignBase)) == NULL)
74688 + RETURN_ERROR(MAJOR, E_NO_MEMORY, NO_MSG);
74689 + p_NewB->p_Next = p_CurrB->p_Next;
74690 + p_CurrB->p_Next = p_NewB;
74691 + }
74692 + p_CurrB->end = holdBase;
74693 + }
74694 + else if ( (alignBase < end) && ((end-alignBase) >= alignment) )
74695 + {
74696 + p_CurrB->base = alignBase;
74697 + }
74698 + else
74699 + {
74700 + if (p_PrevB)
74701 + p_PrevB->p_Next = p_CurrB->p_Next;
74702 + else
74703 + p_MM->freeBlocks[i] = p_CurrB->p_Next;
74704 + XX_Free(p_CurrB);
74705 + }
74706 + break;
74707 + }
74708 + else
74709 + {
74710 + p_PrevB = p_CurrB;
74711 + p_CurrB = p_CurrB->p_Next;
74712 + }
74713 + }
74714 + }
74715 +
74716 + return (E_OK);
74717 +}
74718 +
74719 +/****************************************************************
74720 + * Routine: AddBusy
74721 + *
74722 + * Description:
74723 + * Adds a new busy block to the list of busy blocks. Note,
74724 + * that all busy blocks are ordered by their base address in
74725 + * the busy list.
74726 + *
74727 + * Arguments:
74728 + * MM - handler to the MM object
74729 + * p_NewBusyB - pointer to the a busy block
74730 + *
74731 + * Return value:
74732 + * None.
74733 + *
74734 + ****************************************************************/
74735 +static void AddBusy(t_MM *p_MM, t_BusyBlock *p_NewBusyB)
74736 +{
74737 + t_BusyBlock *p_CurrBusyB, *p_PrevBusyB;
74738 +
74739 + /* finds a place of a new busy block in the list of busy blocks */
74740 + p_PrevBusyB = 0;
74741 + p_CurrBusyB = p_MM->busyBlocks;
74742 +
74743 + while ( p_CurrBusyB && p_NewBusyB->base > p_CurrBusyB->base )
74744 + {
74745 + p_PrevBusyB = p_CurrBusyB;
74746 + p_CurrBusyB = p_CurrBusyB->p_Next;
74747 + }
74748 +
74749 + /* insert the new busy block into the list of busy blocks */
74750 + if ( p_CurrBusyB )
74751 + p_NewBusyB->p_Next = p_CurrBusyB;
74752 + if ( p_PrevBusyB )
74753 + p_PrevBusyB->p_Next = p_NewBusyB;
74754 + else
74755 + p_MM->busyBlocks = p_NewBusyB;
74756 +}
74757 +
74758 +/****************************************************************
74759 + * Routine: CutBusy
74760 + *
74761 + * Description:
74762 + * Cuts a block from base to end from the list of busy blocks.
74763 + * This is done by updating the list of busy blocks do not
74764 + * include a given block, that block is going to be free. If a
74765 + * given block is a part of some other busy block, so that
74766 + * busy block is updated. If there are number of busy blocks
74767 + * included in the given block, so all that blocks are removed
74768 + * from the busy list and the end blocks are updated.
74769 + * If the given block devides some block into two parts, a new
74770 + * busy block is added to the busy list.
74771 + *
74772 + * Arguments:
74773 + * p_MM - pointer to the MM object
74774 + * base - base address of a given busy block
74775 + * end - end address of a given busy block
74776 + *
74777 + * Return value:
74778 + * E_OK on success, E_NOMEMORY otherwise.
74779 + *
74780 + ****************************************************************/
74781 +static t_Error CutBusy(t_MM *p_MM, uint64_t base, uint64_t end)
74782 +{
74783 + t_BusyBlock *p_CurrB, *p_PrevB, *p_NewB;
74784 +
74785 + p_CurrB = p_MM->busyBlocks;
74786 + p_PrevB = p_NewB = 0;
74787 +
74788 + while ( p_CurrB )
74789 + {
74790 + if ( base < p_CurrB->end )
74791 + {
74792 + if ( end > p_CurrB->end )
74793 + {
74794 + t_BusyBlock *p_NextB;
74795 + while ( p_CurrB->p_Next && end >= p_CurrB->p_Next->end )
74796 + {
74797 + p_NextB = p_CurrB->p_Next;
74798 + p_CurrB->p_Next = p_CurrB->p_Next->p_Next;
74799 + XX_Free(p_NextB);
74800 + }
74801 +
74802 + p_NextB = p_CurrB->p_Next;
74803 + if ( p_NextB && end > p_NextB->base )
74804 + {
74805 + p_NextB->base = end;
74806 + }
74807 + }
74808 +
74809 + if ( base <= p_CurrB->base )
74810 + {
74811 + if ( end < p_CurrB->end && end > p_CurrB->base )
74812 + {
74813 + p_CurrB->base = end;
74814 + }
74815 + else if ( end >= p_CurrB->end )
74816 + {
74817 + if ( p_PrevB )
74818 + p_PrevB->p_Next = p_CurrB->p_Next;
74819 + else
74820 + p_MM->busyBlocks = p_CurrB->p_Next;
74821 + XX_Free(p_CurrB);
74822 + }
74823 + }
74824 + else
74825 + {
74826 + if ( end < p_CurrB->end && end > p_CurrB->base )
74827 + {
74828 + if ((p_NewB = CreateBusyBlock(end,
74829 + p_CurrB->end-end,
74830 + p_CurrB->name)) == NULL)
74831 + RETURN_ERROR(MAJOR, E_NO_MEMORY, NO_MSG);
74832 + p_NewB->p_Next = p_CurrB->p_Next;
74833 + p_CurrB->p_Next = p_NewB;
74834 + }
74835 + p_CurrB->end = base;
74836 + }
74837 + break;
74838 + }
74839 + else
74840 + {
74841 + p_PrevB = p_CurrB;
74842 + p_CurrB = p_CurrB->p_Next;
74843 + }
74844 + }
74845 +
74846 + return (E_OK);
74847 +}
74848 +
74849 +/****************************************************************
74850 + * Routine: MmGetGreaterAlignment
74851 + *
74852 + * Description:
74853 + * Allocates a block of memory according to the given size
74854 + * and the alignment. That routine is called from the MM_Get
74855 + * routine if the required alignment is greater then MM_MAX_ALIGNMENT.
74856 + * In that case, it goes over free blocks of 64 byte align list
74857 + * and checks if it has the required size of bytes of the required
74858 + * alignment. If no blocks found returns ILLEGAL_BASE.
74859 + * After the block is found and data is allocated, it calls
74860 + * the internal CutFree routine to update all free lists
74861 + * do not include a just allocated block. Of course, each
74862 + * free list contains a free blocks with the same alignment.
74863 + * It is also creates a busy block that holds
74864 + * information about an allocated block.
74865 + *
74866 + * Arguments:
74867 + * MM - handle to the MM object
74868 + * size - size of the MM
74869 + * alignment - index as a power of two defines
74870 + * a required alignment that is greater then 64.
74871 + * name - the name that specifies an allocated block.
74872 + *
74873 + * Return value:
74874 + * base address of an allocated block.
74875 + * ILLEGAL_BASE if can't allocate a block
74876 + *
74877 + ****************************************************************/
74878 +static uint64_t MmGetGreaterAlignment(t_MM *p_MM, uint64_t size, uint64_t alignment, char* name)
74879 +{
74880 + t_FreeBlock *p_FreeB;
74881 + t_BusyBlock *p_NewBusyB;
74882 + uint64_t holdBase, holdEnd, alignBase = 0;
74883 +
74884 + /* goes over free blocks of the 64 byte alignment list
74885 + and look for a block of the suitable size and
74886 + base address according to the alignment. */
74887 + p_FreeB = p_MM->freeBlocks[MM_MAX_ALIGNMENT];
74888 +
74889 + while ( p_FreeB )
74890 + {
74891 + alignBase = MAKE_ALIGNED(p_FreeB->base, alignment);
74892 +
74893 + /* the block is found if the aligned base inside the block
74894 + * and has the anough size. */
74895 + if ( alignBase >= p_FreeB->base &&
74896 + alignBase < p_FreeB->end &&
74897 + size <= (p_FreeB->end - alignBase) )
74898 + break;
74899 + else
74900 + p_FreeB = p_FreeB->p_Next;
74901 + }
74902 +
74903 + /* If such block isn't found */
74904 + if ( !p_FreeB )
74905 + return (uint64_t)(ILLEGAL_BASE);
74906 +
74907 + holdBase = alignBase;
74908 + holdEnd = alignBase + size;
74909 +
74910 + /* init a new busy block */
74911 + if ((p_NewBusyB = CreateBusyBlock(holdBase, size, name)) == NULL)
74912 + return (uint64_t)(ILLEGAL_BASE);
74913 +
74914 + /* calls Update routine to update a lists of free blocks */
74915 + if ( CutFree ( p_MM, holdBase, holdEnd ) != E_OK )
74916 + {
74917 + XX_Free(p_NewBusyB);
74918 + return (uint64_t)(ILLEGAL_BASE);
74919 + }
74920 +
74921 + /* insert the new busy block into the list of busy blocks */
74922 + AddBusy ( p_MM, p_NewBusyB );
74923 +
74924 + return (holdBase);
74925 +}
74926 +
74927 +
74928 +/**********************************************************************
74929 + * MM API routines set *
74930 + **********************************************************************/
74931 +
74932 +/*****************************************************************************/
74933 +t_Error MM_Init(t_Handle *h_MM, uint64_t base, uint64_t size)
74934 +{
74935 + t_MM *p_MM;
74936 + uint64_t newBase, newSize;
74937 + int i;
74938 +
74939 + if (!size)
74940 + {
74941 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Size (should be positive)"));
74942 + }
74943 +
74944 + /* Initializes a new MM object */
74945 + p_MM = (t_MM *)XX_Malloc(sizeof(t_MM));
74946 + if (!p_MM)
74947 + {
74948 + RETURN_ERROR(MAJOR, E_NO_MEMORY, NO_MSG);
74949 + }
74950 +
74951 + p_MM->h_Spinlock = XX_InitSpinlock();
74952 + if (!p_MM->h_Spinlock)
74953 + {
74954 + XX_Free(p_MM);
74955 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("MM spinlock!"));
74956 + }
74957 +
74958 + /* Initializes counter of free memory to total size */
74959 + p_MM->freeMemSize = size;
74960 +
74961 + /* A busy list is empty */
74962 + p_MM->busyBlocks = 0;
74963 +
74964 + /* Initializes a new memory block */
74965 + if ((p_MM->memBlocks = CreateNewBlock(base, size)) == NULL)
74966 + {
74967 + MM_Free(p_MM);
74968 + RETURN_ERROR(MAJOR, E_NO_MEMORY, NO_MSG);
74969 + }
74970 +
74971 + /* Initializes a new free block for each free list*/
74972 + for (i=0; i <= MM_MAX_ALIGNMENT; i++)
74973 + {
74974 + newBase = MAKE_ALIGNED( base, (0x1 << i) );
74975 + newSize = size - (newBase - base);
74976 +
74977 + if ((p_MM->freeBlocks[i] = CreateFreeBlock(newBase, newSize)) == NULL)
74978 + {
74979 + MM_Free(p_MM);
74980 + RETURN_ERROR(MAJOR, E_NO_MEMORY, NO_MSG);
74981 + }
74982 + }
74983 +
74984 + *h_MM = p_MM;
74985 +
74986 + return (E_OK);
74987 +}
74988 +
74989 +/*****************************************************************************/
74990 +void MM_Free(t_Handle h_MM)
74991 +{
74992 + t_MM *p_MM = (t_MM *)h_MM;
74993 + t_MemBlock *p_MemBlock;
74994 + t_BusyBlock *p_BusyBlock;
74995 + t_FreeBlock *p_FreeBlock;
74996 + void *p_Block;
74997 + int i;
74998 +
74999 + ASSERT_COND(p_MM);
75000 +
75001 + /* release memory allocated for busy blocks */
75002 + p_BusyBlock = p_MM->busyBlocks;
75003 + while ( p_BusyBlock )
75004 + {
75005 + p_Block = p_BusyBlock;
75006 + p_BusyBlock = p_BusyBlock->p_Next;
75007 + XX_Free(p_Block);
75008 + }
75009 +
75010 + /* release memory allocated for free blocks */
75011 + for (i=0; i <= MM_MAX_ALIGNMENT; i++)
75012 + {
75013 + p_FreeBlock = p_MM->freeBlocks[i];
75014 + while ( p_FreeBlock )
75015 + {
75016 + p_Block = p_FreeBlock;
75017 + p_FreeBlock = p_FreeBlock->p_Next;
75018 + XX_Free(p_Block);
75019 + }
75020 + }
75021 +
75022 + /* release memory allocated for memory blocks */
75023 + p_MemBlock = p_MM->memBlocks;
75024 + while ( p_MemBlock )
75025 + {
75026 + p_Block = p_MemBlock;
75027 + p_MemBlock = p_MemBlock->p_Next;
75028 + XX_Free(p_Block);
75029 + }
75030 +
75031 + if (p_MM->h_Spinlock)
75032 + XX_FreeSpinlock(p_MM->h_Spinlock);
75033 +
75034 + /* release memory allocated for MM object itself */
75035 + XX_Free(p_MM);
75036 +}
75037 +
75038 +/*****************************************************************************/
75039 +uint64_t MM_Get(t_Handle h_MM, uint64_t size, uint64_t alignment, char* name)
75040 +{
75041 + t_MM *p_MM = (t_MM *)h_MM;
75042 + t_FreeBlock *p_FreeB;
75043 + t_BusyBlock *p_NewBusyB;
75044 + uint64_t holdBase, holdEnd, j, i = 0;
75045 + uint32_t intFlags;
75046 +
75047 + SANITY_CHECK_RETURN_VALUE(p_MM, E_INVALID_HANDLE, (uint64_t)ILLEGAL_BASE);
75048 +
75049 + /* checks that alignment value is greater then zero */
75050 + if (alignment == 0)
75051 + {
75052 + alignment = 1;
75053 + }
75054 +
75055 + j = alignment;
75056 +
75057 + /* checks if alignment is a power of two, if it correct and if the
75058 + required size is multiple of the given alignment. */
75059 + while ((j & 0x1) == 0)
75060 + {
75061 + i++;
75062 + j = j >> 1;
75063 + }
75064 +
75065 + /* if the given alignment isn't power of two, returns an error */
75066 + if (j != 1)
75067 + {
75068 + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("alignment (should be power of 2)"));
75069 + return (uint64_t)ILLEGAL_BASE;
75070 + }
75071 +
75072 + if (i > MM_MAX_ALIGNMENT)
75073 + {
75074 + return (MmGetGreaterAlignment(p_MM, size, alignment, name));
75075 + }
75076 +
75077 + intFlags = XX_LockIntrSpinlock(p_MM->h_Spinlock);
75078 + /* look for a block of the size greater or equal to the required size. */
75079 + p_FreeB = p_MM->freeBlocks[i];
75080 + while ( p_FreeB && (p_FreeB->end - p_FreeB->base) < size )
75081 + p_FreeB = p_FreeB->p_Next;
75082 +
75083 + /* If such block is found */
75084 + if ( !p_FreeB )
75085 + {
75086 + XX_UnlockIntrSpinlock(p_MM->h_Spinlock, intFlags);
75087 + return (uint64_t)(ILLEGAL_BASE);
75088 + }
75089 +
75090 + holdBase = p_FreeB->base;
75091 + holdEnd = holdBase + size;
75092 +
75093 + /* init a new busy block */
75094 + if ((p_NewBusyB = CreateBusyBlock(holdBase, size, name)) == NULL)
75095 + {
75096 + XX_UnlockIntrSpinlock(p_MM->h_Spinlock, intFlags);
75097 + return (uint64_t)(ILLEGAL_BASE);
75098 + }
75099 +
75100 + /* calls Update routine to update a lists of free blocks */
75101 + if ( CutFree ( p_MM, holdBase, holdEnd ) != E_OK )
75102 + {
75103 + XX_UnlockIntrSpinlock(p_MM->h_Spinlock, intFlags);
75104 + XX_Free(p_NewBusyB);
75105 + return (uint64_t)(ILLEGAL_BASE);
75106 + }
75107 +
75108 + /* Decreasing the allocated memory size from free memory size */
75109 + p_MM->freeMemSize -= size;
75110 +
75111 + /* insert the new busy block into the list of busy blocks */
75112 + AddBusy ( p_MM, p_NewBusyB );
75113 + XX_UnlockIntrSpinlock(p_MM->h_Spinlock, intFlags);
75114 +
75115 + return (holdBase);
75116 +}
75117 +
75118 +/*****************************************************************************/
75119 +uint64_t MM_GetForce(t_Handle h_MM, uint64_t base, uint64_t size, char* name)
75120 +{
75121 + t_MM *p_MM = (t_MM *)h_MM;
75122 + t_FreeBlock *p_FreeB;
75123 + t_BusyBlock *p_NewBusyB;
75124 + uint32_t intFlags;
75125 + bool blockIsFree = FALSE;
75126 +
75127 + ASSERT_COND(p_MM);
75128 +
75129 + intFlags = XX_LockIntrSpinlock(p_MM->h_Spinlock);
75130 + p_FreeB = p_MM->freeBlocks[0]; /* The biggest free blocks are in the
75131 + free list with alignment 1 */
75132 +
75133 + while ( p_FreeB )
75134 + {
75135 + if ( base >= p_FreeB->base && (base+size) <= p_FreeB->end )
75136 + {
75137 + blockIsFree = TRUE;
75138 + break;
75139 + }
75140 + else
75141 + p_FreeB = p_FreeB->p_Next;
75142 + }
75143 +
75144 + if ( !blockIsFree )
75145 + {
75146 + XX_UnlockIntrSpinlock(p_MM->h_Spinlock, intFlags);
75147 + return (uint64_t)(ILLEGAL_BASE);
75148 + }
75149 +
75150 + /* init a new busy block */
75151 + if ((p_NewBusyB = CreateBusyBlock(base, size, name)) == NULL)
75152 + {
75153 + XX_UnlockIntrSpinlock(p_MM->h_Spinlock, intFlags);
75154 + return (uint64_t)(ILLEGAL_BASE);
75155 + }
75156 +
75157 + /* calls Update routine to update a lists of free blocks */
75158 + if ( CutFree ( p_MM, base, base+size ) != E_OK )
75159 + {
75160 + XX_UnlockIntrSpinlock(p_MM->h_Spinlock, intFlags);
75161 + XX_Free(p_NewBusyB);
75162 + return (uint64_t)(ILLEGAL_BASE);
75163 + }
75164 +
75165 + /* Decreasing the allocated memory size from free memory size */
75166 + p_MM->freeMemSize -= size;
75167 +
75168 + /* insert the new busy block into the list of busy blocks */
75169 + AddBusy ( p_MM, p_NewBusyB );
75170 + XX_UnlockIntrSpinlock(p_MM->h_Spinlock, intFlags);
75171 +
75172 + return (base);
75173 +}
75174 +
75175 +/*****************************************************************************/
75176 +uint64_t MM_GetForceMin(t_Handle h_MM, uint64_t size, uint64_t alignment, uint64_t min, char* name)
75177 +{
75178 + t_MM *p_MM = (t_MM *)h_MM;
75179 + t_FreeBlock *p_FreeB;
75180 + t_BusyBlock *p_NewBusyB;
75181 + uint64_t holdBase, holdEnd, j = alignment, i=0;
75182 + uint32_t intFlags;
75183 +
75184 + ASSERT_COND(p_MM);
75185 +
75186 + /* checks if alignment is a power of two, if it correct and if the
75187 + required size is multiple of the given alignment. */
75188 + while ((j & 0x1) == 0)
75189 + {
75190 + i++;
75191 + j = j >> 1;
75192 + }
75193 +
75194 + if ( (j != 1) || (i > MM_MAX_ALIGNMENT) )
75195 + {
75196 + return (uint64_t)(ILLEGAL_BASE);
75197 + }
75198 +
75199 + intFlags = XX_LockIntrSpinlock(p_MM->h_Spinlock);
75200 + p_FreeB = p_MM->freeBlocks[i];
75201 +
75202 + /* look for the first block that contains the minimum
75203 + base address. If the whole required size may be fit
75204 + into it, use that block, otherwise look for the next
75205 + block of size greater or equal to the required size. */
75206 + while ( p_FreeB && (min >= p_FreeB->end))
75207 + p_FreeB = p_FreeB->p_Next;
75208 +
75209 + /* If such block is found */
75210 + if ( !p_FreeB )
75211 + {
75212 + XX_UnlockIntrSpinlock(p_MM->h_Spinlock, intFlags);
75213 + return (uint64_t)(ILLEGAL_BASE);
75214 + }
75215 +
75216 + /* if this block is large enough, use this block */
75217 + holdBase = ( min <= p_FreeB->base ) ? p_FreeB->base : min;
75218 + if ((holdBase + size) <= p_FreeB->end )
75219 + {
75220 + holdEnd = holdBase + size;
75221 + }
75222 + else
75223 + {
75224 + p_FreeB = p_FreeB->p_Next;
75225 + while ( p_FreeB && ((p_FreeB->end - p_FreeB->base) < size) )
75226 + p_FreeB = p_FreeB->p_Next;
75227 +
75228 + /* If such block is found */
75229 + if ( !p_FreeB )
75230 + {
75231 + XX_UnlockIntrSpinlock(p_MM->h_Spinlock, intFlags);
75232 + return (uint64_t)(ILLEGAL_BASE);
75233 + }
75234 +
75235 + holdBase = p_FreeB->base;
75236 + holdEnd = holdBase + size;
75237 + }
75238 +
75239 + /* init a new busy block */
75240 + if ((p_NewBusyB = CreateBusyBlock(holdBase, size, name)) == NULL)
75241 + {
75242 + XX_UnlockIntrSpinlock(p_MM->h_Spinlock, intFlags);
75243 + return (uint64_t)(ILLEGAL_BASE);
75244 + }
75245 +
75246 + /* calls Update routine to update a lists of free blocks */
75247 + if ( CutFree( p_MM, holdBase, holdEnd ) != E_OK )
75248 + {
75249 + XX_UnlockIntrSpinlock(p_MM->h_Spinlock, intFlags);
75250 + XX_Free(p_NewBusyB);
75251 + return (uint64_t)(ILLEGAL_BASE);
75252 + }
75253 +
75254 + /* Decreasing the allocated memory size from free memory size */
75255 + p_MM->freeMemSize -= size;
75256 +
75257 + /* insert the new busy block into the list of busy blocks */
75258 + AddBusy( p_MM, p_NewBusyB );
75259 + XX_UnlockIntrSpinlock(p_MM->h_Spinlock, intFlags);
75260 +
75261 + return (holdBase);
75262 +}
75263 +
75264 +/*****************************************************************************/
75265 +uint64_t MM_Put(t_Handle h_MM, uint64_t base)
75266 +{
75267 + t_MM *p_MM = (t_MM *)h_MM;
75268 + t_BusyBlock *p_BusyB, *p_PrevBusyB;
75269 + uint64_t size;
75270 + uint32_t intFlags;
75271 +
75272 + ASSERT_COND(p_MM);
75273 +
75274 + /* Look for a busy block that have the given base value.
75275 + * That block will be returned back to the memory.
75276 + */
75277 + p_PrevBusyB = 0;
75278 +
75279 + intFlags = XX_LockIntrSpinlock(p_MM->h_Spinlock);
75280 + p_BusyB = p_MM->busyBlocks;
75281 + while ( p_BusyB && base != p_BusyB->base )
75282 + {
75283 + p_PrevBusyB = p_BusyB;
75284 + p_BusyB = p_BusyB->p_Next;
75285 + }
75286 +
75287 + if ( !p_BusyB )
75288 + {
75289 + XX_UnlockIntrSpinlock(p_MM->h_Spinlock, intFlags);
75290 + return (uint64_t)(0);
75291 + }
75292 +
75293 + if ( AddFree( p_MM, p_BusyB->base, p_BusyB->end ) != E_OK )
75294 + {
75295 + XX_UnlockIntrSpinlock(p_MM->h_Spinlock, intFlags);
75296 + return (uint64_t)(0);
75297 + }
75298 +
75299 + /* removes a busy block form the list of busy blocks */
75300 + if ( p_PrevBusyB )
75301 + p_PrevBusyB->p_Next = p_BusyB->p_Next;
75302 + else
75303 + p_MM->busyBlocks = p_BusyB->p_Next;
75304 +
75305 + size = p_BusyB->end - p_BusyB->base;
75306 +
75307 + /* Adding the deallocated memory size to free memory size */
75308 + p_MM->freeMemSize += size;
75309 +
75310 + XX_Free(p_BusyB);
75311 + XX_UnlockIntrSpinlock(p_MM->h_Spinlock, intFlags);
75312 +
75313 + return (size);
75314 +}
75315 +
75316 +/*****************************************************************************/
75317 +uint64_t MM_PutForce(t_Handle h_MM, uint64_t base, uint64_t size)
75318 +{
75319 + t_MM *p_MM = (t_MM *)h_MM;
75320 + uint64_t end = base + size;
75321 + uint32_t intFlags;
75322 +
75323 + ASSERT_COND(p_MM);
75324 +
75325 + intFlags = XX_LockIntrSpinlock(p_MM->h_Spinlock);
75326 +
75327 + if ( CutBusy( p_MM, base, end ) != E_OK )
75328 + {
75329 + XX_UnlockIntrSpinlock(p_MM->h_Spinlock, intFlags);
75330 + return (uint64_t)(0);
75331 + }
75332 +
75333 + if ( AddFree ( p_MM, base, end ) != E_OK )
75334 + {
75335 + XX_UnlockIntrSpinlock(p_MM->h_Spinlock, intFlags);
75336 + return (uint64_t)(0);
75337 + }
75338 +
75339 + /* Adding the deallocated memory size to free memory size */
75340 + p_MM->freeMemSize += size;
75341 +
75342 + XX_UnlockIntrSpinlock(p_MM->h_Spinlock, intFlags);
75343 +
75344 + return (size);
75345 +}
75346 +
75347 +/*****************************************************************************/
75348 +t_Error MM_Add(t_Handle h_MM, uint64_t base, uint64_t size)
75349 +{
75350 + t_MM *p_MM = (t_MM *)h_MM;
75351 + t_MemBlock *p_MemB, *p_NewMemB;
75352 + t_Error errCode;
75353 + uint32_t intFlags;
75354 +
75355 + ASSERT_COND(p_MM);
75356 +
75357 + /* find a last block in the list of memory blocks to insert a new
75358 + * memory block
75359 + */
75360 + intFlags = XX_LockIntrSpinlock(p_MM->h_Spinlock);
75361 +
75362 + p_MemB = p_MM->memBlocks;
75363 + while ( p_MemB->p_Next )
75364 + {
75365 + if ( base >= p_MemB->base && base < p_MemB->end )
75366 + {
75367 + XX_UnlockIntrSpinlock(p_MM->h_Spinlock, intFlags);
75368 + RETURN_ERROR(MAJOR, E_ALREADY_EXISTS, NO_MSG);
75369 + }
75370 + p_MemB = p_MemB->p_Next;
75371 + }
75372 + /* check for a last memory block */
75373 + if ( base >= p_MemB->base && base < p_MemB->end )
75374 + {
75375 + XX_UnlockIntrSpinlock(p_MM->h_Spinlock, intFlags);
75376 + RETURN_ERROR(MAJOR, E_ALREADY_EXISTS, NO_MSG);
75377 + }
75378 +
75379 + /* create a new memory block */
75380 + if ((p_NewMemB = CreateNewBlock(base, size)) == NULL)
75381 + {
75382 + XX_UnlockIntrSpinlock(p_MM->h_Spinlock, intFlags);
75383 + RETURN_ERROR(MAJOR, E_NO_MEMORY, NO_MSG);
75384 + }
75385 +
75386 + /* append a new memory block to the end of the list of memory blocks */
75387 + p_MemB->p_Next = p_NewMemB;
75388 +
75389 + /* add a new free block to the free lists */
75390 + errCode = AddFree(p_MM, base, base+size);
75391 + if (errCode)
75392 + {
75393 + XX_UnlockIntrSpinlock(p_MM->h_Spinlock, intFlags);
75394 + p_MemB->p_Next = 0;
75395 + XX_Free(p_NewMemB);
75396 + return ((t_Error)errCode);
75397 + }
75398 +
75399 + /* Adding the new block size to free memory size */
75400 + p_MM->freeMemSize += size;
75401 +
75402 + XX_UnlockIntrSpinlock(p_MM->h_Spinlock, intFlags);
75403 +
75404 + return (E_OK);
75405 +}
75406 +
75407 +/*****************************************************************************/
75408 +uint64_t MM_GetMemBlock(t_Handle h_MM, int index)
75409 +{
75410 + t_MM *p_MM = (t_MM*)h_MM;
75411 + t_MemBlock *p_MemBlock;
75412 + int i;
75413 +
75414 + ASSERT_COND(p_MM);
75415 +
75416 + p_MemBlock = p_MM->memBlocks;
75417 + for (i=0; i < index; i++)
75418 + p_MemBlock = p_MemBlock->p_Next;
75419 +
75420 + if ( p_MemBlock )
75421 + return (p_MemBlock->base);
75422 + else
75423 + return (uint64_t)ILLEGAL_BASE;
75424 +}
75425 +
75426 +/*****************************************************************************/
75427 +uint64_t MM_GetBase(t_Handle h_MM)
75428 +{
75429 + t_MM *p_MM = (t_MM*)h_MM;
75430 + t_MemBlock *p_MemBlock;
75431 +
75432 + ASSERT_COND(p_MM);
75433 +
75434 + p_MemBlock = p_MM->memBlocks;
75435 + return p_MemBlock->base;
75436 +}
75437 +
75438 +/*****************************************************************************/
75439 +bool MM_InRange(t_Handle h_MM, uint64_t addr)
75440 +{
75441 + t_MM *p_MM = (t_MM*)h_MM;
75442 + t_MemBlock *p_MemBlock;
75443 +
75444 + ASSERT_COND(p_MM);
75445 +
75446 + p_MemBlock = p_MM->memBlocks;
75447 +
75448 + if ((addr >= p_MemBlock->base) && (addr < p_MemBlock->end))
75449 + return TRUE;
75450 + else
75451 + return FALSE;
75452 +}
75453 +
75454 +/*****************************************************************************/
75455 +uint64_t MM_GetFreeMemSize(t_Handle h_MM)
75456 +{
75457 + t_MM *p_MM = (t_MM*)h_MM;
75458 +
75459 + ASSERT_COND(p_MM);
75460 +
75461 + return p_MM->freeMemSize;
75462 +}
75463 +
75464 +/*****************************************************************************/
75465 +void MM_Dump(t_Handle h_MM)
75466 +{
75467 + t_MM *p_MM = (t_MM *)h_MM;
75468 + t_FreeBlock *p_FreeB;
75469 + t_BusyBlock *p_BusyB;
75470 + int i;
75471 +
75472 + p_BusyB = p_MM->busyBlocks;
75473 + XX_Print("List of busy blocks:\n");
75474 + while (p_BusyB)
75475 + {
75476 + XX_Print("\t0x%p: (%s: b=0x%llx, e=0x%llx)\n", p_BusyB, p_BusyB->name, p_BusyB->base, p_BusyB->end );
75477 + p_BusyB = p_BusyB->p_Next;
75478 + }
75479 +
75480 + XX_Print("\nLists of free blocks according to alignment:\n");
75481 + for (i=0; i <= MM_MAX_ALIGNMENT; i++)
75482 + {
75483 + XX_Print("%d alignment:\n", (0x1 << i));
75484 + p_FreeB = p_MM->freeBlocks[i];
75485 + while (p_FreeB)
75486 + {
75487 + XX_Print("\t0x%p: (b=0x%llx, e=0x%llx)\n", p_FreeB, p_FreeB->base, p_FreeB->end);
75488 + p_FreeB = p_FreeB->p_Next;
75489 + }
75490 + XX_Print("\n");
75491 + }
75492 +}
75493 --- /dev/null
75494 +++ b/drivers/net/ethernet/freescale/sdk_fman/etc/mm.h
75495 @@ -0,0 +1,105 @@
75496 +/*
75497 + * Copyright 2008-2012 Freescale Semiconductor Inc.
75498 + *
75499 + * Redistribution and use in source and binary forms, with or without
75500 + * modification, are permitted provided that the following conditions are met:
75501 + * * Redistributions of source code must retain the above copyright
75502 + * notice, this list of conditions and the following disclaimer.
75503 + * * Redistributions in binary form must reproduce the above copyright
75504 + * notice, this list of conditions and the following disclaimer in the
75505 + * documentation and/or other materials provided with the distribution.
75506 + * * Neither the name of Freescale Semiconductor nor the
75507 + * names of its contributors may be used to endorse or promote products
75508 + * derived from this software without specific prior written permission.
75509 + *
75510 + *
75511 + * ALTERNATIVELY, this software may be distributed under the terms of the
75512 + * GNU General Public License ("GPL") as published by the Free Software
75513 + * Foundation, either version 2 of that License or (at your option) any
75514 + * later version.
75515 + *
75516 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
75517 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
75518 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
75519 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
75520 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
75521 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
75522 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
75523 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
75524 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
75525 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
75526 + */
75527 +
75528 +
75529 +/****************************************************************
75530 + *
75531 + * File: mm.h
75532 + *
75533 + *
75534 + * Description:
75535 + * MM (Memory Management) object definitions.
75536 + * It also includes definitions of the Free Block, Busy Block
75537 + * and Memory Block structures used by the MM object.
75538 + *
75539 + ****************************************************************/
75540 +
75541 +#ifndef __MM_H
75542 +#define __MM_H
75543 +
75544 +
75545 +#include "mm_ext.h"
75546 +
75547 +#define __ERR_MODULE__ MODULE_MM
75548 +
75549 +
75550 +#define MAKE_ALIGNED(addr, align) \
75551 + (((uint64_t)(addr) + ((align) - 1)) & (~(((uint64_t)align) - 1)))
75552 +
75553 +
75554 +/* t_MemBlock data structure defines parameters of the Memory Block */
75555 +typedef struct t_MemBlock
75556 +{
75557 + struct t_MemBlock *p_Next; /* Pointer to the next memory block */
75558 +
75559 + uint64_t base; /* Base address of the memory block */
75560 + uint64_t end; /* End address of the memory block */
75561 +} t_MemBlock;
75562 +
75563 +
75564 +/* t_FreeBlock data structure defines parameters of the Free Block */
75565 +typedef struct t_FreeBlock
75566 +{
75567 + struct t_FreeBlock *p_Next; /* Pointer to the next free block */
75568 +
75569 + uint64_t base; /* Base address of the block */
75570 + uint64_t end; /* End address of the block */
75571 +} t_FreeBlock;
75572 +
75573 +
75574 +/* t_BusyBlock data structure defines parameters of the Busy Block */
75575 +typedef struct t_BusyBlock
75576 +{
75577 + struct t_BusyBlock *p_Next; /* Pointer to the next free block */
75578 +
75579 + uint64_t base; /* Base address of the block */
75580 + uint64_t end; /* End address of the block */
75581 + char name[MM_MAX_NAME_LEN]; /* That block of memory was allocated for
75582 + something specified by the Name */
75583 +} t_BusyBlock;
75584 +
75585 +
75586 +/* t_MM data structure defines parameters of the MM object */
75587 +typedef struct t_MM
75588 +{
75589 + t_Handle h_Spinlock;
75590 +
75591 + t_MemBlock *memBlocks; /* List of memory blocks (Memory list) */
75592 + t_BusyBlock *busyBlocks; /* List of busy blocks (Busy list) */
75593 + t_FreeBlock *freeBlocks[MM_MAX_ALIGNMENT + 1];
75594 + /* Alignment lists of free blocks (Free lists) */
75595 +
75596 + uint64_t freeMemSize; /* Total size of free memory (in bytes) */
75597 +} t_MM;
75598 +
75599 +
75600 +#endif /* __MM_H */
75601 --- /dev/null
75602 +++ b/drivers/net/ethernet/freescale/sdk_fman/etc/sprint.c
75603 @@ -0,0 +1,81 @@
75604 +/*
75605 + * Copyright 2008-2012 Freescale Semiconductor Inc.
75606 + *
75607 + * Redistribution and use in source and binary forms, with or without
75608 + * modification, are permitted provided that the following conditions are met:
75609 + * * Redistributions of source code must retain the above copyright
75610 + * notice, this list of conditions and the following disclaimer.
75611 + * * Redistributions in binary form must reproduce the above copyright
75612 + * notice, this list of conditions and the following disclaimer in the
75613 + * documentation and/or other materials provided with the distribution.
75614 + * * Neither the name of Freescale Semiconductor nor the
75615 + * names of its contributors may be used to endorse or promote products
75616 + * derived from this software without specific prior written permission.
75617 + *
75618 + *
75619 + * ALTERNATIVELY, this software may be distributed under the terms of the
75620 + * GNU General Public License ("GPL") as published by the Free Software
75621 + * Foundation, either version 2 of that License or (at your option) any
75622 + * later version.
75623 + *
75624 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
75625 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
75626 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
75627 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
75628 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
75629 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
75630 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
75631 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
75632 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
75633 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
75634 + */
75635 +
75636 +
75637 +/*------------------------------------------------------*/
75638 +/* File: sprint.c */
75639 +/* */
75640 +/* Description: */
75641 +/* Debug routines (externals) */
75642 +/*------------------------------------------------------*/
75643 +#include "string_ext.h"
75644 +#include "stdlib_ext.h"
75645 +#include "stdarg_ext.h"
75646 +#include "sprint_ext.h"
75647 +#include "std_ext.h"
75648 +#include "xx_ext.h"
75649 +
75650 +
75651 +int Sprint(char * buf, const char *fmt, ...)
75652 +{
75653 + va_list args;
75654 + int i;
75655 +
75656 + va_start(args, fmt);
75657 + i=vsprintf(buf,fmt,args);
75658 + va_end(args);
75659 + return i;
75660 +}
75661 +
75662 +int Snprint(char * buf, uint32_t size, const char *fmt, ...)
75663 +{
75664 + va_list args;
75665 + int i;
75666 +
75667 + va_start(args, fmt);
75668 + i=vsnprintf(buf,size,fmt,args);
75669 + va_end(args);
75670 + return i;
75671 +}
75672 +
75673 +#ifndef NCSW_VXWORKS
75674 +int Sscan(const char * buf, const char * fmt, ...)
75675 +{
75676 + va_list args;
75677 + int i;
75678 +
75679 + va_start(args,fmt);
75680 + i = vsscanf(buf,fmt,args);
75681 + va_end(args);
75682 + return i;
75683 +}
75684 +#endif /* NCSW_VXWORKS */
75685 --- /dev/null
75686 +++ b/drivers/net/ethernet/freescale/sdk_fman/fmanv3h_dflags.h
75687 @@ -0,0 +1,57 @@
75688 +/*
75689 + * Copyright 2012 Freescale Semiconductor Inc.
75690 + *
75691 + * Redistribution and use in source and binary forms, with or without
75692 + * modification, are permitted provided that the following conditions are met:
75693 + * * Redistributions of source code must retain the above copyright
75694 + * notice, this list of conditions and the following disclaimer.
75695 + * * Redistributions in binary form must reproduce the above copyright
75696 + * notice, this list of conditions and the following disclaimer in the
75697 + * documentation and/or other materials provided with the distribution.
75698 + * * Neither the name of Freescale Semiconductor nor the
75699 + * names of its contributors may be used to endorse or promote products
75700 + * derived from this software without specific prior written permission.
75701 + *
75702 + *
75703 + * ALTERNATIVELY, this software may be distributed under the terms of the
75704 + * GNU General Public License ("GPL") as published by the Free Software
75705 + * Foundation, either version 2 of that License or (at your option) any
75706 + * later version.
75707 + *
75708 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
75709 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
75710 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
75711 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
75712 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
75713 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
75714 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
75715 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
75716 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
75717 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
75718 + */
75719 +
75720 +#ifndef __dflags_h
75721 +#define __dflags_h
75722 +
75723 +
75724 +#define NCSW_LINUX
75725 +
75726 +#define T4240
75727 +#define NCSW_PPC_CORE
75728 +
75729 +#define DEBUG_ERRORS 1
75730 +
75731 +#if defined(DEBUG)
75732 +#define DEBUG_GLOBAL_LEVEL REPORT_LEVEL_INFO
75733 +
75734 +#define DEBUG_XX_MALLOC
75735 +#define DEBUG_MEM_LEAKS
75736 +
75737 +#else
75738 +#define DEBUG_GLOBAL_LEVEL REPORT_LEVEL_WARNING
75739 +#endif /* (DEBUG) */
75740 +
75741 +#define REPORT_EVENTS 1
75742 +#define EVENT_GLOBAL_LEVEL REPORT_LEVEL_MINOR
75743 +
75744 +#endif /* __dflags_h */
75745 --- /dev/null
75746 +++ b/drivers/net/ethernet/freescale/sdk_fman/fmanv3l_dflags.h
75747 @@ -0,0 +1,56 @@
75748 +/*
75749 + * Copyright 2012 Freescale Semiconductor Inc.
75750 + *
75751 + * Redistribution and use in source and binary forms, with or without
75752 + * modification, are permitted provided that the following conditions are met:
75753 + * * Redistributions of source code must retain the above copyright
75754 + * notice, this list of conditions and the following disclaimer.
75755 + * * Redistributions in binary form must reproduce the above copyright
75756 + * notice, this list of conditions and the following disclaimer in the
75757 + * documentation and/or other materials provided with the distribution.
75758 + * * Neither the name of Freescale Semiconductor nor the
75759 + * names of its contributors may be used to endorse or promote products
75760 + * derived from this software without specific prior written permission.
75761 + *
75762 + *
75763 + * ALTERNATIVELY, this software may be distributed under the terms of the
75764 + * GNU General Public License ("GPL") as published by the Free Software
75765 + * Foundation, either version 2 of that License or (at your option) any
75766 + * later version.
75767 + *
75768 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
75769 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
75770 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
75771 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
75772 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
75773 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
75774 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
75775 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
75776 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
75777 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
75778 + */
75779 +
75780 +#ifndef __dflags_h
75781 +#define __dflags_h
75782 +
75783 +
75784 +#define NCSW_LINUX
75785 +
75786 +#define NCSW_PPC_CORE
75787 +
75788 +#define DEBUG_ERRORS 1
75789 +
75790 +#if defined(DEBUG)
75791 +#define DEBUG_GLOBAL_LEVEL REPORT_LEVEL_INFO
75792 +
75793 +#define DEBUG_XX_MALLOC
75794 +#define DEBUG_MEM_LEAKS
75795 +
75796 +#else
75797 +#define DEBUG_GLOBAL_LEVEL REPORT_LEVEL_WARNING
75798 +#endif /* (DEBUG) */
75799 +
75800 +#define REPORT_EVENTS 1
75801 +#define EVENT_GLOBAL_LEVEL REPORT_LEVEL_MINOR
75802 +
75803 +#endif /* __dflags_h */
75804 --- /dev/null
75805 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/Peripherals/crc_mac_addr_ext.h
75806 @@ -0,0 +1,364 @@
75807 +/*
75808 + * Copyright 2008-2012 Freescale Semiconductor Inc.
75809 + *
75810 + * Redistribution and use in source and binary forms, with or without
75811 + * modification, are permitted provided that the following conditions are met:
75812 + * * Redistributions of source code must retain the above copyright
75813 + * notice, this list of conditions and the following disclaimer.
75814 + * * Redistributions in binary form must reproduce the above copyright
75815 + * notice, this list of conditions and the following disclaimer in the
75816 + * documentation and/or other materials provided with the distribution.
75817 + * * Neither the name of Freescale Semiconductor nor the
75818 + * names of its contributors may be used to endorse or promote products
75819 + * derived from this software without specific prior written permission.
75820 + *
75821 + *
75822 + * ALTERNATIVELY, this software may be distributed under the terms of the
75823 + * GNU General Public License ("GPL") as published by the Free Software
75824 + * Foundation, either version 2 of that License or (at your option) any
75825 + * later version.
75826 + *
75827 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
75828 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
75829 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
75830 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
75831 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
75832 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
75833 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
75834 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
75835 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
75836 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
75837 + */
75838 +
75839 +
75840 +/*------------------------------------------------------*/
75841 +/* */
75842 +/* File: crc_mac_addr_ext.h */
75843 +/* */
75844 +/* Description: */
75845 +/* Define a macro that calculate the crc value of */
75846 +/* an Ethernet MAC address (48 bitd address */
75847 +/*------------------------------------------------------*/
75848 +
75849 +#ifndef __crc_mac_addr_ext_h
75850 +#define __crc_mac_addr_ext_h
75851 +
75852 +#include "std_ext.h"
75853 +
75854 +
75855 +static uint32_t crc_table[256] =
75856 +{
75857 + 0x00000000,
75858 + 0x77073096,
75859 + 0xee0e612c,
75860 + 0x990951ba,
75861 + 0x076dc419,
75862 + 0x706af48f,
75863 + 0xe963a535,
75864 + 0x9e6495a3,
75865 + 0x0edb8832,
75866 + 0x79dcb8a4,
75867 + 0xe0d5e91e,
75868 + 0x97d2d988,
75869 + 0x09b64c2b,
75870 + 0x7eb17cbd,
75871 + 0xe7b82d07,
75872 + 0x90bf1d91,
75873 + 0x1db71064,
75874 + 0x6ab020f2,
75875 + 0xf3b97148,
75876 + 0x84be41de,
75877 + 0x1adad47d,
75878 + 0x6ddde4eb,
75879 + 0xf4d4b551,
75880 + 0x83d385c7,
75881 + 0x136c9856,
75882 + 0x646ba8c0,
75883 + 0xfd62f97a,
75884 + 0x8a65c9ec,
75885 + 0x14015c4f,
75886 + 0x63066cd9,
75887 + 0xfa0f3d63,
75888 + 0x8d080df5,
75889 + 0x3b6e20c8,
75890 + 0x4c69105e,
75891 + 0xd56041e4,
75892 + 0xa2677172,
75893 + 0x3c03e4d1,
75894 + 0x4b04d447,
75895 + 0xd20d85fd,
75896 + 0xa50ab56b,
75897 + 0x35b5a8fa,
75898 + 0x42b2986c,
75899 + 0xdbbbc9d6,
75900 + 0xacbcf940,
75901 + 0x32d86ce3,
75902 + 0x45df5c75,
75903 + 0xdcd60dcf,
75904 + 0xabd13d59,
75905 + 0x26d930ac,
75906 + 0x51de003a,
75907 + 0xc8d75180,
75908 + 0xbfd06116,
75909 + 0x21b4f4b5,
75910 + 0x56b3c423,
75911 + 0xcfba9599,
75912 + 0xb8bda50f,
75913 + 0x2802b89e,
75914 + 0x5f058808,
75915 + 0xc60cd9b2,
75916 + 0xb10be924,
75917 + 0x2f6f7c87,
75918 + 0x58684c11,
75919 + 0xc1611dab,
75920 + 0xb6662d3d,
75921 + 0x76dc4190,
75922 + 0x01db7106,
75923 + 0x98d220bc,
75924 + 0xefd5102a,
75925 + 0x71b18589,
75926 + 0x06b6b51f,
75927 + 0x9fbfe4a5,
75928 + 0xe8b8d433,
75929 + 0x7807c9a2,
75930 + 0x0f00f934,
75931 + 0x9609a88e,
75932 + 0xe10e9818,
75933 + 0x7f6a0dbb,
75934 + 0x086d3d2d,
75935 + 0x91646c97,
75936 + 0xe6635c01,
75937 + 0x6b6b51f4,
75938 + 0x1c6c6162,
75939 + 0x856530d8,
75940 + 0xf262004e,
75941 + 0x6c0695ed,
75942 + 0x1b01a57b,
75943 + 0x8208f4c1,
75944 + 0xf50fc457,
75945 + 0x65b0d9c6,
75946 + 0x12b7e950,
75947 + 0x8bbeb8ea,
75948 + 0xfcb9887c,
75949 + 0x62dd1ddf,
75950 + 0x15da2d49,
75951 + 0x8cd37cf3,
75952 + 0xfbd44c65,
75953 + 0x4db26158,
75954 + 0x3ab551ce,
75955 + 0xa3bc0074,
75956 + 0xd4bb30e2,
75957 + 0x4adfa541,
75958 + 0x3dd895d7,
75959 + 0xa4d1c46d,
75960 + 0xd3d6f4fb,
75961 + 0x4369e96a,
75962 + 0x346ed9fc,
75963 + 0xad678846,
75964 + 0xda60b8d0,
75965 + 0x44042d73,
75966 + 0x33031de5,
75967 + 0xaa0a4c5f,
75968 + 0xdd0d7cc9,
75969 + 0x5005713c,
75970 + 0x270241aa,
75971 + 0xbe0b1010,
75972 + 0xc90c2086,
75973 + 0x5768b525,
75974 + 0x206f85b3,
75975 + 0xb966d409,
75976 + 0xce61e49f,
75977 + 0x5edef90e,
75978 + 0x29d9c998,
75979 + 0xb0d09822,
75980 + 0xc7d7a8b4,
75981 + 0x59b33d17,
75982 + 0x2eb40d81,
75983 + 0xb7bd5c3b,
75984 + 0xc0ba6cad,
75985 + 0xedb88320,
75986 + 0x9abfb3b6,
75987 + 0x03b6e20c,
75988 + 0x74b1d29a,
75989 + 0xead54739,
75990 + 0x9dd277af,
75991 + 0x04db2615,
75992 + 0x73dc1683,
75993 + 0xe3630b12,
75994 + 0x94643b84,
75995 + 0x0d6d6a3e,
75996 + 0x7a6a5aa8,
75997 + 0xe40ecf0b,
75998 + 0x9309ff9d,
75999 + 0x0a00ae27,
76000 + 0x7d079eb1,
76001 + 0xf00f9344,
76002 + 0x8708a3d2,
76003 + 0x1e01f268,
76004 + 0x6906c2fe,
76005 + 0xf762575d,
76006 + 0x806567cb,
76007 + 0x196c3671,
76008 + 0x6e6b06e7,
76009 + 0xfed41b76,
76010 + 0x89d32be0,
76011 + 0x10da7a5a,
76012 + 0x67dd4acc,
76013 + 0xf9b9df6f,
76014 + 0x8ebeeff9,
76015 + 0x17b7be43,
76016 + 0x60b08ed5,
76017 + 0xd6d6a3e8,
76018 + 0xa1d1937e,
76019 + 0x38d8c2c4,
76020 + 0x4fdff252,
76021 + 0xd1bb67f1,
76022 + 0xa6bc5767,
76023 + 0x3fb506dd,
76024 + 0x48b2364b,
76025 + 0xd80d2bda,
76026 + 0xaf0a1b4c,
76027 + 0x36034af6,
76028 + 0x41047a60,
76029 + 0xdf60efc3,
76030 + 0xa867df55,
76031 + 0x316e8eef,
76032 + 0x4669be79,
76033 + 0xcb61b38c,
76034 + 0xbc66831a,
76035 + 0x256fd2a0,
76036 + 0x5268e236,
76037 + 0xcc0c7795,
76038 + 0xbb0b4703,
76039 + 0x220216b9,
76040 + 0x5505262f,
76041 + 0xc5ba3bbe,
76042 + 0xb2bd0b28,
76043 + 0x2bb45a92,
76044 + 0x5cb36a04,
76045 + 0xc2d7ffa7,
76046 + 0xb5d0cf31,
76047 + 0x2cd99e8b,
76048 + 0x5bdeae1d,
76049 + 0x9b64c2b0,
76050 + 0xec63f226,
76051 + 0x756aa39c,
76052 + 0x026d930a,
76053 + 0x9c0906a9,
76054 + 0xeb0e363f,
76055 + 0x72076785,
76056 + 0x05005713,
76057 + 0x95bf4a82,
76058 + 0xe2b87a14,
76059 + 0x7bb12bae,
76060 + 0x0cb61b38,
76061 + 0x92d28e9b,
76062 + 0xe5d5be0d,
76063 + 0x7cdcefb7,
76064 + 0x0bdbdf21,
76065 + 0x86d3d2d4,
76066 + 0xf1d4e242,
76067 + 0x68ddb3f8,
76068 + 0x1fda836e,
76069 + 0x81be16cd,
76070 + 0xf6b9265b,
76071 + 0x6fb077e1,
76072 + 0x18b74777,
76073 + 0x88085ae6,
76074 + 0xff0f6a70,
76075 + 0x66063bca,
76076 + 0x11010b5c,
76077 + 0x8f659eff,
76078 + 0xf862ae69,
76079 + 0x616bffd3,
76080 + 0x166ccf45,
76081 + 0xa00ae278,
76082 + 0xd70dd2ee,
76083 + 0x4e048354,
76084 + 0x3903b3c2,
76085 + 0xa7672661,
76086 + 0xd06016f7,
76087 + 0x4969474d,
76088 + 0x3e6e77db,
76089 + 0xaed16a4a,
76090 + 0xd9d65adc,
76091 + 0x40df0b66,
76092 + 0x37d83bf0,
76093 + 0xa9bcae53,
76094 + 0xdebb9ec5,
76095 + 0x47b2cf7f,
76096 + 0x30b5ffe9,
76097 + 0xbdbdf21c,
76098 + 0xcabac28a,
76099 + 0x53b39330,
76100 + 0x24b4a3a6,
76101 + 0xbad03605,
76102 + 0xcdd70693,
76103 + 0x54de5729,
76104 + 0x23d967bf,
76105 + 0xb3667a2e,
76106 + 0xc4614ab8,
76107 + 0x5d681b02,
76108 + 0x2a6f2b94,
76109 + 0xb40bbe37,
76110 + 0xc30c8ea1,
76111 + 0x5a05df1b,
76112 + 0x2d02ef8d
76113 +};
76114 +
76115 +
76116 +#define GET_MAC_ADDR_CRC(addr, crc) \
76117 +{ \
76118 + uint32_t i; \
76119 + uint8_t data; \
76120 + \
76121 + /* CRC calculation */ \
76122 + crc = 0xffffffff; \
76123 + for (i=0; i < 6; i++) \
76124 + { \
76125 + data = (uint8_t)(addr >> ((5-i)*8)); \
76126 + crc = crc^data; \
76127 + crc = crc_table[crc&0xff] ^ (crc>>8); \
76128 + } \
76129 +} \
76130 +
76131 +/* Define a macro for getting the mirrored value of */
76132 +/* a byte size number. (0x11010011 --> 0x11001011) */
76133 +/* Sometimes the mirrored value of the CRC is required */
76134 +static __inline__ uint8_t GetMirror(uint8_t n)
76135 +{
76136 + uint8_t mirror[16] =
76137 + {
76138 + 0x00,
76139 + 0x08,
76140 + 0x04,
76141 + 0x0c,
76142 + 0x02,
76143 + 0x0a,
76144 + 0x06,
76145 + 0x0e,
76146 + 0x01,
76147 + 0x09,
76148 + 0x05,
76149 + 0x0d,
76150 + 0x03,
76151 + 0x0b,
76152 + 0x07,
76153 + 0x0f
76154 + };
76155 + return ((uint8_t)(((mirror[n & 0x0f] << 4) | (mirror[n >> 4]))));
76156 +}
76157 +
76158 +static __inline__ uint32_t GetMirror32(uint32_t n)
76159 +{
76160 + return (((uint32_t)GetMirror((uint8_t)(n))<<24) |
76161 + ((uint32_t)GetMirror((uint8_t)(n>>8))<<16) |
76162 + ((uint32_t)GetMirror((uint8_t)(n>>16))<<8) |
76163 + ((uint32_t)GetMirror((uint8_t)(n>>24))));
76164 +}
76165 +
76166 +#define MIRROR GetMirror
76167 +#define MIRROR_32 GetMirror32
76168 +
76169 +
76170 +#endif /* __crc_mac_addr_ext_h */
76171 --- /dev/null
76172 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/Peripherals/dpaa_ext.h
76173 @@ -0,0 +1,210 @@
76174 +/* Copyright (c) 2008-2012 Freescale Semiconductor, Inc
76175 + * All rights reserved.
76176 + *
76177 + * Redistribution and use in source and binary forms, with or without
76178 + * modification, are permitted provided that the following conditions are met:
76179 + * * Redistributions of source code must retain the above copyright
76180 + * notice, this list of conditions and the following disclaimer.
76181 + * * Redistributions in binary form must reproduce the above copyright
76182 + * notice, this list of conditions and the following disclaimer in the
76183 + * documentation and/or other materials provided with the distribution.
76184 + * * Neither the name of Freescale Semiconductor nor the
76185 + * names of its contributors may be used to endorse or promote products
76186 + * derived from this software without specific prior written permission.
76187 + *
76188 + *
76189 + * ALTERNATIVELY, this software may be distributed under the terms of the
76190 + * GNU General Public License ("GPL") as published by the Free Software
76191 + * Foundation, either version 2 of that License or (at your option) any
76192 + * later version.
76193 + *
76194 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
76195 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
76196 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
76197 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
76198 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
76199 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
76200 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
76201 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
76202 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
76203 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
76204 + */
76205 +
76206 +
76207 +/**************************************************************************//**
76208 + @File dpaa_ext.h
76209 +
76210 + @Description DPAA Application Programming Interface.
76211 +*//***************************************************************************/
76212 +#ifndef __DPAA_EXT_H
76213 +#define __DPAA_EXT_H
76214 +
76215 +#include "std_ext.h"
76216 +#include "error_ext.h"
76217 +
76218 +
76219 +/**************************************************************************//**
76220 + @Group DPAA_grp Data Path Acceleration Architecture API
76221 +
76222 + @Description DPAA API functions, definitions and enums.
76223 +
76224 + @{
76225 +*//***************************************************************************/
76226 +
76227 +#if defined(__MWERKS__) && !defined(__GNUC__)
76228 +#pragma pack(push,1)
76229 +#endif /* defined(__MWERKS__) && ... */
76230 +
76231 +/**************************************************************************//**
76232 + @Description Frame descriptor
76233 +*//***************************************************************************/
76234 +typedef _Packed struct t_DpaaFD {
76235 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
76236 + volatile uint8_t liodn;
76237 + volatile uint8_t bpid;
76238 + volatile uint8_t elion;
76239 + volatile uint8_t addrh;
76240 + volatile uint32_t addrl;
76241 +#else
76242 + volatile uint32_t addrl;
76243 + volatile uint8_t addrh;
76244 + volatile uint8_t elion;
76245 + volatile uint8_t bpid;
76246 + volatile uint8_t liodn;
76247 + #endif
76248 + volatile uint32_t length; /**< Frame length */
76249 + volatile uint32_t status; /**< FD status */
76250 +} _PackedType t_DpaaFD;
76251 +
76252 +/**************************************************************************//**
76253 + @Description enum for defining frame format
76254 +*//***************************************************************************/
76255 +typedef enum e_DpaaFDFormatType {
76256 + e_DPAA_FD_FORMAT_TYPE_SHORT_SBSF = 0x0, /**< Simple frame Single buffer; Offset and
76257 + small length (9b OFFSET, 20b LENGTH) */
76258 + e_DPAA_FD_FORMAT_TYPE_LONG_SBSF = 0x2, /**< Simple frame, single buffer; big length
76259 + (29b LENGTH ,No OFFSET) */
76260 + e_DPAA_FD_FORMAT_TYPE_SHORT_MBSF = 0x4, /**< Simple frame, Scatter Gather table; Offset
76261 + and small length (9b OFFSET, 20b LENGTH) */
76262 + e_DPAA_FD_FORMAT_TYPE_LONG_MBSF = 0x6, /**< Simple frame, Scatter Gather table;
76263 + big length (29b LENGTH ,No OFFSET) */
76264 + e_DPAA_FD_FORMAT_TYPE_COMPOUND = 0x1, /**< Compound Frame (29b CONGESTION-WEIGHT
76265 + No LENGTH or OFFSET) */
76266 + e_DPAA_FD_FORMAT_TYPE_DUMMY
76267 +} e_DpaaFDFormatType;
76268 +
76269 +/**************************************************************************//**
76270 + @Collection Frame descriptor macros
76271 +*//***************************************************************************/
76272 +#define DPAA_FD_DD_MASK 0xc0000000 /**< FD DD field mask */
76273 +#define DPAA_FD_PID_MASK 0x3f000000 /**< FD PID field mask */
76274 +#define DPAA_FD_ELIODN_MASK 0x0000f000 /**< FD ELIODN field mask */
76275 +#define DPAA_FD_BPID_MASK 0x00ff0000 /**< FD BPID field mask */
76276 +#define DPAA_FD_ADDRH_MASK 0x000000ff /**< FD ADDRH field mask */
76277 +#define DPAA_FD_ADDRL_MASK 0xffffffff /**< FD ADDRL field mask */
76278 +#define DPAA_FD_FORMAT_MASK 0xe0000000 /**< FD FORMAT field mask */
76279 +#define DPAA_FD_OFFSET_MASK 0x1ff00000 /**< FD OFFSET field mask */
76280 +#define DPAA_FD_LENGTH_MASK 0x000fffff /**< FD LENGTH field mask */
76281 +
76282 +#define DPAA_FD_GET_ADDRH(fd) ((t_DpaaFD *)fd)->addrh /**< Macro to get FD ADDRH field */
76283 +#define DPAA_FD_GET_ADDRL(fd) ((t_DpaaFD *)fd)->addrl /**< Macro to get FD ADDRL field */
76284 +#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 */
76285 +#define DPAA_FD_GET_FORMAT(fd) ((((t_DpaaFD *)fd)->length & DPAA_FD_FORMAT_MASK) >> (31-2)) /**< Macro to get FD FORMAT field */
76286 +#define DPAA_FD_GET_OFFSET(fd) ((((t_DpaaFD *)fd)->length & DPAA_FD_OFFSET_MASK) >> (31-11)) /**< Macro to get FD OFFSET field */
76287 +#define DPAA_FD_GET_LENGTH(fd) (((t_DpaaFD *)fd)->length & DPAA_FD_LENGTH_MASK) /**< Macro to get FD LENGTH field */
76288 +#define DPAA_FD_GET_STATUS(fd) ((t_DpaaFD *)fd)->status /**< Macro to get FD STATUS field */
76289 +#define DPAA_FD_GET_ADDR(fd) XX_PhysToVirt(DPAA_FD_GET_PHYS_ADDR(fd)) /**< Macro to get FD ADDR (virtual) */
76290 +
76291 +#define DPAA_FD_SET_ADDRH(fd,val) ((t_DpaaFD *)fd)->addrh = (val) /**< Macro to set FD ADDRH field */
76292 +#define DPAA_FD_SET_ADDRL(fd,val) ((t_DpaaFD *)fd)->addrl = (val) /**< Macro to set FD ADDRL field */
76293 +#define DPAA_FD_SET_ADDR(fd,val) \
76294 +do { \
76295 + uint64_t physAddr = (uint64_t)(XX_VirtToPhys(val)); \
76296 + DPAA_FD_SET_ADDRH(fd, ((uint32_t)(physAddr >> 32))); \
76297 + DPAA_FD_SET_ADDRL(fd, (uint32_t)physAddr); \
76298 +} while (0) /**< Macro to set FD ADDR field */
76299 +#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 */
76300 +#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 */
76301 +#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 */
76302 +#define DPAA_FD_SET_STATUS(fd,val) ((t_DpaaFD *)fd)->status = (val) /**< Macro to set FD STATUS field */
76303 +/* @} */
76304 +
76305 +/**************************************************************************//**
76306 + @Description Frame Scatter/Gather Table Entry
76307 +*//***************************************************************************/
76308 +typedef _Packed struct t_DpaaSGTE {
76309 + volatile uint32_t addrh; /**< Buffer Address high */
76310 + volatile uint32_t addrl; /**< Buffer Address low */
76311 + volatile uint32_t length; /**< Buffer length */
76312 + volatile uint32_t offset; /**< SGTE offset */
76313 +} _PackedType t_DpaaSGTE;
76314 +
76315 +#define DPAA_NUM_OF_SG_TABLE_ENTRY 16
76316 +
76317 +/**************************************************************************//**
76318 + @Description Frame Scatter/Gather Table
76319 +*//***************************************************************************/
76320 +typedef _Packed struct t_DpaaSGT {
76321 + t_DpaaSGTE tableEntry[DPAA_NUM_OF_SG_TABLE_ENTRY];
76322 + /**< Structure that holds information about
76323 + a single S/G entry. */
76324 +} _PackedType t_DpaaSGT;
76325 +
76326 +/**************************************************************************//**
76327 + @Description Compound Frame Table
76328 +*//***************************************************************************/
76329 +typedef _Packed struct t_DpaaCompTbl {
76330 + t_DpaaSGTE outputBuffInfo; /**< Structure that holds information about
76331 + the compound-frame output buffer;
76332 + NOTE: this may point to a S/G table */
76333 + t_DpaaSGTE inputBuffInfo; /**< Structure that holds information about
76334 + the compound-frame input buffer;
76335 + NOTE: this may point to a S/G table */
76336 +} _PackedType t_DpaaCompTbl;
76337 +
76338 +/**************************************************************************//**
76339 + @Collection Frame Scatter/Gather Table Entry macros
76340 +*//***************************************************************************/
76341 +#define DPAA_SGTE_ADDRH_MASK 0x000000ff /**< SGTE ADDRH field mask */
76342 +#define DPAA_SGTE_ADDRL_MASK 0xffffffff /**< SGTE ADDRL field mask */
76343 +#define DPAA_SGTE_E_MASK 0x80000000 /**< SGTE Extension field mask */
76344 +#define DPAA_SGTE_F_MASK 0x40000000 /**< SGTE Final field mask */
76345 +#define DPAA_SGTE_LENGTH_MASK 0x3fffffff /**< SGTE LENGTH field mask */
76346 +#define DPAA_SGTE_BPID_MASK 0x00ff0000 /**< SGTE BPID field mask */
76347 +#define DPAA_SGTE_OFFSET_MASK 0x00001fff /**< SGTE OFFSET field mask */
76348 +
76349 +#define DPAA_SGTE_GET_ADDRH(sgte) (((t_DpaaSGTE *)sgte)->addrh & DPAA_SGTE_ADDRH_MASK) /**< Macro to get SGTE ADDRH field */
76350 +#define DPAA_SGTE_GET_ADDRL(sgte) ((t_DpaaSGTE *)sgte)->addrl /**< Macro to get SGTE ADDRL field */
76351 +#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 */
76352 +#define DPAA_SGTE_GET_EXTENSION(sgte) ((((t_DpaaSGTE *)sgte)->length & DPAA_SGTE_E_MASK) >> (31-0)) /**< Macro to get SGTE EXTENSION field */
76353 +#define DPAA_SGTE_GET_FINAL(sgte) ((((t_DpaaSGTE *)sgte)->length & DPAA_SGTE_F_MASK) >> (31-1)) /**< Macro to get SGTE FINAL field */
76354 +#define DPAA_SGTE_GET_LENGTH(sgte) (((t_DpaaSGTE *)sgte)->length & DPAA_SGTE_LENGTH_MASK) /**< Macro to get SGTE LENGTH field */
76355 +#define DPAA_SGTE_GET_BPID(sgte) ((((t_DpaaSGTE *)sgte)->offset & DPAA_SGTE_BPID_MASK) >> (31-15)) /**< Macro to get SGTE BPID field */
76356 +#define DPAA_SGTE_GET_OFFSET(sgte) (((t_DpaaSGTE *)sgte)->offset & DPAA_SGTE_OFFSET_MASK) /**< Macro to get SGTE OFFSET field */
76357 +#define DPAA_SGTE_GET_ADDR(sgte) XX_PhysToVirt(DPAA_SGTE_GET_PHYS_ADDR(sgte))
76358 +
76359 +#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 */
76360 +#define DPAA_SGTE_SET_ADDRL(sgte,val) ((t_DpaaSGTE *)sgte)->addrl = (val) /**< Macro to set SGTE ADDRL field */
76361 +#define DPAA_SGTE_SET_ADDR(sgte,val) \
76362 +do { \
76363 + uint64_t physAddr = (uint64_t)(XX_VirtToPhys(val)); \
76364 + DPAA_SGTE_SET_ADDRH(sgte, ((uint32_t)(physAddr >> 32))); \
76365 + DPAA_SGTE_SET_ADDRL(sgte, (uint32_t)physAddr); \
76366 +} while (0) /**< Macro to set SGTE ADDR field */
76367 +#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 */
76368 +#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 */
76369 +#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 */
76370 +#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 */
76371 +#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 */
76372 +/* @} */
76373 +
76374 +#if defined(__MWERKS__) && !defined(__GNUC__)
76375 +#pragma pack(pop)
76376 +#endif /* defined(__MWERKS__) && ... */
76377 +
76378 +#define DPAA_LIODN_DONT_OVERRIDE (-1)
76379 +
76380 +/** @} */ /* end of DPAA_grp group */
76381 +
76382 +
76383 +#endif /* __DPAA_EXT_H */
76384 --- /dev/null
76385 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/Peripherals/fm_ext.h
76386 @@ -0,0 +1,1731 @@
76387 +/* Copyright (c) 2008-2012 Freescale Semiconductor, Inc
76388 + * All rights reserved.
76389 + *
76390 + * Redistribution and use in source and binary forms, with or without
76391 + * modification, are permitted provided that the following conditions are met:
76392 + * * Redistributions of source code must retain the above copyright
76393 + * notice, this list of conditions and the following disclaimer.
76394 + * * Redistributions in binary form must reproduce the above copyright
76395 + * notice, this list of conditions and the following disclaimer in the
76396 + * documentation and/or other materials provided with the distribution.
76397 + * * Neither the name of Freescale Semiconductor nor the
76398 + * names of its contributors may be used to endorse or promote products
76399 + * derived from this software without specific prior written permission.
76400 + *
76401 + *
76402 + * ALTERNATIVELY, this software may be distributed under the terms of the
76403 + * GNU General Public License ("GPL") as published by the Free Software
76404 + * Foundation, either version 2 of that License or (at your option) any
76405 + * later version.
76406 + *
76407 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
76408 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
76409 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
76410 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
76411 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
76412 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
76413 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
76414 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
76415 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
76416 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
76417 + */
76418 +
76419 +
76420 +/**************************************************************************//**
76421 + @File fm_ext.h
76422 +
76423 + @Description FM Application Programming Interface.
76424 +*//***************************************************************************/
76425 +#ifndef __FM_EXT
76426 +#define __FM_EXT
76427 +
76428 +#include "error_ext.h"
76429 +#include "std_ext.h"
76430 +#include "dpaa_ext.h"
76431 +#include "fsl_fman_sp.h"
76432 +
76433 +/**************************************************************************//**
76434 + @Group FM_grp Frame Manager API
76435 +
76436 + @Description FM API functions, definitions and enums.
76437 +
76438 + @{
76439 +*//***************************************************************************/
76440 +
76441 +/**************************************************************************//**
76442 + @Group FM_lib_grp FM library
76443 +
76444 + @Description FM API functions, definitions and enums.
76445 +
76446 + The FM module is the main driver module and is a mandatory module
76447 + for FM driver users. This module must be initialized first prior
76448 + to any other drivers modules.
76449 + The FM is a "singleton" module. It is responsible of the common
76450 + HW modules: FPM, DMA, common QMI and common BMI initializations and
76451 + run-time control routines. This module must be initialized always
76452 + when working with any of the FM modules.
76453 + NOTE - We assume that the FM library will be initialized only by core No. 0!
76454 +
76455 + @{
76456 +*//***************************************************************************/
76457 +
76458 +/**************************************************************************//**
76459 + @Description Enum for defining port types
76460 +*//***************************************************************************/
76461 +typedef enum e_FmPortType {
76462 + e_FM_PORT_TYPE_OH_OFFLINE_PARSING = 0, /**< Offline parsing port */
76463 + e_FM_PORT_TYPE_RX, /**< 1G Rx port */
76464 + e_FM_PORT_TYPE_RX_10G, /**< 10G Rx port */
76465 + e_FM_PORT_TYPE_TX, /**< 1G Tx port */
76466 + e_FM_PORT_TYPE_TX_10G, /**< 10G Tx port */
76467 + e_FM_PORT_TYPE_DUMMY
76468 +} e_FmPortType;
76469 +
76470 +/**************************************************************************//**
76471 + @Collection General FM defines
76472 +*//***************************************************************************/
76473 +#define FM_MAX_NUM_OF_PARTITIONS 64 /**< Maximum number of partitions */
76474 +#define FM_PHYS_ADDRESS_SIZE 6 /**< FM Physical address size */
76475 +/* @} */
76476 +
76477 +
76478 +#if defined(__MWERKS__) && !defined(__GNUC__)
76479 +#pragma pack(push,1)
76480 +#endif /* defined(__MWERKS__) && ... */
76481 +
76482 +/**************************************************************************//**
76483 + @Description FM physical Address
76484 +*//***************************************************************************/
76485 +typedef _Packed struct t_FmPhysAddr {
76486 + volatile uint8_t high; /**< High part of the physical address */
76487 + volatile uint32_t low; /**< Low part of the physical address */
76488 +} _PackedType t_FmPhysAddr;
76489 +
76490 +/**************************************************************************//**
76491 + @Description Parse results memory layout
76492 +*//***************************************************************************/
76493 +typedef _Packed struct t_FmPrsResult {
76494 + volatile uint8_t lpid; /**< Logical port id */
76495 + volatile uint8_t shimr; /**< Shim header result */
76496 + volatile uint16_t l2r; /**< Layer 2 result */
76497 + volatile uint16_t l3r; /**< Layer 3 result */
76498 + volatile uint8_t l4r; /**< Layer 4 result */
76499 + volatile uint8_t cplan; /**< Classification plan id */
76500 + volatile uint16_t nxthdr; /**< Next Header */
76501 + volatile uint16_t cksum; /**< Running-sum */
76502 + volatile uint16_t flags_frag_off; /**< Flags & fragment-offset field of the last IP-header */
76503 + volatile uint8_t route_type; /**< Routing type field of a IPv6 routing extension header */
76504 + volatile uint8_t rhp_ip_valid; /**< Routing Extension Header Present; last bit is IP valid */
76505 + volatile uint8_t shim_off[2]; /**< Shim offset */
76506 + volatile uint8_t ip_pid_off; /**< IP PID (last IP-proto) offset */
76507 + volatile uint8_t eth_off; /**< ETH offset */
76508 + volatile uint8_t llc_snap_off; /**< LLC_SNAP offset */
76509 + volatile uint8_t vlan_off[2]; /**< VLAN offset */
76510 + volatile uint8_t etype_off; /**< ETYPE offset */
76511 + volatile uint8_t pppoe_off; /**< PPP offset */
76512 + volatile uint8_t mpls_off[2]; /**< MPLS offset */
76513 + volatile uint8_t ip_off[2]; /**< IP offset */
76514 + volatile uint8_t gre_off; /**< GRE offset */
76515 + volatile uint8_t l4_off; /**< Layer 4 offset */
76516 + volatile uint8_t nxthdr_off; /**< Parser end point */
76517 +} _PackedType t_FmPrsResult;
76518 +
76519 +/**************************************************************************//**
76520 + @Collection FM Parser results
76521 +*//***************************************************************************/
76522 +#define FM_PR_L2_VLAN_STACK 0x00000100 /**< Parse Result: VLAN stack */
76523 +#define FM_PR_L2_ETHERNET 0x00008000 /**< Parse Result: Ethernet*/
76524 +#define FM_PR_L2_VLAN 0x00004000 /**< Parse Result: VLAN */
76525 +#define FM_PR_L2_LLC_SNAP 0x00002000 /**< Parse Result: LLC_SNAP */
76526 +#define FM_PR_L2_MPLS 0x00001000 /**< Parse Result: MPLS */
76527 +#define FM_PR_L2_PPPoE 0x00000800 /**< Parse Result: PPPoE */
76528 +/* @} */
76529 +
76530 +/**************************************************************************//**
76531 + @Collection FM Frame descriptor macros
76532 +*//***************************************************************************/
76533 +#define FM_FD_CMD_FCO 0x80000000 /**< Frame queue Context Override */
76534 +#define FM_FD_CMD_RPD 0x40000000 /**< Read Prepended Data */
76535 +#define FM_FD_CMD_UPD 0x20000000 /**< Update Prepended Data */
76536 +#define FM_FD_CMD_DTC 0x10000000 /**< Do L4 Checksum */
76537 +#define FM_FD_CMD_DCL4C 0x10000000 /**< Didn't calculate L4 Checksum */
76538 +#define FM_FD_CMD_CFQ 0x00ffffff /**< Confirmation Frame Queue */
76539 +
76540 +#define FM_FD_ERR_UNSUPPORTED_FORMAT 0x04000000 /**< Not for Rx-Port! Unsupported Format */
76541 +#define FM_FD_ERR_LENGTH 0x02000000 /**< Not for Rx-Port! Length Error */
76542 +#define FM_FD_ERR_DMA 0x01000000 /**< DMA Data error */
76543 +
76544 +#define FM_FD_IPR 0x00000001 /**< IPR frame (not error) */
76545 +
76546 +#define FM_FD_ERR_IPR_NCSP (0x00100000 | FM_FD_IPR) /**< IPR non-consistent-sp */
76547 +#define FM_FD_ERR_IPR (0x00200000 | FM_FD_IPR) /**< IPR error */
76548 +#define FM_FD_ERR_IPR_TO (0x00300000 | FM_FD_IPR) /**< IPR timeout */
76549 +
76550 +#ifdef FM_CAPWAP_SUPPORT
76551 +#define FM_FD_ERR_CRE 0x00200000
76552 +#define FM_FD_ERR_CHE 0x00100000
76553 +#endif /* FM_CAPWAP_SUPPORT */
76554 +
76555 +#define FM_FD_ERR_PHYSICAL 0x00080000 /**< Rx FIFO overflow, FCS error, code error, running disparity
76556 + error (SGMII and TBI modes), FIFO parity error. PHY
76557 + Sequence error, PHY error control character detected. */
76558 +#define FM_FD_ERR_SIZE 0x00040000 /**< Frame too long OR Frame size exceeds max_length_frame */
76559 +#define FM_FD_ERR_CLS_DISCARD 0x00020000 /**< classification discard */
76560 +#define FM_FD_ERR_EXTRACTION 0x00008000 /**< Extract Out of Frame */
76561 +#define FM_FD_ERR_NO_SCHEME 0x00004000 /**< No Scheme Selected */
76562 +#define FM_FD_ERR_KEYSIZE_OVERFLOW 0x00002000 /**< Keysize Overflow */
76563 +#define FM_FD_ERR_COLOR_RED 0x00000800 /**< Frame color is red */
76564 +#define FM_FD_ERR_COLOR_YELLOW 0x00000400 /**< Frame color is yellow */
76565 +#define FM_FD_ERR_ILL_PLCR 0x00000200 /**< Illegal Policer Profile selected */
76566 +#define FM_FD_ERR_PLCR_FRAME_LEN 0x00000100 /**< Policer frame length error */
76567 +#define FM_FD_ERR_PRS_TIMEOUT 0x00000080 /**< Parser Time out Exceed */
76568 +#define FM_FD_ERR_PRS_ILL_INSTRUCT 0x00000040 /**< Invalid Soft Parser instruction */
76569 +#define FM_FD_ERR_PRS_HDR_ERR 0x00000020 /**< Header error was identified during parsing */
76570 +#define FM_FD_ERR_BLOCK_LIMIT_EXCEEDED 0x00000008 /**< Frame parsed beyind 256 first bytes */
76571 +
76572 +#define FM_FD_TX_STATUS_ERR_MASK (FM_FD_ERR_UNSUPPORTED_FORMAT | \
76573 + FM_FD_ERR_LENGTH | \
76574 + FM_FD_ERR_DMA) /**< TX Error FD bits */
76575 +
76576 +#define FM_FD_RX_STATUS_ERR_MASK (FM_FD_ERR_UNSUPPORTED_FORMAT | \
76577 + FM_FD_ERR_LENGTH | \
76578 + FM_FD_ERR_DMA | \
76579 + FM_FD_ERR_IPR | \
76580 + FM_FD_ERR_IPR_TO | \
76581 + FM_FD_ERR_IPR_NCSP | \
76582 + FM_FD_ERR_PHYSICAL | \
76583 + FM_FD_ERR_SIZE | \
76584 + FM_FD_ERR_CLS_DISCARD | \
76585 + FM_FD_ERR_COLOR_RED | \
76586 + FM_FD_ERR_COLOR_YELLOW | \
76587 + FM_FD_ERR_ILL_PLCR | \
76588 + FM_FD_ERR_PLCR_FRAME_LEN | \
76589 + FM_FD_ERR_EXTRACTION | \
76590 + FM_FD_ERR_NO_SCHEME | \
76591 + FM_FD_ERR_KEYSIZE_OVERFLOW | \
76592 + FM_FD_ERR_PRS_TIMEOUT | \
76593 + FM_FD_ERR_PRS_ILL_INSTRUCT | \
76594 + FM_FD_ERR_PRS_HDR_ERR | \
76595 + FM_FD_ERR_BLOCK_LIMIT_EXCEEDED) /**< RX Error FD bits */
76596 +
76597 +#define FM_FD_RX_STATUS_ERR_NON_FM 0x00400000 /**< non Frame-Manager error */
76598 +/* @} */
76599 +
76600 +/**************************************************************************//**
76601 + @Description Context A
76602 +*//***************************************************************************/
76603 +typedef _Packed struct t_FmContextA {
76604 + volatile uint32_t command; /**< ContextA Command */
76605 + volatile uint8_t res0[4]; /**< ContextA Reserved bits */
76606 +} _PackedType t_FmContextA;
76607 +
76608 +/**************************************************************************//**
76609 + @Description Context B
76610 +*//***************************************************************************/
76611 +typedef uint32_t t_FmContextB;
76612 +
76613 +/**************************************************************************//**
76614 + @Collection Special Operation options
76615 +*//***************************************************************************/
76616 +typedef uint32_t fmSpecialOperations_t; /**< typedef for defining Special Operation options */
76617 +
76618 +#define FM_SP_OP_IPSEC 0x80000000 /**< activate features that related to IPSec (e.g fix Eth-type) */
76619 +#define FM_SP_OP_IPSEC_UPDATE_UDP_LEN 0x40000000 /**< update the UDP-Len after Encryption */
76620 +#define FM_SP_OP_IPSEC_MANIP 0x20000000 /**< handle the IPSec-manip options */
76621 +#define FM_SP_OP_RPD 0x10000000 /**< Set the RPD bit */
76622 +#define FM_SP_OP_DCL4C 0x08000000 /**< Set the DCL4C bit */
76623 +#define FM_SP_OP_CHECK_SEC_ERRORS 0x04000000 /**< Check SEC errors */
76624 +#define FM_SP_OP_CLEAR_RPD 0x02000000 /**< Clear the RPD bit */
76625 +#define FM_SP_OP_CAPWAP_DTLS_ENC 0x01000000 /**< activate features that related to CAPWAP-DTLS post Encryption */
76626 +#define FM_SP_OP_CAPWAP_DTLS_DEC 0x00800000 /**< activate features that related to CAPWAP-DTLS post Decryption */
76627 +#define FM_SP_OP_IPSEC_NO_ETH_HDR 0x00400000 /**< activate features that related to IPSec without Eth hdr */
76628 +/* @} */
76629 +
76630 +/**************************************************************************//**
76631 + @Collection Context A macros
76632 +*//***************************************************************************/
76633 +#define FM_CONTEXTA_OVERRIDE_MASK 0x80000000
76634 +#define FM_CONTEXTA_ICMD_MASK 0x40000000
76635 +#define FM_CONTEXTA_A1_VALID_MASK 0x20000000
76636 +#define FM_CONTEXTA_MACCMD_MASK 0x00ff0000
76637 +#define FM_CONTEXTA_MACCMD_VALID_MASK 0x00800000
76638 +#define FM_CONTEXTA_MACCMD_SECURED_MASK 0x00100000
76639 +#define FM_CONTEXTA_MACCMD_SC_MASK 0x000f0000
76640 +#define FM_CONTEXTA_A1_MASK 0x0000ffff
76641 +
76642 +#define FM_CONTEXTA_GET_OVERRIDE(contextA) ((((t_FmContextA *)contextA)->command & FM_CONTEXTA_OVERRIDE_MASK) >> (31-0))
76643 +#define FM_CONTEXTA_GET_ICMD(contextA) ((((t_FmContextA *)contextA)->command & FM_CONTEXTA_ICMD_MASK) >> (31-1))
76644 +#define FM_CONTEXTA_GET_A1_VALID(contextA) ((((t_FmContextA *)contextA)->command & FM_CONTEXTA_A1_VALID_MASK) >> (31-2))
76645 +#define FM_CONTEXTA_GET_A1(contextA) ((((t_FmContextA *)contextA)->command & FM_CONTEXTA_A1_MASK) >> (31-31))
76646 +#define FM_CONTEXTA_GET_MACCMD(contextA) ((((t_FmContextA *)contextA)->command & FM_CONTEXTA_MACCMD_MASK) >> (31-15))
76647 +#define FM_CONTEXTA_GET_MACCMD_VALID(contextA) ((((t_FmContextA *)contextA)->command & FM_CONTEXTA_MACCMD_VALID_MASK) >> (31-8))
76648 +#define FM_CONTEXTA_GET_MACCMD_SECURED(contextA) ((((t_FmContextA *)contextA)->command & FM_CONTEXTA_MACCMD_SECURED_MASK) >> (31-11))
76649 +#define FM_CONTEXTA_GET_MACCMD_SECURE_CHANNEL(contextA) ((((t_FmContextA *)contextA)->command & FM_CONTEXTA_MACCMD_SC_MASK) >> (31-15))
76650 +
76651 +#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) ))
76652 +#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) ))
76653 +#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) ))
76654 +#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) ))
76655 +#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) ))
76656 +#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) ))
76657 +#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) ))
76658 +#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) ))
76659 +/* @} */
76660 +
76661 +/**************************************************************************//**
76662 + @Collection Context B macros
76663 +*//***************************************************************************/
76664 +#define FM_CONTEXTB_FQID_MASK 0x00ffffff
76665 +
76666 +#define FM_CONTEXTB_GET_FQID(contextB) (*((t_FmContextB *)contextB) & FM_CONTEXTB_FQID_MASK)
76667 +#define FM_CONTEXTB_SET_FQID(contextB,val) (*((t_FmContextB *)contextB) = ((*((t_FmContextB *)contextB) & ~FM_CONTEXTB_FQID_MASK) | ((val) & FM_CONTEXTB_FQID_MASK)))
76668 +/* @} */
76669 +
76670 +#if defined(__MWERKS__) && !defined(__GNUC__)
76671 +#pragma pack(pop)
76672 +#endif /* defined(__MWERKS__) && ... */
76673 +
76674 +
76675 +/**************************************************************************//**
76676 + @Description FM Exceptions
76677 +*//***************************************************************************/
76678 +typedef enum e_FmExceptions {
76679 + e_FM_EX_DMA_BUS_ERROR = 0, /**< DMA bus error. */
76680 + e_FM_EX_DMA_READ_ECC, /**< Read Buffer ECC error (Valid for FM rev < 6)*/
76681 + e_FM_EX_DMA_SYSTEM_WRITE_ECC, /**< Write Buffer ECC error on system side (Valid for FM rev < 6)*/
76682 + e_FM_EX_DMA_FM_WRITE_ECC, /**< Write Buffer ECC error on FM side (Valid for FM rev < 6)*/
76683 + e_FM_EX_DMA_SINGLE_PORT_ECC, /**< Single Port ECC error on FM side (Valid for FM rev > 6)*/
76684 + e_FM_EX_FPM_STALL_ON_TASKS, /**< Stall of tasks on FPM */
76685 + e_FM_EX_FPM_SINGLE_ECC, /**< Single ECC on FPM. */
76686 + e_FM_EX_FPM_DOUBLE_ECC, /**< Double ECC error on FPM ram access */
76687 + e_FM_EX_QMI_SINGLE_ECC, /**< Single ECC on QMI. */
76688 + e_FM_EX_QMI_DOUBLE_ECC, /**< Double bit ECC occurred on QMI */
76689 + e_FM_EX_QMI_DEQ_FROM_UNKNOWN_PORTID,/**< Dequeue from unknown port id */
76690 + e_FM_EX_BMI_LIST_RAM_ECC, /**< Linked List RAM ECC error */
76691 + e_FM_EX_BMI_STORAGE_PROFILE_ECC, /**< Storage Profile ECC Error */
76692 + e_FM_EX_BMI_STATISTICS_RAM_ECC, /**< Statistics Count RAM ECC Error Enable */
76693 + e_FM_EX_BMI_DISPATCH_RAM_ECC, /**< Dispatch RAM ECC Error Enable */
76694 + e_FM_EX_IRAM_ECC, /**< Double bit ECC occurred on IRAM*/
76695 + e_FM_EX_MURAM_ECC /**< Double bit ECC occurred on MURAM*/
76696 +} e_FmExceptions;
76697 +
76698 +/**************************************************************************//**
76699 + @Description Enum for defining port DMA swap mode
76700 +*//***************************************************************************/
76701 +typedef enum e_FmDmaSwapOption {
76702 + e_FM_DMA_NO_SWP = FMAN_DMA_NO_SWP, /**< No swap, transfer data as is.*/
76703 + e_FM_DMA_SWP_PPC_LE = FMAN_DMA_SWP_PPC_LE, /**< The transferred data should be swapped
76704 + in PowerPc Little Endian mode. */
76705 + e_FM_DMA_SWP_BE = FMAN_DMA_SWP_BE /**< The transferred data should be swapped
76706 + in Big Endian mode */
76707 +} e_FmDmaSwapOption;
76708 +
76709 +/**************************************************************************//**
76710 + @Description Enum for defining port DMA cache attributes
76711 +*//***************************************************************************/
76712 +typedef enum e_FmDmaCacheOption {
76713 + e_FM_DMA_NO_STASH = FMAN_DMA_NO_STASH, /**< Cacheable, no Allocate (No Stashing) */
76714 + e_FM_DMA_STASH = FMAN_DMA_STASH /**< Cacheable and Allocate (Stashing on) */
76715 +} e_FmDmaCacheOption;
76716 +
76717 +
76718 +/**************************************************************************//**
76719 + @Group FM_init_grp FM Initialization Unit
76720 +
76721 + @Description FM Initialization Unit
76722 +
76723 + Initialization Flow
76724 + Initialization of the FM Module will be carried out by the application
76725 + according to the following sequence:
76726 + - Calling the configuration routine with basic parameters.
76727 + - Calling the advance initialization routines to change driver's defaults.
76728 + - Calling the initialization routine.
76729 +
76730 + @{
76731 +*//***************************************************************************/
76732 +
76733 +/**************************************************************************//**
76734 + @Function t_FmExceptionsCallback
76735 +
76736 + @Description Exceptions user callback routine, will be called upon an
76737 + exception passing the exception identification.
76738 +
76739 + @Param[in] h_App - User's application descriptor.
76740 + @Param[in] exception - The exception.
76741 +*//***************************************************************************/
76742 +typedef void (t_FmExceptionsCallback)(t_Handle h_App,
76743 + e_FmExceptions exception);
76744 +
76745 +
76746 +/**************************************************************************//**
76747 + @Function t_FmBusErrorCallback
76748 +
76749 + @Description Bus error user callback routine, will be called upon a
76750 + bus error, passing parameters describing the errors and the owner.
76751 +
76752 + @Param[in] h_App - User's application descriptor.
76753 + @Param[in] portType - Port type (e_FmPortType)
76754 + @Param[in] portId - Port id - relative to type.
76755 + @Param[in] addr - Address that caused the error
76756 + @Param[in] tnum - Owner of error
76757 + @Param[in] liodn - Logical IO device number
76758 +*//***************************************************************************/
76759 +typedef void (t_FmBusErrorCallback) (t_Handle h_App,
76760 + e_FmPortType portType,
76761 + uint8_t portId,
76762 + uint64_t addr,
76763 + uint8_t tnum,
76764 + uint16_t liodn);
76765 +
76766 +/**************************************************************************//**
76767 + @Description A structure for defining buffer prefix area content.
76768 +*//***************************************************************************/
76769 +typedef struct t_FmBufferPrefixContent {
76770 + uint16_t privDataSize; /**< Number of bytes to be left at the beginning
76771 + of the external buffer; Note that the private-area will
76772 + start from the base of the buffer address. */
76773 + bool passPrsResult; /**< TRUE to pass the parse result to/from the FM;
76774 + User may use FM_PORT_GetBufferPrsResult() in order to
76775 + get the parser-result from a buffer. */
76776 + bool passTimeStamp; /**< TRUE to pass the timeStamp to/from the FM
76777 + User may use FM_PORT_GetBufferTimeStamp() in order to
76778 + get the parser-result from a buffer. */
76779 + bool passHashResult; /**< TRUE to pass the KG hash result to/from the FM
76780 + User may use FM_PORT_GetBufferHashResult() in order to
76781 + get the parser-result from a buffer. */
76782 + bool passAllOtherPCDInfo;/**< Add all other Internal-Context information:
76783 + AD, hash-result, key, etc. */
76784 + uint16_t dataAlign; /**< 0 to use driver's default alignment [DEFAULT_FM_SP_bufferPrefixContent_dataAlign],
76785 + other value for selecting a data alignment (must be a power of 2);
76786 + if write optimization is used, must be >= 16. */
76787 + uint8_t manipExtraSpace; /**< Maximum extra size needed (insertion-size minus removal-size);
76788 + Note that this field impacts the size of the buffer-prefix
76789 + (i.e. it pushes the data offset);
76790 + This field is irrelevant if DPAA_VERSION==10 */
76791 +} t_FmBufferPrefixContent;
76792 +
76793 +/**************************************************************************//**
76794 + @Description A structure of information about each of the external
76795 + buffer pools used by a port or storage-profile.
76796 +*//***************************************************************************/
76797 +typedef struct t_FmExtPoolParams {
76798 + uint8_t id; /**< External buffer pool id */
76799 + uint16_t size; /**< External buffer pool buffer size */
76800 +} t_FmExtPoolParams;
76801 +
76802 +/**************************************************************************//**
76803 + @Description A structure for informing the driver about the external
76804 + buffer pools allocated in the BM and used by a port or a
76805 + storage-profile.
76806 +*//***************************************************************************/
76807 +typedef struct t_FmExtPools {
76808 + uint8_t numOfPoolsUsed; /**< Number of pools use by this port */
76809 + t_FmExtPoolParams extBufPool[FM_PORT_MAX_NUM_OF_EXT_POOLS];
76810 + /**< Parameters for each port */
76811 +} t_FmExtPools;
76812 +
76813 +/**************************************************************************//**
76814 + @Description A structure for defining backup BM Pools.
76815 +*//***************************************************************************/
76816 +typedef struct t_FmBackupBmPools {
76817 + uint8_t numOfBackupPools; /**< Number of BM backup pools -
76818 + must be smaller than the total number of
76819 + pools defined for the specified port.*/
76820 + uint8_t poolIds[FM_PORT_MAX_NUM_OF_EXT_POOLS];
76821 + /**< numOfBackupPools pool id's, specifying which
76822 + pools should be used only as backup. Pool
76823 + id's specified here must be a subset of the
76824 + pools used by the specified port.*/
76825 +} t_FmBackupBmPools;
76826 +
76827 +/**************************************************************************//**
76828 + @Description A structure for defining BM pool depletion criteria
76829 +*//***************************************************************************/
76830 +typedef struct t_FmBufPoolDepletion {
76831 + bool poolsGrpModeEnable; /**< select mode in which pause frames will be sent after
76832 + a number of pools (all together!) are depleted */
76833 + uint8_t numOfPools; /**< the number of depleted pools that will invoke
76834 + pause frames transmission. */
76835 + bool poolsToConsider[BM_MAX_NUM_OF_POOLS];
76836 + /**< For each pool, TRUE if it should be considered for
76837 + depletion (Note - this pool must be used by this port!). */
76838 + bool singlePoolModeEnable; /**< select mode in which pause frames will be sent after
76839 + a single-pool is depleted; */
76840 + bool poolsToConsiderForSingleMode[BM_MAX_NUM_OF_POOLS];
76841 + /**< For each pool, TRUE if it should be considered for
76842 + depletion (Note - this pool must be used by this port!) */
76843 +#if (DPAA_VERSION >= 11)
76844 + bool pfcPrioritiesEn[FM_MAX_NUM_OF_PFC_PRIORITIES];
76845 + /**< This field is used by the MAC as the Priority Enable Vector in the PFC frame which is transmitted */
76846 +#endif /* (DPAA_VERSION >= 11) */
76847 +} t_FmBufPoolDepletion;
76848 +
76849 +/**************************************************************************//**
76850 + @Description A Structure for defining Ucode patch for loading.
76851 +*//***************************************************************************/
76852 +typedef struct t_FmFirmwareParams {
76853 + uint32_t size; /**< Size of uCode */
76854 + uint32_t *p_Code; /**< A pointer to the uCode */
76855 +} t_FmFirmwareParams;
76856 +
76857 +/**************************************************************************//**
76858 + @Description A Structure for defining FM initialization parameters
76859 +*//***************************************************************************/
76860 +typedef struct t_FmParams {
76861 + uint8_t fmId; /**< Index of the FM */
76862 + uint8_t guestId; /**< FM Partition Id */
76863 + uintptr_t baseAddr; /**< A pointer to base of memory mapped FM registers (virtual);
76864 + this field is optional when the FM runs in "guest-mode"
76865 + (i.e. guestId != NCSW_MASTER_ID); in that case, the driver will
76866 + use the memory-map instead of calling the IPC where possible;
76867 + NOTE that this should include ALL common registers of the FM including
76868 + the PCD registers area (i.e. until the VSP pages - 880KB). */
76869 + t_Handle h_FmMuram; /**< A handle of an initialized MURAM object,
76870 + to be used by the FM. */
76871 + uint16_t fmClkFreq; /**< In Mhz;
76872 + Relevant when FM not runs in "guest-mode". */
76873 + uint16_t fmMacClkRatio; /**< FM MAC Clock ratio, for backward comparability:
76874 + when fmMacClkRatio = 0, ratio is 2:1
76875 + when fmMacClkRatio = 1, ratio is 1:1 */
76876 + t_FmExceptionsCallback *f_Exception; /**< An application callback routine to handle exceptions;
76877 + Relevant when FM not runs in "guest-mode". */
76878 + t_FmBusErrorCallback *f_BusError; /**< An application callback routine to handle exceptions;
76879 + Relevant when FM not runs in "guest-mode". */
76880 + t_Handle h_App; /**< A handle to an application layer object; This handle will
76881 + be passed by the driver upon calling the above callbacks;
76882 + Relevant when FM not runs in "guest-mode". */
76883 + int irq; /**< FM interrupt source for normal events;
76884 + Relevant when FM not runs in "guest-mode". */
76885 + int errIrq; /**< FM interrupt source for errors;
76886 + Relevant when FM not runs in "guest-mode". */
76887 + t_FmFirmwareParams firmware; /**< The firmware parameters structure;
76888 + Relevant when FM not runs in "guest-mode". */
76889 +
76890 +#if (DPAA_VERSION >= 11)
76891 + uintptr_t vspBaseAddr; /**< A pointer to base of memory mapped FM VSP registers (virtual);
76892 + i.e. up to 24KB, depending on the specific chip. */
76893 + uint8_t partVSPBase; /**< The first Virtual-Storage-Profile-id dedicated to this partition.
76894 + NOTE: this parameter relevant only when working with multiple partitions. */
76895 + uint8_t partNumOfVSPs; /**< Number of VSPs dedicated to this partition.
76896 + NOTE: this parameter relevant only when working with multiple partitions. */
76897 +#endif /* (DPAA_VERSION >= 11) */
76898 +} t_FmParams;
76899 +
76900 +
76901 +/**************************************************************************//**
76902 + @Function FM_Config
76903 +
76904 + @Description Creates the FM module and returns its handle (descriptor).
76905 + This descriptor must be passed as first parameter to all other
76906 + FM function calls.
76907 +
76908 + No actual initialization or configuration of FM hardware is
76909 + done by this routine. All FM parameters get default values that
76910 + may be changed by calling one or more of the advance config routines.
76911 +
76912 + @Param[in] p_FmParams - A pointer to a data structure of mandatory FM parameters
76913 +
76914 + @Return A handle to the FM object, or NULL for Failure.
76915 +*//***************************************************************************/
76916 +t_Handle FM_Config(t_FmParams *p_FmParams);
76917 +
76918 +/**************************************************************************//**
76919 + @Function FM_Init
76920 +
76921 + @Description Initializes the FM module by defining the software structure
76922 + and configuring the hardware registers.
76923 +
76924 + @Param[in] h_Fm - FM module descriptor
76925 +
76926 + @Return E_OK on success; Error code otherwise.
76927 +*//***************************************************************************/
76928 +t_Error FM_Init(t_Handle h_Fm);
76929 +
76930 +/**************************************************************************//**
76931 + @Function FM_Free
76932 +
76933 + @Description Frees all resources that were assigned to FM module.
76934 +
76935 + Calling this routine invalidates the descriptor.
76936 +
76937 + @Param[in] h_Fm - FM module descriptor
76938 +
76939 + @Return E_OK on success; Error code otherwise.
76940 +*//***************************************************************************/
76941 +t_Error FM_Free(t_Handle h_Fm);
76942 +
76943 +
76944 +/**************************************************************************//**
76945 + @Group FM_advanced_init_grp FM Advanced Configuration Unit
76946 +
76947 + @Description Advanced configuration routines are optional routines that may
76948 + be called in order to change the default driver settings.
76949 +
76950 + Note: Advanced configuration routines are not available for guest partition.
76951 + @{
76952 +*//***************************************************************************/
76953 +
76954 +/**************************************************************************//**
76955 + @Description Enum for selecting DMA debug mode
76956 +*//***************************************************************************/
76957 +typedef enum e_FmDmaDbgCntMode {
76958 + e_FM_DMA_DBG_NO_CNT = 0, /**< No counting */
76959 + e_FM_DMA_DBG_CNT_DONE, /**< Count DONE commands */
76960 + e_FM_DMA_DBG_CNT_COMM_Q_EM, /**< count command queue emergency signals */
76961 + e_FM_DMA_DBG_CNT_INT_READ_EM, /**< Count Internal Read buffer emergency signal */
76962 + e_FM_DMA_DBG_CNT_INT_WRITE_EM, /**< Count Internal Write buffer emergency signal */
76963 + e_FM_DMA_DBG_CNT_FPM_WAIT, /**< Count FPM WAIT signal */
76964 + e_FM_DMA_DBG_CNT_SIGLE_BIT_ECC, /**< Single bit ECC errors. */
76965 + e_FM_DMA_DBG_CNT_RAW_WAR_PROT /**< Number of times there was a need for RAW & WAR protection. */
76966 +} e_FmDmaDbgCntMode;
76967 +
76968 +/**************************************************************************//**
76969 + @Description Enum for selecting DMA Cache Override
76970 +*//***************************************************************************/
76971 +typedef enum e_FmDmaCacheOverride {
76972 + e_FM_DMA_NO_CACHE_OR = 0, /**< No override of the Cache field */
76973 + e_FM_DMA_NO_STASH_DATA, /**< Data should not be stashed in system level cache */
76974 + e_FM_DMA_MAY_STASH_DATA, /**< Data may be stashed in system level cache */
76975 + e_FM_DMA_STASH_DATA /**< Data should be stashed in system level cache */
76976 +} e_FmDmaCacheOverride;
76977 +
76978 +/**************************************************************************//**
76979 + @Description Enum for selecting DMA External Bus Priority
76980 +*//***************************************************************************/
76981 +typedef enum e_FmDmaExtBusPri {
76982 + e_FM_DMA_EXT_BUS_NORMAL = 0, /**< Normal priority */
76983 + e_FM_DMA_EXT_BUS_EBS, /**< AXI extended bus service priority */
76984 + e_FM_DMA_EXT_BUS_SOS, /**< AXI sos priority */
76985 + e_FM_DMA_EXT_BUS_EBS_AND_SOS /**< AXI ebs + sos priority */
76986 +} e_FmDmaExtBusPri;
76987 +
76988 +/**************************************************************************//**
76989 + @Description Enum for choosing the field that will be output on AID
76990 +*//***************************************************************************/
76991 +typedef enum e_FmDmaAidMode {
76992 + e_FM_DMA_AID_OUT_PORT_ID = 0, /**< 4 LSB of PORT_ID */
76993 + e_FM_DMA_AID_OUT_TNUM /**< 4 LSB of TNUM */
76994 +} e_FmDmaAidMode;
76995 +
76996 +/**************************************************************************//**
76997 + @Description Enum for selecting FPM Catastrophic error behavior
76998 +*//***************************************************************************/
76999 +typedef enum e_FmCatastrophicErr {
77000 + e_FM_CATASTROPHIC_ERR_STALL_PORT = 0, /**< Port_ID is stalled (only reset can release it) */
77001 + e_FM_CATASTROPHIC_ERR_STALL_TASK /**< Only erroneous task is stalled */
77002 +} e_FmCatastrophicErr;
77003 +
77004 +/**************************************************************************//**
77005 + @Description Enum for selecting FPM DMA Error behavior
77006 +*//***************************************************************************/
77007 +typedef enum e_FmDmaErr {
77008 + e_FM_DMA_ERR_CATASTROPHIC = 0, /**< Dma error is treated as a catastrophic
77009 + error (e_FmCatastrophicErr)*/
77010 + e_FM_DMA_ERR_REPORT /**< Dma error is just reported */
77011 +} e_FmDmaErr;
77012 +
77013 +/**************************************************************************//**
77014 + @Description Enum for selecting DMA Emergency level by BMI emergency signal
77015 +*//***************************************************************************/
77016 +typedef enum e_FmDmaEmergencyLevel {
77017 + e_FM_DMA_EM_EBS = 0, /**< EBS emergency */
77018 + e_FM_DMA_EM_SOS /**< SOS emergency */
77019 +} e_FmDmaEmergencyLevel;
77020 +
77021 +/**************************************************************************//**
77022 + @Collection Enum for selecting DMA Emergency options
77023 +*//***************************************************************************/
77024 +typedef uint32_t fmEmergencyBus_t; /**< DMA emergency options */
77025 +
77026 +#define FM_DMA_MURAM_READ_EMERGENCY 0x00800000 /**< Enable emergency for MURAM1 */
77027 +#define FM_DMA_MURAM_WRITE_EMERGENCY 0x00400000 /**< Enable emergency for MURAM2 */
77028 +#define FM_DMA_EXT_BUS_EMERGENCY 0x00100000 /**< Enable emergency for external bus */
77029 +/* @} */
77030 +
77031 +/**************************************************************************//**
77032 + @Description A structure for defining DMA emergency level
77033 +*//***************************************************************************/
77034 +typedef struct t_FmDmaEmergency {
77035 + fmEmergencyBus_t emergencyBusSelect; /**< An OR of the busses where emergency
77036 + should be enabled */
77037 + e_FmDmaEmergencyLevel emergencyLevel; /**< EBS/SOS */
77038 +} t_FmDmaEmergency;
77039 +
77040 +/**************************************************************************//*
77041 + @Description structure for defining FM threshold
77042 +*//***************************************************************************/
77043 +typedef struct t_FmThresholds {
77044 + uint8_t dispLimit; /**< The number of times a frames may
77045 + be passed in the FM before assumed to
77046 + be looping. */
77047 + uint8_t prsDispTh; /**< This is the number pf packets that may be
77048 + queued in the parser dispatch queue*/
77049 + uint8_t plcrDispTh; /**< This is the number pf packets that may be
77050 + queued in the policer dispatch queue*/
77051 + uint8_t kgDispTh; /**< This is the number pf packets that may be
77052 + queued in the keygen dispatch queue*/
77053 + uint8_t bmiDispTh; /**< This is the number pf packets that may be
77054 + queued in the BMI dispatch queue*/
77055 + uint8_t qmiEnqDispTh; /**< This is the number pf packets that may be
77056 + queued in the QMI enqueue dispatch queue*/
77057 + uint8_t qmiDeqDispTh; /**< This is the number pf packets that may be
77058 + queued in the QMI dequeue dispatch queue*/
77059 + uint8_t fmCtl1DispTh; /**< This is the number pf packets that may be
77060 + queued in fmCtl1 dispatch queue*/
77061 + uint8_t fmCtl2DispTh; /**< This is the number pf packets that may be
77062 + queued in fmCtl2 dispatch queue*/
77063 +} t_FmThresholds;
77064 +
77065 +/**************************************************************************//*
77066 + @Description structure for defining DMA thresholds
77067 +*//***************************************************************************/
77068 +typedef struct t_FmDmaThresholds {
77069 + uint8_t assertEmergency; /**< When this value is reached,
77070 + assert emergency (Threshold)*/
77071 + uint8_t clearEmergency; /**< After emergency is asserted, it is held
77072 + until this value is reached (Hystheresis) */
77073 +} t_FmDmaThresholds;
77074 +
77075 +/**************************************************************************//**
77076 + @Function t_FmResetOnInitOverrideCallback
77077 +
77078 + @Description FMan specific reset on init user callback routine,
77079 + will be used to override the standard FMan reset on init procedure
77080 +
77081 + @Param[in] h_Fm - FMan handler
77082 +*//***************************************************************************/
77083 +typedef void (t_FmResetOnInitOverrideCallback)(t_Handle h_Fm);
77084 +
77085 +/**************************************************************************//**
77086 + @Function FM_ConfigResetOnInit
77087 +
77088 + @Description Define whether to reset the FM before initialization.
77089 + Change the default configuration [DEFAULT_resetOnInit].
77090 +
77091 + @Param[in] h_Fm A handle to an FM Module.
77092 + @Param[in] enable When TRUE, FM will be reset before any initialization.
77093 +
77094 + @Return E_OK on success; Error code otherwise.
77095 +
77096 + @Cautions Allowed only following FM_Config() and before FM_Init().
77097 + This routine should NOT be called from guest-partition
77098 + (i.e. guestId != NCSW_MASTER_ID)
77099 +*//***************************************************************************/
77100 +t_Error FM_ConfigResetOnInit(t_Handle h_Fm, bool enable);
77101 +
77102 +/**************************************************************************//**
77103 + @Function FM_ConfigResetOnInitOverrideCallback
77104 +
77105 + @Description Define a special reset of FM before initialization.
77106 + Change the default configuration [DEFAULT_resetOnInitOverrideCallback].
77107 +
77108 + @Param[in] h_Fm A handle to an FM Module.
77109 + @Param[in] f_ResetOnInitOverride FM specific reset on init user callback routine.
77110 +
77111 + @Return E_OK on success; Error code otherwise.
77112 +
77113 + @Cautions Allowed only following FM_Config() and before FM_Init().
77114 + This routine should NOT be called from guest-partition
77115 + (i.e. guestId != NCSW_MASTER_ID)
77116 +*//***************************************************************************/
77117 +t_Error FM_ConfigResetOnInitOverrideCallback(t_Handle h_Fm, t_FmResetOnInitOverrideCallback *f_ResetOnInitOverride);
77118 +
77119 +/**************************************************************************//**
77120 + @Function FM_ConfigTotalFifoSize
77121 +
77122 + @Description Define Total FIFO size for the whole FM.
77123 + Calling this routine changes the total Fifo size in the internal driver
77124 + data base from its default configuration [DEFAULT_totalFifoSize]
77125 +
77126 + @Param[in] h_Fm A handle to an FM Module.
77127 + @Param[in] totalFifoSize The selected new value.
77128 +
77129 + @Return E_OK on success; Error code otherwise.
77130 +
77131 + @Cautions Allowed only following FM_Config() and before FM_Init().
77132 + This routine should NOT be called from guest-partition
77133 + (i.e. guestId != NCSW_MASTER_ID)
77134 +*//***************************************************************************/
77135 +t_Error FM_ConfigTotalFifoSize(t_Handle h_Fm, uint32_t totalFifoSize);
77136 +
77137 + /**************************************************************************//**
77138 + @Function FM_ConfigDmaCacheOverride
77139 +
77140 + @Description Define cache override mode.
77141 + Calling this routine changes the cache override mode
77142 + in the internal driver data base from its default configuration [DEFAULT_cacheOverride]
77143 +
77144 + @Param[in] h_Fm A handle to an FM Module.
77145 + @Param[in] cacheOverride The selected new value.
77146 +
77147 + @Return E_OK on success; Error code otherwise.
77148 +
77149 + @Cautions Allowed only following FM_Config() and before FM_Init().
77150 + This routine should NOT be called from guest-partition
77151 + (i.e. guestId != NCSW_MASTER_ID)
77152 +*//***************************************************************************/
77153 +t_Error FM_ConfigDmaCacheOverride(t_Handle h_Fm, e_FmDmaCacheOverride cacheOverride);
77154 +
77155 +/**************************************************************************//**
77156 + @Function FM_ConfigDmaAidOverride
77157 +
77158 + @Description Define DMA AID override mode.
77159 + Calling this routine changes the AID override mode
77160 + in the internal driver data base from its default configuration [DEFAULT_aidOverride]
77161 +
77162 + @Param[in] h_Fm A handle to an FM Module.
77163 + @Param[in] aidOverride The selected new value.
77164 +
77165 + @Return E_OK on success; Error code otherwise.
77166 +
77167 + @Cautions Allowed only following FM_Config() and before FM_Init().
77168 + This routine should NOT be called from guest-partition
77169 + (i.e. guestId != NCSW_MASTER_ID)
77170 +*//***************************************************************************/
77171 +t_Error FM_ConfigDmaAidOverride(t_Handle h_Fm, bool aidOverride);
77172 +
77173 +/**************************************************************************//**
77174 + @Function FM_ConfigDmaAidMode
77175 +
77176 + @Description Define DMA AID mode.
77177 + Calling this routine changes the AID mode in the internal
77178 + driver data base from its default configuration [DEFAULT_aidMode]
77179 +
77180 + @Param[in] h_Fm A handle to an FM Module.
77181 + @Param[in] aidMode The selected new value.
77182 +
77183 + @Return E_OK on success; Error code otherwise.
77184 +
77185 + @Cautions Allowed only following FM_Config() and before FM_Init().
77186 + This routine should NOT be called from guest-partition
77187 + (i.e. guestId != NCSW_MASTER_ID)
77188 +*//***************************************************************************/
77189 +t_Error FM_ConfigDmaAidMode(t_Handle h_Fm, e_FmDmaAidMode aidMode);
77190 +
77191 +/**************************************************************************//**
77192 + @Function FM_ConfigDmaAxiDbgNumOfBeats
77193 +
77194 + @Description Define DMA AXI number of beats.
77195 + Calling this routine changes the AXI number of beats in the internal
77196 + driver data base from its default configuration [DEFAULT_axiDbgNumOfBeats]
77197 +
77198 + @Param[in] h_Fm A handle to an FM Module.
77199 + @Param[in] axiDbgNumOfBeats The selected new value.
77200 +
77201 + @Return E_OK on success; Error code otherwise.
77202 +
77203 + @Cautions Allowed only following FM_Config() and before FM_Init().
77204 + This routine should NOT be called from guest-partition
77205 + (i.e. guestId != NCSW_MASTER_ID)
77206 +*//***************************************************************************/
77207 +t_Error FM_ConfigDmaAxiDbgNumOfBeats(t_Handle h_Fm, uint8_t axiDbgNumOfBeats);
77208 +
77209 +/**************************************************************************//**
77210 + @Function FM_ConfigDmaCamNumOfEntries
77211 +
77212 + @Description Define number of CAM entries.
77213 + Calling this routine changes the number of CAM entries in the internal
77214 + driver data base from its default configuration [DEFAULT_dmaCamNumOfEntries].
77215 +
77216 + @Param[in] h_Fm A handle to an FM Module.
77217 + @Param[in] numOfEntries The selected new value.
77218 +
77219 + @Return E_OK on success; Error code otherwise.
77220 +
77221 + @Cautions Allowed only following FM_Config() and before FM_Init().
77222 + This routine should NOT be called from guest-partition
77223 + (i.e. guestId != NCSW_MASTER_ID)
77224 +*//***************************************************************************/
77225 +t_Error FM_ConfigDmaCamNumOfEntries(t_Handle h_Fm, uint8_t numOfEntries);
77226 +
77227 +/**************************************************************************//**
77228 + @Function FM_ConfigEnableCounters
77229 +
77230 + @Description Obsolete, always return E_OK.
77231 +
77232 + @Param[in] h_Fm A handle to an FM Module.
77233 +
77234 + @Return E_OK on success; Error code otherwise.
77235 +*//***************************************************************************/
77236 +t_Error FM_ConfigEnableCounters(t_Handle h_Fm);
77237 +
77238 +/**************************************************************************//**
77239 + @Function FM_ConfigDmaDbgCounter
77240 +
77241 + @Description Define DMA debug counter.
77242 + Calling this routine changes the number of the DMA debug counter in the internal
77243 + driver data base from its default configuration [DEFAULT_dmaDbgCntMode].
77244 +
77245 + @Param[in] h_Fm A handle to an FM Module.
77246 + @Param[in] fmDmaDbgCntMode An enum selecting the debug counter mode.
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_ConfigDmaDbgCounter(t_Handle h_Fm, e_FmDmaDbgCntMode fmDmaDbgCntMode);
77255 +
77256 +/**************************************************************************//**
77257 + @Function FM_ConfigDmaStopOnBusErr
77258 +
77259 + @Description Define bus error behavior.
77260 + Calling this routine changes the bus error behavior definition
77261 + in the internal driver data base from its default
77262 + configuration [DEFAULT_dmaStopOnBusError].
77263 +
77264 + @Param[in] h_Fm A handle to an FM Module.
77265 + @Param[in] stop TRUE to stop on bus error, FALSE to continue.
77266 +
77267 + @Return E_OK on success; Error code otherwise.
77268 +
77269 + @Cautions Allowed only following FM_Config() and before FM_Init().
77270 + Only if bus error is enabled.
77271 + This routine should NOT be called from guest-partition
77272 + (i.e. guestId != NCSW_MASTER_ID)
77273 +*//***************************************************************************/
77274 +t_Error FM_ConfigDmaStopOnBusErr(t_Handle h_Fm, bool stop);
77275 +
77276 +/**************************************************************************//**
77277 + @Function FM_ConfigDmaEmergency
77278 +
77279 + @Description Define DMA emergency.
77280 + Calling this routine changes the DMA emergency definition
77281 + in the internal driver data base from its default
77282 + configuration where's it's disabled.
77283 +
77284 + @Param[in] h_Fm A handle to an FM Module.
77285 + @Param[in] p_Emergency An OR mask of all required options.
77286 +
77287 + @Return E_OK on success; Error code otherwise.
77288 +
77289 + @Cautions Allowed only following FM_Config() and before FM_Init().
77290 + This routine should NOT be called from guest-partition
77291 + (i.e. guestId != NCSW_MASTER_ID)
77292 +*//***************************************************************************/
77293 +t_Error FM_ConfigDmaEmergency(t_Handle h_Fm, t_FmDmaEmergency *p_Emergency);
77294 +
77295 +/**************************************************************************//**
77296 + @Function FM_ConfigDmaErr
77297 +
77298 + @Description DMA error treatment.
77299 + Calling this routine changes the DMA error treatment
77300 + in the internal driver data base from its default
77301 + configuration [DEFAULT_dmaErr].
77302 +
77303 + @Param[in] h_Fm A handle to an FM Module.
77304 + @Param[in] dmaErr The selected new choice.
77305 +
77306 + @Return E_OK on success; Error code otherwise.
77307 +
77308 + @Cautions Allowed only following FM_Config() and before FM_Init().
77309 + This routine should NOT be called from guest-partition
77310 + (i.e. guestId != NCSW_MASTER_ID)
77311 +*//***************************************************************************/
77312 +t_Error FM_ConfigDmaErr(t_Handle h_Fm, e_FmDmaErr dmaErr);
77313 +
77314 +/**************************************************************************//**
77315 + @Function FM_ConfigCatastrophicErr
77316 +
77317 + @Description Define FM behavior on catastrophic error.
77318 + Calling this routine changes the FM behavior on catastrophic
77319 + error in the internal driver data base from its default
77320 + [DEFAULT_catastrophicErr].
77321 +
77322 + @Param[in] h_Fm A handle to an FM Module.
77323 + @Param[in] catastrophicErr The selected new choice.
77324 +
77325 + @Return E_OK on success; Error code otherwise.
77326 +
77327 + @Cautions Allowed only following FM_Config() and before FM_Init().
77328 + This routine should NOT be called from guest-partition
77329 + (i.e. guestId != NCSW_MASTER_ID)
77330 +*//***************************************************************************/
77331 +t_Error FM_ConfigCatastrophicErr(t_Handle h_Fm, e_FmCatastrophicErr catastrophicErr);
77332 +
77333 +/**************************************************************************//**
77334 + @Function FM_ConfigEnableMuramTestMode
77335 +
77336 + @Description Enable MURAM test mode.
77337 + Calling this routine changes the internal driver data base
77338 + from its default selection of test mode where it's disabled.
77339 + This routine is only avaiable on old FM revisions (FMan v2).
77340 +
77341 + @Param[in] h_Fm A handle to an FM Module.
77342 +
77343 + @Return E_OK on success; Error code otherwise.
77344 +
77345 + @Cautions Allowed only following FM_Config() and before FM_Init().
77346 + This routine should NOT be called from guest-partition
77347 + (i.e. guestId != NCSW_MASTER_ID)
77348 +*//***************************************************************************/
77349 +t_Error FM_ConfigEnableMuramTestMode(t_Handle h_Fm);
77350 +
77351 +/**************************************************************************//**
77352 + @Function FM_ConfigEnableIramTestMode
77353 +
77354 + @Description Enable IRAM test mode.
77355 + Calling this routine changes the internal driver data base
77356 + from its default selection of test mode where it's disabled.
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 +
77361 + @Return E_OK on success; Error code otherwise.
77362 +
77363 + @Cautions Allowed only following FM_Config() and before FM_Init().
77364 + This routine should NOT be called from guest-partition
77365 + (i.e. guestId != NCSW_MASTER_ID)
77366 +*//***************************************************************************/
77367 +t_Error FM_ConfigEnableIramTestMode(t_Handle h_Fm);
77368 +
77369 +/**************************************************************************//**
77370 + @Function FM_ConfigHaltOnExternalActivation
77371 +
77372 + @Description Define FM behavior on external halt activation.
77373 + Calling this routine changes the FM behavior on external halt
77374 + activation in the internal driver data base from its default
77375 + [DEFAULT_haltOnExternalActivation].
77376 +
77377 + @Param[in] h_Fm A handle to an FM Module.
77378 + @Param[in] enable TRUE to enable halt on external halt
77379 + activation.
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_ConfigHaltOnExternalActivation(t_Handle h_Fm, bool enable);
77388 +
77389 +/**************************************************************************//**
77390 + @Function FM_ConfigHaltOnUnrecoverableEccError
77391 +
77392 + @Description Define FM behavior on external halt activation.
77393 + Calling this routine changes the FM behavior on unrecoverable
77394 + ECC error in the internal driver data base from its default
77395 + [DEFAULT_haltOnUnrecoverableEccError].
77396 + This routine is only avaiable on old FM revisions (FMan v2).
77397 +
77398 + @Param[in] h_Fm A handle to an FM Module.
77399 + @Param[in] enable TRUE to enable halt on unrecoverable Ecc error
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_ConfigHaltOnUnrecoverableEccError(t_Handle h_Fm, bool enable);
77408 +
77409 +/**************************************************************************//**
77410 + @Function FM_ConfigException
77411 +
77412 + @Description Define FM exceptions.
77413 + Calling this routine changes the exceptions defaults in the
77414 + internal driver data base where all exceptions are enabled.
77415 +
77416 + @Param[in] h_Fm A handle to an FM Module.
77417 + @Param[in] exception The exception to be selected.
77418 + @Param[in] enable TRUE to enable interrupt, FALSE to mask it.
77419 +
77420 + @Return E_OK on success; Error code otherwise.
77421 +
77422 + @Cautions Allowed only following FM_Config() and before FM_Init().
77423 + This routine should NOT be called from guest-partition
77424 + (i.e. guestId != NCSW_MASTER_ID)
77425 +*//***************************************************************************/
77426 +t_Error FM_ConfigException(t_Handle h_Fm, e_FmExceptions exception, bool enable);
77427 +
77428 +/**************************************************************************//**
77429 + @Function FM_ConfigExternalEccRamsEnable
77430 +
77431 + @Description Select external ECC enabling.
77432 + Calling this routine changes the ECC enabling control in the internal
77433 + driver data base from its default [DEFAULT_externalEccRamsEnable].
77434 + When this option is enabled Rams ECC enabling is not effected
77435 + by FM_EnableRamsEcc/FM_DisableRamsEcc, but by a JTAG.
77436 +
77437 + @Param[in] h_Fm A handle to an FM Module.
77438 + @Param[in] enable TRUE to enable this option.
77439 +
77440 + @Return E_OK on success; Error code otherwise.
77441 +
77442 + @Cautions Allowed only following FM_Config() and before FM_Init().
77443 + This routine should NOT be called from guest-partition
77444 + (i.e. guestId != NCSW_MASTER_ID)
77445 +*//***************************************************************************/
77446 +t_Error FM_ConfigExternalEccRamsEnable(t_Handle h_Fm, bool enable);
77447 +
77448 +/**************************************************************************//**
77449 + @Function FM_ConfigTnumAgingPeriod
77450 +
77451 + @Description Define Tnum aging period.
77452 + Calling this routine changes the Tnum aging of dequeue TNUMs
77453 + in the QMI in the internal driver data base from its default
77454 + [DEFAULT_tnumAgingPeriod].
77455 +
77456 + @Param[in] h_Fm A handle to an FM Module.
77457 + @Param[in] tnumAgingPeriod Tnum Aging Period in microseconds.
77458 + Note that period is recalculated in units of
77459 + 64 FM clocks. Driver will pick the closest
77460 + possible period.
77461 +
77462 + @Return E_OK on success; Error code otherwise.
77463 +
77464 + @Cautions Allowed only following FM_Config() and before FM_Init().
77465 + This routine should NOT be called from guest-partition
77466 + (i.e. guestId != NCSW_MASTER_ID)
77467 + NOTE that if some MAC is configured for PFC, '0' value is NOT
77468 + allowed.
77469 +*//***************************************************************************/
77470 +t_Error FM_ConfigTnumAgingPeriod(t_Handle h_Fm, uint16_t tnumAgingPeriod);
77471 +
77472 +/**************************************************************************//*
77473 + @Function FM_ConfigDmaEmergencySmoother
77474 +
77475 + @Description Define DMA emergency smoother.
77476 + Calling this routine changes the definition of the minimum
77477 + amount of DATA beats transferred on the AXI READ and WRITE
77478 + ports before lowering the emergency level.
77479 + By default smoother is disabled.
77480 +
77481 + @Param[in] h_Fm A handle to an FM Module.
77482 + @Param[in] emergencyCnt emergency switching counter.
77483 +
77484 + @Return E_OK on success; Error code otherwise.
77485 +
77486 + @Cautions Allowed only following FM_Config() and before FM_Init().
77487 + This routine should NOT be called from guest-partition
77488 + (i.e. guestId != NCSW_MASTER_ID)
77489 +*//***************************************************************************/
77490 +t_Error FM_ConfigDmaEmergencySmoother(t_Handle h_Fm, uint32_t emergencyCnt);
77491 +
77492 +/**************************************************************************//*
77493 + @Function FM_ConfigThresholds
77494 +
77495 + @Description Calling this routine changes the internal driver data base
77496 + from its default FM threshold configuration:
77497 + dispLimit: [DEFAULT_dispLimit]
77498 + prsDispTh: [DEFAULT_prsDispTh]
77499 + plcrDispTh: [DEFAULT_plcrDispTh]
77500 + kgDispTh: [DEFAULT_kgDispTh]
77501 + bmiDispTh: [DEFAULT_bmiDispTh]
77502 + qmiEnqDispTh: [DEFAULT_qmiEnqDispTh]
77503 + qmiDeqDispTh: [DEFAULT_qmiDeqDispTh]
77504 + fmCtl1DispTh: [DEFAULT_fmCtl1DispTh]
77505 + fmCtl2DispTh: [DEFAULT_fmCtl2DispTh]
77506 +
77507 +
77508 + @Param[in] h_Fm A handle to an FM Module.
77509 + @Param[in] p_FmThresholds A structure of threshold parameters.
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_ConfigThresholds(t_Handle h_Fm, t_FmThresholds *p_FmThresholds);
77518 +
77519 +/**************************************************************************//*
77520 + @Function FM_ConfigDmaSosEmergencyThreshold
77521 +
77522 + @Description Calling this routine changes the internal driver data base
77523 + from its default dma SOS emergency configuration [DEFAULT_dmaSosEmergency]
77524 +
77525 + @Param[in] h_Fm A handle to an FM Module.
77526 + @Param[in] dmaSosEmergency The selected new value.
77527 +
77528 + @Return E_OK on success; Error code otherwise.
77529 +
77530 + @Cautions Allowed only following FM_Config() and before FM_Init().
77531 + This routine should NOT be called from guest-partition
77532 + (i.e. guestId != NCSW_MASTER_ID)
77533 +*//***************************************************************************/
77534 +t_Error FM_ConfigDmaSosEmergencyThreshold(t_Handle h_Fm, uint32_t dmaSosEmergency);
77535 +
77536 +/**************************************************************************//*
77537 + @Function FM_ConfigDmaWriteBufThresholds
77538 +
77539 + @Description Calling this routine changes the internal driver data base
77540 + from its default configuration of DMA write buffer threshold
77541 + assertEmergency: [DEFAULT_dmaWriteIntBufLow]
77542 + clearEmergency: [DEFAULT_dmaWriteIntBufHigh]
77543 + This routine is only avaiable on old FM revisions (FMan v2).
77544 +
77545 + @Param[in] h_Fm A handle to an FM Module.
77546 + @Param[in] p_FmDmaThresholds A structure of thresholds to define emergency behavior -
77547 + When 'assertEmergency' value is reached, emergency is asserted,
77548 + then it is held until 'clearEmergency' value is reached.
77549 +
77550 + @Return E_OK on success; Error code otherwise.
77551 +
77552 + @Cautions Allowed only following FM_Config() and before FM_Init().
77553 + This routine should NOT be called from guest-partition
77554 + (i.e. guestId != NCSW_MASTER_ID)
77555 +*//***************************************************************************/
77556 +t_Error FM_ConfigDmaWriteBufThresholds(t_Handle h_Fm, t_FmDmaThresholds *p_FmDmaThresholds);
77557 +
77558 + /**************************************************************************//*
77559 + @Function FM_ConfigDmaCommQThresholds
77560 +
77561 + @Description Calling this routine changes the internal driver data base
77562 + from its default configuration of DMA command queue threshold
77563 + assertEmergency: [DEFAULT_dmaCommQLow]
77564 + clearEmergency: [DEFAULT_dmaCommQHigh]
77565 +
77566 + @Param[in] h_Fm A handle to an FM Module.
77567 + @Param[in] p_FmDmaThresholds A structure of thresholds to define emergency behavior -
77568 + When 'assertEmergency' value is reached, emergency is asserted,
77569 + then it is held until 'clearEmergency' value is reached..
77570 +
77571 + @Return E_OK on success; Error code otherwise.
77572 +
77573 + @Cautions Allowed only following FM_Config() and before FM_Init().
77574 + This routine should NOT be called from guest-partition
77575 + (i.e. guestId != NCSW_MASTER_ID)
77576 +*//***************************************************************************/
77577 +t_Error FM_ConfigDmaCommQThresholds(t_Handle h_Fm, t_FmDmaThresholds *p_FmDmaThresholds);
77578 +
77579 +/**************************************************************************//*
77580 + @Function FM_ConfigDmaReadBufThresholds
77581 +
77582 + @Description Calling this routine changes the internal driver data base
77583 + from its default configuration of DMA read buffer threshold
77584 + assertEmergency: [DEFAULT_dmaReadIntBufLow]
77585 + clearEmergency: [DEFAULT_dmaReadIntBufHigh]
77586 + This routine is only avaiable on old FM revisions (FMan v2).
77587 +
77588 + @Param[in] h_Fm A handle to an FM Module.
77589 + @Param[in] p_FmDmaThresholds A structure of thresholds to define emergency behavior -
77590 + When 'assertEmergency' value is reached, emergency is asserted,
77591 + then it is held until 'clearEmergency' value is reached..
77592 +
77593 + @Return E_OK on success; Error code otherwise.
77594 +
77595 + @Cautions Allowed only following FM_Config() and before FM_Init().
77596 + This routine should NOT be called from guest-partition
77597 + (i.e. guestId != NCSW_MASTER_ID)
77598 +*//***************************************************************************/
77599 +t_Error FM_ConfigDmaReadBufThresholds(t_Handle h_Fm, t_FmDmaThresholds *p_FmDmaThresholds);
77600 +
77601 +/**************************************************************************//*
77602 + @Function FM_ConfigDmaWatchdog
77603 +
77604 + @Description Calling this routine changes the internal driver data base
77605 + from its default watchdog configuration, which is disabled
77606 + [DEFAULT_dmaWatchdog].
77607 +
77608 + @Param[in] h_Fm A handle to an FM Module.
77609 + @Param[in] watchDogValue The selected new value - in microseconds.
77610 +
77611 + @Return E_OK on success; Error code otherwise.
77612 +
77613 + @Cautions Allowed only following FM_Config() and before FM_Init().
77614 + This routine should NOT be called from guest-partition
77615 + (i.e. guestId != NCSW_MASTER_ID)
77616 +*//***************************************************************************/
77617 +t_Error FM_ConfigDmaWatchdog(t_Handle h_Fm, uint32_t watchDogValue);
77618 +
77619 +/** @} */ /* end of FM_advanced_init_grp group */
77620 +/** @} */ /* end of FM_init_grp group */
77621 +
77622 +
77623 +/**************************************************************************//**
77624 + @Group FM_runtime_control_grp FM Runtime Control Unit
77625 +
77626 + @Description FM Runtime control unit API functions, definitions and enums.
77627 + The FM driver provides a set of control routines.
77628 + These routines may only be called after the module was fully
77629 + initialized (both configuration and initialization routines were
77630 + called). They are typically used to get information from hardware
77631 + (status, counters/statistics, revision etc.), to modify a current
77632 + state or to force/enable a required action. Run-time control may
77633 + be called whenever necessary and as many times as needed.
77634 + @{
77635 +*//***************************************************************************/
77636 +
77637 +/**************************************************************************//**
77638 + @Collection General FM defines.
77639 +*//***************************************************************************/
77640 +#define FM_MAX_NUM_OF_VALID_PORTS (FM_MAX_NUM_OF_OH_PORTS + \
77641 + FM_MAX_NUM_OF_1G_RX_PORTS + \
77642 + FM_MAX_NUM_OF_10G_RX_PORTS + \
77643 + FM_MAX_NUM_OF_1G_TX_PORTS + \
77644 + FM_MAX_NUM_OF_10G_TX_PORTS) /**< Number of available FM ports */
77645 +/* @} */
77646 +
77647 +/**************************************************************************//*
77648 + @Description A Structure for Port bandwidth requirement. Port is identified
77649 + by type and relative id.
77650 +*//***************************************************************************/
77651 +typedef struct t_FmPortBandwidth {
77652 + e_FmPortType type; /**< FM port type */
77653 + uint8_t relativePortId; /**< Type relative port id */
77654 + uint8_t bandwidth; /**< bandwidth - (in term of percents) */
77655 +} t_FmPortBandwidth;
77656 +
77657 +/**************************************************************************//*
77658 + @Description A Structure containing an array of Port bandwidth requirements.
77659 + The user should state the ports requiring bandwidth in terms of
77660 + percentage - i.e. all port's bandwidths in the array must add
77661 + up to 100.
77662 +*//***************************************************************************/
77663 +typedef struct t_FmPortsBandwidthParams {
77664 + uint8_t numOfPorts; /**< The number of relevant ports, which is the
77665 + number of valid entries in the array below */
77666 + t_FmPortBandwidth portsBandwidths[FM_MAX_NUM_OF_VALID_PORTS];
77667 + /**< for each port, it's bandwidth (all port's
77668 + bandwidths must add up to 100.*/
77669 +} t_FmPortsBandwidthParams;
77670 +
77671 +/**************************************************************************//**
77672 + @Description DMA Emergency control on MURAM
77673 +*//***************************************************************************/
77674 +typedef enum e_FmDmaMuramPort {
77675 + e_FM_DMA_MURAM_PORT_WRITE, /**< MURAM write port */
77676 + e_FM_DMA_MURAM_PORT_READ /**< MURAM read port */
77677 +} e_FmDmaMuramPort;
77678 +
77679 +/**************************************************************************//**
77680 + @Description Enum for defining FM counters
77681 +*//***************************************************************************/
77682 +typedef enum e_FmCounters {
77683 + e_FM_COUNTERS_ENQ_TOTAL_FRAME = 0, /**< QMI total enqueued frames counter */
77684 + e_FM_COUNTERS_DEQ_TOTAL_FRAME, /**< QMI total dequeued frames counter */
77685 + e_FM_COUNTERS_DEQ_0, /**< QMI 0 frames from QMan counter */
77686 + e_FM_COUNTERS_DEQ_1, /**< QMI 1 frames from QMan counter */
77687 + e_FM_COUNTERS_DEQ_2, /**< QMI 2 frames from QMan counter */
77688 + e_FM_COUNTERS_DEQ_3, /**< QMI 3 frames from QMan counter */
77689 + e_FM_COUNTERS_DEQ_FROM_DEFAULT, /**< QMI dequeue from default queue counter */
77690 + e_FM_COUNTERS_DEQ_FROM_CONTEXT, /**< QMI dequeue from FQ context counter */
77691 + e_FM_COUNTERS_DEQ_FROM_FD, /**< QMI dequeue from FD command field counter */
77692 + e_FM_COUNTERS_DEQ_CONFIRM /**< QMI dequeue confirm counter */
77693 +} e_FmCounters;
77694 +
77695 +/**************************************************************************//**
77696 + @Description A Structure for returning FM revision information
77697 +*//***************************************************************************/
77698 +typedef struct t_FmRevisionInfo {
77699 + uint8_t majorRev; /**< Major revision */
77700 + uint8_t minorRev; /**< Minor revision */
77701 +} t_FmRevisionInfo;
77702 +
77703 +/**************************************************************************//**
77704 + @Description A Structure for returning FM ctrl code revision information
77705 +*//***************************************************************************/
77706 +typedef struct t_FmCtrlCodeRevisionInfo {
77707 + uint16_t packageRev; /**< Package revision */
77708 + uint8_t majorRev; /**< Major revision */
77709 + uint8_t minorRev; /**< Minor revision */
77710 +} t_FmCtrlCodeRevisionInfo;
77711 +
77712 +/**************************************************************************//**
77713 + @Description A Structure for defining DMA status
77714 +*//***************************************************************************/
77715 +typedef struct t_FmDmaStatus {
77716 + bool cmqNotEmpty; /**< Command queue is not empty */
77717 + bool busError; /**< Bus error occurred */
77718 + bool readBufEccError; /**< Double ECC error on buffer Read (Valid for FM rev < 6)*/
77719 + bool writeBufEccSysError; /**< Double ECC error on buffer write from system side (Valid for FM rev < 6)*/
77720 + bool writeBufEccFmError; /**< Double ECC error on buffer write from FM side (Valid for FM rev < 6) */
77721 + bool singlePortEccError; /**< Single Port ECC error from FM side (Valid for FM rev >= 6)*/
77722 +} t_FmDmaStatus;
77723 +
77724 +/**************************************************************************//**
77725 + @Description A Structure for obtaining FM controller monitor values
77726 +*//***************************************************************************/
77727 +typedef struct t_FmCtrlMon {
77728 + uint8_t percentCnt[2]; /**< Percentage value */
77729 +} t_FmCtrlMon;
77730 +
77731 +
77732 +#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
77733 +/**************************************************************************//**
77734 + @Function FM_DumpRegs
77735 +
77736 + @Description Dumps all FM registers
77737 +
77738 + @Param[in] h_Fm A handle to an FM Module.
77739 +
77740 + @Return E_OK on success;
77741 +
77742 + @Cautions Allowed only following FM_Init().
77743 +*//***************************************************************************/
77744 +t_Error FM_DumpRegs(t_Handle h_Fm);
77745 +#endif /* (defined(DEBUG_ERRORS) && ... */
77746 +
77747 +/**************************************************************************//**
77748 + @Function FM_SetException
77749 +
77750 + @Description Calling this routine enables/disables the specified exception.
77751 +
77752 + @Param[in] h_Fm A handle to an FM Module.
77753 + @Param[in] exception The exception to be selected.
77754 + @Param[in] enable TRUE to enable interrupt, FALSE to mask it.
77755 +
77756 + @Return E_OK on success; Error code otherwise.
77757 +
77758 + @Cautions Allowed only following FM_Init().
77759 + This routine should NOT be called from guest-partition
77760 + (i.e. guestId != NCSW_MASTER_ID)
77761 +*//***************************************************************************/
77762 +t_Error FM_SetException(t_Handle h_Fm, e_FmExceptions exception, bool enable);
77763 +
77764 +/**************************************************************************//**
77765 + @Function FM_EnableRamsEcc
77766 +
77767 + @Description Enables ECC mechanism for all the different FM RAM's; E.g. IRAM,
77768 + MURAM, Parser, Keygen, Policer, etc.
77769 + Note:
77770 + If FM_ConfigExternalEccRamsEnable was called to enable external
77771 + setting of ECC, this routine effects IRAM ECC only.
77772 + This routine is also called by the driver if an ECC exception is
77773 + enabled.
77774 +
77775 + @Param[in] h_Fm A handle to an FM Module.
77776 +
77777 + @Return E_OK on success; Error code otherwise.
77778 +
77779 + @Cautions Allowed only following FM_Config() and before FM_Init().
77780 + This routine should NOT be called from guest-partition
77781 + (i.e. guestId != NCSW_MASTER_ID)
77782 +*//***************************************************************************/
77783 +t_Error FM_EnableRamsEcc(t_Handle h_Fm);
77784 +
77785 +/**************************************************************************//**
77786 + @Function FM_DisableRamsEcc
77787 +
77788 + @Description Disables ECC mechanism for all the different FM RAM's; E.g. IRAM,
77789 + MURAM, Parser, Keygen, Policer, etc.
77790 + Note:
77791 + If FM_ConfigExternalEccRamsEnable was called to enable external
77792 + setting of ECC, this routine effects IRAM ECC only.
77793 + In opposed to FM_EnableRamsEcc, this routine must be called
77794 + explicitly to disable all Rams ECC.
77795 +
77796 + @Param[in] h_Fm A handle to an FM Module.
77797 +
77798 + @Return E_OK on success; Error code otherwise.
77799 +
77800 + @Cautions Allowed only following FM_Config() and before FM_Init().
77801 + This routine should NOT be called from guest-partition
77802 + (i.e. guestId != NCSW_MASTER_ID)
77803 +*//***************************************************************************/
77804 +t_Error FM_DisableRamsEcc(t_Handle h_Fm);
77805 +
77806 +/**************************************************************************//**
77807 + @Function FM_GetRevision
77808 +
77809 + @Description Returns the FM revision
77810 +
77811 + @Param[in] h_Fm A handle to an FM Module.
77812 + @Param[out] p_FmRevisionInfo A structure of revision information parameters.
77813 +
77814 + @Return E_OK on success; Error code otherwise.
77815 +
77816 + @Cautions Allowed only following FM_Init().
77817 +*//***************************************************************************/
77818 +t_Error FM_GetRevision(t_Handle h_Fm, t_FmRevisionInfo *p_FmRevisionInfo);
77819 +
77820 +/**************************************************************************//**
77821 + @Function FM_GetFmanCtrlCodeRevision
77822 +
77823 + @Description Returns the Fman controller code revision
77824 +
77825 + @Param[in] h_Fm A handle to an FM Module.
77826 + @Param[out] p_RevisionInfo A structure of revision information parameters.
77827 +
77828 + @Return E_OK on success; Error code otherwise.
77829 +
77830 + @Cautions Allowed only following FM_Init().
77831 +*//***************************************************************************/
77832 +t_Error FM_GetFmanCtrlCodeRevision(t_Handle h_Fm, t_FmCtrlCodeRevisionInfo *p_RevisionInfo);
77833 +
77834 +/**************************************************************************//**
77835 + @Function FM_GetCounter
77836 +
77837 + @Description Reads one of the FM counters.
77838 +
77839 + @Param[in] h_Fm A handle to an FM Module.
77840 + @Param[in] counter The requested counter.
77841 +
77842 + @Return Counter's current value.
77843 +
77844 + @Cautions Allowed only following FM_Init().
77845 + Note that it is user's responsibility to call this routine only
77846 + for enabled counters, and there will be no indication if a
77847 + disabled counter is accessed.
77848 +*//***************************************************************************/
77849 +uint32_t FM_GetCounter(t_Handle h_Fm, e_FmCounters counter);
77850 +
77851 +/**************************************************************************//**
77852 + @Function FM_ModifyCounter
77853 +
77854 + @Description Sets a value to an enabled counter. Use "0" to reset the counter.
77855 +
77856 + @Param[in] h_Fm A handle to an FM Module.
77857 + @Param[in] counter The requested counter.
77858 + @Param[in] val The requested value to be written into the counter.
77859 +
77860 + @Return E_OK on success; Error code otherwise.
77861 +
77862 + @Cautions Allowed only following FM_Init().
77863 + This routine should NOT be called from guest-partition
77864 + (i.e. guestId != NCSW_MASTER_ID)
77865 +*//***************************************************************************/
77866 +t_Error FM_ModifyCounter(t_Handle h_Fm, e_FmCounters counter, uint32_t val);
77867 +
77868 +/**************************************************************************//**
77869 + @Function FM_Resume
77870 +
77871 + @Description Release FM after halt FM command or after unrecoverable ECC error.
77872 +
77873 + @Param[in] h_Fm A handle to an FM Module.
77874 +
77875 + @Return E_OK on success; Error code otherwise.
77876 +
77877 + @Cautions Allowed only following FM_Init().
77878 + This routine should NOT be called from guest-partition
77879 + (i.e. guestId != NCSW_MASTER_ID)
77880 +*//***************************************************************************/
77881 +void FM_Resume(t_Handle h_Fm);
77882 +
77883 +/**************************************************************************//**
77884 + @Function FM_SetDmaEmergency
77885 +
77886 + @Description Manual emergency set
77887 +
77888 + @Param[in] h_Fm A handle to an FM Module.
77889 + @Param[in] muramPort MURAM direction select.
77890 + @Param[in] enable TRUE to manually enable emergency, FALSE to disable.
77891 +
77892 + @Return None.
77893 +
77894 + @Cautions Allowed only following FM_Init().
77895 + This routine should NOT be called from guest-partition
77896 + (i.e. guestId != NCSW_MASTER_ID)
77897 +*//***************************************************************************/
77898 +void FM_SetDmaEmergency(t_Handle h_Fm, e_FmDmaMuramPort muramPort, bool enable);
77899 +
77900 +/**************************************************************************//**
77901 + @Function FM_SetDmaExtBusPri
77902 +
77903 + @Description Set the DMA external bus priority
77904 +
77905 + @Param[in] h_Fm A handle to an FM Module.
77906 + @Param[in] pri External bus priority select
77907 +
77908 + @Return None.
77909 +
77910 + @Cautions Allowed only following FM_Init().
77911 + This routine should NOT be called from guest-partition
77912 + (i.e. guestId != NCSW_MASTER_ID)
77913 +*//***************************************************************************/
77914 +void FM_SetDmaExtBusPri(t_Handle h_Fm, e_FmDmaExtBusPri pri);
77915 +
77916 +/**************************************************************************//**
77917 + @Function FM_GetDmaStatus
77918 +
77919 + @Description Reads the DMA current status
77920 +
77921 + @Param[in] h_Fm A handle to an FM Module.
77922 + @Param[out] p_FmDmaStatus A structure of DMA status parameters.
77923 +
77924 + @Cautions Allowed only following FM_Init().
77925 +*//***************************************************************************/
77926 +void FM_GetDmaStatus(t_Handle h_Fm, t_FmDmaStatus *p_FmDmaStatus);
77927 +
77928 +/**************************************************************************//**
77929 + @Function FM_ErrorIsr
77930 +
77931 + @Description FM interrupt-service-routine for errors.
77932 +
77933 + @Param[in] h_Fm A handle to an FM Module.
77934 +
77935 + @Return E_OK on success; E_EMPTY if no errors found in register, other
77936 + error code otherwise.
77937 +
77938 + @Cautions Allowed only following FM_Init().
77939 + This routine should NOT be called from guest-partition
77940 + (i.e. guestId != NCSW_MASTER_ID)
77941 +*//***************************************************************************/
77942 +t_Error FM_ErrorIsr(t_Handle h_Fm);
77943 +
77944 +/**************************************************************************//**
77945 + @Function FM_EventIsr
77946 +
77947 + @Description FM interrupt-service-routine for normal events.
77948 +
77949 + @Param[in] h_Fm A handle to an FM Module.
77950 +
77951 + @Cautions Allowed only following FM_Init().
77952 + This routine should NOT be called from guest-partition
77953 + (i.e. guestId != NCSW_MASTER_ID)
77954 +*//***************************************************************************/
77955 +void FM_EventIsr(t_Handle h_Fm);
77956 +
77957 +/**************************************************************************//**
77958 + @Function FM_GetSpecialOperationCoding
77959 +
77960 + @Description Return a specific coding according to the input mask.
77961 +
77962 + @Param[in] h_Fm A handle to an FM Module.
77963 + @Param[in] spOper special operation mask.
77964 + @Param[out] p_SpOperCoding special operation code.
77965 +
77966 + @Return E_OK on success; Error code otherwise.
77967 +
77968 + @Cautions Allowed only following FM_Init().
77969 +*//***************************************************************************/
77970 +t_Error FM_GetSpecialOperationCoding(t_Handle h_Fm,
77971 + fmSpecialOperations_t spOper,
77972 + uint8_t *p_SpOperCoding);
77973 +
77974 +/**************************************************************************//**
77975 + @Function FM_CtrlMonStart
77976 +
77977 + @Description Start monitoring utilization of all available FM controllers.
77978 +
77979 + In order to obtain FM controllers utilization the following sequence
77980 + should be used:
77981 + -# FM_CtrlMonStart()
77982 + -# FM_CtrlMonStop()
77983 + -# FM_CtrlMonGetCounters() - issued for each FM controller
77984 +
77985 + @Param[in] h_Fm A handle to an FM Module.
77986 +
77987 + @Return E_OK on success; Error code otherwise.
77988 +
77989 + @Cautions Allowed only following FM_Init().
77990 + This routine should NOT be called from guest-partition
77991 + (i.e. guestId != NCSW_MASTER_ID).
77992 +*//***************************************************************************/
77993 +t_Error FM_CtrlMonStart(t_Handle h_Fm);
77994 +
77995 +/**************************************************************************//**
77996 + @Function FM_CtrlMonStop
77997 +
77998 + @Description Stop monitoring utilization of all available FM controllers.
77999 +
78000 + In order to obtain FM controllers utilization the following sequence
78001 + should be used:
78002 + -# FM_CtrlMonStart()
78003 + -# FM_CtrlMonStop()
78004 + -# FM_CtrlMonGetCounters() - issued for each FM controller
78005 +
78006 + @Param[in] h_Fm A handle to an FM Module.
78007 +
78008 + @Return E_OK on success; Error code otherwise.
78009 +
78010 + @Cautions Allowed only following FM_Init().
78011 + This routine should NOT be called from guest-partition
78012 + (i.e. guestId != NCSW_MASTER_ID).
78013 +*//***************************************************************************/
78014 +t_Error FM_CtrlMonStop(t_Handle h_Fm);
78015 +
78016 +/**************************************************************************//**
78017 + @Function FM_CtrlMonGetCounters
78018 +
78019 + @Description Obtain FM controller utilization parameters.
78020 +
78021 + In order to obtain FM controllers utilization the following sequence
78022 + should be used:
78023 + -# FM_CtrlMonStart()
78024 + -# FM_CtrlMonStop()
78025 + -# FM_CtrlMonGetCounters() - issued for each FM controller
78026 +
78027 + @Param[in] h_Fm A handle to an FM Module.
78028 + @Param[in] fmCtrlIndex FM Controller index for that utilization results
78029 + are requested.
78030 + @Param[in] p_Mon Pointer to utilization results structure.
78031 +
78032 + @Return E_OK on success; Error code otherwise.
78033 +
78034 + @Cautions Allowed only following FM_Init().
78035 + This routine should NOT be called from guest-partition
78036 + (i.e. guestId != NCSW_MASTER_ID).
78037 +*//***************************************************************************/
78038 +t_Error FM_CtrlMonGetCounters(t_Handle h_Fm, uint8_t fmCtrlIndex, t_FmCtrlMon *p_Mon);
78039 +
78040 +
78041 +/**************************************************************************//*
78042 + @Function FM_ForceIntr
78043 +
78044 + @Description Causes an interrupt event on the requested source.
78045 +
78046 + @Param[in] h_Fm A handle to an FM Module.
78047 + @Param[in] exception An exception to be forced.
78048 +
78049 + @Return E_OK on success; Error code if the exception is not enabled,
78050 + or is not able to create interrupt.
78051 +
78052 + @Cautions Allowed only following FM_Init().
78053 + This routine should NOT be called from guest-partition
78054 + (i.e. guestId != NCSW_MASTER_ID)
78055 +*//***************************************************************************/
78056 +t_Error FM_ForceIntr (t_Handle h_Fm, e_FmExceptions exception);
78057 +
78058 +/**************************************************************************//*
78059 + @Function FM_SetPortsBandwidth
78060 +
78061 + @Description Sets relative weights between ports when accessing common resources.
78062 +
78063 + @Param[in] h_Fm A handle to an FM Module.
78064 + @Param[in] p_PortsBandwidth A structure of ports bandwidths in percentage, i.e.
78065 + total must equal 100.
78066 +
78067 + @Return E_OK on success; Error code otherwise.
78068 +
78069 + @Cautions Allowed only following FM_Init().
78070 + This routine should NOT be called from guest-partition
78071 + (i.e. guestId != NCSW_MASTER_ID)
78072 +*//***************************************************************************/
78073 +t_Error FM_SetPortsBandwidth(t_Handle h_Fm, t_FmPortsBandwidthParams *p_PortsBandwidth);
78074 +
78075 +/**************************************************************************//*
78076 + @Function FM_GetMuramHandle
78077 +
78078 + @Description Gets the corresponding MURAM handle
78079 +
78080 + @Param[in] h_Fm A handle to an FM Module.
78081 +
78082 + @Return MURAM handle; NULL otherwise.
78083 +
78084 + @Cautions Allowed only following FM_Init().
78085 + This routine should NOT be called from guest-partition
78086 + (i.e. guestId != NCSW_MASTER_ID)
78087 +*//***************************************************************************/
78088 +t_Handle FM_GetMuramHandle(t_Handle h_Fm);
78089 +
78090 +/** @} */ /* end of FM_runtime_control_grp group */
78091 +/** @} */ /* end of FM_lib_grp group */
78092 +/** @} */ /* end of FM_grp group */
78093 +
78094 +
78095 +#ifdef NCSW_BACKWARD_COMPATIBLE_API
78096 +typedef t_FmFirmwareParams t_FmPcdFirmwareParams;
78097 +typedef t_FmBufferPrefixContent t_FmPortBufferPrefixContent;
78098 +typedef t_FmExtPoolParams t_FmPortExtPoolParams;
78099 +typedef t_FmExtPools t_FmPortExtPools;
78100 +typedef t_FmBackupBmPools t_FmPortBackupBmPools;
78101 +typedef t_FmBufPoolDepletion t_FmPortBufPoolDepletion;
78102 +typedef e_FmDmaSwapOption e_FmPortDmaSwapOption;
78103 +typedef e_FmDmaCacheOption e_FmPortDmaCacheOption;
78104 +
78105 +#define FM_CONTEXTA_GET_OVVERIDE FM_CONTEXTA_GET_OVERRIDE
78106 +#define FM_CONTEXTA_SET_OVVERIDE FM_CONTEXTA_SET_OVERRIDE
78107 +
78108 +#define e_FM_EX_BMI_PIPELINE_ECC e_FM_EX_BMI_STORAGE_PROFILE_ECC
78109 +#define e_FM_PORT_DMA_NO_SWP e_FM_DMA_NO_SWP
78110 +#define e_FM_PORT_DMA_SWP_PPC_LE e_FM_DMA_SWP_PPC_LE
78111 +#define e_FM_PORT_DMA_SWP_BE e_FM_DMA_SWP_BE
78112 +#define e_FM_PORT_DMA_NO_STASH e_FM_DMA_NO_STASH
78113 +#define e_FM_PORT_DMA_STASH e_FM_DMA_STASH
78114 +#endif /* NCSW_BACKWARD_COMPATIBLE_API */
78115 +
78116 +
78117 +#endif /* __FM_EXT */
78118 --- /dev/null
78119 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/Peripherals/fm_mac_ext.h
78120 @@ -0,0 +1,887 @@
78121 +/*
78122 + * Copyright 2008-2012 Freescale Semiconductor Inc.
78123 + *
78124 + * Redistribution and use in source and binary forms, with or without
78125 + * modification, are permitted provided that the following conditions are met:
78126 + * * Redistributions of source code must retain the above copyright
78127 + * notice, this list of conditions and the following disclaimer.
78128 + * * Redistributions in binary form must reproduce the above copyright
78129 + * notice, this list of conditions and the following disclaimer in the
78130 + * documentation and/or other materials provided with the distribution.
78131 + * * Neither the name of Freescale Semiconductor nor the
78132 + * names of its contributors may be used to endorse or promote products
78133 + * derived from this software without specific prior written permission.
78134 + *
78135 + *
78136 + * ALTERNATIVELY, this software may be distributed under the terms of the
78137 + * GNU General Public License ("GPL") as published by the Free Software
78138 + * Foundation, either version 2 of that License or (at your option) any
78139 + * later version.
78140 + *
78141 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
78142 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
78143 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
78144 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
78145 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
78146 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
78147 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
78148 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
78149 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
78150 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
78151 + */
78152 +
78153 +
78154 +/**************************************************************************//**
78155 + @File fm_mac_ext.h
78156 +
78157 + @Description FM MAC ...
78158 +*//***************************************************************************/
78159 +#ifndef __FM_MAC_EXT_H
78160 +#define __FM_MAC_EXT_H
78161 +
78162 +#include "std_ext.h"
78163 +#include "enet_ext.h"
78164 +
78165 +
78166 +/**************************************************************************//**
78167 +
78168 + @Group FM_grp Frame Manager API
78169 +
78170 + @Description FM API functions, definitions and enums
78171 +
78172 + @{
78173 +*//***************************************************************************/
78174 +
78175 +/**************************************************************************//**
78176 + @Group FM_mac_grp FM MAC
78177 +
78178 + @Description FM MAC API functions, definitions and enums
78179 +
78180 + @{
78181 +*//***************************************************************************/
78182 +
78183 +#define FM_MAC_NO_PFC 0xff
78184 +
78185 +
78186 +/**************************************************************************//**
78187 + @Description FM MAC Exceptions
78188 +*//***************************************************************************/
78189 +typedef enum e_FmMacExceptions {
78190 + e_FM_MAC_EX_10G_MDIO_SCAN_EVENTMDIO = 0 /**< 10GEC MDIO scan event interrupt */
78191 + ,e_FM_MAC_EX_10G_MDIO_CMD_CMPL /**< 10GEC MDIO command completion interrupt */
78192 + ,e_FM_MAC_EX_10G_REM_FAULT /**< 10GEC, mEMAC Remote fault interrupt */
78193 + ,e_FM_MAC_EX_10G_LOC_FAULT /**< 10GEC, mEMAC Local fault interrupt */
78194 + ,e_FM_MAC_EX_10G_1TX_ECC_ER /**< 10GEC, mEMAC Transmit frame ECC error interrupt */
78195 + ,e_FM_MAC_EX_10G_TX_FIFO_UNFL /**< 10GEC, mEMAC Transmit FIFO underflow interrupt */
78196 + ,e_FM_MAC_EX_10G_TX_FIFO_OVFL /**< 10GEC, mEMAC Transmit FIFO overflow interrupt */
78197 + ,e_FM_MAC_EX_10G_TX_ER /**< 10GEC Transmit frame error interrupt */
78198 + ,e_FM_MAC_EX_10G_RX_FIFO_OVFL /**< 10GEC, mEMAC Receive FIFO overflow interrupt */
78199 + ,e_FM_MAC_EX_10G_RX_ECC_ER /**< 10GEC, mEMAC Receive frame ECC error interrupt */
78200 + ,e_FM_MAC_EX_10G_RX_JAB_FRM /**< 10GEC Receive jabber frame interrupt */
78201 + ,e_FM_MAC_EX_10G_RX_OVRSZ_FRM /**< 10GEC Receive oversized frame interrupt */
78202 + ,e_FM_MAC_EX_10G_RX_RUNT_FRM /**< 10GEC Receive runt frame interrupt */
78203 + ,e_FM_MAC_EX_10G_RX_FRAG_FRM /**< 10GEC Receive fragment frame interrupt */
78204 + ,e_FM_MAC_EX_10G_RX_LEN_ER /**< 10GEC Receive payload length error interrupt */
78205 + ,e_FM_MAC_EX_10G_RX_CRC_ER /**< 10GEC Receive CRC error interrupt */
78206 + ,e_FM_MAC_EX_10G_RX_ALIGN_ER /**< 10GEC Receive alignment error interrupt */
78207 + ,e_FM_MAC_EX_1G_BAB_RX /**< dTSEC Babbling receive error */
78208 + ,e_FM_MAC_EX_1G_RX_CTL /**< dTSEC Receive control (pause frame) interrupt */
78209 + ,e_FM_MAC_EX_1G_GRATEFUL_TX_STP_COMPLET /**< dTSEC Graceful transmit stop complete */
78210 + ,e_FM_MAC_EX_1G_BAB_TX /**< dTSEC Babbling transmit error */
78211 + ,e_FM_MAC_EX_1G_TX_CTL /**< dTSEC Transmit control (pause frame) interrupt */
78212 + ,e_FM_MAC_EX_1G_TX_ERR /**< dTSEC Transmit error */
78213 + ,e_FM_MAC_EX_1G_LATE_COL /**< dTSEC Late collision */
78214 + ,e_FM_MAC_EX_1G_COL_RET_LMT /**< dTSEC Collision retry limit */
78215 + ,e_FM_MAC_EX_1G_TX_FIFO_UNDRN /**< dTSEC Transmit FIFO underrun */
78216 + ,e_FM_MAC_EX_1G_MAG_PCKT /**< dTSEC Magic Packet detection */
78217 + ,e_FM_MAC_EX_1G_MII_MNG_RD_COMPLET /**< dTSEC MII management read completion */
78218 + ,e_FM_MAC_EX_1G_MII_MNG_WR_COMPLET /**< dTSEC MII management write completion */
78219 + ,e_FM_MAC_EX_1G_GRATEFUL_RX_STP_COMPLET /**< dTSEC Graceful receive stop complete */
78220 + ,e_FM_MAC_EX_1G_TX_DATA_ERR /**< dTSEC Internal data error on transmit */
78221 + ,e_FM_MAC_EX_1G_RX_DATA_ERR /**< dTSEC Internal data error on receive */
78222 + ,e_FM_MAC_EX_1G_1588_TS_RX_ERR /**< dTSEC Time-Stamp Receive Error */
78223 + ,e_FM_MAC_EX_1G_RX_MIB_CNT_OVFL /**< dTSEC MIB counter overflow */
78224 + ,e_FM_MAC_EX_TS_FIFO_ECC_ERR /**< mEMAC Time-stamp FIFO ECC error interrupt;
78225 + not supported on T4240/B4860 rev1 chips */
78226 + ,e_FM_MAC_EX_MAGIC_PACKET_INDICATION = e_FM_MAC_EX_1G_MAG_PCKT
78227 + /**< mEMAC Magic Packet Indication Interrupt */
78228 +} e_FmMacExceptions;
78229 +
78230 +/**************************************************************************//**
78231 + @Description TM MAC statistics level
78232 +*//***************************************************************************/
78233 +typedef enum e_FmMacStatisticsLevel {
78234 + e_FM_MAC_NONE_STATISTICS = 0, /**< No statistics */
78235 + e_FM_MAC_PARTIAL_STATISTICS, /**< Only error counters are available; Optimized for performance */
78236 + e_FM_MAC_FULL_STATISTICS /**< All counters available; Not optimized for performance */
78237 +} e_FmMacStatisticsLevel;
78238 +
78239 +
78240 +#if (DPAA_VERSION >= 11)
78241 +/**************************************************************************//**
78242 + @Description Priority Flow Control Parameters
78243 +*//***************************************************************************/
78244 +typedef struct t_FmMacPfcParams {
78245 + bool pfcEnable; /**< Enable/Disable PFC */
78246 +
78247 + 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*/
78248 +
78249 + 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*/
78250 +
78251 +
78252 +} t_FmMacPfcParams;
78253 +#endif /* (DPAA_VERSION >= 11) */
78254 +
78255 +/**************************************************************************//**
78256 + @Function t_FmMacExceptionCallback
78257 +
78258 + @Description Fm Mac Exception Callback from FM MAC to the user
78259 +
78260 + @Param[in] h_App - Handle to the upper layer handler
78261 +
78262 + @Param[in] exceptions - The exception that occurred
78263 +
78264 + @Return void.
78265 +*//***************************************************************************/
78266 +typedef void (t_FmMacExceptionCallback)(t_Handle h_App, e_FmMacExceptions exceptions);
78267 +
78268 +
78269 +/**************************************************************************//**
78270 + @Description TM MAC statistics rfc3635
78271 +*//***************************************************************************/
78272 +typedef struct t_FmMacStatistics {
78273 +/* RMON */
78274 + uint64_t eStatPkts64; /**< r-10G tr-DT 64 byte frame counter */
78275 + uint64_t eStatPkts65to127; /**< r-10G 65 to 127 byte frame counter */
78276 + uint64_t eStatPkts128to255; /**< r-10G 128 to 255 byte frame counter */
78277 + uint64_t eStatPkts256to511; /**< r-10G 256 to 511 byte frame counter */
78278 + uint64_t eStatPkts512to1023; /**< r-10G 512 to 1023 byte frame counter */
78279 + uint64_t eStatPkts1024to1518; /**< r-10G 1024 to 1518 byte frame counter */
78280 + uint64_t eStatPkts1519to1522; /**< r-10G 1519 to 1522 byte good frame count */
78281 +/* */
78282 + uint64_t eStatFragments; /**< Total number of packets that were less than 64 octets long with a wrong CRC.*/
78283 + uint64_t eStatJabbers; /**< Total number of packets longer than valid maximum length octets */
78284 + uint64_t eStatsDropEvents; /**< number of dropped packets due to internal errors of the MAC Client (during receive). */
78285 + uint64_t eStatCRCAlignErrors; /**< Incremented when frames of correct length but with CRC error are received.*/
78286 + uint64_t eStatUndersizePkts; /**< Incremented for frames under 64 bytes with a valid FCS and otherwise well formed;
78287 + This count does not include range length errors */
78288 + uint64_t eStatOversizePkts; /**< Incremented for frames which exceed 1518 (non VLAN) or 1522 (VLAN) and contains
78289 + a valid FCS and otherwise well formed */
78290 +/* Pause */
78291 + uint64_t teStatPause; /**< Pause MAC Control received */
78292 + uint64_t reStatPause; /**< Pause MAC Control sent */
78293 +/* MIB II */
78294 + uint64_t ifInOctets; /**< Total number of byte received. */
78295 + uint64_t ifInPkts; /**< Total number of packets received.*/
78296 + uint64_t ifInUcastPkts; /**< Total number of unicast frame received;
78297 + NOTE: this counter is not supported on dTSEC MAC */
78298 + uint64_t ifInMcastPkts; /**< Total number of multicast frame received*/
78299 + uint64_t ifInBcastPkts; /**< Total number of broadcast frame received */
78300 + uint64_t ifInDiscards; /**< Frames received, but discarded due to problems within the MAC RX. */
78301 + uint64_t ifInErrors; /**< Number of frames received with error:
78302 + - FIFO Overflow Error
78303 + - CRC Error
78304 + - Frame Too Long Error
78305 + - Alignment Error
78306 + - The dedicated Error Code (0xfe, not a code error) was received */
78307 + uint64_t ifOutOctets; /**< Total number of byte sent. */
78308 + uint64_t ifOutPkts; /**< Total number of packets sent .*/
78309 + uint64_t ifOutUcastPkts; /**< Total number of unicast frame sent;
78310 + NOTE: this counter is not supported on dTSEC MAC */
78311 + uint64_t ifOutMcastPkts; /**< Total number of multicast frame sent */
78312 + uint64_t ifOutBcastPkts; /**< Total number of multicast frame sent */
78313 + uint64_t ifOutDiscards; /**< Frames received, but discarded due to problems within the MAC TX N/A!.*/
78314 + uint64_t ifOutErrors; /**< Number of frames transmitted with error:
78315 + - FIFO Overflow Error
78316 + - FIFO Underflow Error
78317 + - Other */
78318 +} t_FmMacStatistics;
78319 +
78320 +/**************************************************************************//**
78321 + @Description FM MAC Frame Size Counters
78322 +*//***************************************************************************/
78323 +typedef struct t_FmMacFrameSizeCounters {
78324 +
78325 + uint64_t count_pkts_64; /**< 64 byte frame counter */
78326 + uint64_t count_pkts_65_to_127; /**< 65 to 127 byte frame counter */
78327 + uint64_t count_pkts_128_to_255; /**< 128 to 255 byte frame counter */
78328 + uint64_t count_pkts_256_to_511; /**< 256 to 511 byte frame counter */
78329 + uint64_t count_pkts_512_to_1023; /**< 512 to 1023 byte frame counter */
78330 + uint64_t count_pkts_1024_to_1518; /**< 1024 to 1518 byte frame counter */
78331 + uint64_t count_pkts_1519_to_1522; /**< 1519 to 1522 byte good frame count */
78332 +} t_FmMacFrameSizeCounters;
78333 +
78334 +/**************************************************************************//**
78335 + @Group FM_mac_init_grp FM MAC Initialization Unit
78336 +
78337 + @Description FM MAC Initialization Unit
78338 +
78339 + @{
78340 +*//***************************************************************************/
78341 +
78342 +/**************************************************************************//**
78343 + @Description FM MAC config input
78344 +*//***************************************************************************/
78345 +typedef struct t_FmMacParams {
78346 + uintptr_t baseAddr; /**< Base of memory mapped FM MAC registers */
78347 + t_EnetAddr addr; /**< MAC address of device; First octet is sent first */
78348 + uint8_t macId; /**< MAC ID;
78349 + numbering of dTSEC and 1G-mEMAC:
78350 + 0 - FM_MAX_NUM_OF_1G_MACS;
78351 + numbering of 10G-MAC (TGEC) and 10G-mEMAC:
78352 + 0 - FM_MAX_NUM_OF_10G_MACS */
78353 + e_EnetMode enetMode; /**< Ethernet operation mode (MAC-PHY interface and speed);
78354 + Note that the speed should indicate the maximum rate that
78355 + this MAC should support rather than the actual speed;
78356 + i.e. user should use the FM_MAC_AdjustLink() routine to
78357 + provide accurate speed;
78358 + In case of mEMAC RGMII mode, the MAC is configured to RGMII
78359 + automatic mode, where actual speed/duplex mode information
78360 + is provided by PHY automatically in-band; FM_MAC_AdjustLink()
78361 + function should be used to switch to manual RGMII speed/duplex mode
78362 + configuration if RGMII PHY doesn't support in-band status signaling;
78363 + In addition, in mEMAC, in case where user is using the higher MACs
78364 + (i.e. the MACs that should support 10G), user should pass here
78365 + speed=10000 even if the interface is not allowing that (e.g. SGMII). */
78366 + t_Handle h_Fm; /**< A handle to the FM object this port related to */
78367 + int mdioIrq; /**< MDIO exceptions interrupt source - not valid for all
78368 + MACs; MUST be set to 'NO_IRQ' for MACs that don't have
78369 + mdio-irq, or for polling */
78370 + t_FmMacExceptionCallback *f_Event; /**< MDIO Events Callback Routine */
78371 + t_FmMacExceptionCallback *f_Exception; /**< Exception Callback Routine */
78372 + t_Handle h_App; /**< A handle to an application layer object; This handle will
78373 + be passed by the driver upon calling the above callbacks */
78374 +} t_FmMacParams;
78375 +
78376 +
78377 +/**************************************************************************//**
78378 + @Function FM_MAC_Config
78379 +
78380 + @Description Creates descriptor for the FM MAC module.
78381 +
78382 + The routine returns a handle (descriptor) to the FM MAC object.
78383 + This descriptor must be passed as first parameter to all other
78384 + FM MAC function calls.
78385 +
78386 + No actual initialization or configuration of FM MAC hardware is
78387 + done by this routine.
78388 +
78389 + @Param[in] p_FmMacParam - Pointer to data structure of parameters
78390 +
78391 + @Retval Handle to FM MAC object, or NULL for Failure.
78392 +*//***************************************************************************/
78393 +t_Handle FM_MAC_Config(t_FmMacParams *p_FmMacParam);
78394 +
78395 +/**************************************************************************//**
78396 + @Function FM_MAC_Init
78397 +
78398 + @Description Initializes the FM MAC module
78399 +
78400 + @Param[in] h_FmMac - FM module descriptor
78401 +
78402 + @Return E_OK on success; Error code otherwise.
78403 +*//***************************************************************************/
78404 +t_Error FM_MAC_Init(t_Handle h_FmMac);
78405 +
78406 +/**************************************************************************//**
78407 + @Function FM_Free
78408 +
78409 + @Description Frees all resources that were assigned to FM MAC module.
78410 +
78411 + Calling this routine invalidates the descriptor.
78412 +
78413 + @Param[in] h_FmMac - FM module descriptor
78414 +
78415 + @Return E_OK on success; Error code otherwise.
78416 +*//***************************************************************************/
78417 +t_Error FM_MAC_Free(t_Handle h_FmMac);
78418 +
78419 +
78420 +/**************************************************************************//**
78421 + @Group FM_mac_advanced_init_grp FM MAC Advanced Configuration Unit
78422 +
78423 + @Description Configuration functions used to change default values.
78424 +
78425 + @{
78426 +*//***************************************************************************/
78427 +
78428 +/**************************************************************************//**
78429 + @Function FM_MAC_ConfigResetOnInit
78430 +
78431 + @Description Tell the driver whether to reset the FM MAC before initialization or
78432 + not. It changes the default configuration [DEFAULT_resetOnInit].
78433 +
78434 + @Param[in] h_FmMac A handle to a FM MAC Module.
78435 + @Param[in] enable When TRUE, FM will be reset before any initialization.
78436 +
78437 + @Return E_OK on success; Error code otherwise.
78438 +
78439 + @Cautions Allowed only following FM_MAC_Config() and before FM_MAC_Init().
78440 +*//***************************************************************************/
78441 +t_Error FM_MAC_ConfigResetOnInit(t_Handle h_FmMac, bool enable);
78442 +
78443 +/**************************************************************************//**
78444 + @Function FM_MAC_ConfigLoopback
78445 +
78446 + @Description Enable/Disable internal loopback mode
78447 +
78448 + @Param[in] h_FmMac A handle to a FM MAC Module.
78449 + @Param[in] enable TRUE to enable or FALSE to disable.
78450 +
78451 + @Return E_OK on success; Error code otherwise.
78452 +
78453 + @Cautions Allowed only following FM_MAC_Config() and before FM_MAC_Init().
78454 +*//***************************************************************************/
78455 +t_Error FM_MAC_ConfigLoopback(t_Handle h_FmMac, bool enable);
78456 +
78457 +/**************************************************************************//**
78458 + @Function FM_MAC_ConfigMaxFrameLength
78459 +
78460 + @Description Setup maximum Rx Frame Length (in 1G MAC, effects also Tx)
78461 +
78462 + @Param[in] h_FmMac A handle to a FM MAC Module.
78463 + @Param[in] newVal MAX Frame length
78464 +
78465 + @Return E_OK on success; Error code otherwise.
78466 +
78467 + @Cautions Allowed only following FM_MAC_Config() and before FM_MAC_Init().
78468 +*//***************************************************************************/
78469 +t_Error FM_MAC_ConfigMaxFrameLength(t_Handle h_FmMac, uint16_t newVal);
78470 +
78471 +/**************************************************************************//**
78472 + @Function FM_MAC_ConfigWan
78473 +
78474 + @Description ENABLE WAN mode in 10G-MAC
78475 +
78476 + @Param[in] h_FmMac A handle to a FM MAC Module.
78477 + @Param[in] enable TRUE to enable or FALSE to disable.
78478 +
78479 + @Return E_OK on success; Error code otherwise.
78480 +
78481 + @Cautions Allowed only following FM_MAC_Config() and before FM_MAC_Init().
78482 +*//***************************************************************************/
78483 +t_Error FM_MAC_ConfigWan(t_Handle h_FmMac, bool enable);
78484 +
78485 +/**************************************************************************//**
78486 + @Function FM_MAC_ConfigPadAndCrc
78487 +
78488 + @Description Config PAD and CRC mode
78489 +
78490 + @Param[in] h_FmMac A handle to a FM MAC Module.
78491 + @Param[in] enable TRUE to enable or FALSE to disable.
78492 +
78493 + @Return E_OK on success; Error code otherwise.
78494 +
78495 + @Cautions Allowed only following FM_MAC_Config() and before FM_MAC_Init().
78496 + Not supported on 10G-MAC (i.e. CRC & PAD are added automatically
78497 + by HW); on mEMAC, this routine supports only PAD (i.e. CRC is
78498 + added automatically by HW).
78499 +*//***************************************************************************/
78500 +t_Error FM_MAC_ConfigPadAndCrc(t_Handle h_FmMac, bool enable);
78501 +
78502 +/**************************************************************************//**
78503 + @Function FM_MAC_ConfigHalfDuplex
78504 +
78505 + @Description Config Half Duplex Mode
78506 +
78507 + @Param[in] h_FmMac A handle to a FM MAC Module.
78508 + @Param[in] enable TRUE to enable or FALSE to disable.
78509 +
78510 + @Return E_OK on success; Error code otherwise.
78511 +
78512 + @Cautions Allowed only following FM_MAC_Config() and before FM_MAC_Init().
78513 +*//***************************************************************************/
78514 +t_Error FM_MAC_ConfigHalfDuplex(t_Handle h_FmMac, bool enable);
78515 +
78516 +/**************************************************************************//**
78517 + @Function FM_MAC_ConfigTbiPhyAddr
78518 +
78519 + @Description Configures the address of internal TBI PHY.
78520 +
78521 + @Param[in] h_FmMac A handle to a FM MAC Module.
78522 + @Param[in] newVal TBI PHY address (1-31).
78523 +
78524 + @Return E_OK on success; Error code otherwise.
78525 +
78526 + @Cautions Allowed only following FM_MAC_Config() and before FM_MAC_Init().
78527 +*//***************************************************************************/
78528 +t_Error FM_MAC_ConfigTbiPhyAddr(t_Handle h_FmMac, uint8_t newVal);
78529 +
78530 +/**************************************************************************//**
78531 + @Function FM_MAC_ConfigLengthCheck
78532 +
78533 + @Description Configure the frame length checking.
78534 +
78535 + @Param[in] h_FmMac A handle to a FM MAC Module.
78536 + @Param[in] enable TRUE to enable or FALSE to disable.
78537 +
78538 + @Return E_OK on success; Error code otherwise.
78539 +
78540 + @Cautions Allowed only following FM_MAC_Config() and before FM_MAC_Init().
78541 +*//***************************************************************************/
78542 +t_Error FM_MAC_ConfigLengthCheck(t_Handle h_FmMac, bool enable);
78543 +
78544 +/**************************************************************************//**
78545 + @Function FM_MAC_ConfigException
78546 +
78547 + @Description Change Exception selection from default
78548 +
78549 + @Param[in] h_FmMac A handle to a FM MAC Module.
78550 + @Param[in] ex Type of the desired exceptions
78551 + @Param[in] enable TRUE to enable the specified exception, FALSE to disable it.
78552 +
78553 + @Return E_OK on success; Error code otherwise.
78554 +
78555 + @Cautions Allowed only following FM_MAC_Config() and before FM_MAC_Init().
78556 +*//***************************************************************************/
78557 +t_Error FM_MAC_ConfigException(t_Handle h_FmMac, e_FmMacExceptions ex, bool enable);
78558 +
78559 +#ifdef FM_TX_ECC_FRMS_ERRATA_10GMAC_A004
78560 +t_Error FM_MAC_ConfigSkipFman11Workaround (t_Handle h_FmMac);
78561 +#endif /* FM_TX_ECC_FRMS_ERRATA_10GMAC_A004 */
78562 +/** @} */ /* end of FM_mac_advanced_init_grp group */
78563 +/** @} */ /* end of FM_mac_init_grp group */
78564 +
78565 +
78566 +/**************************************************************************//**
78567 + @Group FM_mac_runtime_control_grp FM MAC Runtime Control Unit
78568 +
78569 + @Description FM MAC Runtime control unit API functions, definitions and enums.
78570 +
78571 + @{
78572 +*//***************************************************************************/
78573 +
78574 +/**************************************************************************//**
78575 + @Function FM_MAC_Enable
78576 +
78577 + @Description Enable the MAC
78578 +
78579 + @Param[in] h_FmMac A handle to a FM MAC Module.
78580 + @Param[in] mode Mode of operation (RX, TX, Both)
78581 +
78582 + @Return E_OK on success; Error code otherwise.
78583 +
78584 + @Cautions Allowed only following FM_MAC_Init().
78585 +*//***************************************************************************/
78586 +t_Error FM_MAC_Enable(t_Handle h_FmMac, e_CommMode mode);
78587 +
78588 +/**************************************************************************//**
78589 + @Function FM_MAC_Disable
78590 +
78591 + @Description DISABLE the MAC
78592 +
78593 + @Param[in] h_FmMac A handle to a FM MAC Module.
78594 + @Param[in] mode Define what part to Disable (RX, TX or BOTH)
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_Disable(t_Handle h_FmMac, e_CommMode mode);
78601 +
78602 +/**************************************************************************//**
78603 + @Function FM_MAC_Resume
78604 +
78605 + @Description Re-init the MAC after suspend
78606 +
78607 + @Param[in] h_FmMac A handle to a FM MAC Module.
78608 +
78609 + @Return E_OK on success; Error code otherwise.
78610 +
78611 + @Cautions Allowed only following FM_MAC_Init().
78612 +*//***************************************************************************/
78613 +t_Error FM_MAC_Resume(t_Handle h_FmMac);
78614 +
78615 +/**************************************************************************//**
78616 + @Function FM_MAC_Enable1588TimeStamp
78617 +
78618 + @Description Enables the TSU operation.
78619 +
78620 + @Param[in] h_Fm - Handle to the PTP as returned from the FM_MAC_PtpConfig.
78621 +
78622 + @Return E_OK on success; Error code otherwise.
78623 +
78624 + @Cautions Allowed only following FM_MAC_Init().
78625 +*//***************************************************************************/
78626 +t_Error FM_MAC_Enable1588TimeStamp(t_Handle h_Fm);
78627 +
78628 +/**************************************************************************//**
78629 + @Function FM_MAC_Disable1588TimeStamp
78630 +
78631 + @Description Disables the TSU operation.
78632 +
78633 + @Param[in] h_Fm - Handle to the PTP as returned from the FM_MAC_PtpConfig.
78634 +
78635 + @Return E_OK on success; Error code otherwise.
78636 +
78637 + @Cautions Allowed only following FM_MAC_Init().
78638 +*//***************************************************************************/
78639 +t_Error FM_MAC_Disable1588TimeStamp(t_Handle h_Fm);
78640 +
78641 +/**************************************************************************//**
78642 + @Function FM_MAC_SetTxAutoPauseFrames
78643 +
78644 + @Description Enable/Disable transmission of Pause-Frames.
78645 + The routine changes the default configuration [DEFAULT_TX_PAUSE_TIME].
78646 +
78647 + @Param[in] h_FmMac - A handle to a FM MAC Module.
78648 + @Param[in] pauseTime - Pause quanta value used with transmitted pause frames.
78649 + Each quanta represents a 512 bit-times; Note that '0'
78650 + as an input here will be used as disabling the
78651 + transmission of the pause-frames.
78652 +
78653 + @Return E_OK on success; Error code otherwise.
78654 +
78655 + @Cautions Allowed only following FM_MAC_Init().
78656 +*//***************************************************************************/
78657 +t_Error FM_MAC_SetTxAutoPauseFrames(t_Handle h_FmMac,
78658 + uint16_t pauseTime);
78659 +
78660 + /**************************************************************************//**
78661 + @Function FM_MAC_SetTxPauseFrames
78662 +
78663 + @Description Enable/Disable transmission of Pause-Frames.
78664 + The routine changes the default configuration:
78665 + pause-time - [DEFAULT_TX_PAUSE_TIME]
78666 + threshold-time - [0]
78667 +
78668 + @Param[in] h_FmMac - A handle to a FM MAC Module.
78669 + @Param[in] priority - the PFC class of service; use 'FM_MAC_NO_PFC'
78670 + to indicate legacy pause support (i.e. no PFC).
78671 + @Param[in] pauseTime - Pause quanta value used with transmitted pause frames.
78672 + Each quanta represents a 512 bit-times;
78673 + Note that '0' as an input here will be used as disabling the
78674 + transmission of the pause-frames.
78675 + @Param[in] threshTime - Pause Threshold equanta value used by the MAC to retransmit pause frame.
78676 + if the situation causing a pause frame to be sent didn't finish when the timer
78677 + reached the threshold quanta, the MAC will retransmit the pause frame.
78678 + Each quanta represents a 512 bit-times.
78679 +
78680 + @Return E_OK on success; Error code otherwise.
78681 +
78682 + @Cautions Allowed only following FM_MAC_Init().
78683 + In order for PFC to work properly the user must configure
78684 + TNUM-aging in the tx-port it is recommended that pre-fetch and
78685 + rate limit in the tx port should be disabled;
78686 + PFC is supported only on new mEMAC; i.e. in MACs that don't have
78687 + PFC support (10G-MAC and dTSEC), user should use 'FM_MAC_NO_PFC'
78688 + in the 'priority' field.
78689 +*//***************************************************************************/
78690 +t_Error FM_MAC_SetTxPauseFrames(t_Handle h_FmMac,
78691 + uint8_t priority,
78692 + uint16_t pauseTime,
78693 + uint16_t threshTime);
78694 +
78695 +/**************************************************************************//**
78696 + @Function FM_MAC_SetRxIgnorePauseFrames
78697 +
78698 + @Description Enable/Disable ignoring of Pause-Frames.
78699 +
78700 + @Param[in] h_FmMac - A handle to a FM MAC Module.
78701 + @Param[in] en - boolean indicates whether to ignore the incoming pause
78702 + frames or not.
78703 +
78704 + @Return E_OK on success; Error code otherwise.
78705 +
78706 + @Cautions Allowed only following FM_MAC_Init().
78707 +*//***************************************************************************/
78708 +t_Error FM_MAC_SetRxIgnorePauseFrames(t_Handle h_FmMac, bool en);
78709 +
78710 +/**************************************************************************//**
78711 + @Function FM_MAC_SetWakeOnLan
78712 +
78713 + @Description Enable/Disable Wake On Lan support
78714 +
78715 + @Param[in] h_FmMac - A handle to a FM MAC Module.
78716 + @Param[in] en - boolean indicates whether to enable Wake On Lan
78717 + support or not.
78718 +
78719 + @Return E_OK on success; Error code otherwise.
78720 +
78721 + @Cautions Allowed only following FM_MAC_Init().
78722 +*//***************************************************************************/
78723 +t_Error FM_MAC_SetWakeOnLan(t_Handle h_FmMac, bool en);
78724 +
78725 +/**************************************************************************//**
78726 + @Function FM_MAC_ResetCounters
78727 +
78728 + @Description reset all statistics counters
78729 +
78730 + @Param[in] h_FmMac - A handle to a FM MAC Module.
78731 +
78732 + @Return E_OK on success; Error code otherwise.
78733 +
78734 + @Cautions Allowed only following FM_MAC_Init().
78735 +*//***************************************************************************/
78736 +t_Error FM_MAC_ResetCounters(t_Handle h_FmMac);
78737 +
78738 +/**************************************************************************//**
78739 + @Function FM_MAC_SetException
78740 +
78741 + @Description Enable/Disable a specific Exception
78742 +
78743 + @Param[in] h_FmMac - A handle to a FM MAC Module.
78744 + @Param[in] ex - Type of the desired exceptions
78745 + @Param[in] enable - TRUE to enable the specified exception, FALSE to disable it.
78746 +
78747 +
78748 + @Return E_OK on success; Error code otherwise.
78749 +
78750 + @Cautions Allowed only following FM_MAC_Init().
78751 +*//***************************************************************************/
78752 +t_Error FM_MAC_SetException(t_Handle h_FmMac, e_FmMacExceptions ex, bool enable);
78753 +
78754 +/**************************************************************************//**
78755 + @Function FM_MAC_SetStatistics
78756 +
78757 + @Description Define Statistics level.
78758 + Where applicable, the routine also enables the MIB counters
78759 + overflow interrupt in order to keep counters accurate
78760 + and account for overflows.
78761 + This routine is relevant only for dTSEC.
78762 +
78763 + @Param[in] h_FmMac - A handle to a FM MAC Module.
78764 + @Param[in] statisticsLevel - Full statistics level provides all standard counters but may
78765 + reduce performance. Partial statistics provides only special
78766 + event counters (errors etc.). If selected, regular counters (such as
78767 + byte/packet) will be invalid and will return -1.
78768 +
78769 + @Return E_OK on success; Error code otherwise.
78770 +
78771 + @Cautions Allowed only following FM_MAC_Init().
78772 +*//***************************************************************************/
78773 +t_Error FM_MAC_SetStatistics(t_Handle h_FmMac, e_FmMacStatisticsLevel statisticsLevel);
78774 +
78775 +/**************************************************************************//**
78776 + @Function FM_MAC_GetStatistics
78777 +
78778 + @Description get all statistics counters
78779 +
78780 + @Param[in] h_FmMac - A handle to a FM MAC Module.
78781 + @Param[in] p_Statistics - Structure with statistics
78782 +
78783 + @Return E_OK on success; Error code otherwise.
78784 +
78785 + @Cautions Allowed only following FM_Init().
78786 +*//***************************************************************************/
78787 +t_Error FM_MAC_GetStatistics(t_Handle h_FmMac, t_FmMacStatistics *p_Statistics);
78788 +
78789 +/**************************************************************************//**
78790 + @Function FM_MAC_GetFrameSizeCounters
78791 +
78792 + @Description get MAC statistics counters for different frame size
78793 +
78794 + @Param[in] h_FmMac - A handle to a FM MAC Module.
78795 + @Param[in] p_FrameSizeCounters - Structure with counters
78796 + @Param[in] type - Type of counters to be read
78797 +
78798 + @Return E_OK on success; Error code otherwise.
78799 +
78800 + @Cautions Allowed only following FM_Init().
78801 +*//***************************************************************************/
78802 +t_Error FM_MAC_GetFrameSizeCounters(t_Handle h_FmMac, t_FmMacFrameSizeCounters *p_FrameSizeCounters, e_CommMode type);
78803 +
78804 +/**************************************************************************//**
78805 + @Function FM_MAC_ModifyMacAddr
78806 +
78807 + @Description Replace the main MAC Address
78808 +
78809 + @Param[in] h_FmMac - A handle to a FM Module.
78810 + @Param[in] p_EnetAddr - Ethernet Mac address
78811 +
78812 + @Return E_OK on success; Error code otherwise.
78813 +
78814 + @Cautions Allowed only after FM_MAC_Init().
78815 +*//***************************************************************************/
78816 +t_Error FM_MAC_ModifyMacAddr(t_Handle h_FmMac, t_EnetAddr *p_EnetAddr);
78817 +
78818 +/**************************************************************************//**
78819 + @Function FM_MAC_AddHashMacAddr
78820 +
78821 + @Description Add an Address to the hash table. This is for filter purpose only.
78822 +
78823 + @Param[in] h_FmMac - A handle to a FM Module.
78824 + @Param[in] p_EnetAddr - Ethernet Mac address
78825 +
78826 + @Return E_OK on success; Error code otherwise.
78827 +
78828 + @Cautions Allowed only following FM_MAC_Init(). It is a filter only address.
78829 + @Cautions Some address need to be filterd out in upper FM blocks.
78830 +*//***************************************************************************/
78831 +t_Error FM_MAC_AddHashMacAddr(t_Handle h_FmMac, t_EnetAddr *p_EnetAddr);
78832 +
78833 +/**************************************************************************//**
78834 + @Function FM_MAC_RemoveHashMacAddr
78835 +
78836 + @Description Delete an Address to the hash table. This is for filter purpose only.
78837 +
78838 + @Param[in] h_FmMac - A handle to a FM Module.
78839 + @Param[in] p_EnetAddr - Ethernet Mac address
78840 +
78841 + @Return E_OK on success; Error code otherwise.
78842 +
78843 + @Cautions Allowed only following FM_MAC_Init().
78844 +*//***************************************************************************/
78845 +t_Error FM_MAC_RemoveHashMacAddr(t_Handle h_FmMac, t_EnetAddr *p_EnetAddr);
78846 +
78847 +/**************************************************************************//**
78848 + @Function FM_MAC_AddExactMatchMacAddr
78849 +
78850 + @Description Add a unicast or multicast mac address for exact-match filtering
78851 + (8 on dTSEC, 2 for 10G-MAC)
78852 +
78853 + @Param[in] h_FmMac - A handle to a FM Module.
78854 + @Param[in] p_EnetAddr - MAC Address to ADD
78855 +
78856 + @Return E_OK on success; Error code otherwise.
78857 +
78858 + @Cautions Allowed only after FM_MAC_Init().
78859 +*//***************************************************************************/
78860 +t_Error FM_MAC_AddExactMatchMacAddr(t_Handle h_FmMac, t_EnetAddr *p_EnetAddr);
78861 +
78862 +/**************************************************************************//**
78863 + @Function FM_MAC_RemovelExactMatchMacAddr
78864 +
78865 + @Description Remove a uni cast or multi cast mac address.
78866 +
78867 + @Param[in] h_FmMac - A handle to a FM Module.
78868 + @Param[in] p_EnetAddr - MAC Address to remove
78869 +
78870 + @Return E_OK on success; Error code otherwise..
78871 +
78872 + @Cautions Allowed only after FM_MAC_Init().
78873 +*//***************************************************************************/
78874 +t_Error FM_MAC_RemovelExactMatchMacAddr(t_Handle h_FmMac, t_EnetAddr *p_EnetAddr);
78875 +
78876 +/**************************************************************************//**
78877 + @Function FM_MAC_SetPromiscuous
78878 +
78879 + @Description Enable/Disable MAC Promiscuous mode for ALL mac addresses.
78880 +
78881 + @Param[in] h_FmMac - A handle to a FM MAC Module.
78882 + @Param[in] enable - TRUE to enable or FALSE to disable.
78883 +
78884 + @Return E_OK on success; Error code otherwise.
78885 +
78886 + @Cautions Allowed only after FM_MAC_Init().
78887 +*//***************************************************************************/
78888 +t_Error FM_MAC_SetPromiscuous(t_Handle h_FmMac, bool enable);
78889 +
78890 +/**************************************************************************//**
78891 + @Function FM_MAC_AdjustLink
78892 +
78893 + @Description Adjusts the Ethernet link with new speed/duplex setup.
78894 + This routine is relevant for dTSEC and mEMAC.
78895 + In case of mEMAC, this routine is also used for manual
78896 + re-configuration of RGMII speed and duplex mode for
78897 + RGMII PHYs not supporting in-band status information
78898 + to MAC.
78899 +
78900 + @Param[in] h_FmMac - A handle to a FM Module.
78901 + @Param[in] speed - Ethernet speed.
78902 + @Param[in] fullDuplex - TRUE for full-duplex mode;
78903 + FALSE for half-duplex mode.
78904 +
78905 + @Return E_OK on success; Error code otherwise.
78906 +*//***************************************************************************/
78907 +t_Error FM_MAC_AdjustLink(t_Handle h_FmMac, e_EnetSpeed speed, bool fullDuplex);
78908 +
78909 +/**************************************************************************//**
78910 + @Function FM_MAC_RestartAutoneg
78911 +
78912 + @Description Restarts the auto-negotiation process.
78913 + When auto-negotiation process is invoked under traffic the
78914 + auto-negotiation process between the internal SGMII PHY and the
78915 + external PHY does not always complete successfully. Calling this
78916 + function will restart the auto-negotiation process that will end
78917 + successfully. It is recommended to call this function after issuing
78918 + auto-negotiation restart command to the Eth Phy.
78919 + This routine is relevant only for dTSEC.
78920 +
78921 + @Param[in] h_FmMac - A handle to a FM Module.
78922 +
78923 + @Return E_OK on success; Error code otherwise.
78924 +*//***************************************************************************/
78925 +t_Error FM_MAC_RestartAutoneg(t_Handle h_FmMac);
78926 +
78927 +/**************************************************************************//**
78928 + @Function FM_MAC_GetId
78929 +
78930 + @Description Return the MAC ID
78931 +
78932 + @Param[in] h_FmMac - A handle to a FM Module.
78933 + @Param[out] p_MacId - MAC ID of device
78934 +
78935 + @Return E_OK on success; Error code otherwise.
78936 +
78937 + @Cautions Allowed only after FM_MAC_Init().
78938 +*//***************************************************************************/
78939 +t_Error FM_MAC_GetId(t_Handle h_FmMac, uint32_t *p_MacId);
78940 +
78941 +/**************************************************************************//**
78942 + @Function FM_MAC_GetVesrion
78943 +
78944 + @Description Return Mac HW chip version
78945 +
78946 + @Param[in] h_FmMac - A handle to a FM Module.
78947 + @Param[out] p_MacVresion - Mac version as defined by the chip
78948 +
78949 + @Return E_OK on success; Error code otherwise.
78950 +
78951 + @Cautions Allowed only after FM_MAC_Init().
78952 +*//***************************************************************************/
78953 +t_Error FM_MAC_GetVesrion(t_Handle h_FmMac, uint32_t *p_MacVresion);
78954 +
78955 +/**************************************************************************//**
78956 + @Function FM_MAC_MII_WritePhyReg
78957 +
78958 + @Description Write data into Phy Register
78959 +
78960 + @Param[in] h_FmMac - A handle to a FM Module.
78961 + @Param[in] phyAddr - Phy Address on the MII bus
78962 + @Param[in] reg - Register Number.
78963 + @Param[in] data - Data to write.
78964 +
78965 + @Return E_OK on success; Error code otherwise.
78966 +
78967 + @Cautions Allowed only after FM_MAC_Init().
78968 +*//***************************************************************************/
78969 +t_Error FM_MAC_MII_WritePhyReg(t_Handle h_FmMac, uint8_t phyAddr, uint8_t reg, uint16_t data);
78970 +
78971 +/**************************************************************************//**
78972 + @Function FM_MAC_MII_ReadPhyReg
78973 +
78974 + @Description Read data from Phy Register
78975 +
78976 + @Param[in] h_FmMac - A handle to a FM Module.
78977 + @Param[in] phyAddr - Phy Address on the MII bus
78978 + @Param[in] reg - Register Number.
78979 + @Param[out] p_Data - Data from PHY.
78980 +
78981 + @Return E_OK on success; Error code otherwise.
78982 +
78983 + @Cautions Allowed only after FM_MAC_Init().
78984 +*//***************************************************************************/
78985 +t_Error FM_MAC_MII_ReadPhyReg(t_Handle h_FmMac, uint8_t phyAddr, uint8_t reg, uint16_t *p_Data);
78986 +
78987 +#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
78988 +/**************************************************************************//**
78989 + @Function FM_MAC_DumpRegs
78990 +
78991 + @Description Dump internal registers
78992 +
78993 + @Param[in] h_FmMac - A handle to a FM Module.
78994 +
78995 + @Return E_OK on success; Error code otherwise.
78996 +
78997 + @Cautions Allowed only after FM_MAC_Init().
78998 +*//***************************************************************************/
78999 +t_Error FM_MAC_DumpRegs(t_Handle h_FmMac);
79000 +#endif /* (defined(DEBUG_ERRORS) && ... */
79001 +
79002 +/** @} */ /* end of FM_mac_runtime_control_grp group */
79003 +/** @} */ /* end of FM_mac_grp group */
79004 +/** @} */ /* end of FM_grp group */
79005 +
79006 +
79007 +#endif /* __FM_MAC_EXT_H */
79008 --- /dev/null
79009 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/Peripherals/fm_macsec_ext.h
79010 @@ -0,0 +1,1271 @@
79011 +/*
79012 + * Copyright 2008-2015 Freescale Semiconductor Inc.
79013 + *
79014 + * Redistribution and use in source and binary forms, with or without
79015 + * modification, are permitted provided that the following conditions are met:
79016 + * * Redistributions of source code must retain the above copyright
79017 + * notice, this list of conditions and the following disclaimer.
79018 + * * Redistributions in binary form must reproduce the above copyright
79019 + * notice, this list of conditions and the following disclaimer in the
79020 + * documentation and/or other materials provided with the distribution.
79021 + * * Neither the name of Freescale Semiconductor nor the
79022 + * names of its contributors may be used to endorse or promote products
79023 + * derived from this software without specific prior written permission.
79024 + *
79025 + *
79026 + * ALTERNATIVELY, this software may be distributed under the terms of the
79027 + * GNU General Public License ("GPL") as published by the Free Software
79028 + * Foundation, either version 2 of that License or (at your option) any
79029 + * later version.
79030 + *
79031 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
79032 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
79033 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
79034 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
79035 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
79036 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
79037 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
79038 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
79039 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
79040 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
79041 + */
79042 +
79043 +/**************************************************************************//**
79044 + @File fm_macsec_ext.h
79045 +
79046 + @Description FM MACSEC ...
79047 +*//***************************************************************************/
79048 +#ifndef __FM_MACSEC_EXT_H
79049 +#define __FM_MACSEC_EXT_H
79050 +
79051 +#include "std_ext.h"
79052 +
79053 +
79054 +/**************************************************************************//**
79055 + @Group FM_grp Frame Manager API
79056 +
79057 + @Description FM API functions, definitions and enums
79058 +
79059 + @{
79060 +*//***************************************************************************/
79061 +
79062 +/**************************************************************************//**
79063 + @Group FM_MACSEC_grp FM MACSEC
79064 +
79065 + @Description FM MACSEC API functions, definitions and enums
79066 +
79067 + @{
79068 +*//***************************************************************************/
79069 +
79070 +/**************************************************************************//**
79071 + @Description MACSEC Exceptions
79072 +*//***************************************************************************/
79073 +typedef enum e_FmMacsecExceptions {
79074 + e_FM_MACSEC_EX_SINGLE_BIT_ECC, /**< Single bit ECC error */
79075 + e_FM_MACSEC_EX_MULTI_BIT_ECC /**< Multi bit ECC error */
79076 +} e_FmMacsecExceptions;
79077 +
79078 +
79079 +/**************************************************************************//**
79080 + @Group FM_MACSEC_init_grp FM-MACSEC Initialization Unit
79081 +
79082 + @Description FM MACSEC Initialization Unit
79083 +
79084 + @{
79085 +*//***************************************************************************/
79086 +
79087 +/**************************************************************************//**
79088 + @Function t_FmMacsecExceptionsCallback
79089 +
79090 + @Description Exceptions user callback routine, will be called upon an
79091 + exception passing the exception identification.
79092 +
79093 + @Param[in] h_App A handle to an application layer object; This handle
79094 + will be passed by the driver upon calling this callback.
79095 + @Param[in] exception The exception.
79096 +*//***************************************************************************/
79097 +typedef void (t_FmMacsecExceptionsCallback) ( t_Handle h_App,
79098 + e_FmMacsecExceptions exception);
79099 +
79100 +
79101 +/**************************************************************************//**
79102 + @Description FM MACSEC config input
79103 +*//***************************************************************************/
79104 +typedef struct t_FmMacsecParams {
79105 + t_Handle h_Fm; /**< A handle to the FM object related to */
79106 + bool guestMode; /**< Partition-id */
79107 + union {
79108 + struct {
79109 + uint8_t fmMacId; /**< FM MAC id */
79110 + } guestParams;
79111 +
79112 + struct {
79113 + uintptr_t baseAddr; /**< Base of memory mapped FM MACSEC registers */
79114 + t_Handle h_FmMac; /**< A handle to the FM MAC object related to */
79115 + t_FmMacsecExceptionsCallback *f_Exception; /**< Exception Callback Routine */
79116 + t_Handle h_App; /**< A handle to an application layer object; This handle will
79117 + be passed by the driver upon calling the above callbacks */
79118 + } nonGuestParams;
79119 + };
79120 +} t_FmMacsecParams;
79121 +
79122 +/**************************************************************************//**
79123 + @Function FM_MACSEC_Config
79124 +
79125 + @Description Creates descriptor for the FM MACSEC module;
79126 +
79127 + The routine returns a handle (descriptor) to the FM MACSEC object;
79128 + This descriptor must be passed as first parameter to all other
79129 + FM MACSEC function calls;
79130 +
79131 + No actual initialization or configuration of FM MACSEC hardware is
79132 + done by this routine.
79133 +
79134 + @Param[in] p_FmMacsecParam Pointer to data structure of parameters.
79135 +
79136 + @Retval Handle to FM MACSEC object, or NULL for Failure.
79137 +*//***************************************************************************/
79138 +t_Handle FM_MACSEC_Config(t_FmMacsecParams *p_FmMacsecParam);
79139 +
79140 +/**************************************************************************//**
79141 + @Function FM_MACSEC_Init
79142 +
79143 + @Description Initializes the FM MACSEC module.
79144 +
79145 + @Param[in] h_FmMacsec FM MACSEC module descriptor.
79146 +
79147 + @Return E_OK on success; Error code otherwise.
79148 +*//***************************************************************************/
79149 +t_Error FM_MACSEC_Init(t_Handle h_FmMacsec);
79150 +
79151 +/**************************************************************************//**
79152 + @Function FM_MACSEC_Free
79153 +
79154 + @Description Frees all resources that were assigned to FM MACSEC module;
79155 +
79156 + Calling this routine invalidates the descriptor.
79157 +
79158 + @Param[in] h_FmMacsec FM MACSEC module descriptor.
79159 +
79160 + @Return E_OK on success; Error code otherwise.
79161 +*//***************************************************************************/
79162 +t_Error FM_MACSEC_Free(t_Handle h_FmMacsec);
79163 +
79164 +
79165 +/**************************************************************************//**
79166 + @Group FM_MACSEC_advanced_init_grp FM-MACSEC Advanced Configuration Unit
79167 +
79168 + @Description Configuration functions used to change default values.
79169 +
79170 + @{
79171 +*//***************************************************************************/
79172 +
79173 +/**************************************************************************//**
79174 + @Description enum for unknown sci frame treatment
79175 +*//***************************************************************************/
79176 +typedef enum e_FmMacsecUnknownSciFrameTreatment {
79177 + e_FM_MACSEC_UNKNOWN_SCI_FRAME_TREATMENT_DISCARD_BOTH = 0, /**< Controlled port - Strict mode */
79178 + e_FM_MACSEC_UNKNOWN_SCI_FRAME_TREATMENT_DISCARD_UNCONTROLLED_DELIVER_OR_DISCARD_CONTROLLED, /**< If C bit clear deliver on controlled port, else discard
79179 + Controlled port - Check or Disable mode */
79180 + e_FM_MACSEC_UNKNOWN_SCI_FRAME_TREATMENT_DELIVER_UNCONTROLLED_DISCARD_CONTROLLED, /**< Controlled port - Strict mode */
79181 + 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,
79182 + else discard on uncontrolled port and deliver on controlled port
79183 + Controlled port - Check or Disable mode */
79184 +} e_FmMacsecUnknownSciFrameTreatment;
79185 +
79186 +/**************************************************************************//**
79187 + @Description enum for untag frame treatment
79188 +*//***************************************************************************/
79189 +typedef enum e_FmMacsecUntagFrameTreatment {
79190 + e_FM_MACSEC_UNTAG_FRAME_TREATMENT_DELIVER_UNCONTROLLED_DISCARD_CONTROLLED = 0, /**< Controlled port - Strict mode */
79191 + e_FM_MACSEC_UNTAG_FRAME_TREATMENT_DISCARD_BOTH, /**< Controlled port - Strict mode */
79192 + e_FM_MACSEC_UNTAG_FRAME_TREATMENT_DISCARD_UNCONTROLLED_DELIVER_CONTROLLED_UNMODIFIED /**< Controlled port - Strict mode */
79193 +} e_FmMacsecUntagFrameTreatment;
79194 +
79195 +/**************************************************************************//**
79196 + @Function FM_MACSEC_ConfigUnknownSciFrameTreatment
79197 +
79198 + @Description Change the treatment for received frames with unknown sci from its default
79199 + configuration [DEFAULT_unknownSciFrameTreatment].
79200 +
79201 + @Param[in] h_FmMacsec FM MACSEC module descriptor.
79202 + @Param[in] treatMode The selected mode.
79203 +
79204 + @Return E_OK on success; Error code otherwise.
79205 +
79206 + @Cautions Allowed only following FM_MACSEC_Config() and before FM_MACSEC_Init().
79207 +*//***************************************************************************/
79208 +t_Error FM_MACSEC_ConfigUnknownSciFrameTreatment(t_Handle h_FmMacsec, e_FmMacsecUnknownSciFrameTreatment treatMode);
79209 +
79210 +/**************************************************************************//**
79211 + @Function FM_MACSEC_ConfigInvalidTagsFrameTreatment
79212 +
79213 + @Description Change the treatment for received frames with invalid tags or
79214 + a zero value PN or an invalid ICV from its default configuration
79215 + [DEFAULT_invalidTagsFrameTreatment].
79216 +
79217 + @Param[in] h_FmMacsec FM MACSEC module descriptor.
79218 + @Param[in] deliverUncontrolled If True deliver on the uncontrolled port, else discard;
79219 + In both cases discard on the controlled port;
79220 + this provide Strict, Check or Disable mode.
79221 +
79222 + @Return E_OK on success; Error code otherwise.
79223 +
79224 + @Cautions Allowed only following FM_MACSEC_Config() and before FM_MACSEC_Init().
79225 +*//***************************************************************************/
79226 +t_Error FM_MACSEC_ConfigInvalidTagsFrameTreatment(t_Handle h_FmMacsec, bool deliverUncontrolled);
79227 +
79228 +/**************************************************************************//**
79229 + @Function FM_MACSEC_ConfigEncryptWithNoChangedTextFrameTreatment
79230 +
79231 + @Description Change the treatment for received frames with the Encryption bit
79232 + set and the Changed Text bit clear from its default configuration
79233 + [DEFAULT_encryptWithNoChangedTextFrameTreatment].
79234 +
79235 + @Param[in] h_FmMacsec FM MACSEC module descriptor.
79236 + @Param[in] discardUncontrolled If True discard on the uncontrolled port, else deliver;
79237 + In both cases discard on the controlled port;
79238 + this provide Strict, Check or Disable mode.
79239 +
79240 + @Return E_OK on success; Error code otherwise.
79241 +
79242 + @Cautions Allowed only following FM_MACSEC_Config() and before FM_MACSEC_Init().
79243 +*//***************************************************************************/
79244 +t_Error FM_MACSEC_ConfigEncryptWithNoChangedTextFrameTreatment(t_Handle h_FmMacsec, bool discardUncontrolled);
79245 +
79246 +/**************************************************************************//**
79247 + @Function FM_MACSEC_ConfigChangedTextWithNoEncryptFrameTreatment
79248 +
79249 + @Description Change the treatment for received frames with the Encryption bit
79250 + clear and the Changed Text bit set from its default configuration
79251 + [DEFAULT_changedTextWithNoEncryptFrameTreatment].
79252 +
79253 + @Param[in] h_FmMacsec FM MACSEC module descriptor.
79254 + @Param[in] deliverUncontrolled If True deliver on the uncontrolled port, else discard;
79255 + In both cases discard on the controlled port;
79256 + this provide Strict, Check or Disable mode.
79257 +
79258 + @Return E_OK on success; Error code otherwise.
79259 +
79260 + @Cautions Allowed only following FM_MACSEC_Config() and before FM_MACSEC_Init().
79261 +*//***************************************************************************/
79262 +t_Error FM_MACSEC_ConfigChangedTextWithNoEncryptFrameTreatment(t_Handle h_FmMacsec, bool deliverUncontrolled);
79263 +
79264 +/**************************************************************************//**
79265 + @Function FM_MACSEC_ConfigUntagFrameTreatment
79266 +
79267 + @Description Change the treatment for received frames without the MAC security tag (SecTAG)
79268 + from its default configuration [DEFAULT_untagFrameTreatment].
79269 +
79270 + @Param[in] h_FmMacsec FM MACSEC module descriptor.
79271 + @Param[in] treatMode The selected mode.
79272 +
79273 + @Return E_OK on success; Error code otherwise.
79274 +
79275 + @Cautions Allowed only following FM_MACSEC_Config() and before FM_MACSEC_Init().
79276 +*//***************************************************************************/
79277 +t_Error FM_MACSEC_ConfigUntagFrameTreatment(t_Handle h_FmMacsec, e_FmMacsecUntagFrameTreatment treatMode);
79278 +
79279 +/**************************************************************************//**
79280 + @Function FM_MACSEC_ConfigOnlyScbIsSetFrameTreatment
79281 +
79282 + @Description Change the treatment for received frames with only SCB bit set
79283 + from its default configuration [DEFAULT_onlyScbIsSetFrameTreatment].
79284 +
79285 + @Param[in] h_FmMacsec FM MACSEC module descriptor.
79286 + @Param[in] deliverUncontrolled If True deliver on the uncontrolled port, else discard;
79287 + In both cases discard on the controlled port;
79288 + this provide Strict, Check or Disable mode.
79289 +
79290 + @Return E_OK on success; Error code otherwise.
79291 +
79292 + @Cautions Allowed only following FM_MACSEC_Config() and before FM_MACSEC_Init().
79293 +*//***************************************************************************/
79294 +t_Error FM_MACSEC_ConfigOnlyScbIsSetFrameTreatment(t_Handle h_FmMacsec, bool deliverUncontrolled);
79295 +
79296 +/**************************************************************************//**
79297 + @Function FM_MACSEC_ConfigPnExhaustionThreshold
79298 +
79299 + @Description It's provide the ability to configure a PN exhaustion threshold;
79300 + When the NextPn crosses this value an interrupt event
79301 + is asserted to warn that the active SA should re-key.
79302 +
79303 + @Param[in] h_FmMacsec FM MACSEC module descriptor.
79304 + @Param[in] pnExhThr If the threshold is reached, an interrupt event
79305 + is asserted to re-key.
79306 +
79307 + @Return E_OK on success; Error code otherwise.
79308 +
79309 + @Cautions Allowed only following FM_MACSEC_Config() and before FM_MACSEC_Init().
79310 +*//***************************************************************************/
79311 +t_Error FM_MACSEC_ConfigPnExhaustionThreshold(t_Handle h_FmMacsec, uint32_t pnExhThr);
79312 +
79313 +/**************************************************************************//**
79314 + @Function FM_MACSEC_ConfigKeysUnreadable
79315 +
79316 + @Description Turn on privacy mode; All the keys and their hash values can't be read any more;
79317 + Can not be cleared unless hard reset.
79318 +
79319 + @Param[in] h_FmMacsec FM MACSEC module descriptor.
79320 +
79321 + @Return E_OK on success; Error code otherwise.
79322 +
79323 + @Cautions Allowed only following FM_MACSEC_Config() and before FM_MACSEC_Init().
79324 +*//***************************************************************************/
79325 +t_Error FM_MACSEC_ConfigKeysUnreadable(t_Handle h_FmMacsec);
79326 +
79327 +/**************************************************************************//**
79328 + @Function FM_MACSEC_ConfigSectagWithoutSCI
79329 +
79330 + @Description Promise that all generated Sectag will be without SCI included.
79331 +
79332 + @Param[in] h_FmMacsec FM MACSEC module descriptor.
79333 +
79334 + @Return E_OK on success; Error code otherwise.
79335 +
79336 + @Cautions Allowed only following FM_MACSEC_Config() and before FM_MACSEC_Init().
79337 +*//***************************************************************************/
79338 +t_Error FM_MACSEC_ConfigSectagWithoutSCI(t_Handle h_FmMacsec);
79339 +
79340 +/**************************************************************************//**
79341 + @Function FM_MACSEC_ConfigException
79342 +
79343 + @Description Calling this routine changes the internal driver data base
79344 + from its default selection of exceptions enablement;
79345 + By default all exceptions are enabled.
79346 +
79347 + @Param[in] h_FmMacsec FM MACSEC module descriptor.
79348 + @Param[in] exception The exception to be selected.
79349 + @Param[in] enable TRUE to enable interrupt, FALSE to mask it.
79350 +
79351 + @Return E_OK on success; Error code otherwise.
79352 +
79353 + @Cautions Allowed only following FM_MACSEC_Config() and before FM_MACSEC_Init().
79354 +*//***************************************************************************/
79355 +t_Error FM_MACSEC_ConfigException(t_Handle h_FmMacsec, e_FmMacsecExceptions exception, bool enable);
79356 +
79357 +/** @} */ /* end of FM_MACSEC_advanced_init_grp group */
79358 +/** @} */ /* end of FM_MACSEC_init_grp group */
79359 +
79360 +
79361 +/**************************************************************************//**
79362 + @Group FM_MACSEC_runtime_control_grp FM-MACSEC Runtime Control Data Unit
79363 +
79364 + @Description FM MACSEC runtime control data unit API functions, definitions and enums.
79365 +
79366 + @{
79367 +*//***************************************************************************/
79368 +
79369 +/**************************************************************************//**
79370 + @Function FM_MACSEC_GetRevision
79371 +
79372 + @Description Return MACSEC HW chip revision
79373 +
79374 + @Param[in] h_FmMacsec FM MACSEC module descriptor.
79375 + @Param[out] p_MacsecRevision MACSEC revision as defined by the chip.
79376 +
79377 + @Return E_OK on success; Error code otherwise.
79378 +
79379 + @Cautions Allowed only after FM_MACSEC_Init().
79380 +*//***************************************************************************/
79381 +t_Error FM_MACSEC_GetRevision(t_Handle h_FmMacsec, uint32_t *p_MacsecRevision);
79382 +
79383 +/**************************************************************************//**
79384 + @Function FM_MACSEC_Enable
79385 +
79386 + @Description This routine should be called after MACSEC is initialized for enabling all
79387 + MACSEC engines according to their existing configuration.
79388 +
79389 + @Param[in] h_FmMacsec FM MACSEC module descriptor.
79390 +
79391 + @Return E_OK on success; Error code otherwise.
79392 +
79393 + @Cautions Allowed only following FM_MACSEC_Init() and when MACSEC is disabled.
79394 +*//***************************************************************************/
79395 +t_Error FM_MACSEC_Enable(t_Handle h_FmMacsec);
79396 +
79397 +/**************************************************************************//**
79398 + @Function FM_MACSEC_Disable
79399 +
79400 + @Description This routine may be called when MACSEC is enabled in order to
79401 + disable all MACSEC engines; The MACSEC is working in bypass mode.
79402 +
79403 + @Param[in] h_FmMacsec FM MACSEC module descriptor.
79404 +
79405 + @Return E_OK on success; Error code otherwise.
79406 +
79407 + @Cautions Allowed only following FM_MACSEC_Init() and when MACSEC is enabled.
79408 +*//***************************************************************************/
79409 +t_Error FM_MACSEC_Disable(t_Handle h_FmMacsec);
79410 +
79411 +/**************************************************************************//**
79412 + @Function FM_MACSEC_SetException
79413 +
79414 + @Description Calling this routine enables/disables the specified exception.
79415 +
79416 + @Param[in] h_FmMacsec FM MACSEC module descriptor.
79417 + @Param[in] exception The exception to be selected.
79418 + @Param[in] enable TRUE to enable interrupt, FALSE to mask it.
79419 +
79420 + @Return E_OK on success; Error code otherwise.
79421 +
79422 + @Cautions Allowed only following FM_MACSEC_Init().
79423 +*//***************************************************************************/
79424 +t_Error FM_MACSEC_SetException(t_Handle h_FmMacsec, e_FmMacsecExceptions exception, bool enable);
79425 +
79426 +#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
79427 +/**************************************************************************//**
79428 + @Function FM_MACSEC_DumpRegs
79429 +
79430 + @Description Dump internal registers.
79431 +
79432 + @Param[in] h_FmMacsec - FM MACSEC module descriptor.
79433 +
79434 + @Return E_OK on success; Error code otherwise.
79435 +
79436 + @Cautions Allowed only after FM_MACSEC_Init().
79437 +*//***************************************************************************/
79438 +t_Error FM_MACSEC_DumpRegs(t_Handle h_FmMacsec);
79439 +#endif /* (defined(DEBUG_ERRORS) && ... */
79440 +
79441 +#ifdef VERIFICATION_SUPPORT
79442 +/********************* VERIFICATION ONLY ********************************/
79443 +/**************************************************************************//**
79444 + @Function FM_MACSEC_BackdoorSet
79445 +
79446 + @Description Set register of the MACSEC memory map
79447 +
79448 + @Param[in] h_FmMacsec FM MACSEC module descriptor.
79449 + @Param[out] offset Register offset.
79450 + @Param[out] value Value to write.
79451 +
79452 +
79453 + @Return None
79454 +
79455 + @Cautions Allowed only following FM_MACSEC_Init().
79456 +*//***************************************************************************/
79457 +t_Error FM_MACSEC_BackdoorSet(t_Handle h_FmMacsec, uint32_t offset, uint32_t value);
79458 +
79459 +/**************************************************************************//**
79460 + @Function FM_MACSEC_BackdoorGet
79461 +
79462 + @Description Read from register of the MACSEC memory map.
79463 +
79464 + @Param[in] h_FmMacsec FM MACSEC module descriptor.
79465 + @Param[out] offset Register offset.
79466 +
79467 + @Return Value read
79468 +
79469 + @Cautions Allowed only following FM_MACSEC_Init().
79470 +*//***************************************************************************/
79471 +uint32_t FM_MACSEC_BackdoorGet(t_Handle h_FmMacsec, uint32_t offset);
79472 +#endif /* VERIFICATION_SUPPORT */
79473 +
79474 +/** @} */ /* end of FM_MACSEC_runtime_control_grp group */
79475 +
79476 +
79477 +/**************************************************************************//**
79478 + @Group FM_MACSEC_SECY_grp FM-MACSEC SecY
79479 +
79480 + @Description FM-MACSEC SecY API functions, definitions and enums
79481 +
79482 + @{
79483 +*//***************************************************************************/
79484 +
79485 +typedef uint8_t macsecSAKey_t[32];
79486 +typedef uint64_t macsecSCI_t;
79487 +typedef uint8_t macsecAN_t;
79488 +
79489 +/**************************************************************************//**
79490 +@Description MACSEC SECY Cipher Suite
79491 +*//***************************************************************************/
79492 +typedef enum e_FmMacsecSecYCipherSuite {
79493 + e_FM_MACSEC_SECY_GCM_AES_128 = 0, /**< GCM-AES-128 */
79494 +#if (DPAA_VERSION >= 11)
79495 + e_FM_MACSEC_SECY_GCM_AES_256 /**< GCM-AES-256 */
79496 +#endif /* (DPAA_VERSION >= 11) */
79497 +} e_FmMacsecSecYCipherSuite;
79498 +
79499 +/**************************************************************************//**
79500 + @Description MACSEC SECY Exceptions
79501 +*//***************************************************************************/
79502 +typedef enum e_FmMacsecSecYExceptions {
79503 + e_FM_MACSEC_SECY_EX_FRAME_DISCARDED /**< Frame Discarded */
79504 +} e_FmMacsecSecYExceptions;
79505 +
79506 +/**************************************************************************//**
79507 + @Description MACSEC SECY Events
79508 +*//***************************************************************************/
79509 +typedef enum e_FmMacsecSecYEvents {
79510 + e_FM_MACSEC_SECY_EV_NEXT_PN /**< Next Packet Number exhaustion threshold reached */
79511 +} e_FmMacsecSecYEvents;
79512 +
79513 +/**************************************************************************//**
79514 + @Collection MACSEC SECY Frame Discarded Descriptor error
79515 +*//***************************************************************************/
79516 +typedef uint8_t macsecTxScFrameDiscardedErrSelect_t; /**< typedef for defining Frame Discarded Descriptor errors */
79517 +
79518 +#define FM_MACSEC_SECY_TX_SC_FRM_DISCAR_ERR_NEXT_PN_ZERO 0x8000 /**< NextPn == 0 */
79519 +#define FM_MACSEC_SECY_TX_SC_FRM_DISCAR_ERR_SC_DISBALE 0x4000 /**< SC is disable */
79520 +/* @} */
79521 +
79522 +/**************************************************************************//**
79523 + @Function t_FmMacsecSecYExceptionsCallback
79524 +
79525 + @Description Exceptions user callback routine, will be called upon an
79526 + exception passing the exception identification.
79527 +
79528 + @Param[in] h_App A handle to an application layer object; This handle
79529 + will be passed by the driver upon calling this callback.
79530 + @Param[in] exception The exception.
79531 +*//***************************************************************************/
79532 +typedef void (t_FmMacsecSecYExceptionsCallback) ( t_Handle h_App,
79533 + e_FmMacsecSecYExceptions exception);
79534 +
79535 +/**************************************************************************//**
79536 + @Function t_FmMacsecSecYEventsCallback
79537 +
79538 + @Description Events user callback routine, will be called upon an
79539 + event passing the event identification.
79540 +
79541 + @Param[in] h_App A handle to an application layer object; This handle
79542 + will be passed by the driver upon calling this callback.
79543 + @Param[in] event The event.
79544 +*//***************************************************************************/
79545 +typedef void (t_FmMacsecSecYEventsCallback) ( t_Handle h_App,
79546 + e_FmMacsecSecYEvents event);
79547 +
79548 +/**************************************************************************//**
79549 + @Description RFC2863 MIB
79550 +*//***************************************************************************/
79551 +typedef struct t_MIBStatistics {
79552 + uint64_t ifInOctets; /**< Total number of byte received */
79553 + uint64_t ifInPkts; /**< Total number of packets received */
79554 + uint64_t ifInMcastPkts; /**< Total number of multicast frame received */
79555 + uint64_t ifInBcastPkts; /**< Total number of broadcast frame received */
79556 + uint64_t ifInDiscards; /**< Frames received, but discarded due to problems within the MAC RX :
79557 + - InPktsNoTag,
79558 + - InPktsLate,
79559 + - InPktsOverrun */
79560 + uint64_t ifInErrors; /**< Number of frames received with error:
79561 + - InPktsBadTag,
79562 + - InPktsNoSCI,
79563 + - InPktsNotUsingSA
79564 + - InPktsNotValid */
79565 + uint64_t ifOutOctets; /**< Total number of byte sent */
79566 + uint64_t ifOutPkts; /**< Total number of packets sent */
79567 + uint64_t ifOutMcastPkts; /**< Total number of multicast frame sent */
79568 + uint64_t ifOutBcastPkts; /**< Total number of multicast frame sent */
79569 + uint64_t ifOutDiscards; /**< Frames received, but discarded due to problems within the MAC TX N/A! */
79570 + uint64_t ifOutErrors; /**< Number of frames transmitted with error:
79571 + - FIFO Overflow Error
79572 + - FIFO Underflow Error
79573 + - Other */
79574 +} t_MIBStatistics;
79575 +
79576 +/**************************************************************************//**
79577 + @Description MACSEC SecY Rx SA Statistics
79578 +*//***************************************************************************/
79579 +typedef struct t_FmMacsecSecYRxSaStatistics {
79580 + uint32_t inPktsOK; /**< The number of frames with resolved SCI, have passed all
79581 + frame validation frame validation with the validateFrame not set to disable */
79582 + uint32_t inPktsInvalid; /**< The number of frames with resolved SCI, that have failed frame
79583 + validation with the validateFrame set to check */
79584 + uint32_t inPktsNotValid; /**< The number of frames with resolved SCI, discarded on the controlled port,
79585 + that have failed frame validation with the validateFrame set to strict or the c bit is set */
79586 + uint32_t inPktsNotUsingSA; /**< The number of frames received with resolved SCI and discarded on disabled or
79587 + not provisioned SA with validateFrame in the strict mode or the C bit is set */
79588 + uint32_t inPktsUnusedSA; /**< The number of frames received with resolved SCI on disabled or not provisioned SA
79589 + with validateFrame not in the strict mode and the C bit is cleared */
79590 +} t_FmMacsecSecYRxSaStatistics;
79591 +
79592 +/**************************************************************************//**
79593 + @Description MACSEC SecY Tx SA Statistics
79594 +*//***************************************************************************/
79595 +typedef struct t_FmMacsecSecYTxSaStatistics {
79596 + uint64_t outPktsProtected; /**< The number of frames, that the user of the controlled port requested to
79597 + be transmitted, which were integrity protected */
79598 + uint64_t outPktsEncrypted; /**< The number of frames, that the user of the controlled port requested to
79599 + be transmitted, which were confidentiality protected */
79600 +} t_FmMacsecSecYTxSaStatistics;
79601 +
79602 +/**************************************************************************//**
79603 + @Description MACSEC SecY Rx SC Statistics
79604 +*//***************************************************************************/
79605 +typedef struct t_FmMacsecSecYRxScStatistics {
79606 + uint64_t inPktsUnchecked; /**< The number of frames with resolved SCI, delivered to the user of a controlled port,
79607 + that are not validated with the validateFrame set to disable */
79608 + uint64_t inPktsDelayed; /**< The number of frames with resolved SCI, delivered to the user of a controlled port,
79609 + that have their PN smaller than the lowest_PN with the validateFrame set to
79610 + disable or replayProtect disabled */
79611 + uint64_t inPktsLate; /**< The number of frames with resolved SCI, discarded on the controlled port,
79612 + that have their PN smaller than the lowest_PN with the validateFrame set to
79613 + Check or Strict and replayProtect enabled */
79614 + uint64_t inPktsOK; /**< The number of frames with resolved SCI, have passed all
79615 + frame validation frame validation with the validateFrame not set to disable */
79616 + uint64_t inPktsInvalid; /**< The number of frames with resolved SCI, that have failed frame
79617 + validation with the validateFrame set to check */
79618 + uint64_t inPktsNotValid; /**< The number of frames with resolved SCI, discarded on the controlled port,
79619 + that have failed frame validation with the validateFrame set to strict or the c bit is set */
79620 + uint64_t inPktsNotUsingSA; /**< The number of frames received with resolved SCI and discarded on disabled or
79621 + not provisioned SA with validateFrame in the strict mode or the C bit is set */
79622 + uint64_t inPktsUnusedSA; /**< The number of frames received with resolved SCI on disabled or not provisioned SA
79623 + with validateFrame not in the strict mode and the C bit is cleared */
79624 +} t_FmMacsecSecYRxScStatistics;
79625 +
79626 +/**************************************************************************//**
79627 + @Description MACSEC SecY Tx SC Statistics
79628 +*//***************************************************************************/
79629 +typedef struct t_FmMacsecSecYTxScStatistics {
79630 + uint64_t outPktsProtected; /**< The number of frames, that the user of the controlled port requested to
79631 + be transmitted, which were integrity protected */
79632 + uint64_t outPktsEncrypted; /**< The number of frames, that the user of the controlled port requested to
79633 + be transmitted, which were confidentiality protected */
79634 +} t_FmMacsecSecYTxScStatistics;
79635 +
79636 +/**************************************************************************//**
79637 + @Description MACSEC SecY Statistics
79638 +*//***************************************************************************/
79639 +typedef struct t_FmMacsecSecYStatistics {
79640 + t_MIBStatistics mibCtrlStatistics; /**< Controlled port MIB statistics */
79641 + t_MIBStatistics mibNonCtrlStatistics; /**< Uncontrolled port MIB statistics */
79642 +/* Frame verification statistics */
79643 + uint64_t inPktsUntagged; /**< The number of received packets without the MAC security tag
79644 + (SecTAG) with validateFrames which is not in the strict mode */
79645 + uint64_t inPktsNoTag; /**< The number of received packets discarded without the
79646 + MAC security tag (SecTAG) with validateFrames which is in the strict mode */
79647 + uint64_t inPktsBadTag; /**< The number of received packets discarded with an invalid
79648 + SecTAG or a zero value PN or an invalid ICV */
79649 + uint64_t inPktsUnknownSCI; /**< The number of received packets with unknown SCI with the
79650 + condition : validateFrames is not in the strict mode and the
79651 + C bit in the SecTAG is not set */
79652 + uint64_t inPktsNoSCI; /**< The number of received packets discarded with unknown SCI
79653 + information with the condition : validateFrames is in the strict mode
79654 + or the C bit in the SecTAG is set */
79655 + uint64_t inPktsOverrun; /**< The number of packets discarded because the number of
79656 + received packets exceeded the cryptographic performance capabilities */
79657 +/* Frame validation statistics */
79658 + uint64_t inOctetsValidated; /**< The number of octets of plaintext recovered from received frames with
79659 + resolved SCI that were integrity protected but not encrypted */
79660 + uint64_t inOctetsDecrypted; /**< The number of octets of plaintext recovered from received frames with
79661 + resolved SCI that were integrity protected and encrypted */
79662 +/* Frame generation statistics */
79663 + uint64_t outPktsUntagged; /**< The number of frames, that the user of the controlled port requested to
79664 + be transmitted, with protectFrame false */
79665 + uint64_t outPktsTooLong; /**< The number of frames, that the user of the controlled port requested to
79666 + be transmitted, discarded due to length being larger than Maximum Frame Length (MACSEC_MFL) */
79667 +/* Frame protection statistics */
79668 + uint64_t outOctetsProtected; /**< The number of octets of User Data in transmitted frames that were
79669 + integrity protected but not encrypted */
79670 + uint64_t outOctetsEncrypted; /**< The number of octets of User Data in transmitted frames that were
79671 + both integrity protected and encrypted */
79672 +} t_FmMacsecSecYStatistics;
79673 +
79674 +
79675 +/**************************************************************************//**
79676 + @Description MACSEC SecY SC Params
79677 +*//***************************************************************************/
79678 +typedef struct t_FmMacsecSecYSCParams {
79679 + macsecSCI_t sci; /**< The secure channel identification of the SC */
79680 + e_FmMacsecSecYCipherSuite cipherSuite; /**< Cipher suite to be used for the SC */
79681 +} t_FmMacsecSecYSCParams;
79682 +
79683 +/**************************************************************************//**
79684 + @Group FM_MACSEC_SECY_init_grp FM-MACSEC SecY Initialization Unit
79685 +
79686 + @Description FM-MACSEC SecY Initialization Unit
79687 +
79688 + @{
79689 +*//***************************************************************************/
79690 +
79691 +/**************************************************************************//**
79692 + @Description enum for validate frames
79693 +*//***************************************************************************/
79694 +typedef enum e_FmMacsecValidFrameBehavior {
79695 + e_FM_MACSEC_VALID_FRAME_BEHAVIOR_DISABLE = 0, /**< disable the validation function */
79696 + e_FM_MACSEC_VALID_FRAME_BEHAVIOR_CHECK, /**< enable the validation function but only for checking
79697 + without filtering out invalid frames */
79698 + e_FM_MACSEC_VALID_FRAME_BEHAVIOR_STRICT /**< enable the validation function and also strictly filter
79699 + out those invalid frames */
79700 +} e_FmMacsecValidFrameBehavior;
79701 +
79702 +/**************************************************************************//**
79703 + @Description enum for sci insertion
79704 +*//***************************************************************************/
79705 +typedef enum e_FmMacsecSciInsertionMode {
79706 + e_FM_MACSEC_SCI_INSERTION_MODE_EXPLICIT_SECTAG = 0, /**< explicit sci in the sectag */
79707 + e_FM_MACSEC_SCI_INSERTION_MODE_EXPLICIT_MAC_SA, /**< mac sa is overwritten with the sci*/
79708 + e_FM_MACSEC_SCI_INSERTION_MODE_IMPLICT_PTP /**< implicit point-to-point sci (pre-shared) */
79709 +} e_FmMacsecSciInsertionMode;
79710 +
79711 +/**************************************************************************//**
79712 + @Description FM MACSEC SecY config input
79713 +*//***************************************************************************/
79714 +typedef struct t_FmMacsecSecYParams {
79715 + t_Handle h_FmMacsec; /**< A handle to the FM MACSEC object */
79716 + t_FmMacsecSecYSCParams txScParams; /**< Tx SC Params */
79717 + uint32_t numReceiveChannels; /**< Number of receive channels dedicated to this SecY */
79718 + t_FmMacsecSecYExceptionsCallback *f_Exception; /**< Callback routine to be called by the driver upon SecY exception */
79719 + t_FmMacsecSecYEventsCallback *f_Event; /**< Callback routine to be called by the driver upon SecY event */
79720 + t_Handle h_App; /**< A handle to an application layer object; This handle will
79721 + be passed by the driver upon calling the above callbacks */
79722 +} t_FmMacsecSecYParams;
79723 +
79724 +/**************************************************************************//**
79725 + @Function FM_MACSEC_SECY_Config
79726 +
79727 + @Description Creates descriptor for the FM MACSEC SECY module;
79728 +
79729 + The routine returns a handle (descriptor) to the FM MACSEC SECY object;
79730 + This descriptor must be passed as first parameter to all other
79731 + FM MACSEC SECY function calls;
79732 + No actual initialization or configuration of FM MACSEC SecY hardware is
79733 + done by this routine.
79734 +
79735 + @Param[in] p_FmMacsecSecYParam Pointer to data structure of parameters.
79736 +
79737 + @Return Handle to FM MACSEC SECY object, or NULL for Failure.
79738 +*//***************************************************************************/
79739 +t_Handle FM_MACSEC_SECY_Config(t_FmMacsecSecYParams *p_FmMacsecSecYParam);
79740 +
79741 +/**************************************************************************//**
79742 + @Function FM_MACSEC_SECY_Init
79743 +
79744 + @Description Initializes the FM MACSEC SECY module.
79745 +
79746 + @Param[in] h_FmMacsecSecY FM MACSEC SECY module descriptor.
79747 +
79748 + @Return E_OK on success; Error code otherwise.
79749 +*//***************************************************************************/
79750 +t_Error FM_MACSEC_SECY_Init(t_Handle h_FmMacsecSecY);
79751 +
79752 +/**************************************************************************//**
79753 + @Function FM_MACSEC_SECY_Free
79754 +
79755 + @Description Frees all resources that were assigned to FM MACSEC SECY module.
79756 +
79757 + Calling this routine invalidates the descriptor.
79758 +
79759 + @Param[in] h_FmMacsecSecY FM MACSEC SECY module descriptor.
79760 +
79761 + @Return E_OK on success; Error code otherwise.
79762 +*//***************************************************************************/
79763 +t_Error FM_MACSEC_SECY_Free(t_Handle h_FmMacsecSecY);
79764 +
79765 +/**************************************************************************//**
79766 + @Group FM_MACSEC_SECY_advanced_init_grp FM-MACSEC SecY Advanced Configuration Unit
79767 +
79768 + @Description Configuration functions used to change default values.
79769 +
79770 + @{
79771 +*//***************************************************************************/
79772 +
79773 +/**************************************************************************//**
79774 + @Function FM_MACSEC_SECY_ConfigSciInsertionMode
79775 +
79776 + @Description Calling this routine changes the SCI-insertion-mode in the
79777 + internal driver data base from its default configuration
79778 + [DEFAULT_sciInsertionMode]
79779 +
79780 + @Param[in] h_FmMacsecSecY FM MACSEC SECY module descriptor.
79781 + @Param[in] sciInsertionMode Sci insertion mode
79782 +
79783 + @Return E_OK on success; Error code otherwise.
79784 +
79785 + @Cautions Allowed only following FM_MACSEC_SECY_Config() and before FM_MACSEC_SECY_Init();
79786 +
79787 +*//***************************************************************************/
79788 +t_Error FM_MACSEC_SECY_ConfigSciInsertionMode(t_Handle h_FmMacsecSecY, e_FmMacsecSciInsertionMode sciInsertionMode);
79789 +
79790 +/**************************************************************************//**
79791 + @Function FM_MACSEC_SECY_ConfigProtectFrames
79792 +
79793 + @Description Calling this routine changes the protect-frame mode in the
79794 + internal driver data base from its default configuration
79795 + [DEFAULT_protectFrames]
79796 +
79797 + @Param[in] h_FmMacsecSecY FM MACSEC SECY module descriptor.
79798 + @Param[in] protectFrames If FALSE, frames are transmitted without modification
79799 +
79800 + @Return E_OK on success; Error code otherwise.
79801 +
79802 + @Cautions Allowed only following FM_MACSEC_SECY_Config() and before FM_MACSEC_SECY_Init();
79803 +
79804 +*//***************************************************************************/
79805 +t_Error FM_MACSEC_SECY_ConfigProtectFrames(t_Handle h_FmMacsecSecY, bool protectFrames);
79806 +
79807 +/**************************************************************************//**
79808 + @Function FM_MACSEC_SECY_ConfigReplayWindow
79809 +
79810 + @Description Calling this routine changes the replay-window settings in the
79811 + internal driver data base from its default configuration
79812 + [DEFAULT_replayEnable], [DEFAULT_replayWindow]
79813 +
79814 + @Param[in] h_FmMacsecSecY FM MACSEC SECY module descriptor.
79815 + @Param[in] replayProtect; Replay protection function mode
79816 + @Param[in] replayWindow; The size of the replay window
79817 +
79818 + @Return E_OK on success; Error code otherwise.
79819 +
79820 + @Cautions Allowed only following FM_MACSEC_SECY_Config() and before FM_MACSEC_SECY_Init();
79821 +
79822 +*//***************************************************************************/
79823 +t_Error FM_MACSEC_SECY_ConfigReplayWindow(t_Handle h_FmMacsecSecY, bool replayProtect, uint32_t replayWindow);
79824 +
79825 +/**************************************************************************//**
79826 + @Function FM_MACSEC_SECY_ConfigValidationMode
79827 +
79828 + @Description Calling this routine changes the frame-validation-behavior mode
79829 + in the internal driver data base from its default configuration
79830 + [DEFAULT_validateFrames]
79831 +
79832 + @Param[in] h_FmMacsecSecY FM MACSEC SECY module descriptor.
79833 + @Param[in] validateFrames Validation function mode
79834 +
79835 + @Return E_OK on success; Error code otherwise.
79836 +
79837 + @Cautions Allowed only following FM_MACSEC_SECY_Config() and before FM_MACSEC_SECY_Init();
79838 +
79839 +*//***************************************************************************/
79840 +t_Error FM_MACSEC_SECY_ConfigValidationMode(t_Handle h_FmMacsecSecY, e_FmMacsecValidFrameBehavior validateFrames);
79841 +
79842 +/**************************************************************************//**
79843 + @Function FM_MACSEC_SECY_ConfigConfidentiality
79844 +
79845 + @Description Calling this routine changes the confidentiality settings in the
79846 + internal driver data base from its default configuration
79847 + [DEFAULT_confidentialityEnable], [DEFAULT_confidentialityOffset]
79848 +
79849 + @Param[in] h_FmMacsecSecY FM MACSEC SECY module descriptor.
79850 + @Param[in] confidentialityEnable TRUE - confidentiality protection and integrity protection
79851 + FALSE - no confidentiality protection, only integrity protection
79852 + @Param[in] confidentialityOffset The number of initial octets of each MSDU without confidentiality protection
79853 + common values are 0, 30, and 50
79854 +
79855 + @Return E_OK on success; Error code otherwise.
79856 +
79857 + @Cautions Allowed only following FM_MACSEC_SECY_Config() and before FM_MACSEC_SECY_Init();
79858 +
79859 +*//***************************************************************************/
79860 +t_Error FM_MACSEC_SECY_ConfigConfidentiality(t_Handle h_FmMacsecSecY, bool confidentialityEnable, uint16_t confidentialityOffset);
79861 +
79862 +/**************************************************************************//**
79863 + @Function FM_MACSEC_SECY_ConfigPointToPoint
79864 +
79865 + @Description configure this SecY to work in point-to-point mode, means that
79866 + it will have only one rx sc;
79867 +
79868 + @Param[in] h_FmMacsecSecY FM MACSEC SECY module descriptor.
79869 +
79870 + @Return E_OK on success; Error code otherwise.
79871 +
79872 + @Cautions Allowed only following FM_MACSEC_SECY_Config() and before FM_MACSEC_SECY_Init();
79873 + Can be called only once in a system; only the first secY that will call this
79874 + routine will be able to operate in Point-To-Point mode.
79875 +*//***************************************************************************/
79876 +t_Error FM_MACSEC_SECY_ConfigPointToPoint(t_Handle h_FmMacsecSecY);
79877 +
79878 +/**************************************************************************//**
79879 + @Function FM_MACSEC_SECY_ConfigException
79880 +
79881 + @Description Calling this routine changes the internal driver data base
79882 + from its default selection of exceptions enablement;
79883 + By default all exceptions are enabled.
79884 +
79885 + @Param[in] h_FmMacsecSecY FM MACSEC SECY module descriptor.
79886 + @Param[in] exception The exception to be selected.
79887 + @Param[in] enable TRUE to enable interrupt, FALSE to mask it.
79888 +
79889 + @Return E_OK on success; Error code otherwise.
79890 +
79891 + @Cautions Allowed only following FM_MACSEC_SECY_Config() and before FM_MACSEC_SECY_Init().
79892 +*//***************************************************************************/
79893 +t_Error FM_MACSEC_SECY_ConfigException(t_Handle h_FmMacsecSecY, e_FmMacsecSecYExceptions exception, bool enable);
79894 +
79895 +/**************************************************************************//**
79896 + @Function FM_MACSEC_SECY_ConfigEvent
79897 +
79898 + @Description Calling this routine changes the internal driver data base
79899 + from its default selection of events enablement;
79900 + By default all events are enabled.
79901 +
79902 + @Param[in] h_FmMacsecSecY FM MACSEC SECY module descriptor.
79903 + @Param[in] event The event to be selected.
79904 + @Param[in] enable TRUE to enable interrupt, FALSE to mask it.
79905 +
79906 + @Return E_OK on success; Error code otherwise.
79907 +
79908 + @Cautions Allowed only following FM_MACSEC_SECY_Config() and before FM_MACSEC_SECY_Init().
79909 +*//***************************************************************************/
79910 +t_Error FM_MACSEC_SECY_ConfigEvent(t_Handle h_FmMacsecSecY, e_FmMacsecSecYEvents event, bool enable);
79911 +
79912 +/** @} */ /* end of FM_MACSEC_SECY_advanced_init_grp group */
79913 +/** @} */ /* end of FM_MACSEC_SECY_init_grp group */
79914 +
79915 +
79916 +/**************************************************************************//**
79917 + @Group FM_MACSEC_SECY_runtime_control_grp FM-MACSEC SecY Runtime Control Unit
79918 +
79919 + @Description FM MACSEC SECY Runtime control unit API functions, definitions and enums.
79920 +
79921 + @{
79922 +*//***************************************************************************/
79923 +
79924 +/**************************************************************************//**
79925 + @Function FM_MACSEC_SECY_CreateRxSc
79926 +
79927 + @Description Create a receive secure channel.
79928 +
79929 + @Param[in] h_FmMacsecSecY FM MACSEC SECY module descriptor.
79930 + @Param[in] scParams secure channel params.
79931 +
79932 + @Return E_OK on success; Error code otherwise.
79933 +
79934 + @Cautions Allowed only following FM_MACSEC_SECY_Init().
79935 +*//***************************************************************************/
79936 +t_Handle FM_MACSEC_SECY_CreateRxSc(t_Handle h_FmMacsecSecY, t_FmMacsecSecYSCParams *p_ScParams);
79937 +
79938 +/**************************************************************************//**
79939 + @Function FM_MACSEC_SECY_DeleteRxSc
79940 +
79941 + @Description Deleting an initialized secure channel.
79942 +
79943 + @Param[in] h_FmMacsecSecY FM MACSEC SECY module descriptor.
79944 + @Param[in] h_Sc SC handle as returned by FM_MACSEC_SECY_CreateRxSc.
79945 +
79946 + @Return E_OK on success; Error code otherwise.
79947 +
79948 + @Cautions Allowed only following FM_MACSEC_SECY_CreateRxSc().
79949 +*//***************************************************************************/
79950 +t_Error FM_MACSEC_SECY_DeleteRxSc(t_Handle h_FmMacsecSecY, t_Handle h_Sc);
79951 +
79952 +/**************************************************************************//**
79953 + @Function FM_MACSEC_SECY_CreateRxSa
79954 +
79955 + @Description Create a receive secure association for the secure channel;
79956 + the SA cannot be used to receive frames until FM_MACSEC_SECY_RxSaEnableReceive is called.
79957 +
79958 + @Param[in] h_FmMacsecSecY FM MACSEC SECY module descriptor.
79959 + @Param[in] h_Sc SC handle as returned by FM_MACSEC_SECY_CreateRxSc.
79960 + @Param[in] an association number represent the SA.
79961 + @Param[in] lowestPn the lowest acceptable PN value for a received frame.
79962 + @Param[in] key the desired key for this SA.
79963 +
79964 + @Return E_OK on success; Error code otherwise.
79965 +
79966 + @Cautions Allowed only following FM_MACSEC_SECY_CreateRxSc().
79967 +*//***************************************************************************/
79968 +t_Error FM_MACSEC_SECY_CreateRxSa(t_Handle h_FmMacsecSecY, t_Handle h_Sc, macsecAN_t an, uint32_t lowestPn, macsecSAKey_t key);
79969 +
79970 +/**************************************************************************//**
79971 + @Function FM_MACSEC_SECY_DeleteRxSa
79972 +
79973 + @Description Deleting an initialized secure association.
79974 +
79975 + @Param[in] h_FmMacsecSecY FM MACSEC SECY module descriptor.
79976 + @Param[in] h_Sc SC handle as returned by FM_MACSEC_SECY_CreateRxSc.
79977 + @Param[in] an association number represent the SA.
79978 +
79979 + @Return E_OK on success; Error code otherwise.
79980 +
79981 + @Cautions Allowed only following FM_MACSEC_SECY_Init().
79982 +*//***************************************************************************/
79983 +t_Error FM_MACSEC_SECY_DeleteRxSa(t_Handle h_FmMacsecSecY, t_Handle h_Sc, macsecAN_t an);
79984 +
79985 +/**************************************************************************//**
79986 + @Function FM_MACSEC_SECY_RxSaEnableReceive
79987 +
79988 + @Description Enabling the SA to receive frames.
79989 +
79990 + @Param[in] h_FmMacsecSecY FM MACSEC SECY module descriptor.
79991 + @Param[in] h_Sc SC handle as returned by FM_MACSEC_SECY_CreateRxSc.
79992 + @Param[in] an association number represent the SA.
79993 +
79994 + @Return E_OK on success; Error code otherwise.
79995 +
79996 + @Cautions Allowed only following FM_MACSEC_SECY_CreateRxSa().
79997 +*//***************************************************************************/
79998 +t_Error FM_MACSEC_SECY_RxSaEnableReceive(t_Handle h_FmMacsecSecY, t_Handle h_Sc, macsecAN_t an);
79999 +
80000 +/**************************************************************************//**
80001 + @Function FM_MACSEC_SECY_RxSaDisableReceive
80002 +
80003 + @Description Disabling the SA from receive frames.
80004 +
80005 + @Param[in] h_FmMacsecSecY FM MACSEC SECY module descriptor.
80006 + @Param[in] h_Sc SC handle as returned by FM_MACSEC_SECY_CreateRxSc.
80007 + @Param[in] an association number represent the SA.
80008 +
80009 + @Return E_OK on success; Error code otherwise.
80010 +
80011 + @Cautions Allowed only following FM_MACSEC_SECY_CreateRxSa().
80012 +*//***************************************************************************/
80013 +t_Error FM_MACSEC_SECY_RxSaDisableReceive(t_Handle h_FmMacsecSecY, t_Handle h_Sc, macsecAN_t an);
80014 +
80015 +/**************************************************************************//**
80016 + @Function FM_MACSEC_SECY_RxSaUpdateNextPn
80017 +
80018 + @Description Update the next packet number expected on RX;
80019 + The value of nextPN shall be set to the greater of its existing value and the
80020 + supplied of updtNextPN (802.1AE-2006 10.7.15).
80021 +
80022 + @Param[in] h_FmMacsecSecY FM MACSEC SECY module descriptor.
80023 + @Param[in] h_Sc SC handle as returned by FM_MACSEC_SECY_CreateRxSc.
80024 + @Param[in] an association number represent the SA.
80025 + @Param[in] updtNextPN the next PN value for a received frame.
80026 +
80027 + @Return E_OK on success; Error code otherwise.
80028 +
80029 + @Cautions Allowed only following FM_MACSEC_SECY_CreateRxSa().
80030 +*//***************************************************************************/
80031 +t_Error FM_MACSEC_SECY_RxSaUpdateNextPn(t_Handle h_FmMacsecSecY, t_Handle h_Sc, macsecAN_t an, uint32_t updtNextPN);
80032 +
80033 +/**************************************************************************//**
80034 + @Function FM_MACSEC_SECY_RxSaUpdateLowestPn
80035 +
80036 + @Description Update the lowest packet number expected on RX;
80037 + The value of lowestPN shall be set to the greater of its existing value and the
80038 + supplied of updtLowestPN (802.1AE-2006 10.7.15).
80039 +
80040 + @Param[in] h_FmMacsecSecY FM MACSEC SECY module descriptor.
80041 + @Param[in] h_Sc SC handle as returned by FM_MACSEC_SECY_CreateRxSc.
80042 + @Param[in] an association number represent the SA.
80043 + @Param[in] updtLowestPN the lowest PN acceptable value for a received frame.
80044 +
80045 + @Return E_OK on success; Error code otherwise.
80046 +
80047 + @Cautions Allowed only following FM_MACSEC_SECY_CreateRxSa().
80048 +*//***************************************************************************/
80049 +t_Error FM_MACSEC_SECY_RxSaUpdateLowestPn(t_Handle h_FmMacsecSecY, t_Handle h_Sc, macsecAN_t an, uint32_t updtLowestPN);
80050 +
80051 +/**************************************************************************//**
80052 + @Function FM_MACSEC_SECY_RxSaModifyKey
80053 +
80054 + @Description Modify the current key of the SA with a new one.
80055 +
80056 + @Param[in] h_FmMacsecSecY FM MACSEC SECY module descriptor.
80057 + @Param[in] h_Sc SC handle as returned by FM_MACSEC_SECY_CreateRxSc.
80058 + @Param[in] an association number represent the SA.
80059 + @Param[in] key new key to replace the current key.
80060 +
80061 + @Return E_OK on success; Error code otherwise.
80062 +
80063 + @Cautions Allowed only following FM_MACSEC_SECY_CreateRxSa().
80064 +*//***************************************************************************/
80065 +t_Error FM_MACSEC_SECY_RxSaModifyKey(t_Handle h_FmMacsecSecY, t_Handle h_Sc, macsecAN_t an, macsecSAKey_t key);
80066 +
80067 +/**************************************************************************//**
80068 + @Function FM_MACSEC_SECY_CreateTxSa
80069 +
80070 + @Description Create a transmit secure association for the secure channel;
80071 + the SA cannot be used to transmit frames until FM_MACSEC_SECY_TxSaSetActivate is called;
80072 + Only one SA can be active at a time.
80073 +
80074 + @Param[in] h_FmMacsecSecY FM MACSEC SECY module descriptor.
80075 + @Param[in] an association number represent the SA.
80076 + @Param[in] key the desired key for this SA.
80077 +
80078 + @Return E_OK on success; Error code otherwise.
80079 +
80080 + @Cautions Allowed only following FM_MACSEC_SECY_Init().
80081 +*//***************************************************************************/
80082 +t_Error FM_MACSEC_SECY_CreateTxSa(t_Handle h_FmMacsecSecY, macsecAN_t an, macsecSAKey_t key);
80083 +
80084 +/**************************************************************************//**
80085 + @Function FM_MACSEC_SECY_DeleteTxSa
80086 +
80087 + @Description Deleting an initialized secure association.
80088 +
80089 + @Param[in] h_FmMacsecSecY FM MACSEC SECY module descriptor.
80090 + @Param[in] an association number represent the SA.
80091 +
80092 + @Return E_OK on success; Error code otherwise.
80093 +
80094 + @Cautions Allowed only following FM_MACSEC_SECY_Init().
80095 +*//***************************************************************************/
80096 +t_Error FM_MACSEC_SECY_DeleteTxSa(t_Handle h_FmMacsecSecY, macsecAN_t an);
80097 +
80098 +/**************************************************************************//**
80099 + @Function FM_MACSEC_SECY_TxSaModifyKey
80100 +
80101 + @Description Modify the key of the inactive SA with a new one.
80102 +
80103 + @Param[in] h_FmMacsecSecY FM MACSEC SECY module descriptor.
80104 + @Param[in] nextActiveAn association number represent the next SA to be activated.
80105 + @Param[in] key new key to replace the current key.
80106 +
80107 + @Return E_OK on success; Error code otherwise.
80108 +
80109 + @Cautions Allowed only following FM_MACSEC_SECY_Init().
80110 +*//***************************************************************************/
80111 +t_Error FM_MACSEC_SECY_TxSaModifyKey(t_Handle h_FmMacsecSecY, macsecAN_t nextActiveAn, macsecSAKey_t key);
80112 +
80113 +/**************************************************************************//**
80114 + @Function FM_MACSEC_SECY_TxSaSetActive
80115 +
80116 + @Description Set this SA to the active SA to be used on TX for SC;
80117 + only one SA can be active at a time.
80118 +
80119 + @Param[in] h_FmMacsecSecY FM MACSEC SECY module descriptor.
80120 + @Param[in] an association number represent the SA.
80121 +
80122 + @Return E_OK on success; Error code otherwise.
80123 +
80124 + @Cautions Allowed only following FM_MACSEC_SECY_Init().
80125 +*//***************************************************************************/
80126 +t_Error FM_MACSEC_SECY_TxSaSetActive(t_Handle h_FmMacsecSecY, macsecAN_t an);
80127 +
80128 +/**************************************************************************//**
80129 + @Function FM_MACSEC_SECY_TxSaGetActive
80130 +
80131 + @Description Get the active SA that being used for TX.
80132 +
80133 + @Param[in] h_FmMacsecSecY FM MACSEC SECY module descriptor.
80134 + @Param[out] p_An the active an.
80135 +
80136 + @Return E_OK on success; Error code otherwise.
80137 +
80138 + @Cautions Allowed only following FM_MACSEC_SECY_Init().
80139 +*//***************************************************************************/
80140 +t_Error FM_MACSEC_SECY_TxSaGetActive(t_Handle h_FmMacsecSecY, macsecAN_t *p_An);
80141 +
80142 +/**************************************************************************//**
80143 + @Function FM_MACSEC_SECY_GetStatistics
80144 +
80145 + @Description get all statistics counters.
80146 +
80147 + @Param[in] h_FmMacsecSecY FM MACSEC SECY module descriptor.
80148 + @Param[in] p_Statistics Structure with statistics.
80149 +
80150 + @Return E_OK on success; Error code otherwise.
80151 +
80152 + @Cautions Allowed only following FM_MACSEC_SECY_Init().
80153 +*//***************************************************************************/
80154 +t_Error FM_MACSEC_SECY_GetStatistics(t_Handle h_FmMacsecSecY, t_FmMacsecSecYStatistics *p_Statistics);
80155 +
80156 +/**************************************************************************//**
80157 + @Function FM_MACSEC_SECY_RxScGetStatistics
80158 +
80159 + @Description get all statistics counters.
80160 +
80161 + @Param[in] h_FmMacsecSecY FM MACSEC SECY module descriptor.
80162 + @Param[in] h_Sc Rx Sc handle.
80163 + @Param[in] p_Statistics Structure with statistics.
80164 +
80165 + @Return E_OK on success; Error code otherwise.
80166 +
80167 + @Cautions Allowed only following FM_MACSEC_SECY_Init().
80168 +*//***************************************************************************/
80169 +t_Error FM_MACSEC_SECY_RxScGetStatistics(t_Handle h_FmMacsecSecY, t_Handle h_Sc, t_FmMacsecSecYRxScStatistics *p_Statistics);
80170 +
80171 +/**************************************************************************//**
80172 + @Function FM_MACSEC_SECY_RxSaGetStatistics
80173 +
80174 + @Description get all statistics counters
80175 +
80176 + @Param[in] h_FmMacsecSecY FM MACSEC SECY module descriptor.
80177 + @Param[in] h_Sc Rx Sc handle.
80178 + @Param[in] an association number represent the SA.
80179 + @Param[in] p_Statistics Structure with statistics.
80180 +
80181 + @Return E_OK on success; Error code otherwise.
80182 +
80183 + @Cautions Allowed only following FM_MACSEC_SECY_Init().
80184 +*//***************************************************************************/
80185 +t_Error FM_MACSEC_SECY_RxSaGetStatistics(t_Handle h_FmMacsecSecY, t_Handle h_Sc, macsecAN_t an, t_FmMacsecSecYRxSaStatistics *p_Statistics);
80186 +
80187 +/**************************************************************************//**
80188 + @Function FM_MACSEC_SECY_TxScGetStatistics
80189 +
80190 + @Description get all statistics counters.
80191 +
80192 + @Param[in] h_FmMacsecSecY FM MACSEC SECY module descriptor.
80193 + @Param[in] p_Statistics Structure with statistics.
80194 +
80195 + @Return E_OK on success; Error code otherwise.
80196 +
80197 + @Cautions Allowed only following FM_MACSEC_SECY_Init().
80198 +*//***************************************************************************/
80199 +t_Error FM_MACSEC_SECY_TxScGetStatistics(t_Handle h_FmMacsecSecY, t_FmMacsecSecYTxScStatistics *p_Statistics);
80200 +
80201 +/**************************************************************************//**
80202 + @Function FM_MACSEC_SECY_TxSaGetStatistics
80203 +
80204 + @Description get all statistics counters.
80205 +
80206 + @Param[in] h_FmMacsecSecY FM MACSEC SECY module descriptor.
80207 + @Param[in] an association number represent the SA.
80208 + @Param[in] p_Statistics Structure with statistics.
80209 +
80210 + @Return E_OK on success; Error code otherwise.
80211 +
80212 + @Cautions Allowed only following FM_MACSEC_SECY_Init().
80213 +*//***************************************************************************/
80214 +t_Error FM_MACSEC_SECY_TxSaGetStatistics(t_Handle h_FmMacsecSecY, macsecAN_t an, t_FmMacsecSecYTxSaStatistics *p_Statistics);
80215 +
80216 +/**************************************************************************//**
80217 + @Function FM_MACSEC_SECY_SetException
80218 +
80219 + @Description Calling this routine enables/disables the specified exception.
80220 +
80221 + @Param[in] h_FmMacsecSecY FM MACSEC SECY module descriptor.
80222 + @Param[in] exception The exception to be selected.
80223 + @Param[in] enable TRUE to enable interrupt, FALSE to mask it.
80224 +
80225 + @Return E_OK on success; Error code otherwise.
80226 +
80227 + @Cautions Allowed only following FM_MACSEC_SECY_Init().
80228 +*//***************************************************************************/
80229 +t_Error FM_MACSEC_SECY_SetException(t_Handle h_FmMacsecSecY, e_FmMacsecExceptions exception, bool enable);
80230 +
80231 +/**************************************************************************//**
80232 + @Function FM_MACSEC_SECY_SetEvent
80233 +
80234 + @Description Calling this routine enables/disables the specified event.
80235 +
80236 + @Param[in] h_FmMacsecSecY FM MACSEC SECY module descriptor.
80237 + @Param[in] event The event to be selected.
80238 + @Param[in] enable TRUE to enable interrupt, FALSE to mask it.
80239 +
80240 + @Return E_OK on success; Error code otherwise.
80241 +
80242 + @Cautions Allowed only following FM_MACSEC_SECY_Config() and before FM_MACSEC_SECY_Init().
80243 +*//***************************************************************************/
80244 +t_Error FM_MACSEC_SECY_SetEvent(t_Handle h_FmMacsecSecY, e_FmMacsecSecYEvents event, bool enable);
80245 +
80246 +/**************************************************************************//**
80247 + @Function FM_MACSEC_SECY_GetRxScPhysId
80248 +
80249 + @Description return the physical id of the Secure Channel.
80250 +
80251 + @Param[in] h_FmMacsecSecY FM MACSEC SECY module descriptor.
80252 + @Param[in] h_Sc SC handle as returned by FM_MACSEC_SECY_CreateRxSc.
80253 + @Param[out] p_ScPhysId the SC physical id.
80254 +
80255 + @Return E_OK on success; Error code otherwise.
80256 +
80257 + @Cautions Allowed only following FM_MACSEC_SECY_CreateRxSc().
80258 +*//***************************************************************************/
80259 +t_Error FM_MACSEC_SECY_GetRxScPhysId(t_Handle h_FmMacsecSecY, t_Handle h_Sc, uint32_t *p_ScPhysId);
80260 +
80261 +/**************************************************************************//**
80262 + @Function FM_MACSEC_SECY_GetTxScPhysId
80263 +
80264 + @Description return the physical id of the Secure Channel.
80265 +
80266 + @Param[in] h_FmMacsecSecY FM MACSEC SECY module descriptor.
80267 + @Param[out] p_ScPhysId the SC physical id.
80268 +
80269 + @Return E_OK on success; Error code otherwise.
80270 +
80271 + @Cautions Allowed only following FM_MACSEC_SECY_Init().
80272 +*//***************************************************************************/
80273 +t_Error FM_MACSEC_SECY_GetTxScPhysId(t_Handle h_FmMacsecSecY, uint32_t *p_ScPhysId);
80274 +
80275 +/** @} */ /* end of FM_MACSEC_SECY_runtime_control_grp group */
80276 +/** @} */ /* end of FM_MACSEC_SECY_grp group */
80277 +/** @} */ /* end of FM_MACSEC_grp group */
80278 +/** @} */ /* end of FM_grp group */
80279 +
80280 +
80281 +#endif /* __FM_MACSEC_EXT_H */
80282 --- /dev/null
80283 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/Peripherals/fm_muram_ext.h
80284 @@ -0,0 +1,170 @@
80285 +/*
80286 + * Copyright 2008-2012 Freescale Semiconductor Inc.
80287 + *
80288 + * Redistribution and use in source and binary forms, with or without
80289 + * modification, are permitted provided that the following conditions are met:
80290 + * * Redistributions of source code must retain the above copyright
80291 + * notice, this list of conditions and the following disclaimer.
80292 + * * Redistributions in binary form must reproduce the above copyright
80293 + * notice, this list of conditions and the following disclaimer in the
80294 + * documentation and/or other materials provided with the distribution.
80295 + * * Neither the name of Freescale Semiconductor nor the
80296 + * names of its contributors may be used to endorse or promote products
80297 + * derived from this software without specific prior written permission.
80298 + *
80299 + *
80300 + * ALTERNATIVELY, this software may be distributed under the terms of the
80301 + * GNU General Public License ("GPL") as published by the Free Software
80302 + * Foundation, either version 2 of that License or (at your option) any
80303 + * later version.
80304 + *
80305 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
80306 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
80307 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
80308 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
80309 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
80310 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
80311 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
80312 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
80313 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
80314 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
80315 + */
80316 +
80317 +
80318 +/**************************************************************************//**
80319 + @File fm_muram_ext.h
80320 +
80321 + @Description FM MURAM Application Programming Interface.
80322 +*//***************************************************************************/
80323 +#ifndef __FM_MURAM_EXT
80324 +#define __FM_MURAM_EXT
80325 +
80326 +#include "error_ext.h"
80327 +#include "std_ext.h"
80328 +
80329 +
80330 +/**************************************************************************//**
80331 +
80332 + @Group FM_grp Frame Manager API
80333 +
80334 + @Description FM API functions, definitions and enums
80335 +
80336 + @{
80337 +*//***************************************************************************/
80338 +
80339 +/**************************************************************************//**
80340 + @Group FM_muram_grp FM MURAM
80341 +
80342 + @Description FM MURAM API functions, definitions and enums
80343 +
80344 + @{
80345 +*//***************************************************************************/
80346 +
80347 +/**************************************************************************//**
80348 + @Group FM_muram_init_grp FM MURAM Initialization Unit
80349 +
80350 + @Description FM MURAM initialization API functions, definitions and enums
80351 +
80352 + @{
80353 +*//***************************************************************************/
80354 +
80355 +/**************************************************************************//**
80356 + @Function FM_MURAM_ConfigAndInit
80357 +
80358 + @Description Creates partition in the MURAM.
80359 +
80360 + The routine returns a handle (descriptor) to the MURAM partition.
80361 + This descriptor must be passed as first parameter to all other
80362 + FM-MURAM function calls.
80363 +
80364 + No actual initialization or configuration of FM_MURAM hardware is
80365 + done by this routine.
80366 +
80367 + @Param[in] baseAddress - Pointer to base of memory mapped FM-MURAM.
80368 + @Param[in] size - Size of the FM-MURAM partition.
80369 +
80370 + @Return Handle to FM-MURAM object, or NULL for Failure.
80371 +*//***************************************************************************/
80372 +t_Handle FM_MURAM_ConfigAndInit(uintptr_t baseAddress, uint32_t size);
80373 +
80374 +/**************************************************************************//**
80375 + @Function FM_MURAM_Free
80376 +
80377 + @Description Frees all resources that were assigned to FM-MURAM module.
80378 +
80379 + Calling this routine invalidates the descriptor.
80380 +
80381 + @Param[in] h_FmMuram - FM-MURAM module descriptor.
80382 +
80383 + @Return E_OK on success; Error code otherwise.
80384 +*//***************************************************************************/
80385 +t_Error FM_MURAM_Free(t_Handle h_FmMuram);
80386 +
80387 +/** @} */ /* end of FM_muram_init_grp group */
80388 +
80389 +
80390 +/**************************************************************************//**
80391 + @Group FM_muram_ctrl_grp FM MURAM Control Unit
80392 +
80393 + @Description FM MURAM control API functions, definitions and enums
80394 +
80395 + @{
80396 +*//***************************************************************************/
80397 +
80398 +/**************************************************************************//**
80399 + @Function FM_MURAM_AllocMem
80400 +
80401 + @Description Allocate some memory from FM-MURAM partition.
80402 +
80403 + @Param[in] h_FmMuram - FM-MURAM module descriptor.
80404 + @Param[in] size - size of the memory to be allocated.
80405 + @Param[in] align - Alignment of the memory.
80406 +
80407 + @Return address of the allocated memory; NULL otherwise.
80408 +*//***************************************************************************/
80409 +void * FM_MURAM_AllocMem(t_Handle h_FmMuram, uint32_t size, uint32_t align);
80410 +
80411 +/**************************************************************************//**
80412 + @Function FM_MURAM_AllocMemForce
80413 +
80414 + @Description Allocate some specific memory from FM-MURAM partition (according
80415 + to base).
80416 +
80417 + @Param[in] h_FmMuram - FM-MURAM module descriptor.
80418 + @Param[in] base - the desired base-address to be allocated.
80419 + @Param[in] size - size of the memory to be allocated.
80420 +
80421 + @Return address of the allocated memory; NULL otherwise.
80422 +*//***************************************************************************/
80423 +void * FM_MURAM_AllocMemForce(t_Handle h_FmMuram, uint64_t base, uint32_t size);
80424 +
80425 +/**************************************************************************//**
80426 + @Function FM_MURAM_FreeMem
80427 +
80428 + @Description Free an allocated memory from FM-MURAM partition.
80429 +
80430 + @Param[in] h_FmMuram - FM-MURAM module descriptor.
80431 + @Param[in] ptr - A pointer to an allocated memory.
80432 +
80433 + @Return E_OK on success; Error code otherwise.
80434 +*//***************************************************************************/
80435 +t_Error FM_MURAM_FreeMem(t_Handle h_FmMuram, void *ptr);
80436 +
80437 +/**************************************************************************//**
80438 + @Function FM_MURAM_GetFreeMemSize
80439 +
80440 + @Description Returns the size (in bytes) of free MURAM memory.
80441 +
80442 + @Param[in] h_FmMuram - FM-MURAM module descriptor.
80443 +
80444 + @Return Free MURAM memory size in bytes.
80445 +*//***************************************************************************/
80446 +uint64_t FM_MURAM_GetFreeMemSize(t_Handle h_FmMuram);
80447 +
80448 +/** @} */ /* end of FM_muram_ctrl_grp group */
80449 +/** @} */ /* end of FM_muram_grp group */
80450 +/** @} */ /* end of FM_grp group */
80451 +
80452 +
80453 +
80454 +#endif /* __FM_MURAM_EXT */
80455 --- /dev/null
80456 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/Peripherals/fm_pcd_ext.h
80457 @@ -0,0 +1,3974 @@
80458 +/* Copyright (c) 2008-2012 Freescale Semiconductor, Inc
80459 + * All rights reserved.
80460 + *
80461 + * Redistribution and use in source and binary forms, with or without
80462 + * modification, are permitted provided that the following conditions are met:
80463 + * * Redistributions of source code must retain the above copyright
80464 + * notice, this list of conditions and the following disclaimer.
80465 + * * Redistributions in binary form must reproduce the above copyright
80466 + * notice, this list of conditions and the following disclaimer in the
80467 + * documentation and/or other materials provided with the distribution.
80468 + * * Neither the name of Freescale Semiconductor nor the
80469 + * names of its contributors may be used to endorse or promote products
80470 + * derived from this software without specific prior written permission.
80471 + *
80472 + *
80473 + * ALTERNATIVELY, this software may be distributed under the terms of the
80474 + * GNU General Public License ("GPL") as published by the Free Software
80475 + * Foundation, either version 2 of that License or (at your option) any
80476 + * later version.
80477 + *
80478 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
80479 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
80480 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
80481 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
80482 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
80483 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
80484 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
80485 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
80486 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
80487 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
80488 + */
80489 +
80490 +
80491 +/**************************************************************************//**
80492 + @File fm_pcd_ext.h
80493 +
80494 + @Description FM PCD API definitions
80495 +*//***************************************************************************/
80496 +#ifndef __FM_PCD_EXT
80497 +#define __FM_PCD_EXT
80498 +
80499 +#include "std_ext.h"
80500 +#include "net_ext.h"
80501 +#include "list_ext.h"
80502 +#include "fm_ext.h"
80503 +#include "fsl_fman_kg.h"
80504 +
80505 +
80506 +/**************************************************************************//**
80507 + @Group FM_grp Frame Manager API
80508 +
80509 + @Description Frame Manager Application Programming Interface
80510 +
80511 + @{
80512 +*//***************************************************************************/
80513 +
80514 +/**************************************************************************//**
80515 + @Group FM_PCD_grp FM PCD
80516 +
80517 + @Description Frame Manager PCD (Parse-Classify-Distribute) API.
80518 +
80519 + The FM PCD module is responsible for the initialization of all
80520 + global classifying FM modules. This includes the parser general and
80521 + common registers, the key generator global and common registers,
80522 + and the policer global and common registers.
80523 + In addition, the FM PCD SW module will initialize all required
80524 + key generator schemes, coarse classification flows, and policer
80525 + profiles. When FM module is configured to work with one of these
80526 + entities, it will register to it using the FM PORT API. The PCD
80527 + module will manage the PCD resources - i.e. resource management of
80528 + KeyGen schemes, etc.
80529 +
80530 + @{
80531 +*//***************************************************************************/
80532 +
80533 +/**************************************************************************//**
80534 + @Collection General PCD defines
80535 +*//***************************************************************************/
80536 +#define FM_PCD_MAX_NUM_OF_PRIVATE_HDRS 2 /**< Number of units/headers saved for user */
80537 +
80538 +#define FM_PCD_PRS_NUM_OF_HDRS 16 /**< Number of headers supported by HW parser */
80539 +#define FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS (32 - FM_PCD_MAX_NUM_OF_PRIVATE_HDRS)
80540 + /**< Number of distinction units is limited by
80541 + register size (32 bits) minus reserved bits
80542 + for private headers. */
80543 +#define FM_PCD_MAX_NUM_OF_INTERCHANGEABLE_HDRS 4 /**< Maximum number of interchangeable headers
80544 + in a distinction unit */
80545 +#define FM_PCD_KG_NUM_OF_GENERIC_REGS FM_KG_NUM_OF_GENERIC_REGS /**< Total number of generic KeyGen registers */
80546 +#define FM_PCD_KG_MAX_NUM_OF_EXTRACTS_PER_KEY 35 /**< Max number allowed on any configuration;
80547 + For HW implementation reasons, in most
80548 + cases less than this will be allowed; The
80549 + driver will return an initialization error
80550 + if resource is unavailable. */
80551 +#define FM_PCD_KG_NUM_OF_EXTRACT_MASKS 4 /**< Total number of masks allowed on KeyGen extractions. */
80552 +#define FM_PCD_KG_NUM_OF_DEFAULT_GROUPS 16 /**< Number of default value logical groups */
80553 +
80554 +#define FM_PCD_PRS_NUM_OF_LABELS 32 /**< Maximum number of SW parser labels */
80555 +#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)
80556 + /**< Maximum size of SW parser code */
80557 +
80558 +#define FM_PCD_MAX_MANIP_INSRT_TEMPLATE_SIZE 128 /**< Maximum size of insertion template for
80559 + insert manipulation */
80560 +
80561 +#if (DPAA_VERSION >= 11)
80562 +#define FM_PCD_FRM_REPLIC_MAX_NUM_OF_ENTRIES 64 /**< Maximum possible entries for frame replicator group */
80563 +#endif /* (DPAA_VERSION >= 11) */
80564 +/* @} */
80565 +
80566 +
80567 +/**************************************************************************//**
80568 + @Group FM_PCD_init_grp FM PCD Initialization Unit
80569 +
80570 + @Description Frame Manager PCD Initialization Unit API
80571 +
80572 + @{
80573 +*//***************************************************************************/
80574 +
80575 +/**************************************************************************//**
80576 + @Description PCD counters
80577 +*//***************************************************************************/
80578 +typedef enum e_FmPcdCounters {
80579 + e_FM_PCD_KG_COUNTERS_TOTAL, /**< KeyGen counter */
80580 + e_FM_PCD_PLCR_COUNTERS_RED, /**< Policer counter - counts the total number of RED packets that exit the Policer. */
80581 + e_FM_PCD_PLCR_COUNTERS_YELLOW, /**< Policer counter - counts the total number of YELLOW packets that exit the Policer. */
80582 + e_FM_PCD_PLCR_COUNTERS_RECOLORED_TO_RED, /**< Policer counter - counts the number of packets that changed color to RED by the Policer;
80583 + This is a subset of e_FM_PCD_PLCR_COUNTERS_RED packet count, indicating active color changes. */
80584 + e_FM_PCD_PLCR_COUNTERS_RECOLORED_TO_YELLOW, /**< Policer counter - counts the number of packets that changed color to YELLOW by the Policer;
80585 + This is a subset of e_FM_PCD_PLCR_COUNTERS_YELLOW packet count, indicating active color changes. */
80586 + e_FM_PCD_PLCR_COUNTERS_TOTAL, /**< Policer counter - counts the total number of packets passed in the Policer. */
80587 + e_FM_PCD_PLCR_COUNTERS_LENGTH_MISMATCH, /**< Policer counter - counts the number of packets with length mismatch. */
80588 + e_FM_PCD_PRS_COUNTERS_PARSE_DISPATCH, /**< Parser counter - counts the number of times the parser block is dispatched. */
80589 + e_FM_PCD_PRS_COUNTERS_L2_PARSE_RESULT_RETURNED, /**< Parser counter - counts the number of times L2 parse result is returned (including errors). */
80590 + e_FM_PCD_PRS_COUNTERS_L3_PARSE_RESULT_RETURNED, /**< Parser counter - counts the number of times L3 parse result is returned (including errors). */
80591 + e_FM_PCD_PRS_COUNTERS_L4_PARSE_RESULT_RETURNED, /**< Parser counter - counts the number of times L4 parse result is returned (including errors). */
80592 + e_FM_PCD_PRS_COUNTERS_SHIM_PARSE_RESULT_RETURNED, /**< Parser counter - counts the number of times SHIM parse result is returned (including errors). */
80593 + 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. */
80594 + 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. */
80595 + 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. */
80596 + 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. */
80597 + e_FM_PCD_PRS_COUNTERS_SOFT_PRS_CYCLES, /**< Parser counter - counts the number of cycles spent executing soft parser instruction (including stall cycles). */
80598 + 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. */
80599 + 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). */
80600 + e_FM_PCD_PRS_COUNTERS_MURAM_READ_CYCLES, /**< MURAM counter - counts the number of cycles while performing FMan Memory read. */
80601 + e_FM_PCD_PRS_COUNTERS_MURAM_READ_STALL_CYCLES, /**< MURAM counter - counts the number of cycles stalled while performing FMan Memory read. */
80602 + e_FM_PCD_PRS_COUNTERS_MURAM_WRITE_CYCLES, /**< MURAM counter - counts the number of cycles while performing FMan Memory write. */
80603 + e_FM_PCD_PRS_COUNTERS_MURAM_WRITE_STALL_CYCLES, /**< MURAM counter - counts the number of cycles stalled while performing FMan Memory write. */
80604 + e_FM_PCD_PRS_COUNTERS_FPM_COMMAND_STALL_CYCLES /**< FPM counter - counts the number of cycles stalled while performing a FPM Command. */
80605 +} e_FmPcdCounters;
80606 +
80607 +/**************************************************************************//**
80608 + @Description PCD interrupts
80609 +*//***************************************************************************/
80610 +typedef enum e_FmPcdExceptions {
80611 + e_FM_PCD_KG_EXCEPTION_DOUBLE_ECC, /**< KeyGen double-bit ECC error is detected on internal memory read access. */
80612 + e_FM_PCD_KG_EXCEPTION_KEYSIZE_OVERFLOW, /**< KeyGen scheme configuration error indicating a key size larger than 56 bytes. */
80613 + e_FM_PCD_PLCR_EXCEPTION_DOUBLE_ECC, /**< Policer double-bit ECC error has been detected on PRAM read access. */
80614 + e_FM_PCD_PLCR_EXCEPTION_INIT_ENTRY_ERROR, /**< Policer access to a non-initialized profile has been detected. */
80615 + e_FM_PCD_PLCR_EXCEPTION_PRAM_SELF_INIT_COMPLETE, /**< Policer RAM self-initialization complete */
80616 + e_FM_PCD_PLCR_EXCEPTION_ATOMIC_ACTION_COMPLETE, /**< Policer atomic action complete */
80617 + e_FM_PCD_PRS_EXCEPTION_DOUBLE_ECC, /**< Parser double-bit ECC error */
80618 + e_FM_PCD_PRS_EXCEPTION_SINGLE_ECC /**< Parser single-bit ECC error */
80619 +} e_FmPcdExceptions;
80620 +
80621 +
80622 +/**************************************************************************//**
80623 + @Description Exceptions user callback routine, will be called upon an
80624 + exception passing the exception identification.
80625 +
80626 + @Param[in] h_App - User's application descriptor.
80627 + @Param[in] exception - The exception.
80628 + *//***************************************************************************/
80629 +typedef void (t_FmPcdExceptionCallback) (t_Handle h_App, e_FmPcdExceptions exception);
80630 +
80631 +/**************************************************************************//**
80632 + @Description Exceptions user callback routine, will be called upon an exception
80633 + passing the exception identification.
80634 +
80635 + @Param[in] h_App - User's application descriptor.
80636 + @Param[in] exception - The exception.
80637 + @Param[in] index - id of the relevant source (may be scheme or profile id).
80638 + *//***************************************************************************/
80639 +typedef void (t_FmPcdIdExceptionCallback) ( t_Handle h_App,
80640 + e_FmPcdExceptions exception,
80641 + uint16_t index);
80642 +
80643 +/**************************************************************************//**
80644 + @Description A callback for enqueuing frame onto a QM queue.
80645 +
80646 + @Param[in] h_QmArg - Application's handle passed to QM module on enqueue.
80647 + @Param[in] p_Fd - Frame descriptor for the frame.
80648 +
80649 + @Return E_OK on success; Error code otherwise.
80650 + *//***************************************************************************/
80651 +typedef t_Error (t_FmPcdQmEnqueueCallback) (t_Handle h_QmArg, void *p_Fd);
80652 +
80653 +/**************************************************************************//**
80654 + @Description Host-Command parameters structure.
80655 +
80656 + When using Host command for PCD functionalities, a dedicated port
80657 + must be used. If this routine is called for a PCD in a single partition
80658 + environment, or it is the Master partition in a Multi-partition
80659 + environment, The port will be initialized by the PCD driver
80660 + initialization routine.
80661 + *//***************************************************************************/
80662 +typedef struct t_FmPcdHcParams {
80663 + uintptr_t portBaseAddr; /**< Virtual Address of Host-Command Port memory mapped registers.*/
80664 + uint8_t portId; /**< Port Id (0-6 relative to Host-Command/Offline-Parsing ports);
80665 + NOTE: When configuring Host Command port for
80666 + FMANv3 devices (DPAA_VERSION 11 and higher),
80667 + portId=0 MUST be used. */
80668 + uint16_t liodnBase; /**< LIODN base for this port, to be used together with LIODN offset
80669 + (irrelevant for P4080 revision 1.0) */
80670 + uint32_t errFqid; /**< Host-Command Port error queue Id. */
80671 + uint32_t confFqid; /**< Host-Command Port confirmation queue Id. */
80672 + uint32_t qmChannel; /**< QM channel dedicated to this Host-Command port;
80673 + will be used by the FM for dequeue. */
80674 + t_FmPcdQmEnqueueCallback *f_QmEnqueue; /**< Callback routine for enqueuing a frame to the QM */
80675 + t_Handle h_QmArg; /**< Application's handle passed to QM module on enqueue */
80676 +} t_FmPcdHcParams;
80677 +
80678 +/**************************************************************************//**
80679 + @Description The main structure for PCD initialization
80680 + *//***************************************************************************/
80681 +typedef struct t_FmPcdParams {
80682 + bool prsSupport; /**< TRUE if Parser will be used for any of the FM ports. */
80683 + bool ccSupport; /**< TRUE if Coarse Classification will be used for any
80684 + of the FM ports. */
80685 + bool kgSupport; /**< TRUE if KeyGen will be used for any of the FM ports. */
80686 + bool plcrSupport; /**< TRUE if Policer will be used for any of the FM ports. */
80687 + t_Handle h_Fm; /**< A handle to the FM module. */
80688 + uint8_t numOfSchemes; /**< Number of schemes dedicated to this partition.
80689 + this parameter is relevant if 'kgSupport'=TRUE. */
80690 + bool useHostCommand; /**< Optional for single partition, Mandatory for Multi partition */
80691 + t_FmPcdHcParams hc; /**< Host Command parameters, relevant only if 'useHostCommand'=TRUE;
80692 + Relevant when FM not runs in "guest-mode". */
80693 +
80694 + t_FmPcdExceptionCallback *f_Exception; /**< Callback routine for general PCD exceptions;
80695 + Relevant when FM not runs in "guest-mode". */
80696 + t_FmPcdIdExceptionCallback *f_ExceptionId; /**< Callback routine for specific KeyGen scheme or
80697 + Policer profile exceptions;
80698 + Relevant when FM not runs in "guest-mode". */
80699 + t_Handle h_App; /**< A handle to an application layer object; This handle will
80700 + be passed by the driver upon calling the above callbacks;
80701 + Relevant when FM not runs in "guest-mode". */
80702 + uint8_t partPlcrProfilesBase; /**< The first policer-profile-id dedicated to this partition.
80703 + this parameter is relevant if 'plcrSupport'=TRUE.
80704 + NOTE: this parameter relevant only when working with multiple partitions. */
80705 + uint16_t partNumOfPlcrProfiles; /**< Number of policer-profiles dedicated to this partition.
80706 + this parameter is relevant if 'plcrSupport'=TRUE.
80707 + NOTE: this parameter relevant only when working with multiple partitions. */
80708 +} t_FmPcdParams;
80709 +
80710 +
80711 +/**************************************************************************//**
80712 + @Function FM_PCD_Config
80713 +
80714 + @Description Basic configuration of the PCD module.
80715 + Creates descriptor for the FM PCD module.
80716 +
80717 + @Param[in] p_FmPcdParams A structure of parameters for the initialization of PCD.
80718 +
80719 + @Return A handle to the initialized module.
80720 +*//***************************************************************************/
80721 +t_Handle FM_PCD_Config(t_FmPcdParams *p_FmPcdParams);
80722 +
80723 +/**************************************************************************//**
80724 + @Function FM_PCD_Init
80725 +
80726 + @Description Initialization of the PCD module.
80727 +
80728 + @Param[in] h_FmPcd - FM PCD module descriptor.
80729 +
80730 + @Return E_OK on success; Error code otherwise.
80731 +*//***************************************************************************/
80732 +t_Error FM_PCD_Init(t_Handle h_FmPcd);
80733 +
80734 +/**************************************************************************//**
80735 + @Function FM_PCD_Free
80736 +
80737 + @Description Frees all resources that were assigned to FM module.
80738 +
80739 + Calling this routine invalidates the descriptor.
80740 +
80741 + @Param[in] h_FmPcd - FM PCD module descriptor.
80742 +
80743 + @Return E_OK on success; Error code otherwise.
80744 +*//***************************************************************************/
80745 +t_Error FM_PCD_Free(t_Handle h_FmPcd);
80746 +
80747 +/**************************************************************************//**
80748 + @Group FM_PCD_advanced_cfg_grp FM PCD Advanced Configuration Unit
80749 +
80750 + @Description Frame Manager PCD Advanced Configuration API.
80751 +
80752 + @{
80753 +*//***************************************************************************/
80754 +
80755 +/**************************************************************************//**
80756 + @Function FM_PCD_ConfigException
80757 +
80758 + @Description Calling this routine changes the internal driver data base
80759 + from its default selection of exceptions enabling.
80760 + [DEFAULT_numOfSharedPlcrProfiles].
80761 +
80762 + @Param[in] h_FmPcd FM PCD module descriptor.
80763 + @Param[in] exception The exception to be selected.
80764 + @Param[in] enable TRUE to enable interrupt, FALSE to mask it.
80765 +
80766 + @Return E_OK on success; Error code otherwise.
80767 +
80768 + @Cautions This routine should NOT be called from guest-partition
80769 + (i.e. guestId != NCSW_MASTER_ID)
80770 +*//***************************************************************************/
80771 +t_Error FM_PCD_ConfigException(t_Handle h_FmPcd, e_FmPcdExceptions exception, bool enable);
80772 +
80773 +/**************************************************************************//**
80774 + @Function FM_PCD_ConfigHcFramesDataMemory
80775 +
80776 + @Description Configures memory-partition-id for FMan-Controller Host-Command
80777 + frames. Calling this routine changes the internal driver data
80778 + base from its default configuration [0].
80779 +
80780 + @Param[in] h_FmPcd FM PCD module descriptor.
80781 + @Param[in] memId Memory partition ID.
80782 +
80783 + @Return E_OK on success; Error code otherwise.
80784 +
80785 + @Cautions This routine may be called only if 'useHostCommand' was TRUE
80786 + when FM_PCD_Config() routine was called.
80787 +*//***************************************************************************/
80788 +t_Error FM_PCD_ConfigHcFramesDataMemory(t_Handle h_FmPcd, uint8_t memId);
80789 +
80790 +/**************************************************************************//**
80791 + @Function FM_PCD_ConfigPlcrNumOfSharedProfiles
80792 +
80793 + @Description Calling this routine changes the internal driver data base
80794 + from its default selection of exceptions enablement.
80795 + [DEFAULT_numOfSharedPlcrProfiles].
80796 +
80797 + @Param[in] h_FmPcd FM PCD module descriptor.
80798 + @Param[in] numOfSharedPlcrProfiles Number of profiles to
80799 + be shared between ports on this partition
80800 +
80801 + @Return E_OK on success; Error code otherwise.
80802 +*//***************************************************************************/
80803 +t_Error FM_PCD_ConfigPlcrNumOfSharedProfiles(t_Handle h_FmPcd, uint16_t numOfSharedPlcrProfiles);
80804 +
80805 +/**************************************************************************//**
80806 + @Function FM_PCD_ConfigPlcrAutoRefreshMode
80807 +
80808 + @Description Calling this routine changes the internal driver data base
80809 + from its default selection of exceptions enablement.
80810 + By default auto-refresh is [DEFAULT_plcrAutoRefresh].
80811 +
80812 + @Param[in] h_FmPcd FM PCD module descriptor.
80813 + @Param[in] enable TRUE to enable, FALSE to disable
80814 +
80815 + @Return E_OK on success; Error code otherwise.
80816 +
80817 + @Cautions This routine should NOT be called from guest-partition
80818 + (i.e. guestId != NCSW_MASTER_ID)
80819 +*//***************************************************************************/
80820 +t_Error FM_PCD_ConfigPlcrAutoRefreshMode(t_Handle h_FmPcd, bool enable);
80821 +
80822 +/**************************************************************************//**
80823 + @Function FM_PCD_ConfigPrsMaxCycleLimit
80824 +
80825 + @Description Calling this routine changes the internal data structure for
80826 + the maximum parsing time from its default value
80827 + [DEFAULT_MAX_PRS_CYC_LIM].
80828 +
80829 + @Param[in] h_FmPcd FM PCD module descriptor.
80830 + @Param[in] value 0 to disable the mechanism, or new
80831 + maximum parsing time.
80832 +
80833 + @Return E_OK on success; Error code otherwise.
80834 +
80835 + @Cautions This routine should NOT be called from guest-partition
80836 + (i.e. guestId != NCSW_MASTER_ID)
80837 +*//***************************************************************************/
80838 +t_Error FM_PCD_ConfigPrsMaxCycleLimit(t_Handle h_FmPcd,uint16_t value);
80839 +
80840 +/** @} */ /* end of FM_PCD_advanced_cfg_grp group */
80841 +/** @} */ /* end of FM_PCD_init_grp group */
80842 +
80843 +
80844 +/**************************************************************************//**
80845 + @Group FM_PCD_Runtime_grp FM PCD Runtime Unit
80846 +
80847 + @Description Frame Manager PCD Runtime Unit API
80848 +
80849 + The runtime control allows creation of PCD infrastructure modules
80850 + such as Network Environment Characteristics, Classification Plan
80851 + Groups and Coarse Classification Trees.
80852 + It also allows on-the-fly initialization, modification and removal
80853 + of PCD modules such as KeyGen schemes, coarse classification nodes
80854 + and Policer profiles.
80855 +
80856 + In order to explain the programming model of the PCD driver interface
80857 + a few terms should be explained, and will be used below.
80858 + - Distinction Header - One of the 16 protocols supported by the FM parser,
80859 + or one of the SHIM headers (1 or 2). May be a header with a special
80860 + option (see below).
80861 + - Interchangeable Headers Group - This is a group of Headers recognized
80862 + by either one of them. For example, if in a specific context the user
80863 + chooses to treat IPv4 and IPV6 in the same way, they may create an
80864 + interchangeable Headers Unit consisting of these 2 headers.
80865 + - A Distinction Unit - a Distinction Header or an Interchangeable Headers
80866 + Group.
80867 + - Header with special option - applies to Ethernet, MPLS, VLAN, IPv4 and
80868 + IPv6, includes multicast, broadcast and other protocol specific options.
80869 + In terms of hardware it relates to the options available in the classification
80870 + plan.
80871 + - Network Environment Characteristics - a set of Distinction Units that define
80872 + the total recognizable header selection for a certain environment. This is
80873 + NOT the list of all headers that will ever appear in a flow, but rather
80874 + everything that needs distinction in a flow, where distinction is made by KeyGen
80875 + schemes and coarse classification action descriptors.
80876 +
80877 + The PCD runtime modules initialization is done in stages. The first stage after
80878 + initializing the PCD module itself is to establish a Network Flows Environment
80879 + Definition. The application may choose to establish one or more such environments.
80880 + Later, when needed, the application will have to state, for some of its modules,
80881 + to which single environment it belongs.
80882 +
80883 + @{
80884 +*//***************************************************************************/
80885 +
80886 +/**************************************************************************//**
80887 + @Description A structure for SW parser labels
80888 + *//***************************************************************************/
80889 +typedef struct t_FmPcdPrsLabelParams {
80890 + uint32_t instructionOffset; /**< SW parser label instruction offset (2 bytes
80891 + resolution), relative to Parser RAM. */
80892 + e_NetHeaderType hdr; /**< The existence of this header will invoke
80893 + the SW parser code; Use HEADER_TYPE_NONE
80894 + to indicate that sw parser is to run
80895 + independent of the existence of any protocol
80896 + (run before HW parser). */
80897 + uint8_t indexPerHdr; /**< Normally 0, if more than one SW parser
80898 + attachments for the same header, use this
80899 + index to distinguish between them. */
80900 +} t_FmPcdPrsLabelParams;
80901 +
80902 +/**************************************************************************//**
80903 + @Description A structure for SW parser
80904 + *//***************************************************************************/
80905 +typedef struct t_FmPcdPrsSwParams {
80906 + bool override; /**< FALSE to invoke a check that nothing else
80907 + was loaded to this address, including
80908 + internal patches.
80909 + TRUE to override any existing code.*/
80910 + uint32_t size; /**< SW parser code size */
80911 + uint16_t base; /**< SW parser base (in instruction counts!
80912 + must be larger than 0x20)*/
80913 + uint8_t *p_Code; /**< SW parser code */
80914 + uint32_t swPrsDataParams[FM_PCD_PRS_NUM_OF_HDRS];
80915 + /**< SW parser data (parameters) */
80916 + uint8_t numOfLabels; /**< Number of labels for SW parser. */
80917 + t_FmPcdPrsLabelParams labelsTable[FM_PCD_PRS_NUM_OF_LABELS];
80918 + /**< SW parser labels table, containing
80919 + numOfLabels entries */
80920 +} t_FmPcdPrsSwParams;
80921 +
80922 +
80923 +/**************************************************************************//**
80924 + @Function FM_PCD_Enable
80925 +
80926 + @Description This routine should be called after PCD is initialized for enabling all
80927 + PCD engines according to their existing configuration.
80928 +
80929 + @Param[in] h_FmPcd FM PCD module descriptor.
80930 +
80931 + @Return E_OK on success; Error code otherwise.
80932 +
80933 + @Cautions Allowed only following FM_PCD_Init() and when PCD is disabled.
80934 +*//***************************************************************************/
80935 +t_Error FM_PCD_Enable(t_Handle h_FmPcd);
80936 +
80937 +/**************************************************************************//**
80938 + @Function FM_PCD_Disable
80939 +
80940 + @Description This routine may be called when PCD is enabled in order to
80941 + disable all PCD engines. It may be called
80942 + only when none of the ports in the system are using the PCD.
80943 +
80944 + @Param[in] h_FmPcd FM PCD module descriptor.
80945 +
80946 + @Return E_OK on success; Error code otherwise.
80947 +
80948 + @Cautions Allowed only following FM_PCD_Init() and when PCD is enabled.
80949 +*//***************************************************************************/
80950 +t_Error FM_PCD_Disable(t_Handle h_FmPcd);
80951 +
80952 +/**************************************************************************//**
80953 + @Function FM_PCD_GetCounter
80954 +
80955 + @Description Reads one of the FM PCD counters.
80956 +
80957 + @Param[in] h_FmPcd FM PCD module descriptor.
80958 + @Param[in] counter The requested counter.
80959 +
80960 + @Return Counter's current value.
80961 +
80962 + @Cautions Allowed only following FM_PCD_Init().
80963 + Note that it is user's responsibility to call this routine only
80964 + for enabled counters, and there will be no indication if a
80965 + disabled counter is accessed.
80966 +*//***************************************************************************/
80967 +uint32_t FM_PCD_GetCounter(t_Handle h_FmPcd, e_FmPcdCounters counter);
80968 +
80969 +/**************************************************************************//**
80970 +@Function FM_PCD_PrsLoadSw
80971 +
80972 +@Description This routine may be called in order to load software parsing code.
80973 +
80974 +
80975 +@Param[in] h_FmPcd FM PCD module descriptor.
80976 +@Param[in] p_SwPrs A pointer to a structure of software
80977 + parser parameters, including the software
80978 + parser image.
80979 +
80980 +@Return E_OK on success; Error code otherwise.
80981 +
80982 +@Cautions Allowed only following FM_PCD_Init() and when PCD is disabled.
80983 + This routine should NOT be called from guest-partition
80984 + (i.e. guestId != NCSW_MASTER_ID)
80985 +*//***************************************************************************/
80986 +t_Error FM_PCD_PrsLoadSw(t_Handle h_FmPcd, t_FmPcdPrsSwParams *p_SwPrs);
80987 +
80988 +/**************************************************************************//**
80989 +@Function FM_PCD_SetAdvancedOffloadSupport
80990 +
80991 +@Description This routine must be called in order to support the following features:
80992 + IP-fragmentation, IP-reassembly, IPsec, Header-manipulation, frame-replicator.
80993 +
80994 +@Param[in] h_FmPcd FM PCD module descriptor.
80995 +
80996 +@Return E_OK on success; Error code otherwise.
80997 +
80998 +@Cautions Allowed only following FM_PCD_Init() and when PCD is disabled.
80999 + This routine should NOT be called from guest-partition
81000 + (i.e. guestId != NCSW_MASTER_ID)
81001 +*//***************************************************************************/
81002 +t_Error FM_PCD_SetAdvancedOffloadSupport(t_Handle h_FmPcd);
81003 +
81004 +/**************************************************************************//**
81005 + @Function FM_PCD_KgSetDfltValue
81006 +
81007 + @Description Calling this routine sets a global default value to be used
81008 + by the KeyGen when parser does not recognize a required
81009 + field/header.
81010 + By default default values are 0.
81011 +
81012 + @Param[in] h_FmPcd FM PCD module descriptor.
81013 + @Param[in] valueId 0,1 - one of 2 global default values.
81014 + @Param[in] value The requested default value.
81015 +
81016 + @Return E_OK on success; Error code otherwise.
81017 +
81018 + @Cautions Allowed only following FM_PCD_Init() and when PCD is disabled.
81019 + This routine should NOT be called from guest-partition
81020 + (i.e. guestId != NCSW_MASTER_ID)
81021 +*//***************************************************************************/
81022 +t_Error FM_PCD_KgSetDfltValue(t_Handle h_FmPcd, uint8_t valueId, uint32_t value);
81023 +
81024 +/**************************************************************************//**
81025 + @Function FM_PCD_KgSetAdditionalDataAfterParsing
81026 +
81027 + @Description Calling this routine allows the KeyGen to access data past
81028 + the parser finishing point.
81029 +
81030 + @Param[in] h_FmPcd FM PCD module descriptor.
81031 + @Param[in] payloadOffset the number of bytes beyond the parser location.
81032 +
81033 + @Return E_OK on success; Error code otherwise.
81034 +
81035 + @Cautions Allowed only following FM_PCD_Init() and when PCD is disabled.
81036 + This routine should NOT be called from guest-partition
81037 + (i.e. guestId != NCSW_MASTER_ID)
81038 +*//***************************************************************************/
81039 +t_Error FM_PCD_KgSetAdditionalDataAfterParsing(t_Handle h_FmPcd, uint8_t payloadOffset);
81040 +
81041 +/**************************************************************************//**
81042 + @Function FM_PCD_SetException
81043 +
81044 + @Description Calling this routine enables/disables PCD interrupts.
81045 +
81046 + @Param[in] h_FmPcd FM PCD module descriptor.
81047 + @Param[in] exception The exception to be selected.
81048 + @Param[in] enable TRUE to enable interrupt, FALSE to mask it.
81049 +
81050 + @Return E_OK on success; Error code otherwise.
81051 +
81052 + @Cautions Allowed only following FM_PCD_Init().
81053 + This routine should NOT be called from guest-partition
81054 + (i.e. guestId != NCSW_MASTER_ID)
81055 +*//***************************************************************************/
81056 +t_Error FM_PCD_SetException(t_Handle h_FmPcd, e_FmPcdExceptions exception, bool enable);
81057 +
81058 +/**************************************************************************//**
81059 + @Function FM_PCD_ModifyCounter
81060 +
81061 + @Description Sets a value to an enabled counter. Use "0" to reset the counter.
81062 +
81063 + @Param[in] h_FmPcd FM PCD module descriptor.
81064 + @Param[in] counter The requested counter.
81065 + @Param[in] value The requested value to be written into the counter.
81066 +
81067 + @Return E_OK on success; Error code otherwise.
81068 +
81069 + @Cautions Allowed only following FM_PCD_Init().
81070 + This routine should NOT be called from guest-partition
81071 + (i.e. guestId != NCSW_MASTER_ID)
81072 +*//***************************************************************************/
81073 +t_Error FM_PCD_ModifyCounter(t_Handle h_FmPcd, e_FmPcdCounters counter, uint32_t value);
81074 +
81075 +/**************************************************************************//**
81076 + @Function FM_PCD_SetPlcrStatistics
81077 +
81078 + @Description This routine may be used to enable/disable policer statistics
81079 + counter. By default the statistics is enabled.
81080 +
81081 + @Param[in] h_FmPcd FM PCD module descriptor
81082 + @Param[in] enable TRUE to enable, FALSE to disable.
81083 +
81084 + @Return E_OK on success; Error code otherwise.
81085 +
81086 + @Cautions Allowed only following FM_PCD_Init().
81087 + This routine should NOT be called from guest-partition
81088 + (i.e. guestId != NCSW_MASTER_ID)
81089 +*//***************************************************************************/
81090 +t_Error FM_PCD_SetPlcrStatistics(t_Handle h_FmPcd, bool enable);
81091 +
81092 +/**************************************************************************//**
81093 + @Function FM_PCD_SetPrsStatistics
81094 +
81095 + @Description Defines whether to gather parser statistics including all ports.
81096 +
81097 + @Param[in] h_FmPcd FM PCD module descriptor.
81098 + @Param[in] enable TRUE to enable, FALSE to disable.
81099 +
81100 + @Return None
81101 +
81102 + @Cautions Allowed only following FM_PCD_Init().
81103 + This routine should NOT be called from guest-partition
81104 + (i.e. guestId != NCSW_MASTER_ID)
81105 +*//***************************************************************************/
81106 +void FM_PCD_SetPrsStatistics(t_Handle h_FmPcd, bool enable);
81107 +
81108 +/**************************************************************************//**
81109 + @Function FM_PCD_HcTxConf
81110 +
81111 + @Description This routine should be called to confirm frames that were
81112 + received on the HC confirmation queue.
81113 +
81114 + @Param[in] h_FmPcd A handle to an FM PCD Module.
81115 + @Param[in] p_Fd Frame descriptor of the received frame.
81116 +
81117 + @Cautions Allowed only following FM_PCD_Init(). Allowed only if 'useHostCommand'
81118 + option was selected in the initialization.
81119 +*//***************************************************************************/
81120 +void FM_PCD_HcTxConf(t_Handle h_FmPcd, t_DpaaFD *p_Fd);
81121 +
81122 +/**************************************************************************//*
81123 + @Function FM_PCD_ForceIntr
81124 +
81125 + @Description Causes an interrupt event on the requested source.
81126 +
81127 + @Param[in] h_FmPcd FM PCD module descriptor.
81128 + @Param[in] exception An exception to be forced.
81129 +
81130 + @Return E_OK on success; Error code if the exception is not enabled,
81131 + or is not able to create interrupt.
81132 +
81133 + @Cautions Allowed only following FM_PCD_Init().
81134 + This routine should NOT be called from guest-partition
81135 + (i.e. guestId != NCSW_MASTER_ID)
81136 +*//***************************************************************************/
81137 +t_Error FM_PCD_ForceIntr (t_Handle h_FmPcd, e_FmPcdExceptions exception);
81138 +
81139 +#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
81140 +/**************************************************************************//**
81141 + @Function FM_PCD_DumpRegs
81142 +
81143 + @Description Dumps all PCD registers
81144 +
81145 + @Param[in] h_FmPcd A handle to an FM PCD Module.
81146 +
81147 + @Return E_OK on success; Error code otherwise.
81148 +
81149 + @Cautions Allowed only following FM_PCD_Init().
81150 + NOTE: this routine may be called only for FM in master mode
81151 + (i.e. 'guestId'=NCSW_MASTER_ID) or in a case that the registers
81152 + are mapped.
81153 +*//***************************************************************************/
81154 +t_Error FM_PCD_DumpRegs(t_Handle h_FmPcd);
81155 +
81156 +/**************************************************************************//**
81157 + @Function FM_PCD_KgDumpRegs
81158 +
81159 + @Description Dumps all PCD KG registers
81160 +
81161 + @Param[in] h_FmPcd A handle to an FM PCD Module.
81162 +
81163 + @Return E_OK on success; Error code otherwise.
81164 +
81165 + @Cautions Allowed only following FM_PCD_Init().
81166 + NOTE: this routine may be called only for FM in master mode
81167 + (i.e. 'guestId'=NCSW_MASTER_ID) or in a case that the registers
81168 + are mapped.
81169 +*//***************************************************************************/
81170 +t_Error FM_PCD_KgDumpRegs(t_Handle h_FmPcd);
81171 +
81172 +/**************************************************************************//**
81173 + @Function FM_PCD_PlcrDumpRegs
81174 +
81175 + @Description Dumps all PCD Policer registers
81176 +
81177 + @Param[in] h_FmPcd A handle to an FM PCD Module.
81178 +
81179 + @Return E_OK on success; Error code otherwise.
81180 +
81181 + @Cautions Allowed only following FM_PCD_Init().
81182 + NOTE: this routine may be called only for FM in master mode
81183 + (i.e. 'guestId'=NCSW_MASTER_ID) or in a case that the registers
81184 + are mapped.
81185 +*//***************************************************************************/
81186 +t_Error FM_PCD_PlcrDumpRegs(t_Handle h_FmPcd);
81187 +
81188 +/**************************************************************************//**
81189 + @Function FM_PCD_PlcrProfileDumpRegs
81190 +
81191 + @Description Dumps all PCD Policer profile registers
81192 +
81193 + @Param[in] h_Profile A handle to a Policer profile.
81194 +
81195 + @Return E_OK on success; Error code otherwise.
81196 +
81197 + @Cautions Allowed only following FM_PCD_Init().
81198 + NOTE: this routine may be called only for FM in master mode
81199 + (i.e. 'guestId'=NCSW_MASTER_ID) or in a case that the registers
81200 + are mapped.
81201 +*//***************************************************************************/
81202 +t_Error FM_PCD_PlcrProfileDumpRegs(t_Handle h_Profile);
81203 +
81204 +/**************************************************************************//**
81205 + @Function FM_PCD_PrsDumpRegs
81206 +
81207 + @Description Dumps all PCD Parser registers
81208 +
81209 + @Param[in] h_FmPcd A handle to an FM PCD Module.
81210 +
81211 + @Return E_OK on success; Error code otherwise.
81212 +
81213 + @Cautions Allowed only following FM_PCD_Init().
81214 + NOTE: this routine may be called only for FM in master mode
81215 + (i.e. 'guestId'=NCSW_MASTER_ID) or in a case that the registers
81216 + are mapped.
81217 +*//***************************************************************************/
81218 +t_Error FM_PCD_PrsDumpRegs(t_Handle h_FmPcd);
81219 +
81220 +/**************************************************************************//**
81221 + @Function FM_PCD_HcDumpRegs
81222 +
81223 + @Description Dumps HC Port registers
81224 +
81225 + @Param[in] h_FmPcd A handle to an FM PCD Module.
81226 +
81227 + @Return E_OK on success; Error code otherwise.
81228 +
81229 + @Cautions Allowed only following FM_PCD_Init().
81230 + NOTE: this routine may be called only for FM in master mode
81231 + (i.e. 'guestId'=NCSW_MASTER_ID).
81232 +*//***************************************************************************/
81233 +t_Error FM_PCD_HcDumpRegs(t_Handle h_FmPcd);
81234 +#endif /* (defined(DEBUG_ERRORS) && ... */
81235 +
81236 +
81237 +
81238 +/**************************************************************************//**
81239 + KeyGen FM_PCD_Runtime_build_grp FM PCD Runtime Building Unit
81240 +
81241 + @Description Frame Manager PCD Runtime Building API
81242 +
81243 + This group contains routines for setting, deleting and modifying
81244 + PCD resources, for defining the total PCD tree.
81245 + @{
81246 +*//***************************************************************************/
81247 +
81248 +/**************************************************************************//**
81249 + @Collection Definitions of coarse classification
81250 + parameters as required by KeyGen (when coarse classification
81251 + is the next engine after this scheme).
81252 +*//***************************************************************************/
81253 +#define FM_PCD_MAX_NUM_OF_CC_TREES 8
81254 +#define FM_PCD_MAX_NUM_OF_CC_GROUPS 16
81255 +#define FM_PCD_MAX_NUM_OF_CC_UNITS 4
81256 +#define FM_PCD_MAX_NUM_OF_KEYS 256
81257 +#define FM_PCD_MAX_NUM_OF_FLOWS (4*KILOBYTE)
81258 +#define FM_PCD_MAX_SIZE_OF_KEY 56
81259 +#define FM_PCD_MAX_NUM_OF_CC_ENTRIES_IN_GRP 16
81260 +#define FM_PCD_LAST_KEY_INDEX 0xffff
81261 +
81262 +#define FM_PCD_MAX_NUM_OF_CC_NODES 255 /* Obsolete, not used - will be removed in the future */
81263 +/* @} */
81264 +
81265 +/**************************************************************************//**
81266 + @Collection A set of definitions to allow protocol
81267 + special option description.
81268 +*//***************************************************************************/
81269 +typedef uint32_t protocolOpt_t; /**< A general type to define a protocol option. */
81270 +
81271 +typedef protocolOpt_t ethProtocolOpt_t; /**< Ethernet protocol options. */
81272 +#define ETH_BROADCAST 0x80000000 /**< Ethernet Broadcast. */
81273 +#define ETH_MULTICAST 0x40000000 /**< Ethernet Multicast. */
81274 +
81275 +typedef protocolOpt_t vlanProtocolOpt_t; /**< VLAN protocol options. */
81276 +#define VLAN_STACKED 0x20000000 /**< Stacked VLAN. */
81277 +
81278 +typedef protocolOpt_t mplsProtocolOpt_t; /**< MPLS protocol options. */
81279 +#define MPLS_STACKED 0x10000000 /**< Stacked MPLS. */
81280 +
81281 +typedef protocolOpt_t ipv4ProtocolOpt_t; /**< IPv4 protocol options. */
81282 +#define IPV4_BROADCAST_1 0x08000000 /**< IPv4 Broadcast. */
81283 +#define IPV4_MULTICAST_1 0x04000000 /**< IPv4 Multicast. */
81284 +#define IPV4_UNICAST_2 0x02000000 /**< Tunneled IPv4 - Unicast. */
81285 +#define IPV4_MULTICAST_BROADCAST_2 0x01000000 /**< Tunneled IPv4 - Broadcast/Multicast. */
81286 +
81287 +#define IPV4_FRAG_1 0x00000008 /**< IPV4 reassembly option.
81288 + IPV4 Reassembly manipulation requires network
81289 + environment with IPV4 header and IPV4_FRAG_1 option */
81290 +
81291 +typedef protocolOpt_t ipv6ProtocolOpt_t; /**< IPv6 protocol options. */
81292 +#define IPV6_MULTICAST_1 0x00800000 /**< IPv6 Multicast. */
81293 +#define IPV6_UNICAST_2 0x00400000 /**< Tunneled IPv6 - Unicast. */
81294 +#define IPV6_MULTICAST_2 0x00200000 /**< Tunneled IPv6 - Multicast. */
81295 +
81296 +#define IPV6_FRAG_1 0x00000004 /**< IPV6 reassembly option.
81297 + IPV6 Reassembly manipulation requires network
81298 + environment with IPV6 header and IPV6_FRAG_1 option;
81299 + in case where fragment found, the fragment-extension offset
81300 + may be found at 'shim2' (in parser-result). */
81301 +#if (DPAA_VERSION >= 11)
81302 +typedef protocolOpt_t capwapProtocolOpt_t; /**< CAPWAP protocol options. */
81303 +#define CAPWAP_FRAG_1 0x00000008 /**< CAPWAP reassembly option.
81304 + CAPWAP Reassembly manipulation requires network
81305 + environment with CAPWAP header and CAPWAP_FRAG_1 option;
81306 + in case where fragment found, the fragment-extension offset
81307 + may be found at 'shim2' (in parser-result). */
81308 +#endif /* (DPAA_VERSION >= 11) */
81309 +
81310 +
81311 +/* @} */
81312 +
81313 +#define FM_PCD_MANIP_MAX_HDR_SIZE 256
81314 +#define FM_PCD_MANIP_DSCP_TO_VLAN_TRANS 64
81315 +
81316 +/**************************************************************************//**
81317 + @Collection A set of definitions to support Header Manipulation selection.
81318 +*//***************************************************************************/
81319 +typedef uint32_t hdrManipFlags_t; /**< A general type to define a HMan update command flags. */
81320 +
81321 +typedef hdrManipFlags_t ipv4HdrManipUpdateFlags_t; /**< IPv4 protocol HMan update command flags. */
81322 +
81323 +#define HDR_MANIP_IPV4_TOS 0x80000000 /**< update TOS with the given value ('tos' field
81324 + of t_FmPcdManipHdrFieldUpdateIpv4) */
81325 +#define HDR_MANIP_IPV4_ID 0x40000000 /**< update IP ID with the given value ('id' field
81326 + of t_FmPcdManipHdrFieldUpdateIpv4) */
81327 +#define HDR_MANIP_IPV4_TTL 0x20000000 /**< Decrement TTL by 1 */
81328 +#define HDR_MANIP_IPV4_SRC 0x10000000 /**< update IP source address with the given value
81329 + ('src' field of t_FmPcdManipHdrFieldUpdateIpv4) */
81330 +#define HDR_MANIP_IPV4_DST 0x08000000 /**< update IP destination address with the given value
81331 + ('dst' field of t_FmPcdManipHdrFieldUpdateIpv4) */
81332 +
81333 +typedef hdrManipFlags_t ipv6HdrManipUpdateFlags_t; /**< IPv6 protocol HMan update command flags. */
81334 +
81335 +#define HDR_MANIP_IPV6_TC 0x80000000 /**< update Traffic Class address with the given value
81336 + ('trafficClass' field of t_FmPcdManipHdrFieldUpdateIpv6) */
81337 +#define HDR_MANIP_IPV6_HL 0x40000000 /**< Decrement Hop Limit by 1 */
81338 +#define HDR_MANIP_IPV6_SRC 0x20000000 /**< update IP source address with the given value
81339 + ('src' field of t_FmPcdManipHdrFieldUpdateIpv6) */
81340 +#define HDR_MANIP_IPV6_DST 0x10000000 /**< update IP destination address with the given value
81341 + ('dst' field of t_FmPcdManipHdrFieldUpdateIpv6) */
81342 +
81343 +typedef hdrManipFlags_t tcpUdpHdrManipUpdateFlags_t;/**< TCP/UDP protocol HMan update command flags. */
81344 +
81345 +#define HDR_MANIP_TCP_UDP_SRC 0x80000000 /**< update TCP/UDP source address with the given value
81346 + ('src' field of t_FmPcdManipHdrFieldUpdateTcpUdp) */
81347 +#define HDR_MANIP_TCP_UDP_DST 0x40000000 /**< update TCP/UDP destination address with the given value
81348 + ('dst' field of t_FmPcdManipHdrFieldUpdateTcpUdp) */
81349 +#define HDR_MANIP_TCP_UDP_CHECKSUM 0x20000000 /**< update TCP/UDP checksum */
81350 +
81351 +/* @} */
81352 +
81353 +/**************************************************************************//**
81354 + @Description A type used for returning the order of the key extraction.
81355 + each value in this array represents the index of the extraction
81356 + command as defined by the user in the initialization extraction array.
81357 + The valid size of this array is the user define number of extractions
81358 + required (also marked by the second '0' in this array).
81359 +*//***************************************************************************/
81360 +typedef uint8_t t_FmPcdKgKeyOrder [FM_PCD_KG_MAX_NUM_OF_EXTRACTS_PER_KEY];
81361 +
81362 +/**************************************************************************//**
81363 + @Description All PCD engines
81364 +*//***************************************************************************/
81365 +typedef enum e_FmPcdEngine {
81366 + e_FM_PCD_INVALID = 0, /**< Invalid PCD engine */
81367 + e_FM_PCD_DONE, /**< No PCD Engine indicated */
81368 + e_FM_PCD_KG, /**< KeyGen */
81369 + e_FM_PCD_CC, /**< Coarse classifier */
81370 + e_FM_PCD_PLCR, /**< Policer */
81371 + e_FM_PCD_PRS, /**< Parser */
81372 +#if (DPAA_VERSION >= 11)
81373 + e_FM_PCD_FR, /**< Frame-Replicator */
81374 +#endif /* (DPAA_VERSION >= 11) */
81375 + e_FM_PCD_HASH /**< Hash table */
81376 +} e_FmPcdEngine;
81377 +
81378 +/**************************************************************************//**
81379 + @Description Enumeration type for selecting extraction by header types
81380 +*//***************************************************************************/
81381 +typedef enum e_FmPcdExtractByHdrType {
81382 + e_FM_PCD_EXTRACT_FROM_HDR, /**< Extract bytes from header */
81383 + e_FM_PCD_EXTRACT_FROM_FIELD, /**< Extract bytes from header field */
81384 + e_FM_PCD_EXTRACT_FULL_FIELD /**< Extract a full field */
81385 +} e_FmPcdExtractByHdrType;
81386 +
81387 +/**************************************************************************//**
81388 + @Description Enumeration type for selecting extraction source
81389 + (when it is not the header)
81390 +*//***************************************************************************/
81391 +typedef enum e_FmPcdExtractFrom {
81392 + e_FM_PCD_EXTRACT_FROM_FRAME_START, /**< KG & CC: Extract from beginning of frame */
81393 + e_FM_PCD_EXTRACT_FROM_DFLT_VALUE, /**< KG only: Extract from a default value */
81394 + e_FM_PCD_EXTRACT_FROM_CURR_END_OF_PARSE, /**< KG & CC: Extract from the point where parsing had finished */
81395 + e_FM_PCD_EXTRACT_FROM_KEY, /**< CC only: Field where saved KEY */
81396 + e_FM_PCD_EXTRACT_FROM_HASH, /**< CC only: Field where saved HASH */
81397 + e_FM_PCD_EXTRACT_FROM_PARSE_RESULT, /**< KG only: Extract from the parser result */
81398 + e_FM_PCD_EXTRACT_FROM_ENQ_FQID, /**< KG & CC: Extract from enqueue FQID */
81399 + e_FM_PCD_EXTRACT_FROM_FLOW_ID /**< CC only: Field where saved Dequeue FQID */
81400 +} e_FmPcdExtractFrom;
81401 +
81402 +/**************************************************************************//**
81403 + @Description Enumeration type for selecting extraction type
81404 +*//***************************************************************************/
81405 +typedef enum e_FmPcdExtractType {
81406 + e_FM_PCD_EXTRACT_BY_HDR, /**< Extract according to header */
81407 + e_FM_PCD_EXTRACT_NON_HDR, /**< Extract from data that is not the header */
81408 + e_FM_PCD_KG_EXTRACT_PORT_PRIVATE_INFO /**< Extract private info as specified by user */
81409 +} e_FmPcdExtractType;
81410 +
81411 +/**************************************************************************//**
81412 + @Description Enumeration type for selecting default extraction value
81413 +*//***************************************************************************/
81414 +typedef enum e_FmPcdKgExtractDfltSelect {
81415 + e_FM_PCD_KG_DFLT_GBL_0, /**< Default selection is KG register 0 */
81416 + e_FM_PCD_KG_DFLT_GBL_1, /**< Default selection is KG register 1 */
81417 + e_FM_PCD_KG_DFLT_PRIVATE_0, /**< Default selection is a per scheme register 0 */
81418 + e_FM_PCD_KG_DFLT_PRIVATE_1, /**< Default selection is a per scheme register 1 */
81419 + e_FM_PCD_KG_DFLT_ILLEGAL /**< Illegal selection */
81420 +} e_FmPcdKgExtractDfltSelect;
81421 +
81422 +/**************************************************************************//**
81423 + @Description Enumeration type defining all default groups - each group shares
81424 + a default value, one of four user-initialized values.
81425 +*//***************************************************************************/
81426 +typedef enum e_FmPcdKgKnownFieldsDfltTypes {
81427 + e_FM_PCD_KG_MAC_ADDR, /**< MAC Address */
81428 + e_FM_PCD_KG_TCI, /**< TCI field */
81429 + e_FM_PCD_KG_ENET_TYPE, /**< ENET Type */
81430 + e_FM_PCD_KG_PPP_SESSION_ID, /**< PPP Session id */
81431 + e_FM_PCD_KG_PPP_PROTOCOL_ID, /**< PPP Protocol id */
81432 + e_FM_PCD_KG_MPLS_LABEL, /**< MPLS label */
81433 + e_FM_PCD_KG_IP_ADDR, /**< IP address */
81434 + e_FM_PCD_KG_PROTOCOL_TYPE, /**< Protocol type */
81435 + e_FM_PCD_KG_IP_TOS_TC, /**< TOS or TC */
81436 + e_FM_PCD_KG_IPV6_FLOW_LABEL, /**< IPV6 flow label */
81437 + e_FM_PCD_KG_IPSEC_SPI, /**< IPSEC SPI */
81438 + e_FM_PCD_KG_L4_PORT, /**< L4 Port */
81439 + e_FM_PCD_KG_TCP_FLAG, /**< TCP Flag */
81440 + e_FM_PCD_KG_GENERIC_FROM_DATA, /**< grouping implemented by SW,
81441 + any data extraction that is not the full
81442 + field described above */
81443 + e_FM_PCD_KG_GENERIC_FROM_DATA_NO_V, /**< grouping implemented by SW,
81444 + any data extraction without validation */
81445 + e_FM_PCD_KG_GENERIC_NOT_FROM_DATA /**< grouping implemented by SW,
81446 + extraction from parser result or
81447 + direct use of default value */
81448 +} e_FmPcdKgKnownFieldsDfltTypes;
81449 +
81450 +/**************************************************************************//**
81451 + @Description Enumeration type for defining header index for scenarios with
81452 + multiple (tunneled) headers
81453 +*//***************************************************************************/
81454 +typedef enum e_FmPcdHdrIndex {
81455 + e_FM_PCD_HDR_INDEX_NONE = 0, /**< used when multiple headers not used, also
81456 + to specify regular IP (not tunneled). */
81457 + e_FM_PCD_HDR_INDEX_1, /**< may be used for VLAN, MPLS, tunneled IP */
81458 + e_FM_PCD_HDR_INDEX_2, /**< may be used for MPLS, tunneled IP */
81459 + e_FM_PCD_HDR_INDEX_3, /**< may be used for MPLS */
81460 + e_FM_PCD_HDR_INDEX_LAST = 0xFF /**< may be used for VLAN, MPLS */
81461 +} e_FmPcdHdrIndex;
81462 +
81463 +/**************************************************************************//**
81464 + @Description Enumeration type for selecting the policer profile functional type
81465 +*//***************************************************************************/
81466 +typedef enum e_FmPcdProfileTypeSelection {
81467 + e_FM_PCD_PLCR_PORT_PRIVATE, /**< Port dedicated profile */
81468 + e_FM_PCD_PLCR_SHARED /**< Shared profile (shared within partition) */
81469 +} e_FmPcdProfileTypeSelection;
81470 +
81471 +/**************************************************************************//**
81472 + @Description Enumeration type for selecting the policer profile algorithm
81473 +*//***************************************************************************/
81474 +typedef enum e_FmPcdPlcrAlgorithmSelection {
81475 + e_FM_PCD_PLCR_PASS_THROUGH, /**< Policer pass through */
81476 + e_FM_PCD_PLCR_RFC_2698, /**< Policer algorithm RFC 2698 */
81477 + e_FM_PCD_PLCR_RFC_4115 /**< Policer algorithm RFC 4115 */
81478 +} e_FmPcdPlcrAlgorithmSelection;
81479 +
81480 +/**************************************************************************//**
81481 + @Description Enumeration type for selecting a policer profile color mode
81482 +*//***************************************************************************/
81483 +typedef enum e_FmPcdPlcrColorMode {
81484 + e_FM_PCD_PLCR_COLOR_BLIND, /**< Color blind */
81485 + e_FM_PCD_PLCR_COLOR_AWARE /**< Color aware */
81486 +} e_FmPcdPlcrColorMode;
81487 +
81488 +/**************************************************************************//**
81489 + @Description Enumeration type for selecting a policer profile color
81490 +*//***************************************************************************/
81491 +typedef enum e_FmPcdPlcrColor {
81492 + e_FM_PCD_PLCR_GREEN, /**< Green color code */
81493 + e_FM_PCD_PLCR_YELLOW, /**< Yellow color code */
81494 + e_FM_PCD_PLCR_RED, /**< Red color code */
81495 + e_FM_PCD_PLCR_OVERRIDE /**< Color override code */
81496 +} e_FmPcdPlcrColor;
81497 +
81498 +/**************************************************************************//**
81499 + @Description Enumeration type for selecting the policer profile packet frame length selector
81500 +*//***************************************************************************/
81501 +typedef enum e_FmPcdPlcrFrameLengthSelect {
81502 + e_FM_PCD_PLCR_L2_FRM_LEN, /**< L2 frame length */
81503 + e_FM_PCD_PLCR_L3_FRM_LEN, /**< L3 frame length */
81504 + e_FM_PCD_PLCR_L4_FRM_LEN, /**< L4 frame length */
81505 + e_FM_PCD_PLCR_FULL_FRM_LEN /**< Full frame length */
81506 +} e_FmPcdPlcrFrameLengthSelect;
81507 +
81508 +/**************************************************************************//**
81509 + @Description Enumeration type for selecting roll-back frame
81510 +*//***************************************************************************/
81511 +typedef enum e_FmPcdPlcrRollBackFrameSelect {
81512 + e_FM_PCD_PLCR_ROLLBACK_L2_FRM_LEN, /**< Roll-back L2 frame length */
81513 + e_FM_PCD_PLCR_ROLLBACK_FULL_FRM_LEN /**< Roll-back Full frame length */
81514 +} e_FmPcdPlcrRollBackFrameSelect;
81515 +
81516 +/**************************************************************************//**
81517 + @Description Enumeration type for selecting the policer profile packet or byte mode
81518 +*//***************************************************************************/
81519 +typedef enum e_FmPcdPlcrRateMode {
81520 + e_FM_PCD_PLCR_BYTE_MODE, /**< Byte mode */
81521 + e_FM_PCD_PLCR_PACKET_MODE /**< Packet mode */
81522 +} e_FmPcdPlcrRateMode;
81523 +
81524 +/**************************************************************************//**
81525 + @Description Enumeration type for defining action of frame
81526 +*//***************************************************************************/
81527 +typedef enum e_FmPcdDoneAction {
81528 + e_FM_PCD_ENQ_FRAME = 0, /**< Enqueue frame */
81529 + e_FM_PCD_DROP_FRAME /**< Mark this frame as error frame and continue
81530 + to error flow; 'FM_PORT_FRM_ERR_CLS_DISCARD'
81531 + flag will be set for this frame. */
81532 +} e_FmPcdDoneAction;
81533 +
81534 +/**************************************************************************//**
81535 + @Description Enumeration type for selecting the policer counter
81536 +*//***************************************************************************/
81537 +typedef enum e_FmPcdPlcrProfileCounters {
81538 + e_FM_PCD_PLCR_PROFILE_GREEN_PACKET_TOTAL_COUNTER, /**< Green packets counter */
81539 + e_FM_PCD_PLCR_PROFILE_YELLOW_PACKET_TOTAL_COUNTER, /**< Yellow packets counter */
81540 + e_FM_PCD_PLCR_PROFILE_RED_PACKET_TOTAL_COUNTER, /**< Red packets counter */
81541 + e_FM_PCD_PLCR_PROFILE_RECOLOURED_YELLOW_PACKET_TOTAL_COUNTER, /**< Recolored yellow packets counter */
81542 + e_FM_PCD_PLCR_PROFILE_RECOLOURED_RED_PACKET_TOTAL_COUNTER /**< Recolored red packets counter */
81543 +} e_FmPcdPlcrProfileCounters;
81544 +
81545 +/**************************************************************************//**
81546 + @Description Enumeration type for selecting the PCD action after extraction
81547 +*//***************************************************************************/
81548 +typedef enum e_FmPcdAction {
81549 + e_FM_PCD_ACTION_NONE, /**< NONE */
81550 + e_FM_PCD_ACTION_EXACT_MATCH, /**< Exact match on the selected extraction */
81551 + e_FM_PCD_ACTION_INDEXED_LOOKUP /**< Indexed lookup on the selected extraction */
81552 +} e_FmPcdAction;
81553 +
81554 +/**************************************************************************//**
81555 + @Description Enumeration type for selecting type of insert manipulation
81556 +*//***************************************************************************/
81557 +typedef enum e_FmPcdManipHdrInsrtType {
81558 + e_FM_PCD_MANIP_INSRT_GENERIC, /**< Insert according to offset & size */
81559 + e_FM_PCD_MANIP_INSRT_BY_HDR, /**< Insert according to protocol */
81560 +#if ((DPAA_VERSION == 10) && defined(FM_CAPWAP_SUPPORT))
81561 + e_FM_PCD_MANIP_INSRT_BY_TEMPLATE /**< Insert template to start of frame */
81562 +#endif /* ((DPAA_VERSION == 10) && defined(FM_CAPWAP_SUPPORT)) */
81563 +} e_FmPcdManipHdrInsrtType;
81564 +
81565 +/**************************************************************************//**
81566 + @Description Enumeration type for selecting type of remove manipulation
81567 +*//***************************************************************************/
81568 +typedef enum e_FmPcdManipHdrRmvType {
81569 + e_FM_PCD_MANIP_RMV_GENERIC, /**< Remove according to offset & size */
81570 + e_FM_PCD_MANIP_RMV_BY_HDR /**< Remove according to offset & size */
81571 +} e_FmPcdManipHdrRmvType;
81572 +
81573 +/**************************************************************************//**
81574 + @Description Enumeration type for selecting specific L2 fields removal
81575 +*//***************************************************************************/
81576 +typedef enum e_FmPcdManipHdrRmvSpecificL2 {
81577 + e_FM_PCD_MANIP_HDR_RMV_ETHERNET, /**< Ethernet/802.3 MAC */
81578 + e_FM_PCD_MANIP_HDR_RMV_STACKED_QTAGS, /**< stacked QTags */
81579 + e_FM_PCD_MANIP_HDR_RMV_ETHERNET_AND_MPLS, /**< MPLS and Ethernet/802.3 MAC header until
81580 + the header which follows the MPLS header */
81581 + e_FM_PCD_MANIP_HDR_RMV_MPLS, /**< Remove MPLS header (Unlimited MPLS labels) */
81582 + e_FM_PCD_MANIP_HDR_RMV_PPPOE /**< Remove the PPPoE header and PPP protocol field. */
81583 +} e_FmPcdManipHdrRmvSpecificL2;
81584 +
81585 +/**************************************************************************//**
81586 + @Description Enumeration type for selecting specific fields updates
81587 +*//***************************************************************************/
81588 +typedef enum e_FmPcdManipHdrFieldUpdateType {
81589 + e_FM_PCD_MANIP_HDR_FIELD_UPDATE_VLAN, /**< VLAN updates */
81590 + e_FM_PCD_MANIP_HDR_FIELD_UPDATE_IPV4, /**< IPV4 updates */
81591 + e_FM_PCD_MANIP_HDR_FIELD_UPDATE_IPV6, /**< IPV6 updates */
81592 + e_FM_PCD_MANIP_HDR_FIELD_UPDATE_TCP_UDP, /**< TCP_UDP updates */
81593 +} e_FmPcdManipHdrFieldUpdateType;
81594 +
81595 +/**************************************************************************//**
81596 + @Description Enumeration type for selecting VLAN updates
81597 +*//***************************************************************************/
81598 +typedef enum e_FmPcdManipHdrFieldUpdateVlan {
81599 + e_FM_PCD_MANIP_HDR_FIELD_UPDATE_VLAN_VPRI, /**< Replace VPri of outer most VLAN tag. */
81600 + e_FM_PCD_MANIP_HDR_FIELD_UPDATE_DSCP_TO_VLAN /**< DSCP to VLAN priority bits translation */
81601 +} e_FmPcdManipHdrFieldUpdateVlan;
81602 +
81603 +/**************************************************************************//**
81604 + @Description Enumeration type for selecting specific L2 header insertion
81605 +*//***************************************************************************/
81606 +typedef enum e_FmPcdManipHdrInsrtSpecificL2 {
81607 + e_FM_PCD_MANIP_HDR_INSRT_MPLS, /**< Insert MPLS header (Unlimited MPLS labels) */
81608 + e_FM_PCD_MANIP_HDR_INSRT_PPPOE /**< Insert PPPOE */
81609 +} e_FmPcdManipHdrInsrtSpecificL2;
81610 +
81611 +#if (DPAA_VERSION >= 11)
81612 +/**************************************************************************//**
81613 + @Description Enumeration type for selecting QoS mapping mode
81614 +
81615 + Note: In all cases except 'e_FM_PCD_MANIP_HDR_QOS_MAPPING_NONE'
81616 + User should instruct the port to read the hash-result
81617 +*//***************************************************************************/
81618 +typedef enum e_FmPcdManipHdrQosMappingMode {
81619 + e_FM_PCD_MANIP_HDR_QOS_MAPPING_NONE = 0, /**< No mapping, QoS field will not be changed */
81620 + e_FM_PCD_MANIP_HDR_QOS_MAPPING_AS_IS, /**< QoS field will be overwritten by the last byte in the hash-result. */
81621 +} e_FmPcdManipHdrQosMappingMode;
81622 +
81623 +/**************************************************************************//**
81624 + @Description Enumeration type for selecting QoS source
81625 +
81626 + Note: In all cases except 'e_FM_PCD_MANIP_HDR_QOS_SRC_NONE'
81627 + User should left room for the hash-result on input/output buffer
81628 + and instruct the port to read/write the hash-result to the buffer (RPD should be set)
81629 +*//***************************************************************************/
81630 +typedef enum e_FmPcdManipHdrQosSrc {
81631 + e_FM_PCD_MANIP_HDR_QOS_SRC_NONE = 0, /**< TODO */
81632 + e_FM_PCD_MANIP_HDR_QOS_SRC_USER_DEFINED, /**< QoS will be taken from the last byte in the hash-result. */
81633 +} e_FmPcdManipHdrQosSrc;
81634 +#endif /* (DPAA_VERSION >= 11) */
81635 +
81636 +/**************************************************************************//**
81637 + @Description Enumeration type for selecting type of header insertion
81638 +*//***************************************************************************/
81639 +typedef enum e_FmPcdManipHdrInsrtByHdrType {
81640 + e_FM_PCD_MANIP_INSRT_BY_HDR_SPECIFIC_L2, /**< Specific L2 fields insertion */
81641 +#if (DPAA_VERSION >= 11)
81642 + e_FM_PCD_MANIP_INSRT_BY_HDR_IP, /**< IP insertion */
81643 + e_FM_PCD_MANIP_INSRT_BY_HDR_UDP, /**< UDP insertion */
81644 + e_FM_PCD_MANIP_INSRT_BY_HDR_UDP_LITE, /**< UDP lite insertion */
81645 + e_FM_PCD_MANIP_INSRT_BY_HDR_CAPWAP /**< CAPWAP insertion */
81646 +#endif /* (DPAA_VERSION >= 11) */
81647 +} e_FmPcdManipHdrInsrtByHdrType;
81648 +
81649 +/**************************************************************************//**
81650 + @Description Enumeration type for selecting specific customCommand
81651 +*//***************************************************************************/
81652 +typedef enum e_FmPcdManipHdrCustomType {
81653 + e_FM_PCD_MANIP_HDR_CUSTOM_IP_REPLACE, /**< Replace IPv4/IPv6 */
81654 + e_FM_PCD_MANIP_HDR_CUSTOM_GEN_FIELD_REPLACE, /**< Replace IPv4/IPv6 */
81655 +} e_FmPcdManipHdrCustomType;
81656 +
81657 +/**************************************************************************//**
81658 + @Description Enumeration type for selecting specific customCommand
81659 +*//***************************************************************************/
81660 +typedef enum e_FmPcdManipHdrCustomIpReplace {
81661 + e_FM_PCD_MANIP_HDR_CUSTOM_REPLACE_IPV4_BY_IPV6, /**< Replace IPv4 by IPv6 */
81662 + e_FM_PCD_MANIP_HDR_CUSTOM_REPLACE_IPV6_BY_IPV4 /**< Replace IPv6 by IPv4 */
81663 +} e_FmPcdManipHdrCustomIpReplace;
81664 +
81665 +/**************************************************************************//**
81666 + @Description Enumeration type for selecting type of header removal
81667 +*//***************************************************************************/
81668 +typedef enum e_FmPcdManipHdrRmvByHdrType {
81669 + e_FM_PCD_MANIP_RMV_BY_HDR_SPECIFIC_L2 = 0, /**< Specific L2 fields removal */
81670 +#if (DPAA_VERSION >= 11)
81671 + e_FM_PCD_MANIP_RMV_BY_HDR_CAPWAP, /**< CAPWAP removal */
81672 +#endif /* (DPAA_VERSION >= 11) */
81673 +#if (DPAA_VERSION >= 11) || ((DPAA_VERSION == 10) && defined(FM_CAPWAP_SUPPORT))
81674 + e_FM_PCD_MANIP_RMV_BY_HDR_FROM_START, /**< Locate from data that is not the header */
81675 +#endif /* (DPAA_VERSION >= 11) || ((DPAA_VERSION == 10) && defined(FM_CAPWAP_SUPPORT)) */
81676 +} e_FmPcdManipHdrRmvByHdrType;
81677 +
81678 +/**************************************************************************//**
81679 + @Description Enumeration type for selecting type of timeout mode
81680 +*//***************************************************************************/
81681 +typedef enum e_FmPcdManipReassemTimeOutMode {
81682 + e_FM_PCD_MANIP_TIME_OUT_BETWEEN_FRAMES, /**< Limits the time of the reassembly process
81683 + from the first fragment to the last */
81684 + e_FM_PCD_MANIP_TIME_OUT_BETWEEN_FRAG /**< Limits the time of receiving the fragment */
81685 +} e_FmPcdManipReassemTimeOutMode;
81686 +
81687 +/**************************************************************************//**
81688 + @Description Enumeration type for selecting type of WaysNumber mode
81689 +*//***************************************************************************/
81690 +typedef enum e_FmPcdManipReassemWaysNumber {
81691 + e_FM_PCD_MANIP_ONE_WAY_HASH = 1, /**< One way hash */
81692 + e_FM_PCD_MANIP_TWO_WAYS_HASH, /**< Two ways hash */
81693 + e_FM_PCD_MANIP_THREE_WAYS_HASH, /**< Three ways hash */
81694 + e_FM_PCD_MANIP_FOUR_WAYS_HASH, /**< Four ways hash */
81695 + e_FM_PCD_MANIP_FIVE_WAYS_HASH, /**< Five ways hash */
81696 + e_FM_PCD_MANIP_SIX_WAYS_HASH, /**< Six ways hash */
81697 + e_FM_PCD_MANIP_SEVEN_WAYS_HASH, /**< Seven ways hash */
81698 + e_FM_PCD_MANIP_EIGHT_WAYS_HASH /**< Eight ways hash */
81699 +} e_FmPcdManipReassemWaysNumber;
81700 +
81701 +#if ((DPAA_VERSION == 10) && defined(FM_CAPWAP_SUPPORT))
81702 +/**************************************************************************//**
81703 + @Description Enumeration type for selecting type of statistics mode
81704 +*//***************************************************************************/
81705 +typedef enum e_FmPcdStatsType {
81706 + e_FM_PCD_STATS_PER_FLOWID = 0 /**< Flow ID is used as index for getting statistics */
81707 +} e_FmPcdStatsType;
81708 +#endif /* ((DPAA_VERSION == 10) && defined(FM_CAPWAP_SUPPORT)) */
81709 +
81710 +/**************************************************************************//**
81711 + @Description Enumeration type for selecting manipulation type
81712 +*//***************************************************************************/
81713 +typedef enum e_FmPcdManipType {
81714 + e_FM_PCD_MANIP_HDR = 0, /**< Header manipulation */
81715 + e_FM_PCD_MANIP_REASSEM, /**< Reassembly */
81716 + e_FM_PCD_MANIP_FRAG, /**< Fragmentation */
81717 + e_FM_PCD_MANIP_SPECIAL_OFFLOAD /**< Special Offloading */
81718 +} e_FmPcdManipType;
81719 +
81720 +/**************************************************************************//**
81721 + @Description Enumeration type for selecting type of statistics mode
81722 +*//***************************************************************************/
81723 +typedef enum e_FmPcdCcStatsMode {
81724 + e_FM_PCD_CC_STATS_MODE_NONE = 0, /**< No statistics support */
81725 + e_FM_PCD_CC_STATS_MODE_FRAME, /**< Frame count statistics */
81726 + e_FM_PCD_CC_STATS_MODE_BYTE_AND_FRAME, /**< Byte and frame count statistics */
81727 +#if (DPAA_VERSION >= 11)
81728 + e_FM_PCD_CC_STATS_MODE_RMON, /**< Byte and frame length range count statistics;
81729 + This mode is supported only on B4860 device */
81730 +#endif /* (DPAA_VERSION >= 11) */
81731 +} e_FmPcdCcStatsMode;
81732 +
81733 +/**************************************************************************//**
81734 + @Description Enumeration type for determining the action in case an IP packet
81735 + is larger than MTU but its DF (Don't Fragment) bit is set.
81736 +*//***************************************************************************/
81737 +typedef enum e_FmPcdManipDontFragAction {
81738 + e_FM_PCD_MANIP_DISCARD_PACKET = 0, /**< Discard packet */
81739 + e_FM_PCD_MANIP_ENQ_TO_ERR_Q_OR_DISCARD_PACKET = e_FM_PCD_MANIP_DISCARD_PACKET,
81740 + /**< Obsolete, cannot enqueue to error queue;
81741 + In practice, selects to discard packets;
81742 + Will be removed in the future */
81743 + e_FM_PCD_MANIP_FRAGMENT_PACKET, /**< Fragment packet and continue normal processing */
81744 + e_FM_PCD_MANIP_CONTINUE_WITHOUT_FRAG /**< Continue normal processing without fragmenting the packet */
81745 +} e_FmPcdManipDontFragAction;
81746 +
81747 +/**************************************************************************//**
81748 + @Description Enumeration type for selecting type of special offload manipulation
81749 +*//***************************************************************************/
81750 +typedef enum e_FmPcdManipSpecialOffloadType {
81751 + e_FM_PCD_MANIP_SPECIAL_OFFLOAD_IPSEC, /**< IPSec offload manipulation */
81752 +#if (DPAA_VERSION >= 11)
81753 + e_FM_PCD_MANIP_SPECIAL_OFFLOAD_CAPWAP /**< CAPWAP offload manipulation */
81754 +#endif /* (DPAA_VERSION >= 11) */
81755 +} e_FmPcdManipSpecialOffloadType;
81756 +
81757 +
81758 +/**************************************************************************//**
81759 + @Description A Union of protocol dependent special options
81760 +*//***************************************************************************/
81761 +typedef union u_FmPcdHdrProtocolOpt {
81762 + ethProtocolOpt_t ethOpt; /**< Ethernet options */
81763 + vlanProtocolOpt_t vlanOpt; /**< VLAN options */
81764 + mplsProtocolOpt_t mplsOpt; /**< MPLS options */
81765 + ipv4ProtocolOpt_t ipv4Opt; /**< IPv4 options */
81766 + ipv6ProtocolOpt_t ipv6Opt; /**< IPv6 options */
81767 +#if (DPAA_VERSION >= 11)
81768 + capwapProtocolOpt_t capwapOpt; /**< CAPWAP options */
81769 +#endif /* (DPAA_VERSION >= 11) */
81770 +} u_FmPcdHdrProtocolOpt;
81771 +
81772 +/**************************************************************************//**
81773 + @Description A union holding protocol fields
81774 +
81775 +
81776 + Fields supported as "full fields":
81777 + HEADER_TYPE_ETH:
81778 + NET_HEADER_FIELD_ETH_DA
81779 + NET_HEADER_FIELD_ETH_SA
81780 + NET_HEADER_FIELD_ETH_TYPE
81781 +
81782 + HEADER_TYPE_LLC_SNAP:
81783 + NET_HEADER_FIELD_LLC_SNAP_TYPE
81784 +
81785 + HEADER_TYPE_VLAN:
81786 + NET_HEADER_FIELD_VLAN_TCI
81787 + (index may apply:
81788 + e_FM_PCD_HDR_INDEX_NONE/e_FM_PCD_HDR_INDEX_1,
81789 + e_FM_PCD_HDR_INDEX_LAST)
81790 +
81791 + HEADER_TYPE_MPLS:
81792 + NET_HEADER_FIELD_MPLS_LABEL_STACK
81793 + (index may apply:
81794 + e_FM_PCD_HDR_INDEX_NONE/e_FM_PCD_HDR_INDEX_1,
81795 + e_FM_PCD_HDR_INDEX_2,
81796 + e_FM_PCD_HDR_INDEX_LAST)
81797 +
81798 + HEADER_TYPE_IPv4:
81799 + NET_HEADER_FIELD_IPv4_SRC_IP
81800 + NET_HEADER_FIELD_IPv4_DST_IP
81801 + NET_HEADER_FIELD_IPv4_PROTO
81802 + NET_HEADER_FIELD_IPv4_TOS
81803 + (index may apply:
81804 + e_FM_PCD_HDR_INDEX_NONE/e_FM_PCD_HDR_INDEX_1,
81805 + e_FM_PCD_HDR_INDEX_2/e_FM_PCD_HDR_INDEX_LAST)
81806 +
81807 + HEADER_TYPE_IPv6:
81808 + NET_HEADER_FIELD_IPv6_SRC_IP
81809 + NET_HEADER_FIELD_IPv6_DST_IP
81810 + NET_HEADER_FIELD_IPv6_NEXT_HDR
81811 + NET_HEADER_FIELD_IPv6_VER | NET_HEADER_FIELD_IPv6_FL | NET_HEADER_FIELD_IPv6_TC (must come together!)
81812 + (index may apply:
81813 + e_FM_PCD_HDR_INDEX_NONE/e_FM_PCD_HDR_INDEX_1,
81814 + e_FM_PCD_HDR_INDEX_2/e_FM_PCD_HDR_INDEX_LAST)
81815 +
81816 + (Note that starting from DPAA 1-1, NET_HEADER_FIELD_IPv6_NEXT_HDR applies to
81817 + the last next header indication, meaning the next L4, which may be
81818 + present at the Ipv6 last extension. On earlier revisions this field
81819 + applies to the Next-Header field of the main IPv6 header)
81820 +
81821 + HEADER_TYPE_IP:
81822 + NET_HEADER_FIELD_IP_PROTO
81823 + (index may apply:
81824 + e_FM_PCD_HDR_INDEX_LAST)
81825 + NET_HEADER_FIELD_IP_DSCP
81826 + (index may apply:
81827 + e_FM_PCD_HDR_INDEX_NONE/e_FM_PCD_HDR_INDEX_1)
81828 + HEADER_TYPE_GRE:
81829 + NET_HEADER_FIELD_GRE_TYPE
81830 +
81831 + HEADER_TYPE_MINENCAP
81832 + NET_HEADER_FIELD_MINENCAP_SRC_IP
81833 + NET_HEADER_FIELD_MINENCAP_DST_IP
81834 + NET_HEADER_FIELD_MINENCAP_TYPE
81835 +
81836 + HEADER_TYPE_TCP:
81837 + NET_HEADER_FIELD_TCP_PORT_SRC
81838 + NET_HEADER_FIELD_TCP_PORT_DST
81839 + NET_HEADER_FIELD_TCP_FLAGS
81840 +
81841 + HEADER_TYPE_UDP:
81842 + NET_HEADER_FIELD_UDP_PORT_SRC
81843 + NET_HEADER_FIELD_UDP_PORT_DST
81844 +
81845 + HEADER_TYPE_UDP_LITE:
81846 + NET_HEADER_FIELD_UDP_LITE_PORT_SRC
81847 + NET_HEADER_FIELD_UDP_LITE_PORT_DST
81848 +
81849 + HEADER_TYPE_IPSEC_AH:
81850 + NET_HEADER_FIELD_IPSEC_AH_SPI
81851 + NET_HEADER_FIELD_IPSEC_AH_NH
81852 +
81853 + HEADER_TYPE_IPSEC_ESP:
81854 + NET_HEADER_FIELD_IPSEC_ESP_SPI
81855 +
81856 + HEADER_TYPE_SCTP:
81857 + NET_HEADER_FIELD_SCTP_PORT_SRC
81858 + NET_HEADER_FIELD_SCTP_PORT_DST
81859 +
81860 + HEADER_TYPE_DCCP:
81861 + NET_HEADER_FIELD_DCCP_PORT_SRC
81862 + NET_HEADER_FIELD_DCCP_PORT_DST
81863 +
81864 + HEADER_TYPE_PPPoE:
81865 + NET_HEADER_FIELD_PPPoE_PID
81866 + NET_HEADER_FIELD_PPPoE_SID
81867 +
81868 + *****************************************************************
81869 + Fields supported as "from fields":
81870 + HEADER_TYPE_ETH (with or without validation):
81871 + NET_HEADER_FIELD_ETH_TYPE
81872 +
81873 + HEADER_TYPE_VLAN (with or without validation):
81874 + NET_HEADER_FIELD_VLAN_TCI
81875 + (index may apply:
81876 + e_FM_PCD_HDR_INDEX_NONE/e_FM_PCD_HDR_INDEX_1,
81877 + e_FM_PCD_HDR_INDEX_LAST)
81878 +
81879 + HEADER_TYPE_IPv4 (without validation):
81880 + NET_HEADER_FIELD_IPv4_PROTO
81881 + (index may apply:
81882 + e_FM_PCD_HDR_INDEX_NONE/e_FM_PCD_HDR_INDEX_1,
81883 + e_FM_PCD_HDR_INDEX_2/e_FM_PCD_HDR_INDEX_LAST)
81884 +
81885 + HEADER_TYPE_IPv6 (without validation):
81886 + NET_HEADER_FIELD_IPv6_NEXT_HDR
81887 + (index may apply:
81888 + e_FM_PCD_HDR_INDEX_NONE/e_FM_PCD_HDR_INDEX_1,
81889 + e_FM_PCD_HDR_INDEX_2/e_FM_PCD_HDR_INDEX_LAST)
81890 +
81891 +*//***************************************************************************/
81892 +typedef union t_FmPcdFields {
81893 + headerFieldEth_t eth; /**< Ethernet */
81894 + headerFieldVlan_t vlan; /**< VLAN */
81895 + headerFieldLlcSnap_t llcSnap; /**< LLC SNAP */
81896 + headerFieldPppoe_t pppoe; /**< PPPoE */
81897 + headerFieldMpls_t mpls; /**< MPLS */
81898 + headerFieldIp_t ip; /**< IP */
81899 + headerFieldIpv4_t ipv4; /**< IPv4 */
81900 + headerFieldIpv6_t ipv6; /**< IPv6 */
81901 + headerFieldUdp_t udp; /**< UDP */
81902 + headerFieldUdpLite_t udpLite; /**< UDP Lite */
81903 + headerFieldTcp_t tcp; /**< TCP */
81904 + headerFieldSctp_t sctp; /**< SCTP */
81905 + headerFieldDccp_t dccp; /**< DCCP */
81906 + headerFieldGre_t gre; /**< GRE */
81907 + headerFieldMinencap_t minencap; /**< Minimal Encapsulation */
81908 + headerFieldIpsecAh_t ipsecAh; /**< IPSec AH */
81909 + headerFieldIpsecEsp_t ipsecEsp; /**< IPSec ESP */
81910 + headerFieldUdpEncapEsp_t udpEncapEsp; /**< UDP Encapsulation ESP */
81911 +} t_FmPcdFields;
81912 +
81913 +/**************************************************************************//**
81914 + @Description Parameters for defining header extraction for key generation
81915 +*//***************************************************************************/
81916 +typedef struct t_FmPcdFromHdr {
81917 + uint8_t size; /**< Size in byte */
81918 + uint8_t offset; /**< Byte offset */
81919 +} t_FmPcdFromHdr;
81920 +
81921 +/**************************************************************************//**
81922 + @Description Parameters for defining field extraction for key generation
81923 +*//***************************************************************************/
81924 +typedef struct t_FmPcdFromField {
81925 + t_FmPcdFields field; /**< Field selection */
81926 + uint8_t size; /**< Size in byte */
81927 + uint8_t offset; /**< Byte offset */
81928 +} t_FmPcdFromField;
81929 +
81930 +/**************************************************************************//**
81931 + @Description Parameters for defining a single network environment unit
81932 +
81933 + A distinction unit should be defined if it will later be used
81934 + by one or more PCD engines to distinguish between flows.
81935 +*//***************************************************************************/
81936 +typedef struct t_FmPcdDistinctionUnit {
81937 + struct {
81938 + e_NetHeaderType hdr; /**< One of the headers supported by the FM */
81939 + u_FmPcdHdrProtocolOpt opt; /**< Select only one option ! */
81940 + } hdrs[FM_PCD_MAX_NUM_OF_INTERCHANGEABLE_HDRS];
81941 +} t_FmPcdDistinctionUnit;
81942 +
81943 +/**************************************************************************//**
81944 + @Description Parameters for defining all different distinction units supported
81945 + by a specific PCD Network Environment Characteristics module.
81946 +
81947 + Each unit represent a protocol or a group of protocols that may
81948 + be used later by the different PCD engines to distinguish
81949 + between flows.
81950 +*//***************************************************************************/
81951 +typedef struct t_FmPcdNetEnvParams {
81952 + uint8_t numOfDistinctionUnits; /**< Number of different units to be identified */
81953 + t_FmPcdDistinctionUnit units[FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS]; /**< An array of numOfDistinctionUnits of the
81954 + different units to be identified */
81955 +} t_FmPcdNetEnvParams;
81956 +
81957 +/**************************************************************************//**
81958 + @Description Parameters for defining a single extraction action when
81959 + creating a key
81960 +*//***************************************************************************/
81961 +typedef struct t_FmPcdExtractEntry {
81962 + e_FmPcdExtractType type; /**< Extraction type select */
81963 + union {
81964 + struct {
81965 + e_NetHeaderType hdr; /**< Header selection */
81966 + bool ignoreProtocolValidation;
81967 + /**< Ignore protocol validation */
81968 + e_FmPcdHdrIndex hdrIndex; /**< Relevant only for MPLS, VLAN and tunneled
81969 + IP. Otherwise should be cleared. */
81970 + e_FmPcdExtractByHdrType type; /**< Header extraction type select */
81971 + union {
81972 + t_FmPcdFromHdr fromHdr; /**< Extract bytes from header parameters */
81973 + t_FmPcdFromField fromField; /**< Extract bytes from field parameters */
81974 + t_FmPcdFields fullField; /**< Extract full filed parameters */
81975 + } extractByHdrType;
81976 + } extractByHdr; /**< used when type = e_FM_PCD_KG_EXTRACT_BY_HDR */
81977 + struct {
81978 + e_FmPcdExtractFrom src; /**< Non-header extraction source */
81979 + e_FmPcdAction action; /**< Relevant for CC Only */
81980 + uint16_t icIndxMask; /**< Relevant only for CC when
81981 + action = e_FM_PCD_ACTION_INDEXED_LOOKUP;
81982 + Note that the number of bits that are set within
81983 + this mask must be log2 of the CC-node 'numOfKeys'.
81984 + Note that the mask cannot be set on the lower bits. */
81985 + uint8_t offset; /**< Byte offset */
81986 + uint8_t size; /**< Size in byte */
81987 + } extractNonHdr; /**< used when type = e_FM_PCD_KG_EXTRACT_NON_HDR */
81988 + };
81989 +} t_FmPcdExtractEntry;
81990 +
81991 +/**************************************************************************//**
81992 + @Description Parameters for defining masks for each extracted field in the key.
81993 +*//***************************************************************************/
81994 +typedef struct t_FmPcdKgExtractMask {
81995 + uint8_t extractArrayIndex; /**< Index in the extraction array, as initialized by user */
81996 + uint8_t offset; /**< Byte offset */
81997 + uint8_t mask; /**< A byte mask (selected bits will be used) */
81998 +} t_FmPcdKgExtractMask;
81999 +
82000 +/**************************************************************************//**
82001 + @Description Parameters for defining default selection per groups of fields
82002 +*//***************************************************************************/
82003 +typedef struct t_FmPcdKgExtractDflt {
82004 + e_FmPcdKgKnownFieldsDfltTypes type; /**< Default type select */
82005 + e_FmPcdKgExtractDfltSelect dfltSelect; /**< Default register select */
82006 +} t_FmPcdKgExtractDflt;
82007 +
82008 +/**************************************************************************//**
82009 + @Description Parameters for defining key extraction and hashing
82010 +*//***************************************************************************/
82011 +typedef struct t_FmPcdKgKeyExtractAndHashParams {
82012 + uint32_t privateDflt0; /**< Scheme default register 0 */
82013 + uint32_t privateDflt1; /**< Scheme default register 1 */
82014 + uint8_t numOfUsedExtracts; /**< defines the valid size of the following array */
82015 + t_FmPcdExtractEntry extractArray [FM_PCD_KG_MAX_NUM_OF_EXTRACTS_PER_KEY]; /**< An array of extractions definition. */
82016 + uint8_t numOfUsedDflts; /**< defines the valid size of the following array */
82017 + t_FmPcdKgExtractDflt dflts[FM_PCD_KG_NUM_OF_DEFAULT_GROUPS];
82018 + /**< For each extraction used in this scheme, specify the required
82019 + default register to be used when header is not found.
82020 + types not specified in this array will get undefined value. */
82021 + uint8_t numOfUsedMasks; /**< defines the valid size of the following array */
82022 + t_FmPcdKgExtractMask masks[FM_PCD_KG_NUM_OF_EXTRACT_MASKS];
82023 + uint8_t hashShift; /**< hash result right shift. Select the 24 bits out of the 64 hash
82024 + result. 0 means using the 24 LSB's, otherwise use the
82025 + 24 LSB's after shifting right.*/
82026 + uint32_t hashDistributionNumOfFqids; /**< must be > 1 and a power of 2. Represents the range
82027 + of queues for the key and hash functionality */
82028 + uint8_t hashDistributionFqidsShift; /**< selects the FQID bits that will be effected by the hash */
82029 + bool symmetricHash; /**< TRUE to generate the same hash for frames with swapped source and
82030 + destination fields on all layers; If TRUE, driver will check that for
82031 + all layers, if SRC extraction is selected, DST extraction must also be
82032 + selected, and vice versa. */
82033 +} t_FmPcdKgKeyExtractAndHashParams;
82034 +
82035 +/**************************************************************************//**
82036 + @Description Parameters for defining a single FQID mask (extracted OR).
82037 +*//***************************************************************************/
82038 +typedef struct t_FmPcdKgExtractedOrParams {
82039 + e_FmPcdExtractType type; /**< Extraction type select */
82040 + union {
82041 + struct { /**< used when type = e_FM_PCD_KG_EXTRACT_BY_HDR */
82042 + e_NetHeaderType hdr;
82043 + e_FmPcdHdrIndex hdrIndex; /**< Relevant only for MPLS, VLAN and tunneled
82044 + IP. Otherwise should be cleared.*/
82045 + bool ignoreProtocolValidation;
82046 + /**< continue extraction even if protocol is not recognized */
82047 + } extractByHdr; /**< Header to extract by */
82048 + e_FmPcdExtractFrom src; /**< used when type = e_FM_PCD_KG_EXTRACT_NON_HDR */
82049 + };
82050 + uint8_t extractionOffset; /**< Offset for extraction (in bytes). */
82051 + e_FmPcdKgExtractDfltSelect dfltValue; /**< Select register from which extraction is taken if
82052 + field not found */
82053 + uint8_t mask; /**< Extraction mask (specified bits are used) */
82054 + uint8_t bitOffsetInFqid; /**< 0-31, Selects which bits of the 24 FQID bits to effect using
82055 + the extracted byte; Assume byte is placed as the 8 MSB's in
82056 + a 32 bit word where the lower bits
82057 + are the FQID; i.e if bitOffsetInFqid=1 than its LSB
82058 + will effect the FQID MSB, if bitOffsetInFqid=24 than the
82059 + extracted byte will effect the 8 LSB's of the FQID,
82060 + if bitOffsetInFqid=31 than the byte's MSB will effect
82061 + the FQID's LSB; 0 means - no effect on FQID;
82062 + Note that one, and only one of
82063 + bitOffsetInFqid or bitOffsetInPlcrProfile must be set (i.e,
82064 + extracted byte must effect either FQID or Policer profile).*/
82065 + uint8_t bitOffsetInPlcrProfile;
82066 + /**< 0-15, Selects which bits of the 8 policer profile id bits to
82067 + effect using the extracted byte; Assume byte is placed
82068 + as the 8 MSB's in a 16 bit word where the lower bits
82069 + are the policer profile id; i.e if bitOffsetInPlcrProfile=1
82070 + than its LSB will effect the profile MSB, if bitOffsetInFqid=8
82071 + than the extracted byte will effect the whole policer profile id,
82072 + if bitOffsetInFqid=15 than the byte's MSB will effect
82073 + the Policer Profile id's LSB;
82074 + 0 means - no effect on policer profile; Note that one, and only one of
82075 + bitOffsetInFqid or bitOffsetInPlcrProfile must be set (i.e,
82076 + extracted byte must effect either FQID or Policer profile).*/
82077 +} t_FmPcdKgExtractedOrParams;
82078 +
82079 +/**************************************************************************//**
82080 + @Description Parameters for configuring a scheme counter
82081 +*//***************************************************************************/
82082 +typedef struct t_FmPcdKgSchemeCounter {
82083 + bool update; /**< FALSE to keep the current counter state
82084 + and continue from that point, TRUE to update/reset
82085 + the counter when the scheme is written. */
82086 + uint32_t value; /**< If update=TRUE, this value will be written into the
82087 + counter. clear this field to reset the counter. */
82088 +} t_FmPcdKgSchemeCounter;
82089 +
82090 +/**************************************************************************//**
82091 + @Description Parameters for configuring a policer profile for a KeyGen scheme
82092 + (when policer is the next engine after this scheme).
82093 +*//***************************************************************************/
82094 +typedef struct t_FmPcdKgPlcrProfile {
82095 + bool sharedProfile; /**< TRUE if this profile is shared between ports
82096 + (managed by master partition); Must not be TRUE
82097 + if profile is after Coarse Classification*/
82098 + bool direct; /**< if TRUE, directRelativeProfileId only selects the profile
82099 + id, if FALSE fqidOffsetRelativeProfileIdBase is used
82100 + together with fqidOffsetShift and numOfProfiles
82101 + parameters, to define a range of profiles from
82102 + which the KeyGen result will determine the
82103 + destination policer profile. */
82104 + union {
82105 + uint16_t directRelativeProfileId; /**< Used if 'direct' is TRUE, to select policer profile.
82106 + should indicate the policer profile offset within the
82107 + port's policer profiles or shared window. */
82108 + struct {
82109 + uint8_t fqidOffsetShift; /**< Shift on the KeyGen create FQID offset (i.e. not the
82110 + final FQID - without the FQID base). */
82111 + uint8_t fqidOffsetRelativeProfileIdBase;
82112 + /**< The base of the FMan Port's relative Storage-Profile ID;
82113 + this value will be "OR'ed" with the KeyGen create FQID
82114 + offset (i.e. not the final FQID - without the FQID base);
82115 + the final result should indicate the Storage-Profile offset
82116 + within the FMan Port's relative Storage-Profiles window/
82117 + (or the SHARED window depends on 'sharedProfile'). */
82118 + uint8_t numOfProfiles; /**< Range of profiles starting at base */
82119 + } indirectProfile; /**< Indirect profile parameters */
82120 + } profileSelect; /**< Direct/indirect profile selection and parameters */
82121 +} t_FmPcdKgPlcrProfile;
82122 +
82123 +#if (DPAA_VERSION >= 11)
82124 +/**************************************************************************//**
82125 + @Description Parameters for configuring a storage profile for a KeyGen scheme.
82126 +*//***************************************************************************/
82127 +typedef struct t_FmPcdKgStorageProfile {
82128 + bool direct; /**< If TRUE, directRelativeProfileId only selects the
82129 + profile id;
82130 + If FALSE, fqidOffsetRelativeProfileIdBase is used
82131 + together with fqidOffsetShift and numOfProfiles
82132 + parameters to define a range of profiles from which
82133 + the KeyGen result will determine the destination
82134 + storage profile. */
82135 + union {
82136 + uint16_t directRelativeProfileId; /**< Used when 'direct' is TRUE, to select a storage profile;
82137 + should indicate the storage profile offset within the
82138 + port's storage profiles window. */
82139 + struct {
82140 + uint8_t fqidOffsetShift; /**< Shift on the KeyGen create FQID offset (i.e. not the
82141 + final FQID - without the FQID base). */
82142 + uint8_t fqidOffsetRelativeProfileIdBase;
82143 + /**< The base of the FMan Port's relative Storage-Profile ID;
82144 + this value will be "OR'ed" with the KeyGen create FQID
82145 + offset (i.e. not the final FQID - without the FQID base);
82146 + the final result should indicate the Storage-Profile offset
82147 + within the FMan Port's relative Storage-Profiles window. */
82148 + uint8_t numOfProfiles; /**< Range of profiles starting at base. */
82149 + } indirectProfile; /**< Indirect profile parameters. */
82150 + } profileSelect; /**< Direct/indirect profile selection and parameters. */
82151 +} t_FmPcdKgStorageProfile;
82152 +#endif /* (DPAA_VERSION >= 11) */
82153 +
82154 +/**************************************************************************//**
82155 + @Description Parameters for defining CC as the next engine after KeyGen
82156 +*//***************************************************************************/
82157 +typedef struct t_FmPcdKgCc {
82158 + t_Handle h_CcTree; /**< A handle to a CC Tree */
82159 + uint8_t grpId; /**< CC group id within the CC tree */
82160 + bool plcrNext; /**< TRUE if after CC, in case of data frame,
82161 + policing is required. */
82162 + bool bypassPlcrProfileGeneration; /**< TRUE to bypass KeyGen policer profile generation;
82163 + selected profile is the one set at port initialization. */
82164 + t_FmPcdKgPlcrProfile plcrProfile; /**< Valid only if plcrNext = TRUE and
82165 + bypassPlcrProfileGeneration = FALSE */
82166 +} t_FmPcdKgCc;
82167 +
82168 +/**************************************************************************//**
82169 + @Description Parameters for defining initializing a KeyGen scheme
82170 +*//***************************************************************************/
82171 +typedef struct t_FmPcdKgSchemeParams {
82172 + bool modify; /**< TRUE to change an existing scheme */
82173 + union
82174 + {
82175 + uint8_t relativeSchemeId; /**< if modify=FALSE:Partition relative scheme id */
82176 + t_Handle h_Scheme; /**< if modify=TRUE: a handle of the existing scheme */
82177 + } id;
82178 + bool alwaysDirect; /**< This scheme is reached only directly, i.e. no need
82179 + for match vector; KeyGen will ignore it when matching */
82180 + struct { /**< HL Relevant only if alwaysDirect = FALSE */
82181 + t_Handle h_NetEnv; /**< A handle to the Network environment as returned
82182 + by FM_PCD_NetEnvCharacteristicsSet() */
82183 + uint8_t numOfDistinctionUnits; /**< Number of NetEnv units listed in unitIds array */
82184 + uint8_t unitIds[FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS];
82185 + /**< Indexes as passed to SetNetEnvCharacteristics array*/
82186 + } netEnvParams;
82187 + bool useHash; /**< use the KeyGen Hash functionality */
82188 + t_FmPcdKgKeyExtractAndHashParams keyExtractAndHashParams;
82189 + /**< used only if useHash = TRUE */
82190 + bool bypassFqidGeneration; /**< Normally - FALSE, TRUE to avoid FQID update in the IC;
82191 + In such a case FQID after KeyGen will be the default FQID
82192 + defined for the relevant port, or the FQID defined by CC
82193 + in cases where CC was the previous engine. */
82194 + uint32_t baseFqid; /**< Base FQID; Relevant only if bypassFqidGeneration = FALSE;
82195 + If hash is used and an even distribution is expected
82196 + according to hashDistributionNumOfFqids, baseFqid must be aligned to
82197 + hashDistributionNumOfFqids. */
82198 + uint8_t numOfUsedExtractedOrs; /**< Number of FQID masks listed in extractedOrs array */
82199 + t_FmPcdKgExtractedOrParams extractedOrs[FM_PCD_KG_NUM_OF_GENERIC_REGS];
82200 + /**< FM_PCD_KG_NUM_OF_GENERIC_REGS
82201 + registers are shared between qidMasks
82202 + functionality and some of the extraction
82203 + actions; Normally only some will be used
82204 + for qidMask. Driver will return error if
82205 + resource is full at initialization time. */
82206 +
82207 +#if (DPAA_VERSION >= 11)
82208 + bool overrideStorageProfile; /**< TRUE if KeyGen override previously decided storage profile */
82209 + t_FmPcdKgStorageProfile storageProfile; /**< Used when overrideStorageProfile TRUE */
82210 +#endif /* (DPAA_VERSION >= 11) */
82211 +
82212 + e_FmPcdEngine nextEngine; /**< may be BMI, PLCR or CC */
82213 + union { /**< depends on nextEngine */
82214 + e_FmPcdDoneAction doneAction; /**< Used when next engine is BMI (done) */
82215 + t_FmPcdKgPlcrProfile plcrProfile; /**< Used when next engine is PLCR */
82216 + t_FmPcdKgCc cc; /**< Used when next engine is CC */
82217 + } kgNextEngineParams;
82218 + t_FmPcdKgSchemeCounter schemeCounter; /**< A structure of parameters for updating
82219 + the scheme counter */
82220 +} t_FmPcdKgSchemeParams;
82221 +
82222 +/**************************************************************************//**
82223 + @Collection Definitions for CC statistics
82224 +*//***************************************************************************/
82225 +#if (DPAA_VERSION >= 11)
82226 +#define FM_PCD_CC_STATS_MAX_NUM_OF_FLR 10 /* Maximal supported number of frame length ranges */
82227 +#define FM_PCD_CC_STATS_FLR_SIZE 2 /* Size in bytes of a frame length range limit */
82228 +#endif /* (DPAA_VERSION >= 11) */
82229 +#define FM_PCD_CC_STATS_COUNTER_SIZE 4 /* Size in bytes of a frame length range counter */
82230 +/* @} */
82231 +
82232 +/**************************************************************************//**
82233 + @Description Parameters for defining CC as the next engine after a CC node.
82234 +*//***************************************************************************/
82235 +typedef struct t_FmPcdCcNextCcParams {
82236 + t_Handle h_CcNode; /**< A handle of the next CC node */
82237 +} t_FmPcdCcNextCcParams;
82238 +
82239 +#if (DPAA_VERSION >= 11)
82240 +/**************************************************************************//**
82241 + @Description Parameters for defining Frame replicator as the next engine after a CC node.
82242 +*//***************************************************************************/
82243 +typedef struct t_FmPcdCcNextFrParams {
82244 + t_Handle h_FrmReplic; /**< A handle of the next frame replicator group */
82245 +} t_FmPcdCcNextFrParams;
82246 +#endif /* (DPAA_VERSION >= 11) */
82247 +
82248 +/**************************************************************************//**
82249 + @Description Parameters for defining Policer as the next engine after a CC node.
82250 +*//***************************************************************************/
82251 +typedef struct t_FmPcdCcNextPlcrParams {
82252 + bool overrideParams; /**< TRUE if CC override previously decided parameters*/
82253 + bool sharedProfile; /**< Relevant only if overrideParams=TRUE:
82254 + TRUE if this profile is shared between ports */
82255 + uint16_t newRelativeProfileId; /**< Relevant only if overrideParams=TRUE:
82256 + (otherwise profile id is taken from KeyGen);
82257 + This parameter should indicate the policer
82258 + profile offset within the port's
82259 + policer profiles or from SHARED window.*/
82260 + uint32_t newFqid; /**< Relevant only if overrideParams=TRUE:
82261 + FQID for enqueuing the frame;
82262 + In earlier chips if policer next engine is KEYGEN,
82263 + this parameter can be 0, because the KEYGEN
82264 + always decides the enqueue FQID.*/
82265 +#if (DPAA_VERSION >= 11)
82266 + uint8_t newRelativeStorageProfileId;
82267 + /**< Indicates the relative storage profile offset within
82268 + the port's storage profiles window;
82269 + Relevant only if the port was configured with VSP. */
82270 +#endif /* (DPAA_VERSION >= 11) */
82271 +} t_FmPcdCcNextPlcrParams;
82272 +
82273 +/**************************************************************************//**
82274 + @Description Parameters for defining enqueue as the next action after a CC node.
82275 +*//***************************************************************************/
82276 +typedef struct t_FmPcdCcNextEnqueueParams {
82277 + e_FmPcdDoneAction action; /**< Action - when next engine is BMI (done) */
82278 + bool overrideFqid; /**< TRUE if CC override previously decided fqid and vspid,
82279 + relevant if action = e_FM_PCD_ENQ_FRAME */
82280 + uint32_t newFqid; /**< Valid if overrideFqid=TRUE, FQID for enqueuing the frame
82281 + (otherwise FQID is taken from KeyGen),
82282 + relevant if action = e_FM_PCD_ENQ_FRAME */
82283 +#if (DPAA_VERSION >= 11)
82284 + uint8_t newRelativeStorageProfileId;
82285 + /**< Valid if overrideFqid=TRUE, Indicates the relative virtual
82286 + storage profile offset within the port's storage profiles
82287 + window; Relevant only if the port was configured with VSP. */
82288 +#endif /* (DPAA_VERSION >= 11) */
82289 +} t_FmPcdCcNextEnqueueParams;
82290 +
82291 +/**************************************************************************//**
82292 + @Description Parameters for defining KeyGen as the next engine after a CC node.
82293 +*//***************************************************************************/
82294 +typedef struct t_FmPcdCcNextKgParams {
82295 + bool overrideFqid; /**< TRUE if CC override previously decided fqid and vspid,
82296 + Note - this parameters irrelevant for earlier chips */
82297 + uint32_t newFqid; /**< Valid if overrideFqid=TRUE, FQID for enqueuing the frame
82298 + (otherwise FQID is taken from KeyGen),
82299 + Note - this parameters irrelevant for earlier chips */
82300 +#if (DPAA_VERSION >= 11)
82301 + uint8_t newRelativeStorageProfileId;
82302 + /**< Valid if overrideFqid=TRUE, Indicates the relative virtual
82303 + storage profile offset within the port's storage profiles
82304 + window; Relevant only if the port was configured with VSP. */
82305 +#endif /* (DPAA_VERSION >= 11) */
82306 +
82307 + t_Handle h_DirectScheme; /**< Direct scheme handle to go to. */
82308 +} t_FmPcdCcNextKgParams;
82309 +
82310 +/**************************************************************************//**
82311 + @Description Parameters for defining the next engine after a CC node.
82312 +*//***************************************************************************/
82313 +typedef struct t_FmPcdCcNextEngineParams {
82314 + e_FmPcdEngine nextEngine; /**< User has to initialize parameters
82315 + according to nextEngine definition */
82316 + union {
82317 + t_FmPcdCcNextCcParams ccParams; /**< Parameters in case next engine is CC */
82318 + t_FmPcdCcNextPlcrParams plcrParams; /**< Parameters in case next engine is PLCR */
82319 + t_FmPcdCcNextEnqueueParams enqueueParams; /**< Parameters in case next engine is BMI */
82320 + t_FmPcdCcNextKgParams kgParams; /**< Parameters in case next engine is KG */
82321 +#if (DPAA_VERSION >= 11)
82322 + t_FmPcdCcNextFrParams frParams; /**< Parameters in case next engine is FR */
82323 +#endif /* (DPAA_VERSION >= 11) */
82324 + } params; /**< union used for all the next-engine parameters options */
82325 +
82326 + t_Handle h_Manip; /**< Handle to Manipulation object.
82327 + Relevant if next engine is of type result
82328 + (e_FM_PCD_PLCR, e_FM_PCD_KG, e_FM_PCD_DONE) */
82329 +
82330 + bool statisticsEn; /**< If TRUE, statistics counters are incremented
82331 + for each frame passing through this
82332 + Coarse Classification entry. */
82333 +} t_FmPcdCcNextEngineParams;
82334 +
82335 +/**************************************************************************//**
82336 + @Description Parameters for defining a single CC key
82337 +*//***************************************************************************/
82338 +typedef struct t_FmPcdCcKeyParams {
82339 + uint8_t *p_Key; /**< Relevant only if 'action' = e_FM_PCD_ACTION_EXACT_MATCH;
82340 + pointer to the key of the size defined in keySize */
82341 + uint8_t *p_Mask; /**< Relevant only if 'action' = e_FM_PCD_ACTION_EXACT_MATCH;
82342 + pointer to the Mask per key of the size defined
82343 + in keySize. p_Key and p_Mask (if defined) has to be
82344 + of the same size defined in the keySize;
82345 + NOTE that if this value is equal for all entries whithin
82346 + this table, the driver will automatically use global-mask
82347 + (i.e. one common mask for all entries) instead of private
82348 + one; that is done in order to spare some memory and for
82349 + better performance. */
82350 + t_FmPcdCcNextEngineParams ccNextEngineParams;
82351 + /**< parameters for the next for the defined Key in
82352 + the p_Key */
82353 +} t_FmPcdCcKeyParams;
82354 +
82355 +/**************************************************************************//**
82356 + @Description Parameters for defining CC keys parameters
82357 + The driver supports two methods for CC node allocation: dynamic and static.
82358 + Static mode was created in order to prevent runtime alloc/free
82359 + of FMan memory (MURAM), which may cause fragmentation; in this mode,
82360 + the driver automatically allocates the memory according to
82361 + 'maxNumOfKeys' parameter. The driver calculates the maximal memory
82362 + size that may be used for this CC-Node taking into consideration
82363 + 'maskSupport' and 'statisticsMode' parameters.
82364 + When 'action' = e_FM_PCD_ACTION_INDEXED_LOOKUP in the extraction
82365 + parameters of this node, 'maxNumOfKeys' must be equal to 'numOfKeys'.
82366 + In dynamic mode, 'maxNumOfKeys' must be zero. At initialization,
82367 + all required structures are allocated according to 'numOfKeys'
82368 + parameter. During runtime modification, these structures are
82369 + re-allocated according to the updated number of keys.
82370 +
82371 + Please note that 'action' and 'icIndxMask' mentioned in the
82372 + specific parameter explanations are passed in the extraction
82373 + parameters of the node (fields of extractCcParams.extractNonHdr).
82374 +*//***************************************************************************/
82375 +typedef struct t_KeysParams {
82376 + uint16_t maxNumOfKeys; /**< Maximum number of keys that will (ever) be used in this CC-Node;
82377 + A value of zero may be used for dynamic memory allocation. */
82378 + bool maskSupport; /**< This parameter is relevant only if a node is initialized with
82379 + 'action' = e_FM_PCD_ACTION_EXACT_MATCH and maxNumOfKeys > 0;
82380 + Should be TRUE to reserve table memory for key masks, even if
82381 + initial keys do not contain masks, or if the node was initialized
82382 + as 'empty' (without keys); this will allow user to add keys with
82383 + masks at runtime.
82384 + NOTE that if user want to use only global-masks (i.e. one common mask
82385 + for all the entries within this table, this parameter should set to 'FALSE'. */
82386 + e_FmPcdCcStatsMode statisticsMode; /**< Determines the supported statistics mode for all node's keys.
82387 + To enable statistics gathering, statistics should be enabled per
82388 + every key, using 'statisticsEn' in next engine parameters structure
82389 + of that key;
82390 + If 'maxNumOfKeys' is set, all required structures will be
82391 + preallocated for all keys. */
82392 +#if (DPAA_VERSION >= 11)
82393 + uint16_t frameLengthRanges[FM_PCD_CC_STATS_MAX_NUM_OF_FLR];
82394 + /**< Relevant only for 'RMON' statistics mode
82395 + (this feature is supported only on B4860 device);
82396 + Holds a list of programmable thresholds - for each received frame,
82397 + its length in bytes is examined against these range thresholds and
82398 + the appropriate counter is incremented by 1 - for example, to belong
82399 + to range i, the following should hold:
82400 + range i-1 threshold < frame length <= range i threshold
82401 + Each range threshold must be larger then its preceding range
82402 + threshold, and last range threshold must be 0xFFFF. */
82403 +#endif /* (DPAA_VERSION >= 11) */
82404 + uint16_t numOfKeys; /**< Number of initial keys;
82405 + Note that in case of 'action' = e_FM_PCD_ACTION_INDEXED_LOOKUP,
82406 + this field should be power-of-2 of the number of bits that are
82407 + set in 'icIndxMask'. */
82408 + uint8_t keySize; /**< Size of key - for extraction of type FULL_FIELD, 'keySize' has
82409 + to be the standard size of the selected key; For other extraction
82410 + types, 'keySize' has to be as size of extraction; When 'action' =
82411 + e_FM_PCD_ACTION_INDEXED_LOOKUP, 'keySize' must be 2. */
82412 + t_FmPcdCcKeyParams keyParams[FM_PCD_MAX_NUM_OF_KEYS];
82413 + /**< An array with 'numOfKeys' entries, each entry specifies the
82414 + corresponding key parameters;
82415 + When 'action' = e_FM_PCD_ACTION_EXACT_MATCH, this value must not
82416 + exceed 255 (FM_PCD_MAX_NUM_OF_KEYS-1) as the last entry is saved
82417 + for the 'miss' entry. */
82418 + t_FmPcdCcNextEngineParams ccNextEngineParamsForMiss;
82419 + /**< Parameters for defining the next engine when a key is not matched;
82420 + Not relevant if action = e_FM_PCD_ACTION_INDEXED_LOOKUP. */
82421 +} t_KeysParams;
82422 +
82423 +
82424 +/**************************************************************************//**
82425 + @Description Parameters for defining a CC node
82426 +*//***************************************************************************/
82427 +typedef struct t_FmPcdCcNodeParams {
82428 + t_FmPcdExtractEntry extractCcParams; /**< Extraction parameters */
82429 + t_KeysParams keysParams; /**< Keys definition matching the selected extraction */
82430 +} t_FmPcdCcNodeParams;
82431 +
82432 +/**************************************************************************//**
82433 + @Description Parameters for defining a hash table
82434 +*//***************************************************************************/
82435 +typedef struct t_FmPcdHashTableParams {
82436 + uint16_t maxNumOfKeys; /**< Maximum Number Of Keys that will (ever) be used in this Hash-table */
82437 + e_FmPcdCcStatsMode statisticsMode; /**< If not e_FM_PCD_CC_STATS_MODE_NONE, the required structures for the
82438 + requested statistics mode will be allocated according to maxNumOfKeys. */
82439 + uint8_t kgHashShift; /**< KG-Hash-shift as it was configured in the KG-scheme
82440 + that leads to this hash-table. */
82441 + uint16_t hashResMask; /**< Mask that will be used on the hash-result;
82442 + The number-of-sets for this hash will be calculated
82443 + as (2^(number of bits set in 'hashResMask'));
82444 + The 4 lower bits must be cleared. */
82445 + uint8_t hashShift; /**< Byte offset from the beginning of the KeyGen hash result to the
82446 + 2-bytes to be used as hash index. */
82447 + uint8_t matchKeySize; /**< Size of the exact match keys held by the hash buckets */
82448 +
82449 + t_FmPcdCcNextEngineParams ccNextEngineParamsForMiss; /**< Parameters for defining the next engine when a key is not matched */
82450 +
82451 +} t_FmPcdHashTableParams;
82452 +
82453 +/**************************************************************************//**
82454 + @Description Parameters for defining a CC tree group.
82455 +
82456 + This structure defines a CC group in terms of NetEnv units
82457 + and the action to be taken in each case. The unitIds list must
82458 + be given in order from low to high indices.
82459 +
82460 + t_FmPcdCcNextEngineParams is a list of 2^numOfDistinctionUnits
82461 + structures where each defines the next action to be taken for
82462 + each units combination. for example:
82463 + numOfDistinctionUnits = 2
82464 + unitIds = {1,3}
82465 + p_NextEnginePerEntriesInGrp[0] = t_FmPcdCcNextEngineParams for the case that
82466 + unit 1 - not found; unit 3 - not found;
82467 + p_NextEnginePerEntriesInGrp[1] = t_FmPcdCcNextEngineParams for the case that
82468 + unit 1 - not found; unit 3 - found;
82469 + p_NextEnginePerEntriesInGrp[2] = t_FmPcdCcNextEngineParams for the case that
82470 + unit 1 - found; unit 3 - not found;
82471 + p_NextEnginePerEntriesInGrp[3] = t_FmPcdCcNextEngineParams for the case that
82472 + unit 1 - found; unit 3 - found;
82473 +*//***************************************************************************/
82474 +typedef struct t_FmPcdCcGrpParams {
82475 + uint8_t numOfDistinctionUnits; /**< Up to 4 */
82476 + uint8_t unitIds[FM_PCD_MAX_NUM_OF_CC_UNITS];
82477 + /**< Indices of the units as defined in
82478 + FM_PCD_NetEnvCharacteristicsSet() */
82479 + t_FmPcdCcNextEngineParams nextEnginePerEntriesInGrp[FM_PCD_MAX_NUM_OF_CC_ENTRIES_IN_GRP];
82480 + /**< Maximum entries per group is 16 */
82481 +} t_FmPcdCcGrpParams;
82482 +
82483 +/**************************************************************************//**
82484 + @Description Parameters for defining CC tree groups
82485 +*//***************************************************************************/
82486 +typedef struct t_FmPcdCcTreeParams {
82487 + t_Handle h_NetEnv; /**< A handle to the Network environment as returned
82488 + by FM_PCD_NetEnvCharacteristicsSet() */
82489 + uint8_t numOfGrps; /**< Number of CC groups within the CC tree */
82490 + t_FmPcdCcGrpParams ccGrpParams[FM_PCD_MAX_NUM_OF_CC_GROUPS];
82491 + /**< Parameters for each group. */
82492 +} t_FmPcdCcTreeParams;
82493 +
82494 +
82495 +/**************************************************************************//**
82496 + @Description CC key statistics structure
82497 +*//***************************************************************************/
82498 +typedef struct t_FmPcdCcKeyStatistics {
82499 + uint32_t byteCount; /**< This counter reflects byte count of frames that
82500 + were matched by this key. */
82501 + uint32_t frameCount; /**< This counter reflects count of frames that
82502 + were matched by this key. */
82503 +#if (DPAA_VERSION >= 11)
82504 + uint32_t frameLengthRangeCount[FM_PCD_CC_STATS_MAX_NUM_OF_FLR];
82505 + /**< These counters reflect how many frames matched
82506 + this key in 'RMON' statistics mode:
82507 + Each counter holds the number of frames of a
82508 + specific frames length range, according to the
82509 + ranges provided at initialization. */
82510 +#endif /* (DPAA_VERSION >= 11) */
82511 +} t_FmPcdCcKeyStatistics;
82512 +
82513 +/**************************************************************************//**
82514 + @Description Parameters for defining policer byte rate
82515 +*//***************************************************************************/
82516 +typedef struct t_FmPcdPlcrByteRateModeParams {
82517 + e_FmPcdPlcrFrameLengthSelect frameLengthSelection; /**< Frame length selection */
82518 + e_FmPcdPlcrRollBackFrameSelect rollBackFrameSelection; /**< relevant option only e_FM_PCD_PLCR_L2_FRM_LEN,
82519 + e_FM_PCD_PLCR_FULL_FRM_LEN */
82520 +} t_FmPcdPlcrByteRateModeParams;
82521 +
82522 +/**************************************************************************//**
82523 + @Description Parameters for defining the policer profile (based on
82524 + RFC-2698 or RFC-4115 attributes).
82525 +*//***************************************************************************/
82526 +typedef struct t_FmPcdPlcrNonPassthroughAlgParams {
82527 + e_FmPcdPlcrRateMode rateMode; /**< Byte mode or Packet mode */
82528 + t_FmPcdPlcrByteRateModeParams byteModeParams; /**< Valid for Byte NULL for Packet */
82529 + uint32_t committedInfoRate; /**< KBits/Second or Packets/Second */
82530 + uint32_t committedBurstSize; /**< Bytes/Packets */
82531 + uint32_t peakOrExcessInfoRate; /**< KBits/Second or Packets/Second */
82532 + uint32_t peakOrExcessBurstSize; /**< Bytes/Packets */
82533 +} t_FmPcdPlcrNonPassthroughAlgParams;
82534 +
82535 +/**************************************************************************//**
82536 + @Description Parameters for defining the next engine after policer
82537 +*//***************************************************************************/
82538 +typedef union u_FmPcdPlcrNextEngineParams {
82539 + e_FmPcdDoneAction action; /**< Action - when next engine is BMI (done) */
82540 + t_Handle h_Profile; /**< Policer profile handle - used when next engine
82541 + is Policer, must be a SHARED profile */
82542 + t_Handle h_DirectScheme; /**< Direct scheme select - when next engine is KeyGen */
82543 +} u_FmPcdPlcrNextEngineParams;
82544 +
82545 +/**************************************************************************//**
82546 + @Description Parameters for defining the policer profile entry
82547 +*//***************************************************************************/
82548 +typedef struct t_FmPcdPlcrProfileParams {
82549 + bool modify; /**< TRUE to change an existing profile */
82550 + union {
82551 + struct {
82552 + e_FmPcdProfileTypeSelection profileType; /**< Type of policer profile */
82553 + t_Handle h_FmPort; /**< Relevant for per-port profiles only */
82554 + uint16_t relativeProfileId; /**< Profile id - relative to shared group or to port */
82555 + } newParams; /**< use it when modify = FALSE */
82556 + t_Handle h_Profile; /**< A handle to a profile - use it when modify=TRUE */
82557 + } id;
82558 + e_FmPcdPlcrAlgorithmSelection algSelection; /**< Profile Algorithm PASS_THROUGH, RFC_2698, RFC_4115 */
82559 + e_FmPcdPlcrColorMode colorMode; /**< COLOR_BLIND, COLOR_AWARE */
82560 +
82561 + union {
82562 + e_FmPcdPlcrColor dfltColor; /**< For Color-Blind Pass-Through mode; the policer will re-color
82563 + any incoming packet with the default value. */
82564 + e_FmPcdPlcrColor override; /**< For Color-Aware modes; the profile response to a
82565 + pre-color value of 2'b11. */
82566 + } color;
82567 +
82568 + t_FmPcdPlcrNonPassthroughAlgParams nonPassthroughAlgParams; /**< RFC2698 or RFC4115 parameters */
82569 +
82570 + e_FmPcdEngine nextEngineOnGreen; /**< Next engine for green-colored frames */
82571 + u_FmPcdPlcrNextEngineParams paramsOnGreen; /**< Next engine parameters for green-colored frames */
82572 +
82573 + e_FmPcdEngine nextEngineOnYellow; /**< Next engine for yellow-colored frames */
82574 + u_FmPcdPlcrNextEngineParams paramsOnYellow; /**< Next engine parameters for yellow-colored frames */
82575 +
82576 + e_FmPcdEngine nextEngineOnRed; /**< Next engine for red-colored frames */
82577 + u_FmPcdPlcrNextEngineParams paramsOnRed; /**< Next engine parameters for red-colored frames */
82578 +
82579 + bool trapProfileOnFlowA; /**< Obsolete - do not use */
82580 + bool trapProfileOnFlowB; /**< Obsolete - do not use */
82581 + bool trapProfileOnFlowC; /**< Obsolete - do not use */
82582 +} t_FmPcdPlcrProfileParams;
82583 +
82584 +/**************************************************************************//**
82585 + @Description Parameters for selecting a location for requested manipulation
82586 +*//***************************************************************************/
82587 +typedef struct t_FmManipHdrInfo {
82588 + e_NetHeaderType hdr; /**< Header selection */
82589 + e_FmPcdHdrIndex hdrIndex; /**< Relevant only for MPLS, VLAN and tunneled IP. Otherwise should be cleared. */
82590 + bool byField; /**< TRUE if the location of manipulation is according to some field in the specific header*/
82591 + t_FmPcdFields fullField; /**< Relevant only when byField = TRUE: Extract field */
82592 +} t_FmManipHdrInfo;
82593 +
82594 +#if ((DPAA_VERSION == 10) && defined(FM_CAPWAP_SUPPORT))
82595 +/**************************************************************************//**
82596 + @Description Parameters for defining an insertion manipulation
82597 + of type e_FM_PCD_MANIP_INSRT_TO_START_OF_FRAME_TEMPLATE
82598 +*//***************************************************************************/
82599 +typedef struct t_FmPcdManipHdrInsrtByTemplateParams {
82600 + uint8_t size; /**< Size of insert template to the start of the frame. */
82601 + uint8_t hdrTemplate[FM_PCD_MAX_MANIP_INSRT_TEMPLATE_SIZE];
82602 + /**< Array of the insertion template. */
82603 +
82604 + bool modifyOuterIp; /**< TRUE if user want to modify some fields in outer IP. */
82605 + struct {
82606 + uint16_t ipOuterOffset; /**< Offset of outer IP in the insert template, relevant if modifyOuterIp = TRUE.*/
82607 + uint16_t dscpEcn; /**< value of dscpEcn in IP outer, relevant if modifyOuterIp = TRUE.
82608 + in IPV4 dscpEcn only byte - it has to be adjusted to the right*/
82609 + bool udpPresent; /**< TRUE if UDP is present in the insert template, relevant if modifyOuterIp = TRUE.*/
82610 + uint8_t udpOffset; /**< Offset in the insert template of UDP, relevant if modifyOuterIp = TRUE and udpPresent=TRUE.*/
82611 + uint8_t ipIdentGenId; /**< Used by FMan-CTRL to calculate IP-identification field,relevant if modifyOuterIp = TRUE.*/
82612 + 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.*/
82613 + struct {
82614 + uint8_t blockSize; /**< The CAAM block-size; Used by FMan-CTRL to calculate the IP Total Length field.*/
82615 + uint8_t extraBytesAddedAlignedToBlockSize; /**< Used by FMan-CTRL to calculate the IP Total Length field and UDP length*/
82616 + uint8_t extraBytesAddedNotAlignedToBlockSize;/**< Used by FMan-CTRL to calculate the IP Total Length field and UDP length.*/
82617 + } recalculateLengthParams; /**< Recalculate length parameters - relevant if modifyOuterIp = TRUE and recalculateLength = TRUE */
82618 + } modifyOuterIpParams; /**< Outer IP modification parameters - ignored if modifyOuterIp is FALSE */
82619 +
82620 + bool modifyOuterVlan; /**< TRUE if user wants to modify VPri field in the outer VLAN header*/
82621 + struct {
82622 + uint8_t vpri; /**< Value of VPri, relevant if modifyOuterVlan = TRUE
82623 + VPri only 3 bits, it has to be adjusted to the right*/
82624 + } modifyOuterVlanParams;
82625 +} t_FmPcdManipHdrInsrtByTemplateParams;
82626 +
82627 +/**************************************************************************//**
82628 + @Description Parameters for defining CAPWAP fragmentation
82629 +*//***************************************************************************/
82630 +typedef struct t_CapwapFragmentationParams {
82631 + uint16_t sizeForFragmentation; /**< if length of the frame is greater than this value, CAPWAP fragmentation will be executed.*/
82632 + bool headerOptionsCompr; /**< TRUE - first fragment include the CAPWAP header options field,
82633 + and all other fragments exclude the CAPWAP options field,
82634 + FALSE - all fragments include CAPWAP header options field. */
82635 +} t_CapwapFragmentationParams;
82636 +
82637 +/**************************************************************************//**
82638 + @Description Parameters for defining CAPWAP reassembly
82639 +*//***************************************************************************/
82640 +typedef struct t_CapwapReassemblyParams {
82641 + uint16_t maxNumFramesInProcess; /**< Number of frames which can be reassembled concurrently; must be power of 2.
82642 + In case numOfFramesPerHashEntry == e_FM_PCD_MANIP_FOUR_WAYS_HASH,
82643 + maxNumFramesInProcess has to be in the range of 4 - 512,
82644 + In case numOfFramesPerHashEntry == e_FM_PCD_MANIP_EIGHT_WAYS_HASH,
82645 + maxNumFramesInProcess has to be in the range of 8 - 2048 */
82646 + bool haltOnDuplicationFrag; /**< If TRUE, reassembly process will be halted due to duplicated fragment,
82647 + and all processed fragments will be enqueued with error indication;
82648 + If FALSE, only duplicated fragments will be enqueued with error indication. */
82649 +
82650 + e_FmPcdManipReassemTimeOutMode timeOutMode; /**< Expiration delay initialized by the reassembly process */
82651 + uint32_t fqidForTimeOutFrames; /**< FQID in which time out frames will enqueue during Time Out Process */
82652 + uint32_t timeoutRoutineRequestTime;
82653 + /**< Represents the time interval in microseconds between consecutive
82654 + timeout routine requests It has to be power of 2. */
82655 + uint32_t timeoutThresholdForReassmProcess;
82656 + /**< Time interval (microseconds) for marking frames in process as too old;
82657 + Frames in process are those for which at least one fragment was received
82658 + but not all fragments. */
82659 +
82660 + e_FmPcdManipReassemWaysNumber numOfFramesPerHashEntry;/**< Number of frames per hash entry (needed for the reassembly process) */
82661 +} t_CapwapReassemblyParams;
82662 +
82663 +/**************************************************************************//**
82664 + @Description Parameters for defining fragmentation/reassembly manipulation
82665 +*//***************************************************************************/
82666 +typedef struct t_FmPcdManipFragOrReasmParams {
82667 + bool frag; /**< TRUE if using the structure for fragmentation,
82668 + otherwise this structure is used for reassembly */
82669 + uint8_t sgBpid; /**< Scatter/Gather buffer pool id;
82670 + Same LIODN number is used for these buffers as for
82671 + the received frames buffers, so buffers of this pool
82672 + need to be allocated in the same memory area as the
82673 + received buffers. If the received buffers arrive
82674 + from different sources, the Scatter/Gather BP id
82675 + should be mutual to all these sources. */
82676 + e_NetHeaderType hdr; /**< Header selection */
82677 + union {
82678 + t_CapwapFragmentationParams capwapFragParams; /**< Structure for CAPWAP fragmentation,
82679 + relevant if 'frag' = TRUE, 'hdr' = HEADER_TYPE_CAPWAP */
82680 + t_CapwapReassemblyParams capwapReasmParams; /**< Structure for CAPWAP reassembly,
82681 + relevant if 'frag' = FALSE, 'hdr' = HEADER_TYPE_CAPWAP */
82682 + } u;
82683 +} t_FmPcdManipFragOrReasmParams;
82684 +#endif /* ((DPAA_VERSION == 10) && defined(FM_CAPWAP_SUPPORT)) */
82685 +
82686 +
82687 +/**************************************************************************//**
82688 + @Description Parameters for defining header removal by header type
82689 +*//***************************************************************************/
82690 +typedef struct t_FmPcdManipHdrRmvByHdrParams {
82691 + e_FmPcdManipHdrRmvByHdrType type; /**< Selection of header removal location */
82692 + union {
82693 +#if ((DPAA_VERSION == 10) && defined(FM_CAPWAP_SUPPORT))
82694 + struct {
82695 + bool include; /**< If FALSE, remove until the specified header (not including the header);
82696 + If TRUE, remove also the specified header. */
82697 + t_FmManipHdrInfo hdrInfo;
82698 + } fromStartByHdr; /**< Relevant when type = e_FM_PCD_MANIP_RMV_BY_HDR_FROM_START */
82699 +#endif /* (DPAA_VERSION >= 11) || ... */
82700 +#if (DPAA_VERSION >= 11)
82701 + t_FmManipHdrInfo hdrInfo; /**< Relevant when type = e_FM_PCD_MANIP_RMV_BY_HDR_FROM_START */
82702 +#endif /* (DPAA_VERSION >= 11) */
82703 + e_FmPcdManipHdrRmvSpecificL2 specificL2; /**< Relevant when type = e_FM_PCD_MANIP_BY_HDR_SPECIFIC_L2;
82704 + Defines which L2 headers to remove. */
82705 + } u;
82706 +} t_FmPcdManipHdrRmvByHdrParams;
82707 +
82708 +/**************************************************************************//**
82709 + @Description Parameters for configuring IP fragmentation manipulation
82710 +
82711 + Restrictions:
82712 + - IP Fragmentation output fragments must not be forwarded to application directly.
82713 + - Maximum number of fragments per frame is 16.
82714 + - Fragmentation of IP fragments is not supported.
82715 + - IPv4 packets containing header Option fields are fragmented by copying all option
82716 + fields to each fragment, regardless of the copy bit value.
82717 + - Transmit confirmation is not supported.
82718 + - Fragmentation after SEC can't handle S/G frames.
82719 + - Fragmentation nodes must be set as the last PCD action (i.e. the
82720 + corresponding CC node key must have next engine set to e_FM_PCD_DONE).
82721 + - Only BMan buffers shall be used for frames to be fragmented.
82722 + - IPF does not support VSP. Therefore, on the same port where we have IPF
82723 + we cannot support VSP.
82724 + - NOTE: The following comment is relevant only for FMAN v3 devices: IPF
82725 + does not support VSP. Therefore, on the same port where we have IPF we
82726 + cannot support VSP.
82727 +*//***************************************************************************/
82728 +typedef struct t_FmPcdManipFragIpParams {
82729 + uint16_t sizeForFragmentation; /**< If length of the frame is greater than this value,
82730 + IP fragmentation will be executed.*/
82731 +#if (DPAA_VERSION == 10)
82732 + uint8_t scratchBpid; /**< Absolute buffer pool id according to BM configuration.*/
82733 +#endif /* (DPAA_VERSION == 10) */
82734 + bool sgBpidEn; /**< Enable a dedicated buffer pool id for the Scatter/Gather buffer allocation;
82735 + If disabled, the Scatter/Gather buffer will be allocated from the same pool as the
82736 + received frame's buffer. */
82737 + uint8_t sgBpid; /**< Scatter/Gather buffer pool id;
82738 + This parameters is relevant when 'sgBpidEn=TRUE';
82739 + Same LIODN number is used for these buffers as for the received frames buffers, so buffers
82740 + of this pool need to be allocated in the same memory area as the received buffers.
82741 + If the received buffers arrive from different sources, the Scatter/Gather BP id should be
82742 + mutual to all these sources. */
82743 + e_FmPcdManipDontFragAction dontFragAction; /**< Don't Fragment Action - If an IP packet is larger
82744 + than MTU and its DF bit is set, then this field will
82745 + determine the action to be taken.*/
82746 +} t_FmPcdManipFragIpParams;
82747 +
82748 +/**************************************************************************//**
82749 + @Description Parameters for configuring IP reassembly manipulation.
82750 +
82751 + This is a common structure for both IPv4 and IPv6 reassembly
82752 + manipulation. For reassembly of both IPv4 and IPv6, make sure to
82753 + set the 'hdr' field in t_FmPcdManipReassemParams to HEADER_TYPE_IPv6.
82754 +
82755 + Restrictions:
82756 + - Application must define at least one scheme to catch the reassembled frames.
82757 + - Maximum number of fragments per frame is 16.
82758 + - Reassembly of IPv4 fragments containing Option fields is supported.
82759 +
82760 +*//***************************************************************************/
82761 +typedef struct t_FmPcdManipReassemIpParams {
82762 + uint8_t relativeSchemeId[2]; /**< Partition relative scheme id:
82763 + relativeSchemeId[0] - Relative scheme ID for IPV4 Reassembly manipulation;
82764 + relativeSchemeId[1] - Relative scheme ID for IPV6 Reassembly manipulation;
82765 + NOTE: The following comment is relevant only for FMAN v2 devices:
82766 + Relative scheme ID for IPv4/IPv6 Reassembly manipulation must be smaller than
82767 + the user schemes id to ensure that the reassembly schemes will be first match;
82768 + Rest schemes, if defined, should have higher relative scheme ID. */
82769 +#if (DPAA_VERSION >= 11)
82770 + uint32_t nonConsistentSpFqid; /**< In case that other fragments of the frame corresponds to different storage
82771 + profile than the opening fragment (Non-Consistent-SP state)
82772 + then one of two possible scenarios occurs:
82773 + if 'nonConsistentSpFqid != 0', the reassembled frame will be enqueued to
82774 + this fqid, otherwise a 'Non Consistent SP' bit will be set in the FD[status].*/
82775 +#else
82776 + uint8_t sgBpid; /**< Buffer pool id for the S/G frame created by the reassembly process */
82777 +#endif /* (DPAA_VERSION >= 11) */
82778 + uint8_t dataMemId; /**< Memory partition ID for the IPR's external tables structure */
82779 + uint16_t dataLiodnOffset; /**< LIODN offset for access the IPR's external tables structure. */
82780 + uint16_t minFragSize[2]; /**< Minimum fragment size:
82781 + minFragSize[0] - for ipv4, minFragSize[1] - for ipv6 */
82782 + e_FmPcdManipReassemWaysNumber numOfFramesPerHashEntry[2];
82783 + /**< Number of frames per hash entry needed for reassembly process:
82784 + numOfFramesPerHashEntry[0] - for ipv4 (max value is e_FM_PCD_MANIP_EIGHT_WAYS_HASH);
82785 + numOfFramesPerHashEntry[1] - for ipv6 (max value is e_FM_PCD_MANIP_SIX_WAYS_HASH). */
82786 + uint16_t maxNumFramesInProcess; /**< Number of frames which can be processed by Reassembly in the same time;
82787 + Must be power of 2;
82788 + In the case numOfFramesPerHashEntry == e_FM_PCD_MANIP_FOUR_WAYS_HASH,
82789 + maxNumFramesInProcess has to be in the range of 4 - 512;
82790 + In the case numOfFramesPerHashEntry == e_FM_PCD_MANIP_EIGHT_WAYS_HASH,
82791 + maxNumFramesInProcess has to be in the range of 8 - 2048. */
82792 + e_FmPcdManipReassemTimeOutMode timeOutMode; /**< Expiration delay initialized by Reassembly process */
82793 + uint32_t fqidForTimeOutFrames; /**< FQID in which time out frames will enqueue during Time Out Process;
82794 + Recommended value for this field is 0; in this way timed-out frames will be discarded */
82795 + uint32_t timeoutThresholdForReassmProcess;
82796 + /**< Represents the time interval in microseconds which defines
82797 + if opened frame (at least one fragment was processed but not all the fragments)is found as too old*/
82798 +} t_FmPcdManipReassemIpParams;
82799 +
82800 +/**************************************************************************//**
82801 + @Description structure for defining IPSEC manipulation
82802 +*//***************************************************************************/
82803 +typedef struct t_FmPcdManipSpecialOffloadIPSecParams {
82804 + bool decryption; /**< TRUE if being used in decryption direction;
82805 + FALSE if being used in encryption direction. */
82806 + bool ecnCopy; /**< TRUE to copy the ECN bits from inner/outer to outer/inner
82807 + (direction depends on the 'decryption' field). */
82808 + bool dscpCopy; /**< TRUE to copy the DSCP bits from inner/outer to outer/inner
82809 + (direction depends on the 'decryption' field). */
82810 + bool variableIpHdrLen; /**< TRUE for supporting variable IP header length in decryption. */
82811 + bool variableIpVersion; /**< TRUE for supporting both IP version on the same SA in encryption */
82812 + uint8_t outerIPHdrLen; /**< if 'variableIpVersion == TRUE' then this field must be set to non-zero value;
82813 + It is specifies the length of the outer IP header that was configured in the
82814 + corresponding SA. */
82815 + uint16_t arwSize; /**< if <> '0' then will perform ARW check for this SA;
82816 + The value must be a multiplication of 16 */
82817 + uintptr_t arwAddr; /**< if arwSize <> '0' then this field must be set to non-zero value;
82818 + MUST be allocated from FMAN's MURAM that the post-sec op-port belongs to;
82819 + Must be 4B aligned. Required MURAM size is 'NEXT_POWER_OF_2(arwSize+32))/8+4' Bytes */
82820 +} t_FmPcdManipSpecialOffloadIPSecParams;
82821 +
82822 +#if (DPAA_VERSION >= 11)
82823 +/**************************************************************************//**
82824 + @Description Parameters for configuring CAPWAP fragmentation manipulation
82825 +
82826 + Restrictions:
82827 + - Maximum number of fragments per frame is 16.
82828 + - Transmit confirmation is not supported.
82829 + - Fragmentation nodes must be set as the last PCD action (i.e. the
82830 + corresponding CC node key must have next engine set to e_FM_PCD_DONE).
82831 + - Only BMan buffers shall be used for frames to be fragmented.
82832 + - NOTE: The following comment is relevant only for FMAN v3 devices: IPF
82833 + does not support VSP. Therefore, on the same port where we have IPF we
82834 + cannot support VSP.
82835 +*//***************************************************************************/
82836 +typedef struct t_FmPcdManipFragCapwapParams {
82837 + uint16_t sizeForFragmentation; /**< If length of the frame is greater than this value,
82838 + CAPWAP fragmentation will be executed.*/
82839 + bool sgBpidEn; /**< Enable a dedicated buffer pool id for the Scatter/Gather buffer allocation;
82840 + If disabled, the Scatter/Gather buffer will be allocated from the same pool as the
82841 + received frame's buffer. */
82842 + uint8_t sgBpid; /**< Scatter/Gather buffer pool id;
82843 + This parameters is relevant when 'sgBpidEn=TRUE';
82844 + Same LIODN number is used for these buffers as for the received frames buffers, so buffers
82845 + of this pool need to be allocated in the same memory area as the received buffers.
82846 + If the received buffers arrive from different sources, the Scatter/Gather BP id should be
82847 + mutual to all these sources. */
82848 + bool compressModeEn; /**< CAPWAP Header Options Compress Enable mode;
82849 + When this mode is enabled then only the first fragment include the CAPWAP header options
82850 + field (if user provides it in the input frame) and all other fragments exclude the CAPWAP
82851 + options field (CAPWAP header is updated accordingly).*/
82852 +} t_FmPcdManipFragCapwapParams;
82853 +
82854 +/**************************************************************************//**
82855 + @Description Parameters for configuring CAPWAP reassembly manipulation.
82856 +
82857 + Restrictions:
82858 + - Application must define one scheme to catch the reassembled frames.
82859 + - Maximum number of fragments per frame is 16.
82860 +
82861 +*//***************************************************************************/
82862 +typedef struct t_FmPcdManipReassemCapwapParams {
82863 + uint8_t relativeSchemeId; /**< Partition relative scheme id;
82864 + NOTE: this id must be smaller than the user schemes id to ensure that the reassembly scheme will be first match;
82865 + Rest schemes, if defined, should have higher relative scheme ID. */
82866 + uint8_t dataMemId; /**< Memory partition ID for the IPR's external tables structure */
82867 + uint16_t dataLiodnOffset; /**< LIODN offset for access the IPR's external tables structure. */
82868 + uint16_t maxReassembledFrameLength;/**< The maximum CAPWAP reassembled frame length in bytes;
82869 + If maxReassembledFrameLength == 0, any successful reassembled frame length is
82870 + considered as a valid length;
82871 + if maxReassembledFrameLength > 0, a successful reassembled frame which its length
82872 + exceeds this value is considered as an error frame (FD status[CRE] bit is set). */
82873 + e_FmPcdManipReassemWaysNumber numOfFramesPerHashEntry;
82874 + /**< Number of frames per hash entry needed for reassembly process */
82875 + uint16_t maxNumFramesInProcess; /**< Number of frames which can be processed by reassembly in the same time;
82876 + Must be power of 2;
82877 + In the case numOfFramesPerHashEntry == e_FM_PCD_MANIP_FOUR_WAYS_HASH,
82878 + maxNumFramesInProcess has to be in the range of 4 - 512;
82879 + In the case numOfFramesPerHashEntry == e_FM_PCD_MANIP_EIGHT_WAYS_HASH,
82880 + maxNumFramesInProcess has to be in the range of 8 - 2048. */
82881 + e_FmPcdManipReassemTimeOutMode timeOutMode; /**< Expiration delay initialized by Reassembly process */
82882 + uint32_t fqidForTimeOutFrames; /**< FQID in which time out frames will enqueue during Time Out Process;
82883 + Recommended value for this field is 0; in this way timed-out frames will be discarded */
82884 + uint32_t timeoutThresholdForReassmProcess;
82885 + /**< Represents the time interval in microseconds which defines
82886 + if opened frame (at least one fragment was processed but not all the fragments)is found as too old*/
82887 +} t_FmPcdManipReassemCapwapParams;
82888 +
82889 +/**************************************************************************//**
82890 + @Description structure for defining CAPWAP manipulation
82891 +*//***************************************************************************/
82892 +typedef struct t_FmPcdManipSpecialOffloadCapwapParams {
82893 + bool dtls; /**< TRUE if continue to SEC DTLS encryption */
82894 + e_FmPcdManipHdrQosSrc qosSrc; /**< TODO */
82895 +} t_FmPcdManipSpecialOffloadCapwapParams;
82896 +
82897 +#endif /* (DPAA_VERSION >= 11) */
82898 +
82899 +
82900 +/**************************************************************************//**
82901 + @Description Parameters for defining special offload manipulation
82902 +*//***************************************************************************/
82903 +typedef struct t_FmPcdManipSpecialOffloadParams {
82904 + e_FmPcdManipSpecialOffloadType type; /**< Type of special offload manipulation */
82905 + union
82906 + {
82907 + t_FmPcdManipSpecialOffloadIPSecParams ipsec; /**< Parameters for IPSec; Relevant when
82908 + type = e_FM_PCD_MANIP_SPECIAL_OFFLOAD_IPSEC */
82909 +#if (DPAA_VERSION >= 11)
82910 + t_FmPcdManipSpecialOffloadCapwapParams capwap; /**< Parameters for CAPWAP; Relevant when
82911 + type = e_FM_PCD_MANIP_SPECIAL_OFFLOAD_CAPWAP */
82912 +#endif /* (DPAA_VERSION >= 11) */
82913 + } u;
82914 +} t_FmPcdManipSpecialOffloadParams;
82915 +
82916 +/**************************************************************************//**
82917 + @Description Parameters for defining insertion manipulation
82918 +*//***************************************************************************/
82919 +typedef struct t_FmPcdManipHdrInsrt {
82920 + uint8_t size; /**< size of inserted section */
82921 + uint8_t *p_Data; /**< data to be inserted */
82922 +} t_FmPcdManipHdrInsrt;
82923 +
82924 +
82925 +/**************************************************************************//**
82926 + @Description Parameters for defining generic removal manipulation
82927 +*//***************************************************************************/
82928 +typedef struct t_FmPcdManipHdrRmvGenericParams {
82929 + uint8_t offset; /**< Offset from beginning of header to the start
82930 + location of the removal */
82931 + uint8_t size; /**< Size of removed section */
82932 +} t_FmPcdManipHdrRmvGenericParams;
82933 +
82934 +/**************************************************************************//**
82935 + @Description Parameters for defining generic insertion manipulation
82936 +*//***************************************************************************/
82937 +typedef struct t_FmPcdManipHdrInsrtGenericParams {
82938 + uint8_t offset; /**< Offset from beginning of header to the start
82939 + location of the insertion */
82940 + uint8_t size; /**< Size of inserted section */
82941 + bool replace; /**< TRUE to override (replace) existing data at
82942 + 'offset', FALSE to insert */
82943 + uint8_t *p_Data; /**< Pointer to data to be inserted */
82944 +} t_FmPcdManipHdrInsrtGenericParams;
82945 +
82946 +/**************************************************************************//**
82947 + @Description Parameters for defining header manipulation VLAN DSCP To Vpri translation
82948 +*//***************************************************************************/
82949 +typedef struct t_FmPcdManipHdrFieldUpdateVlanDscpToVpri {
82950 + uint8_t dscpToVpriTable[FM_PCD_MANIP_DSCP_TO_VLAN_TRANS];
82951 + /**< A table of VPri values for each DSCP value;
82952 + The index is the DSCP value (0-0x3F) and the
82953 + value is the corresponding VPRI (0-15). */
82954 + uint8_t vpriDefVal; /**< 0-7, Relevant only if if updateType =
82955 + e_FM_PCD_MANIP_HDR_FIELD_UPDATE_DSCP_TO_VLAN,
82956 + this field is the Q Tag default value if the
82957 + IP header is not found. */
82958 +} t_FmPcdManipHdrFieldUpdateVlanDscpToVpri;
82959 +
82960 +/**************************************************************************//**
82961 + @Description Parameters for defining header manipulation VLAN fields updates
82962 +*//***************************************************************************/
82963 +typedef struct t_FmPcdManipHdrFieldUpdateVlan {
82964 + e_FmPcdManipHdrFieldUpdateVlan updateType; /**< Selects VLAN update type */
82965 + union {
82966 + uint8_t vpri; /**< 0-7, Relevant only if If updateType =
82967 + e_FM_PCD_MANIP_HDR_FIELD_UPDATE_VLAN_PRI, this
82968 + is the new VLAN pri. */
82969 + t_FmPcdManipHdrFieldUpdateVlanDscpToVpri dscpToVpri; /**< Parameters structure, Relevant only if updateType
82970 + = e_FM_PCD_MANIP_HDR_FIELD_UPDATE_DSCP_TO_VLAN. */
82971 + } u;
82972 +} t_FmPcdManipHdrFieldUpdateVlan;
82973 +
82974 +/**************************************************************************//**
82975 + @Description Parameters for defining header manipulation IPV4 fields updates
82976 +*//***************************************************************************/
82977 +typedef struct t_FmPcdManipHdrFieldUpdateIpv4 {
82978 + ipv4HdrManipUpdateFlags_t validUpdates; /**< ORed flag, selecting the required updates */
82979 + uint8_t tos; /**< 8 bit New TOS; Relevant if validUpdates contains
82980 + HDR_MANIP_IPV4_TOS */
82981 + uint16_t id; /**< 16 bit New IP ID; Relevant only if validUpdates
82982 + contains HDR_MANIP_IPV4_ID */
82983 + uint32_t src; /**< 32 bit New IP SRC; Relevant only if validUpdates
82984 + contains HDR_MANIP_IPV4_SRC */
82985 + uint32_t dst; /**< 32 bit New IP DST; Relevant only if validUpdates
82986 + contains HDR_MANIP_IPV4_DST */
82987 +} t_FmPcdManipHdrFieldUpdateIpv4;
82988 +
82989 +/**************************************************************************//**
82990 + @Description Parameters for defining header manipulation IPV6 fields updates
82991 +*//***************************************************************************/
82992 +typedef struct t_FmPcdManipHdrFieldUpdateIpv6 {
82993 + ipv6HdrManipUpdateFlags_t validUpdates; /**< ORed flag, selecting the required updates */
82994 + uint8_t trafficClass; /**< 8 bit New Traffic Class; Relevant if validUpdates contains
82995 + HDR_MANIP_IPV6_TC */
82996 + uint8_t src[NET_HEADER_FIELD_IPv6_ADDR_SIZE];
82997 + /**< 16 byte new IP SRC; Relevant only if validUpdates
82998 + contains HDR_MANIP_IPV6_SRC */
82999 + uint8_t dst[NET_HEADER_FIELD_IPv6_ADDR_SIZE];
83000 + /**< 16 byte new IP DST; Relevant only if validUpdates
83001 + contains HDR_MANIP_IPV6_DST */
83002 +} t_FmPcdManipHdrFieldUpdateIpv6;
83003 +
83004 +/**************************************************************************//**
83005 + @Description Parameters for defining header manipulation TCP/UDP fields updates
83006 +*//***************************************************************************/
83007 +typedef struct t_FmPcdManipHdrFieldUpdateTcpUdp {
83008 + tcpUdpHdrManipUpdateFlags_t validUpdates; /**< ORed flag, selecting the required updates */
83009 + uint16_t src; /**< 16 bit New TCP/UDP SRC; Relevant only if validUpdates
83010 + contains HDR_MANIP_TCP_UDP_SRC */
83011 + uint16_t dst; /**< 16 bit New TCP/UDP DST; Relevant only if validUpdates
83012 + contains HDR_MANIP_TCP_UDP_DST */
83013 +} t_FmPcdManipHdrFieldUpdateTcpUdp;
83014 +
83015 +/**************************************************************************//**
83016 + @Description Parameters for defining header manipulation fields updates
83017 +*//***************************************************************************/
83018 +typedef struct t_FmPcdManipHdrFieldUpdateParams {
83019 + e_FmPcdManipHdrFieldUpdateType type; /**< Type of header field update manipulation */
83020 + union {
83021 + t_FmPcdManipHdrFieldUpdateVlan vlan; /**< Parameters for VLAN update. Relevant when
83022 + type = e_FM_PCD_MANIP_HDR_FIELD_UPDATE_VLAN */
83023 + t_FmPcdManipHdrFieldUpdateIpv4 ipv4; /**< Parameters for IPv4 update. Relevant when
83024 + type = e_FM_PCD_MANIP_HDR_FIELD_UPDATE_IPV4 */
83025 + t_FmPcdManipHdrFieldUpdateIpv6 ipv6; /**< Parameters for IPv6 update. Relevant when
83026 + type = e_FM_PCD_MANIP_HDR_FIELD_UPDATE_IPV6 */
83027 + t_FmPcdManipHdrFieldUpdateTcpUdp tcpUdp; /**< Parameters for TCP/UDP update. Relevant when
83028 + type = e_FM_PCD_MANIP_HDR_FIELD_UPDATE_TCP_UDP */
83029 + } u;
83030 +} t_FmPcdManipHdrFieldUpdateParams;
83031 +
83032 +
83033 +
83034 +/**************************************************************************//**
83035 + @Description Parameters for defining custom header manipulation for generic field replacement
83036 +*//***************************************************************************/
83037 +typedef struct t_FmPcdManipHdrCustomGenFieldReplace {
83038 + uint8_t srcOffset; /**< Location of new data - Offset from
83039 + Parse Result (>= 16, srcOffset+size <= 32, ) */
83040 + uint8_t dstOffset; /**< Location of data to be overwritten - Offset from
83041 + start of frame (dstOffset + size <= 256). */
83042 + uint8_t size; /**< The number of bytes (<=16) to be replaced */
83043 + uint8_t mask; /**< Optional 1 byte mask. Set to select bits for
83044 + replacement (1 - bit will be replaced);
83045 + Clear to use field as is. */
83046 + uint8_t maskOffset; /**< Relevant if mask != 0;
83047 + Mask offset within the replaces "size" */
83048 +} t_FmPcdManipHdrCustomGenFieldReplace;
83049 +
83050 +/**************************************************************************//**
83051 + @Description Parameters for defining custom header manipulation for IP replacement
83052 +*//***************************************************************************/
83053 +typedef struct t_FmPcdManipHdrCustomIpHdrReplace {
83054 + e_FmPcdManipHdrCustomIpReplace replaceType; /**< Selects replace update type */
83055 + bool decTtlHl; /**< Decrement TTL (IPV4) or Hop limit (IPV6) by 1 */
83056 + bool updateIpv4Id; /**< Relevant when replaceType =
83057 + e_FM_PCD_MANIP_HDR_CUSTOM_REPLACE_IPV6_BY_IPV4 */
83058 + uint16_t id; /**< 16 bit New IP ID; Relevant only if
83059 + updateIpv4Id = TRUE */
83060 + uint8_t hdrSize; /**< The size of the new IP header */
83061 + uint8_t hdr[FM_PCD_MANIP_MAX_HDR_SIZE];
83062 + /**< The new IP header */
83063 +} t_FmPcdManipHdrCustomIpHdrReplace;
83064 +
83065 +/**************************************************************************//**
83066 + @Description Parameters for defining custom header manipulation
83067 +*//***************************************************************************/
83068 +typedef struct t_FmPcdManipHdrCustomParams {
83069 + e_FmPcdManipHdrCustomType type; /**< Type of header field update manipulation */
83070 + union {
83071 + t_FmPcdManipHdrCustomIpHdrReplace ipHdrReplace; /**< Parameters IP header replacement */
83072 + t_FmPcdManipHdrCustomGenFieldReplace genFieldReplace; /**< Parameters IP header replacement */
83073 + } u;
83074 +} t_FmPcdManipHdrCustomParams;
83075 +
83076 +/**************************************************************************//**
83077 + @Description Parameters for defining specific L2 insertion manipulation
83078 +*//***************************************************************************/
83079 +typedef struct t_FmPcdManipHdrInsrtSpecificL2Params {
83080 + e_FmPcdManipHdrInsrtSpecificL2 specificL2; /**< Selects which L2 headers to insert */
83081 + bool update; /**< TRUE to update MPLS header */
83082 + uint8_t size; /**< size of inserted section */
83083 + uint8_t *p_Data; /**< data to be inserted */
83084 +} t_FmPcdManipHdrInsrtSpecificL2Params;
83085 +
83086 +#if (DPAA_VERSION >= 11)
83087 +/**************************************************************************//**
83088 + @Description Parameters for defining IP insertion manipulation
83089 +*//***************************************************************************/
83090 +typedef struct t_FmPcdManipHdrInsrtIpParams {
83091 + bool calcL4Checksum; /**< Calculate L4 checksum. */
83092 + e_FmPcdManipHdrQosMappingMode mappingMode; /**< TODO */
83093 + uint8_t lastPidOffset; /**< the offset of the last Protocol within
83094 + the inserted header */
83095 + uint16_t id; /**< 16 bit New IP ID */
83096 + bool dontFragOverwrite;
83097 + /**< IPv4 only. DF is overwritten with the hash-result next-to-last byte.
83098 + * This byte is configured to be overwritten when RPD is set. */
83099 + uint8_t lastDstOffset;
83100 + /**< IPv6 only. if routing extension exist, user should set the offset of the destination address
83101 + * in order to calculate UDP checksum pseudo header;
83102 + * Otherwise set it to '0'. */
83103 + t_FmPcdManipHdrInsrt insrt; /**< size and data to be inserted. */
83104 +} t_FmPcdManipHdrInsrtIpParams;
83105 +#endif /* (DPAA_VERSION >= 11) */
83106 +
83107 +/**************************************************************************//**
83108 + @Description Parameters for defining header insertion manipulation by header type
83109 +*//***************************************************************************/
83110 +typedef struct t_FmPcdManipHdrInsrtByHdrParams {
83111 + e_FmPcdManipHdrInsrtByHdrType type; /**< Selects manipulation type */
83112 + union {
83113 +
83114 + t_FmPcdManipHdrInsrtSpecificL2Params specificL2Params;
83115 + /**< Used when type = e_FM_PCD_MANIP_INSRT_BY_HDR_SPECIFIC_L2:
83116 + Selects which L2 headers to insert */
83117 +#if (DPAA_VERSION >= 11)
83118 + t_FmPcdManipHdrInsrtIpParams ipParams; /**< Used when type = e_FM_PCD_MANIP_INSRT_BY_HDR_IP */
83119 + t_FmPcdManipHdrInsrt insrt; /**< Used when type is one of e_FM_PCD_MANIP_INSRT_BY_HDR_UDP,
83120 + e_FM_PCD_MANIP_INSRT_BY_HDR_UDP_LITE, or
83121 + e_FM_PCD_MANIP_INSRT_BY_HDR_CAPWAP */
83122 +#endif /* (DPAA_VERSION >= 11) */
83123 + } u;
83124 +} t_FmPcdManipHdrInsrtByHdrParams;
83125 +
83126 +/**************************************************************************//**
83127 + @Description Parameters for defining header insertion manipulation
83128 +*//***************************************************************************/
83129 +typedef struct t_FmPcdManipHdrInsrtParams {
83130 + e_FmPcdManipHdrInsrtType type; /**< Type of insertion manipulation */
83131 + union {
83132 + t_FmPcdManipHdrInsrtByHdrParams byHdr; /**< Parameters for defining header insertion manipulation by header type,
83133 + relevant if 'type' = e_FM_PCD_MANIP_INSRT_BY_HDR */
83134 + t_FmPcdManipHdrInsrtGenericParams generic; /**< Parameters for defining generic header insertion manipulation,
83135 + relevant if 'type' = e_FM_PCD_MANIP_INSRT_GENERIC */
83136 +#if ((DPAA_VERSION == 10) && defined(FM_CAPWAP_SUPPORT))
83137 + t_FmPcdManipHdrInsrtByTemplateParams byTemplate; /**< Parameters for defining header insertion manipulation by template,
83138 + relevant if 'type' = e_FM_PCD_MANIP_INSRT_BY_TEMPLATE */
83139 +#endif /* ((DPAA_VERSION == 10) && defined(FM_CAPWAP_SUPPORT)) */
83140 + } u;
83141 +} t_FmPcdManipHdrInsrtParams;
83142 +
83143 +/**************************************************************************//**
83144 + @Description Parameters for defining header removal manipulation
83145 +*//***************************************************************************/
83146 +typedef struct t_FmPcdManipHdrRmvParams {
83147 + e_FmPcdManipHdrRmvType type; /**< Type of header removal manipulation */
83148 + union {
83149 + t_FmPcdManipHdrRmvByHdrParams byHdr; /**< Parameters for defining header removal manipulation by header type,
83150 + relevant if type = e_FM_PCD_MANIP_RMV_BY_HDR */
83151 + t_FmPcdManipHdrRmvGenericParams generic; /**< Parameters for defining generic header removal manipulation,
83152 + relevant if type = e_FM_PCD_MANIP_RMV_GENERIC */
83153 + } u;
83154 +} t_FmPcdManipHdrRmvParams;
83155 +
83156 +/**************************************************************************//**
83157 + @Description Parameters for defining header manipulation node
83158 +*//***************************************************************************/
83159 +typedef struct t_FmPcdManipHdrParams {
83160 + bool rmv; /**< TRUE, to define removal manipulation */
83161 + t_FmPcdManipHdrRmvParams rmvParams; /**< Parameters for removal manipulation, relevant if 'rmv' = TRUE */
83162 +
83163 + bool insrt; /**< TRUE, to define insertion manipulation */
83164 + t_FmPcdManipHdrInsrtParams insrtParams; /**< Parameters for insertion manipulation, relevant if 'insrt' = TRUE */
83165 +
83166 + bool fieldUpdate; /**< TRUE, to define field update manipulation */
83167 + t_FmPcdManipHdrFieldUpdateParams fieldUpdateParams; /**< Parameters for field update manipulation, relevant if 'fieldUpdate' = TRUE */
83168 +
83169 + bool custom; /**< TRUE, to define custom manipulation */
83170 + t_FmPcdManipHdrCustomParams customParams; /**< Parameters for custom manipulation, relevant if 'custom' = TRUE */
83171 +
83172 + bool dontParseAfterManip;/**< TRUE to de-activate the parser after the manipulation defined in this node.
83173 + Restrictions:
83174 + 1. MUST be set if the next engine after the CC is not another CC node
83175 + (but rather Policer or Keygen), and this is the last (no h_NextManip) in a chain
83176 + of manipulation nodes. This includes single nodes (i.e. no h_NextManip and
83177 + also never pointed as h_NextManip of other manipulation nodes)
83178 + 2. MUST be set if the next engine after the CC is another CC node, and
83179 + this is NOT the last manipulation node (i.e. it has h_NextManip).*/
83180 +} t_FmPcdManipHdrParams;
83181 +
83182 +/**************************************************************************//**
83183 + @Description Parameters for defining fragmentation manipulation
83184 +*//***************************************************************************/
83185 +typedef struct t_FmPcdManipFragParams {
83186 + e_NetHeaderType hdr; /**< Header selection */
83187 + union {
83188 +#if (DPAA_VERSION >= 11)
83189 + t_FmPcdManipFragCapwapParams capwapFrag; /**< Parameters for defining CAPWAP fragmentation,
83190 + relevant if 'hdr' = HEADER_TYPE_CAPWAP */
83191 +#endif /* (DPAA_VERSION >= 11) */
83192 + t_FmPcdManipFragIpParams ipFrag; /**< Parameters for defining IP fragmentation,
83193 + relevant if 'hdr' = HEADER_TYPE_Ipv4 or HEADER_TYPE_Ipv6 */
83194 + } u;
83195 +} t_FmPcdManipFragParams;
83196 +
83197 +/**************************************************************************//**
83198 + @Description Parameters for defining reassembly manipulation
83199 +*//***************************************************************************/
83200 +typedef struct t_FmPcdManipReassemParams {
83201 + e_NetHeaderType hdr; /**< Header selection */
83202 + union {
83203 +#if (DPAA_VERSION >= 11)
83204 + t_FmPcdManipReassemCapwapParams capwapReassem; /**< Parameters for defining CAPWAP reassembly,
83205 + relevant if 'hdr' = HEADER_TYPE_CAPWAP */
83206 +#endif /* (DPAA_VERSION >= 11) */
83207 +
83208 + t_FmPcdManipReassemIpParams ipReassem; /**< Parameters for defining IP reassembly,
83209 + relevant if 'hdr' = HEADER_TYPE_Ipv4 or HEADER_TYPE_Ipv6 */
83210 + } u;
83211 +} t_FmPcdManipReassemParams;
83212 +
83213 +/**************************************************************************//**
83214 + @Description Parameters for defining a manipulation node
83215 +*//***************************************************************************/
83216 +typedef struct t_FmPcdManipParams {
83217 + e_FmPcdManipType type; /**< Selects type of manipulation node */
83218 + union{
83219 + t_FmPcdManipHdrParams hdr; /**< Parameters for defining header manipulation node */
83220 + t_FmPcdManipReassemParams reassem; /**< Parameters for defining reassembly manipulation node */
83221 + t_FmPcdManipFragParams frag; /**< Parameters for defining fragmentation manipulation node */
83222 + t_FmPcdManipSpecialOffloadParams specialOffload; /**< Parameters for defining special offload manipulation node */
83223 + } u;
83224 +
83225 + t_Handle h_NextManip; /**< Supported for Header Manipulation only;
83226 + Handle to another (previously defined) manipulation node;
83227 + Allows concatenation of manipulation actions;
83228 + This parameter is optional and may be NULL. */
83229 +#if ((DPAA_VERSION == 10) && defined(FM_CAPWAP_SUPPORT))
83230 + bool fragOrReasm; /**< TRUE, if defined fragmentation/reassembly manipulation */
83231 + t_FmPcdManipFragOrReasmParams fragOrReasmParams; /**< Parameters for fragmentation/reassembly manipulation,
83232 + relevant if fragOrReasm = TRUE */
83233 +#endif /* ((DPAA_VERSION == 10) && defined(FM_CAPWAP_SUPPORT)) */
83234 +} t_FmPcdManipParams;
83235 +
83236 +/**************************************************************************//**
83237 + @Description Structure for retrieving IP reassembly statistics
83238 +*//***************************************************************************/
83239 +typedef struct t_FmPcdManipReassemIpStats {
83240 + /* common counters for both IPv4 and IPv6 */
83241 + uint32_t timeout; /**< Counts the number of timeout occurrences */
83242 + uint32_t rfdPoolBusy; /**< Counts the number of failed attempts to allocate
83243 + a Reassembly Frame Descriptor */
83244 + uint32_t internalBufferBusy; /**< Counts the number of times an internal buffer busy occurred */
83245 + uint32_t externalBufferBusy; /**< Counts the number of times external buffer busy occurred */
83246 + uint32_t sgFragments; /**< Counts the number of Scatter/Gather fragments */
83247 + uint32_t dmaSemaphoreDepletion; /**< Counts the number of failed attempts to allocate a DMA semaphore */
83248 +#if (DPAA_VERSION >= 11)
83249 + uint32_t nonConsistentSp; /**< Counts the number of Non Consistent Storage Profile events for
83250 + successfully reassembled frames */
83251 +#endif /* (DPAA_VERSION >= 11) */
83252 + struct {
83253 + uint32_t successfullyReassembled; /**< Counts the number of successfully reassembled frames */
83254 + uint32_t validFragments; /**< Counts the total number of valid fragments that
83255 + have been processed for all frames */
83256 + uint32_t processedFragments; /**< Counts the number of processed fragments
83257 + (valid and error fragments) for all frames */
83258 + uint32_t malformedFragments; /**< Counts the number of malformed fragments processed for all frames */
83259 + uint32_t discardedFragments; /**< Counts the number of fragments discarded by the reassembly process */
83260 + uint32_t autoLearnBusy; /**< Counts the number of times a busy condition occurs when attempting
83261 + to access an IP-Reassembly Automatic Learning Hash set */
83262 + uint32_t moreThan16Fragments; /**< Counts the fragment occurrences in which the number of fragments-per-frame
83263 + exceeds 16 */
83264 + } specificHdrStatistics[2]; /**< slot '0' is for IPv4, slot '1' is for IPv6 */
83265 +} t_FmPcdManipReassemIpStats;
83266 +
83267 +/**************************************************************************//**
83268 + @Description Structure for retrieving IP fragmentation statistics
83269 +*//***************************************************************************/
83270 +typedef struct t_FmPcdManipFragIpStats {
83271 + uint32_t totalFrames; /**< Number of frames that passed through the manipulation node */
83272 + uint32_t fragmentedFrames; /**< Number of frames that were fragmented */
83273 + uint32_t generatedFragments; /**< Number of fragments that were generated */
83274 +} t_FmPcdManipFragIpStats;
83275 +
83276 +#if (DPAA_VERSION >= 11)
83277 +/**************************************************************************//**
83278 + @Description Structure for retrieving CAPWAP reassembly statistics
83279 +*//***************************************************************************/
83280 +typedef struct t_FmPcdManipReassemCapwapStats {
83281 + uint32_t timeout; /**< Counts the number of timeout occurrences */
83282 + uint32_t rfdPoolBusy; /**< Counts the number of failed attempts to allocate
83283 + a Reassembly Frame Descriptor */
83284 + uint32_t internalBufferBusy; /**< Counts the number of times an internal buffer busy occurred */
83285 + uint32_t externalBufferBusy; /**< Counts the number of times external buffer busy occurred */
83286 + uint32_t sgFragments; /**< Counts the number of Scatter/Gather fragments */
83287 + uint32_t dmaSemaphoreDepletion; /**< Counts the number of failed attempts to allocate a DMA semaphore */
83288 + uint32_t successfullyReassembled; /**< Counts the number of successfully reassembled frames */
83289 + uint32_t validFragments; /**< Counts the total number of valid fragments that
83290 + have been processed for all frames */
83291 + uint32_t processedFragments; /**< Counts the number of processed fragments
83292 + (valid and error fragments) for all frames */
83293 + uint32_t malformedFragments; /**< Counts the number of malformed fragments processed for all frames */
83294 + uint32_t autoLearnBusy; /**< Counts the number of times a busy condition occurs when attempting
83295 + to access an Reassembly Automatic Learning Hash set */
83296 + uint32_t discardedFragments; /**< Counts the number of fragments discarded by the reassembly process */
83297 + uint32_t moreThan16Fragments; /**< Counts the fragment occurrences in which the number of fragments-per-frame
83298 + exceeds 16 */
83299 + uint32_t exceedMaxReassemblyFrameLen;/**< ounts the number of times that a successful reassembled frame
83300 + length exceeds MaxReassembledFrameLength value */
83301 +} t_FmPcdManipReassemCapwapStats;
83302 +
83303 +/**************************************************************************//**
83304 + @Description Structure for retrieving CAPWAP fragmentation statistics
83305 +*//***************************************************************************/
83306 +typedef struct t_FmPcdManipFragCapwapStats {
83307 + uint32_t totalFrames; /**< Number of frames that passed through the manipulation node */
83308 + uint32_t fragmentedFrames; /**< Number of frames that were fragmented */
83309 + uint32_t generatedFragments; /**< Number of fragments that were generated */
83310 +#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
83311 + uint8_t sgAllocationFailure; /**< Number of allocation failure of s/g buffers */
83312 +#endif /* (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0)) */
83313 +} t_FmPcdManipFragCapwapStats;
83314 +#endif /* (DPAA_VERSION >= 11) */
83315 +
83316 +/**************************************************************************//**
83317 + @Description Structure for retrieving reassembly statistics
83318 +*//***************************************************************************/
83319 +typedef struct t_FmPcdManipReassemStats {
83320 + union {
83321 + t_FmPcdManipReassemIpStats ipReassem; /**< Structure for IP reassembly statistics */
83322 +#if (DPAA_VERSION >= 11)
83323 + t_FmPcdManipReassemCapwapStats capwapReassem; /**< Structure for CAPWAP reassembly statistics */
83324 +#endif /* (DPAA_VERSION >= 11) */
83325 + } u;
83326 +} t_FmPcdManipReassemStats;
83327 +
83328 +/**************************************************************************//**
83329 + @Description Structure for retrieving fragmentation statistics
83330 +*//***************************************************************************/
83331 +typedef struct t_FmPcdManipFragStats {
83332 + union {
83333 + t_FmPcdManipFragIpStats ipFrag; /**< Structure for IP fragmentation statistics */
83334 +#if (DPAA_VERSION >= 11)
83335 + t_FmPcdManipFragCapwapStats capwapFrag; /**< Structure for CAPWAP fragmentation statistics */
83336 +#endif /* (DPAA_VERSION >= 11) */
83337 + } u;
83338 +} t_FmPcdManipFragStats;
83339 +
83340 +/**************************************************************************//**
83341 + @Description Structure for selecting manipulation statistics
83342 +*//***************************************************************************/
83343 +typedef struct t_FmPcdManipStats {
83344 + union {
83345 + t_FmPcdManipReassemStats reassem; /**< Structure for reassembly statistics */
83346 + t_FmPcdManipFragStats frag; /**< Structure for fragmentation statistics */
83347 + } u;
83348 +} t_FmPcdManipStats;
83349 +
83350 +#if (DPAA_VERSION >= 11)
83351 +/**************************************************************************//**
83352 + @Description Parameters for defining frame replicator group and its members
83353 +*//***************************************************************************/
83354 +typedef struct t_FmPcdFrmReplicGroupParams {
83355 + uint8_t maxNumOfEntries; /**< Maximal number of members in the group;
83356 + Must be at least 2. */
83357 + uint8_t numOfEntries; /**< Number of members in the group;
83358 + Must be at least 1. */
83359 + t_FmPcdCcNextEngineParams nextEngineParams[FM_PCD_FRM_REPLIC_MAX_NUM_OF_ENTRIES];
83360 + /**< Array of members' parameters */
83361 +} t_FmPcdFrmReplicGroupParams;
83362 +#endif /* (DPAA_VERSION >= 11) */
83363 +
83364 +#if ((DPAA_VERSION == 10) && defined(FM_CAPWAP_SUPPORT))
83365 +/**************************************************************************//**
83366 + @Description structure for defining statistics node
83367 +*//***************************************************************************/
83368 +typedef struct t_FmPcdStatsParams {
83369 + e_FmPcdStatsType type; /**< type of statistics node */
83370 +} t_FmPcdStatsParams;
83371 +#endif /* ((DPAA_VERSION == 10) && defined(FM_CAPWAP_SUPPORT)) */
83372 +
83373 +/**************************************************************************//**
83374 + @Function FM_PCD_NetEnvCharacteristicsSet
83375 +
83376 + @Description Define a set of Network Environment Characteristics.
83377 +
83378 + When setting an environment it is important to understand its
83379 + application. It is not meant to describe the flows that will run
83380 + on the ports using this environment, but what the user means TO DO
83381 + with the PCD mechanisms in order to parse-classify-distribute those
83382 + frames.
83383 + By specifying a distinction unit, the user means it would use that option
83384 + for distinction between frames at either a KeyGen scheme or a coarse
83385 + classification action descriptor. Using interchangeable headers to define a
83386 + unit means that the user is indifferent to which of the interchangeable
83387 + headers is present in the frame, and wants the distinction to be based
83388 + on the presence of either one of them.
83389 +
83390 + Depending on context, there are limitations to the use of environments. A
83391 + port using the PCD functionality is bound to an environment. Some or even
83392 + all ports may share an environment but also an environment per port is
83393 + possible. When initializing a scheme, a classification plan group (see below),
83394 + or a coarse classification tree, one of the initialized environments must be
83395 + stated and related to. When a port is bound to a scheme, a classification
83396 + plan group, or a coarse classification tree, it MUST be bound to the same
83397 + environment.
83398 +
83399 + The different PCD modules, may relate (for flows definition) ONLY on
83400 + distinction units as defined by their environment. When initializing a
83401 + scheme for example, it may not choose to select IPV4 as a match for
83402 + recognizing flows unless it was defined in the relating environment. In
83403 + fact, to guide the user through the configuration of the PCD, each module's
83404 + characterization in terms of flows is not done using protocol names, but using
83405 + environment indexes.
83406 +
83407 + In terms of HW implementation, the list of distinction units sets the LCV vectors
83408 + and later used for match vector, classification plan vectors and coarse classification
83409 + indexing.
83410 +
83411 + @Param[in] h_FmPcd FM PCD module descriptor.
83412 + @Param[in] p_NetEnvParams A structure of parameters for the initialization of
83413 + the network environment.
83414 +
83415 + @Return A handle to the initialized object on success; NULL code otherwise.
83416 +
83417 + @Cautions Allowed only following FM_PCD_Init().
83418 +*//***************************************************************************/
83419 +t_Handle FM_PCD_NetEnvCharacteristicsSet(t_Handle h_FmPcd, t_FmPcdNetEnvParams *p_NetEnvParams);
83420 +
83421 +/**************************************************************************//**
83422 + @Function FM_PCD_NetEnvCharacteristicsDelete
83423 +
83424 + @Description Deletes a set of Network Environment Characteristics.
83425 +
83426 + @Param[in] h_NetEnv A handle to the Network environment.
83427 +
83428 + @Return E_OK on success; Error code otherwise.
83429 +*//***************************************************************************/
83430 +t_Error FM_PCD_NetEnvCharacteristicsDelete(t_Handle h_NetEnv);
83431 +
83432 +/**************************************************************************//**
83433 + @Function FM_PCD_KgSchemeSet
83434 +
83435 + @Description Initializing or modifying and enabling a scheme for the KeyGen.
83436 + This routine should be called for adding or modifying a scheme.
83437 + When a scheme needs modifying, the API requires that it will be
83438 + rewritten. In such a case 'modify' should be TRUE. If the
83439 + routine is called for a valid scheme and 'modify' is FALSE,
83440 + it will return error.
83441 +
83442 + @Param[in] h_FmPcd If this is a new scheme - A handle to an FM PCD Module.
83443 + Otherwise NULL (ignored by driver).
83444 + @Param[in,out] p_SchemeParams A structure of parameters for defining the scheme
83445 +
83446 + @Return A handle to the initialized scheme on success; NULL code otherwise.
83447 + When used as "modify" (rather than for setting a new scheme),
83448 + p_SchemeParams->id.h_Scheme will return NULL if action fails due to scheme
83449 + BUSY state.
83450 +
83451 + @Cautions Allowed only following FM_PCD_Init().
83452 +*//***************************************************************************/
83453 +t_Handle FM_PCD_KgSchemeSet(t_Handle h_FmPcd,
83454 + t_FmPcdKgSchemeParams *p_SchemeParams);
83455 +
83456 +/**************************************************************************//**
83457 + @Function FM_PCD_KgSchemeDelete
83458 +
83459 + @Description Deleting an initialized scheme.
83460 +
83461 + @Param[in] h_Scheme scheme handle as returned by FM_PCD_KgSchemeSet()
83462 +
83463 + @Return E_OK on success; Error code otherwise.
83464 +
83465 + @Cautions Allowed only following FM_PCD_Init() & FM_PCD_KgSchemeSet().
83466 +*//***************************************************************************/
83467 +t_Error FM_PCD_KgSchemeDelete(t_Handle h_Scheme);
83468 +
83469 +/**************************************************************************//**
83470 + @Function FM_PCD_KgSchemeGetCounter
83471 +
83472 + @Description Reads scheme packet counter.
83473 +
83474 + @Param[in] h_Scheme scheme handle as returned by FM_PCD_KgSchemeSet().
83475 +
83476 + @Return Counter's current value.
83477 +
83478 + @Cautions Allowed only following FM_PCD_Init() & FM_PCD_KgSchemeSet().
83479 +*//***************************************************************************/
83480 +uint32_t FM_PCD_KgSchemeGetCounter(t_Handle h_Scheme);
83481 +
83482 +/**************************************************************************//**
83483 + @Function FM_PCD_KgSchemeSetCounter
83484 +
83485 + @Description Writes scheme packet counter.
83486 +
83487 + @Param[in] h_Scheme scheme handle as returned by FM_PCD_KgSchemeSet().
83488 + @Param[in] value New scheme counter value - typically '0' for
83489 + resetting the counter.
83490 +
83491 + @Return E_OK on success; Error code otherwise.
83492 +
83493 + @Cautions Allowed only following FM_PCD_Init() & FM_PCD_KgSchemeSet().
83494 +*//***************************************************************************/
83495 +t_Error FM_PCD_KgSchemeSetCounter(t_Handle h_Scheme, uint32_t value);
83496 +
83497 +/**************************************************************************//**
83498 + @Function FM_PCD_PlcrProfileSet
83499 +
83500 + @Description Sets a profile entry in the policer profile table.
83501 + The routine overrides any existing value.
83502 +
83503 + @Param[in] h_FmPcd A handle to an FM PCD Module.
83504 + @Param[in] p_Profile A structure of parameters for defining a
83505 + policer profile entry.
83506 +
83507 + @Return A handle to the initialized object on success; NULL code otherwise.
83508 + When used as "modify" (rather than for setting a new profile),
83509 + p_Profile->id.h_Profile will return NULL if action fails due to profile
83510 + BUSY state.
83511 + @Cautions Allowed only following FM_PCD_Init().
83512 +*//***************************************************************************/
83513 +t_Handle FM_PCD_PlcrProfileSet(t_Handle h_FmPcd,
83514 + t_FmPcdPlcrProfileParams *p_Profile);
83515 +
83516 +/**************************************************************************//**
83517 + @Function FM_PCD_PlcrProfileDelete
83518 +
83519 + @Description Delete a profile entry in the policer profile table.
83520 + The routine set entry to invalid.
83521 +
83522 + @Param[in] h_Profile A handle to the profile.
83523 +
83524 + @Return E_OK on success; Error code otherwise.
83525 +
83526 + @Cautions Allowed only following FM_PCD_Init().
83527 +*//***************************************************************************/
83528 +t_Error FM_PCD_PlcrProfileDelete(t_Handle h_Profile);
83529 +
83530 +/**************************************************************************//**
83531 + @Function FM_PCD_PlcrProfileGetCounter
83532 +
83533 + @Description Sets an entry in the classification plan.
83534 + The routine overrides any existing value.
83535 +
83536 + @Param[in] h_Profile A handle to the profile.
83537 + @Param[in] counter Counter selector.
83538 +
83539 + @Return specific counter value.
83540 +
83541 + @Cautions Allowed only following FM_PCD_Init().
83542 +*//***************************************************************************/
83543 +uint32_t FM_PCD_PlcrProfileGetCounter(t_Handle h_Profile,
83544 + e_FmPcdPlcrProfileCounters counter);
83545 +
83546 +/**************************************************************************//**
83547 + @Function FM_PCD_PlcrProfileSetCounter
83548 +
83549 + @Description Sets an entry in the classification plan.
83550 + The routine overrides any existing value.
83551 +
83552 + @Param[in] h_Profile A handle to the profile.
83553 + @Param[in] counter Counter selector.
83554 + @Param[in] value value to set counter with.
83555 +
83556 + @Return E_OK on success; Error code otherwise.
83557 +
83558 + @Cautions Allowed only following FM_PCD_Init().
83559 +*//***************************************************************************/
83560 +t_Error FM_PCD_PlcrProfileSetCounter(t_Handle h_Profile,
83561 + e_FmPcdPlcrProfileCounters counter,
83562 + uint32_t value);
83563 +
83564 +/**************************************************************************//**
83565 + @Function FM_PCD_CcRootBuild
83566 +
83567 + @Description This routine must be called to define a complete coarse
83568 + classification tree. This is the way to define coarse
83569 + classification to a certain flow - the KeyGen schemes
83570 + may point only to trees defined in this way.
83571 +
83572 + @Param[in] h_FmPcd FM PCD module descriptor.
83573 + @Param[in] p_Params A structure of parameters to define the tree.
83574 +
83575 + @Return A handle to the initialized object on success; NULL code otherwise.
83576 +
83577 + @Cautions Allowed only following FM_PCD_Init().
83578 +*//***************************************************************************/
83579 +t_Handle FM_PCD_CcRootBuild (t_Handle h_FmPcd,
83580 + t_FmPcdCcTreeParams *p_Params);
83581 +
83582 +/**************************************************************************//**
83583 + @Function FM_PCD_CcRootDelete
83584 +
83585 + @Description Deleting an built tree.
83586 +
83587 + @Param[in] h_CcTree A handle to a CC tree.
83588 +
83589 + @Return E_OK on success; Error code otherwise.
83590 +
83591 + @Cautions Allowed only following FM_PCD_Init().
83592 +*//***************************************************************************/
83593 +t_Error FM_PCD_CcRootDelete(t_Handle h_CcTree);
83594 +
83595 +/**************************************************************************//**
83596 + @Function FM_PCD_CcRootModifyNextEngine
83597 +
83598 + @Description Modify the Next Engine Parameters in the entry of the tree.
83599 +
83600 + @Param[in] h_CcTree A handle to the tree
83601 + @Param[in] grpId A Group index in the tree
83602 + @Param[in] index Entry index in the group defined by grpId
83603 + @Param[in] p_FmPcdCcNextEngineParams Pointer to new next engine parameters
83604 +
83605 + @Return E_OK on success; Error code otherwise.
83606 +
83607 + @Cautions Allowed only following FM_PCD_CcBuildTree().
83608 +*//***************************************************************************/
83609 +t_Error FM_PCD_CcRootModifyNextEngine(t_Handle h_CcTree,
83610 + uint8_t grpId,
83611 + uint8_t index,
83612 + t_FmPcdCcNextEngineParams *p_FmPcdCcNextEngineParams);
83613 +
83614 +/**************************************************************************//**
83615 + @Function FM_PCD_MatchTableSet
83616 +
83617 + @Description This routine should be called for each CC (coarse classification)
83618 + node. The whole CC tree should be built bottom up so that each
83619 + node points to already defined nodes.
83620 +
83621 + @Param[in] h_FmPcd FM PCD module descriptor.
83622 + @Param[in] p_Param A structure of parameters defining the CC node
83623 +
83624 + @Return A handle to the initialized object on success; NULL code otherwise.
83625 +
83626 + @Cautions Allowed only following FM_PCD_Init().
83627 +*//***************************************************************************/
83628 +t_Handle FM_PCD_MatchTableSet(t_Handle h_FmPcd, t_FmPcdCcNodeParams *p_Param);
83629 +
83630 +/**************************************************************************//**
83631 + @Function FM_PCD_MatchTableDelete
83632 +
83633 + @Description Deleting an built node.
83634 +
83635 + @Param[in] h_CcNode A handle to a CC node.
83636 +
83637 + @Return E_OK on success; Error code otherwise.
83638 +
83639 + @Cautions Allowed only following FM_PCD_Init().
83640 +*//***************************************************************************/
83641 +t_Error FM_PCD_MatchTableDelete(t_Handle h_CcNode);
83642 +
83643 +/**************************************************************************//**
83644 + @Function FM_PCD_MatchTableModifyMissNextEngine
83645 +
83646 + @Description Modify the Next Engine Parameters of the Miss key case of the node.
83647 +
83648 + @Param[in] h_CcNode A handle to the node
83649 + @Param[in] p_FmPcdCcNextEngineParams Parameters for defining next engine
83650 +
83651 + @Return E_OK on success; Error code otherwise.
83652 +
83653 + @Cautions Allowed only following FM_PCD_MatchTableSet();
83654 + Not relevant in the case the node is of type 'INDEXED_LOOKUP'.
83655 + When configuring nextEngine = e_FM_PCD_CC, note that
83656 + p_FmPcdCcNextEngineParams->ccParams.h_CcNode must be different
83657 + from the currently changed table.
83658 +
83659 +*//***************************************************************************/
83660 +t_Error FM_PCD_MatchTableModifyMissNextEngine(t_Handle h_CcNode,
83661 + t_FmPcdCcNextEngineParams *p_FmPcdCcNextEngineParams);
83662 +
83663 +/**************************************************************************//**
83664 + @Function FM_PCD_MatchTableRemoveKey
83665 +
83666 + @Description Remove the key (including next engine parameters of this key)
83667 + defined by the index of the relevant node.
83668 +
83669 + @Param[in] h_CcNode A handle to the node
83670 + @Param[in] keyIndex Key index for removing
83671 +
83672 + @Return E_OK on success; Error code otherwise.
83673 +
83674 + @Cautions Allowed only following FM_PCD_MatchTableSet() was called for this
83675 + node and the nodes that lead to it.
83676 +*//***************************************************************************/
83677 +t_Error FM_PCD_MatchTableRemoveKey(t_Handle h_CcNode, uint16_t keyIndex);
83678 +
83679 +/**************************************************************************//**
83680 + @Function FM_PCD_MatchTableAddKey
83681 +
83682 + @Description Add the key (including next engine parameters of this key in the
83683 + index defined by the keyIndex. Note that 'FM_PCD_LAST_KEY_INDEX'
83684 + may be used by user that don't care about the position of the
83685 + key in the table - in that case, the key will be automatically
83686 + added by the driver in the last available entry.
83687 +
83688 + @Param[in] h_CcNode A handle to the node
83689 + @Param[in] keyIndex Key index for adding.
83690 + @Param[in] keySize Key size of added key
83691 + @Param[in] p_KeyParams A pointer to the parameters includes
83692 + new key with Next Engine Parameters
83693 +
83694 + @Return E_OK on success; Error code otherwise.
83695 +
83696 + @Cautions Allowed only following FM_PCD_MatchTableSet() was called for this
83697 + node and the nodes that lead to it.
83698 +*//***************************************************************************/
83699 +t_Error FM_PCD_MatchTableAddKey(t_Handle h_CcNode,
83700 + uint16_t keyIndex,
83701 + uint8_t keySize,
83702 + t_FmPcdCcKeyParams *p_KeyParams);
83703 +
83704 +/**************************************************************************//**
83705 + @Function FM_PCD_MatchTableModifyNextEngine
83706 +
83707 + @Description Modify the Next Engine Parameters in the relevant key entry of the node.
83708 +
83709 + @Param[in] h_CcNode A handle to the node
83710 + @Param[in] keyIndex Key index for Next Engine modifications
83711 + @Param[in] p_FmPcdCcNextEngineParams Parameters for defining next engine
83712 +
83713 + @Return E_OK on success; Error code otherwise.
83714 +
83715 + @Cautions Allowed only following FM_PCD_MatchTableSet().
83716 + When configuring nextEngine = e_FM_PCD_CC, note that
83717 + p_FmPcdCcNextEngineParams->ccParams.h_CcNode must be different
83718 + from the currently changed table.
83719 +
83720 +*//***************************************************************************/
83721 +t_Error FM_PCD_MatchTableModifyNextEngine(t_Handle h_CcNode,
83722 + uint16_t keyIndex,
83723 + t_FmPcdCcNextEngineParams *p_FmPcdCcNextEngineParams);
83724 +
83725 +/**************************************************************************//**
83726 + @Function FM_PCD_MatchTableModifyKeyAndNextEngine
83727 +
83728 + @Description Modify the key and Next Engine Parameters of this key in the
83729 + index defined by the keyIndex.
83730 +
83731 + @Param[in] h_CcNode A handle to the node
83732 + @Param[in] keyIndex Key index for adding
83733 + @Param[in] keySize Key size of added key
83734 + @Param[in] p_KeyParams A pointer to the parameters includes
83735 + modified key and modified Next Engine Parameters
83736 +
83737 + @Return E_OK on success; Error code otherwise.
83738 +
83739 + @Cautions Allowed only following FM_PCD_MatchTableSet() was called for this
83740 + node and the nodes that lead to it.
83741 + When configuring nextEngine = e_FM_PCD_CC, note that
83742 + p_FmPcdCcNextEngineParams->ccParams.h_CcNode must be different
83743 + from the currently changed table.
83744 +*//***************************************************************************/
83745 +t_Error FM_PCD_MatchTableModifyKeyAndNextEngine(t_Handle h_CcNode,
83746 + uint16_t keyIndex,
83747 + uint8_t keySize,
83748 + t_FmPcdCcKeyParams *p_KeyParams);
83749 +
83750 +/**************************************************************************//**
83751 + @Function FM_PCD_MatchTableModifyKey
83752 +
83753 + @Description Modify the key in the index defined by the keyIndex.
83754 +
83755 + @Param[in] h_CcNode A handle to the node
83756 + @Param[in] keyIndex Key index for adding
83757 + @Param[in] keySize Key size of added key
83758 + @Param[in] p_Key A pointer to the new key
83759 + @Param[in] p_Mask A pointer to the new mask if relevant,
83760 + otherwise pointer to NULL
83761 +
83762 + @Return E_OK on success; Error code otherwise.
83763 +
83764 + @Cautions Allowed only following FM_PCD_MatchTableSet() was called for this
83765 + node and the nodes that lead to it.
83766 +*//***************************************************************************/
83767 +t_Error FM_PCD_MatchTableModifyKey(t_Handle h_CcNode,
83768 + uint16_t keyIndex,
83769 + uint8_t keySize,
83770 + uint8_t *p_Key,
83771 + uint8_t *p_Mask);
83772 +
83773 +/**************************************************************************//**
83774 + @Function FM_PCD_MatchTableFindNRemoveKey
83775 +
83776 + @Description Remove the key (including next engine parameters of this key)
83777 + defined by the key and mask. Note that this routine will search
83778 + the node to locate the index of the required key (& mask) to remove.
83779 +
83780 + @Param[in] h_CcNode A handle to the node
83781 + @Param[in] keySize Key size of the one to remove.
83782 + @Param[in] p_Key A pointer to the requested key to remove.
83783 + @Param[in] p_Mask A pointer to the mask if relevant,
83784 + otherwise pointer to NULL
83785 +
83786 + @Return E_OK on success; Error code otherwise.
83787 +
83788 + @Cautions Allowed only following FM_PCD_MatchTableSet() was called for this
83789 + node and the nodes that lead to it.
83790 +*//***************************************************************************/
83791 +t_Error FM_PCD_MatchTableFindNRemoveKey(t_Handle h_CcNode,
83792 + uint8_t keySize,
83793 + uint8_t *p_Key,
83794 + uint8_t *p_Mask);
83795 +
83796 +/**************************************************************************//**
83797 + @Function FM_PCD_MatchTableFindNModifyNextEngine
83798 +
83799 + @Description Modify the Next Engine Parameters in the relevant key entry of
83800 + the node. Note that this routine will search the node to locate
83801 + the index of the required key (& mask) to modify.
83802 +
83803 + @Param[in] h_CcNode A handle to the node
83804 + @Param[in] keySize Key size of the one to modify.
83805 + @Param[in] p_Key A pointer to the requested key to modify.
83806 + @Param[in] p_Mask A pointer to the mask if relevant,
83807 + otherwise pointer to NULL
83808 + @Param[in] p_FmPcdCcNextEngineParams Parameters for defining next engine
83809 +
83810 + @Return E_OK on success; Error code otherwise.
83811 +
83812 + @Cautions Allowed only following FM_PCD_MatchTableSet().
83813 + When configuring nextEngine = e_FM_PCD_CC, note that
83814 + p_FmPcdCcNextEngineParams->ccParams.h_CcNode must be different
83815 + from the currently changed table.
83816 +*//***************************************************************************/
83817 +t_Error FM_PCD_MatchTableFindNModifyNextEngine(t_Handle h_CcNode,
83818 + uint8_t keySize,
83819 + uint8_t *p_Key,
83820 + uint8_t *p_Mask,
83821 + t_FmPcdCcNextEngineParams *p_FmPcdCcNextEngineParams);
83822 +
83823 +/**************************************************************************//**
83824 + @Function FM_PCD_MatchTableFindNModifyKeyAndNextEngine
83825 +
83826 + @Description Modify the key and Next Engine Parameters of this key in the
83827 + index defined by the keyIndex. Note that this routine will search
83828 + the node to locate the index of the required key (& mask) to modify.
83829 +
83830 + @Param[in] h_CcNode A handle to the node
83831 + @Param[in] keySize Key size of the one to modify.
83832 + @Param[in] p_Key A pointer to the requested key to modify.
83833 + @Param[in] p_Mask A pointer to the mask if relevant,
83834 + otherwise pointer to NULL
83835 + @Param[in] p_KeyParams A pointer to the parameters includes
83836 + modified key and modified Next Engine Parameters
83837 +
83838 + @Return E_OK on success; Error code otherwise.
83839 +
83840 + @Cautions Allowed only following FM_PCD_MatchTableSet() was called for this
83841 + node and the nodes that lead to it.
83842 + When configuring nextEngine = e_FM_PCD_CC, note that
83843 + p_FmPcdCcNextEngineParams->ccParams.h_CcNode must be different
83844 + from the currently changed table.
83845 +*//***************************************************************************/
83846 +t_Error FM_PCD_MatchTableFindNModifyKeyAndNextEngine(t_Handle h_CcNode,
83847 + uint8_t keySize,
83848 + uint8_t *p_Key,
83849 + uint8_t *p_Mask,
83850 + t_FmPcdCcKeyParams *p_KeyParams);
83851 +
83852 +/**************************************************************************//**
83853 + @Function FM_PCD_MatchTableFindNModifyKey
83854 +
83855 + @Description Modify the key in the index defined by the keyIndex. Note that
83856 + this routine will search the node to locate the index of the
83857 + required key (& mask) to modify.
83858 +
83859 + @Param[in] h_CcNode A handle to the node
83860 + @Param[in] keySize Key size of the one to modify.
83861 + @Param[in] p_Key A pointer to the requested key to modify.
83862 + @Param[in] p_Mask A pointer to the mask if relevant,
83863 + otherwise pointer to NULL
83864 + @Param[in] p_NewKey A pointer to the new key
83865 + @Param[in] p_NewMask A pointer to the new mask if relevant,
83866 + otherwise pointer to NULL
83867 +
83868 + @Return E_OK on success; Error code otherwise.
83869 +
83870 + @Cautions Allowed only following FM_PCD_MatchTableSet() was called for this
83871 + node and the nodes that lead to it.
83872 +*//***************************************************************************/
83873 +t_Error FM_PCD_MatchTableFindNModifyKey(t_Handle h_CcNode,
83874 + uint8_t keySize,
83875 + uint8_t *p_Key,
83876 + uint8_t *p_Mask,
83877 + uint8_t *p_NewKey,
83878 + uint8_t *p_NewMask);
83879 +
83880 +/**************************************************************************//**
83881 + @Function FM_PCD_MatchTableGetKeyCounter
83882 +
83883 + @Description This routine may be used to get a counter of specific key in a CC
83884 + Node; This counter reflects how many frames passed that were matched
83885 + this key.
83886 +
83887 + @Param[in] h_CcNode A handle to the node
83888 + @Param[in] keyIndex Key index for adding
83889 +
83890 + @Return The specific key counter.
83891 +
83892 + @Cautions Allowed only following FM_PCD_MatchTableSet().
83893 +*//***************************************************************************/
83894 +uint32_t FM_PCD_MatchTableGetKeyCounter(t_Handle h_CcNode, uint16_t keyIndex);
83895 +
83896 +/**************************************************************************//**
83897 + @Function FM_PCD_MatchTableGetKeyStatistics
83898 +
83899 + @Description This routine may be used to get statistics counters of specific key
83900 + in a CC Node.
83901 +
83902 + If 'e_FM_PCD_CC_STATS_MODE_FRAME' and
83903 + 'e_FM_PCD_CC_STATS_MODE_BYTE_AND_FRAME' were set for this node,
83904 + these counters reflect how many frames passed that were matched
83905 + this key; The total frames count will be returned in the counter
83906 + of the first range (as only one frame length range was defined).
83907 + If 'e_FM_PCD_CC_STATS_MODE_RMON' was set for this node, the total
83908 + frame count will be separated to frame length counters, based on
83909 + provided frame length ranges.
83910 +
83911 + @Param[in] h_CcNode A handle to the node
83912 + @Param[in] keyIndex Key index for adding
83913 + @Param[out] p_KeyStatistics Key statistics counters
83914 +
83915 + @Return The specific key statistics.
83916 +
83917 + @Cautions Allowed only following FM_PCD_MatchTableSet().
83918 +*//***************************************************************************/
83919 +t_Error FM_PCD_MatchTableGetKeyStatistics(t_Handle h_CcNode,
83920 + uint16_t keyIndex,
83921 + t_FmPcdCcKeyStatistics *p_KeyStatistics);
83922 +
83923 +/**************************************************************************//**
83924 + @Function FM_PCD_MatchTableGetMissStatistics
83925 +
83926 + @Description This routine may be used to get statistics counters of miss entry
83927 + in a CC Node.
83928 +
83929 + If 'e_FM_PCD_CC_STATS_MODE_FRAME' and
83930 + 'e_FM_PCD_CC_STATS_MODE_BYTE_AND_FRAME' were set for this node,
83931 + these counters reflect how many frames were not matched to any
83932 + existing key and therefore passed through the miss entry; The
83933 + total frames count will be returned in the counter of the
83934 + first range (as only one frame length range was defined).
83935 +
83936 + @Param[in] h_CcNode A handle to the node
83937 + @Param[out] p_MissStatistics Statistics counters for 'miss'
83938 +
83939 + @Return The statistics for 'miss'.
83940 +
83941 + @Cautions Allowed only following FM_PCD_MatchTableSet().
83942 +*//***************************************************************************/
83943 +t_Error FM_PCD_MatchTableGetMissStatistics(t_Handle h_CcNode,
83944 + t_FmPcdCcKeyStatistics *p_MissStatistics);
83945 +
83946 +/**************************************************************************//**
83947 + @Function FM_PCD_MatchTableFindNGetKeyStatistics
83948 +
83949 + @Description This routine may be used to get statistics counters of specific key
83950 + in a CC Node.
83951 +
83952 + If 'e_FM_PCD_CC_STATS_MODE_FRAME' and
83953 + 'e_FM_PCD_CC_STATS_MODE_BYTE_AND_FRAME' were set for this node,
83954 + these counters reflect how many frames passed that were matched
83955 + this key; The total frames count will be returned in the counter
83956 + of the first range (as only one frame length range was defined).
83957 + If 'e_FM_PCD_CC_STATS_MODE_RMON' was set for this node, the total
83958 + frame count will be separated to frame length counters, based on
83959 + provided frame length ranges.
83960 + Note that this routine will search the node to locate the index
83961 + of the required key based on received key parameters.
83962 +
83963 + @Param[in] h_CcNode A handle to the node
83964 + @Param[in] keySize Size of the requested key
83965 + @Param[in] p_Key A pointer to the requested key
83966 + @Param[in] p_Mask A pointer to the mask if relevant,
83967 + otherwise pointer to NULL
83968 + @Param[out] p_KeyStatistics Key statistics counters
83969 +
83970 + @Return The specific key statistics.
83971 +
83972 + @Cautions Allowed only following FM_PCD_MatchTableSet().
83973 +*//***************************************************************************/
83974 +t_Error FM_PCD_MatchTableFindNGetKeyStatistics(t_Handle h_CcNode,
83975 + uint8_t keySize,
83976 + uint8_t *p_Key,
83977 + uint8_t *p_Mask,
83978 + t_FmPcdCcKeyStatistics *p_KeyStatistics);
83979 +
83980 +/**************************************************************************//*
83981 + @Function FM_PCD_MatchTableGetNextEngine
83982 +
83983 + @Description Gets NextEngine of the relevant keyIndex.
83984 +
83985 + @Param[in] h_CcNode A handle to the node.
83986 + @Param[in] keyIndex keyIndex in the relevant node.
83987 + @Param[out] p_FmPcdCcNextEngineParams here updated nextEngine parameters for
83988 + the relevant keyIndex of the CC Node
83989 + received as parameter to this function
83990 +
83991 + @Return E_OK on success; Error code otherwise.
83992 +
83993 + @Cautions Allowed only following FM_PCD_Init().
83994 +*//***************************************************************************/
83995 +t_Error FM_PCD_MatchTableGetNextEngine(t_Handle h_CcNode,
83996 + uint16_t keyIndex,
83997 + t_FmPcdCcNextEngineParams *p_FmPcdCcNextEngineParams);
83998 +
83999 +/**************************************************************************//*
84000 + @Function FM_PCD_MatchTableGetIndexedHashBucket
84001 +
84002 + @Description This routine simulates KeyGen operation on the provided key and
84003 + calculates to which hash bucket it will be mapped.
84004 +
84005 + @Param[in] h_CcNode A handle to the node.
84006 + @Param[in] kgKeySize Key size as it was configured in the KG
84007 + scheme that leads to this hash.
84008 + @Param[in] p_KgKey Pointer to the key; must be like the key
84009 + that the KG is generated, i.e. the same
84010 + extraction and with mask if exist.
84011 + @Param[in] kgHashShift Hash-shift as it was configured in the KG
84012 + scheme that leads to this hash.
84013 + @Param[out] p_CcNodeBucketHandle Pointer to the bucket of the provided key.
84014 + @Param[out] p_BucketIndex Index to the bucket of the provided key
84015 + @Param[out] p_LastIndex Pointer to last index in the bucket of the
84016 + provided key.
84017 +
84018 + @Return E_OK on success; Error code otherwise.
84019 +
84020 + @Cautions Allowed only following FM_PCD_HashTableSet()
84021 +*//***************************************************************************/
84022 +t_Error FM_PCD_MatchTableGetIndexedHashBucket(t_Handle h_CcNode,
84023 + uint8_t kgKeySize,
84024 + uint8_t *p_KgKey,
84025 + uint8_t kgHashShift,
84026 + t_Handle *p_CcNodeBucketHandle,
84027 + uint8_t *p_BucketIndex,
84028 + uint16_t *p_LastIndex);
84029 +
84030 +/**************************************************************************//**
84031 + @Function FM_PCD_HashTableSet
84032 +
84033 + @Description This routine initializes a hash table structure.
84034 + KeyGen hash result determines the hash bucket.
84035 + Next, KeyGen key is compared against all keys of this
84036 + bucket (exact match).
84037 + Number of sets (number of buckets) of the hash equals to the
84038 + number of 1-s in 'hashResMask' in the provided parameters.
84039 + Number of hash table ways is then calculated by dividing
84040 + 'maxNumOfKeys' equally between the hash sets. This is the maximal
84041 + number of keys that a hash bucket may hold.
84042 + The hash table is initialized empty and keys may be
84043 + added to it following the initialization. Keys masks are not
84044 + supported in current hash table implementation.
84045 + The initialized hash table can be integrated as a node in a
84046 + CC tree.
84047 +
84048 + @Param[in] h_FmPcd FM PCD module descriptor.
84049 + @Param[in] p_Param A structure of parameters defining the hash table
84050 +
84051 + @Return A handle to the initialized object on success; NULL code otherwise.
84052 +
84053 + @Cautions Allowed only following FM_PCD_Init().
84054 +*//***************************************************************************/
84055 +t_Handle FM_PCD_HashTableSet(t_Handle h_FmPcd, t_FmPcdHashTableParams *p_Param);
84056 +
84057 +/**************************************************************************//**
84058 + @Function FM_PCD_HashTableDelete
84059 +
84060 + @Description This routine deletes the provided hash table and released all
84061 + its allocated resources.
84062 +
84063 + @Param[in] h_HashTbl A handle to a hash table
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_HashTableDelete(t_Handle h_HashTbl);
84070 +
84071 +/**************************************************************************//**
84072 + @Function FM_PCD_HashTableAddKey
84073 +
84074 + @Description This routine adds the provided key (including next engine
84075 + parameters of this key) to the hash table.
84076 + The key is added as the last key of the bucket that it is
84077 + mapped to.
84078 +
84079 + @Param[in] h_HashTbl A handle to a hash table
84080 + @Param[in] keySize Key size of added key
84081 + @Param[in] p_KeyParams A pointer to the parameters includes
84082 + new key with next engine parameters; The pointer
84083 + to the key mask must be NULL, as masks are not
84084 + supported in hash table implementation.
84085 +
84086 + @Return E_OK on success; Error code otherwise.
84087 +
84088 + @Cautions Allowed only following FM_PCD_HashTableSet().
84089 +*//***************************************************************************/
84090 +t_Error FM_PCD_HashTableAddKey(t_Handle h_HashTbl,
84091 + uint8_t keySize,
84092 + t_FmPcdCcKeyParams *p_KeyParams);
84093 +
84094 +/**************************************************************************//**
84095 + @Function FM_PCD_HashTableRemoveKey
84096 +
84097 + @Description This routine removes the requested key (including next engine
84098 + parameters of this key) from the hash table.
84099 +
84100 + @Param[in] h_HashTbl A handle to a hash table
84101 + @Param[in] keySize Key size of the one to remove.
84102 + @Param[in] p_Key A pointer to the requested key to remove.
84103 +
84104 + @Return E_OK on success; Error code otherwise.
84105 +
84106 + @Cautions Allowed only following FM_PCD_HashTableSet().
84107 +*//***************************************************************************/
84108 +t_Error FM_PCD_HashTableRemoveKey(t_Handle h_HashTbl,
84109 + uint8_t keySize,
84110 + uint8_t *p_Key);
84111 +
84112 +/**************************************************************************//**
84113 + @Function FM_PCD_HashTableModifyNextEngine
84114 +
84115 + @Description This routine modifies the next engine for the provided key. The
84116 + key should be previously added to the hash table.
84117 +
84118 + @Param[in] h_HashTbl A handle to a hash table
84119 + @Param[in] keySize Key size of the key to modify.
84120 + @Param[in] p_Key A pointer to the requested key to modify.
84121 + @Param[in] p_FmPcdCcNextEngineParams A structure for defining new next engine
84122 + parameters.
84123 +
84124 + @Return E_OK on success; Error code otherwise.
84125 +
84126 + @Cautions Allowed only following FM_PCD_HashTableSet().
84127 + When configuring nextEngine = e_FM_PCD_CC, note that
84128 + p_FmPcdCcNextEngineParams->ccParams.h_CcNode must be different
84129 + from the currently changed table.
84130 +*//***************************************************************************/
84131 +t_Error FM_PCD_HashTableModifyNextEngine(t_Handle h_HashTbl,
84132 + uint8_t keySize,
84133 + uint8_t *p_Key,
84134 + t_FmPcdCcNextEngineParams *p_FmPcdCcNextEngineParams);
84135 +
84136 +/**************************************************************************//**
84137 + @Function FM_PCD_HashTableModifyMissNextEngine
84138 +
84139 + @Description This routine modifies the next engine on key match miss.
84140 +
84141 + @Param[in] h_HashTbl A handle to a hash table
84142 + @Param[in] p_FmPcdCcNextEngineParams A structure for defining new next engine
84143 + parameters.
84144 +
84145 + @Return E_OK on success; Error code otherwise.
84146 +
84147 + @Cautions Allowed only following FM_PCD_HashTableSet().
84148 + When configuring nextEngine = e_FM_PCD_CC, note that
84149 + p_FmPcdCcNextEngineParams->ccParams.h_CcNode must be different
84150 + from the currently changed table.
84151 +*//***************************************************************************/
84152 +t_Error FM_PCD_HashTableModifyMissNextEngine(t_Handle h_HashTbl,
84153 + t_FmPcdCcNextEngineParams *p_FmPcdCcNextEngineParams);
84154 +
84155 +/**************************************************************************//*
84156 + @Function FM_PCD_HashTableGetMissNextEngine
84157 +
84158 + @Description Gets NextEngine in case of key match miss.
84159 +
84160 + @Param[in] h_HashTbl A handle to a hash table
84161 + @Param[out] p_FmPcdCcNextEngineParams Next engine parameters for the specified
84162 + hash table.
84163 +
84164 + @Return E_OK on success; Error code otherwise.
84165 +
84166 + @Cautions Allowed only following FM_PCD_HashTableSet().
84167 +*//***************************************************************************/
84168 +t_Error FM_PCD_HashTableGetMissNextEngine(t_Handle h_HashTbl,
84169 + t_FmPcdCcNextEngineParams *p_FmPcdCcNextEngineParams);
84170 +
84171 +/**************************************************************************//**
84172 + @Function FM_PCD_HashTableFindNGetKeyStatistics
84173 +
84174 + @Description This routine may be used to get statistics counters of specific key
84175 + in a hash table.
84176 +
84177 + If 'e_FM_PCD_CC_STATS_MODE_FRAME' and
84178 + 'e_FM_PCD_CC_STATS_MODE_BYTE_AND_FRAME' were set for this node,
84179 + these counters reflect how many frames passed that were matched
84180 + this key; The total frames count will be returned in the counter
84181 + of the first range (as only one frame length range was defined).
84182 + If 'e_FM_PCD_CC_STATS_MODE_RMON' was set for this node, the total
84183 + frame count will be separated to frame length counters, based on
84184 + provided frame length ranges.
84185 + Note that this routine will identify the bucket of this key in
84186 + the hash table and will search the bucket to locate the index
84187 + of the required key based on received key parameters.
84188 +
84189 + @Param[in] h_HashTbl A handle to a hash table
84190 + @Param[in] keySize Size of the requested key
84191 + @Param[in] p_Key A pointer to the requested key
84192 + @Param[out] p_KeyStatistics Key statistics counters
84193 +
84194 + @Return The specific key statistics.
84195 +
84196 + @Cautions Allowed only following FM_PCD_HashTableSet().
84197 +*//***************************************************************************/
84198 +t_Error FM_PCD_HashTableFindNGetKeyStatistics(t_Handle h_HashTbl,
84199 + uint8_t keySize,
84200 + uint8_t *p_Key,
84201 + t_FmPcdCcKeyStatistics *p_KeyStatistics);
84202 +
84203 +/**************************************************************************//**
84204 + @Function FM_PCD_HashTableGetMissStatistics
84205 +
84206 + @Description This routine may be used to get statistics counters of 'miss'
84207 + entry of the a hash table.
84208 +
84209 + If 'e_FM_PCD_CC_STATS_MODE_FRAME' and
84210 + 'e_FM_PCD_CC_STATS_MODE_BYTE_AND_FRAME' were set for this node,
84211 + these counters reflect how many frames were not matched to any
84212 + existing key and therefore passed through the miss entry;
84213 +
84214 + @Param[in] h_HashTbl A handle to a hash table
84215 + @Param[out] p_MissStatistics Statistics counters for 'miss'
84216 +
84217 + @Return The statistics for 'miss'.
84218 +
84219 + @Cautions Allowed only following FM_PCD_HashTableSet().
84220 +*//***************************************************************************/
84221 +t_Error FM_PCD_HashTableGetMissStatistics(t_Handle h_HashTbl,
84222 + t_FmPcdCcKeyStatistics *p_MissStatistics);
84223 +
84224 +/**************************************************************************//**
84225 + @Function FM_PCD_ManipNodeSet
84226 +
84227 + @Description This routine should be called for defining a manipulation
84228 + node. A manipulation node must be defined before the CC node
84229 + that precedes it.
84230 +
84231 + @Param[in] h_FmPcd FM PCD module descriptor.
84232 + @Param[in] p_FmPcdManipParams A structure of parameters defining the manipulation
84233 +
84234 + @Return A handle to the initialized object on success; NULL code otherwise.
84235 +
84236 + @Cautions Allowed only following FM_PCD_Init().
84237 +*//***************************************************************************/
84238 +t_Handle FM_PCD_ManipNodeSet(t_Handle h_FmPcd, t_FmPcdManipParams *p_FmPcdManipParams);
84239 +
84240 +/**************************************************************************//**
84241 + @Function FM_PCD_ManipNodeDelete
84242 +
84243 + @Description Delete an existing manipulation node.
84244 +
84245 + @Param[in] h_ManipNode A handle to a manipulation node.
84246 +
84247 + @Return E_OK on success; Error code otherwise.
84248 +
84249 + @Cautions Allowed only following FM_PCD_ManipNodeSet().
84250 +*//***************************************************************************/
84251 +t_Error FM_PCD_ManipNodeDelete(t_Handle h_ManipNode);
84252 +
84253 +/**************************************************************************//**
84254 + @Function FM_PCD_ManipGetStatistics
84255 +
84256 + @Description Retrieve the manipulation statistics.
84257 +
84258 + @Param[in] h_ManipNode A handle to a manipulation node.
84259 + @Param[out] p_FmPcdManipStats A structure for retrieving the manipulation statistics
84260 +
84261 + @Return E_OK on success; Error code otherwise.
84262 +
84263 + @Cautions Allowed only following FM_PCD_ManipNodeSet().
84264 +*//***************************************************************************/
84265 +t_Error FM_PCD_ManipGetStatistics(t_Handle h_ManipNode, t_FmPcdManipStats *p_FmPcdManipStats);
84266 +
84267 +/**************************************************************************//**
84268 + @Function FM_PCD_ManipNodeReplace
84269 +
84270 + @Description Change existing manipulation node to be according to new requirement.
84271 +
84272 + @Param[in] h_ManipNode A handle to a manipulation node.
84273 + @Param[out] p_ManipParams A structure of parameters defining the change requirement
84274 +
84275 + @Return E_OK on success; Error code otherwise.
84276 +
84277 + @Cautions Allowed only following FM_PCD_ManipNodeSet().
84278 +*//***************************************************************************/
84279 +t_Error FM_PCD_ManipNodeReplace(t_Handle h_ManipNode, t_FmPcdManipParams *p_ManipParams);
84280 +
84281 +#if (DPAA_VERSION >= 11)
84282 +/**************************************************************************//**
84283 + @Function FM_PCD_FrmReplicSetGroup
84284 +
84285 + @Description Initialize a Frame Replicator group.
84286 +
84287 + @Param[in] h_FmPcd FM PCD module descriptor.
84288 + @Param[in] p_FrmReplicGroupParam A structure of parameters for the initialization of
84289 + the frame replicator group.
84290 +
84291 + @Return A handle to the initialized object on success; NULL code otherwise.
84292 +
84293 + @Cautions Allowed only following FM_PCD_Init().
84294 +*//***************************************************************************/
84295 +t_Handle FM_PCD_FrmReplicSetGroup(t_Handle h_FmPcd, t_FmPcdFrmReplicGroupParams *p_FrmReplicGroupParam);
84296 +
84297 +/**************************************************************************//**
84298 + @Function FM_PCD_FrmReplicDeleteGroup
84299 +
84300 + @Description Delete a Frame Replicator group.
84301 +
84302 + @Param[in] h_FrmReplicGroup A handle to the frame replicator group.
84303 +
84304 + @Return E_OK on success; Error code otherwise.
84305 +
84306 + @Cautions Allowed only following FM_PCD_FrmReplicSetGroup().
84307 +*//***************************************************************************/
84308 +t_Error FM_PCD_FrmReplicDeleteGroup(t_Handle h_FrmReplicGroup);
84309 +
84310 +/**************************************************************************//**
84311 + @Function FM_PCD_FrmReplicAddMember
84312 +
84313 + @Description Add the member in the index defined by the memberIndex.
84314 +
84315 + @Param[in] h_FrmReplicGroup A handle to the frame replicator group.
84316 + @Param[in] memberIndex member index for adding.
84317 + @Param[in] p_MemberParams A pointer to the new member parameters.
84318 +
84319 + @Return E_OK on success; Error code otherwise.
84320 +
84321 + @Cautions Allowed only following FM_PCD_FrmReplicSetGroup() of this group.
84322 +*//***************************************************************************/
84323 +t_Error FM_PCD_FrmReplicAddMember(t_Handle h_FrmReplicGroup,
84324 + uint16_t memberIndex,
84325 + t_FmPcdCcNextEngineParams *p_MemberParams);
84326 +
84327 +/**************************************************************************//**
84328 + @Function FM_PCD_FrmReplicRemoveMember
84329 +
84330 + @Description Remove the member defined by the index from the relevant group.
84331 +
84332 + @Param[in] h_FrmReplicGroup A handle to the frame replicator group.
84333 + @Param[in] memberIndex member index for removing.
84334 +
84335 + @Return E_OK on success; Error code otherwise.
84336 +
84337 + @Cautions Allowed only following FM_PCD_FrmReplicSetGroup() of this group.
84338 +*//***************************************************************************/
84339 +t_Error FM_PCD_FrmReplicRemoveMember(t_Handle h_FrmReplicGroup,
84340 + uint16_t memberIndex);
84341 +#endif /* (DPAA_VERSION >= 11) */
84342 +
84343 +#if ((DPAA_VERSION == 10) && defined(FM_CAPWAP_SUPPORT))
84344 +/**************************************************************************//**
84345 + @Function FM_PCD_StatisticsSetNode
84346 +
84347 + @Description This routine should be called for defining a statistics node.
84348 +
84349 + @Param[in] h_FmPcd FM PCD module descriptor.
84350 + @Param[in] p_FmPcdstatsParams A structure of parameters defining the statistics
84351 +
84352 + @Return A handle to the initialized object on success; NULL code otherwise.
84353 +
84354 + @Cautions Allowed only following FM_PCD_Init().
84355 +*//***************************************************************************/
84356 +t_Handle FM_PCD_StatisticsSetNode(t_Handle h_FmPcd, t_FmPcdStatsParams *p_FmPcdstatsParams);
84357 +#endif /* ((DPAA_VERSION == 10) && defined(FM_CAPWAP_SUPPORT)) */
84358 +
84359 +/** @} */ /* end of FM_PCD_Runtime_build_grp group */
84360 +/** @} */ /* end of FM_PCD_Runtime_grp group */
84361 +/** @} */ /* end of FM_PCD_grp group */
84362 +/** @} */ /* end of FM_grp group */
84363 +
84364 +
84365 +#ifdef NCSW_BACKWARD_COMPATIBLE_API
84366 +#define FM_PCD_MAX_NUM_OF_INTERCHANGABLE_HDRS FM_PCD_MAX_NUM_OF_INTERCHANGEABLE_HDRS
84367 +#define e_FM_PCD_MANIP_ONE_WAYS_HASH e_FM_PCD_MANIP_ONE_WAY_HASH
84368 +#define e_FM_PCD_MANIP_TOW_WAYS_HASH e_FM_PCD_MANIP_TWO_WAYS_HASH
84369 +
84370 +#define e_FM_PCD_MANIP_FRAGMENT_PACKECT e_FM_PCD_MANIP_FRAGMENT_PACKET /* Feb13 */
84371 +
84372 +#define FM_PCD_SetNetEnvCharacteristics(_pcd, _params) \
84373 + FM_PCD_NetEnvCharacteristicsSet(_pcd, _params)
84374 +#define FM_PCD_KgSetScheme(_pcd, _params) FM_PCD_KgSchemeSet(_pcd, _params)
84375 +#define FM_PCD_CcBuildTree(_pcd, _params) FM_PCD_CcRootBuild(_pcd, _params)
84376 +#define FM_PCD_CcSetNode(_pcd, _params) FM_PCD_MatchTableSet(_pcd, _params)
84377 +#define FM_PCD_PlcrSetProfile(_pcd, _params) FM_PCD_PlcrProfileSet(_pcd, _params)
84378 +#define FM_PCD_ManipSetNode(_pcd, _params) FM_PCD_ManipNodeSet(_pcd, _params)
84379 +
84380 +#define FM_PCD_DeleteNetEnvCharacteristics(_pcd, ...) \
84381 + FM_PCD_NetEnvCharacteristicsDelete(__VA_ARGS__)
84382 +#define FM_PCD_KgDeleteScheme(_pcd, ...) \
84383 + FM_PCD_KgSchemeDelete(__VA_ARGS__)
84384 +#define FM_PCD_KgGetSchemeCounter(_pcd, ...) \
84385 + FM_PCD_KgSchemeGetCounter(__VA_ARGS__)
84386 +#define FM_PCD_KgSetSchemeCounter(_pcd, ...) \
84387 + FM_PCD_KgSchemeSetCounter(__VA_ARGS__)
84388 +#define FM_PCD_PlcrDeleteProfile(_pcd, ...) \
84389 + FM_PCD_PlcrProfileDelete(__VA_ARGS__)
84390 +#define FM_PCD_PlcrGetProfileCounter(_pcd, ...) \
84391 + FM_PCD_PlcrProfileGetCounter(__VA_ARGS__)
84392 +#define FM_PCD_PlcrSetProfileCounter(_pcd, ...) \
84393 + FM_PCD_PlcrProfileSetCounter(__VA_ARGS__)
84394 +#define FM_PCD_CcDeleteTree(_pcd, ...) \
84395 + FM_PCD_CcRootDelete(__VA_ARGS__)
84396 +#define FM_PCD_CcTreeModifyNextEngine(_pcd, ...) \
84397 + FM_PCD_CcRootModifyNextEngine(__VA_ARGS__)
84398 +#define FM_PCD_CcDeleteNode(_pcd, ...) \
84399 + FM_PCD_MatchTableDelete(__VA_ARGS__)
84400 +#define FM_PCD_CcNodeModifyMissNextEngine(_pcd, ...) \
84401 + FM_PCD_MatchTableModifyMissNextEngine(__VA_ARGS__)
84402 +#define FM_PCD_CcNodeRemoveKey(_pcd, ...) \
84403 + FM_PCD_MatchTableRemoveKey(__VA_ARGS__)
84404 +#define FM_PCD_CcNodeAddKey(_pcd, ...) \
84405 + FM_PCD_MatchTableAddKey(__VA_ARGS__)
84406 +#define FM_PCD_CcNodeModifyNextEngine(_pcd, ...) \
84407 + FM_PCD_MatchTableModifyNextEngine(__VA_ARGS__)
84408 +#define FM_PCD_CcNodeModifyKeyAndNextEngine(_pcd, ...) \
84409 + FM_PCD_MatchTableModifyKeyAndNextEngine(__VA_ARGS__)
84410 +#define FM_PCD_CcNodeModifyKey(_pcd, ...) \
84411 + FM_PCD_MatchTableModifyKey(__VA_ARGS__)
84412 +#define FM_PCD_CcNodeFindNRemoveKey(_pcd, ...) \
84413 + FM_PCD_MatchTableFindNRemoveKey(__VA_ARGS__)
84414 +#define FM_PCD_CcNodeFindNModifyNextEngine(_pcd, ...) \
84415 + FM_PCD_MatchTableFindNModifyNextEngine(__VA_ARGS__)
84416 +#define FM_PCD_CcNodeFindNModifyKeyAndNextEngine(_pcd, ...) \
84417 + FM_PCD_MatchTableFindNModifyKeyAndNextEngine(__VA_ARGS__)
84418 +#define FM_PCD_CcNodeFindNModifyKey(_pcd, ...) \
84419 + FM_PCD_MatchTableFindNModifyKey(__VA_ARGS__)
84420 +#define FM_PCD_CcIndexedHashNodeGetBucket(_pcd, ...) \
84421 + FM_PCD_MatchTableGetIndexedHashBucket(__VA_ARGS__)
84422 +#define FM_PCD_CcNodeGetNextEngine(_pcd, ...) \
84423 + FM_PCD_MatchTableGetNextEngine(__VA_ARGS__)
84424 +#define FM_PCD_CcNodeGetKeyCounter(_pcd, ...) \
84425 + FM_PCD_MatchTableGetKeyCounter(__VA_ARGS__)
84426 +#define FM_PCD_ManipDeleteNode(_pcd, ...) \
84427 + FM_PCD_ManipNodeDelete(__VA_ARGS__)
84428 +#endif /* NCSW_BACKWARD_COMPATIBLE_API */
84429 +
84430 +
84431 +#endif /* __FM_PCD_EXT */
84432 --- /dev/null
84433 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/Peripherals/fm_port_ext.h
84434 @@ -0,0 +1,2608 @@
84435 +/* Copyright (c) 2008-2012 Freescale Semiconductor, Inc.
84436 + * All rights reserved.
84437 + *
84438 + * Redistribution and use in source and binary forms, with or without
84439 + * modification, are permitted provided that the following conditions are met:
84440 + * * Redistributions of source code must retain the above copyright
84441 + * notice, this list of conditions and the following disclaimer.
84442 + * * Redistributions in binary form must reproduce the above copyright
84443 + * notice, this list of conditions and the following disclaimer in the
84444 + * documentation and/or other materials provided with the distribution.
84445 + * * Neither the name of Freescale Semiconductor nor the
84446 + * names of its contributors may be used to endorse or promote products
84447 + * derived from this software without specific prior written permission.
84448 + *
84449 + *
84450 + * ALTERNATIVELY, this software may be distributed under the terms of the
84451 + * GNU General Public License ("GPL") as published by the Free Software
84452 + * Foundation, either version 2 of that License or (at your option) any
84453 + * later version.
84454 + *
84455 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
84456 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
84457 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
84458 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
84459 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
84460 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
84461 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
84462 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
84463 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
84464 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
84465 + */
84466 +
84467 +
84468 +/**************************************************************************//**
84469 + @File fm_port_ext.h
84470 +
84471 + @Description FM-Port Application Programming Interface.
84472 +*//***************************************************************************/
84473 +#ifndef __FM_PORT_EXT
84474 +#define __FM_PORT_EXT
84475 +
84476 +#include "error_ext.h"
84477 +#include "std_ext.h"
84478 +#include "fm_pcd_ext.h"
84479 +#include "fm_ext.h"
84480 +#include "net_ext.h"
84481 +
84482 +
84483 +/**************************************************************************//**
84484 +
84485 + @Group FM_grp Frame Manager API
84486 +
84487 + @Description FM API functions, definitions and enums
84488 +
84489 + @{
84490 +*//***************************************************************************/
84491 +
84492 +/**************************************************************************//**
84493 + @Group FM_PORT_grp FM Port
84494 +
84495 + @Description FM Port API
84496 +
84497 + The FM uses a general module called "port" to represent a Tx port
84498 + (MAC), an Rx port (MAC) or Offline Parsing port.
84499 + The number of ports in an FM varies between SOCs.
84500 + The SW driver manages these ports as sub-modules of the FM, i.e.
84501 + after an FM is initialized, its ports may be initialized and
84502 + operated upon.
84503 +
84504 + The port is initialized aware of its type, but other functions on
84505 + a port may be indifferent to its type. When necessary, the driver
84506 + verifies coherence and returns error if applicable.
84507 +
84508 + On initialization, user specifies the port type and it's index
84509 + (relative to the port's type) - always starting at 0.
84510 +
84511 + @{
84512 +*//***************************************************************************/
84513 +
84514 +/**************************************************************************//**
84515 + @Description An enum for defining port PCD modes.
84516 + This enum defines the superset of PCD engines support - i.e. not
84517 + all engines have to be used, but all have to be enabled. The real
84518 + flow of a specific frame depends on the PCD configuration and the
84519 + frame headers and payload.
84520 + Note: the first engine and the first engine after the parser (if
84521 + exists) should be in order, the order is important as it will
84522 + define the flow of the port. However, as for the rest engines
84523 + (the ones that follows), the order is not important anymore as
84524 + it is defined by the PCD graph itself.
84525 +*//***************************************************************************/
84526 +typedef enum e_FmPortPcdSupport {
84527 + e_FM_PORT_PCD_SUPPORT_NONE = 0 /**< BMI to BMI, PCD is not used */
84528 + , e_FM_PORT_PCD_SUPPORT_PRS_ONLY /**< Use only Parser */
84529 + , e_FM_PORT_PCD_SUPPORT_PLCR_ONLY /**< Use only Policer */
84530 + , e_FM_PORT_PCD_SUPPORT_PRS_AND_PLCR /**< Use Parser and Policer */
84531 + , e_FM_PORT_PCD_SUPPORT_PRS_AND_KG /**< Use Parser and Keygen */
84532 + , e_FM_PORT_PCD_SUPPORT_PRS_AND_KG_AND_CC /**< Use Parser, Keygen and Coarse Classification */
84533 + , e_FM_PORT_PCD_SUPPORT_PRS_AND_KG_AND_CC_AND_PLCR
84534 + /**< Use all PCD engines */
84535 + , e_FM_PORT_PCD_SUPPORT_PRS_AND_KG_AND_PLCR /**< Use Parser, Keygen and Policer */
84536 + , e_FM_PORT_PCD_SUPPORT_PRS_AND_CC /**< Use Parser and Coarse Classification */
84537 + , e_FM_PORT_PCD_SUPPORT_PRS_AND_CC_AND_PLCR /**< Use Parser and Coarse Classification and Policer */
84538 + , e_FM_PORT_PCD_SUPPORT_CC_ONLY /**< Use only Coarse Classification */
84539 +#ifdef FM_CAPWAP_SUPPORT
84540 + , e_FM_PORT_PCD_SUPPORT_CC_AND_KG /**< Use Coarse Classification,and Keygen */
84541 + , e_FM_PORT_PCD_SUPPORT_CC_AND_KG_AND_PLCR /**< Use Coarse Classification, Keygen and Policer */
84542 +#endif /* FM_CAPWAP_SUPPORT */
84543 +} e_FmPortPcdSupport;
84544 +
84545 +/**************************************************************************//**
84546 + @Description Port interrupts
84547 +*//***************************************************************************/
84548 +typedef enum e_FmPortExceptions {
84549 + e_FM_PORT_EXCEPTION_IM_BUSY /**< Independent-Mode Rx-BUSY */
84550 +} e_FmPortExceptions;
84551 +
84552 +
84553 +/**************************************************************************//**
84554 + @Collection General FM Port defines
84555 +*//***************************************************************************/
84556 +#define FM_PORT_PRS_RESULT_NUM_OF_WORDS 8 /**< Number of 4 bytes words in parser result */
84557 +/* @} */
84558 +
84559 +/**************************************************************************//**
84560 + @Collection FM Frame error
84561 +*//***************************************************************************/
84562 +typedef uint32_t fmPortFrameErrSelect_t; /**< typedef for defining Frame Descriptor errors */
84563 +
84564 +#define FM_PORT_FRM_ERR_UNSUPPORTED_FORMAT FM_FD_ERR_UNSUPPORTED_FORMAT /**< Not for Rx-Port! Unsupported Format */
84565 +#define FM_PORT_FRM_ERR_LENGTH FM_FD_ERR_LENGTH /**< Not for Rx-Port! Length Error */
84566 +#define FM_PORT_FRM_ERR_DMA FM_FD_ERR_DMA /**< DMA Data error */
84567 +#define FM_PORT_FRM_ERR_NON_FM FM_FD_RX_STATUS_ERR_NON_FM /**< non Frame-Manager error; probably come from SEC that
84568 + was chained to FM */
84569 +
84570 +#define FM_PORT_FRM_ERR_IPRE (FM_FD_ERR_IPR & ~FM_FD_IPR) /**< IPR error */
84571 +#define FM_PORT_FRM_ERR_IPR_NCSP (FM_FD_ERR_IPR_NCSP & ~FM_FD_IPR) /**< IPR non-consistent-sp */
84572 +
84573 +#define FM_PORT_FRM_ERR_IPFE 0 /**< Obsolete; will be removed in the future */
84574 +
84575 +#ifdef FM_CAPWAP_SUPPORT
84576 +#define FM_PORT_FRM_ERR_CRE FM_FD_ERR_CRE
84577 +#define FM_PORT_FRM_ERR_CHE FM_FD_ERR_CHE
84578 +#endif /* FM_CAPWAP_SUPPORT */
84579 +
84580 +#define FM_PORT_FRM_ERR_PHYSICAL FM_FD_ERR_PHYSICAL /**< Rx FIFO overflow, FCS error, code error, running disparity
84581 + error (SGMII and TBI modes), FIFO parity error. PHY
84582 + Sequence error, PHY error control character detected. */
84583 +#define FM_PORT_FRM_ERR_SIZE FM_FD_ERR_SIZE /**< Frame too long OR Frame size exceeds max_length_frame */
84584 +#define FM_PORT_FRM_ERR_CLS_DISCARD FM_FD_ERR_CLS_DISCARD /**< indicates a classifier "drop" operation */
84585 +#define FM_PORT_FRM_ERR_EXTRACTION FM_FD_ERR_EXTRACTION /**< Extract Out of Frame */
84586 +#define FM_PORT_FRM_ERR_NO_SCHEME FM_FD_ERR_NO_SCHEME /**< No Scheme Selected */
84587 +#define FM_PORT_FRM_ERR_KEYSIZE_OVERFLOW FM_FD_ERR_KEYSIZE_OVERFLOW /**< Keysize Overflow */
84588 +#define FM_PORT_FRM_ERR_COLOR_RED FM_FD_ERR_COLOR_RED /**< Frame color is red */
84589 +#define FM_PORT_FRM_ERR_COLOR_YELLOW FM_FD_ERR_COLOR_YELLOW /**< Frame color is yellow */
84590 +#define FM_PORT_FRM_ERR_ILL_PLCR FM_FD_ERR_ILL_PLCR /**< Illegal Policer Profile selected */
84591 +#define FM_PORT_FRM_ERR_PLCR_FRAME_LEN FM_FD_ERR_PLCR_FRAME_LEN /**< Policer frame length error */
84592 +#define FM_PORT_FRM_ERR_PRS_TIMEOUT FM_FD_ERR_PRS_TIMEOUT /**< Parser Time out Exceed */
84593 +#define FM_PORT_FRM_ERR_PRS_ILL_INSTRUCT FM_FD_ERR_PRS_ILL_INSTRUCT /**< Invalid Soft Parser instruction */
84594 +#define FM_PORT_FRM_ERR_PRS_HDR_ERR FM_FD_ERR_PRS_HDR_ERR /**< Header error was identified during parsing */
84595 +#define FM_PORT_FRM_ERR_BLOCK_LIMIT_EXCEEDED FM_FD_ERR_BLOCK_LIMIT_EXCEEDED /**< Frame parsed beyind 256 first bytes */
84596 +#define FM_PORT_FRM_ERR_PROCESS_TIMEOUT 0x00000001 /**< FPM Frame Processing Timeout Exceeded */
84597 +/* @} */
84598 +
84599 +
84600 +
84601 +/**************************************************************************//**
84602 + @Group FM_PORT_init_grp FM Port Initialization Unit
84603 +
84604 + @Description FM Port Initialization Unit
84605 +
84606 + @{
84607 +*//***************************************************************************/
84608 +
84609 +/**************************************************************************//**
84610 + @Description Exceptions user callback routine, will be called upon an
84611 + exception passing the exception identification.
84612 +
84613 + @Param[in] h_App - User's application descriptor.
84614 + @Param[in] exception - The exception.
84615 + *//***************************************************************************/
84616 +typedef void (t_FmPortExceptionCallback) (t_Handle h_App, e_FmPortExceptions exception);
84617 +
84618 +/**************************************************************************//**
84619 + @Description User callback function called by driver with received data.
84620 +
84621 + User provides this function. Driver invokes it.
84622 +
84623 + @Param[in] h_App Application's handle originally specified to
84624 + the API Config function
84625 + @Param[in] p_Data A pointer to data received
84626 + @Param[in] length length of received data
84627 + @Param[in] status receive status and errors
84628 + @Param[in] position position of buffer in frame
84629 + @Param[in] h_BufContext A handle of the user acossiated with this buffer
84630 +
84631 + @Retval e_RX_STORE_RESPONSE_CONTINUE - order the driver to continue Rx
84632 + operation for all ready data.
84633 + @Retval e_RX_STORE_RESPONSE_PAUSE - order the driver to stop Rx operation.
84634 +*//***************************************************************************/
84635 +typedef e_RxStoreResponse (t_FmPortImRxStoreCallback) (t_Handle h_App,
84636 + uint8_t *p_Data,
84637 + uint16_t length,
84638 + uint16_t status,
84639 + uint8_t position,
84640 + t_Handle h_BufContext);
84641 +
84642 +/**************************************************************************//**
84643 + @Description User callback function called by driver when transmit completed.
84644 +
84645 + User provides this function. Driver invokes it.
84646 +
84647 + @Param[in] h_App Application's handle originally specified to
84648 + the API Config function
84649 + @Param[in] p_Data A pointer to data received
84650 + @Param[in] status transmit status and errors
84651 + @Param[in] lastBuffer is last buffer in frame
84652 + @Param[in] h_BufContext A handle of the user acossiated with this buffer
84653 + *//***************************************************************************/
84654 +typedef void (t_FmPortImTxConfCallback) (t_Handle h_App,
84655 + uint8_t *p_Data,
84656 + uint16_t status,
84657 + t_Handle h_BufContext);
84658 +
84659 +/**************************************************************************//**
84660 + @Description A structure for additional Rx port parameters
84661 +*//***************************************************************************/
84662 +typedef struct t_FmPortRxParams {
84663 + uint32_t errFqid; /**< Error Queue Id. */
84664 + uint32_t dfltFqid; /**< Default Queue Id. */
84665 + uint16_t liodnOffset; /**< Port's LIODN offset. */
84666 + t_FmExtPools extBufPools; /**< Which external buffer pools are used
84667 + (up to FM_PORT_MAX_NUM_OF_EXT_POOLS), and their sizes. */
84668 +} t_FmPortRxParams;
84669 +
84670 +/**************************************************************************//**
84671 + @Description A structure for additional non-Rx port parameters
84672 +*//***************************************************************************/
84673 +typedef struct t_FmPortNonRxParams {
84674 + uint32_t errFqid; /**< Error Queue Id. */
84675 + uint32_t dfltFqid; /**< For Tx - Default Confirmation queue,
84676 + 0 means no Tx confirmation for processed
84677 + frames. For OP port - default Rx queue. */
84678 + uint32_t qmChannel; /**< QM-channel dedicated to this port; will be used
84679 + by the FM for dequeue. */
84680 +} t_FmPortNonRxParams;
84681 +
84682 +/**************************************************************************//**
84683 + @Description A structure for additional Rx port parameters
84684 +*//***************************************************************************/
84685 +typedef struct t_FmPortImRxTxParams {
84686 + t_Handle h_FmMuram; /**< A handle of the FM-MURAM partition */
84687 + uint16_t liodnOffset; /**< For Rx ports only. Port's LIODN Offset. */
84688 + uint8_t dataMemId; /**< Memory partition ID for data buffers */
84689 + uint32_t dataMemAttributes; /**< Memory attributes for data buffers */
84690 + t_BufferPoolInfo rxPoolParams; /**< For Rx ports only. */
84691 + t_FmPortImRxStoreCallback *f_RxStore; /**< For Rx ports only. */
84692 + t_FmPortImTxConfCallback *f_TxConf; /**< For Tx ports only. */
84693 +} t_FmPortImRxTxParams;
84694 +
84695 +/**************************************************************************//**
84696 + @Description A union for additional parameters depending on port type
84697 +*//***************************************************************************/
84698 +typedef union u_FmPortSpecificParams {
84699 + t_FmPortImRxTxParams imRxTxParams; /**< Rx/Tx Independent-Mode port parameter structure */
84700 + t_FmPortRxParams rxParams; /**< Rx port parameters structure */
84701 + t_FmPortNonRxParams nonRxParams; /**< Non-Rx port parameters structure */
84702 +} u_FmPortSpecificParams;
84703 +
84704 +/**************************************************************************//**
84705 + @Description A structure representing FM initialization parameters
84706 +*//***************************************************************************/
84707 +typedef struct t_FmPortParams {
84708 + uintptr_t baseAddr; /**< Virtual Address of memory mapped FM Port registers.*/
84709 + t_Handle h_Fm; /**< A handle to the FM object this port related to */
84710 + e_FmPortType portType; /**< Port type */
84711 + uint8_t portId; /**< Port Id - relative to type;
84712 + NOTE: When configuring Offline Parsing port for
84713 + FMANv3 devices (DPAA_VERSION 11 and higher),
84714 + it is highly recommended NOT to use portId=0 due to lack
84715 + of HW resources on portId=0. */
84716 + bool independentModeEnable;
84717 + /**< This port is Independent-Mode - Used for Rx/Tx ports only! */
84718 + uint16_t liodnBase; /**< Irrelevant for P4080 rev 1. LIODN base for this port, to be
84719 + used together with LIODN offset. */
84720 + u_FmPortSpecificParams specificParams; /**< Additional parameters depending on port
84721 + type. */
84722 +
84723 + t_FmPortExceptionCallback *f_Exception; /**< Relevant for IM only Callback routine to be called on BUSY exception */
84724 + t_Handle h_App; /**< A handle to an application layer object; This handle will
84725 + be passed by the driver upon calling the above callbacks */
84726 +} t_FmPortParams;
84727 +
84728 +
84729 +/**************************************************************************//**
84730 + @Function FM_PORT_Config
84731 +
84732 + @Description Creates a descriptor for the FM PORT module.
84733 +
84734 + The routine returns a handle (descriptor) to the FM PORT object.
84735 + This descriptor must be passed as first parameter to all other
84736 + FM PORT function calls.
84737 +
84738 + No actual initialization or configuration of FM hardware is
84739 + done by this routine.
84740 +
84741 + @Param[in] p_FmPortParams - Pointer to data structure of parameters
84742 +
84743 + @Retval Handle to FM object, or NULL for Failure.
84744 +*//***************************************************************************/
84745 +t_Handle FM_PORT_Config(t_FmPortParams *p_FmPortParams);
84746 +
84747 +/**************************************************************************//**
84748 + @Function FM_PORT_Init
84749 +
84750 + @Description Initializes the FM PORT module by defining the software structure
84751 + and configuring the hardware registers.
84752 +
84753 + @Param[in] h_FmPort - FM PORT module descriptor
84754 +
84755 + @Return E_OK on success; Error code otherwise.
84756 +*//***************************************************************************/
84757 +t_Error FM_PORT_Init(t_Handle h_FmPort);
84758 +
84759 +/**************************************************************************//**
84760 + @Function FM_PORT_Free
84761 +
84762 + @Description Frees all resources that were assigned to FM PORT module.
84763 +
84764 + Calling this routine invalidates the descriptor.
84765 +
84766 + @Param[in] h_FmPort - FM PORT module descriptor
84767 +
84768 + @Return E_OK on success; Error code otherwise.
84769 +*//***************************************************************************/
84770 +t_Error FM_PORT_Free(t_Handle h_FmPort);
84771 +
84772 +
84773 +/**************************************************************************//**
84774 + @Group FM_PORT_advanced_init_grp FM Port Advanced Configuration Unit
84775 +
84776 + @Description Configuration functions used to change default values.
84777 +
84778 + @{
84779 +*//***************************************************************************/
84780 +
84781 +/**************************************************************************//**
84782 + @Description enum for defining QM frame dequeue
84783 +*//***************************************************************************/
84784 +typedef enum e_FmPortDeqType {
84785 + e_FM_PORT_DEQ_TYPE1, /**< Dequeue from the SP channel - with priority precedence,
84786 + and Intra-Class Scheduling respected. */
84787 + e_FM_PORT_DEQ_TYPE2, /**< Dequeue from the SP channel - with active FQ precedence,
84788 + and Intra-Class Scheduling respected. */
84789 + e_FM_PORT_DEQ_TYPE3 /**< Dequeue from the SP channel - with active FQ precedence,
84790 + and override Intra-Class Scheduling */
84791 +} e_FmPortDeqType;
84792 +
84793 +/**************************************************************************//**
84794 + @Description enum for defining QM frame dequeue
84795 +*//***************************************************************************/
84796 +typedef enum e_FmPortDeqPrefetchOption {
84797 + e_FM_PORT_DEQ_NO_PREFETCH, /**< QMI preforms a dequeue action for a single frame
84798 + only when a dedicated portID Tnum is waiting. */
84799 + e_FM_PORT_DEQ_PARTIAL_PREFETCH, /**< QMI preforms a dequeue action for 3 frames when
84800 + one dedicated portId tnum is waiting. */
84801 + e_FM_PORT_DEQ_FULL_PREFETCH /**< QMI preforms a dequeue action for 3 frames when
84802 + no dedicated portId tnums are waiting. */
84803 +
84804 +} e_FmPortDeqPrefetchOption;
84805 +
84806 +/**************************************************************************//**
84807 + @Description enum for defining port default color
84808 +*//***************************************************************************/
84809 +typedef enum e_FmPortColor {
84810 + e_FM_PORT_COLOR_GREEN, /**< Default port color is green */
84811 + e_FM_PORT_COLOR_YELLOW, /**< Default port color is yellow */
84812 + e_FM_PORT_COLOR_RED, /**< Default port color is red */
84813 + e_FM_PORT_COLOR_OVERRIDE /**< Ignore color */
84814 +} e_FmPortColor;
84815 +
84816 +/**************************************************************************//**
84817 + @Description A structure for defining Dual Tx rate limiting scale
84818 +*//***************************************************************************/
84819 +typedef enum e_FmPortDualRateLimiterScaleDown {
84820 + e_FM_PORT_DUAL_RATE_LIMITER_NONE = 0, /**< Use only single rate limiter */
84821 + e_FM_PORT_DUAL_RATE_LIMITER_SCALE_DOWN_BY_2, /**< Divide high rate limiter by 2 */
84822 + e_FM_PORT_DUAL_RATE_LIMITER_SCALE_DOWN_BY_4, /**< Divide high rate limiter by 4 */
84823 + e_FM_PORT_DUAL_RATE_LIMITER_SCALE_DOWN_BY_8 /**< Divide high rate limiter by 8 */
84824 +} e_FmPortDualRateLimiterScaleDown;
84825 +
84826 +
84827 +/**************************************************************************//**
84828 + @Description A structure for defining FM port resources
84829 +*//***************************************************************************/
84830 +typedef struct t_FmPortRsrc {
84831 + uint32_t num; /**< Committed required resource */
84832 + uint32_t extra; /**< Extra (not committed) required resource */
84833 +} t_FmPortRsrc;
84834 +
84835 +/**************************************************************************//**
84836 + @Description A structure for defining observed pool depletion
84837 +*//***************************************************************************/
84838 +typedef struct t_FmPortObservedBufPoolDepletion {
84839 + t_FmBufPoolDepletion poolDepletionParams;/**< parameters to define pool depletion */
84840 + t_FmExtPools poolsParams; /**< Which external buffer pools are observed
84841 + (up to FM_PORT_MAX_NUM_OF_OBSERVED_EXT_POOLS),
84842 + and their sizes. */
84843 +} t_FmPortObservedBufPoolDepletion;
84844 +
84845 +/**************************************************************************//**
84846 + @Description A structure for defining Tx rate limiting
84847 +*//***************************************************************************/
84848 +typedef struct t_FmPortRateLimit {
84849 + uint16_t maxBurstSize; /**< in KBytes for Tx ports, in frames
84850 + for OP ports. (note that
84851 + for early chips burst size is
84852 + rounded up to a multiply of 1000 frames).*/
84853 + uint32_t rateLimit; /**< in Kb/sec for Tx ports, in frame/sec for
84854 + OP ports. Rate limit refers to
84855 + data rate (rather than line rate). */
84856 + e_FmPortDualRateLimiterScaleDown rateLimitDivider; /**< For OP ports only. Not-valid
84857 + for some earlier chip revisions */
84858 +} t_FmPortRateLimit;
84859 +
84860 +/**************************************************************************//**
84861 + @Description A structure for defining the parameters of
84862 + the Rx port performance counters
84863 +*//***************************************************************************/
84864 +typedef struct t_FmPortPerformanceCnt {
84865 + uint8_t taskCompVal; /**< Task compare value */
84866 + uint8_t queueCompVal; /**< Rx queue/Tx confirm queue compare
84867 + value (unused for H/O) */
84868 + uint8_t dmaCompVal; /**< Dma compare value */
84869 + uint32_t fifoCompVal; /**< Fifo compare value (in bytes) */
84870 +} t_FmPortPerformanceCnt;
84871 +
84872 +
84873 +/**************************************************************************//**
84874 + @Description A structure for defining the sizes of the Deep Sleep
84875 + the Auto Response tables
84876 +*//***************************************************************************/
84877 +typedef struct t_FmPortDsarTablesSizes
84878 +{
84879 + uint16_t maxNumOfArpEntries;
84880 + uint16_t maxNumOfEchoIpv4Entries;
84881 + uint16_t maxNumOfNdpEntries;
84882 + uint16_t maxNumOfEchoIpv6Entries;
84883 + uint16_t maxNumOfSnmpIPV4Entries;
84884 + uint16_t maxNumOfSnmpIPV6Entries;
84885 + uint16_t maxNumOfSnmpOidEntries;
84886 + uint16_t maxNumOfSnmpOidChar; /* total amount of character needed for the snmp table */
84887 +
84888 + uint16_t maxNumOfIpProtFiltering;
84889 + uint16_t maxNumOfTcpPortFiltering;
84890 + uint16_t maxNumOfUdpPortFiltering;
84891 +} t_FmPortDsarTablesSizes;
84892 +
84893 +
84894 +/**************************************************************************//**
84895 + @Function FM_PORT_ConfigDsarSupport
84896 +
84897 + @Description This function will allocate the amount of MURAM needed for
84898 + this max number of entries for Deep Sleep Auto Response.
84899 + it will calculate all needed MURAM for autoresponse including
84900 + necesary common stuff.
84901 +
84902 +
84903 + @Param[in] h_FmPort A handle to a FM Port module.
84904 + @Param[in] params A pointer to a structure containing the maximum
84905 + sizes of the auto response tables
84906 +
84907 + @Return E_OK on success; Error code otherwise.
84908 +
84909 + @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init().
84910 +*//***************************************************************************/
84911 +t_Error FM_PORT_ConfigDsarSupport(t_Handle h_FmPortRx, t_FmPortDsarTablesSizes *params);
84912 +
84913 +/**************************************************************************//**
84914 + @Function FM_PORT_ConfigNumOfOpenDmas
84915 +
84916 + @Description Calling this routine changes the max number of open DMA's
84917 + available for this port. It changes this parameter in the
84918 + internal driver data base from its default configuration
84919 + [OP: 1]
84920 + [1G-RX, 1G-TX: 1 (+1)]
84921 + [10G-RX, 10G-TX: 8 (+8)]
84922 +
84923 + @Param[in] h_FmPort A handle to a FM Port module.
84924 + @Param[in] p_OpenDmas A pointer to a structure of parameters defining
84925 + the open DMA allocation.
84926 +
84927 + @Return E_OK on success; Error code otherwise.
84928 +
84929 + @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init().
84930 +*//***************************************************************************/
84931 +t_Error FM_PORT_ConfigNumOfOpenDmas(t_Handle h_FmPort, t_FmPortRsrc *p_OpenDmas);
84932 +
84933 +/**************************************************************************//**
84934 + @Function FM_PORT_ConfigNumOfTasks
84935 +
84936 + @Description Calling this routine changes the max number of tasks
84937 + available for this port. It changes this parameter in the
84938 + internal driver data base from its default configuration
84939 + [OP: 1]
84940 + [1G-RX, 1G-TX: 3 (+2)]
84941 + [10G-RX, 10G-TX: 16 (+8)]
84942 +
84943 + @Param[in] h_FmPort A handle to a FM Port module.
84944 + @Param[in] p_NumOfTasks A pointer to a structure of parameters defining
84945 + the tasks allocation.
84946 +
84947 + @Return E_OK on success; Error code otherwise.
84948 +
84949 + @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init().
84950 +*//***************************************************************************/
84951 +t_Error FM_PORT_ConfigNumOfTasks(t_Handle h_FmPort, t_FmPortRsrc *p_NumOfTasks);
84952 +
84953 +/**************************************************************************//**
84954 + @Function FM_PORT_ConfigSizeOfFifo
84955 +
84956 + @Description Calling this routine changes the max FIFO size configured for this port.
84957 +
84958 + This function changes the internal driver data base from its
84959 + default configuration. Please refer to the driver's User Guide for
84960 + information on default FIFO sizes in the various devices.
84961 + [OP: 2KB]
84962 + [1G-RX, 1G-TX: 11KB]
84963 + [10G-RX, 10G-TX: 12KB]
84964 +
84965 + @Param[in] h_FmPort A handle to a FM Port module.
84966 + @Param[in] p_SizeOfFifo A pointer to a structure of parameters defining
84967 + the FIFO allocation.
84968 +
84969 + @Return E_OK on success; Error code otherwise.
84970 +
84971 + @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init().
84972 +*//***************************************************************************/
84973 +t_Error FM_PORT_ConfigSizeOfFifo(t_Handle h_FmPort, t_FmPortRsrc *p_SizeOfFifo);
84974 +
84975 +/**************************************************************************//**
84976 + @Function FM_PORT_ConfigDeqHighPriority
84977 +
84978 + @Description Calling this routine changes the dequeue priority in the
84979 + internal driver data base from its default configuration
84980 + 1G: [DEFAULT_PORT_deqHighPriority_1G]
84981 + 10G: [DEFAULT_PORT_deqHighPriority_10G]
84982 +
84983 + May be used for Non-Rx ports only
84984 +
84985 + @Param[in] h_FmPort A handle to a FM Port module.
84986 + @Param[in] highPri TRUE to select high priority, FALSE for normal operation.
84987 +
84988 + @Return E_OK on success; Error code otherwise.
84989 +
84990 + @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init().
84991 +*//***************************************************************************/
84992 +t_Error FM_PORT_ConfigDeqHighPriority(t_Handle h_FmPort, bool highPri);
84993 +
84994 +/**************************************************************************//**
84995 + @Function FM_PORT_ConfigDeqType
84996 +
84997 + @Description Calling this routine changes the dequeue type parameter in the
84998 + internal driver data base from its default configuration
84999 + [DEFAULT_PORT_deqType].
85000 +
85001 + May be used for Non-Rx ports only
85002 +
85003 + @Param[in] h_FmPort A handle to a FM Port module.
85004 + @Param[in] deqType According to QM definition.
85005 +
85006 + @Return E_OK on success; Error code otherwise.
85007 +
85008 + @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init().
85009 +*//***************************************************************************/
85010 +t_Error FM_PORT_ConfigDeqType(t_Handle h_FmPort, e_FmPortDeqType deqType);
85011 +
85012 +/**************************************************************************//**
85013 + @Function FM_PORT_ConfigDeqPrefetchOption
85014 +
85015 + @Description Calling this routine changes the dequeue prefetch option parameter in the
85016 + internal driver data base from its default configuration
85017 + [DEFAULT_PORT_deqPrefetchOption]
85018 + Note: Available for some chips only
85019 +
85020 + May be used for Non-Rx ports only
85021 +
85022 + @Param[in] h_FmPort A handle to a FM Port module.
85023 + @Param[in] deqPrefetchOption New option
85024 +
85025 + @Return E_OK on success; Error code otherwise.
85026 +
85027 + @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init().
85028 +*//***************************************************************************/
85029 +t_Error FM_PORT_ConfigDeqPrefetchOption(t_Handle h_FmPort, e_FmPortDeqPrefetchOption deqPrefetchOption);
85030 +
85031 +/**************************************************************************//**
85032 + @Function FM_PORT_ConfigDeqByteCnt
85033 +
85034 + @Description Calling this routine changes the dequeue byte count parameter in
85035 + the internal driver data base from its default configuration
85036 + 1G:[DEFAULT_PORT_deqByteCnt_1G].
85037 + 10G:[DEFAULT_PORT_deqByteCnt_10G].
85038 +
85039 + May be used for Non-Rx ports only
85040 +
85041 + @Param[in] h_FmPort A handle to a FM Port module.
85042 + @Param[in] deqByteCnt New byte count
85043 +
85044 + @Return E_OK on success; Error code otherwise.
85045 +
85046 + @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init().
85047 +*//***************************************************************************/
85048 +t_Error FM_PORT_ConfigDeqByteCnt(t_Handle h_FmPort, uint16_t deqByteCnt);
85049 +
85050 +/**************************************************************************//**
85051 + @Function FM_PORT_ConfigBufferPrefixContent
85052 +
85053 + @Description Defines the structure, size and content of the application buffer.
85054 + The prefix will
85055 + In Tx ports, if 'passPrsResult', the application
85056 + should set a value to their offsets in the prefix of
85057 + the FM will save the first 'privDataSize', than,
85058 + depending on 'passPrsResult' and 'passTimeStamp', copy parse result
85059 + and timeStamp, and the packet itself (in this order), to the
85060 + application buffer, and to offset.
85061 + Calling this routine changes the buffer margins definitions
85062 + in the internal driver data base from its default
85063 + configuration: Data size: [DEFAULT_PORT_bufferPrefixContent_privDataSize]
85064 + Pass Parser result: [DEFAULT_PORT_bufferPrefixContent_passPrsResult].
85065 + Pass timestamp: [DEFAULT_PORT_bufferPrefixContent_passTimeStamp].
85066 +
85067 + May be used for all ports
85068 +
85069 + @Param[in] h_FmPort A handle to a FM Port module.
85070 + @Param[in,out] p_FmBufferPrefixContent A structure of parameters describing the
85071 + structure of the buffer.
85072 + Out parameter: Start margin - offset
85073 + of data from start of external buffer.
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_ConfigBufferPrefixContent(t_Handle h_FmPort,
85080 + t_FmBufferPrefixContent *p_FmBufferPrefixContent);
85081 +
85082 +/**************************************************************************//**
85083 + @Function FM_PORT_ConfigCheksumLastBytesIgnore
85084 +
85085 + @Description Calling this routine changes the number of checksum bytes to ignore
85086 + parameter in the internal driver data base from its default configuration
85087 + [DEFAULT_PORT_cheksumLastBytesIgnore]
85088 +
85089 + May be used by Tx & Rx ports only
85090 +
85091 + @Param[in] h_FmPort A handle to a FM Port module.
85092 + @Param[in] cheksumLastBytesIgnore New value
85093 +
85094 + @Return E_OK on success; Error code otherwise.
85095 +
85096 + @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init().
85097 +*//***************************************************************************/
85098 +t_Error FM_PORT_ConfigCheksumLastBytesIgnore(t_Handle h_FmPort, uint8_t cheksumLastBytesIgnore);
85099 +
85100 +/**************************************************************************//**
85101 + @Function FM_PORT_ConfigCutBytesFromEnd
85102 +
85103 + @Description Calling this routine changes the number of bytes to cut from a
85104 + frame's end parameter in the internal driver data base
85105 + from its default configuration [DEFAULT_PORT_cutBytesFromEnd]
85106 + Note that if the result of (frame length before chop - cutBytesFromEnd) is
85107 + less than 14 bytes, the chop operation is not executed.
85108 +
85109 + May be used for Rx ports only
85110 +
85111 + @Param[in] h_FmPort A handle to a FM Port module.
85112 + @Param[in] cutBytesFromEnd New value
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_ConfigCutBytesFromEnd(t_Handle h_FmPort, uint8_t cutBytesFromEnd);
85119 +
85120 +/**************************************************************************//**
85121 + @Function FM_PORT_ConfigPoolDepletion
85122 +
85123 + @Description Calling this routine enables pause frame generation depending on the
85124 + depletion status of BM pools. It also defines the conditions to activate
85125 + this functionality. By default, this functionality is disabled.
85126 +
85127 + May be used for Rx ports only
85128 +
85129 + @Param[in] h_FmPort A handle to a FM Port module.
85130 + @Param[in] p_BufPoolDepletion A structure of pool depletion parameters
85131 +
85132 + @Return E_OK on success; Error code otherwise.
85133 +
85134 + @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init().
85135 +*//***************************************************************************/
85136 +t_Error FM_PORT_ConfigPoolDepletion(t_Handle h_FmPort, t_FmBufPoolDepletion *p_BufPoolDepletion);
85137 +
85138 +/**************************************************************************//**
85139 + @Function FM_PORT_ConfigObservedPoolDepletion
85140 +
85141 + @Description Calling this routine enables a mechanism to stop port enqueue
85142 + depending on the depletion status of selected BM pools.
85143 + It also defines the conditions to activate
85144 + this functionality. By default, this functionality is disabled.
85145 +
85146 + Note: Available for some chips only
85147 +
85148 + May be used for OP ports only
85149 +
85150 + @Param[in] h_FmPort A handle to a FM Port module.
85151 + @Param[in] p_FmPortObservedBufPoolDepletion A structure of parameters for pool depletion.
85152 +
85153 + @Return E_OK on success; Error code otherwise.
85154 +
85155 + @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init().
85156 +*//***************************************************************************/
85157 +t_Error FM_PORT_ConfigObservedPoolDepletion(t_Handle h_FmPort,
85158 + t_FmPortObservedBufPoolDepletion *p_FmPortObservedBufPoolDepletion);
85159 +
85160 +/**************************************************************************//**
85161 + @Function FM_PORT_ConfigExtBufPools
85162 +
85163 + @Description This routine should be called for OP ports
85164 + that internally use BM buffer pools. In such cases, e.g. for fragmentation and
85165 + re-assembly, the FM needs new BM buffers. By calling this routine the user
85166 + specifies the BM buffer pools that should be used.
85167 +
85168 + Note: Available for some chips only
85169 +
85170 + May be used for OP ports only
85171 +
85172 + @Param[in] h_FmPort A handle to a FM Port module.
85173 + @Param[in] p_FmExtPools A structure of parameters for the external pools.
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_ConfigExtBufPools(t_Handle h_FmPort, t_FmExtPools *p_FmExtPools);
85180 +
85181 +/**************************************************************************//**
85182 + @Function FM_PORT_ConfigBackupPools
85183 +
85184 + @Description Calling this routine allows the configuration of some of the BM pools
85185 + defined for this port as backup pools.
85186 + A pool configured to be a backup pool will be used only if all other
85187 + enabled non-backup pools are depleted.
85188 +
85189 + May be used for Rx ports only
85190 +
85191 + @Param[in] h_FmPort A handle to a FM Port module.
85192 + @Param[in] p_FmPortBackupBmPools An array of pool id's. All pools specified here will
85193 + be defined as backup pools.
85194 +
85195 + @Return E_OK on success; Error code otherwise.
85196 +
85197 + @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init().
85198 +*//***************************************************************************/
85199 +t_Error FM_PORT_ConfigBackupPools(t_Handle h_FmPort, t_FmBackupBmPools *p_FmPortBackupBmPools);
85200 +
85201 +/**************************************************************************//**
85202 + @Function FM_PORT_ConfigFrmDiscardOverride
85203 +
85204 + @Description Calling this routine changes the error frames destination parameter
85205 + in the internal driver data base from its default configuration:
85206 + override = [DEFAULT_PORT_frmDiscardOverride]
85207 +
85208 + May be used for Rx and OP ports only
85209 +
85210 + @Param[in] h_FmPort A handle to a FM Port module.
85211 + @Param[in] override TRUE to override discarding of error frames and
85212 + enqueueing them to error queue.
85213 +
85214 + @Return E_OK on success; Error code otherwise.
85215 +
85216 + @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init().
85217 +*//***************************************************************************/
85218 +t_Error FM_PORT_ConfigFrmDiscardOverride(t_Handle h_FmPort, bool override);
85219 +
85220 +/**************************************************************************//**
85221 + @Function FM_PORT_ConfigErrorsToDiscard
85222 +
85223 + @Description Calling this routine changes the behaviour on error parameter
85224 + in the internal driver data base from its default configuration:
85225 + [DEFAULT_PORT_errorsToDiscard].
85226 + If a requested error was previously defined as "ErrorsToEnqueue" it's
85227 + definition will change and the frame will be discarded.
85228 + Errors that were not defined either as "ErrorsToEnqueue" nor as
85229 + "ErrorsToDiscard", will be forwarded to CPU.
85230 +
85231 + May be used for Rx and OP ports only
85232 +
85233 + @Param[in] h_FmPort A handle to a FM Port module.
85234 + @Param[in] errs A list of errors to discard
85235 +
85236 + @Return E_OK on success; Error code otherwise.
85237 +
85238 + @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init().
85239 +*//***************************************************************************/
85240 +t_Error FM_PORT_ConfigErrorsToDiscard(t_Handle h_FmPort, fmPortFrameErrSelect_t errs);
85241 +
85242 +/**************************************************************************//**
85243 + @Function FM_PORT_ConfigDmaSwapData
85244 +
85245 + @Description Calling this routine changes the DMA swap data aparameter
85246 + in the internal driver data base from its default
85247 + configuration [DEFAULT_PORT_dmaSwapData]
85248 +
85249 + May be used for all port types
85250 +
85251 + @Param[in] h_FmPort A handle to a FM Port module.
85252 + @Param[in] swapData New selection
85253 +
85254 + @Return E_OK on success; Error code otherwise.
85255 +
85256 + @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init().
85257 +*//***************************************************************************/
85258 +t_Error FM_PORT_ConfigDmaSwapData(t_Handle h_FmPort, e_FmDmaSwapOption swapData);
85259 +
85260 +/**************************************************************************//**
85261 + @Function FM_PORT_ConfigDmaIcCacheAttr
85262 +
85263 + @Description Calling this routine changes the internal context cache
85264 + attribute parameter in the internal driver data base
85265 + from its default configuration [DEFAULT_PORT_dmaIntContextCacheAttr]
85266 +
85267 + May be used for all port types
85268 +
85269 + @Param[in] h_FmPort A handle to a FM Port module.
85270 + @Param[in] intContextCacheAttr New selection
85271 +
85272 + @Return E_OK on success; Error code otherwise.
85273 +
85274 + @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init().
85275 +*//***************************************************************************/
85276 +t_Error FM_PORT_ConfigDmaIcCacheAttr(t_Handle h_FmPort, e_FmDmaCacheOption intContextCacheAttr);
85277 +
85278 +/**************************************************************************//**
85279 + @Function FM_PORT_ConfigDmaHdrAttr
85280 +
85281 + @Description Calling this routine changes the header cache
85282 + attribute parameter in the internal driver data base
85283 + from its default configuration [DEFAULT_PORT_dmaHeaderCacheAttr]
85284 +
85285 + May be used for all port types
85286 +
85287 + @Param[in] h_FmPort A handle to a FM Port module.
85288 + @Param[in] headerCacheAttr New selection
85289 +
85290 + @Return E_OK on success; Error code otherwise.
85291 +
85292 + @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init().
85293 +*//***************************************************************************/
85294 +t_Error FM_PORT_ConfigDmaHdrAttr(t_Handle h_FmPort, e_FmDmaCacheOption headerCacheAttr);
85295 +
85296 +/**************************************************************************//**
85297 + @Function FM_PORT_ConfigDmaScatterGatherAttr
85298 +
85299 + @Description Calling this routine changes the scatter gather cache
85300 + attribute parameter in the internal driver data base
85301 + from its default configuration [DEFAULT_PORT_dmaScatterGatherCacheAttr]
85302 +
85303 + May be used for all port types
85304 +
85305 + @Param[in] h_FmPort A handle to a FM Port module.
85306 + @Param[in] scatterGatherCacheAttr New selection
85307 +
85308 + @Return E_OK on success; Error code otherwise.
85309 +
85310 + @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init().
85311 +*//***************************************************************************/
85312 +t_Error FM_PORT_ConfigDmaScatterGatherAttr(t_Handle h_FmPort, e_FmDmaCacheOption scatterGatherCacheAttr);
85313 +
85314 +/**************************************************************************//**
85315 + @Function FM_PORT_ConfigDmaWriteOptimize
85316 +
85317 + @Description Calling this routine changes the write optimization
85318 + parameter in the internal driver data base
85319 + from its default configuration: By default optimize = [DEFAULT_PORT_dmaWriteOptimize].
85320 + Note:
85321 +
85322 + 1. For head optimization, data alignment must be >= 16 (supported by default).
85323 +
85324 + 3. For tail optimization, note that the optimization is performed by extending the write transaction
85325 + of the frame payload at the tail as needed to achieve optimal bus transfers, so that the last write
85326 + is extended to be on 16/64 bytes aligned block (chip dependent).
85327 +
85328 + Relevant for non-Tx port types
85329 +
85330 + @Param[in] h_FmPort A handle to a FM Port module.
85331 + @Param[in] optimize TRUE to enable optimization, FALSE for normal operation
85332 +
85333 + @Return E_OK on success; Error code otherwise.
85334 +
85335 + @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init().
85336 +*//***************************************************************************/
85337 +t_Error FM_PORT_ConfigDmaWriteOptimize(t_Handle h_FmPort, bool optimize);
85338 +
85339 +/**************************************************************************//**
85340 + @Function FM_PORT_ConfigNoScatherGather
85341 +
85342 + @Description Calling this routine changes the noScatherGather parameter in internal driver data base
85343 + from its default configuration.
85344 +
85345 + @Param[in] h_FmPort A handle to a FM Port module.
85346 + @Param[in] noScatherGather (TRUE - frame is discarded if can not be stored in single buffer,
85347 + FALSE - frame can be stored in scatter gather (S/G) format).
85348 +
85349 + @Return E_OK on success; Error code otherwise.
85350 +
85351 + @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init().
85352 +*//***************************************************************************/
85353 +t_Error FM_PORT_ConfigNoScatherGather(t_Handle h_FmPort, bool noScatherGather);
85354 +
85355 +/**************************************************************************//**
85356 + @Function FM_PORT_ConfigDfltColor
85357 +
85358 + @Description Calling this routine changes the internal default color parameter
85359 + in the internal driver data base
85360 + from its default configuration [DEFAULT_PORT_color]
85361 +
85362 + May be used for all port types
85363 +
85364 + @Param[in] h_FmPort A handle to a FM Port module.
85365 + @Param[in] color New selection
85366 +
85367 + @Return E_OK on success; Error code otherwise.
85368 +
85369 + @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init().
85370 +*//***************************************************************************/
85371 +t_Error FM_PORT_ConfigDfltColor(t_Handle h_FmPort, e_FmPortColor color);
85372 +
85373 +/**************************************************************************//**
85374 + @Function FM_PORT_ConfigSyncReq
85375 +
85376 + @Description Calling this routine changes the synchronization attribute parameter
85377 + in the internal driver data base from its default configuration:
85378 + syncReq = [DEFAULT_PORT_syncReq]
85379 +
85380 + May be used for all port types
85381 +
85382 + @Param[in] h_FmPort A handle to a FM Port module.
85383 + @Param[in] syncReq TRUE to request synchronization, FALSE otherwize.
85384 +
85385 + @Return E_OK on success; Error code otherwise.
85386 +
85387 + @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init().
85388 +*//***************************************************************************/
85389 +t_Error FM_PORT_ConfigSyncReq(t_Handle h_FmPort, bool syncReq);
85390 +
85391 +/**************************************************************************//**
85392 + @Function FM_PORT_ConfigForwardReuseIntContext
85393 +
85394 + @Description This routine is relevant for Rx ports that are routed to OP port.
85395 + It changes the internal context reuse option in the internal
85396 + driver data base from its default configuration:
85397 + reuse = [DEFAULT_PORT_forwardIntContextReuse]
85398 +
85399 + May be used for Rx ports only
85400 +
85401 + @Param[in] h_FmPort A handle to a FM Port module.
85402 + @Param[in] reuse TRUE to reuse internal context on frames
85403 + forwarded to OP port.
85404 +
85405 + @Return E_OK on success; Error code otherwise.
85406 +
85407 + @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init().
85408 +*//***************************************************************************/
85409 +t_Error FM_PORT_ConfigForwardReuseIntContext(t_Handle h_FmPort, bool reuse);
85410 +
85411 +/**************************************************************************//**
85412 + @Function FM_PORT_ConfigDontReleaseTxBufToBM
85413 +
85414 + @Description This routine should be called if no Tx confirmation
85415 + is done, and yet buffers should not be released to the BM.
85416 + Normally, buffers are returned using the Tx confirmation
85417 + process. When Tx confirmation is not used (defFqid=0),
85418 + buffers are typically released to the BM. This routine
85419 + may be called to avoid this behavior and not release the
85420 + buffers.
85421 +
85422 + May be used for Tx ports only
85423 +
85424 + @Param[in] h_FmPort A handle to a FM Port module.
85425 +
85426 + @Return E_OK on success; Error code otherwise.
85427 +
85428 + @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init().
85429 +*//***************************************************************************/
85430 +t_Error FM_PORT_ConfigDontReleaseTxBufToBM(t_Handle h_FmPort);
85431 +
85432 +/**************************************************************************//**
85433 + @Function FM_PORT_ConfigIMMaxRxBufLength
85434 +
85435 + @Description Changes the maximum receive buffer length from its default
85436 + configuration: Closest rounded down power of 2 value of the
85437 + data buffer size.
85438 +
85439 + The maximum receive buffer length directly affects the structure
85440 + of received frames (single- or multi-buffered) and the performance
85441 + of both the FM and the driver.
85442 +
85443 + The selection between single- or multi-buffered frames should be
85444 + done according to the characteristics of the specific application.
85445 + The recommended mode is to use a single data buffer per packet,
85446 + as this mode provides the best performance. However, the user can
85447 + select to use multiple data buffers per packet.
85448 +
85449 + @Param[in] h_FmPort A handle to a FM Port module.
85450 + @Param[in] newVal Maximum receive buffer length (in bytes).
85451 +
85452 + @Return E_OK on success; Error code otherwise.
85453 +
85454 + @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init().
85455 + This routine is to be used only if Independent-Mode is enabled.
85456 +*//***************************************************************************/
85457 +t_Error FM_PORT_ConfigIMMaxRxBufLength(t_Handle h_FmPort, uint16_t newVal);
85458 +
85459 +/**************************************************************************//**
85460 + @Function FM_PORT_ConfigIMRxBdRingLength
85461 +
85462 + @Description Changes the receive BD ring length from its default
85463 + configuration:[DEFAULT_PORT_rxBdRingLength]
85464 +
85465 + @Param[in] h_FmPort A handle to a FM Port module.
85466 + @Param[in] newVal The desired BD ring length.
85467 +
85468 + @Return E_OK on success; Error code otherwise.
85469 +
85470 + @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init().
85471 + This routine is to be used only if Independent-Mode is enabled.
85472 +*//***************************************************************************/
85473 +t_Error FM_PORT_ConfigIMRxBdRingLength(t_Handle h_FmPort, uint16_t newVal);
85474 +
85475 +/**************************************************************************//**
85476 + @Function FM_PORT_ConfigIMTxBdRingLength
85477 +
85478 + @Description Changes the transmit BD ring length from its default
85479 + configuration:[DEFAULT_PORT_txBdRingLength]
85480 +
85481 + @Param[in] h_FmPort A handle to a FM Port module.
85482 + @Param[in] newVal The desired BD ring length.
85483 +
85484 + @Return E_OK on success; Error code otherwise.
85485 +
85486 + @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init().
85487 + This routine is to be used only if Independent-Mode is enabled.
85488 +*//***************************************************************************/
85489 +t_Error FM_PORT_ConfigIMTxBdRingLength(t_Handle h_FmPort, uint16_t newVal);
85490 +
85491 +/**************************************************************************//**
85492 + @Function FM_PORT_ConfigIMFmanCtrlExternalStructsMemory
85493 +
85494 + @Description Configures memory partition and attributes for FMan-Controller
85495 + data structures (e.g. BD rings).
85496 + Calling this routine changes the internal driver data base
85497 + from its default configuration
85498 + [DEFAULT_PORT_ImfwExtStructsMemId, DEFAULT_PORT_ImfwExtStructsMemAttr].
85499 +
85500 + @Param[in] h_FmPort A handle to a FM Port module.
85501 + @Param[in] memId Memory partition ID.
85502 + @Param[in] memAttributes Memory attributes mask (a combination of MEMORY_ATTR_x flags).
85503 +
85504 + @Return E_OK on success; Error code otherwise.
85505 +*//***************************************************************************/
85506 +t_Error FM_PORT_ConfigIMFmanCtrlExternalStructsMemory(t_Handle h_FmPort,
85507 + uint8_t memId,
85508 + uint32_t memAttributes);
85509 +
85510 +/**************************************************************************//**
85511 + @Function FM_PORT_ConfigIMPolling
85512 +
85513 + @Description Changes the Rx flow from interrupt driven (default) to polling.
85514 +
85515 + @Param[in] h_FmPort A handle to a FM Port module.
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 + This routine is to be used only if Independent-Mode is enabled.
85521 +*//***************************************************************************/
85522 +t_Error FM_PORT_ConfigIMPolling(t_Handle h_FmPort);
85523 +
85524 +/**************************************************************************//**
85525 + @Function FM_PORT_ConfigMaxFrameLength
85526 +
85527 + @Description Changes the definition of the max size of frame that should be
85528 + transmitted/received on this port from its default value [DEFAULT_PORT_maxFrameLength].
85529 + This parameter is used for confirmation of the minimum Fifo
85530 + size calculations and only for Tx ports or ports working in
85531 + independent mode. This should be larger than the maximum possible
85532 + MTU that will be used for this port (i.e. its MAC).
85533 +
85534 + @Param[in] h_FmPort A handle to a FM Port module.
85535 + @Param[in] length Max size of frame
85536 +
85537 + @Return E_OK on success; Error code otherwise.
85538 +
85539 + @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init().
85540 + This routine is to be used only if Independent-Mode is enabled.
85541 +*//***************************************************************************/
85542 +t_Error FM_PORT_ConfigMaxFrameLength(t_Handle h_FmPort, uint16_t length);
85543 +
85544 +/**************************************************************************//*
85545 + @Function FM_PORT_ConfigTxFifoMinFillLevel
85546 +
85547 + @Description Calling this routine changes the fifo minimum
85548 + fill level parameter in the internal driver data base
85549 + from its default configuration [DEFAULT_PORT_txFifoMinFillLevel]
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] minFillLevel 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_ConfigTxFifoMinFillLevel(t_Handle h_FmPort, uint32_t minFillLevel);
85561 +
85562 +/**************************************************************************//*
85563 + @Function FM_PORT_ConfigFifoDeqPipelineDepth
85564 +
85565 + @Description Calling this routine changes the fifo dequeue
85566 + pipeline depth parameter in the internal driver data base
85567 +
85568 + from its default configuration: 1G ports: [DEFAULT_PORT_fifoDeqPipelineDepth_1G],
85569 + 10G port: [DEFAULT_PORT_fifoDeqPipelineDepth_10G],
85570 + OP port: [DEFAULT_PORT_fifoDeqPipelineDepth_OH]
85571 +
85572 + May be used for Tx/OP ports only
85573 +
85574 + @Param[in] h_FmPort A handle to a FM Port module.
85575 + @Param[in] deqPipelineDepth New value
85576 +
85577 + @Return E_OK on success; Error code otherwise.
85578 +
85579 + @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init().
85580 +*//***************************************************************************/
85581 +t_Error FM_PORT_ConfigFifoDeqPipelineDepth(t_Handle h_FmPort, uint8_t deqPipelineDepth);
85582 +
85583 +/**************************************************************************//*
85584 + @Function FM_PORT_ConfigTxFifoLowComfLevel
85585 +
85586 + @Description Calling this routine changes the fifo low comfort level
85587 + parameter in internal driver data base
85588 + from its default configuration [DEFAULT_PORT_txFifoLowComfLevel]
85589 +
85590 + May be used for Tx ports only
85591 +
85592 + @Param[in] h_FmPort A handle to a FM Port module.
85593 + @Param[in] fifoLowComfLevel New value
85594 +
85595 + @Return E_OK on success; Error code otherwise.
85596 +
85597 + @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init().
85598 +*//***************************************************************************/
85599 +t_Error FM_PORT_ConfigTxFifoLowComfLevel(t_Handle h_FmPort, uint32_t fifoLowComfLevel);
85600 +
85601 +/**************************************************************************//*
85602 + @Function FM_PORT_ConfigRxFifoThreshold
85603 +
85604 + @Description Calling this routine changes the threshold of the FIFO
85605 + fill level parameter in the internal driver data base
85606 + from its default configuration [DEFAULT_PORT_rxFifoThreshold]
85607 +
85608 + If the total number of buffers which are
85609 + currently in use and associated with the
85610 + specific RX port exceed this threshold, the
85611 + BMI will signal the MAC to send a pause frame
85612 + over the link.
85613 +
85614 + May be used for Rx ports only
85615 +
85616 + @Param[in] h_FmPort A handle to a FM Port module.
85617 + @Param[in] fifoThreshold New value
85618 +
85619 + @Return E_OK on success; Error code otherwise.
85620 +
85621 + @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init().
85622 +*//***************************************************************************/
85623 +t_Error FM_PORT_ConfigRxFifoThreshold(t_Handle h_FmPort, uint32_t fifoThreshold);
85624 +
85625 +/**************************************************************************//*
85626 + @Function FM_PORT_ConfigRxFifoPriElevationLevel
85627 +
85628 + @Description Calling this routine changes the priority elevation level
85629 + parameter in the internal driver data base from its default
85630 + configuration [DEFAULT_PORT_rxFifoPriElevationLevel]
85631 +
85632 + If the total number of buffers which are currently in use and
85633 + associated with the specific RX port exceed the amount specified
85634 + in priElevationLevel, BMI will signal the main FM's DMA to
85635 + elevate the FM priority on the system bus.
85636 +
85637 + May be used for Rx ports only
85638 +
85639 + @Param[in] h_FmPort A handle to a FM Port module.
85640 + @Param[in] priElevationLevel New value
85641 +
85642 + @Return E_OK on success; Error code otherwise.
85643 +
85644 + @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init().
85645 +*//***************************************************************************/
85646 +t_Error FM_PORT_ConfigRxFifoPriElevationLevel(t_Handle h_FmPort, uint32_t priElevationLevel);
85647 +
85648 +#ifdef FM_HEAVY_TRAFFIC_HANG_ERRATA_FMAN_A005669
85649 +/**************************************************************************//*
85650 + @Function FM_PORT_ConfigBCBWorkaround
85651 +
85652 + @Description Configures BCB errata workaround.
85653 +
85654 + When BCB errata is applicable, the workaround is always
85655 + performed by FM Controller. Thus, this functions doesn't
85656 + actually enable errata workaround but rather allows driver
85657 + to perform adjustments required due to errata workaround
85658 + execution in FM controller.
85659 +
85660 + Applying BCB workaround also configures FM_PORT_FRM_ERR_PHYSICAL
85661 + errors to be discarded. Thus FM_PORT_FRM_ERR_PHYSICAL can't be
85662 + set by FM_PORT_SetErrorsRoute() function.
85663 +
85664 + @Param[in] h_FmPort A handle to a FM Port module.
85665 +
85666 + @Return E_OK on success; Error code otherwise.
85667 +
85668 + @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init().
85669 +*//***************************************************************************/
85670 +t_Error FM_PORT_ConfigBCBWorkaround(t_Handle h_FmPort);
85671 +#endif /* FM_HEAVY_TRAFFIC_HANG_ERRATA_FMAN_A005669 */
85672 +
85673 +#if (DPAA_VERSION >= 11)
85674 +/**************************************************************************//*
85675 + @Function FM_PORT_ConfigInternalBuffOffset
85676 +
85677 + @Description Configures internal buffer offset.
85678 +
85679 + May be used for Rx and OP ports only
85680 +
85681 + @Param[in] h_FmPort A handle to a FM Port module.
85682 + @Param[in] val New value
85683 +
85684 + @Return E_OK on success; Error code otherwise.
85685 +
85686 + @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init().
85687 +*//***************************************************************************/
85688 +t_Error FM_PORT_ConfigInternalBuffOffset(t_Handle h_FmPort, uint8_t val);
85689 +#endif /* (DPAA_VERSION >= 11) */
85690 +
85691 +/** @} */ /* end of FM_PORT_advanced_init_grp group */
85692 +/** @} */ /* end of FM_PORT_init_grp group */
85693 +
85694 +
85695 +/**************************************************************************//**
85696 + @Group FM_PORT_runtime_control_grp FM Port Runtime Control Unit
85697 +
85698 + @Description FM Port Runtime control unit API functions, definitions and enums.
85699 +
85700 + @{
85701 +*//***************************************************************************/
85702 +
85703 +/**************************************************************************//**
85704 + @Description enum for defining FM Port counters
85705 +*//***************************************************************************/
85706 +typedef enum e_FmPortCounters {
85707 + e_FM_PORT_COUNTERS_CYCLE, /**< BMI performance counter */
85708 + e_FM_PORT_COUNTERS_TASK_UTIL, /**< BMI performance counter */
85709 + e_FM_PORT_COUNTERS_QUEUE_UTIL, /**< BMI performance counter */
85710 + e_FM_PORT_COUNTERS_DMA_UTIL, /**< BMI performance counter */
85711 + e_FM_PORT_COUNTERS_FIFO_UTIL, /**< BMI performance counter */
85712 + e_FM_PORT_COUNTERS_RX_PAUSE_ACTIVATION, /**< BMI Rx only performance counter */
85713 + e_FM_PORT_COUNTERS_FRAME, /**< BMI statistics counter */
85714 + e_FM_PORT_COUNTERS_DISCARD_FRAME, /**< BMI statistics counter */
85715 + e_FM_PORT_COUNTERS_DEALLOC_BUF, /**< BMI deallocate buffer statistics counter */
85716 + e_FM_PORT_COUNTERS_RX_BAD_FRAME, /**< BMI Rx only statistics counter */
85717 + e_FM_PORT_COUNTERS_RX_LARGE_FRAME, /**< BMI Rx only statistics counter */
85718 + e_FM_PORT_COUNTERS_RX_FILTER_FRAME, /**< BMI Rx & OP only statistics counter */
85719 + e_FM_PORT_COUNTERS_RX_LIST_DMA_ERR, /**< BMI Rx, OP & HC only statistics counter */
85720 + e_FM_PORT_COUNTERS_RX_OUT_OF_BUFFERS_DISCARD, /**< BMI Rx, OP & HC statistics counter */
85721 + e_FM_PORT_COUNTERS_PREPARE_TO_ENQUEUE_COUNTER, /**< BMI Rx, OP & HC only statistics counter */
85722 + e_FM_PORT_COUNTERS_WRED_DISCARD, /**< BMI OP & HC only statistics counter */
85723 + e_FM_PORT_COUNTERS_LENGTH_ERR, /**< BMI non-Rx statistics counter */
85724 + e_FM_PORT_COUNTERS_UNSUPPRTED_FORMAT, /**< BMI non-Rx statistics counter */
85725 + e_FM_PORT_COUNTERS_DEQ_TOTAL, /**< QMI total QM dequeues counter */
85726 + e_FM_PORT_COUNTERS_ENQ_TOTAL, /**< QMI total QM enqueues counter */
85727 + e_FM_PORT_COUNTERS_DEQ_FROM_DEFAULT, /**< QMI counter */
85728 + e_FM_PORT_COUNTERS_DEQ_CONFIRM /**< QMI counter */
85729 +} e_FmPortCounters;
85730 +
85731 +typedef struct t_FmPortBmiStats {
85732 + uint32_t cntCycle;
85733 + uint32_t cntTaskUtil;
85734 + uint32_t cntQueueUtil;
85735 + uint32_t cntDmaUtil;
85736 + uint32_t cntFifoUtil;
85737 + uint32_t cntRxPauseActivation;
85738 + uint32_t cntFrame;
85739 + uint32_t cntDiscardFrame;
85740 + uint32_t cntDeallocBuf;
85741 + uint32_t cntRxBadFrame;
85742 + uint32_t cntRxLargeFrame;
85743 + uint32_t cntRxFilterFrame;
85744 + uint32_t cntRxListDmaErr;
85745 + uint32_t cntRxOutOfBuffersDiscard;
85746 + uint32_t cntWredDiscard;
85747 + uint32_t cntLengthErr;
85748 + uint32_t cntUnsupportedFormat;
85749 +} t_FmPortBmiStats;
85750 +
85751 +/**************************************************************************//**
85752 + @Description Structure for Port id parameters.
85753 + Fields commented 'IN' are passed by the port module to be used
85754 + by the FM module.
85755 + Fields commented 'OUT' will be filled by FM before returning to port.
85756 +*//***************************************************************************/
85757 +typedef struct t_FmPortCongestionGrps {
85758 + uint16_t numOfCongestionGrpsToConsider; /**< The number of required CGs
85759 + to define the size of the following array */
85760 + uint8_t congestionGrpsToConsider[FM_PORT_NUM_OF_CONGESTION_GRPS];
85761 + /**< An array of CG indexes;
85762 + Note that the size of the array should be
85763 + 'numOfCongestionGrpsToConsider'. */
85764 +#if (DPAA_VERSION >= 11)
85765 + bool pfcPrioritiesEn[FM_PORT_NUM_OF_CONGESTION_GRPS][FM_MAX_NUM_OF_PFC_PRIORITIES];
85766 + /**< a matrix that represents the map between the CG ids
85767 + defined in 'congestionGrpsToConsider' to the priorties
85768 + mapping array. */
85769 +#endif /* (DPAA_VERSION >= 11) */
85770 +} t_FmPortCongestionGrps;
85771 +
85772 +/**************************************************************************//**
85773 + @Description Structure for Deep Sleep Auto Response ARP Entry
85774 +*//***************************************************************************/
85775 +typedef struct t_FmPortDsarArpEntry
85776 +{
85777 + uint32_t ipAddress;
85778 + uint8_t mac[6];
85779 + bool isVlan;
85780 + uint16_t vid;
85781 +} t_FmPortDsarArpEntry;
85782 +
85783 +/**************************************************************************//**
85784 + @Description Structure for Deep Sleep Auto Response ARP info
85785 +*//***************************************************************************/
85786 +typedef struct t_FmPortDsarArpInfo
85787 +{
85788 + uint8_t tableSize;
85789 + t_FmPortDsarArpEntry *p_AutoResTable;
85790 + bool enableConflictDetection; /* when TRUE Conflict Detection will be checked and wake the host if needed */
85791 +} t_FmPortDsarArpInfo;
85792 +
85793 +/**************************************************************************//**
85794 + @Description Structure for Deep Sleep Auto Response NDP Entry
85795 +*//***************************************************************************/
85796 +typedef struct t_FmPortDsarNdpEntry
85797 +{
85798 + uint32_t ipAddress[4];
85799 + uint8_t mac[6];
85800 + bool isVlan;
85801 + uint16_t vid;
85802 +} t_FmPortDsarNdpEntry;
85803 +
85804 +/**************************************************************************//**
85805 + @Description Structure for Deep Sleep Auto Response NDP info
85806 +*//***************************************************************************/
85807 +typedef struct t_FmPortDsarNdpInfo
85808 +{
85809 + uint32_t multicastGroup;
85810 +
85811 + uint8_t tableSizeAssigned;
85812 + t_FmPortDsarNdpEntry *p_AutoResTableAssigned; /* This list refer to solicitation IP addresses.
85813 + Note that all IP adresses must be from the same multicast group.
85814 + This will be checked and if not operation will fail. */
85815 + uint8_t tableSizeTmp;
85816 + t_FmPortDsarNdpEntry *p_AutoResTableTmp; /* This list refer to temp IP addresses.
85817 + Note that all temp IP adresses must be from the same multicast group.
85818 + This will be checked and if not operation will fail. */
85819 +
85820 + bool enableConflictDetection; /* when TRUE Conflict Detection will be checked and wake the host if needed */
85821 +
85822 +} t_FmPortDsarNdpInfo;
85823 +
85824 +/**************************************************************************//**
85825 + @Description Structure for Deep Sleep Auto Response ICMPV4 info
85826 +*//***************************************************************************/
85827 +typedef struct t_FmPortDsarEchoIpv4Info
85828 +{
85829 + uint8_t tableSize;
85830 + t_FmPortDsarArpEntry *p_AutoResTable;
85831 +} t_FmPortDsarEchoIpv4Info;
85832 +
85833 +/**************************************************************************//**
85834 + @Description Structure for Deep Sleep Auto Response ICMPV6 info
85835 +*//***************************************************************************/
85836 +typedef struct t_FmPortDsarEchoIpv6Info
85837 +{
85838 + uint8_t tableSize;
85839 + t_FmPortDsarNdpEntry *p_AutoResTable;
85840 +} t_FmPortDsarEchoIpv6Info;
85841 +
85842 +/**************************************************************************//**
85843 +@Description Deep Sleep Auto Response SNMP OIDs table entry
85844 +
85845 +*//***************************************************************************/
85846 +typedef struct {
85847 + uint16_t oidSize;
85848 + uint8_t *oidVal; /* only the oid string */
85849 + uint16_t resSize;
85850 + uint8_t *resVal; /* resVal will be the entire reply,
85851 + i.e. "Type|Length|Value" */
85852 +} t_FmPortDsarOidsEntry;
85853 +
85854 +/**************************************************************************//**
85855 + @Description Deep Sleep Auto Response SNMP IPv4 Addresses Table Entry
85856 + Refer to the FMan Controller spec for more details.
85857 +*//***************************************************************************/
85858 +typedef struct
85859 +{
85860 + uint32_t ipv4Addr; /*!< 32 bit IPv4 Address. */
85861 + bool isVlan;
85862 + uint16_t vid; /*!< 12 bits VLAN ID. The 4 left-most bits should be cleared */
85863 + /*!< This field should be 0x0000 for an entry with no VLAN tag or a null VLAN ID. */
85864 +} t_FmPortDsarSnmpIpv4AddrTblEntry;
85865 +
85866 +/**************************************************************************//**
85867 + @Description Deep Sleep Auto Response SNMP IPv6 Addresses Table Entry
85868 + Refer to the FMan Controller spec for more details.
85869 +*//***************************************************************************/
85870 +typedef struct
85871 +{
85872 + uint32_t ipv6Addr[4]; /*!< 4 * 32 bit IPv6 Address. */
85873 + bool isVlan;
85874 + uint16_t vid; /*!< 12 bits VLAN ID. The 4 left-most bits should be cleared */
85875 + /*!< This field should be 0x0000 for an entry with no VLAN tag or a null VLAN ID. */
85876 +} t_FmPortDsarSnmpIpv6AddrTblEntry;
85877 +
85878 +/**************************************************************************//**
85879 + @Description Deep Sleep Auto Response SNMP Descriptor
85880 +
85881 +*//***************************************************************************/
85882 +typedef struct
85883 +{
85884 + uint16_t control; /**< Control bits [0-15]. */
85885 + uint16_t maxSnmpMsgLength; /**< Maximal allowed SNMP message length. */
85886 + uint16_t numOfIpv4Addresses; /**< Number of entries in IPv4 addresses table. */
85887 + uint16_t numOfIpv6Addresses; /**< Number of entries in IPv6 addresses table. */
85888 + t_FmPortDsarSnmpIpv4AddrTblEntry *p_Ipv4AddrTbl; /**< Pointer to IPv4 addresses table. */
85889 + t_FmPortDsarSnmpIpv6AddrTblEntry *p_Ipv6AddrTbl; /**< Pointer to IPv6 addresses table. */
85890 + uint8_t *p_RdOnlyCommunityStr; /**< Pointer to the Read Only Community String. */
85891 + uint8_t *p_RdWrCommunityStr; /**< Pointer to the Read Write Community String. */
85892 + t_FmPortDsarOidsEntry *p_OidsTbl; /**< Pointer to OIDs table. */
85893 + uint32_t oidsTblSize; /**< Number of entries in OIDs table. */
85894 +} t_FmPortDsarSnmpInfo;
85895 +
85896 +/**************************************************************************//**
85897 + @Description Structure for Deep Sleep Auto Response filtering Entry
85898 +*//***************************************************************************/
85899 +typedef struct t_FmPortDsarFilteringEntry
85900 +{
85901 + uint16_t srcPort;
85902 + uint16_t dstPort;
85903 + uint16_t srcPortMask;
85904 + uint16_t dstPortMask;
85905 +} t_FmPortDsarFilteringEntry;
85906 +
85907 +/**************************************************************************//**
85908 + @Description Structure for Deep Sleep Auto Response filtering info
85909 +*//***************************************************************************/
85910 +typedef struct t_FmPortDsarFilteringInfo
85911 +{
85912 + /* IP protocol filtering parameters */
85913 + uint8_t ipProtTableSize;
85914 + uint8_t *p_IpProtTablePtr;
85915 + bool ipProtPassOnHit; /* when TRUE, miss in the table will cause the packet to be droped,
85916 + hit will pass the packet to UDP/TCP filters if needed and if not
85917 + to the classification tree. If the classification tree will pass
85918 + the packet to a queue it will cause a wake interupt.
85919 + When FALSE it the other way around. */
85920 + /* UDP port filtering parameters */
85921 + uint8_t udpPortsTableSize;
85922 + t_FmPortDsarFilteringEntry *p_UdpPortsTablePtr;
85923 + bool udpPortPassOnHit; /* when TRUE, miss in the table will cause the packet to be droped,
85924 + hit will pass the packet to classification tree.
85925 + If the classification tree will pass the packet to a queue it
85926 + will cause a wake interupt.
85927 + When FALSE it the other way around. */
85928 + /* TCP port filtering parameters */
85929 + uint16_t tcpFlagsMask;
85930 + uint8_t tcpPortsTableSize;
85931 + t_FmPortDsarFilteringEntry *p_TcpPortsTablePtr;
85932 + bool tcpPortPassOnHit; /* when TRUE, miss in the table will cause the packet to be droped,
85933 + hit will pass the packet to classification tree.
85934 + If the classification tree will pass the packet to a queue it
85935 + will cause a wake interupt.
85936 + When FALSE it the other way around. */
85937 +} t_FmPortDsarFilteringInfo;
85938 +
85939 +/**************************************************************************//**
85940 + @Description Structure for Deep Sleep Auto Response parameters
85941 +*//***************************************************************************/
85942 +typedef struct t_FmPortDsarParams
85943 +{
85944 + t_Handle h_FmPortTx;
85945 + t_FmPortDsarArpInfo *p_AutoResArpInfo;
85946 + t_FmPortDsarEchoIpv4Info *p_AutoResEchoIpv4Info;
85947 + t_FmPortDsarNdpInfo *p_AutoResNdpInfo;
85948 + t_FmPortDsarEchoIpv6Info *p_AutoResEchoIpv6Info;
85949 + t_FmPortDsarSnmpInfo *p_AutoResSnmpInfo;
85950 + t_FmPortDsarFilteringInfo *p_AutoResFilteringInfo;
85951 +} t_FmPortDsarParams;
85952 +
85953 +/**************************************************************************//**
85954 + @Function FM_PORT_EnterDsar
85955 +
85956 + @Description Enter Deep Sleep Auto Response mode.
85957 + This function write the apropriate values to in the relevant
85958 + tables in the MURAM.
85959 +
85960 + @Param[in] h_FmPortRx - FM PORT module descriptor
85961 + @Param[in] params - Auto Response parameters
85962 +
85963 + @Return E_OK on success; Error code otherwise.
85964 +
85965 + @Cautions Allowed only following FM_PORT_Init().
85966 +*//***************************************************************************/
85967 +t_Error FM_PORT_EnterDsar(t_Handle h_FmPortRx, t_FmPortDsarParams *params);
85968 +
85969 +/**************************************************************************//**
85970 + @Function FM_PORT_EnterDsarFinal
85971 +
85972 + @Description Enter Deep Sleep Auto Response mode.
85973 + This function sets the Tx port in independent mode as needed
85974 + and redirect the receive flow to go through the
85975 + Dsar Fman-ctrl code
85976 +
85977 + @Param[in] h_DsarRxPort - FM Rx PORT module descriptor
85978 + @Param[in] h_DsarTxPort - FM Tx PORT module descriptor
85979 +
85980 + @Return E_OK on success; Error code otherwise.
85981 +
85982 + @Cautions Allowed only following FM_PORT_Init().
85983 +*//***************************************************************************/
85984 +t_Error FM_PORT_EnterDsarFinal(t_Handle h_DsarRxPort, t_Handle h_DsarTxPort);
85985 +
85986 +/**************************************************************************//**
85987 + @Function FM_PORT_ExitDsar
85988 +
85989 + @Description Exit Deep Sleep Auto Response mode.
85990 + This function reverse the AR mode and put the ports back into
85991 + their original wake mode
85992 +
85993 + @Param[in] h_FmPortRx - FM PORT Rx module descriptor
85994 + @Param[in] h_FmPortTx - FM PORT Tx module descriptor
85995 +
85996 + @Return E_OK on success; Error code otherwise.
85997 +
85998 + @Cautions Allowed only following FM_PORT_EnterDsar().
85999 +*//***************************************************************************/
86000 +void FM_PORT_ExitDsar(t_Handle h_FmPortRx, t_Handle h_FmPortTx);
86001 +
86002 +/**************************************************************************//**
86003 + @Function FM_PORT_IsInDsar
86004 +
86005 + @Description This function returns TRUE if the port was set as Auto Response
86006 + and FALSE if not. Once Exit AR mode it will return FALSE as well
86007 + until re-enabled once more.
86008 +
86009 + @Param[in] h_FmPort - FM PORT module descriptor
86010 +
86011 + @Return E_OK on success; Error code otherwise.
86012 +*//***************************************************************************/
86013 +bool FM_PORT_IsInDsar(t_Handle h_FmPort);
86014 +
86015 +typedef struct t_FmPortDsarStats
86016 +{
86017 + uint32_t arpArCnt;
86018 + uint32_t echoIcmpv4ArCnt;
86019 + uint32_t ndpArCnt;
86020 + uint32_t echoIcmpv6ArCnt;
86021 + uint32_t snmpGetCnt;
86022 + uint32_t snmpGetNextCnt;
86023 +} t_FmPortDsarStats;
86024 +
86025 +/**************************************************************************//**
86026 + @Function FM_PORT_GetDsarStats
86027 +
86028 + @Description Return statistics for Deep Sleep Auto Response
86029 +
86030 + @Param[in] h_FmPortRx - FM PORT module descriptor
86031 + @Param[out] stats - structure containing the statistics counters
86032 +
86033 + @Return E_OK on success; Error code otherwise.
86034 +*//***************************************************************************/
86035 +t_Error FM_PORT_GetDsarStats(t_Handle h_FmPortRx, t_FmPortDsarStats *stats);
86036 +
86037 +#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
86038 +/**************************************************************************//**
86039 + @Function FM_PORT_DumpRegs
86040 +
86041 + @Description Dump all regs.
86042 +
86043 + Calling this routine invalidates the descriptor.
86044 +
86045 + @Param[in] h_FmPort - FM PORT module descriptor
86046 +
86047 + @Return E_OK on success; Error code otherwise.
86048 +
86049 + @Cautions Allowed only following FM_PORT_Init().
86050 +*//***************************************************************************/
86051 +t_Error FM_PORT_DumpRegs(t_Handle h_FmPort);
86052 +#endif /* (defined(DEBUG_ERRORS) && ... */
86053 +
86054 +/**************************************************************************//**
86055 + @Function FM_PORT_GetBufferDataOffset
86056 +
86057 + @Description Relevant for Rx ports.
86058 + Returns the data offset from the beginning of the data buffer
86059 +
86060 + @Param[in] h_FmPort - FM PORT module descriptor
86061 +
86062 + @Return data offset.
86063 +
86064 + @Cautions Allowed only following FM_PORT_Init().
86065 +*//***************************************************************************/
86066 +uint32_t FM_PORT_GetBufferDataOffset(t_Handle h_FmPort);
86067 +
86068 +/**************************************************************************//**
86069 + @Function FM_PORT_GetBufferICInfo
86070 +
86071 + @Description Returns the Internal Context offset from the beginning of the data buffer
86072 +
86073 + @Param[in] h_FmPort - FM PORT module descriptor
86074 + @Param[in] p_Data - A pointer to the data buffer.
86075 +
86076 + @Return Internal context info pointer on success, NULL if 'allOtherInfo' was not
86077 + configured for this port.
86078 +
86079 + @Cautions Allowed only following FM_PORT_Init().
86080 +*//***************************************************************************/
86081 +uint8_t * FM_PORT_GetBufferICInfo(t_Handle h_FmPort, char *p_Data);
86082 +
86083 +/**************************************************************************//**
86084 + @Function FM_PORT_GetBufferPrsResult
86085 +
86086 + @Description Returns the pointer to the parse result in the data buffer.
86087 + In Rx ports this is relevant after reception, if parse
86088 + result is configured to be part of the data passed to the
86089 + application. For non Rx ports it may be used to get the pointer
86090 + of the area in the buffer where parse result should be
86091 + initialized - if so configured.
86092 + See FM_PORT_ConfigBufferPrefixContent for data buffer prefix
86093 + configuration.
86094 +
86095 + @Param[in] h_FmPort - FM PORT module descriptor
86096 + @Param[in] p_Data - A pointer to the data buffer.
86097 +
86098 + @Return Parse result pointer on success, NULL if parse result was not
86099 + configured for this port.
86100 +
86101 + @Cautions Allowed only following FM_PORT_Init().
86102 +*//***************************************************************************/
86103 +t_FmPrsResult * FM_PORT_GetBufferPrsResult(t_Handle h_FmPort, char *p_Data);
86104 +
86105 +/**************************************************************************//**
86106 + @Function FM_PORT_GetBufferTimeStamp
86107 +
86108 + @Description Returns the time stamp in the data buffer.
86109 + Relevant for Rx ports for getting the buffer time stamp.
86110 + See FM_PORT_ConfigBufferPrefixContent for data buffer prefix
86111 + configuration.
86112 +
86113 + @Param[in] h_FmPort - FM PORT module descriptor
86114 + @Param[in] p_Data - A pointer to the data buffer.
86115 +
86116 + @Return A pointer to the hash result on success, NULL otherwise.
86117 +
86118 + @Cautions Allowed only following FM_PORT_Init().
86119 +*//***************************************************************************/
86120 +uint64_t * FM_PORT_GetBufferTimeStamp(t_Handle h_FmPort, char *p_Data);
86121 +
86122 +/**************************************************************************//**
86123 + @Function FM_PORT_GetBufferHashResult
86124 +
86125 + @Description Given a data buffer, on the condition that hash result was defined
86126 + as a part of the buffer content (see FM_PORT_ConfigBufferPrefixContent)
86127 + this routine will return the pointer to the hash result location in the
86128 + buffer prefix.
86129 +
86130 + @Param[in] h_FmPort - FM PORT module descriptor
86131 + @Param[in] p_Data - A pointer to the data buffer.
86132 +
86133 + @Return A pointer to the hash result on success, NULL otherwise.
86134 +
86135 + @Cautions Allowed only following FM_PORT_Init().
86136 +*//***************************************************************************/
86137 +uint8_t * FM_PORT_GetBufferHashResult(t_Handle h_FmPort, char *p_Data);
86138 +
86139 +/**************************************************************************//**
86140 + @Function FM_PORT_Disable
86141 +
86142 + @Description Gracefully disable an FM port. The port will not start new tasks after all
86143 + tasks associated with the port are terminated.
86144 +
86145 + @Param[in] h_FmPort A handle to a FM Port module.
86146 +
86147 + @Return E_OK on success; Error code otherwise.
86148 +
86149 + @Cautions Allowed only following FM_PORT_Init().
86150 + This is a blocking routine, it returns after port is
86151 + gracefully stopped, i.e. the port will not except new frames,
86152 + but it will finish all frames or tasks which were already began
86153 +*//***************************************************************************/
86154 +t_Error FM_PORT_Disable(t_Handle h_FmPort);
86155 +
86156 +/**************************************************************************//**
86157 + @Function FM_PORT_Enable
86158 +
86159 + @Description A runtime routine provided to allow disable/enable of port.
86160 +
86161 + @Param[in] h_FmPort A handle to a FM Port module.
86162 +
86163 + @Return E_OK on success; Error code otherwise.
86164 +
86165 + @Cautions Allowed only following FM_PORT_Init().
86166 +*//***************************************************************************/
86167 +t_Error FM_PORT_Enable(t_Handle h_FmPort);
86168 +
86169 +/**************************************************************************//**
86170 + @Function FM_PORT_SetRateLimit
86171 +
86172 + @Description Calling this routine enables rate limit algorithm.
86173 + By default, this functionality is disabled.
86174 + Note that rate-limit mechanism uses the FM time stamp.
86175 + The selected rate limit specified here would be
86176 + rounded DOWN to the nearest 16M.
86177 +
86178 + May be used for Tx and OP ports only
86179 +
86180 + @Param[in] h_FmPort A handle to a FM Port module.
86181 + @Param[in] p_RateLimit A structure of rate limit parameters
86182 +
86183 + @Return E_OK on success; Error code otherwise.
86184 +
86185 + @Cautions Allowed only following FM_PORT_Init().
86186 + If rate limit is set on a port that need to send PFC frames,
86187 + it might violate the stop transmit timing.
86188 +*//***************************************************************************/
86189 +t_Error FM_PORT_SetRateLimit(t_Handle h_FmPort, t_FmPortRateLimit *p_RateLimit);
86190 +
86191 +/**************************************************************************//**
86192 + @Function FM_PORT_DeleteRateLimit
86193 +
86194 + @Description Calling this routine disables and clears rate limit
86195 + initialization.
86196 +
86197 + May be used for Tx and OP ports only
86198 +
86199 + @Param[in] h_FmPort A handle to a FM Port module.
86200 +
86201 + @Return E_OK on success; Error code otherwise.
86202 +
86203 + @Cautions Allowed only following FM_PORT_Init().
86204 +*//***************************************************************************/
86205 +t_Error FM_PORT_DeleteRateLimit(t_Handle h_FmPort);
86206 +
86207 +/**************************************************************************//**
86208 + @Function FM_PORT_SetPfcPrioritiesMappingToQmanWQ
86209 +
86210 + @Description Calling this routine maps each PFC received priority to the transmit WQ.
86211 + This WQ will be blocked upon receiving a PFC frame with this priority.
86212 +
86213 + May be used for Tx ports only.
86214 +
86215 + @Param[in] h_FmPort A handle to a FM Port module.
86216 + @Param[in] prio PFC priority (0-7).
86217 + @Param[in] wq Work Queue (0-7).
86218 +
86219 + @Return E_OK on success; Error code otherwise.
86220 +
86221 + @Cautions Allowed only following FM_PORT_Init().
86222 +*//***************************************************************************/
86223 +t_Error FM_PORT_SetPfcPrioritiesMappingToQmanWQ(t_Handle h_FmPort, uint8_t prio, uint8_t wq);
86224 +
86225 +/**************************************************************************//**
86226 + @Function FM_PORT_SetStatisticsCounters
86227 +
86228 + @Description Calling this routine enables/disables port's statistics counters.
86229 + By default, counters are enabled.
86230 +
86231 + May be used for all port types
86232 +
86233 + @Param[in] h_FmPort A handle to a FM Port module.
86234 + @Param[in] enable TRUE to enable, FALSE to disable.
86235 +
86236 + @Return E_OK on success; Error code otherwise.
86237 +
86238 + @Cautions Allowed only following FM_PORT_Init().
86239 +*//***************************************************************************/
86240 +t_Error FM_PORT_SetStatisticsCounters(t_Handle h_FmPort, bool enable);
86241 +
86242 +/**************************************************************************//**
86243 + @Function FM_PORT_SetFrameQueueCounters
86244 +
86245 + @Description Calling this routine enables/disables port's enqueue/dequeue counters.
86246 + By default, counters are enabled.
86247 +
86248 + May be used for all ports
86249 +
86250 + @Param[in] h_FmPort A handle to a FM Port module.
86251 + @Param[in] enable TRUE to enable, FALSE to disable.
86252 +
86253 + @Return E_OK on success; Error code otherwise.
86254 +
86255 + @Cautions Allowed only following FM_PORT_Init().
86256 +*//***************************************************************************/
86257 +t_Error FM_PORT_SetFrameQueueCounters(t_Handle h_FmPort, bool enable);
86258 +
86259 +/**************************************************************************//**
86260 + @Function FM_PORT_AnalyzePerformanceParams
86261 +
86262 + @Description User may call this routine to so the driver will analyze if the
86263 + basic performance parameters are correct and also the driver may
86264 + suggest of improvements; The basic parameters are FIFO sizes, number
86265 + of DMAs and number of TNUMs for the port.
86266 +
86267 + May be used for all port types
86268 +
86269 + @Param[in] h_FmPort A handle to a FM Port module.
86270 +
86271 + @Return E_OK on success; Error code otherwise.
86272 +
86273 + @Cautions Allowed only following FM_PORT_Init().
86274 +*//***************************************************************************/
86275 +t_Error FM_PORT_AnalyzePerformanceParams(t_Handle h_FmPort);
86276 +
86277 +
86278 +/**************************************************************************//**
86279 + @Function FM_PORT_SetAllocBufCounter
86280 +
86281 + @Description Calling this routine enables/disables BM pool allocate
86282 + buffer counters.
86283 + By default, counters are enabled.
86284 +
86285 + May be used for Rx ports only
86286 +
86287 + @Param[in] h_FmPort A handle to a FM Port module.
86288 + @Param[in] poolId BM pool id.
86289 + @Param[in] enable TRUE to enable, FALSE to disable.
86290 +
86291 + @Return E_OK on success; Error code otherwise.
86292 +
86293 + @Cautions Allowed only following FM_PORT_Init().
86294 +*//***************************************************************************/
86295 +t_Error FM_PORT_SetAllocBufCounter(t_Handle h_FmPort, uint8_t poolId, bool enable);
86296 +
86297 +/**************************************************************************//**
86298 + @Function FM_PORT_GetBmiCounters
86299 +
86300 + @Description Read port's BMI stat counters and place them into
86301 + a designated structure of counters.
86302 +
86303 + @Param[in] h_FmPort A handle to a FM Port module.
86304 + @Param[out] p_BmiStats counters structure
86305 +
86306 + @Return E_OK on success; Error code otherwise.
86307 +
86308 + @Cautions Allowed only following FM_PORT_Init().
86309 +*//***************************************************************************/
86310 +t_Error FM_PORT_GetBmiCounters(t_Handle h_FmPort, t_FmPortBmiStats *p_BmiStats);
86311 +
86312 +/**************************************************************************//**
86313 + @Function FM_PORT_GetCounter
86314 +
86315 + @Description Reads one of the FM PORT counters.
86316 +
86317 + @Param[in] h_FmPort A handle to a FM Port module.
86318 + @Param[in] fmPortCounter The requested counter.
86319 +
86320 + @Return Counter's current value.
86321 +
86322 + @Cautions Allowed only following FM_PORT_Init().
86323 + Note that it is user's responsibility to call this routine only
86324 + for enabled counters, and there will be no indication if a
86325 + disabled counter is accessed.
86326 +*//***************************************************************************/
86327 +uint32_t FM_PORT_GetCounter(t_Handle h_FmPort, e_FmPortCounters fmPortCounter);
86328 +
86329 +/**************************************************************************//**
86330 + @Function FM_PORT_ModifyCounter
86331 +
86332 + @Description Sets a value to an enabled counter. Use "0" to reset the counter.
86333 +
86334 + @Param[in] h_FmPort A handle to a FM Port module.
86335 + @Param[in] fmPortCounter The requested counter.
86336 + @Param[in] value The requested value to be written into the counter.
86337 +
86338 + @Return E_OK on success; Error code otherwise.
86339 +
86340 + @Cautions Allowed only following FM_PORT_Init().
86341 +*//***************************************************************************/
86342 +t_Error FM_PORT_ModifyCounter(t_Handle h_FmPort, e_FmPortCounters fmPortCounter, uint32_t value);
86343 +
86344 +/**************************************************************************//**
86345 + @Function FM_PORT_GetAllocBufCounter
86346 +
86347 + @Description Reads one of the FM PORT buffer counters.
86348 +
86349 + @Param[in] h_FmPort A handle to a FM Port module.
86350 + @Param[in] poolId The requested pool.
86351 +
86352 + @Return Counter's current value.
86353 +
86354 + @Cautions Allowed only following FM_PORT_Init().
86355 + Note that it is user's responsibility to call this routine only
86356 + for enabled counters, and there will be no indication if a
86357 + disabled counter is accessed.
86358 +*//***************************************************************************/
86359 +uint32_t FM_PORT_GetAllocBufCounter(t_Handle h_FmPort, uint8_t poolId);
86360 +
86361 +/**************************************************************************//**
86362 + @Function FM_PORT_ModifyAllocBufCounter
86363 +
86364 + @Description Sets a value to an enabled counter. Use "0" to reset the counter.
86365 +
86366 + @Param[in] h_FmPort A handle to a FM Port module.
86367 + @Param[in] poolId The requested pool.
86368 + @Param[in] value The requested value to be written into the counter.
86369 +
86370 + @Return E_OK on success; Error code otherwise.
86371 +
86372 + @Cautions Allowed only following FM_PORT_Init().
86373 +*//***************************************************************************/
86374 +t_Error FM_PORT_ModifyAllocBufCounter(t_Handle h_FmPort, uint8_t poolId, uint32_t value);
86375 +
86376 +/**************************************************************************//**
86377 + @Function FM_PORT_AddCongestionGrps
86378 +
86379 + @Description This routine effects the corresponding Tx port.
86380 + It should be called in order to enable pause
86381 + frame transmission in case of congestion in one or more
86382 + of the congestion groups relevant to this port.
86383 + Each call to this routine may add one or more congestion
86384 + groups to be considered relevant to this port.
86385 +
86386 + May be used for Rx, or RX+OP ports only (depending on chip)
86387 +
86388 + @Param[in] h_FmPort A handle to a FM Port module.
86389 + @Param[in] p_CongestionGrps A pointer to an array of congestion groups
86390 + id's to consider.
86391 +
86392 + @Return E_OK on success; Error code otherwise.
86393 +
86394 + @Cautions Allowed only following FM_PORT_Init().
86395 +*//***************************************************************************/
86396 +t_Error FM_PORT_AddCongestionGrps(t_Handle h_FmPort, t_FmPortCongestionGrps *p_CongestionGrps);
86397 +
86398 +/**************************************************************************//**
86399 + @Function FM_PORT_RemoveCongestionGrps
86400 +
86401 + @Description This routine effects the corresponding Tx port. It should be
86402 + called when congestion groups were
86403 + defined for this port and are no longer relevant, or pause
86404 + frames transmitting is not required on their behalf.
86405 + Each call to this routine may remove one or more congestion
86406 + groups to be considered relevant to this port.
86407 +
86408 + May be used for Rx, or RX+OP ports only (depending on chip)
86409 +
86410 + @Param[in] h_FmPort A handle to a FM Port module.
86411 + @Param[in] p_CongestionGrps A pointer to an array of congestion groups
86412 + id's to consider.
86413 +
86414 + @Return E_OK on success; Error code otherwise.
86415 +
86416 + @Cautions Allowed only following FM_PORT_Init().
86417 +*//***************************************************************************/
86418 +t_Error FM_PORT_RemoveCongestionGrps(t_Handle h_FmPort, t_FmPortCongestionGrps *p_CongestionGrps);
86419 +
86420 +/**************************************************************************//**
86421 + @Function FM_PORT_IsStalled
86422 +
86423 + @Description A routine for checking whether the specified port is stalled.
86424 +
86425 + @Param[in] h_FmPort A handle to a FM Port module.
86426 +
86427 + @Return TRUE if port is stalled, FALSE otherwize
86428 +
86429 + @Cautions Allowed only following FM_PORT_Init().
86430 +*//***************************************************************************/
86431 +bool FM_PORT_IsStalled(t_Handle h_FmPort);
86432 +
86433 +/**************************************************************************//**
86434 + @Function FM_PORT_ReleaseStalled
86435 +
86436 + @Description This routine may be called in case the port was stalled and may
86437 + now be released.
86438 + Note that this routine is available only on older FMan revisions
86439 + (FMan v2, DPAA v1.0 only).
86440 +
86441 + @Param[in] h_FmPort A handle to a FM Port module.
86442 +
86443 + @Return E_OK on success; Error code otherwise.
86444 +
86445 + @Cautions Allowed only following FM_PORT_Init().
86446 +*//***************************************************************************/
86447 +t_Error FM_PORT_ReleaseStalled(t_Handle h_FmPort);
86448 +
86449 +/**************************************************************************//**
86450 + @Function FM_PORT_SetRxL4ChecksumVerify
86451 +
86452 + @Description This routine is relevant for Rx ports (1G and 10G). The routine
86453 + set/clear the L3/L4 checksum verification (on RX side).
86454 + Note that this takes affect only if hw-parser is enabled!
86455 +
86456 + @Param[in] h_FmPort A handle to a FM Port module.
86457 + @Param[in] l4Checksum boolean indicates whether to do L3/L4 checksum
86458 + on frames or not.
86459 +
86460 + @Return E_OK on success; Error code otherwise.
86461 +
86462 + @Cautions Allowed only following FM_PORT_Init().
86463 +*//***************************************************************************/
86464 +t_Error FM_PORT_SetRxL4ChecksumVerify(t_Handle h_FmPort, bool l4Checksum);
86465 +
86466 +/**************************************************************************//**
86467 + @Function FM_PORT_SetErrorsRoute
86468 +
86469 + @Description Errors selected for this routine will cause a frame with that error
86470 + to be enqueued to error queue.
86471 + Errors not selected for this routine will cause a frame with that error
86472 + to be enqueued to the one of the other port queues.
86473 + By default all errors are defined to be enqueued to error queue.
86474 + Errors that were configured to be discarded (at initialization)
86475 + may not be selected here.
86476 +
86477 + May be used for Rx and OP ports only
86478 +
86479 + @Param[in] h_FmPort A handle to a FM Port module.
86480 + @Param[in] errs A list of errors to enqueue to error queue
86481 +
86482 + @Return E_OK on success; Error code otherwise.
86483 +
86484 + @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init().
86485 +*//***************************************************************************/
86486 +t_Error FM_PORT_SetErrorsRoute(t_Handle h_FmPort, fmPortFrameErrSelect_t errs);
86487 +
86488 +/**************************************************************************//**
86489 + @Function FM_PORT_SetIMExceptions
86490 +
86491 + @Description Calling this routine enables/disables FM PORT interrupts.
86492 +
86493 + @Param[in] h_FmPort FM PORT module descriptor.
86494 + @Param[in] exception The exception to be selected.
86495 + @Param[in] enable TRUE to enable interrupt, FALSE to mask it.
86496 +
86497 + @Return E_OK on success; Error code otherwise.
86498 +
86499 + @Cautions Allowed only following FM_PORT_Init().
86500 + This routine should NOT be called from guest-partition
86501 + (i.e. guestId != NCSW_MASTER_ID)
86502 +*//***************************************************************************/
86503 +t_Error FM_PORT_SetIMExceptions(t_Handle h_FmPort, e_FmPortExceptions exception, bool enable);
86504 +
86505 +/**************************************************************************//*
86506 + @Function FM_PORT_SetPerformanceCounters
86507 +
86508 + @Description Calling this routine enables/disables port's performance counters.
86509 + By default, counters are enabled.
86510 +
86511 + May be used for all port types
86512 +
86513 + @Param[in] h_FmPort A handle to a FM Port module.
86514 + @Param[in] enable TRUE to enable, FALSE to disable.
86515 +
86516 + @Return E_OK on success; Error code otherwise.
86517 +
86518 + @Cautions Allowed only following FM_PORT_Init().
86519 +*//***************************************************************************/
86520 +t_Error FM_PORT_SetPerformanceCounters(t_Handle h_FmPort, bool enable);
86521 +
86522 +/**************************************************************************//*
86523 + @Function FM_PORT_SetPerformanceCountersParams
86524 +
86525 + @Description Calling this routine defines port's performance
86526 + counters parameters.
86527 +
86528 + May be used for all port types
86529 +
86530 + @Param[in] h_FmPort A handle to a FM Port module.
86531 + @Param[in] p_FmPortPerformanceCnt A pointer to a structure of performance
86532 + counters parameters.
86533 +
86534 + @Return E_OK on success; Error code otherwise.
86535 +
86536 + @Cautions Allowed only following FM_PORT_Init().
86537 +*//***************************************************************************/
86538 +t_Error FM_PORT_SetPerformanceCountersParams(t_Handle h_FmPort, t_FmPortPerformanceCnt *p_FmPortPerformanceCnt);
86539 +
86540 +/**************************************************************************//**
86541 + @Group FM_PORT_pcd_runtime_control_grp FM Port PCD Runtime Control Unit
86542 +
86543 + @Description FM Port PCD Runtime control unit API functions, definitions and enums.
86544 +
86545 + @{
86546 +*//***************************************************************************/
86547 +
86548 +/**************************************************************************//**
86549 + @Description A structure defining the KG scheme after the parser.
86550 + This is relevant only to change scheme selection mode - from
86551 + direct to indirect and vice versa, or when the scheme is selected directly,
86552 + to select the scheme id.
86553 +
86554 +*//***************************************************************************/
86555 +typedef struct t_FmPcdKgSchemeSelect {
86556 + bool direct; /**< TRUE to use 'h_Scheme' directly, FALSE to use LCV. */
86557 + t_Handle h_DirectScheme; /**< Scheme handle, selects the scheme after parser;
86558 + Relevant only when 'direct' is TRUE. */
86559 +} t_FmPcdKgSchemeSelect;
86560 +
86561 +/**************************************************************************//**
86562 + @Description A structure of scheme parameters
86563 +*//***************************************************************************/
86564 +typedef struct t_FmPcdPortSchemesParams {
86565 + uint8_t numOfSchemes; /**< Number of schemes for port to be bound to. */
86566 + t_Handle h_Schemes[FM_PCD_KG_NUM_OF_SCHEMES]; /**< Array of 'numOfSchemes' schemes for the
86567 + port to be bound to */
86568 +} t_FmPcdPortSchemesParams;
86569 +
86570 +/**************************************************************************//**
86571 + @Description Union for defining port protocol parameters for parser
86572 +*//***************************************************************************/
86573 +typedef union u_FmPcdHdrPrsOpts {
86574 + /* MPLS */
86575 + struct {
86576 + bool labelInterpretationEnable; /**< When this bit is set, the last MPLS label will be
86577 + interpreted as described in HW spec table. When the bit
86578 + is cleared, the parser will advance to MPLS next parse */
86579 + e_NetHeaderType nextParse; /**< must be equal or higher than IPv4 */
86580 + } mplsPrsOptions;
86581 + /* VLAN */
86582 + struct {
86583 + uint16_t tagProtocolId1; /**< User defined Tag Protocol Identifier, to be recognized
86584 + on VLAN TAG on top of 0x8100 and 0x88A8 */
86585 + uint16_t tagProtocolId2; /**< User defined Tag Protocol Identifier, to be recognized
86586 + on VLAN TAG on top of 0x8100 and 0x88A8 */
86587 + } vlanPrsOptions;
86588 + /* PPP */
86589 + struct{
86590 + bool enableMTUCheck; /**< Check validity of MTU according to RFC2516 */
86591 + } pppoePrsOptions;
86592 +
86593 + /* IPV6 */
86594 + struct{
86595 + bool routingHdrEnable; /**< TRUE to enable routing header, otherwise ignore */
86596 + } ipv6PrsOptions;
86597 +
86598 + /* UDP */
86599 + struct{
86600 + bool padIgnoreChecksum; /**< TRUE to ignore pad in checksum */
86601 + } udpPrsOptions;
86602 +
86603 + /* TCP */
86604 + struct {
86605 + bool padIgnoreChecksum; /**< TRUE to ignore pad in checksum */
86606 + } tcpPrsOptions;
86607 +} u_FmPcdHdrPrsOpts;
86608 +
86609 +/**************************************************************************//**
86610 + @Description A structure for defining each header for the parser
86611 +*//***************************************************************************/
86612 +typedef struct t_FmPcdPrsAdditionalHdrParams {
86613 + e_NetHeaderType hdr; /**< Selected header; use HEADER_TYPE_NONE
86614 + to indicate that sw parser is to run first
86615 + (before HW parser, and independent of the
86616 + existence of any protocol), in this case,
86617 + swPrsEnable must be set, and all other
86618 + parameters are irrelevant. */
86619 + bool errDisable; /**< TRUE to disable error indication */
86620 + bool swPrsEnable; /**< Enable jump to SW parser when this
86621 + header is recognized by the HW parser. */
86622 + uint8_t indexPerHdr; /**< Normally 0, if more than one sw parser
86623 + attachments exists for the same header,
86624 + (in the main sw parser code) use this
86625 + index to distinguish between them. */
86626 + bool usePrsOpts; /**< TRUE to use parser options. */
86627 + u_FmPcdHdrPrsOpts prsOpts; /**< A union according to header type,
86628 + defining the parser options selected.*/
86629 +} t_FmPcdPrsAdditionalHdrParams;
86630 +
86631 +/**************************************************************************//**
86632 + @Description struct for defining port PCD parameters
86633 +*//***************************************************************************/
86634 +typedef struct t_FmPortPcdPrsParams {
86635 + uint8_t prsResultPrivateInfo; /**< The private info provides a method of inserting
86636 + port information into the parser result. This information
86637 + may be extracted by Keygen and be used for frames
86638 + distribution when a per-port distinction is required,
86639 + it may also be used as a port logical id for analyzing
86640 + incoming frames. */
86641 + uint8_t parsingOffset; /**< Number of bytes from beginning of packet to start parsing */
86642 + e_NetHeaderType firstPrsHdr; /**< The type of the first header expected at 'parsingOffset' */
86643 + bool includeInPrsStatistics; /**< TRUE to include this port in the parser statistics;
86644 + NOTE: this field is not valid when the FM is in "guest" mode
86645 + and IPC is not available. */
86646 + uint8_t numOfHdrsWithAdditionalParams; /**< Normally 0, some headers may get
86647 + special parameters */
86648 + t_FmPcdPrsAdditionalHdrParams additionalParams[FM_PCD_PRS_NUM_OF_HDRS];
86649 + /**< 'numOfHdrsWithAdditionalParams' structures
86650 + of additional parameters
86651 + for each header that requires them */
86652 + bool setVlanTpid1; /**< TRUE to configure user selection of Ethertype to
86653 + indicate a VLAN tag (in addition to the TPID values
86654 + 0x8100 and 0x88A8). */
86655 + uint16_t vlanTpid1; /**< extra tag to use if setVlanTpid1=TRUE. */
86656 + bool setVlanTpid2; /**< TRUE to configure user selection of Ethertype to
86657 + indicate a VLAN tag (in addition to the TPID values
86658 + 0x8100 and 0x88A8). */
86659 + uint16_t vlanTpid2; /**< extra tag to use if setVlanTpid1=TRUE. */
86660 +} t_FmPortPcdPrsParams;
86661 +
86662 +/**************************************************************************//**
86663 + @Description struct for defining coarse alassification parameters
86664 +*//***************************************************************************/
86665 +typedef struct t_FmPortPcdCcParams {
86666 + t_Handle h_CcTree; /**< A handle to a CC tree */
86667 +} t_FmPortPcdCcParams;
86668 +
86669 +/**************************************************************************//**
86670 + @Description struct for defining keygen parameters
86671 +*//***************************************************************************/
86672 +typedef struct t_FmPortPcdKgParams {
86673 + uint8_t numOfSchemes; /**< Number of schemes for port to be bound to. */
86674 + t_Handle h_Schemes[FM_PCD_KG_NUM_OF_SCHEMES];
86675 + /**< Array of 'numOfSchemes' schemes handles for the
86676 + port to be bound to */
86677 + bool directScheme; /**< TRUE for going from parser to a specific scheme,
86678 + regardless of parser result */
86679 + t_Handle h_DirectScheme; /**< relevant only if direct == TRUE, Scheme handle,
86680 + as returned by FM_PCD_KgSetScheme */
86681 +} t_FmPortPcdKgParams;
86682 +
86683 +/**************************************************************************//**
86684 + @Description struct for defining policer parameters
86685 +*//***************************************************************************/
86686 +typedef struct t_FmPortPcdPlcrParams {
86687 + t_Handle h_Profile; /**< Selected profile handle */
86688 +} t_FmPortPcdPlcrParams;
86689 +
86690 +/**************************************************************************//**
86691 + @Description struct for defining port PCD parameters
86692 +*//***************************************************************************/
86693 +typedef struct t_FmPortPcdParams {
86694 + e_FmPortPcdSupport pcdSupport; /**< Relevant for Rx and offline ports only.
86695 + Describes the active PCD engines for this port. */
86696 + t_Handle h_NetEnv; /**< HL Unused in PLCR only mode */
86697 + t_FmPortPcdPrsParams *p_PrsParams; /**< Parser parameters for this port */
86698 + t_FmPortPcdCcParams *p_CcParams; /**< Coarse classification parameters for this port */
86699 + t_FmPortPcdKgParams *p_KgParams; /**< Keygen parameters for this port */
86700 + t_FmPortPcdPlcrParams *p_PlcrParams; /**< Policer parameters for this port; Relevant for one of
86701 + following cases:
86702 + e_FM_PORT_PCD_SUPPORT_PLCR_ONLY or
86703 + e_FM_PORT_PCD_SUPPORT_PRS_AND_PLCR were selected,
86704 + or if any flow uses a KG scheme were policer
86705 + profile is not generated
86706 + ('bypassPlcrProfileGeneration selected'). */
86707 + t_Handle h_IpReassemblyManip; /**< IP Reassembly manipulation */
86708 +#if (DPAA_VERSION >= 11)
86709 + t_Handle h_CapwapReassemblyManip;/**< CAPWAP Reassembly manipulation */
86710 +#endif /* (DPAA_VERSION >= 11) */
86711 +} t_FmPortPcdParams;
86712 +
86713 +/**************************************************************************//**
86714 + @Description A structure for defining the Parser starting point
86715 +*//***************************************************************************/
86716 +typedef struct t_FmPcdPrsStart {
86717 + uint8_t parsingOffset; /**< Number of bytes from beginning of packet to
86718 + start parsing */
86719 + e_NetHeaderType firstPrsHdr; /**< The type of the first header axpected at
86720 + 'parsingOffset' */
86721 +} t_FmPcdPrsStart;
86722 +
86723 +#if (DPAA_VERSION >= 11)
86724 +/**************************************************************************//**
86725 + @Description struct for defining external buffer margins
86726 +*//***************************************************************************/
86727 +typedef struct t_FmPortVSPAllocParams {
86728 + uint8_t numOfProfiles; /**< Number of Virtual Storage Profiles; must be a power of 2 */
86729 + uint8_t dfltRelativeId; /**< The default Virtual-Storage-Profile-id dedicated to Rx/OP port
86730 + The same default Virtual-Storage-Profile-id will be for coupled Tx port
86731 + if relevant function called for Rx port */
86732 + t_Handle h_FmTxPort; /**< Handle to coupled Tx Port; not relevant for OP port. */
86733 +} t_FmPortVSPAllocParams;
86734 +#endif /* (DPAA_VERSION >= 11) */
86735 +
86736 +
86737 +/**************************************************************************//**
86738 + @Function FM_PORT_SetPCD
86739 +
86740 + @Description Calling this routine defines the port's PCD configuration.
86741 + It changes it from its default configuration which is PCD
86742 + disabled (BMI to BMI) and configures it according to the passed
86743 + parameters.
86744 +
86745 + May be used for Rx and OP ports only
86746 +
86747 + @Param[in] h_FmPort A handle to a FM Port module.
86748 + @Param[in] p_FmPortPcd A Structure of parameters defining the port's PCD
86749 + configuration.
86750 +
86751 + @Return E_OK on success; Error code otherwise.
86752 +
86753 + @Cautions Allowed only following FM_PORT_Init().
86754 +*//***************************************************************************/
86755 +t_Error FM_PORT_SetPCD(t_Handle h_FmPort, t_FmPortPcdParams *p_FmPortPcd);
86756 +
86757 +/**************************************************************************//**
86758 + @Function FM_PORT_DeletePCD
86759 +
86760 + @Description Calling this routine releases the port's PCD configuration.
86761 + The port returns to its default configuration which is PCD
86762 + disabled (BMI to BMI) and all PCD configuration is removed.
86763 +
86764 + May be used for Rx and OP ports which are
86765 + in PCD mode only
86766 +
86767 + @Param[in] h_FmPort A handle to a FM Port module.
86768 +
86769 + @Return E_OK on success; Error code otherwise.
86770 +
86771 + @Cautions Allowed only following FM_PORT_Init().
86772 +*//***************************************************************************/
86773 +t_Error FM_PORT_DeletePCD(t_Handle h_FmPort);
86774 +
86775 +/**************************************************************************//**
86776 + @Function FM_PORT_AttachPCD
86777 +
86778 + @Description This routine may be called after FM_PORT_DetachPCD was called,
86779 + to return to the originally configured PCD support flow.
86780 + The couple of routines are used to allow PCD configuration changes
86781 + that demand that PCD will not be used while changes take place.
86782 +
86783 + May be used for Rx and OP ports which are
86784 + in PCD mode only
86785 +
86786 + @Param[in] h_FmPort A handle to a FM Port module.
86787 +
86788 + @Return E_OK on success; Error code otherwise.
86789 +
86790 + @Cautions Allowed only following FM_PORT_Init().
86791 +*//***************************************************************************/
86792 +t_Error FM_PORT_AttachPCD(t_Handle h_FmPort);
86793 +
86794 +/**************************************************************************//**
86795 + @Function FM_PORT_DetachPCD
86796 +
86797 + @Description Calling this routine detaches the port from its PCD functionality.
86798 + The port returns to its default flow which is BMI to BMI.
86799 +
86800 + May be used for Rx and OP ports which are
86801 + in PCD mode only
86802 +
86803 + @Param[in] h_FmPort A handle to a FM Port module.
86804 +
86805 + @Return E_OK on success; Error code otherwise.
86806 +
86807 + @Cautions Allowed only following FM_PORT_AttachPCD().
86808 +*//***************************************************************************/
86809 +t_Error FM_PORT_DetachPCD(t_Handle h_FmPort);
86810 +
86811 +/**************************************************************************//**
86812 + @Function FM_PORT_PcdPlcrAllocProfiles
86813 +
86814 + @Description This routine may be called only for ports that use the Policer in
86815 + order to allocate private policer profiles.
86816 +
86817 + @Param[in] h_FmPort A handle to a FM Port module.
86818 + @Param[in] numOfProfiles The number of required policer profiles
86819 +
86820 + @Return E_OK on success; Error code otherwise.
86821 +
86822 + @Cautions Allowed only following FM_PORT_Init() and FM_PCD_Init(),
86823 + and before FM_PORT_SetPCD().
86824 +*//***************************************************************************/
86825 +t_Error FM_PORT_PcdPlcrAllocProfiles(t_Handle h_FmPort, uint16_t numOfProfiles);
86826 +
86827 +/**************************************************************************//**
86828 + @Function FM_PORT_PcdPlcrFreeProfiles
86829 +
86830 + @Description This routine should be called for freeing private policer profiles.
86831 +
86832 + @Param[in] h_FmPort A handle to a FM Port module.
86833 +
86834 + @Return E_OK on success; Error code otherwise.
86835 +
86836 + @Cautions Allowed only following FM_PORT_Init() and FM_PCD_Init(),
86837 + and before FM_PORT_SetPCD().
86838 +*//***************************************************************************/
86839 +t_Error FM_PORT_PcdPlcrFreeProfiles(t_Handle h_FmPort);
86840 +
86841 +#if (DPAA_VERSION >= 11)
86842 +/**************************************************************************//**
86843 + @Function FM_PORT_VSPAlloc
86844 +
86845 + @Description This routine allocated VSPs per port and forces the port to work
86846 + in VSP mode. Note that the port is initialized by default with the
86847 + physical-storage-profile only.
86848 +
86849 + @Param[in] h_FmPort A handle to a FM Port module.
86850 + @Param[in] p_Params A structure of parameters for allocation VSP's per port
86851 +
86852 + @Return E_OK on success; Error code otherwise.
86853 +
86854 + @Cautions Allowed only following FM_PORT_Init(), and before FM_PORT_SetPCD()
86855 + and also before FM_PORT_Enable(); i.e. the port should be disabled.
86856 +*//***************************************************************************/
86857 +t_Error FM_PORT_VSPAlloc(t_Handle h_FmPort, t_FmPortVSPAllocParams *p_Params);
86858 +#endif /* (DPAA_VERSION >= 11) */
86859 +
86860 +/**************************************************************************//**
86861 + @Function FM_PORT_PcdKgModifyInitialScheme
86862 +
86863 + @Description This routine may be called only for ports that use the keygen in
86864 + order to change the initial scheme frame should be routed to.
86865 + The change may be of a scheme id (in case of direct mode),
86866 + from direct to indirect, or from indirect to direct - specifying the scheme id.
86867 +
86868 + @Param[in] h_FmPort A handle to a FM Port module.
86869 + @Param[in] p_FmPcdKgScheme A structure of parameters for defining whether
86870 + a scheme is direct/indirect, and if direct - scheme id.
86871 +
86872 + @Return E_OK on success; Error code otherwise.
86873 +
86874 + @Cautions Allowed only following FM_PORT_Init() and FM_PORT_SetPCD().
86875 +*//***************************************************************************/
86876 +t_Error FM_PORT_PcdKgModifyInitialScheme (t_Handle h_FmPort, t_FmPcdKgSchemeSelect *p_FmPcdKgScheme);
86877 +
86878 +/**************************************************************************//**
86879 + @Function FM_PORT_PcdPlcrModifyInitialProfile
86880 +
86881 + @Description This routine may be called for ports with flows
86882 + e_FM_PORT_PCD_SUPPORT_PLCR_ONLY or e_FM_PORT_PCD_SUPPORT_PRS_AND_PLCR
86883 + only, to change the initial Policer profile frame should be
86884 + routed to. The change may be of a profile and/or absolute/direct
86885 + mode selection.
86886 +
86887 + @Param[in] h_FmPort A handle to a FM Port module.
86888 + @Param[in] h_Profile Policer profile handle
86889 +
86890 + @Return E_OK on success; Error code otherwise.
86891 +
86892 + @Cautions Allowed only following FM_PORT_Init() and FM_PORT_SetPCD().
86893 +*//***************************************************************************/
86894 +t_Error FM_PORT_PcdPlcrModifyInitialProfile (t_Handle h_FmPort, t_Handle h_Profile);
86895 +
86896 +/**************************************************************************//**
86897 + @Function FM_PORT_PcdCcModifyTree
86898 +
86899 + @Description This routine may be called for ports that use coarse classification tree
86900 + if the user wishes to replace the tree. The routine may not be called while port
86901 + receives packets using the PCD functionalities, therefor port must be first detached
86902 + from the PCD, only than the routine may be called, and than port be attached to PCD again.
86903 +
86904 + @Param[in] h_FmPort A handle to a FM Port module.
86905 + @Param[in] h_CcTree A CC tree that was already built. The tree id as returned from
86906 + the BuildTree routine.
86907 +
86908 + @Return E_OK on success; Error code otherwise.
86909 +
86910 + @Cautions Allowed only following FM_PORT_Init(), FM_PORT_SetPCD() and FM_PORT_DetachPCD()
86911 +*//***************************************************************************/
86912 +t_Error FM_PORT_PcdCcModifyTree (t_Handle h_FmPort, t_Handle h_CcTree);
86913 +
86914 +/**************************************************************************//**
86915 + @Function FM_PORT_PcdKgBindSchemes
86916 +
86917 + @Description These routines may be called for adding more schemes for the
86918 + port to be bound to. The selected schemes are not added,
86919 + just this specific port starts using them.
86920 +
86921 + @Param[in] h_FmPort A handle to a FM Port module.
86922 + @Param[in] p_PortScheme A structure defining the list of schemes to be added.
86923 +
86924 + @Return E_OK on success; Error code otherwise.
86925 +
86926 + @Cautions Allowed only following FM_PORT_Init() and FM_PORT_SetPCD().
86927 +*//***************************************************************************/
86928 +t_Error FM_PORT_PcdKgBindSchemes (t_Handle h_FmPort, t_FmPcdPortSchemesParams *p_PortScheme);
86929 +
86930 +/**************************************************************************//**
86931 + @Function FM_PORT_PcdKgUnbindSchemes
86932 +
86933 + @Description These routines may be called for adding more schemes for the
86934 + port to be bound to. The selected schemes are not removed or invalidated,
86935 + just this specific port stops using them.
86936 +
86937 + @Param[in] h_FmPort A handle to a FM Port module.
86938 + @Param[in] p_PortScheme A structure defining the list of schemes to be added.
86939 +
86940 + @Return E_OK on success; Error code otherwise.
86941 +
86942 + @Cautions Allowed only following FM_PORT_Init() and FM_PORT_SetPCD().
86943 +*//***************************************************************************/
86944 +t_Error FM_PORT_PcdKgUnbindSchemes (t_Handle h_FmPort, t_FmPcdPortSchemesParams *p_PortScheme);
86945 +
86946 +/**************************************************************************//**
86947 + @Function FM_PORT_GetIPv4OptionsCount
86948 +
86949 + @Description TODO
86950 +
86951 + @Param[in] h_FmPort A handle to a FM Port module.
86952 + @Param[out] p_Ipv4OptionsCount will hold the counter value
86953 +
86954 + @Return E_OK on success; Error code otherwise.
86955 +
86956 + @Cautions Allowed only following FM_PORT_Init()
86957 +*//***************************************************************************/
86958 +t_Error FM_PORT_GetIPv4OptionsCount(t_Handle h_FmPort, uint32_t *p_Ipv4OptionsCount);
86959 +
86960 +/** @} */ /* end of FM_PORT_pcd_runtime_control_grp group */
86961 +/** @} */ /* end of FM_PORT_runtime_control_grp group */
86962 +
86963 +
86964 +/**************************************************************************//**
86965 + @Group FM_PORT_runtime_data_grp FM Port Runtime Data-path Unit
86966 +
86967 + @Description FM Port Runtime data unit API functions, definitions and enums.
86968 + This API is valid only if working in Independent-Mode.
86969 +
86970 + @{
86971 +*//***************************************************************************/
86972 +
86973 +/**************************************************************************//**
86974 + @Function FM_PORT_ImTx
86975 +
86976 + @Description Tx function, called to transmit a data buffer on the port.
86977 +
86978 + @Param[in] h_FmPort A handle to a FM Port module.
86979 + @Param[in] p_Data A pointer to an LCP data buffer.
86980 + @Param[in] length Size of data for transmission.
86981 + @Param[in] lastBuffer Buffer position - TRUE for the last buffer
86982 + of a frame, including a single buffer frame
86983 + @Param[in] h_BufContext A handle of the user acossiated with this buffer
86984 +
86985 + @Return E_OK on success; Error code otherwise.
86986 +
86987 + @Cautions Allowed only following FM_PORT_Init().
86988 + NOTE - This routine can be used only when working in
86989 + Independent-Mode mode.
86990 +*//***************************************************************************/
86991 +t_Error FM_PORT_ImTx( t_Handle h_FmPort,
86992 + uint8_t *p_Data,
86993 + uint16_t length,
86994 + bool lastBuffer,
86995 + t_Handle h_BufContext);
86996 +
86997 +/**************************************************************************//**
86998 + @Function FM_PORT_ImTxConf
86999 +
87000 + @Description Tx port confirmation routine, optional, may be called to verify
87001 + transmission of all frames. The procedure performed by this
87002 + routine will be performed automatically on next buffer transmission,
87003 + but if desired, calling this routine will invoke this action on
87004 + demand.
87005 +
87006 + @Param[in] h_FmPort A handle to a FM Port module.
87007 +
87008 + @Cautions Allowed only following FM_PORT_Init().
87009 + NOTE - This routine can be used only when working in
87010 + Independent-Mode mode.
87011 +*//***************************************************************************/
87012 +void FM_PORT_ImTxConf(t_Handle h_FmPort);
87013 +
87014 +/**************************************************************************//**
87015 + @Function FM_PORT_ImRx
87016 +
87017 + @Description Rx function, may be called to poll for received buffers.
87018 + Normally, Rx process is invoked by the driver on Rx interrupt.
87019 + Alternatively, this routine may be called on demand.
87020 +
87021 + @Param[in] h_FmPort A handle to a FM Port module.
87022 +
87023 + @Return E_OK on success; Error code otherwise.
87024 +
87025 + @Cautions Allowed only following FM_PORT_Init().
87026 + NOTE - This routine can be used only when working in
87027 + Independent-Mode mode.
87028 +*//***************************************************************************/
87029 +t_Error FM_PORT_ImRx(t_Handle h_FmPort);
87030 +
87031 +/** @} */ /* end of FM_PORT_runtime_data_grp group */
87032 +/** @} */ /* end of FM_PORT_grp group */
87033 +/** @} */ /* end of FM_grp group */
87034 +
87035 +
87036 +
87037 +#ifdef NCSW_BACKWARD_COMPATIBLE_API
87038 +#define FM_PORT_ConfigTxFifoDeqPipelineDepth FM_PORT_ConfigFifoDeqPipelineDepth
87039 +#endif /* NCSW_BACKWARD_COMPATIBLE_API */
87040 +
87041 +
87042 +#endif /* __FM_PORT_EXT */
87043 --- /dev/null
87044 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/Peripherals/fm_rtc_ext.h
87045 @@ -0,0 +1,619 @@
87046 +/*
87047 + * Copyright 2008-2012 Freescale Semiconductor Inc.
87048 + *
87049 + * Redistribution and use in source and binary forms, with or without
87050 + * modification, are permitted provided that the following conditions are met:
87051 + * * Redistributions of source code must retain the above copyright
87052 + * notice, this list of conditions and the following disclaimer.
87053 + * * Redistributions in binary form must reproduce the above copyright
87054 + * notice, this list of conditions and the following disclaimer in the
87055 + * documentation and/or other materials provided with the distribution.
87056 + * * Neither the name of Freescale Semiconductor nor the
87057 + * names of its contributors may be used to endorse or promote products
87058 + * derived from this software without specific prior written permission.
87059 + *
87060 + *
87061 + * ALTERNATIVELY, this software may be distributed under the terms of the
87062 + * GNU General Public License ("GPL") as published by the Free Software
87063 + * Foundation, either version 2 of that License or (at your option) any
87064 + * later version.
87065 + *
87066 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
87067 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
87068 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
87069 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
87070 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
87071 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
87072 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
87073 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
87074 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
87075 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
87076 + */
87077 +
87078 +
87079 +/**************************************************************************//**
87080 + @File fm_rtc_ext.h
87081 +
87082 + @Description External definitions and API for FM RTC IEEE1588 Timer Module.
87083 +
87084 + @Cautions None.
87085 +*//***************************************************************************/
87086 +
87087 +#ifndef __FM_RTC_EXT_H__
87088 +#define __FM_RTC_EXT_H__
87089 +
87090 +
87091 +#include "error_ext.h"
87092 +#include "std_ext.h"
87093 +#include "fsl_fman_rtc.h"
87094 +
87095 +/**************************************************************************//**
87096 +
87097 + @Group FM_grp Frame Manager API
87098 +
87099 + @Description FM API functions, definitions and enums
87100 +
87101 + @{
87102 +*//***************************************************************************/
87103 +
87104 +/**************************************************************************//**
87105 + @Group fm_rtc_grp FM RTC
87106 +
87107 + @Description FM RTC functions, definitions and enums.
87108 +
87109 + @{
87110 +*//***************************************************************************/
87111 +
87112 +/**************************************************************************//**
87113 + @Group fm_rtc_init_grp FM RTC Initialization Unit
87114 +
87115 + @Description FM RTC initialization API.
87116 +
87117 + @{
87118 +*//***************************************************************************/
87119 +
87120 +/**************************************************************************//**
87121 + @Description FM RTC Alarm Polarity Options.
87122 +*//***************************************************************************/
87123 +typedef enum e_FmRtcAlarmPolarity
87124 +{
87125 + e_FM_RTC_ALARM_POLARITY_ACTIVE_HIGH = E_FMAN_RTC_ALARM_POLARITY_ACTIVE_HIGH, /**< Active-high output polarity */
87126 + e_FM_RTC_ALARM_POLARITY_ACTIVE_LOW = E_FMAN_RTC_ALARM_POLARITY_ACTIVE_LOW /**< Active-low output polarity */
87127 +} e_FmRtcAlarmPolarity;
87128 +
87129 +/**************************************************************************//**
87130 + @Description FM RTC Trigger Polarity Options.
87131 +*//***************************************************************************/
87132 +typedef enum e_FmRtcTriggerPolarity
87133 +{
87134 + e_FM_RTC_TRIGGER_ON_RISING_EDGE = E_FMAN_RTC_TRIGGER_ON_RISING_EDGE, /**< Trigger on rising edge */
87135 + e_FM_RTC_TRIGGER_ON_FALLING_EDGE = E_FMAN_RTC_TRIGGER_ON_FALLING_EDGE /**< Trigger on falling edge */
87136 +} e_FmRtcTriggerPolarity;
87137 +
87138 +/**************************************************************************//**
87139 + @Description IEEE1588 Timer Module FM RTC Optional Clock Sources.
87140 +*//***************************************************************************/
87141 +typedef enum e_FmSrcClock
87142 +{
87143 + e_FM_RTC_SOURCE_CLOCK_EXTERNAL = E_FMAN_RTC_SOURCE_CLOCK_EXTERNAL, /**< external high precision timer reference clock */
87144 + e_FM_RTC_SOURCE_CLOCK_SYSTEM = E_FMAN_RTC_SOURCE_CLOCK_SYSTEM, /**< MAC system clock */
87145 + e_FM_RTC_SOURCE_CLOCK_OSCILATOR = E_FMAN_RTC_SOURCE_CLOCK_OSCILATOR /**< RTC clock oscilator */
87146 +}e_FmSrcClk;
87147 +
87148 +/**************************************************************************//**
87149 + @Description FM RTC configuration parameters structure.
87150 +
87151 + This structure should be passed to FM_RTC_Config().
87152 +*//***************************************************************************/
87153 +typedef struct t_FmRtcParams
87154 +{
87155 + t_Handle h_Fm; /**< FM Handle*/
87156 + uintptr_t baseAddress; /**< Base address of FM RTC registers */
87157 + t_Handle h_App; /**< A handle to an application layer object; This handle will
87158 + be passed by the driver upon calling the above callbacks */
87159 +} t_FmRtcParams;
87160 +
87161 +
87162 +/**************************************************************************//**
87163 + @Function FM_RTC_Config
87164 +
87165 + @Description Configures the FM RTC module according to user's parameters.
87166 +
87167 + The driver assigns default values to some FM RTC parameters.
87168 + These parameters can be overwritten using the advanced
87169 + configuration routines.
87170 +
87171 + @Param[in] p_FmRtcParam - FM RTC configuration parameters.
87172 +
87173 + @Return Handle to the new FM RTC object; NULL pointer on failure.
87174 +
87175 + @Cautions None
87176 +*//***************************************************************************/
87177 +t_Handle FM_RTC_Config(t_FmRtcParams *p_FmRtcParam);
87178 +
87179 +/**************************************************************************//**
87180 + @Function FM_RTC_Init
87181 +
87182 + @Description Initializes the FM RTC driver and hardware.
87183 +
87184 + @Param[in] h_FmRtc - Handle to FM RTC object.
87185 +
87186 + @Return E_OK on success; Error code otherwise.
87187 +
87188 + @Cautions h_FmRtc must have been previously created using FM_RTC_Config().
87189 +*//***************************************************************************/
87190 +t_Error FM_RTC_Init(t_Handle h_FmRtc);
87191 +
87192 +/**************************************************************************//**
87193 + @Function FM_RTC_Free
87194 +
87195 + @Description Frees the FM RTC object and all allocated resources.
87196 +
87197 + @Param[in] h_FmRtc - Handle to FM RTC object.
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_Free(t_Handle h_FmRtc);
87204 +
87205 +
87206 +/**************************************************************************//**
87207 + @Group fm_rtc_adv_config_grp FM RTC Advanced Configuration Unit
87208 +
87209 + @Description FM RTC advanced configuration functions.
87210 +
87211 + @{
87212 +*//***************************************************************************/
87213 +
87214 +/**************************************************************************//**
87215 + @Function FM_RTC_ConfigPeriod
87216 +
87217 + @Description Configures the period of the timestamp if different than
87218 + default [DEFAULT_clockPeriod].
87219 +
87220 + @Param[in] h_FmRtc - Handle to FM RTC object.
87221 + @Param[in] period - Period in nano-seconds.
87222 +
87223 + @Return E_OK on success; Error code otherwise.
87224 +
87225 + @Cautions h_FmRtc must have been previously created using FM_RTC_Config().
87226 +*//***************************************************************************/
87227 +t_Error FM_RTC_ConfigPeriod(t_Handle h_FmRtc, uint32_t period);
87228 +
87229 +/**************************************************************************//**
87230 + @Function FM_RTC_ConfigSourceClock
87231 +
87232 + @Description Configures the source clock of the RTC.
87233 +
87234 + @Param[in] h_FmRtc - Handle to FM RTC object.
87235 + @Param[in] srcClk - Source clock selection.
87236 + @Param[in] freqInMhz - the source-clock frequency (in MHz).
87237 +
87238 + @Return E_OK on success; Error code otherwise.
87239 +
87240 + @Cautions h_FmRtc must have been previously created using FM_RTC_Config().
87241 +*//***************************************************************************/
87242 +t_Error FM_RTC_ConfigSourceClock(t_Handle h_FmRtc,
87243 + e_FmSrcClk srcClk,
87244 + uint32_t freqInMhz);
87245 +
87246 +/**************************************************************************//**
87247 + @Function FM_RTC_ConfigPulseRealignment
87248 +
87249 + @Description Configures the RTC to automatic FIPER pulse realignment in
87250 + response to timer adjustments [DEFAULT_pulseRealign]
87251 +
87252 + In this mode, the RTC clock is identical to the source clock.
87253 + This feature can be useful when the system contains an external
87254 + RTC with inherent frequency compensation.
87255 +
87256 + @Param[in] h_FmRtc - Handle to FM RTC object.
87257 + @Param[in] enable - TRUE to enable automatic realignment.
87258 +
87259 + @Return E_OK on success; Error code otherwise.
87260 +
87261 + @Cautions h_FmRtc must have been previously created using FM_RTC_Config().
87262 +*//***************************************************************************/
87263 +t_Error FM_RTC_ConfigPulseRealignment(t_Handle h_FmRtc, bool enable);
87264 +
87265 +/**************************************************************************//**
87266 + @Function FM_RTC_ConfigFrequencyBypass
87267 +
87268 + @Description Configures the RTC to bypass the frequency compensation
87269 + mechanism. [DEFAULT_bypass]
87270 +
87271 + In this mode, the RTC clock is identical to the source clock.
87272 + This feature can be useful when the system contains an external
87273 + RTC with inherent frequency compensation.
87274 +
87275 + @Param[in] h_FmRtc - Handle to FM RTC object.
87276 + @Param[in] enabled - TRUE to bypass frequency compensation;
87277 + FALSE otherwise.
87278 +
87279 + @Return E_OK on success; Error code otherwise.
87280 +
87281 + @Cautions h_FmRtc must have been previously created using FM_RTC_Config().
87282 +*//***************************************************************************/
87283 +t_Error FM_RTC_ConfigFrequencyBypass(t_Handle h_FmRtc, bool enabled);
87284 +
87285 +/**************************************************************************//**
87286 + @Function FM_RTC_ConfigInvertedInputClockPhase
87287 +
87288 + @Description Configures the RTC to invert the source clock phase on input.
87289 + [DEFAULT_invertInputClkPhase]
87290 +
87291 + @Param[in] h_FmRtc - Handle to FM RTC object.
87292 + @Param[in] inverted - TRUE to invert the source clock phase on input.
87293 + FALSE otherwise.
87294 +
87295 + @Return E_OK on success; Error code otherwise.
87296 +
87297 + @Cautions h_FmRtc must have been previously created using FM_RTC_Config().
87298 +*//***************************************************************************/
87299 +t_Error FM_RTC_ConfigInvertedInputClockPhase(t_Handle h_FmRtc, bool inverted);
87300 +
87301 +/**************************************************************************//**
87302 + @Function FM_RTC_ConfigInvertedOutputClockPhase
87303 +
87304 + @Description Configures the RTC to invert the output clock phase.
87305 + [DEFAULT_invertOutputClkPhase]
87306 +
87307 + @Param[in] h_FmRtc - Handle to FM RTC object.
87308 + @Param[in] inverted - TRUE to invert the output clock phase.
87309 + FALSE otherwise.
87310 +
87311 + @Return E_OK on success; Error code otherwise.
87312 +
87313 + @Cautions h_FmRtc must have been previously created using FM_RTC_Config().
87314 +*//***************************************************************************/
87315 +t_Error FM_RTC_ConfigInvertedOutputClockPhase(t_Handle h_FmRtc, bool inverted);
87316 +
87317 +/**************************************************************************//**
87318 + @Function FM_RTC_ConfigOutputClockDivisor
87319 +
87320 + @Description Configures the divisor for generating the output clock from
87321 + the RTC clock. [DEFAULT_outputClockDivisor]
87322 +
87323 + @Param[in] h_FmRtc - Handle to FM RTC object.
87324 + @Param[in] divisor - Divisor for generation of the output clock.
87325 +
87326 + @Return E_OK on success; Error code otherwise.
87327 +
87328 + @Cautions h_FmRtc must have been previously created using FM_RTC_Config().
87329 +*//***************************************************************************/
87330 +t_Error FM_RTC_ConfigOutputClockDivisor(t_Handle h_FmRtc, uint16_t divisor);
87331 +
87332 +/**************************************************************************//**
87333 + @Function FM_RTC_ConfigAlarmPolarity
87334 +
87335 + @Description Configures the polarity (active-high/active-low) of a specific
87336 + alarm signal. [DEFAULT_alarmPolarity]
87337 +
87338 + @Param[in] h_FmRtc - Handle to FM RTC object.
87339 + @Param[in] alarmId - Alarm ID.
87340 + @Param[in] alarmPolarity - Alarm polarity.
87341 +
87342 + @Return E_OK on success; Error code otherwise.
87343 +
87344 + @Cautions h_FmRtc must have been previously created using FM_RTC_Config().
87345 +*//***************************************************************************/
87346 +t_Error FM_RTC_ConfigAlarmPolarity(t_Handle h_FmRtc,
87347 + uint8_t alarmId,
87348 + e_FmRtcAlarmPolarity alarmPolarity);
87349 +
87350 +/**************************************************************************//**
87351 + @Function FM_RTC_ConfigExternalTriggerPolarity
87352 +
87353 + @Description Configures the polarity (rising/falling edge) of a specific
87354 + external trigger signal. [DEFAULT_triggerPolarity]
87355 +
87356 + @Param[in] h_FmRtc - Handle to FM RTC object.
87357 + @Param[in] triggerId - Trigger ID.
87358 + @Param[in] triggerPolarity - Trigger polarity.
87359 +
87360 + @Return E_OK on success; Error code otherwise.
87361 +
87362 + @Cautions h_FmRtc must have been previously created using FM_RTC_Config().
87363 +*//***************************************************************************/
87364 +t_Error FM_RTC_ConfigExternalTriggerPolarity(t_Handle h_FmRtc,
87365 + uint8_t triggerId,
87366 + e_FmRtcTriggerPolarity triggerPolarity);
87367 +
87368 +/** @} */ /* end of fm_rtc_adv_config_grp */
87369 +/** @} */ /* end of fm_rtc_init_grp */
87370 +
87371 +
87372 +/**************************************************************************//**
87373 + @Group fm_rtc_control_grp FM RTC Control Unit
87374 +
87375 + @Description FM RTC runtime control API.
87376 +
87377 + @{
87378 +*//***************************************************************************/
87379 +
87380 +/**************************************************************************//**
87381 + @Function t_FmRtcExceptionsCallback
87382 +
87383 + @Description Exceptions user callback routine, used for RTC different mechanisms.
87384 +
87385 + @Param[in] h_App - User's application descriptor.
87386 + @Param[in] id - source id.
87387 +*//***************************************************************************/
87388 +typedef void (t_FmRtcExceptionsCallback) ( t_Handle h_App, uint8_t id);
87389 +
87390 +/**************************************************************************//**
87391 + @Description FM RTC alarm parameters.
87392 +*//***************************************************************************/
87393 +typedef struct t_FmRtcAlarmParams {
87394 + uint8_t alarmId; /**< 0 or 1 */
87395 + uint64_t alarmTime; /**< In nanoseconds, the time when the alarm
87396 + should go off - must be a multiple of
87397 + the RTC period */
87398 + t_FmRtcExceptionsCallback *f_AlarmCallback; /**< This routine will be called when RTC
87399 + reaches alarmTime */
87400 + bool clearOnExpiration; /**< TRUE to turn off the alarm once expired. */
87401 +} t_FmRtcAlarmParams;
87402 +
87403 +/**************************************************************************//**
87404 + @Description FM RTC Periodic Pulse parameters.
87405 +*//***************************************************************************/
87406 +typedef struct t_FmRtcPeriodicPulseParams {
87407 + uint8_t periodicPulseId; /**< 0 or 1 */
87408 + uint64_t periodicPulsePeriod; /**< In Nanoseconds. Must be
87409 + a multiple of the RTC period */
87410 + t_FmRtcExceptionsCallback *f_PeriodicPulseCallback; /**< This routine will be called every
87411 + periodicPulsePeriod. */
87412 +} t_FmRtcPeriodicPulseParams;
87413 +
87414 +/**************************************************************************//**
87415 + @Description FM RTC Periodic Pulse parameters.
87416 +*//***************************************************************************/
87417 +typedef struct t_FmRtcExternalTriggerParams {
87418 + uint8_t externalTriggerId; /**< 0 or 1 */
87419 + bool usePulseAsInput; /**< Use the pulse interrupt instead of
87420 + an external signal */
87421 + t_FmRtcExceptionsCallback *f_ExternalTriggerCallback; /**< This routine will be called every
87422 + periodicPulsePeriod. */
87423 +} t_FmRtcExternalTriggerParams;
87424 +
87425 +
87426 +/**************************************************************************//**
87427 + @Function FM_RTC_Enable
87428 +
87429 + @Description Enable the RTC (time count is started).
87430 +
87431 + The user can select to resume the time count from previous
87432 + point, or to restart the time count.
87433 +
87434 + @Param[in] h_FmRtc - Handle to FM RTC object.
87435 + @Param[in] resetClock - Restart the time count from zero.
87436 +
87437 + @Return E_OK on success; Error code otherwise.
87438 +
87439 + @Cautions h_FmRtc must have been previously initialized using FM_RTC_Init().
87440 +*//***************************************************************************/
87441 +t_Error FM_RTC_Enable(t_Handle h_FmRtc, bool resetClock);
87442 +
87443 +/**************************************************************************//**
87444 + @Function FM_RTC_Disable
87445 +
87446 + @Description Disables the RTC (time count is stopped).
87447 +
87448 + @Param[in] h_FmRtc - Handle to FM RTC object.
87449 +
87450 + @Return E_OK on success; Error code otherwise.
87451 +
87452 + @Cautions h_FmRtc must have been previously initialized using FM_RTC_Init().
87453 +*//***************************************************************************/
87454 +t_Error FM_RTC_Disable(t_Handle h_FmRtc);
87455 +
87456 +/**************************************************************************//**
87457 + @Function FM_RTC_SetClockOffset
87458 +
87459 + @Description Sets the clock offset (usually relative to another clock).
87460 +
87461 + The user can pass a negative offset value.
87462 +
87463 + @Param[in] h_FmRtc - Handle to FM RTC object.
87464 + @Param[in] offset - New clock offset (in nanoseconds).
87465 +
87466 + @Return E_OK on success; Error code otherwise.
87467 +
87468 + @Cautions h_FmRtc must have been previously initialized using FM_RTC_Init().
87469 +*//***************************************************************************/
87470 +t_Error FM_RTC_SetClockOffset(t_Handle h_FmRtc, int64_t offset);
87471 +
87472 +/**************************************************************************//**
87473 + @Function FM_RTC_SetAlarm
87474 +
87475 + @Description Schedules an alarm event to a given RTC time.
87476 +
87477 + @Param[in] h_FmRtc - Handle to FM RTC object.
87478 + @Param[in] p_FmRtcAlarmParams - Alarm parameters.
87479 +
87480 + @Return E_OK on success; Error code otherwise.
87481 +
87482 + @Cautions h_FmRtc must have been previously initialized using FM_RTC_Init().
87483 + Must be called only prior to FM_RTC_Enable().
87484 +*//***************************************************************************/
87485 +t_Error FM_RTC_SetAlarm(t_Handle h_FmRtc, t_FmRtcAlarmParams *p_FmRtcAlarmParams);
87486 +
87487 +/**************************************************************************//**
87488 + @Function FM_RTC_SetPeriodicPulse
87489 +
87490 + @Description Sets a periodic pulse.
87491 +
87492 + @Param[in] h_FmRtc - Handle to FM RTC object.
87493 + @Param[in] p_FmRtcPeriodicPulseParams - Periodic pulse parameters.
87494 +
87495 + @Return E_OK on success; Error code otherwise.
87496 +
87497 + @Cautions h_FmRtc must have been previously initialized using FM_RTC_Init().
87498 + Must be called only prior to FM_RTC_Enable().
87499 +*//***************************************************************************/
87500 +t_Error FM_RTC_SetPeriodicPulse(t_Handle h_FmRtc, t_FmRtcPeriodicPulseParams *p_FmRtcPeriodicPulseParams);
87501 +
87502 +/**************************************************************************//**
87503 + @Function FM_RTC_ClearPeriodicPulse
87504 +
87505 + @Description Clears a periodic pulse.
87506 +
87507 + @Param[in] h_FmRtc - Handle to FM RTC object.
87508 + @Param[in] periodicPulseId - Periodic pulse id.
87509 +
87510 + @Return E_OK on success; Error code otherwise.
87511 +
87512 + @Cautions h_FmRtc must have been previously initialized using FM_RTC_Init().
87513 +*//***************************************************************************/
87514 +t_Error FM_RTC_ClearPeriodicPulse(t_Handle h_FmRtc, uint8_t periodicPulseId);
87515 +
87516 +/**************************************************************************//**
87517 + @Function FM_RTC_SetExternalTrigger
87518 +
87519 + @Description Sets an external trigger indication and define a callback
87520 + routine to be called on such event.
87521 +
87522 + @Param[in] h_FmRtc - Handle to FM RTC object.
87523 + @Param[in] p_FmRtcExternalTriggerParams - External Trigger parameters.
87524 +
87525 + @Return E_OK on success; Error code otherwise.
87526 +
87527 + @Cautions h_FmRtc must have been previously initialized using FM_RTC_Init().
87528 +*//***************************************************************************/
87529 +t_Error FM_RTC_SetExternalTrigger(t_Handle h_FmRtc, t_FmRtcExternalTriggerParams *p_FmRtcExternalTriggerParams);
87530 +
87531 +/**************************************************************************//**
87532 + @Function FM_RTC_ClearExternalTrigger
87533 +
87534 + @Description Clears external trigger indication.
87535 +
87536 + @Param[in] h_FmRtc - Handle to FM RTC object.
87537 + @Param[in] id - External Trigger id.
87538 +
87539 + @Return E_OK on success; Error code otherwise.
87540 +
87541 + @Cautions h_FmRtc must have been previously initialized using FM_RTC_Init().
87542 +*//***************************************************************************/
87543 +t_Error FM_RTC_ClearExternalTrigger(t_Handle h_FmRtc, uint8_t id);
87544 +
87545 +/**************************************************************************//**
87546 + @Function FM_RTC_GetExternalTriggerTimeStamp
87547 +
87548 + @Description Reads the External Trigger TimeStamp.
87549 +
87550 + @Param[in] h_FmRtc - Handle to FM RTC object.
87551 + @Param[in] triggerId - External Trigger id.
87552 + @Param[out] p_TimeStamp - External Trigger timestamp (in nanoseconds).
87553 +
87554 + @Return E_OK on success; Error code otherwise.
87555 +
87556 + @Cautions h_FmRtc must have been previously initialized using FM_RTC_Init().
87557 +*//***************************************************************************/
87558 +t_Error FM_RTC_GetExternalTriggerTimeStamp(t_Handle h_FmRtc,
87559 + uint8_t triggerId,
87560 + uint64_t *p_TimeStamp);
87561 +
87562 +/**************************************************************************//**
87563 + @Function FM_RTC_GetCurrentTime
87564 +
87565 + @Description Returns the current RTC time.
87566 +
87567 + @Param[in] h_FmRtc - Handle to FM RTC object.
87568 + @Param[out] p_Ts - returned time stamp (in nanoseconds).
87569 +
87570 + @Return E_OK on success; Error code otherwise.
87571 +
87572 + @Cautions h_FmRtc must have been previously initialized using FM_RTC_Init().
87573 +*//***************************************************************************/
87574 +t_Error FM_RTC_GetCurrentTime(t_Handle h_FmRtc, uint64_t *p_Ts);
87575 +
87576 +/**************************************************************************//**
87577 + @Function FM_RTC_SetCurrentTime
87578 +
87579 + @Description Sets the current RTC time.
87580 +
87581 + @Param[in] h_FmRtc - Handle to FM RTC object.
87582 + @Param[in] ts - The new time stamp (in nanoseconds).
87583 +
87584 + @Return E_OK on success; Error code otherwise.
87585 +
87586 + @Cautions h_FmRtc must have been previously initialized using FM_RTC_Init().
87587 +*//***************************************************************************/
87588 +t_Error FM_RTC_SetCurrentTime(t_Handle h_FmRtc, uint64_t ts);
87589 +
87590 +/**************************************************************************//**
87591 + @Function FM_RTC_GetFreqCompensation
87592 +
87593 + @Description Retrieves the frequency compensation value
87594 +
87595 + @Param[in] h_FmRtc - Handle to FM RTC object.
87596 + @Param[out] p_Compensation - A pointer to the returned value of compensation.
87597 +
87598 + @Return E_OK on success; Error code otherwise.
87599 +
87600 + @Cautions h_FmRtc must have been previously initialized using FM_RTC_Init().
87601 +*//***************************************************************************/
87602 +t_Error FM_RTC_GetFreqCompensation(t_Handle h_FmRtc, uint32_t *p_Compensation);
87603 +
87604 +/**************************************************************************//**
87605 + @Function FM_RTC_SetFreqCompensation
87606 +
87607 + @Description Sets a new frequency compensation value.
87608 +
87609 + @Param[in] h_FmRtc - Handle to FM RTC object.
87610 + @Param[in] freqCompensation - The new frequency compensation value to set.
87611 +
87612 + @Return E_OK on success; Error code otherwise.
87613 +
87614 + @Cautions h_FmRtc must have been previously initialized using FM_RTC_Init().
87615 +*//***************************************************************************/
87616 +t_Error FM_RTC_SetFreqCompensation(t_Handle h_FmRtc, uint32_t freqCompensation);
87617 +
87618 +#ifdef CONFIG_PTP_1588_CLOCK_DPAA
87619 +/**************************************************************************//**
87620 +*@Function FM_RTC_EnableInterrupt
87621 +*
87622 +*@Description Enable interrupt of FM RTC.
87623 +*
87624 +*@Param[in] h_FmRtc - Handle to FM RTC object.
87625 +*@Param[in] events - Interrupt events.
87626 +*
87627 +*@Return E_OK on success; Error code otherwise.
87628 +*//***************************************************************************/
87629 +t_Error FM_RTC_EnableInterrupt(t_Handle h_FmRtc, uint32_t events);
87630 +
87631 +/**************************************************************************//**
87632 +*@Function FM_RTC_DisableInterrupt
87633 +*
87634 +*@Description Disable interrupt of FM RTC.
87635 +*
87636 +*@Param[in] h_FmRtc - Handle to FM RTC object.
87637 +*@Param[in] events - Interrupt events.
87638 +*
87639 +*@Return E_OK on success; Error code otherwise.
87640 +*//***************************************************************************/
87641 +t_Error FM_RTC_DisableInterrupt(t_Handle h_FmRtc, uint32_t events);
87642 +#endif
87643 +
87644 +#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
87645 +/**************************************************************************//**
87646 + @Function FM_RTC_DumpRegs
87647 +
87648 + @Description Dumps all FM registers
87649 +
87650 + @Param[in] h_FmRtc A handle to an FM RTC Module.
87651 +
87652 + @Return E_OK on success;
87653 +
87654 + @Cautions Allowed only FM_Init().
87655 +*//***************************************************************************/
87656 +t_Error FM_RTC_DumpRegs(t_Handle h_FmRtc);
87657 +#endif /* (defined(DEBUG_ERRORS) && ... */
87658 +
87659 +/** @} */ /* end of fm_rtc_control_grp */
87660 +/** @} */ /* end of fm_rtc_grp */
87661 +/** @} */ /* end of FM_grp group */
87662 +
87663 +
87664 +#endif /* __FM_RTC_EXT_H__ */
87665 --- /dev/null
87666 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/Peripherals/fm_vsp_ext.h
87667 @@ -0,0 +1,411 @@
87668 +/*
87669 + * Copyright 2008-2012 Freescale Semiconductor Inc.
87670 + *
87671 + * Redistribution and use in source and binary forms, with or without
87672 + * modification, are permitted provided that the following conditions are met:
87673 + * * Redistributions of source code must retain the above copyright
87674 + * notice, this list of conditions and the following disclaimer.
87675 + * * Redistributions in binary form must reproduce the above copyright
87676 + * notice, this list of conditions and the following disclaimer in the
87677 + * documentation and/or other materials provided with the distribution.
87678 + * * Neither the name of Freescale Semiconductor nor the
87679 + * names of its contributors may be used to endorse or promote products
87680 + * derived from this software without specific prior written permission.
87681 + *
87682 + *
87683 + * ALTERNATIVELY, this software may be distributed under the terms of the
87684 + * GNU General Public License ("GPL") as published by the Free Software
87685 + * Foundation, either version 2 of that License or (at your option) any
87686 + * later version.
87687 + *
87688 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
87689 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
87690 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
87691 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
87692 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
87693 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
87694 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
87695 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
87696 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
87697 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
87698 + */
87699 +
87700 +
87701 +/**************************************************************************//**
87702 + @File fm_vsp_ext.h
87703 +
87704 + @Description FM Virtual Storage-Profile ...
87705 +*//***************************************************************************/
87706 +#ifndef __FM_VSP_EXT_H
87707 +#define __FM_VSP_EXT_H
87708 +
87709 +#include "std_ext.h"
87710 +#include "error_ext.h"
87711 +#include "string_ext.h"
87712 +#include "debug_ext.h"
87713 +
87714 +#include "fm_ext.h"
87715 +
87716 +
87717 +/**************************************************************************//**
87718 +
87719 + @Group FM_grp Frame Manager API
87720 +
87721 + @Description FM API functions, definitions and enums
87722 +
87723 + @{
87724 +*//***************************************************************************/
87725 +
87726 +/**************************************************************************//**
87727 + @Group FM_VSP_grp FM Virtual-Storage-Profile
87728 +
87729 + @Description FM Virtual-Storage-Profile API
87730 +
87731 + @{
87732 +*//***************************************************************************/
87733 +
87734 +/**************************************************************************//**
87735 + @Group FM_VSP_init_grp FM VSP Initialization Unit
87736 +
87737 + @Description FM VSP initialization API.
87738 +
87739 + @{
87740 +*//***************************************************************************/
87741 +
87742 +/**************************************************************************//**
87743 + @Description Virtual Storage Profile
87744 +*//***************************************************************************/
87745 +typedef struct t_FmVspParams {
87746 + t_Handle h_Fm; /**< A handle to the FM object this VSP related to */
87747 + t_FmExtPools extBufPools; /**< Which external buffer pools are used
87748 + (up to FM_PORT_MAX_NUM_OF_EXT_POOLS), and their sizes.
87749 + parameter associated with Rx / OP port */
87750 + uint16_t liodnOffset; /**< VSP's LIODN offset */
87751 + struct {
87752 + e_FmPortType portType; /**< Port type */
87753 + uint8_t portId; /**< Port Id - relative to type */
87754 + } portParams;
87755 + uint8_t relativeProfileId; /**< VSP Id - relative to VSP's range
87756 + defined in relevant FM object */
87757 +} t_FmVspParams;
87758 +
87759 +
87760 +/**************************************************************************//**
87761 + @Function FM_VSP_Config
87762 +
87763 + @Description Creates descriptor for the FM VSP module.
87764 +
87765 + The routine returns a handle (descriptor) to the FM VSP object.
87766 + This descriptor must be passed as first parameter to all other
87767 + FM VSP function calls.
87768 +
87769 + No actual initialization or configuration of FM hardware is
87770 + done by this routine.
87771 +
87772 +@Param[in] p_FmVspParams Pointer to data structure of parameters
87773 +
87774 + @Retval Handle to FM VSP object, or NULL for Failure.
87775 +*//***************************************************************************/
87776 +t_Handle FM_VSP_Config(t_FmVspParams *p_FmVspParams);
87777 +
87778 +/**************************************************************************//**
87779 + @Function FM_VSP_Init
87780 +
87781 + @Description Initializes the FM VSP module
87782 +
87783 + @Param[in] h_FmVsp - FM VSP module descriptor
87784 +
87785 + @Return E_OK on success; Error code otherwise.
87786 +*//***************************************************************************/
87787 +t_Error FM_VSP_Init(t_Handle h_FmVsp);
87788 +
87789 +/**************************************************************************//**
87790 + @Function FM_VSP_Free
87791 +
87792 + @Description Frees all resources that were assigned to FM VSP module.
87793 +
87794 + Calling this routine invalidates the descriptor.
87795 +
87796 + @Param[in] h_FmVsp - FM VSP module descriptor
87797 +
87798 + @Return E_OK on success; Error code otherwise.
87799 +*//***************************************************************************/
87800 +t_Error FM_VSP_Free(t_Handle h_FmVsp);
87801 +
87802 +
87803 +/**************************************************************************//**
87804 + @Group FM_VSP_adv_config_grp FM VSP Advanced Configuration Unit
87805 +
87806 + @Description FM VSP advanced configuration functions.
87807 +
87808 + @{
87809 +*//***************************************************************************/
87810 +
87811 +/**************************************************************************//**
87812 + @Function FM_VSP_ConfigBufferPrefixContent
87813 +
87814 + @Description Defines the structure, size and content of the application buffer.
87815 +
87816 + The prefix will
87817 + In VSPs defined for Tx ports, if 'passPrsResult', the application
87818 + should set a value to their offsets in the prefix of
87819 + the FM will save the first 'privDataSize', than,
87820 + depending on 'passPrsResult' and 'passTimeStamp', copy parse result
87821 + and timeStamp, and the packet itself (in this order), to the
87822 + application buffer, and to offset.
87823 +
87824 + Calling this routine changes the buffer margins definitions
87825 + in the internal driver data base from its default
87826 + configuration: Data size: [DEFAULT_FM_SP_bufferPrefixContent_privDataSize]
87827 + Pass Parser result: [DEFAULT_FM_SP_bufferPrefixContent_passPrsResult].
87828 + Pass timestamp: [DEFAULT_FM_SP_bufferPrefixContent_passTimeStamp].
87829 +
87830 + @Param[in] h_FmVsp A handle to a FM VSP module.
87831 + @Param[in,out] p_FmBufferPrefixContent A structure of parameters describing the
87832 + structure of the buffer.
87833 + Out parameter: Start margin - offset
87834 + of data from start of external buffer.
87835 +
87836 + @Return E_OK on success; Error code otherwise.
87837 +
87838 + @Cautions Allowed only following FM_VSP_Config() and before FM_VSP_Init().
87839 +*//***************************************************************************/
87840 +t_Error FM_VSP_ConfigBufferPrefixContent(t_Handle h_FmVsp,
87841 + t_FmBufferPrefixContent *p_FmBufferPrefixContent);
87842 +
87843 +/**************************************************************************//**
87844 + @Function FM_VSP_ConfigDmaSwapData
87845 +
87846 + @Description Calling this routine changes the DMA swap data parameter
87847 + in the internal driver data base from its default
87848 + configuration [DEFAULT_FM_SP_dmaSwapData]
87849 +
87850 + @Param[in] h_FmVsp A handle to a FM VSP module.
87851 + @Param[in] swapData New selection
87852 +
87853 + @Return E_OK on success; Error code otherwise.
87854 +
87855 + @Cautions Allowed only following FM_VSP_Config() and before FM_VSP_Init().
87856 +*//***************************************************************************/
87857 +t_Error FM_VSP_ConfigDmaSwapData(t_Handle h_FmVsp, e_FmDmaSwapOption swapData);
87858 +
87859 +/**************************************************************************//**
87860 + @Function FM_VSP_ConfigDmaIcCacheAttr
87861 +
87862 + @Description Calling this routine changes the internal context cache
87863 + attribute parameter in the internal driver data base
87864 + from its default configuration [DEFAULT_FM_SP_dmaIntContextCacheAttr]
87865 +
87866 + @Param[in] h_FmVsp A handle to a FM VSP module.
87867 + @Param[in] intContextCacheAttr New selection
87868 +
87869 + @Return E_OK on success; Error code otherwise.
87870 +
87871 + @Cautions Allowed only following FM_VSP_Config() and before FM_VSP_Init().
87872 +*//***************************************************************************/
87873 +t_Error FM_VSP_ConfigDmaIcCacheAttr(t_Handle h_FmVsp,
87874 + e_FmDmaCacheOption intContextCacheAttr);
87875 +
87876 +/**************************************************************************//**
87877 + @Function FM_VSP_ConfigDmaHdrAttr
87878 +
87879 + @Description Calling this routine changes the header cache
87880 + attribute parameter in the internal driver data base
87881 + from its default configuration [DEFAULT_FM_SP_dmaHeaderCacheAttr]
87882 +
87883 + @Param[in] h_FmVsp A handle to a FM VSP module.
87884 + @Param[in] headerCacheAttr New selection
87885 +
87886 + @Return E_OK on success; Error code otherwise.
87887 +
87888 + @Cautions Allowed only following FM_VSP_Config() and before FM_VSP_Init().
87889 +*//***************************************************************************/
87890 +t_Error FM_VSP_ConfigDmaHdrAttr(t_Handle h_FmVsp, e_FmDmaCacheOption headerCacheAttr);
87891 +
87892 +/**************************************************************************//**
87893 + @Function FM_VSP_ConfigDmaScatterGatherAttr
87894 +
87895 + @Description Calling this routine changes the scatter gather cache
87896 + attribute parameter in the internal driver data base
87897 + from its default configuration [DEFAULT_FM_SP_dmaScatterGatherCacheAttr]
87898 +
87899 + @Param[in] h_FmVsp A handle to a FM VSP module.
87900 + @Param[in] scatterGatherCacheAttr New selection
87901 +
87902 + @Return E_OK on success; Error code otherwise.
87903 +
87904 + @Cautions Allowed only following FM_VSP_Config() and before FM_VSP_Init().
87905 +*//***************************************************************************/
87906 +t_Error FM_VSP_ConfigDmaScatterGatherAttr(t_Handle h_FmVsp,
87907 + e_FmDmaCacheOption scatterGatherCacheAttr);
87908 +
87909 +/**************************************************************************//**
87910 + @Function FM_VSP_ConfigDmaWriteOptimize
87911 +
87912 + @Description Calling this routine changes the write optimization
87913 + parameter in the internal driver data base
87914 + from its default configuration: optimize = [DEFAULT_FM_SP_dmaWriteOptimize]
87915 +
87916 + @Param[in] h_FmVsp A handle to a FM VSP module.
87917 + @Param[in] optimize TRUE to enable optimization, FALSE for normal operation
87918 +
87919 + @Return E_OK on success; Error code otherwise.
87920 +
87921 + @Cautions Allowed only following FM_VSP_Config() and before FM_VSP_Init().
87922 +*//***************************************************************************/
87923 +t_Error FM_VSP_ConfigDmaWriteOptimize(t_Handle h_FmVsp, bool optimize);
87924 +
87925 +/**************************************************************************//**
87926 + @Function FM_VSP_ConfigNoScatherGather
87927 +
87928 + @Description Calling this routine changes the possibility to receive S/G frame
87929 + in the internal driver data base
87930 + from its default configuration: optimize = [DEFAULT_FM_SP_noScatherGather]
87931 +
87932 + @Param[in] h_FmVsp A handle to a FM VSP module.
87933 + @Param[in] noScatherGather TRUE to operate without scatter/gather capability.
87934 +
87935 + @Return E_OK on success; Error code otherwise.
87936 +
87937 + @Cautions Allowed only following FM_VSP_Config() and before FM_VSP_Init().
87938 +*//***************************************************************************/
87939 +t_Error FM_VSP_ConfigNoScatherGather(t_Handle h_FmVsp, bool noScatherGather);
87940 +
87941 +/**************************************************************************//**
87942 + @Function FM_VSP_ConfigPoolDepletion
87943 +
87944 + @Description Calling this routine enables pause frame generation depending on the
87945 + depletion status of BM pools. It also defines the conditions to activate
87946 + this functionality. By default, this functionality is disabled.
87947 +
87948 + @Param[in] h_FmVsp A handle to a FM VSP module.
87949 + @Param[in] p_BufPoolDepletion A structure of pool depletion parameters
87950 +
87951 + @Return E_OK on success; Error code otherwise.
87952 +
87953 + @Cautions Allowed only following FM_VSP_Config() and before FM_VSP_Init().
87954 +*//***************************************************************************/
87955 +t_Error FM_VSP_ConfigPoolDepletion(t_Handle h_FmVsp, t_FmBufPoolDepletion *p_BufPoolDepletion);
87956 +
87957 +/**************************************************************************//**
87958 + @Function FM_VSP_ConfigBackupPools
87959 +
87960 + @Description Calling this routine allows the configuration of some of the BM pools
87961 + defined for this port as backup pools.
87962 + A pool configured to be a backup pool will be used only if all other
87963 + enabled non-backup pools are depleted.
87964 +
87965 + @Param[in] h_FmVsp A handle to a FM VSP module.
87966 + @Param[in] p_BackupBmPools An array of pool id's. All pools specified here will
87967 + be defined as backup pools.
87968 +
87969 + @Return E_OK on success; Error code otherwise.
87970 +
87971 + @Cautions Allowed only following FM_VSP_Config() and before FM_VSP_Init().
87972 +*//***************************************************************************/
87973 +t_Error FM_VSP_ConfigBackupPools(t_Handle h_FmVsp, t_FmBackupBmPools *p_BackupBmPools);
87974 +
87975 +/** @} */ /* end of FM_VSP_adv_config_grp group */
87976 +/** @} */ /* end of FM_VSP_init_grp group */
87977 +
87978 +
87979 +/**************************************************************************//**
87980 + @Group FM_VSP_control_grp FM VSP Control Unit
87981 +
87982 + @Description FM VSP runtime control API.
87983 +
87984 + @{
87985 +*//***************************************************************************/
87986 +
87987 +/**************************************************************************//**
87988 + @Function FM_VSP_GetBufferDataOffset
87989 +
87990 + @Description Relevant for Rx ports.
87991 + Returns the data offset from the beginning of the data buffer
87992 +
87993 + @Param[in] h_FmVsp - FM PORT module descriptor
87994 +
87995 + @Return data offset.
87996 +
87997 + @Cautions Allowed only following FM_VSP_Init().
87998 +*//***************************************************************************/
87999 +uint32_t FM_VSP_GetBufferDataOffset(t_Handle h_FmVsp);
88000 +
88001 +/**************************************************************************//**
88002 + @Function FM_VSP_GetBufferICInfo
88003 +
88004 + @Description Returns the Internal Context offset from the beginning of the data buffer
88005 +
88006 + @Param[in] h_FmVsp - FM PORT module descriptor
88007 + @Param[in] p_Data - A pointer to the data buffer.
88008 +
88009 + @Return Internal context info pointer on success, NULL if 'allOtherInfo' was not
88010 + configured for this port.
88011 +
88012 + @Cautions Allowed only following FM_VSP_Init().
88013 +*//***************************************************************************/
88014 +uint8_t * FM_VSP_GetBufferICInfo(t_Handle h_FmVsp, char *p_Data);
88015 +
88016 +/**************************************************************************//**
88017 + @Function FM_VSP_GetBufferPrsResult
88018 +
88019 + @Description Returns the pointer to the parse result in the data buffer.
88020 + In Rx ports this is relevant after reception, if parse
88021 + result is configured to be part of the data passed to the
88022 + application. For non Rx ports it may be used to get the pointer
88023 + of the area in the buffer where parse result should be
88024 + initialized - if so configured.
88025 + See FM_VSP_ConfigBufferPrefixContent for data buffer prefix
88026 + configuration.
88027 +
88028 + @Param[in] h_FmVsp - FM PORT module descriptor
88029 + @Param[in] p_Data - A pointer to the data buffer.
88030 +
88031 + @Return Parse result pointer on success, NULL if parse result was not
88032 + configured for this port.
88033 +
88034 + @Cautions Allowed only following FM_VSP_Init().
88035 +*//***************************************************************************/
88036 +t_FmPrsResult * FM_VSP_GetBufferPrsResult(t_Handle h_FmVsp, char *p_Data);
88037 +
88038 +/**************************************************************************//**
88039 + @Function FM_VSP_GetBufferTimeStamp
88040 +
88041 + @Description Returns the time stamp in the data buffer.
88042 + Relevant for Rx ports for getting the buffer time stamp.
88043 + See FM_VSP_ConfigBufferPrefixContent for data buffer prefix
88044 + configuration.
88045 +
88046 + @Param[in] h_FmVsp - FM PORT module descriptor
88047 + @Param[in] p_Data - A pointer to the data buffer.
88048 +
88049 + @Return A pointer to the hash result on success, NULL otherwise.
88050 +
88051 + @Cautions Allowed only following FM_VSP_Init().
88052 +*//***************************************************************************/
88053 +uint64_t * FM_VSP_GetBufferTimeStamp(t_Handle h_FmVsp, char *p_Data);
88054 +
88055 +/**************************************************************************//**
88056 + @Function FM_VSP_GetBufferHashResult
88057 +
88058 + @Description Given a data buffer, on the condition that hash result was defined
88059 + as a part of the buffer content (see FM_VSP_ConfigBufferPrefixContent)
88060 + this routine will return the pointer to the hash result location in the
88061 + buffer prefix.
88062 +
88063 + @Param[in] h_FmVsp - FM PORT module descriptor
88064 + @Param[in] p_Data - A pointer to the data buffer.
88065 +
88066 + @Return A pointer to the hash result on success, NULL otherwise.
88067 +
88068 + @Cautions Allowed only following FM_VSP_Init().
88069 +*//***************************************************************************/
88070 +uint8_t * FM_VSP_GetBufferHashResult(t_Handle h_FmVsp, char *p_Data);
88071 +
88072 +
88073 +/** @} */ /* end of FM_VSP_control_grp group */
88074 +/** @} */ /* end of FM_VSP_grp group */
88075 +/** @} */ /* end of FM_grp group */
88076 +
88077 +
88078 +#endif /* __FM_VSP_EXT_H */
88079 --- /dev/null
88080 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/Peripherals/mii_acc_ext.h
88081 @@ -0,0 +1,76 @@
88082 +/*
88083 + * Copyright 2008-2012 Freescale Semiconductor Inc.
88084 + *
88085 + * Redistribution and use in source and binary forms, with or without
88086 + * modification, are permitted provided that the following conditions are met:
88087 + * * Redistributions of source code must retain the above copyright
88088 + * notice, this list of conditions and the following disclaimer.
88089 + * * Redistributions in binary form must reproduce the above copyright
88090 + * notice, this list of conditions and the following disclaimer in the
88091 + * documentation and/or other materials provided with the distribution.
88092 + * * Neither the name of Freescale Semiconductor nor the
88093 + * names of its contributors may be used to endorse or promote products
88094 + * derived from this software without specific prior written permission.
88095 + *
88096 + *
88097 + * ALTERNATIVELY, this software may be distributed under the terms of the
88098 + * GNU General Public License ("GPL") as published by the Free Software
88099 + * Foundation, either version 2 of that License or (at your option) any
88100 + * later version.
88101 + *
88102 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
88103 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
88104 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
88105 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
88106 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
88107 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
88108 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
88109 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
88110 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
88111 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
88112 + */
88113 +
88114 +
88115 +
88116 +#ifndef __MII_ACC_EXT_H
88117 +#define __MII_ACC_EXT_H
88118 +
88119 +
88120 +/**************************************************************************//**
88121 + @Function MII_ReadPhyReg
88122 +
88123 + @Description This routine is called to read a specified PHY
88124 + register value.
88125 +
88126 + @Param[in] h_MiiAccess - Handle to MII configuration access registers
88127 + @Param[in] phyAddr - PHY address (0-31).
88128 + @Param[in] reg - PHY register to read
88129 + @Param[out] p_Data - Gets the register value.
88130 +
88131 + @Return Always zero (success).
88132 +*//***************************************************************************/
88133 +int MII_ReadPhyReg(t_Handle h_MiiAccess,
88134 + uint8_t phyAddr,
88135 + uint8_t reg,
88136 + uint16_t *p_Data);
88137 +
88138 +/**************************************************************************//**
88139 + @Function MII_WritePhyReg
88140 +
88141 + @Description This routine is called to write data to a specified PHY
88142 + register.
88143 +
88144 + @Param[in] h_MiiAccess - Handle to MII configuration access registers
88145 + @Param[in] phyAddr - PHY address (0-31).
88146 + @Param[in] reg - PHY register to write
88147 + @Param[in] data - Data to write in register.
88148 +
88149 + @Return Always zero (success).
88150 +*//***************************************************************************/
88151 +int MII_WritePhyReg(t_Handle h_MiiAccess,
88152 + uint8_t phyAddr,
88153 + uint8_t reg,
88154 + uint16_t data);
88155 +
88156 +
88157 +#endif /* __MII_ACC_EXT_H */
88158 --- /dev/null
88159 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/core_ext.h
88160 @@ -0,0 +1,90 @@
88161 +/*
88162 + * Copyright 2008-2012 Freescale Semiconductor Inc.
88163 + *
88164 + * Redistribution and use in source and binary forms, with or without
88165 + * modification, are permitted provided that the following conditions are met:
88166 + * * Redistributions of source code must retain the above copyright
88167 + * notice, this list of conditions and the following disclaimer.
88168 + * * Redistributions in binary form must reproduce the above copyright
88169 + * notice, this list of conditions and the following disclaimer in the
88170 + * documentation and/or other materials provided with the distribution.
88171 + * * Neither the name of Freescale Semiconductor nor the
88172 + * names of its contributors may be used to endorse or promote products
88173 + * derived from this software without specific prior written permission.
88174 + *
88175 + *
88176 + * ALTERNATIVELY, this software may be distributed under the terms of the
88177 + * GNU General Public License ("GPL") as published by the Free Software
88178 + * Foundation, either version 2 of that License or (at your option) any
88179 + * later version.
88180 + *
88181 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
88182 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
88183 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
88184 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
88185 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
88186 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
88187 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
88188 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
88189 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
88190 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
88191 + */
88192 +
88193 +
88194 +/**************************************************************************//**
88195 + @File core_ext.h
88196 +
88197 + @Description Generic interface to basic core operations.
88198 +
88199 + The system integrator must ensure that this interface is
88200 + mapped to a specific core implementation, by including the
88201 + appropriate header file.
88202 +*//***************************************************************************/
88203 +#ifndef __CORE_EXT_H
88204 +#define __CORE_EXT_H
88205 +
88206 +#ifdef CONFIG_FMAN_ARM
88207 +#include "arm_ext.h"
88208 +#include <linux/smp.h>
88209 +#else
88210 +#ifdef NCSW_PPC_CORE
88211 +#include "ppc_ext.h"
88212 +#elif defined(NCSW_VXWORKS)
88213 +#include "core_vxw_ext.h"
88214 +#else
88215 +#error "Core is not defined!"
88216 +#endif /* NCSW_CORE */
88217 +
88218 +#if (!defined(CORE_IS_LITTLE_ENDIAN) && !defined(CORE_IS_BIG_ENDIAN))
88219 +#error "Must define core as little-endian or big-endian!"
88220 +#endif /* (!defined(CORE_IS_LITTLE_ENDIAN) && ... */
88221 +
88222 +#ifndef CORE_CACHELINE_SIZE
88223 +#error "Must define the core cache-line size!"
88224 +#endif /* !CORE_CACHELINE_SIZE */
88225 +
88226 +#endif /* CONFIG_FMAN_ARM */
88227 +
88228 +
88229 +/**************************************************************************//**
88230 + @Function CORE_GetId
88231 +
88232 + @Description Returns the core ID in the system.
88233 +
88234 + @Return Core ID.
88235 +*//***************************************************************************/
88236 +uint32_t CORE_GetId(void);
88237 +
88238 +/**************************************************************************//**
88239 + @Function CORE_MemoryBarrier
88240 +
88241 + @Description This routine will cause the core to stop executing any commands
88242 + until all previous memory read/write commands are completely out
88243 + of the core's pipeline.
88244 +
88245 + @Return None.
88246 +*//***************************************************************************/
88247 +void CORE_MemoryBarrier(void);
88248 +#define fsl_mem_core_barrier() CORE_MemoryBarrier()
88249 +
88250 +#endif /* __CORE_EXT_H */
88251 --- /dev/null
88252 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/cores/arm_ext.h
88253 @@ -0,0 +1,55 @@
88254 +/*
88255 + * Copyright 2008-2012 Freescale Semiconductor Inc.
88256 + *
88257 + * Redistribution and use in source and binary forms, with or without
88258 + * modification, are permitted provided that the following conditions are met:
88259 + * * Redistributions of source code must retain the above copyright
88260 + * notice, this list of conditions and the following disclaimer.
88261 + * * Redistributions in binary form must reproduce the above copyright
88262 + * notice, this list of conditions and the following disclaimer in the
88263 + * documentation and/or other materials provided with the distribution.
88264 + * * Neither the name of Freescale Semiconductor nor the
88265 + * names of its contributors may be used to endorse or promote products
88266 + * derived from this software without specific prior written permission.
88267 + *
88268 + *
88269 + * ALTERNATIVELY, this software may be distributed under the terms of the
88270 + * GNU General Public License ("GPL") as published by the Free Software
88271 + * Foundation, either version 2 of that License or (at your option) any
88272 + * later version.
88273 + *
88274 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
88275 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
88276 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
88277 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
88278 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
88279 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
88280 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
88281 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
88282 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
88283 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
88284 + */
88285 +
88286 +
88287 +/**************************************************************************//**
88288 + @File arm_ext.h
88289 +
88290 + @Description Core API for ARM cores
88291 +
88292 + These routines must be implemented by each specific PowerPC
88293 + core driver.
88294 +*//***************************************************************************/
88295 +#ifndef __ARM_EXT_H
88296 +#define __ARM_EXT_H
88297 +
88298 +#include "part_ext.h"
88299 +
88300 +
88301 +#define CORE_IS_LITTLE_ENDIAN
88302 +
88303 +static __inline__ void CORE_MemoryBarrier(void)
88304 +{
88305 + mb();
88306 +}
88307 +
88308 +#endif /* __PPC_EXT_H */
88309 --- /dev/null
88310 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/cores/e500v2_ext.h
88311 @@ -0,0 +1,476 @@
88312 +/*
88313 + * Copyright 2008-2012 Freescale Semiconductor Inc.
88314 + *
88315 + * Redistribution and use in source and binary forms, with or without
88316 + * modification, are permitted provided that the following conditions are met:
88317 + * * Redistributions of source code must retain the above copyright
88318 + * notice, this list of conditions and the following disclaimer.
88319 + * * Redistributions in binary form must reproduce the above copyright
88320 + * notice, this list of conditions and the following disclaimer in the
88321 + * documentation and/or other materials provided with the distribution.
88322 + * * Neither the name of Freescale Semiconductor nor the
88323 + * names of its contributors may be used to endorse or promote products
88324 + * derived from this software without specific prior written permission.
88325 + *
88326 + *
88327 + * ALTERNATIVELY, this software may be distributed under the terms of the
88328 + * GNU General Public License ("GPL") as published by the Free Software
88329 + * Foundation, either version 2 of that License or (at your option) any
88330 + * later version.
88331 + *
88332 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
88333 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
88334 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
88335 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
88336 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
88337 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
88338 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
88339 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
88340 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
88341 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
88342 + */
88343 +
88344 +
88345 +/**************************************************************************//**
88346 + @File e500v2_ext.h
88347 +
88348 + @Description E500 external definitions prototypes
88349 + This file is not included by the E500
88350 + source file as it is an assembly file. It is used
88351 + only for prototypes exposure, for inclusion
88352 + by user and other modules.
88353 +*//***************************************************************************/
88354 +
88355 +#ifndef __E500V2_EXT_H
88356 +#define __E500V2_EXT_H
88357 +
88358 +#include "std_ext.h"
88359 +
88360 +
88361 +/* Layer 1 Cache Manipulations
88362 + *==============================
88363 + * Should not be called directly by the user.
88364 + */
88365 +void L1DCache_Invalidate (void);
88366 +void L1ICache_Invalidate(void);
88367 +void L1DCache_Enable(void);
88368 +void L1ICache_Enable(void);
88369 +void L1DCache_Disable(void);
88370 +void L1ICache_Disable(void);
88371 +void L1DCache_Flush(void);
88372 +void L1ICache_Flush(void);
88373 +uint32_t L1ICache_IsEnabled(void);
88374 +uint32_t L1DCache_IsEnabled(void);
88375 +/*
88376 + *
88377 + */
88378 +uint32_t L1DCache_LineLock(uint32_t addr);
88379 +uint32_t L1ICache_LineLock(uint32_t addr);
88380 +void L1Cache_BroadCastEnable(void);
88381 +void L1Cache_BroadCastDisable(void);
88382 +
88383 +
88384 +#define CORE_DCacheEnable E500_DCacheEnable
88385 +#define CORE_ICacheEnable E500_ICacheEnable
88386 +#define CORE_DCacheDisable E500_DCacheDisable
88387 +#define CORE_ICacheDisable E500_ICacheDisable
88388 +#define CORE_GetId E500_GetId
88389 +#define CORE_TestAndSet E500_TestAndSet
88390 +#define CORE_MemoryBarrier E500_MemoryBarrier
88391 +#define CORE_InstructionSync E500_InstructionSync
88392 +
88393 +#define CORE_SetDozeMode E500_SetDozeMode
88394 +#define CORE_SetNapMode E500_SetNapMode
88395 +#define CORE_SetSleepMode E500_SetSleepMode
88396 +#define CORE_SetJogMode E500_SetJogMode
88397 +#define CORE_SetDeepSleepMode E500_SetDeepSleepMode
88398 +
88399 +#define CORE_RecoverDozeMode E500_RecoverDozeMode
88400 +#define CORE_RecoverNapMode E500_RecoverNapMode
88401 +#define CORE_RecoverSleepMode E500_RecoverSleepMode
88402 +#define CORE_RecoverJogMode E500_RecoverJogMode
88403 +
88404 +void E500_SetDozeMode(void);
88405 +void E500_SetNapMode(void);
88406 +void E500_SetSleepMode(void);
88407 +void E500_SetJogMode(void);
88408 +t_Error E500_SetDeepSleepMode(uint32_t bptrAddress);
88409 +
88410 +void E500_RecoverDozeMode(void);
88411 +void E500_RecoverNapMode(void);
88412 +void E500_RecoverSleepMode(void);
88413 +void E500_RecoverJogMode(void);
88414 +
88415 +
88416 +/**************************************************************************//**
88417 + @Group E500_id E500 Application Programming Interface
88418 +
88419 + @Description E500 API functions, definitions and enums
88420 +
88421 + @{
88422 +*//***************************************************************************/
88423 +
88424 +/**************************************************************************//**
88425 + @Group E500_init_grp E500 Initialization Unit
88426 +
88427 + @Description E500 initialization unit API functions, definitions and enums
88428 +
88429 + @{
88430 +*//***************************************************************************/
88431 +
88432 +
88433 +/**************************************************************************//**
88434 + @Function E500_DCacheEnable
88435 +
88436 + @Description Enables the data cache for memory pages that are
88437 + not cache inhibited.
88438 +
88439 + @Return None.
88440 +*//***************************************************************************/
88441 +void E500_DCacheEnable(void);
88442 +
88443 +/**************************************************************************//**
88444 + @Function E500_ICacheEnable
88445 +
88446 + @Description Enables the instruction cache for memory pages that are
88447 + not cache inhibited.
88448 +
88449 + @Return None.
88450 +*//***************************************************************************/
88451 +void E500_ICacheEnable(void);
88452 +
88453 +/**************************************************************************//**
88454 + @Function E500_DCacheDisable
88455 +
88456 + @Description Disables the data cache.
88457 +
88458 + @Return None.
88459 +*//***************************************************************************/
88460 +void E500_DCacheDisable(void);
88461 +
88462 +/**************************************************************************//**
88463 + @Function E500_ICacheDisable
88464 +
88465 + @Description Disables the instruction cache.
88466 +
88467 + @Return None.
88468 +*//***************************************************************************/
88469 +void E500_ICacheDisable(void);
88470 +
88471 +/**************************************************************************//**
88472 + @Function E500_DCacheFlush
88473 +
88474 + @Description Flushes the data cache
88475 +
88476 + @Return None.
88477 +*//***************************************************************************/
88478 +void E500_DCacheFlush(void);
88479 +
88480 +/**************************************************************************//**
88481 + @Function E500_ICacheFlush
88482 +
88483 + @Description Flushes the instruction cache.
88484 +
88485 + @Return None.
88486 +*//***************************************************************************/
88487 +void E500_ICacheFlush(void);
88488 +
88489 +/**************************************************************************//**
88490 + @Function E500_DCacheSetStashId
88491 +
88492 + @Description Set Stash Id for data cache
88493 +
88494 + @Param[in] stashId the stash id to be set.
88495 +
88496 + @Return None.
88497 +*//***************************************************************************/
88498 +void E500_DCacheSetStashId(uint8_t stashId);
88499 +
88500 +/**************************************************************************//**
88501 + @Description E500mc L2 Cache Operation Mode
88502 +*//***************************************************************************/
88503 +typedef enum e_E500mcL2CacheMode
88504 +{
88505 + e_L2_CACHE_MODE_DATA_ONLY = 0x00000001, /**< Cache data only */
88506 + e_L2_CACHE_MODE_INST_ONLY = 0x00000002, /**< Cache instructions only */
88507 + e_L2_CACHE_MODE_DATA_AND_INST = 0x00000003 /**< Cache data and instructions */
88508 +} e_E500mcL2CacheMode;
88509 +
88510 +#if defined(CORE_E500MC) || defined(CORE_E5500)
88511 +/**************************************************************************//**
88512 + @Function E500_L2CacheEnable
88513 +
88514 + @Description Enables the cache for memory pages that are not cache inhibited.
88515 +
88516 + @param[in] mode - L2 cache mode: data only, instruction only or instruction and data.
88517 +
88518 + @Return None.
88519 +
88520 + @Cautions This routine must be call only ONCE for both caches. I.e. it is
88521 + not possible to call this routine for i-cache and than to call
88522 + again for d-cache; The second call will override the first one.
88523 +*//***************************************************************************/
88524 +void E500_L2CacheEnable(e_E500mcL2CacheMode mode);
88525 +
88526 +/**************************************************************************//**
88527 + @Function E500_L2CacheDisable
88528 +
88529 + @Description Disables the cache (data instruction or both).
88530 +
88531 + @Return None.
88532 +
88533 +*//***************************************************************************/
88534 +void E500_L2CacheDisable(void);
88535 +
88536 +/**************************************************************************//**
88537 + @Function E500_L2CacheFlush
88538 +
88539 + @Description Flushes the cache.
88540 +
88541 + @Return None.
88542 +*//***************************************************************************/
88543 +void E500_L2CacheFlush(void);
88544 +
88545 +/**************************************************************************//**
88546 + @Function E500_L2SetStashId
88547 +
88548 + @Description Set Stash Id
88549 +
88550 + @Param[in] stashId the stash id to be set.
88551 +
88552 + @Return None.
88553 +*//***************************************************************************/
88554 +void E500_L2SetStashId(uint8_t stashId);
88555 +#endif /* defined(CORE_E500MC) || defined(CORE_E5500) */
88556 +
88557 +#ifdef CORE_E6500
88558 +/**************************************************************************//**
88559 + @Function E6500_L2CacheEnable
88560 +
88561 + @Description Enables the cache for memory pages that are not cache inhibited.
88562 +
88563 + @param[in] mode - L2 cache mode: support data & instruction only.
88564 +
88565 + @Return None.
88566 +
88567 + @Cautions This routine must be call only ONCE for both caches. I.e. it is
88568 + not possible to call this routine for i-cache and than to call
88569 + again for d-cache; The second call will override the first one.
88570 +*//***************************************************************************/
88571 +void E6500_L2CacheEnable(uintptr_t clusterBase);
88572 +
88573 +/**************************************************************************//**
88574 + @Function E6500_L2CacheDisable
88575 +
88576 + @Description Disables the cache (data instruction or both).
88577 +
88578 + @Return None.
88579 +
88580 +*//***************************************************************************/
88581 +void E6500_L2CacheDisable(uintptr_t clusterBase);
88582 +
88583 +/**************************************************************************//**
88584 + @Function E6500_L2CacheFlush
88585 +
88586 + @Description Flushes the cache.
88587 +
88588 + @Return None.
88589 +*//***************************************************************************/
88590 +void E6500_L2CacheFlush(uintptr_t clusterBase);
88591 +
88592 +/**************************************************************************//**
88593 + @Function E6500_L2SetStashId
88594 +
88595 + @Description Set Stash Id
88596 +
88597 + @Param[in] stashId the stash id to be set.
88598 +
88599 + @Return None.
88600 +*//***************************************************************************/
88601 +void E6500_L2SetStashId(uintptr_t clusterBase, uint8_t stashId);
88602 +
88603 +/**************************************************************************//**
88604 + @Function E6500_GetCcsrBase
88605 +
88606 + @Description Obtain SoC CCSR base address
88607 +
88608 + @Param[in] None.
88609 +
88610 + @Return Physical CCSR base address.
88611 +*//***************************************************************************/
88612 +physAddress_t E6500_GetCcsrBase(void);
88613 +#endif /* CORE_E6500 */
88614 +
88615 +/**************************************************************************//**
88616 + @Function E500_AddressBusStreamingEnable
88617 +
88618 + @Description Enables address bus streaming on the CCB.
88619 +
88620 + This setting, along with the ECM streaming configuration
88621 + parameters, enables address bus streaming on the CCB.
88622 +
88623 + @Return None.
88624 +*//***************************************************************************/
88625 +void E500_AddressBusStreamingEnable(void);
88626 +
88627 +/**************************************************************************//**
88628 + @Function E500_AddressBusStreamingDisable
88629 +
88630 + @Description Disables address bus streaming on the CCB.
88631 +
88632 + @Return None.
88633 +*//***************************************************************************/
88634 +void E500_AddressBusStreamingDisable(void);
88635 +
88636 +/**************************************************************************//**
88637 + @Function E500_AddressBroadcastEnable
88638 +
88639 + @Description Enables address broadcast.
88640 +
88641 + The e500 broadcasts cache management instructions (dcbst, dcblc
88642 + (CT = 1), icblc (CT = 1), dcbf, dcbi, mbar, msync, tlbsync, icbi)
88643 + based on ABE. ABE must be set to allow management of external
88644 + L2 caches.
88645 +
88646 + @Return None.
88647 +*//***************************************************************************/
88648 +void E500_AddressBroadcastEnable(void);
88649 +
88650 +/**************************************************************************//**
88651 + @Function E500_AddressBroadcastDisable
88652 +
88653 + @Description Disables address broadcast.
88654 +
88655 + The e500 broadcasts cache management instructions (dcbst, dcblc
88656 + (CT = 1), icblc (CT = 1), dcbf, dcbi, mbar, msync, tlbsync, icbi)
88657 + based on ABE. ABE must be set to allow management of external
88658 + L2 caches.
88659 +
88660 + @Return None.
88661 +*//***************************************************************************/
88662 +void E500_AddressBroadcastDisable(void);
88663 +
88664 +/**************************************************************************//**
88665 + @Function E500_IsTaskletSupported
88666 +
88667 + @Description Checks if tasklets are supported by the e500 interrupt handler.
88668 +
88669 + @Retval TRUE - Tasklets are supported.
88670 + @Retval FALSE - Tasklets are not supported.
88671 +*//***************************************************************************/
88672 +bool E500_IsTaskletSupported(void);
88673 +
88674 +void E500_EnableTimeBase(void);
88675 +void E500_DisableTimeBase(void);
88676 +
88677 +uint64_t E500_GetTimeBaseTime(void);
88678 +
88679 +void E500_GenericIntrInit(void);
88680 +
88681 +t_Error E500_SetIntr(int ppcIntrSrc,
88682 + void (* Isr)(t_Handle handle),
88683 + t_Handle handle);
88684 +
88685 +t_Error E500_ClearIntr(int ppcIntrSrc);
88686 +
88687 +/**************************************************************************//**
88688 + @Function E500_GenericIntrHandler
88689 +
88690 + @Description This is the general e500 interrupt handler.
88691 +
88692 + It is called by the main assembly interrupt handler
88693 + when an exception occurs and no other function has been
88694 + assigned to this exception.
88695 +
88696 + @Param intrEntry - (In) The exception interrupt vector entry.
88697 +*//***************************************************************************/
88698 +void E500_GenericIntrHandler(uint32_t intrEntry);
88699 +
88700 +/**************************************************************************//**
88701 + @Function CriticalIntr
88702 +
88703 + @Description This is the specific critical e500 interrupt handler.
88704 +
88705 + It is called by the main assembly interrupt handler
88706 + when an critical interrupt.
88707 +
88708 + @Param intrEntry - (In) The exception interrupt vector entry.
88709 +*//***************************************************************************/
88710 +void CriticalIntr(uint32_t intrEntry);
88711 +
88712 +
88713 +/**************************************************************************//**
88714 + @Function E500_GetId
88715 +
88716 + @Description Returns the core ID in the system.
88717 +
88718 + @Return Core ID.
88719 +*//***************************************************************************/
88720 +uint32_t E500_GetId(void);
88721 +
88722 +/**************************************************************************//**
88723 + @Function E500_TestAndSet
88724 +
88725 + @Description This routine tries to atomically test-and-set an integer
88726 + in memory to a non-zero value.
88727 +
88728 + The memory will be set only if it is tested as zero, in which
88729 + case the routine returns the new non-zero value; otherwise the
88730 + routine returns zero.
88731 +
88732 + @Param[in] p - pointer to a volatile int in memory, on which test-and-set
88733 + operation should be made.
88734 +
88735 + @Retval Zero - Operation failed - memory was already set.
88736 + @Retval Non-zero - Operation succeeded - memory has been set.
88737 +*//***************************************************************************/
88738 +int E500_TestAndSet(volatile int *p);
88739 +
88740 +/**************************************************************************//**
88741 + @Function E500_MemoryBarrier
88742 +
88743 + @Description This routine will cause the core to stop executing any commands
88744 + until all previous memory read/write commands are completely out
88745 + of the core's pipeline.
88746 +
88747 + @Return None.
88748 +*//***************************************************************************/
88749 +static __inline__ void E500_MemoryBarrier(void)
88750 +{
88751 +#ifndef CORE_E500V2
88752 + __asm__ ("mbar 1");
88753 +#else /* CORE_E500V2 */
88754 + /**** ERRATA WORK AROUND START ****/
88755 + /* ERRATA num: CPU1 */
88756 + /* Description: "mbar MO = 1" instruction fails to order caching-inhibited
88757 + guarded loads and stores. */
88758 +
88759 + /* "msync" instruction is used instead */
88760 +
88761 + __asm__ ("msync");
88762 +
88763 + /**** ERRATA WORK AROUND END ****/
88764 +#endif /* CORE_E500V2 */
88765 +}
88766 +
88767 +/**************************************************************************//**
88768 + @Function E500_InstructionSync
88769 +
88770 + @Description This routine will cause the core to wait for previous instructions
88771 + (including any interrupts they generate) to complete before the
88772 + synchronization command executes, which purges all instructions
88773 + from the processor's pipeline and refetches the next instruction.
88774 +
88775 + @Return None.
88776 +*//***************************************************************************/
88777 +static __inline__ void E500_InstructionSync(void)
88778 +{
88779 + __asm__ ("isync");
88780 +}
88781 +
88782 +
88783 +/** @} */ /* end of E500_init_grp group */
88784 +/** @} */ /* end of E500_grp group */
88785 +
88786 +
88787 +#endif /* __E500V2_EXT_H */
88788 --- /dev/null
88789 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/cores/ppc_ext.h
88790 @@ -0,0 +1,141 @@
88791 +/*
88792 + * Copyright 2008-2012 Freescale Semiconductor Inc.
88793 + *
88794 + * Redistribution and use in source and binary forms, with or without
88795 + * modification, are permitted provided that the following conditions are met:
88796 + * * Redistributions of source code must retain the above copyright
88797 + * notice, this list of conditions and the following disclaimer.
88798 + * * Redistributions in binary form must reproduce the above copyright
88799 + * notice, this list of conditions and the following disclaimer in the
88800 + * documentation and/or other materials provided with the distribution.
88801 + * * Neither the name of Freescale Semiconductor nor the
88802 + * names of its contributors may be used to endorse or promote products
88803 + * derived from this software without specific prior written permission.
88804 + *
88805 + *
88806 + * ALTERNATIVELY, this software may be distributed under the terms of the
88807 + * GNU General Public License ("GPL") as published by the Free Software
88808 + * Foundation, either version 2 of that License or (at your option) any
88809 + * later version.
88810 + *
88811 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
88812 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
88813 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
88814 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
88815 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
88816 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
88817 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
88818 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
88819 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
88820 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
88821 + */
88822 +
88823 +
88824 +/**************************************************************************//**
88825 + @File ppc_ext.h
88826 +
88827 + @Description Core API for PowerPC cores
88828 +
88829 + These routines must be implemented by each specific PowerPC
88830 + core driver.
88831 +*//***************************************************************************/
88832 +#ifndef __PPC_EXT_H
88833 +#define __PPC_EXT_H
88834 +
88835 +#include "part_ext.h"
88836 +
88837 +
88838 +#define CORE_IS_BIG_ENDIAN
88839 +
88840 +#if defined(CORE_E300) || defined(CORE_E500V2)
88841 +#define CORE_CACHELINE_SIZE 32
88842 +#elif defined(CORE_E500MC) || defined(CORE_E5500) || defined(CORE_E6500)
88843 +#define CORE_CACHELINE_SIZE 64
88844 +#else
88845 +#error "Core not defined!"
88846 +#endif /* defined(CORE_E300) || ... */
88847 +
88848 +
88849 +/**************************************************************************//**
88850 + @Function CORE_TestAndSet
88851 +
88852 + @Description This routine tries to atomically test-and-set an integer
88853 + in memory to a non-zero value.
88854 +
88855 + The memory will be set only if it is tested as zero, in which
88856 + case the routine returns the new non-zero value; otherwise the
88857 + routine returns zero.
88858 +
88859 + @Param[in] p - pointer to a volatile int in memory, on which test-and-set
88860 + operation should be made.
88861 +
88862 + @Retval Zero - Operation failed - memory was already set.
88863 + @Retval Non-zero - Operation succeeded - memory has been set.
88864 +*//***************************************************************************/
88865 +int CORE_TestAndSet(volatile int *p);
88866 +
88867 +/**************************************************************************//**
88868 + @Function CORE_InstructionSync
88869 +
88870 + @Description This routine will cause the core to wait for previous instructions
88871 + (including any interrupts they generate) to complete before the
88872 + synchronization command executes, which purges all instructions
88873 + from the processor's pipeline and refetches the next instruction.
88874 +
88875 + @Return None.
88876 +*//***************************************************************************/
88877 +void CORE_InstructionSync(void);
88878 +
88879 +/**************************************************************************//**
88880 + @Function CORE_DCacheEnable
88881 +
88882 + @Description Enables the data cache for memory pages that are
88883 + not cache inhibited.
88884 +
88885 + @Return None.
88886 +*//***************************************************************************/
88887 +void CORE_DCacheEnable(void);
88888 +
88889 +/**************************************************************************//**
88890 + @Function CORE_ICacheEnable
88891 +
88892 + @Description Enables the instruction cache for memory pages that are
88893 + not cache inhibited.
88894 +
88895 + @Return None.
88896 +*//***************************************************************************/
88897 +void CORE_ICacheEnable(void);
88898 +
88899 +/**************************************************************************//**
88900 + @Function CORE_DCacheDisable
88901 +
88902 + @Description Disables the data cache.
88903 +
88904 + @Return None.
88905 +*//***************************************************************************/
88906 +void CORE_DCacheDisable(void);
88907 +
88908 +/**************************************************************************//**
88909 + @Function CORE_ICacheDisable
88910 +
88911 + @Description Disables the instruction cache.
88912 +
88913 + @Return None.
88914 +*//***************************************************************************/
88915 +void CORE_ICacheDisable(void);
88916 +
88917 +
88918 +
88919 +#if defined(CORE_E300)
88920 +#include "e300_ext.h"
88921 +#elif defined(CORE_E500V2) || defined(CORE_E500MC) || defined(CORE_E5500) || defined(CORE_E6500)
88922 +#include "e500v2_ext.h"
88923 +#if !defined(NCSW_LINUX)
88924 +#include "e500v2_asm_ext.h"
88925 +#endif
88926 +#else
88927 +#error "Core not defined!"
88928 +#endif
88929 +
88930 +
88931 +#endif /* __PPC_EXT_H */
88932 --- /dev/null
88933 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/ddr_std_ext.h
88934 @@ -0,0 +1,77 @@
88935 +/*
88936 + * Copyright 2008-2012 Freescale Semiconductor Inc.
88937 + *
88938 + * Redistribution and use in source and binary forms, with or without
88939 + * modification, are permitted provided that the following conditions are met:
88940 + * * Redistributions of source code must retain the above copyright
88941 + * notice, this list of conditions and the following disclaimer.
88942 + * * Redistributions in binary form must reproduce the above copyright
88943 + * notice, this list of conditions and the following disclaimer in the
88944 + * documentation and/or other materials provided with the distribution.
88945 + * * Neither the name of Freescale Semiconductor nor the
88946 + * names of its contributors may be used to endorse or promote products
88947 + * derived from this software without specific prior written permission.
88948 + *
88949 + *
88950 + * ALTERNATIVELY, this software may be distributed under the terms of the
88951 + * GNU General Public License ("GPL") as published by the Free Software
88952 + * Foundation, either version 2 of that License or (at your option) any
88953 + * later version.
88954 + *
88955 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
88956 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
88957 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
88958 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
88959 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
88960 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
88961 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
88962 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
88963 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
88964 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
88965 + */
88966 +
88967 +#ifndef __DDR_SDT_EXT_H
88968 +#define __DDR_SDT_EXT_H
88969 +
88970 +
88971 +/**************************************************************************//**
88972 + @Group ddr_Generic_Resources
88973 +
88974 + @Description ddr generic functions, definitions and enums.
88975 +
88976 + @{
88977 +*//***************************************************************************/
88978 +
88979 +
88980 +/**************************************************************************//**
88981 + @Description SPD maximum size
88982 +*//***************************************************************************/
88983 +#define SPD_MAX_SIZE 256
88984 +
88985 +/**************************************************************************//**
88986 + @Description DDR types select
88987 +*//***************************************************************************/
88988 +typedef enum e_DdrType
88989 +{
88990 + e_DDR_DDR1,
88991 + e_DDR_DDR2,
88992 + e_DDR_DDR3,
88993 + e_DDR_DDR3L,
88994 + e_DDR_DDR4
88995 +} e_DdrType;
88996 +
88997 +/**************************************************************************//**
88998 + @Description DDR Mode.
88999 +*//***************************************************************************/
89000 +typedef enum e_DdrMode
89001 +{
89002 + e_DDR_BUS_WIDTH_32BIT,
89003 + e_DDR_BUS_WIDTH_64BIT
89004 +} e_DdrMode;
89005 +
89006 +/** @} */ /* end of ddr_Generic_Resources group */
89007 +
89008 +
89009 +
89010 +#endif /* __DDR_SDT_EXT_H */
89011 +
89012 --- /dev/null
89013 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/debug_ext.h
89014 @@ -0,0 +1,233 @@
89015 +/*
89016 + * Copyright 2008-2012 Freescale Semiconductor Inc.
89017 + *
89018 + * Redistribution and use in source and binary forms, with or without
89019 + * modification, are permitted provided that the following conditions are met:
89020 + * * Redistributions of source code must retain the above copyright
89021 + * notice, this list of conditions and the following disclaimer.
89022 + * * Redistributions in binary form must reproduce the above copyright
89023 + * notice, this list of conditions and the following disclaimer in the
89024 + * documentation and/or other materials provided with the distribution.
89025 + * * Neither the name of Freescale Semiconductor nor the
89026 + * names of its contributors may be used to endorse or promote products
89027 + * derived from this software without specific prior written permission.
89028 + *
89029 + *
89030 + * ALTERNATIVELY, this software may be distributed under the terms of the
89031 + * GNU General Public License ("GPL") as published by the Free Software
89032 + * Foundation, either version 2 of that License or (at your option) any
89033 + * later version.
89034 + *
89035 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
89036 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
89037 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
89038 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
89039 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
89040 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
89041 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
89042 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
89043 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
89044 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
89045 + */
89046 +
89047 +
89048 +/**************************************************************************//**
89049 + @File debug_ext.h
89050 +
89051 + @Description Debug mode definitions.
89052 +*//***************************************************************************/
89053 +
89054 +#ifndef __DEBUG_EXT_H
89055 +#define __DEBUG_EXT_H
89056 +
89057 +#include "std_ext.h"
89058 +#include "xx_ext.h"
89059 +#include "memcpy_ext.h"
89060 +#if (DEBUG_ERRORS > 0)
89061 +#include "sprint_ext.h"
89062 +#include "string_ext.h"
89063 +#endif /* DEBUG_ERRORS > 0 */
89064 +
89065 +
89066 +#if (DEBUG_ERRORS > 0)
89067 +
89068 +/* Internally used macros */
89069 +
89070 +#define DUMP_Print XX_Print
89071 +#define DUMP_MAX_LEVELS 6
89072 +#define DUMP_IDX_LEN 6
89073 +#define DUMP_MAX_STR 64
89074 +
89075 +
89076 +#define _CREATE_DUMP_SUBSTR(phrase) \
89077 + dumpTmpLevel = 0; dumpSubStr[0] = '\0'; \
89078 + snprintf(dumpTmpStr, DUMP_MAX_STR, "%s", #phrase); \
89079 + p_DumpToken = strtok(dumpTmpStr, (dumpIsArr[0] ? "[" : ".")); \
89080 + while ((p_DumpToken != NULL) && (dumpTmpLevel < DUMP_MAX_LEVELS)) \
89081 + { \
89082 + strlcat(dumpSubStr, p_DumpToken, DUMP_MAX_STR); \
89083 + if (dumpIsArr[dumpTmpLevel]) \
89084 + { \
89085 + strlcat(dumpSubStr, dumpIdxStr[dumpTmpLevel], DUMP_MAX_STR); \
89086 + p_DumpToken = strtok(NULL, "."); \
89087 + } \
89088 + if ((p_DumpToken != NULL) && \
89089 + ((p_DumpToken = strtok(NULL, (dumpIsArr[++dumpTmpLevel] ? "[" : "."))) != NULL)) \
89090 + strlcat(dumpSubStr, ".", DUMP_MAX_STR); \
89091 + }
89092 +
89093 +
89094 +/**************************************************************************//**
89095 + @Group gen_id General Drivers Utilities
89096 +
89097 + @Description External routines.
89098 +
89099 + @{
89100 +*//***************************************************************************/
89101 +
89102 +/**************************************************************************//**
89103 + @Group dump_id Memory and Registers Dump Mechanism
89104 +
89105 + @Description Macros for dumping memory mapped structures.
89106 +
89107 + @{
89108 +*//***************************************************************************/
89109 +
89110 +/**************************************************************************//**
89111 + @Description Declaration of dump mechanism variables.
89112 +
89113 + This macro must be declared at the beginning of each routine
89114 + which uses the dump mechanism macros, before the routine's code
89115 + starts.
89116 +*//***************************************************************************/
89117 +#define DECLARE_DUMP \
89118 + char dumpIdxStr[DUMP_MAX_LEVELS + 1][DUMP_IDX_LEN] = { "", }; \
89119 + char dumpSubStr[DUMP_MAX_STR] = ""; \
89120 + char dumpTmpStr[DUMP_MAX_STR] = ""; \
89121 + char *p_DumpToken = NULL; \
89122 + int dumpArrIdx = 0, dumpArrSize = 0, dumpLevel = 0, dumpTmpLevel = 0; \
89123 + uint8_t dumpIsArr[DUMP_MAX_LEVELS + 1] = { 0 }; \
89124 + /* Prevent warnings if not all used */ \
89125 + UNUSED(dumpIdxStr[0][0]); \
89126 + UNUSED(dumpSubStr[0]); \
89127 + UNUSED(dumpTmpStr[0]); \
89128 + UNUSED(p_DumpToken); \
89129 + UNUSED(dumpArrIdx); \
89130 + UNUSED(dumpArrSize); \
89131 + UNUSED(dumpLevel); \
89132 + UNUSED(dumpTmpLevel); \
89133 + UNUSED(dumpIsArr[0]);
89134 +
89135 +
89136 +/**************************************************************************//**
89137 + @Description Prints a title for a subsequent dumped structure or memory.
89138 +
89139 + The inputs for this macro are the structure/memory title and
89140 + its base addresses.
89141 +*//***************************************************************************/
89142 +#define DUMP_TITLE(addr, msg) \
89143 + DUMP_Print("\r\n"); DUMP_Print msg; \
89144 + if (addr) \
89145 + DUMP_Print(" (%p)", (addr)); \
89146 + DUMP_Print("\r\n---------------------------------------------------------\r\n");
89147 +
89148 +/**************************************************************************//**
89149 + @Description Prints a subtitle for a subsequent dumped sub-structure (optional).
89150 +
89151 + The inputs for this macro are the sub-structure subtitle.
89152 + A separating line with this subtitle will be printed.
89153 +*//***************************************************************************/
89154 +#define DUMP_SUBTITLE(subtitle) \
89155 + DUMP_Print("----------- "); DUMP_Print subtitle; DUMP_Print("\r\n")
89156 +
89157 +
89158 +/**************************************************************************//**
89159 + @Description Dumps a memory region in 4-bytes aligned format.
89160 +
89161 + The inputs for this macro are the base addresses and size
89162 + (in bytes) of the memory region.
89163 +*//***************************************************************************/
89164 +#define DUMP_MEMORY(addr, size) \
89165 + MemDisp((uint8_t *)(addr), (int)(size))
89166 +
89167 +
89168 +/**************************************************************************//**
89169 + @Description Declares a dump loop, for dumping a sub-structure array.
89170 +
89171 + The inputs for this macro are:
89172 + - idx: an index variable, for indexing the sub-structure items
89173 + inside the loop. This variable must be declared separately
89174 + in the beginning of the routine.
89175 + - cnt: the number of times to repeat the loop. This number should
89176 + equal the number of items in the sub-structures array.
89177 +
89178 + Note, that the body of the loop must be written inside brackets.
89179 +*//***************************************************************************/
89180 +#define DUMP_SUBSTRUCT_ARRAY(idx, cnt) \
89181 + for (idx=0, dumpIsArr[dumpLevel++] = 1; \
89182 + (idx < cnt) && (dumpLevel > 0) && snprintf(dumpIdxStr[dumpLevel-1], DUMP_IDX_LEN, "[%d]", idx); \
89183 + idx++, ((idx < cnt) || (dumpIsArr[--dumpLevel] = 0)))
89184 +
89185 +
89186 +/**************************************************************************//**
89187 + @Description Dumps a structure's member variable.
89188 +
89189 + The input for this macro is the full reference for the member
89190 + variable, where the structure is referenced using a pointer.
89191 +
89192 + Note, that a members array must be dumped using DUMP_ARR macro,
89193 + rather than using this macro.
89194 +
89195 + If the member variable is part of a sub-structure hierarchy,
89196 + the full hierarchy (including array indexing) must be specified.
89197 +
89198 + Examples: p_Struct->member
89199 + p_Struct->sub.member
89200 + p_Struct->sub[i].member
89201 +*//***************************************************************************/
89202 +#define DUMP_VAR(st, phrase) \
89203 + do { \
89204 + void *addr = (void *)&((st)->phrase); \
89205 + physAddress_t physAddr = XX_VirtToPhys(addr); \
89206 + _CREATE_DUMP_SUBSTR(phrase); \
89207 + DUMP_Print("0x%010llX: 0x%08x%8s\t%s\r\n", \
89208 + physAddr, GET_UINT32(*(uint32_t*)addr), "", dumpSubStr); \
89209 + } while (0)
89210 +
89211 +
89212 +/**************************************************************************//**
89213 + @Description Dumps a structure's members array.
89214 +
89215 + The input for this macro is the full reference for the members
89216 + array, where the structure is referenced using a pointer.
89217 +
89218 + If the members array is part of a sub-structure hierarchy,
89219 + the full hierarchy (including array indexing) must be specified.
89220 +
89221 + Examples: p_Struct->array
89222 + p_Struct->sub.array
89223 + p_Struct->sub[i].array
89224 +*//***************************************************************************/
89225 +#define DUMP_ARR(st, phrase) \
89226 + do { \
89227 + physAddress_t physAddr; \
89228 + _CREATE_DUMP_SUBSTR(phrase); \
89229 + dumpArrSize = ARRAY_SIZE((st)->phrase); \
89230 + for (dumpArrIdx=0; dumpArrIdx < dumpArrSize; dumpArrIdx++) { \
89231 + physAddr = XX_VirtToPhys((void *)&((st)->phrase[dumpArrIdx])); \
89232 + DUMP_Print("0x%010llX: 0x%08x%8s\t%s[%d]\r\n", \
89233 + physAddr, GET_UINT32((st)->phrase[dumpArrIdx]), "", dumpSubStr, dumpArrIdx); \
89234 + } \
89235 + } while (0)
89236 +
89237 +
89238 +
89239 +#endif /* DEBUG_ERRORS > 0 */
89240 +
89241 +
89242 +/** @} */ /* end of dump_id group */
89243 +/** @} */ /* end of gen_id group */
89244 +
89245 +
89246 +#endif /* __DEBUG_EXT_H */
89247 +
89248 --- /dev/null
89249 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/endian_ext.h
89250 @@ -0,0 +1,447 @@
89251 +/*
89252 + * Copyright 2008-2012 Freescale Semiconductor Inc.
89253 + *
89254 + * Redistribution and use in source and binary forms, with or without
89255 + * modification, are permitted provided that the following conditions are met:
89256 + * * Redistributions of source code must retain the above copyright
89257 + * notice, this list of conditions and the following disclaimer.
89258 + * * Redistributions in binary form must reproduce the above copyright
89259 + * notice, this list of conditions and the following disclaimer in the
89260 + * documentation and/or other materials provided with the distribution.
89261 + * * Neither the name of Freescale Semiconductor nor the
89262 + * names of its contributors may be used to endorse or promote products
89263 + * derived from this software without specific prior written permission.
89264 + *
89265 + *
89266 + * ALTERNATIVELY, this software may be distributed under the terms of the
89267 + * GNU General Public License ("GPL") as published by the Free Software
89268 + * Foundation, either version 2 of that License or (at your option) any
89269 + * later version.
89270 + *
89271 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
89272 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
89273 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
89274 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
89275 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
89276 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
89277 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
89278 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
89279 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
89280 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
89281 + */
89282 +
89283 +
89284 +/**************************************************************************//**
89285 +
89286 + @File endian_ext.h
89287 +
89288 + @Description Big/little endian swapping routines.
89289 +*//***************************************************************************/
89290 +
89291 +#ifndef __ENDIAN_EXT_H
89292 +#define __ENDIAN_EXT_H
89293 +
89294 +#include "std_ext.h"
89295 +
89296 +
89297 +/**************************************************************************//**
89298 + @Group gen_id General Drivers Utilities
89299 +
89300 + @Description General usage API. This API is intended for usage by both the
89301 + internal modules and the user's application.
89302 +
89303 + @{
89304 +*//***************************************************************************/
89305 +
89306 +/**************************************************************************//**
89307 + @Group endian_id Big/Little-Endian Conversion
89308 +
89309 + @Description Routines and macros for Big/Little-Endian conversion and
89310 + general byte swapping.
89311 +
89312 + All routines and macros are expecting unsigned values as
89313 + parameters, but will generate the correct result also for
89314 + signed values. Therefore, signed/unsigned casting is allowed.
89315 + @{
89316 +*//***************************************************************************/
89317 +
89318 +/**************************************************************************//**
89319 + @Collection Byte-Swap Macros
89320 +
89321 + Macros for swapping byte order.
89322 +
89323 + @Cautions The parameters of these macros are evaluated multiple times.
89324 + For calculated expressions or expressions that contain function
89325 + calls it is recommended to use the byte-swap routines.
89326 +
89327 + @{
89328 +*//***************************************************************************/
89329 +
89330 +/**************************************************************************//**
89331 + @Description Swaps the byte order of a given 16-bit value.
89332 +
89333 + @Param[in] val - The 16-bit value to swap.
89334 +
89335 + @Return The byte-swapped value..
89336 +
89337 + @Cautions The given value is evaluated multiple times by this macro.
89338 + For calculated expressions or expressions that contain function
89339 + calls it is recommended to use the SwapUint16() routine.
89340 +
89341 + @hideinitializer
89342 +*//***************************************************************************/
89343 +#define SWAP_UINT16(val) \
89344 + ((uint16_t)((((val) & 0x00FF) << 8) | (((val) & 0xFF00) >> 8)))
89345 +
89346 +/**************************************************************************//**
89347 + @Description Swaps the byte order of a given 32-bit value.
89348 +
89349 + @Param[in] val - The 32-bit value to swap.
89350 +
89351 + @Return The byte-swapped value..
89352 +
89353 + @Cautions The given value is evaluated multiple times by this macro.
89354 + For calculated expressions or expressions that contain function
89355 + calls it is recommended to use the SwapUint32() routine.
89356 +
89357 + @hideinitializer
89358 +*//***************************************************************************/
89359 +#define SWAP_UINT32(val) \
89360 + ((uint32_t)((((val) & 0x000000FF) << 24) | \
89361 + (((val) & 0x0000FF00) << 8) | \
89362 + (((val) & 0x00FF0000) >> 8) | \
89363 + (((val) & 0xFF000000) >> 24)))
89364 +
89365 +/**************************************************************************//**
89366 + @Description Swaps the byte order of a given 64-bit value.
89367 +
89368 + @Param[in] val - The 64-bit value to swap.
89369 +
89370 + @Return The byte-swapped value..
89371 +
89372 + @Cautions The given value is evaluated multiple times by this macro.
89373 + For calculated expressions or expressions that contain function
89374 + calls it is recommended to use the SwapUint64() routine.
89375 +
89376 + @hideinitializer
89377 +*//***************************************************************************/
89378 +#define SWAP_UINT64(val) \
89379 + ((uint64_t)((((val) & 0x00000000000000FFULL) << 56) | \
89380 + (((val) & 0x000000000000FF00ULL) << 40) | \
89381 + (((val) & 0x0000000000FF0000ULL) << 24) | \
89382 + (((val) & 0x00000000FF000000ULL) << 8) | \
89383 + (((val) & 0x000000FF00000000ULL) >> 8) | \
89384 + (((val) & 0x0000FF0000000000ULL) >> 24) | \
89385 + (((val) & 0x00FF000000000000ULL) >> 40) | \
89386 + (((val) & 0xFF00000000000000ULL) >> 56)))
89387 +
89388 +/* @} */
89389 +
89390 +/**************************************************************************//**
89391 + @Collection Byte-Swap Routines
89392 +
89393 + Routines for swapping the byte order of a given parameter and
89394 + returning the swapped value.
89395 +
89396 + These inline routines are safer than the byte-swap macros,
89397 + because they evaluate the parameter expression only once.
89398 + @{
89399 +*//***************************************************************************/
89400 +
89401 +/**************************************************************************//**
89402 + @Function SwapUint16
89403 +
89404 + @Description Returns the byte-swapped value of a given 16-bit value.
89405 +
89406 + @Param[in] val - The 16-bit value.
89407 +
89408 + @Return The byte-swapped value of the parameter.
89409 +*//***************************************************************************/
89410 +static __inline__ uint16_t SwapUint16(uint16_t val)
89411 +{
89412 + return (uint16_t)(((val & 0x00FF) << 8) |
89413 + ((val & 0xFF00) >> 8));
89414 +}
89415 +
89416 +/**************************************************************************//**
89417 + @Function SwapUint32
89418 +
89419 + @Description Returns the byte-swapped value of a given 32-bit value.
89420 +
89421 + @Param[in] val - The 32-bit value.
89422 +
89423 + @Return The byte-swapped value of the parameter.
89424 +*//***************************************************************************/
89425 +static __inline__ uint32_t SwapUint32(uint32_t val)
89426 +{
89427 + return (uint32_t)(((val & 0x000000FF) << 24) |
89428 + ((val & 0x0000FF00) << 8) |
89429 + ((val & 0x00FF0000) >> 8) |
89430 + ((val & 0xFF000000) >> 24));
89431 +}
89432 +
89433 +/**************************************************************************//**
89434 + @Function SwapUint64
89435 +
89436 + @Description Returns the byte-swapped value of a given 64-bit value.
89437 +
89438 + @Param[in] val - The 64-bit value.
89439 +
89440 + @Return The byte-swapped value of the parameter.
89441 +*//***************************************************************************/
89442 +static __inline__ uint64_t SwapUint64(uint64_t val)
89443 +{
89444 + return (uint64_t)(((val & 0x00000000000000FFULL) << 56) |
89445 + ((val & 0x000000000000FF00ULL) << 40) |
89446 + ((val & 0x0000000000FF0000ULL) << 24) |
89447 + ((val & 0x00000000FF000000ULL) << 8) |
89448 + ((val & 0x000000FF00000000ULL) >> 8) |
89449 + ((val & 0x0000FF0000000000ULL) >> 24) |
89450 + ((val & 0x00FF000000000000ULL) >> 40) |
89451 + ((val & 0xFF00000000000000ULL) >> 56));
89452 +}
89453 +
89454 +/* @} */
89455 +
89456 +/**************************************************************************//**
89457 + @Collection In-place Byte-Swap-And-Set Routines
89458 +
89459 + Routines for swapping the byte order of a given variable and
89460 + setting the swapped value back to the same variable.
89461 + @{
89462 +*//***************************************************************************/
89463 +
89464 +/**************************************************************************//**
89465 + @Function SwapUint16P
89466 +
89467 + @Description Swaps the byte order of a given 16-bit variable.
89468 +
89469 + @Param[in] p_Val - Pointer to the 16-bit variable.
89470 +
89471 + @Return None.
89472 +*//***************************************************************************/
89473 +static __inline__ void SwapUint16P(uint16_t *p_Val)
89474 +{
89475 + *p_Val = SwapUint16(*p_Val);
89476 +}
89477 +
89478 +/**************************************************************************//**
89479 + @Function SwapUint32P
89480 +
89481 + @Description Swaps the byte order of a given 32-bit variable.
89482 +
89483 + @Param[in] p_Val - Pointer to the 32-bit variable.
89484 +
89485 + @Return None.
89486 +*//***************************************************************************/
89487 +static __inline__ void SwapUint32P(uint32_t *p_Val)
89488 +{
89489 + *p_Val = SwapUint32(*p_Val);
89490 +}
89491 +
89492 +/**************************************************************************//**
89493 + @Function SwapUint64P
89494 +
89495 + @Description Swaps the byte order of a given 64-bit variable.
89496 +
89497 + @Param[in] p_Val - Pointer to the 64-bit variable.
89498 +
89499 + @Return None.
89500 +*//***************************************************************************/
89501 +static __inline__ void SwapUint64P(uint64_t *p_Val)
89502 +{
89503 + *p_Val = SwapUint64(*p_Val);
89504 +}
89505 +
89506 +/* @} */
89507 +
89508 +
89509 +/**************************************************************************//**
89510 + @Collection Little-Endian Conversion Macros
89511 +
89512 + These macros convert given parameters to or from Little-Endian
89513 + format. Use these macros when you want to read or write a specific
89514 + Little-Endian value in memory, without a-priori knowing the CPU
89515 + byte order.
89516 +
89517 + These macros use the byte-swap routines. For conversion of
89518 + constants in initialization structures, you may use the CONST
89519 + versions of these macros (see below), which are using the
89520 + byte-swap macros instead.
89521 + @{
89522 +*//***************************************************************************/
89523 +
89524 +/**************************************************************************//**
89525 + @Description Converts a given 16-bit value from CPU byte order to
89526 + Little-Endian byte order.
89527 +
89528 + @Param[in] val - The 16-bit value to convert.
89529 +
89530 + @Return The converted value.
89531 +
89532 + @hideinitializer
89533 +*//***************************************************************************/
89534 +#define CPU_TO_LE16(val) SwapUint16(val)
89535 +
89536 +/**************************************************************************//**
89537 + @Description Converts a given 32-bit value from CPU byte order to
89538 + Little-Endian byte order.
89539 +
89540 + @Param[in] val - The 32-bit value to convert.
89541 +
89542 + @Return The converted value.
89543 +
89544 + @hideinitializer
89545 +*//***************************************************************************/
89546 +#define CPU_TO_LE32(val) SwapUint32(val)
89547 +
89548 +/**************************************************************************//**
89549 + @Description Converts a given 64-bit value from CPU byte order to
89550 + Little-Endian byte order.
89551 +
89552 + @Param[in] val - The 64-bit value to convert.
89553 +
89554 + @Return The converted value.
89555 +
89556 + @hideinitializer
89557 +*//***************************************************************************/
89558 +#define CPU_TO_LE64(val) SwapUint64(val)
89559 +
89560 +
89561 +/**************************************************************************//**
89562 + @Description Converts a given 16-bit value from Little-Endian byte order to
89563 + CPU byte order.
89564 +
89565 + @Param[in] val - The 16-bit value to convert.
89566 +
89567 + @Return The converted value.
89568 +
89569 + @hideinitializer
89570 +*//***************************************************************************/
89571 +#define LE16_TO_CPU(val) CPU_TO_LE16(val)
89572 +
89573 +/**************************************************************************//**
89574 + @Description Converts a given 32-bit value from Little-Endian byte order to
89575 + CPU byte order.
89576 +
89577 + @Param[in] val - The 32-bit value to convert.
89578 +
89579 + @Return The converted value.
89580 +
89581 + @hideinitializer
89582 +*//***************************************************************************/
89583 +#define LE32_TO_CPU(val) CPU_TO_LE32(val)
89584 +
89585 +/**************************************************************************//**
89586 + @Description Converts a given 64-bit value from Little-Endian byte order to
89587 + CPU byte order.
89588 +
89589 + @Param[in] val - The 64-bit value to convert.
89590 +
89591 + @Return The converted value.
89592 +
89593 + @hideinitializer
89594 +*//***************************************************************************/
89595 +#define LE64_TO_CPU(val) CPU_TO_LE64(val)
89596 +
89597 +/* @} */
89598 +
89599 +/**************************************************************************//**
89600 + @Collection Little-Endian Constant Conversion Macros
89601 +
89602 + These macros convert given constants to or from Little-Endian
89603 + format. Use these macros when you want to read or write a specific
89604 + Little-Endian constant in memory, without a-priori knowing the
89605 + CPU byte order.
89606 +
89607 + These macros use the byte-swap macros, therefore can be used for
89608 + conversion of constants in initialization structures.
89609 +
89610 + @Cautions The parameters of these macros are evaluated multiple times.
89611 + For non-constant expressions, use the non-CONST macro versions.
89612 +
89613 + @{
89614 +*//***************************************************************************/
89615 +
89616 +/**************************************************************************//**
89617 + @Description Converts a given 16-bit constant from CPU byte order to
89618 + Little-Endian byte order.
89619 +
89620 + @Param[in] val - The 16-bit value to convert.
89621 +
89622 + @Return The converted value.
89623 +
89624 + @hideinitializer
89625 +*//***************************************************************************/
89626 +#define CONST_CPU_TO_LE16(val) SWAP_UINT16(val)
89627 +
89628 +/**************************************************************************//**
89629 + @Description Converts a given 32-bit constant from CPU byte order to
89630 + Little-Endian byte order.
89631 +
89632 + @Param[in] val - The 32-bit value to convert.
89633 +
89634 + @Return The converted value.
89635 +
89636 + @hideinitializer
89637 +*//***************************************************************************/
89638 +#define CONST_CPU_TO_LE32(val) SWAP_UINT32(val)
89639 +
89640 +/**************************************************************************//**
89641 + @Description Converts a given 64-bit constant from CPU byte order to
89642 + Little-Endian byte order.
89643 +
89644 + @Param[in] val - The 64-bit value to convert.
89645 +
89646 + @Return The converted value.
89647 +
89648 + @hideinitializer
89649 +*//***************************************************************************/
89650 +#define CONST_CPU_TO_LE64(val) SWAP_UINT64(val)
89651 +
89652 +
89653 +/**************************************************************************//**
89654 + @Description Converts a given 16-bit constant from Little-Endian byte order
89655 + to CPU byte order.
89656 +
89657 + @Param[in] val - The 16-bit value to convert.
89658 +
89659 + @Return The converted value.
89660 +
89661 + @hideinitializer
89662 +*//***************************************************************************/
89663 +#define CONST_LE16_TO_CPU(val) CONST_CPU_TO_LE16(val)
89664 +
89665 +/**************************************************************************//**
89666 + @Description Converts a given 32-bit constant from Little-Endian byte order
89667 + to CPU byte order.
89668 +
89669 + @Param[in] val - The 32-bit value to convert.
89670 +
89671 + @Return The converted value.
89672 +
89673 + @hideinitializer
89674 +*//***************************************************************************/
89675 +#define CONST_LE32_TO_CPU(val) CONST_CPU_TO_LE32(val)
89676 +
89677 +/**************************************************************************//**
89678 + @Description Converts a given 64-bit constant from Little-Endian byte order
89679 + to CPU byte order.
89680 +
89681 + @Param[in] val - The 64-bit value to convert.
89682 +
89683 + @Return The converted value.
89684 +
89685 + @hideinitializer
89686 +*//***************************************************************************/
89687 +#define CONST_LE64_TO_CPU(val) CONST_CPU_TO_LE64(val)
89688 +
89689 +/* @} */
89690 +
89691 +
89692 +/** @} */ /* end of endian_id group */
89693 +/** @} */ /* end of gen_id group */
89694 +
89695 +
89696 +#endif /* __ENDIAN_EXT_H */
89697 +
89698 --- /dev/null
89699 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/enet_ext.h
89700 @@ -0,0 +1,205 @@
89701 +/* Copyright (c) 2008-2012 Freescale Semiconductor, Inc
89702 + * All rights reserved.
89703 + *
89704 + * Redistribution and use in source and binary forms, with or without
89705 + * modification, are permitted provided that the following conditions are met:
89706 + * * Redistributions of source code must retain the above copyright
89707 + * notice, this list of conditions and the following disclaimer.
89708 + * * Redistributions in binary form must reproduce the above copyright
89709 + * notice, this list of conditions and the following disclaimer in the
89710 + * documentation and/or other materials provided with the distribution.
89711 + * * Neither the name of Freescale Semiconductor nor the
89712 + * names of its contributors may be used to endorse or promote products
89713 + * derived from this software without specific prior written permission.
89714 + *
89715 + *
89716 + * ALTERNATIVELY, this software may be distributed under the terms of the
89717 + * GNU General Public License ("GPL") as published by the Free Software
89718 + * Foundation, either version 2 of that License or (at your option) any
89719 + * later version.
89720 + *
89721 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
89722 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
89723 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
89724 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
89725 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
89726 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
89727 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
89728 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
89729 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
89730 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
89731 + */
89732 +
89733 +
89734 +/**************************************************************************//**
89735 + @File enet_ext.h
89736 +
89737 + @Description Ethernet generic definitions and enums.
89738 +*//***************************************************************************/
89739 +
89740 +#ifndef __ENET_EXT_H
89741 +#define __ENET_EXT_H
89742 +
89743 +#include "fsl_enet.h"
89744 +
89745 +#define ENET_NUM_OCTETS_PER_ADDRESS 6 /**< Number of octets (8-bit bytes) in an ethernet address */
89746 +#define ENET_GROUP_ADDR 0x01 /**< Group address mask for ethernet addresses */
89747 +
89748 +
89749 +/**************************************************************************//**
89750 + @Description Ethernet Address
89751 +*//***************************************************************************/
89752 +typedef uint8_t t_EnetAddr[ENET_NUM_OCTETS_PER_ADDRESS];
89753 +
89754 +/**************************************************************************//**
89755 + @Description Ethernet Address Type.
89756 +*//***************************************************************************/
89757 +typedef enum e_EnetAddrType
89758 +{
89759 + e_ENET_ADDR_TYPE_INDIVIDUAL, /**< Individual (unicast) address */
89760 + e_ENET_ADDR_TYPE_GROUP, /**< Group (multicast) address */
89761 + e_ENET_ADDR_TYPE_BROADCAST /**< Broadcast address */
89762 +} e_EnetAddrType;
89763 +
89764 +/**************************************************************************//**
89765 + @Description Ethernet MAC-PHY Interface
89766 +*//***************************************************************************/
89767 +typedef enum e_EnetInterface
89768 +{
89769 + e_ENET_IF_MII = E_ENET_IF_MII, /**< MII interface */
89770 + e_ENET_IF_RMII = E_ENET_IF_RMII, /**< RMII interface */
89771 + e_ENET_IF_SMII = E_ENET_IF_SMII, /**< SMII interface */
89772 + e_ENET_IF_GMII = E_ENET_IF_GMII, /**< GMII interface */
89773 + e_ENET_IF_RGMII = E_ENET_IF_RGMII, /**< RGMII interface */
89774 + e_ENET_IF_TBI = E_ENET_IF_TBI, /**< TBI interface */
89775 + e_ENET_IF_RTBI = E_ENET_IF_RTBI, /**< RTBI interface */
89776 + e_ENET_IF_SGMII = E_ENET_IF_SGMII, /**< SGMII interface */
89777 + e_ENET_IF_XGMII = E_ENET_IF_XGMII, /**< XGMII interface */
89778 + e_ENET_IF_QSGMII= E_ENET_IF_QSGMII, /**< QSGMII interface */
89779 + e_ENET_IF_XFI = E_ENET_IF_XFI /**< XFI interface */
89780 +} e_EnetInterface;
89781 +
89782 +#define ENET_IF_SGMII_BASEX 0x80000000 /**< SGMII/QSGII interface with 1000BaseX
89783 + auto-negotiation between MAC and phy
89784 + or backplane;
89785 + Note: 1000BaseX auto-negotiation relates
89786 + only to interface between MAC and phy/backplane,
89787 + SGMII phy can still synchronize with far-end phy
89788 + at 10Mbps, 100Mbps or 1000Mbps */
89789 +
89790 +/**************************************************************************//**
89791 + @Description Ethernet Duplex Mode
89792 +*//***************************************************************************/
89793 +typedef enum e_EnetDuplexMode
89794 +{
89795 + e_ENET_HALF_DUPLEX, /**< Half-Duplex mode */
89796 + e_ENET_FULL_DUPLEX /**< Full-Duplex mode */
89797 +} e_EnetDuplexMode;
89798 +
89799 +/**************************************************************************//**
89800 + @Description Ethernet Speed (nominal data rate)
89801 +*//***************************************************************************/
89802 +typedef enum e_EnetSpeed
89803 +{
89804 + e_ENET_SPEED_10 = E_ENET_SPEED_10, /**< 10 Mbps */
89805 + e_ENET_SPEED_100 = E_ENET_SPEED_100, /**< 100 Mbps */
89806 + e_ENET_SPEED_1000 = E_ENET_SPEED_1000, /**< 1000 Mbps = 1 Gbps */
89807 + e_ENET_SPEED_2500 = E_ENET_SPEED_2500, /**< 2500 Mbps = 2.5 Gbps */
89808 + e_ENET_SPEED_10000 = E_ENET_SPEED_10000 /**< 10000 Mbps = 10 Gbps */
89809 +} e_EnetSpeed;
89810 +
89811 +/**************************************************************************//**
89812 + @Description Ethernet mode (combination of MAC-PHY interface and speed)
89813 +*//***************************************************************************/
89814 +typedef enum e_EnetMode
89815 +{
89816 + e_ENET_MODE_INVALID = 0, /**< Invalid Ethernet mode */
89817 + e_ENET_MODE_MII_10 = (e_ENET_IF_MII | e_ENET_SPEED_10), /**< 10 Mbps MII */
89818 + e_ENET_MODE_MII_100 = (e_ENET_IF_MII | e_ENET_SPEED_100), /**< 100 Mbps MII */
89819 + e_ENET_MODE_RMII_10 = (e_ENET_IF_RMII | e_ENET_SPEED_10), /**< 10 Mbps RMII */
89820 + e_ENET_MODE_RMII_100 = (e_ENET_IF_RMII | e_ENET_SPEED_100), /**< 100 Mbps RMII */
89821 + e_ENET_MODE_SMII_10 = (e_ENET_IF_SMII | e_ENET_SPEED_10), /**< 10 Mbps SMII */
89822 + e_ENET_MODE_SMII_100 = (e_ENET_IF_SMII | e_ENET_SPEED_100), /**< 100 Mbps SMII */
89823 + e_ENET_MODE_GMII_1000 = (e_ENET_IF_GMII | e_ENET_SPEED_1000), /**< 1000 Mbps GMII */
89824 + e_ENET_MODE_RGMII_10 = (e_ENET_IF_RGMII | e_ENET_SPEED_10), /**< 10 Mbps RGMII */
89825 + e_ENET_MODE_RGMII_100 = (e_ENET_IF_RGMII | e_ENET_SPEED_100), /**< 100 Mbps RGMII */
89826 + e_ENET_MODE_RGMII_1000 = (e_ENET_IF_RGMII | e_ENET_SPEED_1000), /**< 1000 Mbps RGMII */
89827 + e_ENET_MODE_TBI_1000 = (e_ENET_IF_TBI | e_ENET_SPEED_1000), /**< 1000 Mbps TBI */
89828 + e_ENET_MODE_RTBI_1000 = (e_ENET_IF_RTBI | e_ENET_SPEED_1000), /**< 1000 Mbps RTBI */
89829 + e_ENET_MODE_SGMII_10 = (e_ENET_IF_SGMII | e_ENET_SPEED_10),
89830 + /**< 10 Mbps SGMII with auto-negotiation between MAC and
89831 + SGMII phy according to Cisco SGMII specification */
89832 + e_ENET_MODE_SGMII_100 = (e_ENET_IF_SGMII | e_ENET_SPEED_100),
89833 + /**< 100 Mbps SGMII with auto-negotiation between MAC and
89834 + SGMII phy according to Cisco SGMII specification */
89835 + e_ENET_MODE_SGMII_1000 = (e_ENET_IF_SGMII | e_ENET_SPEED_1000),
89836 + /**< 1000 Mbps SGMII with auto-negotiation between MAC and
89837 + SGMII phy according to Cisco SGMII specification */
89838 + e_ENET_MODE_SGMII_2500 = (e_ENET_IF_SGMII | e_ENET_SPEED_2500),
89839 + e_ENET_MODE_SGMII_BASEX_10 = (ENET_IF_SGMII_BASEX | e_ENET_IF_SGMII | e_ENET_SPEED_10),
89840 + /**< 10 Mbps SGMII with 1000BaseX auto-negotiation between
89841 + MAC and SGMII phy or backplane */
89842 + e_ENET_MODE_SGMII_BASEX_100 = (ENET_IF_SGMII_BASEX | e_ENET_IF_SGMII | e_ENET_SPEED_100),
89843 + /**< 100 Mbps SGMII with 1000BaseX auto-negotiation between
89844 + MAC and SGMII phy or backplane */
89845 + e_ENET_MODE_SGMII_BASEX_1000 = (ENET_IF_SGMII_BASEX | e_ENET_IF_SGMII | e_ENET_SPEED_1000),
89846 + /**< 1000 Mbps SGMII with 1000BaseX auto-negotiation between
89847 + MAC and SGMII phy or backplane */
89848 + e_ENET_MODE_QSGMII_1000 = (e_ENET_IF_QSGMII| e_ENET_SPEED_1000),
89849 + /**< 1000 Mbps QSGMII with auto-negotiation between MAC and
89850 + QSGMII phy according to Cisco QSGMII specification */
89851 + e_ENET_MODE_QSGMII_BASEX_1000 = (ENET_IF_SGMII_BASEX | e_ENET_IF_QSGMII| e_ENET_SPEED_1000),
89852 + /**< 1000 Mbps QSGMII with 1000BaseX auto-negotiation between
89853 + MAC and QSGMII phy or backplane */
89854 + e_ENET_MODE_XGMII_10000 = (e_ENET_IF_XGMII | e_ENET_SPEED_10000), /**< 10000 Mbps XGMII */
89855 + e_ENET_MODE_XFI_10000 = (e_ENET_IF_XFI | e_ENET_SPEED_10000) /**< 10000 Mbps XFI */
89856 +} e_EnetMode;
89857 +
89858 +
89859 +#define IS_ENET_MODE_VALID(mode) \
89860 + (((mode) == e_ENET_MODE_MII_10 ) || \
89861 + ((mode) == e_ENET_MODE_MII_100 ) || \
89862 + ((mode) == e_ENET_MODE_RMII_10 ) || \
89863 + ((mode) == e_ENET_MODE_RMII_100 ) || \
89864 + ((mode) == e_ENET_MODE_SMII_10 ) || \
89865 + ((mode) == e_ENET_MODE_SMII_100 ) || \
89866 + ((mode) == e_ENET_MODE_GMII_1000 ) || \
89867 + ((mode) == e_ENET_MODE_RGMII_10 ) || \
89868 + ((mode) == e_ENET_MODE_RGMII_100 ) || \
89869 + ((mode) == e_ENET_MODE_RGMII_1000 ) || \
89870 + ((mode) == e_ENET_MODE_TBI_1000 ) || \
89871 + ((mode) == e_ENET_MODE_RTBI_1000 ) || \
89872 + ((mode) == e_ENET_MODE_SGMII_10 ) || \
89873 + ((mode) == e_ENET_MODE_SGMII_100 ) || \
89874 + ((mode) == e_ENET_MODE_SGMII_1000 ) || \
89875 + ((mode) == e_ENET_MODE_SGMII_BASEX_10 ) || \
89876 + ((mode) == e_ENET_MODE_SGMII_BASEX_100 ) || \
89877 + ((mode) == e_ENET_MODE_SGMII_BASEX_1000 ) || \
89878 + ((mode) == e_ENET_MODE_XGMII_10000) || \
89879 + ((mode) == e_ENET_MODE_QSGMII_1000) || \
89880 + ((mode) == e_ENET_MODE_QSGMII_BASEX_1000) || \
89881 + ((mode) == e_ENET_MODE_XFI_10000))
89882 +
89883 +
89884 +#define MAKE_ENET_MODE(_interface, _speed) (e_EnetMode)((_interface) | (_speed))
89885 +
89886 +#define ENET_INTERFACE_FROM_MODE(mode) (e_EnetInterface)((mode) & 0x0FFF0000)
89887 +#define ENET_SPEED_FROM_MODE(mode) (e_EnetSpeed)((mode) & 0x0000FFFF)
89888 +
89889 +#define ENET_ADDR_TO_UINT64(_enetAddr) \
89890 + (uint64_t)(((uint64_t)(_enetAddr)[0] << 40) | \
89891 + ((uint64_t)(_enetAddr)[1] << 32) | \
89892 + ((uint64_t)(_enetAddr)[2] << 24) | \
89893 + ((uint64_t)(_enetAddr)[3] << 16) | \
89894 + ((uint64_t)(_enetAddr)[4] << 8) | \
89895 + ((uint64_t)(_enetAddr)[5]))
89896 +
89897 +#define MAKE_ENET_ADDR_FROM_UINT64(_addr64, _enetAddr) \
89898 + do { \
89899 + int i; \
89900 + for (i=0; i < ENET_NUM_OCTETS_PER_ADDRESS; i++) \
89901 + (_enetAddr)[i] = (uint8_t)((_addr64) >> ((5-i)*8)); \
89902 + } while (0)
89903 +
89904 +
89905 +#endif /* __ENET_EXT_H */
89906 --- /dev/null
89907 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/error_ext.h
89908 @@ -0,0 +1,529 @@
89909 +/* Copyright (c) 2008-2012 Freescale Semiconductor, Inc
89910 + * All rights reserved.
89911 + *
89912 + * Redistribution and use in source and binary forms, with or without
89913 + * modification, are permitted provided that the following conditions are met:
89914 + * * Redistributions of source code must retain the above copyright
89915 + * notice, this list of conditions and the following disclaimer.
89916 + * * Redistributions in binary form must reproduce the above copyright
89917 + * notice, this list of conditions and the following disclaimer in the
89918 + * documentation and/or other materials provided with the distribution.
89919 + * * Neither the name of Freescale Semiconductor nor the
89920 + * names of its contributors may be used to endorse or promote products
89921 + * derived from this software without specific prior written permission.
89922 + *
89923 + *
89924 + * ALTERNATIVELY, this software may be distributed under the terms of the
89925 + * GNU General Public License ("GPL") as published by the Free Software
89926 + * Foundation, either version 2 of that License or (at your option) any
89927 + * later version.
89928 + *
89929 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
89930 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
89931 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
89932 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
89933 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
89934 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
89935 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
89936 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
89937 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
89938 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
89939 + */
89940 +
89941 +
89942 +/**************************************************************************//**
89943 + @File error_ext.h
89944 +
89945 + @Description Error definitions.
89946 +*//***************************************************************************/
89947 +
89948 +#ifndef __ERROR_EXT_H
89949 +#define __ERROR_EXT_H
89950 +
89951 +#if !defined(NCSW_LINUX)
89952 +#include <errno.h>
89953 +#endif
89954 +
89955 +#include "std_ext.h"
89956 +#include "xx_ext.h"
89957 +#include "core_ext.h"
89958 +
89959 +
89960 +
89961 +
89962 +/**************************************************************************//**
89963 + @Group gen_id General Drivers Utilities
89964 +
89965 + @Description External routines.
89966 +
89967 + @{
89968 +*//***************************************************************************/
89969 +
89970 +/**************************************************************************//**
89971 + @Group gen_error_id Errors, Events and Debug
89972 +
89973 + @Description External routines.
89974 +
89975 + @{
89976 +*//***************************************************************************/
89977 +
89978 +/******************************************************************************
89979 +The scheme below provides the bits description for error codes:
89980 +
89981 + 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
89982 +| Reserved (should be zero) | Module ID |
89983 +
89984 + 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
89985 +| Error Type |
89986 +******************************************************************************/
89987 +
89988 +#define ERROR_CODE(_err) ((((uint32_t)_err) & 0x0000FFFF) | __ERR_MODULE__)
89989 +
89990 +#define GET_ERROR_TYPE(_errcode) ((_errcode) & 0x0000FFFF)
89991 + /**< Extract module code from error code (#t_Error) */
89992 +
89993 +#define GET_ERROR_MODULE(_errcode) ((_errcode) & 0x00FF0000)
89994 + /**< Extract error type (#e_ErrorType) from
89995 + error code (#t_Error) */
89996 +
89997 +
89998 +/**************************************************************************//**
89999 + @Description Error Type Enumeration
90000 +*//***************************************************************************/
90001 +typedef enum e_ErrorType /* Comments / Associated Message Strings */
90002 +{ /* ------------------------------------------------------------ */
90003 + E_OK = 0 /* Never use "RETURN_ERROR" with E_OK; Use "return E_OK;" */
90004 + ,E_WRITE_FAILED = EIO /**< Write access failed on memory/device. */
90005 + /* String: none, or device name. */
90006 + ,E_NO_DEVICE = ENXIO /**< The associated device is not initialized. */
90007 + /* String: none. */
90008 + ,E_NOT_AVAILABLE = EAGAIN
90009 + /**< Resource is unavailable. */
90010 + /* String: none, unless the operation is not the main goal
90011 + of the function (in this case add resource description). */
90012 + ,E_NO_MEMORY = ENOMEM /**< External memory allocation failed. */
90013 + /* String: description of item for which allocation failed. */
90014 + ,E_INVALID_ADDRESS = EFAULT
90015 + /**< Invalid address. */
90016 + /* String: description of the specific violation. */
90017 + ,E_BUSY = EBUSY /**< Resource or module is busy. */
90018 + /* String: none, unless the operation is not the main goal
90019 + of the function (in this case add resource description). */
90020 + ,E_ALREADY_EXISTS = EEXIST
90021 + /**< Requested resource or item already exists. */
90022 + /* Use when resource duplication or sharing are not allowed.
90023 + String: none, unless the operation is not the main goal
90024 + of the function (in this case add item description). */
90025 + ,E_INVALID_OPERATION = ENODEV
90026 + /**< The operation/command is invalid (unrecognized). */
90027 + /* String: none. */
90028 + ,E_INVALID_VALUE = EDOM /**< Invalid value. */
90029 + /* Use for non-enumeration parameters, and
90030 + only when other error types are not suitable.
90031 + String: parameter description + "(should be <attribute>)",
90032 + e.g: "Maximum Rx buffer length (should be divisible by 8)",
90033 + "Channel number (should be even)". */
90034 + ,E_NOT_IN_RANGE = ERANGE/**< Parameter value is out of range. */
90035 + /* Don't use this error for enumeration parameters.
90036 + String: parameter description + "(should be %d-%d)",
90037 + e.g: "Number of pad characters (should be 0-15)". */
90038 + ,E_NOT_SUPPORTED = ENOSYS
90039 + /**< The function is not supported or not implemented. */
90040 + /* String: none. */
90041 + ,E_INVALID_STATE /**< The operation is not allowed in current module state. */
90042 + /* String: none. */
90043 + ,E_INVALID_HANDLE /**< Invalid handle of module or object. */
90044 + /* String: none, unless the function takes in more than one
90045 + handle (in this case add the handle description) */
90046 + ,E_INVALID_ID /**< Invalid module ID (usually enumeration or index). */
90047 + /* String: none, unless the function takes in more than one
90048 + ID (in this case add the ID description) */
90049 + ,E_NULL_POINTER /**< Unexpected NULL pointer. */
90050 + /* String: pointer description. */
90051 + ,E_INVALID_SELECTION /**< Invalid selection or mode. */
90052 + /* Use for enumeration values, only when other error types
90053 + are not suitable.
90054 + String: parameter description. */
90055 + ,E_INVALID_COMM_MODE /**< Invalid communication mode. */
90056 + /* String: none, unless the function takes in more than one
90057 + communication mode indications (in this case add
90058 + parameter description). */
90059 + ,E_INVALID_MEMORY_TYPE /**< Invalid memory type. */
90060 + /* String: none, unless the function takes in more than one
90061 + memory types (in this case add memory description,
90062 + e.g: "Data memory", "Buffer descriptors memory"). */
90063 + ,E_INVALID_CLOCK /**< Invalid clock. */
90064 + /* String: none, unless the function takes in more than one
90065 + clocks (in this case add clock description,
90066 + e.g: "Rx clock", "Tx clock"). */
90067 + ,E_CONFLICT /**< Some setting conflicts with another setting. */
90068 + /* String: description of the conflicting settings. */
90069 + ,E_NOT_ALIGNED /**< Non-aligned address. */
90070 + /* String: parameter description + "(should be %d-bytes aligned)",
90071 + e.g: "Rx data buffer (should be 32-bytes aligned)". */
90072 + ,E_NOT_FOUND /**< Requested resource or item was not found. */
90073 + /* Use only when the resource/item is uniquely identified.
90074 + String: none, unless the operation is not the main goal
90075 + of the function (in this case add item description). */
90076 + ,E_FULL /**< Resource is full. */
90077 + /* String: none, unless the operation is not the main goal
90078 + of the function (in this case add resource description). */
90079 + ,E_EMPTY /**< Resource is empty. */
90080 + /* String: none, unless the operation is not the main goal
90081 + of the function (in this case add resource description). */
90082 + ,E_ALREADY_FREE /**< Specified resource or item is already free or deleted. */
90083 + /* String: none, unless the operation is not the main goal
90084 + of the function (in this case add item description). */
90085 + ,E_READ_FAILED /**< Read access failed on memory/device. */
90086 + /* String: none, or device name. */
90087 + ,E_INVALID_FRAME /**< Invalid frame object (NULL handle or missing buffers). */
90088 + /* String: none. */
90089 + ,E_SEND_FAILED /**< Send operation failed on device. */
90090 + /* String: none, or device name. */
90091 + ,E_RECEIVE_FAILED /**< Receive operation failed on device. */
90092 + /* String: none, or device name. */
90093 + ,E_TIMEOUT/* = ETIMEDOUT*/ /**< The operation timed out. */
90094 + /* String: none. */
90095 +
90096 + ,E_DUMMY_LAST /* NEVER USED */
90097 +
90098 +} e_ErrorType;
90099 +
90100 +/**************************************************************************//**
90101 + @Description Event Type Enumeration
90102 +*//***************************************************************************/
90103 +typedef enum e_Event /* Comments / Associated Flags and Message Strings */
90104 +{ /* ------------------------------------------------------------ */
90105 + EV_NO_EVENT = 0 /**< No event; Never used. */
90106 +
90107 + ,EV_RX_DISCARD /**< Received packet discarded (by the driver, and only for
90108 + complete packets);
90109 + Flags: error flags in case of error, zero otherwise. */
90110 + /* String: reason for discard, e.g: "Error in frame",
90111 + "Disordered frame", "Incomplete frame", "No frame object". */
90112 + ,EV_RX_ERROR /**< Receive error (by hardware/firmware);
90113 + Flags: usually status flags from the buffer descriptor. */
90114 + /* String: none. */
90115 + ,EV_TX_ERROR /**< Transmit error (by hardware/firmware);
90116 + Flags: usually status flags from the buffer descriptor. */
90117 + /* String: none. */
90118 + ,EV_NO_BUFFERS /**< System ran out of buffer objects;
90119 + Flags: zero. */
90120 + /* String: none. */
90121 + ,EV_NO_MB_FRAMES /**< System ran out of multi-buffer frame objects;
90122 + Flags: zero. */
90123 + /* String: none. */
90124 + ,EV_NO_SB_FRAMES /**< System ran out of single-buffer frame objects;
90125 + Flags: zero. */
90126 + /* String: none. */
90127 + ,EV_TX_QUEUE_FULL /**< Transmit queue is full;
90128 + Flags: zero. */
90129 + /* String: none. */
90130 + ,EV_RX_QUEUE_FULL /**< Receive queue is full;
90131 + Flags: zero. */
90132 + /* String: none. */
90133 + ,EV_INTR_QUEUE_FULL /**< Interrupt queue overflow;
90134 + Flags: zero. */
90135 + /* String: none. */
90136 + ,EV_NO_DATA_BUFFER /**< Data buffer allocation (from higher layer) failed;
90137 + Flags: zero. */
90138 + /* String: none. */
90139 + ,EV_OBJ_POOL_EMPTY /**< Objects pool is empty;
90140 + Flags: zero. */
90141 + /* String: object description (name). */
90142 + ,EV_BUS_ERROR /**< Illegal access on bus;
90143 + Flags: the address (if available) or bus identifier */
90144 + /* String: bus/address/module description. */
90145 + ,EV_PTP_TXTS_QUEUE_FULL /**< PTP Tx timestamps queue is full;
90146 + Flags: zero. */
90147 + /* String: none. */
90148 + ,EV_PTP_RXTS_QUEUE_FULL /**< PTP Rx timestamps queue is full;
90149 + Flags: zero. */
90150 + /* String: none. */
90151 + ,EV_DUMMY_LAST
90152 +
90153 +} e_Event;
90154 +
90155 +
90156 +/**************************************************************************//**
90157 + @Collection Debug Levels for Errors and Events
90158 +
90159 + The level description refers to errors only.
90160 + For events, classification is done by the user.
90161 +
90162 + The TRACE, INFO and WARNING levels are allowed only when using
90163 + the DBG macro, and are not allowed when using the error macros
90164 + (RETURN_ERROR or REPORT_ERROR).
90165 + @{
90166 +*//***************************************************************************/
90167 +#define REPORT_LEVEL_CRITICAL 1 /**< Crasher: Incorrect flow, NULL pointers/handles. */
90168 +#define REPORT_LEVEL_MAJOR 2 /**< Cannot proceed: Invalid operation, parameters or
90169 + configuration. */
90170 +#define REPORT_LEVEL_MINOR 3 /**< Recoverable problem: a repeating call with the same
90171 + parameters may be successful. */
90172 +#define REPORT_LEVEL_WARNING 4 /**< Something is not exactly right, yet it is not an error. */
90173 +#define REPORT_LEVEL_INFO 5 /**< Messages which may be of interest to user/programmer. */
90174 +#define REPORT_LEVEL_TRACE 6 /**< Program flow messages. */
90175 +
90176 +#define EVENT_DISABLED 0xFF /**< Disabled event (not reported at all) */
90177 +
90178 +/* @} */
90179 +
90180 +
90181 +
90182 +#define NO_MSG ("")
90183 +
90184 +#ifndef DEBUG_GLOBAL_LEVEL
90185 +#define DEBUG_GLOBAL_LEVEL REPORT_LEVEL_WARNING
90186 +#endif /* DEBUG_GLOBAL_LEVEL */
90187 +
90188 +#ifndef ERROR_GLOBAL_LEVEL
90189 +#define ERROR_GLOBAL_LEVEL DEBUG_GLOBAL_LEVEL
90190 +#endif /* ERROR_GLOBAL_LEVEL */
90191 +
90192 +#ifndef EVENT_GLOBAL_LEVEL
90193 +#define EVENT_GLOBAL_LEVEL REPORT_LEVEL_MINOR
90194 +#endif /* EVENT_GLOBAL_LEVEL */
90195 +
90196 +#ifdef EVENT_LOCAL_LEVEL
90197 +#define EVENT_DYNAMIC_LEVEL EVENT_LOCAL_LEVEL
90198 +#else
90199 +#define EVENT_DYNAMIC_LEVEL EVENT_GLOBAL_LEVEL
90200 +#endif /* EVENT_LOCAL_LEVEL */
90201 +
90202 +
90203 +#ifndef DEBUG_DYNAMIC_LEVEL
90204 +#define DEBUG_USING_STATIC_LEVEL
90205 +
90206 +#ifdef DEBUG_STATIC_LEVEL
90207 +#define DEBUG_DYNAMIC_LEVEL DEBUG_STATIC_LEVEL
90208 +#else
90209 +#define DEBUG_DYNAMIC_LEVEL DEBUG_GLOBAL_LEVEL
90210 +#endif /* DEBUG_STATIC_LEVEL */
90211 +
90212 +#else /* DEBUG_DYNAMIC_LEVEL */
90213 +#ifdef DEBUG_STATIC_LEVEL
90214 +#error "Please use either DEBUG_STATIC_LEVEL or DEBUG_DYNAMIC_LEVEL (not both)"
90215 +#else
90216 +int DEBUG_DYNAMIC_LEVEL = DEBUG_GLOBAL_LEVEL;
90217 +#endif /* DEBUG_STATIC_LEVEL */
90218 +#endif /* !DEBUG_DYNAMIC_LEVEL */
90219 +
90220 +
90221 +#ifndef ERROR_DYNAMIC_LEVEL
90222 +
90223 +#ifdef ERROR_STATIC_LEVEL
90224 +#define ERROR_DYNAMIC_LEVEL ERROR_STATIC_LEVEL
90225 +#else
90226 +#define ERROR_DYNAMIC_LEVEL ERROR_GLOBAL_LEVEL
90227 +#endif /* ERROR_STATIC_LEVEL */
90228 +
90229 +#else /* ERROR_DYNAMIC_LEVEL */
90230 +#ifdef ERROR_STATIC_LEVEL
90231 +#error "Please use either ERROR_STATIC_LEVEL or ERROR_DYNAMIC_LEVEL (not both)"
90232 +#else
90233 +int ERROR_DYNAMIC_LEVEL = ERROR_GLOBAL_LEVEL;
90234 +#endif /* ERROR_STATIC_LEVEL */
90235 +#endif /* !ERROR_DYNAMIC_LEVEL */
90236 +
90237 +#define PRINT_FORMAT "[CPU%02d, %s:%d %s]"
90238 +#define PRINT_FMT_PARAMS raw_smp_processor_id(), __FILE__, __LINE__, __FUNCTION__
90239 +
90240 +#if (!(defined(DEBUG_ERRORS)) || (DEBUG_ERRORS == 0))
90241 +/* No debug/error/event messages at all */
90242 +#define DBG(_level, _vmsg)
90243 +
90244 +#define REPORT_ERROR(_level, _err, _vmsg)
90245 +
90246 +#define RETURN_ERROR(_level, _err, _vmsg) \
90247 + return ERROR_CODE(_err)
90248 +
90249 +#if (REPORT_EVENTS > 0)
90250 +
90251 +#define REPORT_EVENT(_ev, _appId, _flg, _vmsg) \
90252 + do { \
90253 + if (_ev##_LEVEL <= EVENT_DYNAMIC_LEVEL) { \
90254 + XX_EventById((uint32_t)(_ev), (t_Handle)(_appId), (uint16_t)(_flg), NO_MSG); \
90255 + } \
90256 + } while (0)
90257 +
90258 +#else
90259 +
90260 +#define REPORT_EVENT(_ev, _appId, _flg, _vmsg)
90261 +
90262 +#endif /* (REPORT_EVENTS > 0) */
90263 +
90264 +
90265 +#else /* DEBUG_ERRORS > 0 */
90266 +
90267 +extern const char *dbgLevelStrings[];
90268 +extern const char *moduleStrings[];
90269 +#if (REPORT_EVENTS > 0)
90270 +extern const char *eventStrings[];
90271 +#endif /* (REPORT_EVENTS > 0) */
90272 +
90273 +char * ErrTypeStrings (e_ErrorType err);
90274 +
90275 +
90276 +#if ((defined(DEBUG_USING_STATIC_LEVEL)) && (DEBUG_DYNAMIC_LEVEL < REPORT_LEVEL_WARNING))
90277 +/* No need for DBG macro - debug level is higher anyway */
90278 +#define DBG(_level, _vmsg)
90279 +#else
90280 +#define DBG(_level, _vmsg) \
90281 + do { \
90282 + if (REPORT_LEVEL_##_level <= DEBUG_DYNAMIC_LEVEL) { \
90283 + XX_Print("> %s (%s) " PRINT_FORMAT ": ", \
90284 + dbgLevelStrings[REPORT_LEVEL_##_level - 1], \
90285 + moduleStrings[__ERR_MODULE__ >> 16], \
90286 + PRINT_FMT_PARAMS); \
90287 + XX_Print _vmsg; \
90288 + XX_Print("\r\n"); \
90289 + } \
90290 + } while (0)
90291 +#endif /* (defined(DEBUG_USING_STATIC_LEVEL) && (DEBUG_DYNAMIC_LEVEL < WARNING)) */
90292 +
90293 +
90294 +#define REPORT_ERROR(_level, _err, _vmsg) \
90295 + do { \
90296 + if (REPORT_LEVEL_##_level <= ERROR_DYNAMIC_LEVEL) { \
90297 + XX_Print("! %s %s Error " PRINT_FORMAT ": %s; ", \
90298 + dbgLevelStrings[REPORT_LEVEL_##_level - 1], \
90299 + moduleStrings[__ERR_MODULE__ >> 16], \
90300 + PRINT_FMT_PARAMS, \
90301 + ErrTypeStrings((e_ErrorType)GET_ERROR_TYPE(_err))); \
90302 + XX_Print _vmsg; \
90303 + XX_Print("\r\n"); \
90304 + } \
90305 + } while (0)
90306 +
90307 +
90308 +#define RETURN_ERROR(_level, _err, _vmsg) \
90309 + do { \
90310 + REPORT_ERROR(_level, (_err), _vmsg); \
90311 + return ERROR_CODE(_err); \
90312 + } while (0)
90313 +
90314 +
90315 +#if (REPORT_EVENTS > 0)
90316 +
90317 +#define REPORT_EVENT(_ev, _appId, _flg, _vmsg) \
90318 + do { \
90319 + if (_ev##_LEVEL <= EVENT_DYNAMIC_LEVEL) { \
90320 + XX_Print("~ %s %s Event " PRINT_FORMAT ": %s (flags: 0x%04x); ", \
90321 + dbgLevelStrings[_ev##_LEVEL - 1], \
90322 + moduleStrings[__ERR_MODULE__ >> 16], \
90323 + PRINT_FMT_PARAMS, \
90324 + eventStrings[((_ev) - EV_NO_EVENT - 1)], \
90325 + (uint16_t)(_flg)); \
90326 + XX_Print _vmsg; \
90327 + XX_Print("\r\n"); \
90328 + XX_EventById((uint32_t)(_ev), (t_Handle)(_appId), (uint16_t)(_flg), NO_MSG); \
90329 + } \
90330 + } while (0)
90331 +
90332 +#else /* not REPORT_EVENTS */
90333 +
90334 +#define REPORT_EVENT(_ev, _appId, _flg, _vmsg)
90335 +
90336 +#endif /* (REPORT_EVENTS > 0) */
90337 +
90338 +#endif /* (DEBUG_ERRORS > 0) */
90339 +
90340 +
90341 +/**************************************************************************//**
90342 + @Function ASSERT_COND
90343 +
90344 + @Description Assertion macro.
90345 +
90346 + @Param[in] _cond - The condition being checked, in positive form;
90347 + Failure of the condition triggers the assert.
90348 +*//***************************************************************************/
90349 +#ifdef DISABLE_ASSERTIONS
90350 +#define ASSERT_COND(_cond)
90351 +#else
90352 +#define ASSERT_COND(_cond) \
90353 + do { \
90354 + if (!(_cond)) { \
90355 + XX_Print("*** ASSERT_COND failed " PRINT_FORMAT "\r\n", \
90356 + PRINT_FMT_PARAMS); \
90357 + XX_Exit(1); \
90358 + } \
90359 + } while (0)
90360 +#endif /* DISABLE_ASSERTIONS */
90361 +
90362 +
90363 +#ifdef DISABLE_INIT_PARAMETERS_CHECK
90364 +
90365 +#define CHECK_INIT_PARAMETERS(handle, f_check)
90366 +#define CHECK_INIT_PARAMETERS_RETURN_VALUE(handle, f_check, retval)
90367 +
90368 +#else
90369 +
90370 +#define CHECK_INIT_PARAMETERS(handle, f_check) \
90371 + do { \
90372 + t_Error err = f_check(handle); \
90373 + if (err != E_OK) { \
90374 + RETURN_ERROR(MAJOR, err, NO_MSG); \
90375 + } \
90376 + } while (0)
90377 +
90378 +#define CHECK_INIT_PARAMETERS_RETURN_VALUE(handle, f_check, retval) \
90379 + do { \
90380 + t_Error err = f_check(handle); \
90381 + if (err != E_OK) { \
90382 + REPORT_ERROR(MAJOR, err, NO_MSG); \
90383 + return (retval); \
90384 + } \
90385 + } while (0)
90386 +
90387 +#endif /* DISABLE_INIT_PARAMETERS_CHECK */
90388 +
90389 +#ifdef DISABLE_SANITY_CHECKS
90390 +
90391 +#define SANITY_CHECK_RETURN_ERROR(_cond, _err)
90392 +#define SANITY_CHECK_RETURN_VALUE(_cond, _err, retval)
90393 +#define SANITY_CHECK_RETURN(_cond, _err)
90394 +#define SANITY_CHECK_EXIT(_cond, _err)
90395 +
90396 +#else /* DISABLE_SANITY_CHECKS */
90397 +
90398 +#define SANITY_CHECK_RETURN_ERROR(_cond, _err) \
90399 + do { \
90400 + if (!(_cond)) { \
90401 + RETURN_ERROR(CRITICAL, (_err), NO_MSG); \
90402 + } \
90403 + } while (0)
90404 +
90405 +#define SANITY_CHECK_RETURN_VALUE(_cond, _err, retval) \
90406 + do { \
90407 + if (!(_cond)) { \
90408 + REPORT_ERROR(CRITICAL, (_err), NO_MSG); \
90409 + return (retval); \
90410 + } \
90411 + } while (0)
90412 +
90413 +#define SANITY_CHECK_RETURN(_cond, _err) \
90414 + do { \
90415 + if (!(_cond)) { \
90416 + REPORT_ERROR(CRITICAL, (_err), NO_MSG); \
90417 + return; \
90418 + } \
90419 + } while (0)
90420 +
90421 +#define SANITY_CHECK_EXIT(_cond, _err) \
90422 + do { \
90423 + if (!(_cond)) { \
90424 + REPORT_ERROR(CRITICAL, (_err), NO_MSG); \
90425 + XX_Exit(1); \
90426 + } \
90427 + } while (0)
90428 +
90429 +#endif /* DISABLE_SANITY_CHECKS */
90430 +
90431 +/** @} */ /* end of Debug/error Utils group */
90432 +
90433 +/** @} */ /* end of General Utils group */
90434 +
90435 +#endif /* __ERROR_EXT_H */
90436 +
90437 +
90438 --- /dev/null
90439 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/etc/list_ext.h
90440 @@ -0,0 +1,358 @@
90441 +/* Copyright (c) 2008-2012 Freescale Semiconductor, Inc
90442 + * All rights reserved.
90443 + *
90444 + * Redistribution and use in source and binary forms, with or without
90445 + * modification, are permitted provided that the following conditions are met:
90446 + * * Redistributions of source code must retain the above copyright
90447 + * notice, this list of conditions and the following disclaimer.
90448 + * * Redistributions in binary form must reproduce the above copyright
90449 + * notice, this list of conditions and the following disclaimer in the
90450 + * documentation and/or other materials provided with the distribution.
90451 + * * Neither the name of Freescale Semiconductor nor the
90452 + * names of its contributors may be used to endorse or promote products
90453 + * derived from this software without specific prior written permission.
90454 + *
90455 + *
90456 + * ALTERNATIVELY, this software may be distributed under the terms of the
90457 + * GNU General Public License ("GPL") as published by the Free Software
90458 + * Foundation, either version 2 of that License or (at your option) any
90459 + * later version.
90460 + *
90461 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
90462 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
90463 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
90464 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
90465 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
90466 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
90467 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
90468 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
90469 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
90470 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
90471 + */
90472 +
90473 +
90474 +/**************************************************************************//**
90475 +
90476 + @File list_ext.h
90477 +
90478 + @Description External prototypes for list.c
90479 +*//***************************************************************************/
90480 +
90481 +#ifndef __LIST_EXT_H
90482 +#define __LIST_EXT_H
90483 +
90484 +
90485 +#include "std_ext.h"
90486 +
90487 +
90488 +/**************************************************************************//**
90489 + @Group etc_id Utility Library Application Programming Interface
90490 +
90491 + @Description External routines.
90492 +
90493 + @{
90494 +*//***************************************************************************/
90495 +
90496 +/**************************************************************************//**
90497 + @Group list_id List
90498 +
90499 + @Description List module functions,definitions and enums.
90500 +
90501 + @{
90502 +*//***************************************************************************/
90503 +
90504 +/**************************************************************************//**
90505 + @Description List structure.
90506 +*//***************************************************************************/
90507 +typedef struct List
90508 +{
90509 + struct List *p_Next; /**< A pointer to the next list object */
90510 + struct List *p_Prev; /**< A pointer to the previous list object */
90511 +} t_List;
90512 +
90513 +
90514 +/**************************************************************************//**
90515 + @Function LIST_FIRST/LIST_LAST/LIST_NEXT/LIST_PREV
90516 +
90517 + @Description Macro to get first/last/next/previous entry in a list.
90518 +
90519 + @Param[in] p_List - A pointer to a list.
90520 +*//***************************************************************************/
90521 +#define LIST_FIRST(p_List) (p_List)->p_Next
90522 +#define LIST_LAST(p_List) (p_List)->p_Prev
90523 +#define LIST_NEXT LIST_FIRST
90524 +#define LIST_PREV LIST_LAST
90525 +
90526 +
90527 +/**************************************************************************//**
90528 + @Function LIST_INIT
90529 +
90530 + @Description Macro for initialization of a list struct.
90531 +
90532 + @Param[in] lst - The t_List object to initialize.
90533 +*//***************************************************************************/
90534 +#define LIST_INIT(lst) {&(lst), &(lst)}
90535 +
90536 +
90537 +/**************************************************************************//**
90538 + @Function LIST
90539 +
90540 + @Description Macro to declare of a list.
90541 +
90542 + @Param[in] listName - The list object name.
90543 +*//***************************************************************************/
90544 +#define LIST(listName) t_List listName = LIST_INIT(listName)
90545 +
90546 +
90547 +/**************************************************************************//**
90548 + @Function INIT_LIST
90549 +
90550 + @Description Macro to initialize a list pointer.
90551 +
90552 + @Param[in] p_List - The list pointer.
90553 +*//***************************************************************************/
90554 +#define INIT_LIST(p_List) LIST_FIRST(p_List) = LIST_LAST(p_List) = (p_List)
90555 +
90556 +
90557 +/**************************************************************************//**
90558 + @Function LIST_OBJECT
90559 +
90560 + @Description Macro to get the struct (object) for this entry.
90561 +
90562 + @Param[in] type - The type of the struct (object) this list is embedded in.
90563 + @Param[in] member - The name of the t_List object within the struct.
90564 +
90565 + @Return The structure pointer for this entry.
90566 +*//***************************************************************************/
90567 +#define MEMBER_OFFSET(type, member) (PTR_TO_UINT(&((type *)0)->member))
90568 +#define LIST_OBJECT(p_List, type, member) \
90569 + ((type *)((char *)(p_List)-MEMBER_OFFSET(type, member)))
90570 +
90571 +
90572 +/**************************************************************************//**
90573 + @Function LIST_FOR_EACH
90574 +
90575 + @Description Macro to iterate over a list.
90576 +
90577 + @Param[in] p_Pos - A pointer to a list to use as a loop counter.
90578 + @Param[in] p_Head - A pointer to the head for your list pointer.
90579 +
90580 + @Cautions You can't delete items with this routine.
90581 + For deletion use LIST_FOR_EACH_SAFE().
90582 +*//***************************************************************************/
90583 +#define LIST_FOR_EACH(p_Pos, p_Head) \
90584 + for (p_Pos = LIST_FIRST(p_Head); p_Pos != (p_Head); p_Pos = LIST_NEXT(p_Pos))
90585 +
90586 +
90587 +/**************************************************************************//**
90588 + @Function LIST_FOR_EACH_SAFE
90589 +
90590 + @Description Macro to iterate over a list safe against removal of list entry.
90591 +
90592 + @Param[in] p_Pos - A pointer to a list to use as a loop counter.
90593 + @Param[in] p_Tmp - Another pointer to a list to use as temporary storage.
90594 + @Param[in] p_Head - A pointer to the head for your list pointer.
90595 +*//***************************************************************************/
90596 +#define LIST_FOR_EACH_SAFE(p_Pos, p_Tmp, p_Head) \
90597 + for (p_Pos = LIST_FIRST(p_Head), p_Tmp = LIST_FIRST(p_Pos); \
90598 + p_Pos != (p_Head); \
90599 + p_Pos = p_Tmp, p_Tmp = LIST_NEXT(p_Pos))
90600 +
90601 +
90602 +/**************************************************************************//**
90603 + @Function LIST_FOR_EACH_OBJECT_SAFE
90604 +
90605 + @Description Macro to iterate over list of given type safely.
90606 +
90607 + @Param[in] p_Pos - A pointer to a list to use as a loop counter.
90608 + @Param[in] p_Tmp - Another pointer to a list to use as temporary storage.
90609 + @Param[in] type - The type of the struct this is embedded in.
90610 + @Param[in] p_Head - A pointer to the head for your list pointer.
90611 + @Param[in] member - The name of the list_struct within the struct.
90612 +
90613 + @Cautions You can't delete items with this routine.
90614 + For deletion use LIST_FOR_EACH_SAFE().
90615 +*//***************************************************************************/
90616 +#define LIST_FOR_EACH_OBJECT_SAFE(p_Pos, p_Tmp, p_Head, type, member) \
90617 + for (p_Pos = LIST_OBJECT(LIST_FIRST(p_Head), type, member), \
90618 + p_Tmp = LIST_OBJECT(LIST_FIRST(&p_Pos->member), type, member); \
90619 + &p_Pos->member != (p_Head); \
90620 + p_Pos = p_Tmp, \
90621 + p_Tmp = LIST_OBJECT(LIST_FIRST(&p_Pos->member), type, member))
90622 +
90623 +/**************************************************************************//**
90624 + @Function LIST_FOR_EACH_OBJECT
90625 +
90626 + @Description Macro to iterate over list of given type.
90627 +
90628 + @Param[in] p_Pos - A pointer to a list to use as a loop counter.
90629 + @Param[in] type - The type of the struct this is embedded in.
90630 + @Param[in] p_Head - A pointer to the head for your list pointer.
90631 + @Param[in] member - The name of the list_struct within the struct.
90632 +
90633 + @Cautions You can't delete items with this routine.
90634 + For deletion use LIST_FOR_EACH_SAFE().
90635 +*//***************************************************************************/
90636 +#define LIST_FOR_EACH_OBJECT(p_Pos, type, p_Head, member) \
90637 + for (p_Pos = LIST_OBJECT(LIST_FIRST(p_Head), type, member); \
90638 + &p_Pos->member != (p_Head); \
90639 + p_Pos = LIST_OBJECT(LIST_FIRST(&(p_Pos->member)), type, member))
90640 +
90641 +
90642 +/**************************************************************************//**
90643 + @Function LIST_Add
90644 +
90645 + @Description Add a new entry to a list.
90646 +
90647 + Insert a new entry after the specified head.
90648 + This is good for implementing stacks.
90649 +
90650 + @Param[in] p_New - A pointer to a new list entry to be added.
90651 + @Param[in] p_Head - A pointer to a list head to add it after.
90652 +
90653 + @Return none.
90654 +*//***************************************************************************/
90655 +static __inline__ void LIST_Add(t_List *p_New, t_List *p_Head)
90656 +{
90657 + LIST_PREV(LIST_NEXT(p_Head)) = p_New;
90658 + LIST_NEXT(p_New) = LIST_NEXT(p_Head);
90659 + LIST_PREV(p_New) = p_Head;
90660 + LIST_NEXT(p_Head) = p_New;
90661 +}
90662 +
90663 +
90664 +/**************************************************************************//**
90665 + @Function LIST_AddToTail
90666 +
90667 + @Description Add a new entry to a list.
90668 +
90669 + Insert a new entry before the specified head.
90670 + This is useful for implementing queues.
90671 +
90672 + @Param[in] p_New - A pointer to a new list entry to be added.
90673 + @Param[in] p_Head - A pointer to a list head to add it before.
90674 +
90675 + @Return none.
90676 +*//***************************************************************************/
90677 +static __inline__ void LIST_AddToTail(t_List *p_New, t_List *p_Head)
90678 +{
90679 + LIST_NEXT(LIST_PREV(p_Head)) = p_New;
90680 + LIST_PREV(p_New) = LIST_PREV(p_Head);
90681 + LIST_NEXT(p_New) = p_Head;
90682 + LIST_PREV(p_Head) = p_New;
90683 +}
90684 +
90685 +
90686 +/**************************************************************************//**
90687 + @Function LIST_Del
90688 +
90689 + @Description Deletes entry from a list.
90690 +
90691 + @Param[in] p_Entry - A pointer to the element to delete from the list.
90692 +
90693 + @Return none.
90694 +
90695 + @Cautions LIST_IsEmpty() on entry does not return true after this,
90696 + the entry is in an undefined state.
90697 +*//***************************************************************************/
90698 +static __inline__ void LIST_Del(t_List *p_Entry)
90699 +{
90700 + LIST_PREV(LIST_NEXT(p_Entry)) = LIST_PREV(p_Entry);
90701 + LIST_NEXT(LIST_PREV(p_Entry)) = LIST_NEXT(p_Entry);
90702 +}
90703 +
90704 +
90705 +/**************************************************************************//**
90706 + @Function LIST_DelAndInit
90707 +
90708 + @Description Deletes entry from list and reinitialize it.
90709 +
90710 + @Param[in] p_Entry - A pointer to the element to delete from the list.
90711 +
90712 + @Return none.
90713 +*//***************************************************************************/
90714 +static __inline__ void LIST_DelAndInit(t_List *p_Entry)
90715 +{
90716 + LIST_Del(p_Entry);
90717 + INIT_LIST(p_Entry);
90718 +}
90719 +
90720 +
90721 +/**************************************************************************//**
90722 + @Function LIST_Move
90723 +
90724 + @Description Delete from one list and add as another's head.
90725 +
90726 + @Param[in] p_Entry - A pointer to the list entry to move.
90727 + @Param[in] p_Head - A pointer to the list head that will precede our entry.
90728 +
90729 + @Return none.
90730 +*//***************************************************************************/
90731 +static __inline__ void LIST_Move(t_List *p_Entry, t_List *p_Head)
90732 +{
90733 + LIST_Del(p_Entry);
90734 + LIST_Add(p_Entry, p_Head);
90735 +}
90736 +
90737 +
90738 +/**************************************************************************//**
90739 + @Function LIST_MoveToTail
90740 +
90741 + @Description Delete from one list and add as another's tail.
90742 +
90743 + @Param[in] p_Entry - A pointer to the entry to move.
90744 + @Param[in] p_Head - A pointer to the list head that will follow our entry.
90745 +
90746 + @Return none.
90747 +*//***************************************************************************/
90748 +static __inline__ void LIST_MoveToTail(t_List *p_Entry, t_List *p_Head)
90749 +{
90750 + LIST_Del(p_Entry);
90751 + LIST_AddToTail(p_Entry, p_Head);
90752 +}
90753 +
90754 +
90755 +/**************************************************************************//**
90756 + @Function LIST_IsEmpty
90757 +
90758 + @Description Tests whether a list is empty.
90759 +
90760 + @Param[in] p_List - A pointer to the list to test.
90761 +
90762 + @Return 1 if the list is empty, 0 otherwise.
90763 +*//***************************************************************************/
90764 +static __inline__ int LIST_IsEmpty(t_List *p_List)
90765 +{
90766 + return (LIST_FIRST(p_List) == p_List);
90767 +}
90768 +
90769 +
90770 +/**************************************************************************//**
90771 + @Function LIST_Append
90772 +
90773 + @Description Join two lists.
90774 +
90775 + @Param[in] p_NewList - A pointer to the new list to add.
90776 + @Param[in] p_Head - A pointer to the place to add it in the first list.
90777 +
90778 + @Return none.
90779 +*//***************************************************************************/
90780 +void LIST_Append(t_List *p_NewList, t_List *p_Head);
90781 +
90782 +
90783 +/**************************************************************************//**
90784 + @Function LIST_NumOfObjs
90785 +
90786 + @Description Counts number of objects in the list
90787 +
90788 + @Param[in] p_List - A pointer to the list which objects are to be counted.
90789 +
90790 + @Return Number of objects in the list.
90791 +*//***************************************************************************/
90792 +int LIST_NumOfObjs(t_List *p_List);
90793 +
90794 +/** @} */ /* end of list_id group */
90795 +/** @} */ /* end of etc_id group */
90796 +
90797 +
90798 +#endif /* __LIST_EXT_H */
90799 --- /dev/null
90800 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/etc/mem_ext.h
90801 @@ -0,0 +1,318 @@
90802 +/* Copyright (c) 2008-2012 Freescale Semiconductor, Inc
90803 + * All rights reserved.
90804 + *
90805 + * Redistribution and use in source and binary forms, with or without
90806 + * modification, are permitted provided that the following conditions are met:
90807 + * * Redistributions of source code must retain the above copyright
90808 + * notice, this list of conditions and the following disclaimer.
90809 + * * Redistributions in binary form must reproduce the above copyright
90810 + * notice, this list of conditions and the following disclaimer in the
90811 + * documentation and/or other materials provided with the distribution.
90812 + * * Neither the name of Freescale Semiconductor nor the
90813 + * names of its contributors may be used to endorse or promote products
90814 + * derived from this software without specific prior written permission.
90815 + *
90816 + *
90817 + * ALTERNATIVELY, this software may be distributed under the terms of the
90818 + * GNU General Public License ("GPL") as published by the Free Software
90819 + * Foundation, either version 2 of that License or (at your option) any
90820 + * later version.
90821 + *
90822 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
90823 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
90824 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
90825 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
90826 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
90827 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
90828 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
90829 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
90830 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
90831 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
90832 + */
90833 +
90834 +
90835 +/**************************************************************************//**
90836 +
90837 + @File mem_ext.h
90838 +
90839 + @Description External prototypes for the memory manager object
90840 +*//***************************************************************************/
90841 +
90842 +#ifndef __MEM_EXT_H
90843 +#define __MEM_EXT_H
90844 +
90845 +#include "std_ext.h"
90846 +#include "part_ext.h"
90847 +
90848 +
90849 +/**************************************************************************//**
90850 + @Group etc_id Utility Library Application Programming Interface
90851 +
90852 + @Description External routines.
90853 +
90854 + @{
90855 +*//***************************************************************************/
90856 +
90857 +/**************************************************************************//**
90858 + @Group mem_id Slab Memory Manager
90859 +
90860 + @Description Slab Memory Manager module functions, definitions and enums.
90861 +
90862 + @{
90863 +*//***************************************************************************/
90864 +
90865 +/* Each block is of the following structure:
90866 + *
90867 + *
90868 + * +-----------+----------+---------------------------+-----------+-----------+
90869 + * | Alignment | Prefix | Data | Postfix | Alignment |
90870 + * | field | field | field | field | Padding |
90871 + * | | | | | |
90872 + * +-----------+----------+---------------------------+-----------+-----------+
90873 + * and at the beginning of all bytes, an additional optional padding might reside
90874 + * to ensure that the first blocks data field is aligned as requested.
90875 + */
90876 +
90877 +
90878 +#define MEM_MAX_NAME_LENGTH 8
90879 +
90880 +/**************************************************************************//*
90881 + @Description Memory Segment structure
90882 +*//***************************************************************************/
90883 +
90884 +typedef struct
90885 +{
90886 + char name[MEM_MAX_NAME_LENGTH];
90887 + /* The segment's name */
90888 + uint8_t **p_Bases; /* Base addresses of the segments */
90889 + uint8_t **p_BlocksStack; /* Array of pointers to blocks */
90890 + t_Handle h_Spinlock;
90891 + uint16_t dataSize; /* Size of each data block */
90892 + uint16_t prefixSize; /* How many bytes to reserve before the data */
90893 + uint16_t postfixSize; /* How many bytes to reserve after the data */
90894 + uint16_t alignment; /* Requested alignment for the data field */
90895 + int allocOwner; /* Memory allocation owner */
90896 + uint32_t getFailures; /* Number of times get failed */
90897 + uint32_t num; /* Number of blocks in segment */
90898 + uint32_t current; /* Current block */
90899 + bool consecutiveMem; /* Allocate consecutive data blocks memory */
90900 +#ifdef DEBUG_MEM_LEAKS
90901 + void *p_MemDbg; /* MEM debug database (MEM leaks detection) */
90902 + uint32_t blockOffset;
90903 + uint32_t blockSize;
90904 +#endif /* DEBUG_MEM_LEAKS */
90905 +} t_MemorySegment;
90906 +
90907 +
90908 +
90909 +/**************************************************************************//**
90910 + @Function MEM_Init
90911 +
90912 + @Description Create a new memory segment.
90913 +
90914 + @Param[in] name - Name of memory partition.
90915 + @Param[in] p_Handle - Handle to new segment is returned through here.
90916 + @Param[in] num - Number of blocks in new segment.
90917 + @Param[in] dataSize - Size of blocks in segment.
90918 + @Param[in] prefixSize - How many bytes to allocate before the data.
90919 + @Param[in] postfixSize - How many bytes to allocate after the data.
90920 + @Param[in] alignment - Requested alignment for data field (in bytes).
90921 +
90922 + @Return E_OK - success, E_NO_MEMORY - out of memory.
90923 +*//***************************************************************************/
90924 +t_Error MEM_Init(char name[],
90925 + t_Handle *p_Handle,
90926 + uint32_t num,
90927 + uint16_t dataSize,
90928 + uint16_t prefixSize,
90929 + uint16_t postfixSize,
90930 + uint16_t alignment);
90931 +
90932 +/**************************************************************************//**
90933 + @Function MEM_InitSmart
90934 +
90935 + @Description Create a new memory segment.
90936 +
90937 + @Param[in] name - Name of memory partition.
90938 + @Param[in] p_Handle - Handle to new segment is returned through here.
90939 + @Param[in] num - Number of blocks in new segment.
90940 + @Param[in] dataSize - Size of blocks in segment.
90941 + @Param[in] prefixSize - How many bytes to allocate before the data.
90942 + @Param[in] postfixSize - How many bytes to allocate after the data.
90943 + @Param[in] alignment - Requested alignment for data field (in bytes).
90944 + @Param[in] memPartitionId - Memory partition ID for allocation.
90945 + @Param[in] consecutiveMem - Whether to allocate the memory blocks
90946 + continuously or not.
90947 +
90948 + @Return E_OK - success, E_NO_MEMORY - out of memory.
90949 +*//***************************************************************************/
90950 +t_Error MEM_InitSmart(char name[],
90951 + t_Handle *p_Handle,
90952 + uint32_t num,
90953 + uint16_t dataSize,
90954 + uint16_t prefixSize,
90955 + uint16_t postfixSize,
90956 + uint16_t alignment,
90957 + uint8_t memPartitionId,
90958 + bool consecutiveMem);
90959 +
90960 +/**************************************************************************//**
90961 + @Function MEM_InitByAddress
90962 +
90963 + @Description Create a new memory segment with a specified base address.
90964 +
90965 + @Param[in] name - Name of memory partition.
90966 + @Param[in] p_Handle - Handle to new segment is returned through here.
90967 + @Param[in] num - Number of blocks in new segment.
90968 + @Param[in] dataSize - Size of blocks in segment.
90969 + @Param[in] prefixSize - How many bytes to allocate before the data.
90970 + @Param[in] postfixSize - How many bytes to allocate after the data.
90971 + @Param[in] alignment - Requested alignment for data field (in bytes).
90972 + @Param[in] address - The required base address.
90973 +
90974 + @Return E_OK - success, E_NO_MEMORY - out of memory.
90975 + *//***************************************************************************/
90976 +t_Error MEM_InitByAddress(char name[],
90977 + t_Handle *p_Handle,
90978 + uint32_t num,
90979 + uint16_t dataSize,
90980 + uint16_t prefixSize,
90981 + uint16_t postfixSize,
90982 + uint16_t alignment,
90983 + uint8_t *address);
90984 +
90985 +/**************************************************************************//**
90986 + @Function MEM_Free
90987 +
90988 + @Description Free a specific memory segment.
90989 +
90990 + @Param[in] h_Mem - Handle to memory segment.
90991 +
90992 + @Return None.
90993 +*//***************************************************************************/
90994 +void MEM_Free(t_Handle h_Mem);
90995 +
90996 +/**************************************************************************//**
90997 + @Function MEM_Get
90998 +
90999 + @Description Get a block of memory from a segment.
91000 +
91001 + @Param[in] h_Mem - Handle to memory segment.
91002 +
91003 + @Return Pointer to new memory block on success,0 otherwise.
91004 +*//***************************************************************************/
91005 +void * MEM_Get(t_Handle h_Mem);
91006 +
91007 +/**************************************************************************//**
91008 + @Function MEM_GetN
91009 +
91010 + @Description Get up to N blocks of memory from a segment.
91011 +
91012 + The blocks are assumed to be of a fixed size (one size per segment).
91013 +
91014 + @Param[in] h_Mem - Handle to memory segment.
91015 + @Param[in] num - Number of blocks to allocate.
91016 + @Param[out] array - Array of at least num pointers to which the addresses
91017 + of the allocated blocks are written.
91018 +
91019 + @Return The number of blocks actually allocated.
91020 +
91021 + @Cautions Interrupts are disabled for all of the allocation loop.
91022 + Although this loop is very short for each block (several machine
91023 + instructions), you should not allocate a very large number
91024 + of blocks via this routine.
91025 +*//***************************************************************************/
91026 +uint16_t MEM_GetN(t_Handle h_Mem, uint32_t num, void *array[]);
91027 +
91028 +/**************************************************************************//**
91029 + @Function MEM_Put
91030 +
91031 + @Description Put a block of memory back to a segment.
91032 +
91033 + @Param[in] h_Mem - Handle to memory segment.
91034 + @Param[in] p_Block - The block to return.
91035 +
91036 + @Return Pointer to new memory block on success,0 otherwise.
91037 +*//***************************************************************************/
91038 +t_Error MEM_Put(t_Handle h_Mem, void *p_Block);
91039 +
91040 +/**************************************************************************//**
91041 + @Function MEM_ComputePartitionSize
91042 +
91043 + @Description calculate a tight upper boundary of the size of a partition with
91044 + given attributes.
91045 +
91046 + The returned value is suitable if one wants to use MEM_InitByAddress().
91047 +
91048 + @Param[in] num - The number of blocks in the segment.
91049 + @Param[in] dataSize - Size of block to get.
91050 + @Param[in] prefixSize - The prefix size
91051 + @Param postfixSize - The postfix size
91052 + @Param[in] alignment - The requested alignment value (in bytes)
91053 +
91054 + @Return The memory block size a segment with the given attributes needs.
91055 +*//***************************************************************************/
91056 +uint32_t MEM_ComputePartitionSize(uint32_t num,
91057 + uint16_t dataSize,
91058 + uint16_t prefixSize,
91059 + uint16_t postfixSize,
91060 + uint16_t alignment);
91061 +
91062 +#ifdef DEBUG_MEM_LEAKS
91063 +#if !((defined(__MWERKS__) || defined(__GNUC__)) && (__dest_os == __ppc_eabi))
91064 +#error "Memory-Leaks-Debug option is supported only for freescale CodeWarrior"
91065 +#endif /* !(defined(__MWERKS__) && ... */
91066 +
91067 +/**************************************************************************//**
91068 + @Function MEM_CheckLeaks
91069 +
91070 + @Description Report MEM object leaks.
91071 +
91072 + This routine is automatically called by the MEM_Free() routine,
91073 + but it can also be invoked while the MEM object is alive.
91074 +
91075 + @Param[in] h_Mem - Handle to memory segment.
91076 +
91077 + @Return None.
91078 +*//***************************************************************************/
91079 +void MEM_CheckLeaks(t_Handle h_Mem);
91080 +
91081 +#else /* not DEBUG_MEM_LEAKS */
91082 +#define MEM_CheckLeaks(h_Mem)
91083 +#endif /* not DEBUG_MEM_LEAKS */
91084 +
91085 +/**************************************************************************//**
91086 + @Description Get base of MEM
91087 +*//***************************************************************************/
91088 +#define MEM_GetBase(h_Mem) ((t_MemorySegment *)(h_Mem))->p_Bases[0]
91089 +
91090 +/**************************************************************************//**
91091 + @Description Get size of MEM block
91092 +*//***************************************************************************/
91093 +#define MEM_GetSize(h_Mem) ((t_MemorySegment *)(h_Mem))->dataSize
91094 +
91095 +/**************************************************************************//**
91096 + @Description Get prefix size of MEM block
91097 +*//***************************************************************************/
91098 +#define MEM_GetPrefixSize(h_Mem) ((t_MemorySegment *)(h_Mem))->prefixSize
91099 +
91100 +/**************************************************************************//**
91101 + @Description Get postfix size of MEM block
91102 +*//***************************************************************************/
91103 +#define MEM_GetPostfixSize(h_Mem) ((t_MemorySegment *)(h_Mem))->postfixSize
91104 +
91105 +/**************************************************************************//**
91106 + @Description Get alignment of MEM block (in bytes)
91107 +*//***************************************************************************/
91108 +#define MEM_GetAlignment(h_Mem) ((t_MemorySegment *)(h_Mem))->alignment
91109 +
91110 +/**************************************************************************//**
91111 + @Description Get the number of blocks in the segment
91112 +*//***************************************************************************/
91113 +#define MEM_GetNumOfBlocks(h_Mem) ((t_MemorySegment *)(h_Mem))->num
91114 +
91115 +/** @} */ /* end of MEM group */
91116 +/** @} */ /* end of etc_id group */
91117 +
91118 +
91119 +#endif /* __MEM_EXT_H */
91120 --- /dev/null
91121 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/etc/memcpy_ext.h
91122 @@ -0,0 +1,208 @@
91123 +/* Copyright (c) 2008-2012 Freescale Semiconductor, Inc
91124 + * All rights reserved.
91125 + *
91126 + * Redistribution and use in source and binary forms, with or without
91127 + * modification, are permitted provided that the following conditions are met:
91128 + * * Redistributions of source code must retain the above copyright
91129 + * notice, this list of conditions and the following disclaimer.
91130 + * * Redistributions in binary form must reproduce the above copyright
91131 + * notice, this list of conditions and the following disclaimer in the
91132 + * documentation and/or other materials provided with the distribution.
91133 + * * Neither the name of Freescale Semiconductor nor the
91134 + * names of its contributors may be used to endorse or promote products
91135 + * derived from this software without specific prior written permission.
91136 + *
91137 + *
91138 + * ALTERNATIVELY, this software may be distributed under the terms of the
91139 + * GNU General Public License ("GPL") as published by the Free Software
91140 + * Foundation, either version 2 of that License or (at your option) any
91141 + * later version.
91142 + *
91143 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
91144 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
91145 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
91146 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
91147 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
91148 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
91149 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
91150 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
91151 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
91152 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
91153 + */
91154 +
91155 +
91156 +/**************************************************************************//**
91157 +
91158 + @File memcpy_ext.h
91159 +
91160 + @Description Efficient functions for copying and setting blocks of memory.
91161 +*//***************************************************************************/
91162 +
91163 +#ifndef __MEMCPY_EXT_H
91164 +#define __MEMCPY_EXT_H
91165 +
91166 +#include "std_ext.h"
91167 +
91168 +
91169 +/**************************************************************************//**
91170 + @Group etc_id Utility Library Application Programming Interface
91171 +
91172 + @Description External routines.
91173 +
91174 + @{
91175 +*//***************************************************************************/
91176 +
91177 +/**************************************************************************//**
91178 + @Group mem_cpy Memory Copy
91179 +
91180 + @Description Memory Copy module functions,definitions and enums.
91181 +
91182 + @{
91183 +*//***************************************************************************/
91184 +
91185 +/**************************************************************************//**
91186 + @Function MemCpy32
91187 +
91188 + @Description Copies one memory buffer into another one in 4-byte chunks!
91189 + Which should be more efficient than byte by byte.
91190 +
91191 + For large buffers (over 60 bytes) this function is about 4 times
91192 + more efficient than the trivial memory copy. For short buffers
91193 + it is reduced to the trivial copy and may be a bit worse.
91194 +
91195 + @Param[in] pDst - The address of the destination buffer.
91196 + @Param[in] pSrc - The address of the source buffer.
91197 + @Param[in] size - The number of bytes that will be copied from pSrc to pDst.
91198 +
91199 + @Return pDst (the address of the destination buffer).
91200 +
91201 + @Cautions There is no parameter or boundary checking! It is up to the user
91202 + to supply non-null parameters as source & destination and size
91203 + that actually fits into the destination buffer.
91204 +*//***************************************************************************/
91205 +void * MemCpy32(void* pDst,void* pSrc, uint32_t size);
91206 +void * IO2IOCpy32(void* pDst,void* pSrc, uint32_t size);
91207 +void * IO2MemCpy32(void* pDst,void* pSrc, uint32_t size);
91208 +void * Mem2IOCpy32(void* pDst,void* pSrc, uint32_t size);
91209 +
91210 +/**************************************************************************//**
91211 + @Function MemCpy64
91212 +
91213 + @Description Copies one memory buffer into another one in 8-byte chunks!
91214 + Which should be more efficient than byte by byte.
91215 +
91216 + For large buffers (over 60 bytes) this function is about 8 times
91217 + more efficient than the trivial memory copy. For short buffers
91218 + it is reduced to the trivial copy and may be a bit worse.
91219 +
91220 + Some testing suggests that MemCpy32() preforms better than
91221 + MemCpy64() over small buffers. On average they break even at
91222 + 100 byte buffers. For buffers larger than that MemCpy64 is
91223 + superior.
91224 +
91225 + @Param[in] pDst - The address of the destination buffer.
91226 + @Param[in] pSrc - The address of the source buffer.
91227 + @Param[in] size - The number of bytes that will be copied from pSrc to pDst.
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 parameters as source & destination and size
91233 + that actually fits into their buffer.
91234 +
91235 + Do not use under Linux.
91236 +*//***************************************************************************/
91237 +void * MemCpy64(void* pDst,void* pSrc, uint32_t size);
91238 +
91239 +/**************************************************************************//**
91240 + @Function MemSet32
91241 +
91242 + @Description Sets all bytes of a memory buffer to a specific value, in
91243 + 4-byte chunks.
91244 +
91245 + @Param[in] pDst - The address of the destination buffer.
91246 + @Param[in] val - Value to set destination bytes to.
91247 + @Param[in] size - The number of bytes that will be set to val.
91248 +
91249 + @Return pDst (the address of the destination buffer).
91250 +
91251 + @Cautions There is no parameter or boundary checking! It is up to the user
91252 + to supply non null parameter as destination and size
91253 + that actually fits into the destination buffer.
91254 +*//***************************************************************************/
91255 +void * MemSet32(void* pDst, uint8_t val, uint32_t size);
91256 +void * IOMemSet32(void* pDst, uint8_t val, uint32_t size);
91257 +
91258 +/**************************************************************************//**
91259 + @Function MemSet64
91260 +
91261 + @Description Sets all bytes of a memory buffer to a specific value, in
91262 + 8-byte chunks.
91263 +
91264 + @Param[in] pDst - The address of the destination buffer.
91265 + @Param[in] val - Value to set destination bytes to.
91266 + @Param[in] size - The number of bytes that will be set to val.
91267 +
91268 + @Return pDst (the address of the destination buffer).
91269 +
91270 + @Cautions There is no parameter or boundary checking! It is up to the user
91271 + to supply non null parameter as destination and size
91272 + that actually fits into the destination buffer.
91273 +*//***************************************************************************/
91274 +void * MemSet64(void* pDst, uint8_t val, uint32_t size);
91275 +
91276 +/**************************************************************************//**
91277 + @Function MemDisp
91278 +
91279 + @Description Displays a block of memory in chunks of 32 bits.
91280 +
91281 + @Param[in] addr - The address of the memory to display.
91282 + @Param[in] size - The number of bytes that will be displayed.
91283 +
91284 + @Return None.
91285 +
91286 + @Cautions There is no parameter or boundary checking! It is up to the user
91287 + to supply non null parameter as destination and size
91288 + that actually fits into the destination buffer.
91289 +*//***************************************************************************/
91290 +void MemDisp(uint8_t *addr, int size);
91291 +
91292 +/**************************************************************************//**
91293 + @Function MemCpy8
91294 +
91295 + @Description Trivial copy one memory buffer into another byte by byte
91296 +
91297 + @Param[in] pDst - The address of the destination buffer.
91298 + @Param[in] pSrc - The address of the source buffer.
91299 + @Param[in] size - The number of bytes that will be copied from pSrc to pDst.
91300 +
91301 + @Return pDst (the address of the destination buffer).
91302 +
91303 + @Cautions There is no parameter or boundary checking! It is up to the user
91304 + to supply non-null parameters as source & destination and size
91305 + that actually fits into the destination buffer.
91306 +*//***************************************************************************/
91307 +void * MemCpy8(void* pDst,void* pSrc, uint32_t size);
91308 +
91309 +/**************************************************************************//**
91310 + @Function MemSet8
91311 +
91312 + @Description Sets all bytes of a memory buffer to a specific value byte by byte.
91313 +
91314 + @Param[in] pDst - The address of the destination buffer.
91315 + @Param[in] c - Value to set destination bytes to.
91316 + @Param[in] size - The number of bytes that will be set to val.
91317 +
91318 + @Return pDst (the address of the destination buffer).
91319 +
91320 + @Cautions There is no parameter or boundary checking! It is up to the user
91321 + to supply non null parameter as destination and size
91322 + that actually fits into the destination buffer.
91323 +*//***************************************************************************/
91324 +void * MemSet8(void* pDst, int c, uint32_t size);
91325 +
91326 +/** @} */ /* end of mem_cpy group */
91327 +/** @} */ /* end of etc_id group */
91328 +
91329 +
91330 +#endif /* __MEMCPY_EXT_H */
91331 --- /dev/null
91332 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/etc/mm_ext.h
91333 @@ -0,0 +1,310 @@
91334 +/* Copyright (c) 2008-2012 Freescale Semiconductor, Inc
91335 + * All rights reserved.
91336 + *
91337 + * Redistribution and use in source and binary forms, with or without
91338 + * modification, are permitted provided that the following conditions are met:
91339 + * * Redistributions of source code must retain the above copyright
91340 + * notice, this list of conditions and the following disclaimer.
91341 + * * Redistributions in binary form must reproduce the above copyright
91342 + * notice, this list of conditions and the following disclaimer in the
91343 + * documentation and/or other materials provided with the distribution.
91344 + * * Neither the name of Freescale Semiconductor nor the
91345 + * names of its contributors may be used to endorse or promote products
91346 + * derived from this software without specific prior written permission.
91347 + *
91348 + *
91349 + * ALTERNATIVELY, this software may be distributed under the terms of the
91350 + * GNU General Public License ("GPL") as published by the Free Software
91351 + * Foundation, either version 2 of that License or (at your option) any
91352 + * later version.
91353 + *
91354 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
91355 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
91356 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
91357 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
91358 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
91359 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
91360 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
91361 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
91362 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
91363 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
91364 + */
91365 +
91366 +
91367 +/**************************************************************************//**
91368 + @File mm_ext.h
91369 +
91370 + @Description Memory Manager Application Programming Interface
91371 +*//***************************************************************************/
91372 +#ifndef __MM_EXT
91373 +#define __MM_EXT
91374 +
91375 +#include "std_ext.h"
91376 +
91377 +#define MM_MAX_ALIGNMENT 20 /* Alignments from 2 to 128 are available
91378 + where maximum alignment defined as
91379 + MM_MAX_ALIGNMENT power of 2 */
91380 +
91381 +#define MM_MAX_NAME_LEN 32
91382 +
91383 +/**************************************************************************//**
91384 + @Group etc_id Utility Library Application Programming Interface
91385 +
91386 + @Description External routines.
91387 +
91388 + @{
91389 +*//***************************************************************************/
91390 +
91391 +/**************************************************************************//**
91392 + @Group mm_grp Flexible Memory Manager
91393 +
91394 + @Description Flexible Memory Manager module functions,definitions and enums.
91395 + (All of the following functions,definitions and enums can be found in mm_ext.h)
91396 +
91397 + @{
91398 +*//***************************************************************************/
91399 +
91400 +
91401 +/**************************************************************************//**
91402 + @Function MM_Init
91403 +
91404 + @Description Initializes a new MM object.
91405 +
91406 + It initializes a new memory block consisting of base address
91407 + and size of the available memory by calling to MemBlock_Init
91408 + routine. It is also initializes a new free block for each
91409 + by calling FreeBlock_Init routine, which is pointed to
91410 + the almost all memory started from the required alignment
91411 + from the base address and to the end of the memory.
91412 + The handle to the new MM object is returned via "MM"
91413 + argument (passed by reference).
91414 +
91415 + @Param[in] h_MM - Handle to the MM object.
91416 + @Param[in] base - Base address of the MM.
91417 + @Param[in] size - Size of the MM.
91418 +
91419 + @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.
91420 +*//***************************************************************************/
91421 +t_Error MM_Init(t_Handle *h_MM, uint64_t base, uint64_t size);
91422 +
91423 +/**************************************************************************//**
91424 + @Function MM_Get
91425 +
91426 + @Description Allocates a block of memory according to the given size and the alignment.
91427 +
91428 + The Alignment argument tells from which
91429 + free list allocate a block of memory. 2^alignment indicates
91430 + the alignment that the base address of the allocated block
91431 + should have. So, the only values 1, 2, 4, 8, 16, 32 and 64
91432 + are available for the alignment argument.
91433 + The routine passes through the specific free list of free
91434 + blocks and seeks for a first block that have anough memory
91435 + that is required (best fit).
91436 + After the block is found and data is allocated, it calls
91437 + the internal MM_CutFree routine to update all free lists
91438 + do not include a just allocated block. Of course, each
91439 + free list contains a free blocks with the same alignment.
91440 + It is also creates a busy block that holds
91441 + information about an allocated block.
91442 +
91443 + @Param[in] h_MM - Handle to the MM object.
91444 + @Param[in] size - Size of the MM.
91445 + @Param[in] alignment - Index as a power of two defines a required
91446 + alignment (in bytes); Should be 1, 2, 4, 8, 16, 32 or 64
91447 + @Param[in] name - The name that specifies an allocated block.
91448 +
91449 + @Return base address of an allocated block ILLEGAL_BASE if can't allocate a block
91450 +*//***************************************************************************/
91451 +uint64_t MM_Get(t_Handle h_MM, uint64_t size, uint64_t alignment, char *name);
91452 +
91453 +/**************************************************************************//**
91454 + @Function MM_GetBase
91455 +
91456 + @Description Gets the base address of the required MM objects.
91457 +
91458 + @Param[in] h_MM - Handle to the MM object.
91459 +
91460 + @Return base address of the block.
91461 +*//***************************************************************************/
91462 +uint64_t MM_GetBase(t_Handle h_MM);
91463 +
91464 +/**************************************************************************//**
91465 + @Function MM_GetForce
91466 +
91467 + @Description Force memory allocation.
91468 +
91469 + It means to allocate a block of memory of the given
91470 + size from the given base address.
91471 + The routine checks if the required block can be allocated
91472 + (that is it is free) and then, calls the internal MM_CutFree
91473 + routine to update all free lists do not include that block.
91474 +
91475 + @Param[in] h_MM - Handle to the MM object.
91476 + @Param[in] base - Base address of the MM.
91477 + @Param[in] size - Size of the MM.
91478 + @Param[in] name - Name that specifies an allocated block.
91479 +
91480 + @Return base address of an allocated block, ILLEGAL_BASE if can't allocate a block.
91481 +*//***************************************************************************/
91482 +uint64_t MM_GetForce(t_Handle h_MM, uint64_t base, uint64_t size, char *name);
91483 +
91484 +/**************************************************************************//**
91485 + @Function MM_GetForceMin
91486 +
91487 + @Description Allocates a block of memory according to the given size, the alignment and minimum base address.
91488 +
91489 + The Alignment argument tells from which
91490 + free list allocate a block of memory. 2^alignment indicates
91491 + the alignment that the base address of the allocated block
91492 + should have. So, the only values 1, 2, 4, 8, 16, 32 and 64
91493 + are available for the alignment argument.
91494 + The minimum baser address forces the location of the block
91495 + to be from a given address onward.
91496 + The routine passes through the specific free list of free
91497 + blocks and seeks for the first base address equal or smaller
91498 + than the required minimum address and end address larger than
91499 + than the required base + its size - i.e. that may contain
91500 + the required block.
91501 + After the block is found and data is allocated, it calls
91502 + the internal MM_CutFree routine to update all free lists
91503 + do not include a just allocated block. Of course, each
91504 + free list contains a free blocks with the same alignment.
91505 + It is also creates a busy block that holds
91506 + information about an allocated block.
91507 +
91508 + @Param[in] h_MM - Handle to the MM object.
91509 + @Param[in] size - Size of the MM.
91510 + @Param[in] alignment - Index as a power of two defines a required
91511 + alignment (in bytes); Should be 1, 2, 4, 8, 16, 32 or 64
91512 + @Param[in] min - The minimum base address of the block.
91513 + @Param[in] name - Name that specifies an allocated block.
91514 +
91515 + @Return base address of an allocated block,ILLEGAL_BASE if can't allocate a block.
91516 +*//***************************************************************************/
91517 +uint64_t MM_GetForceMin(t_Handle h_MM,
91518 + uint64_t size,
91519 + uint64_t alignment,
91520 + uint64_t min,
91521 + char *name);
91522 +
91523 +/**************************************************************************//**
91524 + @Function MM_Put
91525 +
91526 + @Description Puts a block of memory of the given base address back to the memory.
91527 +
91528 + It checks if there is a busy block with the
91529 + given base address. If not, it returns 0, that
91530 + means can't free a block. Otherwise, it gets parameters of
91531 + the busy block and after it updates lists of free blocks,
91532 + removes that busy block from the list by calling to MM_CutBusy
91533 + routine.
91534 + After that it calls to MM_AddFree routine to add a new free
91535 + block to the free lists.
91536 +
91537 + @Param[in] h_MM - Handle to the MM object.
91538 + @Param[in] base - Base address of the MM.
91539 +
91540 + @Return The size of bytes released, 0 if failed.
91541 +*//***************************************************************************/
91542 +uint64_t MM_Put(t_Handle h_MM, uint64_t base);
91543 +
91544 +/**************************************************************************//**
91545 + @Function MM_PutForce
91546 +
91547 + @Description Releases a block of memory of the required size from the required base address.
91548 +
91549 + First, it calls to MM_CutBusy routine
91550 + to cut a free block from the busy list. And then, calls to
91551 + MM_AddFree routine to add the free block to the free lists.
91552 +
91553 + @Param[in] h_MM - Handle to the MM object.
91554 + @Param[in] base - Base address of of a block to free.
91555 + @Param[in] size - Size of a block to free.
91556 +
91557 + @Return The number of bytes released, 0 on failure.
91558 +*//***************************************************************************/
91559 +uint64_t MM_PutForce(t_Handle h_MM, uint64_t base, uint64_t size);
91560 +
91561 +/**************************************************************************//**
91562 + @Function MM_Add
91563 +
91564 + @Description Adds a new memory block for memory allocation.
91565 +
91566 + When a new memory block is initialized and added to the
91567 + memory list, it calls to MM_AddFree routine to add the
91568 + new free block to the free lists.
91569 +
91570 + @Param[in] h_MM - Handle to the MM object.
91571 + @Param[in] base - Base address of the memory block.
91572 + @Param[in] size - Size of the memory block.
91573 +
91574 + @Return E_OK on success, otherwise returns an error code.
91575 +*//***************************************************************************/
91576 +t_Error MM_Add(t_Handle h_MM, uint64_t base, uint64_t size);
91577 +
91578 +/**************************************************************************//**
91579 + @Function MM_Dump
91580 +
91581 + @Description Prints results of free and busy lists.
91582 +
91583 + @Param[in] h_MM - Handle to the MM object.
91584 +*//***************************************************************************/
91585 +void MM_Dump(t_Handle h_MM);
91586 +
91587 +/**************************************************************************//**
91588 + @Function MM_Free
91589 +
91590 + @Description Releases memory allocated for MM object.
91591 +
91592 + @Param[in] h_MM - Handle of the MM object.
91593 +*//***************************************************************************/
91594 +void MM_Free(t_Handle h_MM);
91595 +
91596 +/**************************************************************************//**
91597 + @Function MM_GetMemBlock
91598 +
91599 + @Description Returns base address of the memory block specified by the index.
91600 +
91601 + If index is 0, returns base address
91602 + of the first memory block, 1 - returns base address
91603 + of the second memory block, etc.
91604 + Note, those memory blocks are allocated by the
91605 + application before MM_Init or MM_Add and have to
91606 + be released by the application before or after invoking
91607 + the MM_Free routine.
91608 +
91609 + @Param[in] h_MM - Handle to the MM object.
91610 + @Param[in] index - Index of the memory block.
91611 +
91612 + @Return valid base address or ILLEGAL_BASE if no memory block specified by the index.
91613 +*//***************************************************************************/
91614 +uint64_t MM_GetMemBlock(t_Handle h_MM, int index);
91615 +
91616 +/**************************************************************************//**
91617 + @Function MM_InRange
91618 +
91619 + @Description Checks if a specific address is in the memory range of the passed MM object.
91620 +
91621 + @Param[in] h_MM - Handle to the MM object.
91622 + @Param[in] addr - The address to be checked.
91623 +
91624 + @Return TRUE if the address is in the address range of the block, FALSE otherwise.
91625 +*//***************************************************************************/
91626 +bool MM_InRange(t_Handle h_MM, uint64_t addr);
91627 +
91628 +/**************************************************************************//**
91629 + @Function MM_GetFreeMemSize
91630 +
91631 + @Description Returns the size (in bytes) of free memory.
91632 +
91633 + @Param[in] h_MM - Handle to the MM object.
91634 +
91635 + @Return Free memory size in bytes.
91636 +*//***************************************************************************/
91637 +uint64_t MM_GetFreeMemSize(t_Handle h_MM);
91638 +
91639 +
91640 +/** @} */ /* end of mm_grp group */
91641 +/** @} */ /* end of etc_id group */
91642 +
91643 +#endif /* __MM_EXT_H */
91644 --- /dev/null
91645 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/etc/sprint_ext.h
91646 @@ -0,0 +1,118 @@
91647 +/* Copyright (c) 2008-2012 Freescale Semiconductor, Inc
91648 + * All rights reserved.
91649 + *
91650 + * Redistribution and use in source and binary forms, with or without
91651 + * modification, are permitted provided that the following conditions are met:
91652 + * * Redistributions of source code must retain the above copyright
91653 + * notice, this list of conditions and the following disclaimer.
91654 + * * Redistributions in binary form must reproduce the above copyright
91655 + * notice, this list of conditions and the following disclaimer in the
91656 + * documentation and/or other materials provided with the distribution.
91657 + * * Neither the name of Freescale Semiconductor nor the
91658 + * names of its contributors may be used to endorse or promote products
91659 + * derived from this software without specific prior written permission.
91660 + *
91661 + *
91662 + * ALTERNATIVELY, this software may be distributed under the terms of the
91663 + * GNU General Public License ("GPL") as published by the Free Software
91664 + * Foundation, either version 2 of that License or (at your option) any
91665 + * later version.
91666 + *
91667 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
91668 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
91669 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
91670 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
91671 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
91672 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
91673 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
91674 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
91675 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
91676 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
91677 + */
91678 +
91679 +
91680 +/**************************************************************************//**
91681 + @File sprint_ext.h
91682 +
91683 + @Description Debug routines (externals).
91684 +
91685 +*//***************************************************************************/
91686 +
91687 +#ifndef __SPRINT_EXT_H
91688 +#define __SPRINT_EXT_H
91689 +
91690 +
91691 +#if defined(NCSW_LINUX) && defined(__KERNEL__)
91692 +#include <linux/kernel.h>
91693 +
91694 +#elif defined(NCSW_VXWORKS)
91695 +#include "private/stdioP.h"
91696 +
91697 +#else
91698 +#include <stdio.h>
91699 +#endif /* defined(NCSW_LINUX) && defined(__KERNEL__) */
91700 +
91701 +#include "std_ext.h"
91702 +
91703 +
91704 +/**************************************************************************//**
91705 + @Group etc_id Utility Library Application Programming Interface
91706 +
91707 + @Description External routines.
91708 +
91709 + @{
91710 +*//***************************************************************************/
91711 +
91712 +/**************************************************************************//**
91713 + @Group sprint_id Sprint
91714 +
91715 + @Description Sprint & Sscan module functions,definitions and enums.
91716 +
91717 + @{
91718 +*//***************************************************************************/
91719 +
91720 +/**************************************************************************//**
91721 + @Function Sprint
91722 +
91723 + @Description Format a string and place it in a buffer.
91724 +
91725 + @Param[in] buff - The buffer to place the result into.
91726 + @Param[in] str - The format string to use.
91727 + @Param[in] ... - Arguments for the format string.
91728 +
91729 + @Return Number of bytes formatted.
91730 +*//***************************************************************************/
91731 +int Sprint(char *buff, const char *str, ...);
91732 +
91733 +/**************************************************************************//**
91734 + @Function Snprint
91735 +
91736 + @Description Format a string and place it in a buffer.
91737 +
91738 + @Param[in] buf - The buffer to place the result into.
91739 + @Param[in] size - The size of the buffer, including the trailing null space.
91740 + @Param[in] fmt - The format string to use.
91741 + @Param[in] ... - Arguments for the format string.
91742 +
91743 + @Return Number of bytes formatted.
91744 +*//***************************************************************************/
91745 +int Snprint(char * buf, uint32_t size, const char *fmt, ...);
91746 +
91747 +/**************************************************************************//**
91748 + @Function Sscan
91749 +
91750 + @Description Unformat a buffer into a list of arguments.
91751 +
91752 + @Param[in] buf - input buffer.
91753 + @Param[in] fmt - formatting of buffer.
91754 + @Param[out] ... - resulting arguments.
91755 +
91756 + @Return Number of bytes unformatted.
91757 +*//***************************************************************************/
91758 +int Sscan(const char * buf, const char * fmt, ...);
91759 +
91760 +/** @} */ /* end of sprint_id group */
91761 +/** @} */ /* end of etc_id group */
91762 +
91763 +
91764 +#endif /* __SPRINT_EXT_H */
91765 --- /dev/null
91766 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/flib/common/arch/ppc_access.h
91767 @@ -0,0 +1,37 @@
91768 +/*
91769 + * Copyright 2008-2012 Freescale Semiconductor Inc.
91770 + *
91771 + * Redistribution and use in source and binary forms, with or without
91772 + * modification, are permitted provided that the following conditions are met:
91773 + * * Redistributions of source code must retain the above copyright
91774 + * notice, this list of conditions and the following disclaimer.
91775 + * * Redistributions in binary form must reproduce the above copyright
91776 + * notice, this list of conditions and the following disclaimer in the
91777 + * documentation and/or other materials provided with the distribution.
91778 + * * Neither the name of Freescale Semiconductor nor the
91779 + * names of its contributors may be used to endorse or promote products
91780 + * derived from this software without specific prior written permission.
91781 + *
91782 + *
91783 + * ALTERNATIVELY, this software may be distributed under the terms of the
91784 + * GNU General Public License ("GPL") as published by the Free Software
91785 + * Foundation, either version 2 of that License or (at your option) any
91786 + * later version.
91787 + *
91788 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
91789 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
91790 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
91791 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
91792 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
91793 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
91794 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
91795 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
91796 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
91797 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
91798 + */
91799 +
91800 +#ifndef FL_E500_MACROS_H
91801 +#define FL_E500_MACROS_H
91802 +
91803 +#endif /* FL_E500_MACROS_H */
91804 +
91805 --- /dev/null
91806 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/flib/common/general.h
91807 @@ -0,0 +1,52 @@
91808 +/*
91809 + * Copyright 2008-2012 Freescale Semiconductor Inc.
91810 + *
91811 + * Redistribution and use in source and binary forms, with or without
91812 + * modification, are permitted provided that the following conditions are met:
91813 + * * Redistributions of source code must retain the above copyright
91814 + * notice, this list of conditions and the following disclaimer.
91815 + * * Redistributions in binary form must reproduce the above copyright
91816 + * notice, this list of conditions and the following disclaimer in the
91817 + * documentation and/or other materials provided with the distribution.
91818 + * * Neither the name of Freescale Semiconductor nor the
91819 + * names of its contributors may be used to endorse or promote products
91820 + * derived from this software without specific prior written permission.
91821 + *
91822 + *
91823 + * ALTERNATIVELY, this software may be distributed under the terms of the
91824 + * GNU General Public License ("GPL") as published by the Free Software
91825 + * Foundation, either version 2 of that License or (at your option) any
91826 + * later version.
91827 + *
91828 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
91829 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
91830 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
91831 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
91832 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
91833 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
91834 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
91835 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
91836 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
91837 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
91838 + */
91839 +
91840 +#ifndef __GENERAL_H
91841 +#define __GENERAL_H
91842 +
91843 +#include "std_ext.h"
91844 +#if !defined(NCSW_LINUX)
91845 +#include "errno.h"
91846 +#endif
91847 +
91848 +
91849 +extern uint32_t get_mac_addr_crc(uint64_t _addr);
91850 +
91851 +#ifndef CONFIG_FMAN_ARM
91852 +#define iowrite32be(val, addr) WRITE_UINT32(*addr, val)
91853 +#define ioread32be(addr) GET_UINT32(*addr)
91854 +#endif
91855 +
91856 +#define ether_crc(len, addr) get_mac_addr_crc(*(uint64_t *)(addr)>>16)
91857 +
91858 +
91859 +#endif /* __GENERAL_H */
91860 --- /dev/null
91861 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/flib/fman_common.h
91862 @@ -0,0 +1,78 @@
91863 +/*
91864 + * Copyright 2008-2013 Freescale Semiconductor Inc.
91865 + *
91866 + * Redistribution and use in source and binary forms, with or without
91867 + * modification, are permitted provided that the following conditions are met:
91868 + * * Redistributions of source code must retain the above copyright
91869 + * notice, this list of conditions and the following disclaimer.
91870 + * * Redistributions in binary form must reproduce the above copyright
91871 + * notice, this list of conditions and the following disclaimer in the
91872 + * documentation and/or other materials provided with the distribution.
91873 + * * Neither the name of Freescale Semiconductor nor the
91874 + * names of its contributors may be used to endorse or promote products
91875 + * derived from this software without specific prior written permission.
91876 + *
91877 + *
91878 + * ALTERNATIVELY, this software may be distributed under the terms of the
91879 + * GNU General Public License ("GPL") as published by the Free Software
91880 + * Foundation, either version 2 of that License or (at your option) any
91881 + * later version.
91882 + *
91883 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
91884 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
91885 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
91886 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
91887 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
91888 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
91889 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
91890 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
91891 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
91892 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
91893 + */
91894 +
91895 +
91896 +#ifndef __FMAN_COMMON_H
91897 +#define __FMAN_COMMON_H
91898 +
91899 +/**************************************************************************//**
91900 + @Description NIA Description
91901 +*//***************************************************************************/
91902 +#define NIA_ORDER_RESTOR 0x00800000
91903 +#define NIA_ENG_FM_CTL 0x00000000
91904 +#define NIA_ENG_PRS 0x00440000
91905 +#define NIA_ENG_KG 0x00480000
91906 +#define NIA_ENG_PLCR 0x004C0000
91907 +#define NIA_ENG_BMI 0x00500000
91908 +#define NIA_ENG_QMI_ENQ 0x00540000
91909 +#define NIA_ENG_QMI_DEQ 0x00580000
91910 +#define NIA_ENG_MASK 0x007C0000
91911 +
91912 +#define NIA_FM_CTL_AC_CC 0x00000006
91913 +#define NIA_FM_CTL_AC_HC 0x0000000C
91914 +#define NIA_FM_CTL_AC_IND_MODE_TX 0x00000008
91915 +#define NIA_FM_CTL_AC_IND_MODE_RX 0x0000000A
91916 +#define NIA_FM_CTL_AC_FRAG 0x0000000e
91917 +#define NIA_FM_CTL_AC_PRE_FETCH 0x00000010
91918 +#define NIA_FM_CTL_AC_POST_FETCH_PCD 0x00000012
91919 +#define NIA_FM_CTL_AC_POST_FETCH_PCD_UDP_LEN 0x00000018
91920 +#define NIA_FM_CTL_AC_POST_FETCH_NO_PCD 0x00000012
91921 +#define NIA_FM_CTL_AC_FRAG_CHECK 0x00000014
91922 +#define NIA_FM_CTL_AC_PRE_CC 0x00000020
91923 +
91924 +
91925 +#define NIA_BMI_AC_ENQ_FRAME 0x00000002
91926 +#define NIA_BMI_AC_TX_RELEASE 0x000002C0
91927 +#define NIA_BMI_AC_RELEASE 0x000000C0
91928 +#define NIA_BMI_AC_DISCARD 0x000000C1
91929 +#define NIA_BMI_AC_TX 0x00000274
91930 +#define NIA_BMI_AC_FETCH 0x00000208
91931 +#define NIA_BMI_AC_MASK 0x000003FF
91932 +
91933 +#define NIA_KG_DIRECT 0x00000100
91934 +#define NIA_KG_CC_EN 0x00000200
91935 +#define NIA_PLCR_ABSOLUTE 0x00008000
91936 +
91937 +#define NIA_BMI_AC_ENQ_FRAME_WITHOUT_DMA 0x00000202
91938 +#define NIA_BMI_AC_FETCH_ALL_FRAME 0x0000020c
91939 +
91940 +#endif /* __FMAN_COMMON_H */
91941 --- /dev/null
91942 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/flib/fsl_enet.h
91943 @@ -0,0 +1,273 @@
91944 +/*
91945 + * Copyright 2008-2012 Freescale Semiconductor Inc.
91946 + *
91947 + * Redistribution and use in source and binary forms, with or without
91948 + * modification, are permitted provided that the following conditions are met:
91949 + * * Redistributions of source code must retain the above copyright
91950 + * notice, this list of conditions and the following disclaimer.
91951 + * * Redistributions in binary form must reproduce the above copyright
91952 + * notice, this list of conditions and the following disclaimer in the
91953 + * documentation and/or other materials provided with the distribution.
91954 + * * Neither the name of Freescale Semiconductor nor the
91955 + * names of its contributors may be used to endorse or promote products
91956 + * derived from this software without specific prior written permission.
91957 + *
91958 + *
91959 + * ALTERNATIVELY, this software may be distributed under the terms of the
91960 + * GNU General Public License ("GPL") as published by the Free Software
91961 + * Foundation, either version 2 of that License or (at your option) any
91962 + * later version.
91963 + *
91964 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
91965 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
91966 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
91967 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
91968 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
91969 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
91970 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
91971 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
91972 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
91973 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
91974 + */
91975 +
91976 +#ifndef __FSL_ENET_H
91977 +#define __FSL_ENET_H
91978 +
91979 +/**
91980 + @Description Ethernet MAC-PHY Interface
91981 +*/
91982 +
91983 +enum enet_interface {
91984 + E_ENET_IF_MII = 0x00010000, /**< MII interface */
91985 + E_ENET_IF_RMII = 0x00020000, /**< RMII interface */
91986 + E_ENET_IF_SMII = 0x00030000, /**< SMII interface */
91987 + E_ENET_IF_GMII = 0x00040000, /**< GMII interface */
91988 + E_ENET_IF_RGMII = 0x00050000, /**< RGMII interface */
91989 + E_ENET_IF_TBI = 0x00060000, /**< TBI interface */
91990 + E_ENET_IF_RTBI = 0x00070000, /**< RTBI interface */
91991 + E_ENET_IF_SGMII = 0x00080000, /**< SGMII interface */
91992 + E_ENET_IF_XGMII = 0x00090000, /**< XGMII interface */
91993 + E_ENET_IF_QSGMII = 0x000a0000, /**< QSGMII interface */
91994 + E_ENET_IF_XFI = 0x000b0000 /**< XFI interface */
91995 +};
91996 +
91997 +/**
91998 + @Description Ethernet Speed (nominal data rate)
91999 +*/
92000 +enum enet_speed {
92001 + E_ENET_SPEED_10 = 10, /**< 10 Mbps */
92002 + E_ENET_SPEED_100 = 100, /**< 100 Mbps */
92003 + E_ENET_SPEED_1000 = 1000, /**< 1000 Mbps = 1 Gbps */
92004 + E_ENET_SPEED_2500 = 2500, /**< 2500 Mbps = 2.5 Gbps */
92005 + E_ENET_SPEED_10000 = 10000 /**< 10000 Mbps = 10 Gbps */
92006 +};
92007 +
92008 +enum mac_type {
92009 + E_MAC_DTSEC,
92010 + E_MAC_TGEC,
92011 + E_MAC_MEMAC
92012 +};
92013 +
92014 +/**************************************************************************//**
92015 + @Description Enum for inter-module interrupts registration
92016 +*//***************************************************************************/
92017 +enum fman_event_modules {
92018 + E_FMAN_MOD_PRS, /**< Parser event */
92019 + E_FMAN_MOD_KG, /**< Keygen event */
92020 + E_FMAN_MOD_PLCR, /**< Policer event */
92021 + E_FMAN_MOD_10G_MAC, /**< 10G MAC event */
92022 + E_FMAN_MOD_1G_MAC, /**< 1G MAC event */
92023 + E_FMAN_MOD_TMR, /**< Timer event */
92024 + E_FMAN_MOD_FMAN_CTRL, /**< FMAN Controller Timer event */
92025 + E_FMAN_MOD_MACSEC,
92026 + E_FMAN_MOD_DUMMY_LAST
92027 +};
92028 +
92029 +/**************************************************************************//**
92030 + @Description Enum for interrupts types
92031 +*//***************************************************************************/
92032 +enum fman_intr_type {
92033 + E_FMAN_INTR_TYPE_ERR,
92034 + E_FMAN_INTR_TYPE_NORMAL
92035 +};
92036 +
92037 +/**************************************************************************//**
92038 + @Description enum for defining MAC types
92039 +*//***************************************************************************/
92040 +enum fman_mac_type {
92041 + E_FMAN_MAC_10G = 0, /**< 10G MAC */
92042 + E_FMAN_MAC_1G /**< 1G MAC */
92043 +};
92044 +
92045 +enum fman_mac_exceptions {
92046 + E_FMAN_MAC_EX_10G_MDIO_SCAN_EVENTMDIO = 0,
92047 + /**< 10GEC MDIO scan event interrupt */
92048 + E_FMAN_MAC_EX_10G_MDIO_CMD_CMPL,
92049 + /**< 10GEC MDIO command completion interrupt */
92050 + E_FMAN_MAC_EX_10G_REM_FAULT,
92051 + /**< 10GEC, mEMAC Remote fault interrupt */
92052 + E_FMAN_MAC_EX_10G_LOC_FAULT,
92053 + /**< 10GEC, mEMAC Local fault interrupt */
92054 + E_FMAN_MAC_EX_10G_1TX_ECC_ER,
92055 + /**< 10GEC, mEMAC Transmit frame ECC error interrupt */
92056 + E_FMAN_MAC_EX_10G_TX_FIFO_UNFL,
92057 + /**< 10GEC, mEMAC Transmit FIFO underflow interrupt */
92058 + E_FMAN_MAC_EX_10G_TX_FIFO_OVFL,
92059 + /**< 10GEC, mEMAC Transmit FIFO overflow interrupt */
92060 + E_FMAN_MAC_EX_10G_TX_ER,
92061 + /**< 10GEC Transmit frame error interrupt */
92062 + E_FMAN_MAC_EX_10G_RX_FIFO_OVFL,
92063 + /**< 10GEC, mEMAC Receive FIFO overflow interrupt */
92064 + E_FMAN_MAC_EX_10G_RX_ECC_ER,
92065 + /**< 10GEC, mEMAC Receive frame ECC error interrupt */
92066 + E_FMAN_MAC_EX_10G_RX_JAB_FRM,
92067 + /**< 10GEC Receive jabber frame interrupt */
92068 + E_FMAN_MAC_EX_10G_RX_OVRSZ_FRM,
92069 + /**< 10GEC Receive oversized frame interrupt */
92070 + E_FMAN_MAC_EX_10G_RX_RUNT_FRM,
92071 + /**< 10GEC Receive runt frame interrupt */
92072 + E_FMAN_MAC_EX_10G_RX_FRAG_FRM,
92073 + /**< 10GEC Receive fragment frame interrupt */
92074 + E_FMAN_MAC_EX_10G_RX_LEN_ER,
92075 + /**< 10GEC Receive payload length error interrupt */
92076 + E_FMAN_MAC_EX_10G_RX_CRC_ER,
92077 + /**< 10GEC Receive CRC error interrupt */
92078 + E_FMAN_MAC_EX_10G_RX_ALIGN_ER,
92079 + /**< 10GEC Receive alignment error interrupt */
92080 + E_FMAN_MAC_EX_1G_BAB_RX,
92081 + /**< dTSEC Babbling receive error */
92082 + E_FMAN_MAC_EX_1G_RX_CTL,
92083 + /**< dTSEC Receive control (pause frame) interrupt */
92084 + E_FMAN_MAC_EX_1G_GRATEFUL_TX_STP_COMPLET,
92085 + /**< dTSEC Graceful transmit stop complete */
92086 + E_FMAN_MAC_EX_1G_BAB_TX,
92087 + /**< dTSEC Babbling transmit error */
92088 + E_FMAN_MAC_EX_1G_TX_CTL,
92089 + /**< dTSEC Transmit control (pause frame) interrupt */
92090 + E_FMAN_MAC_EX_1G_TX_ERR,
92091 + /**< dTSEC Transmit error */
92092 + E_FMAN_MAC_EX_1G_LATE_COL,
92093 + /**< dTSEC Late collision */
92094 + E_FMAN_MAC_EX_1G_COL_RET_LMT,
92095 + /**< dTSEC Collision retry limit */
92096 + E_FMAN_MAC_EX_1G_TX_FIFO_UNDRN,
92097 + /**< dTSEC Transmit FIFO underrun */
92098 + E_FMAN_MAC_EX_1G_MAG_PCKT,
92099 + /**< dTSEC Magic Packet detection */
92100 + E_FMAN_MAC_EX_1G_MII_MNG_RD_COMPLET,
92101 + /**< dTSEC MII management read completion */
92102 + E_FMAN_MAC_EX_1G_MII_MNG_WR_COMPLET,
92103 + /**< dTSEC MII management write completion */
92104 + E_FMAN_MAC_EX_1G_GRATEFUL_RX_STP_COMPLET,
92105 + /**< dTSEC Graceful receive stop complete */
92106 + E_FMAN_MAC_EX_1G_TX_DATA_ERR,
92107 + /**< dTSEC Internal data error on transmit */
92108 + E_FMAN_MAC_EX_1G_RX_DATA_ERR,
92109 + /**< dTSEC Internal data error on receive */
92110 + E_FMAN_MAC_EX_1G_1588_TS_RX_ERR,
92111 + /**< dTSEC Time-Stamp Receive Error */
92112 + E_FMAN_MAC_EX_1G_RX_MIB_CNT_OVFL,
92113 + /**< dTSEC MIB counter overflow */
92114 + E_FMAN_MAC_EX_TS_FIFO_ECC_ERR,
92115 + /**< mEMAC Time-stamp FIFO ECC error interrupt;
92116 + not supported on T4240/B4860 rev1 chips */
92117 +};
92118 +
92119 +#define ENET_IF_SGMII_BASEX 0x80000000
92120 + /**< SGMII/QSGII interface with 1000BaseX auto-negotiation between MAC
92121 + and phy or backplane;
92122 + Note: 1000BaseX auto-negotiation relates only to interface between MAC
92123 + and phy/backplane, SGMII phy can still synchronize with far-end phy at
92124 + 10Mbps, 100Mbps or 1000Mbps */
92125 +
92126 +enum enet_mode {
92127 + E_ENET_MODE_INVALID = 0,
92128 + /**< Invalid Ethernet mode */
92129 + E_ENET_MODE_MII_10 = (E_ENET_IF_MII | E_ENET_SPEED_10),
92130 + /**< 10 Mbps MII */
92131 + E_ENET_MODE_MII_100 = (E_ENET_IF_MII | E_ENET_SPEED_100),
92132 + /**< 100 Mbps MII */
92133 + E_ENET_MODE_RMII_10 = (E_ENET_IF_RMII | E_ENET_SPEED_10),
92134 + /**< 10 Mbps RMII */
92135 + E_ENET_MODE_RMII_100 = (E_ENET_IF_RMII | E_ENET_SPEED_100),
92136 + /**< 100 Mbps RMII */
92137 + E_ENET_MODE_SMII_10 = (E_ENET_IF_SMII | E_ENET_SPEED_10),
92138 + /**< 10 Mbps SMII */
92139 + E_ENET_MODE_SMII_100 = (E_ENET_IF_SMII | E_ENET_SPEED_100),
92140 + /**< 100 Mbps SMII */
92141 + E_ENET_MODE_GMII_1000 = (E_ENET_IF_GMII | E_ENET_SPEED_1000),
92142 + /**< 1000 Mbps GMII */
92143 + E_ENET_MODE_RGMII_10 = (E_ENET_IF_RGMII | E_ENET_SPEED_10),
92144 + /**< 10 Mbps RGMII */
92145 + E_ENET_MODE_RGMII_100 = (E_ENET_IF_RGMII | E_ENET_SPEED_100),
92146 + /**< 100 Mbps RGMII */
92147 + E_ENET_MODE_RGMII_1000 = (E_ENET_IF_RGMII | E_ENET_SPEED_1000),
92148 + /**< 1000 Mbps RGMII */
92149 + E_ENET_MODE_TBI_1000 = (E_ENET_IF_TBI | E_ENET_SPEED_1000),
92150 + /**< 1000 Mbps TBI */
92151 + E_ENET_MODE_RTBI_1000 = (E_ENET_IF_RTBI | E_ENET_SPEED_1000),
92152 + /**< 1000 Mbps RTBI */
92153 + E_ENET_MODE_SGMII_10 = (E_ENET_IF_SGMII | E_ENET_SPEED_10),
92154 + /**< 10 Mbps SGMII with auto-negotiation between MAC and
92155 + SGMII phy according to Cisco SGMII specification */
92156 + E_ENET_MODE_SGMII_100 = (E_ENET_IF_SGMII | E_ENET_SPEED_100),
92157 + /**< 100 Mbps SGMII with auto-negotiation between MAC and
92158 + SGMII phy according to Cisco SGMII specification */
92159 + E_ENET_MODE_SGMII_1000 = (E_ENET_IF_SGMII | E_ENET_SPEED_1000),
92160 + /**< 1000 Mbps SGMII with auto-negotiation between MAC and
92161 + SGMII phy according to Cisco SGMII specification */
92162 + E_ENET_MODE_SGMII_BASEX_10 = (ENET_IF_SGMII_BASEX | E_ENET_IF_SGMII
92163 + | E_ENET_SPEED_10),
92164 + /**< 10 Mbps SGMII with 1000BaseX auto-negotiation between
92165 + MAC and SGMII phy or backplane */
92166 + E_ENET_MODE_SGMII_BASEX_100 = (ENET_IF_SGMII_BASEX | E_ENET_IF_SGMII
92167 + | E_ENET_SPEED_100),
92168 + /**< 100 Mbps SGMII with 1000BaseX auto-negotiation between
92169 + MAC and SGMII phy or backplane */
92170 + E_ENET_MODE_SGMII_BASEX_1000 = (ENET_IF_SGMII_BASEX | E_ENET_IF_SGMII
92171 + | E_ENET_SPEED_1000),
92172 + /**< 1000 Mbps SGMII with 1000BaseX auto-negotiation between
92173 + MAC and SGMII phy or backplane */
92174 + E_ENET_MODE_QSGMII_1000 = (E_ENET_IF_QSGMII | E_ENET_SPEED_1000),
92175 + /**< 1000 Mbps QSGMII with auto-negotiation between MAC and
92176 + QSGMII phy according to Cisco QSGMII specification */
92177 + E_ENET_MODE_QSGMII_BASEX_1000 = (ENET_IF_SGMII_BASEX | E_ENET_IF_QSGMII
92178 + | E_ENET_SPEED_1000),
92179 + /**< 1000 Mbps QSGMII with 1000BaseX auto-negotiation between
92180 + MAC and QSGMII phy or backplane */
92181 + E_ENET_MODE_XGMII_10000 = (E_ENET_IF_XGMII | E_ENET_SPEED_10000),
92182 + /**< 10000 Mbps XGMII */
92183 + E_ENET_MODE_XFI_10000 = (E_ENET_IF_XFI | E_ENET_SPEED_10000)
92184 + /**< 10000 Mbps XFI */
92185 +};
92186 +
92187 +enum fmam_mac_statistics_level {
92188 + E_FMAN_MAC_NONE_STATISTICS, /**< No statistics */
92189 + E_FMAN_MAC_PARTIAL_STATISTICS, /**< Only error counters are available;
92190 + Optimized for performance */
92191 + E_FMAN_MAC_FULL_STATISTICS /**< All counters available; Not
92192 + optimized for performance */
92193 +};
92194 +
92195 +#define _MAKE_ENET_MODE(_interface, _speed) (enum enet_mode)((_interface) \
92196 + | (_speed))
92197 +
92198 +#define _ENET_INTERFACE_FROM_MODE(mode) (enum enet_interface) \
92199 + ((mode) & 0x0FFF0000)
92200 +#define _ENET_SPEED_FROM_MODE(mode) (enum enet_speed)((mode) & 0x0000FFFF)
92201 +#define _ENET_ADDR_TO_UINT64(_enet_addr) \
92202 + (uint64_t)(((uint64_t)(_enet_addr)[0] << 40) | \
92203 + ((uint64_t)(_enet_addr)[1] << 32) | \
92204 + ((uint64_t)(_enet_addr)[2] << 24) | \
92205 + ((uint64_t)(_enet_addr)[3] << 16) | \
92206 + ((uint64_t)(_enet_addr)[4] << 8) | \
92207 + ((uint64_t)(_enet_addr)[5]))
92208 +
92209 +#define _MAKE_ENET_ADDR_FROM_UINT64(_addr64, _enet_addr) \
92210 + do { \
92211 + int i; \
92212 + for (i = 0; i < ENET_NUM_OCTETS_PER_ADDRESS; i++) \
92213 + (_enet_addr)[i] = (uint8_t)((_addr64) >> ((5-i)*8));\
92214 + } while (0)
92215 +
92216 +#endif /* __FSL_ENET_H */
92217 --- /dev/null
92218 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/flib/fsl_fman.h
92219 @@ -0,0 +1,825 @@
92220 +/*
92221 + * Copyright 2013 Freescale Semiconductor Inc.
92222 + *
92223 + * Redistribution and use in source and binary forms, with or without
92224 + * modification, are permitted provided that the following conditions are met:
92225 + * * Redistributions of source code must retain the above copyright
92226 + * notice, this list of conditions and the following disclaimer.
92227 + * * Redistributions in binary form must reproduce the above copyright
92228 + * notice, this list of conditions and the following disclaimer in the
92229 + * documentation and/or other materials provided with the distribution.
92230 + * * Neither the name of Freescale Semiconductor nor the
92231 + * names of its contributors may be used to endorse or promote products
92232 + * derived from this software without specific prior written permission.
92233 + *
92234 + *
92235 + * ALTERNATIVELY, this software may be distributed under the terms of the
92236 + * GNU General Public License ("GPL") as published by the Free Software
92237 + * Foundation, either version 2 of that License or (at your option) any
92238 + * later version.
92239 + *
92240 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
92241 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
92242 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
92243 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
92244 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
92245 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
92246 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
92247 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
92248 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
92249 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
92250 + */
92251 +
92252 +#ifndef __FSL_FMAN_H
92253 +#define __FSL_FMAN_H
92254 +
92255 +#include "common/general.h"
92256 +
92257 +struct fman_ext_pool_params {
92258 + uint8_t id; /**< External buffer pool id */
92259 + uint16_t size; /**< External buffer pool buffer size */
92260 +};
92261 +
92262 +struct fman_ext_pools {
92263 + uint8_t num_pools_used; /**< Number of pools use by this port */
92264 + struct fman_ext_pool_params *ext_buf_pool;
92265 + /**< Parameters for each port */
92266 +};
92267 +
92268 +struct fman_backup_bm_pools {
92269 + uint8_t num_backup_pools; /**< Number of BM backup pools -
92270 + must be smaller than the total number
92271 + of pools defined for the specified
92272 + port.*/
92273 + uint8_t *pool_ids; /**< numOfBackupPools pool id's,
92274 + specifying which pools should be used
92275 + only as backup. Pool id's specified
92276 + here must be a subset of the pools
92277 + used by the specified port.*/
92278 +};
92279 +
92280 +/**************************************************************************//**
92281 + @Description A structure for defining BM pool depletion criteria
92282 +*//***************************************************************************/
92283 +struct fman_buf_pool_depletion {
92284 + bool buf_pool_depletion_enabled;
92285 + bool pools_grp_mode_enable; /**< select mode in which pause frames
92286 + will be sent after a number of pools
92287 + (all together!) are depleted */
92288 + uint8_t num_pools; /**< the number of depleted pools that
92289 + will invoke pause frames transmission.
92290 + */
92291 + bool *pools_to_consider; /**< For each pool, TRUE if it should be
92292 + considered for depletion (Note - this
92293 + pool must be used by this port!). */
92294 + bool single_pool_mode_enable; /**< select mode in which pause frames
92295 + will be sent after a single-pool
92296 + is depleted; */
92297 + bool *pools_to_consider_for_single_mode;
92298 + /**< For each pool, TRUE if it should be
92299 + considered for depletion (Note - this
92300 + pool must be used by this port!) */
92301 + bool has_pfc_priorities;
92302 + bool *pfc_priorities_en; /**< This field is used by the MAC as
92303 + the Priority Enable Vector in the PFC
92304 + frame which is transmitted */
92305 +};
92306 +
92307 +/**************************************************************************//**
92308 + @Description Enum for defining port DMA swap mode
92309 +*//***************************************************************************/
92310 +enum fman_dma_swap_option {
92311 + FMAN_DMA_NO_SWP, /**< No swap, transfer data as is.*/
92312 + FMAN_DMA_SWP_PPC_LE, /**< The transferred data should be swapped
92313 + in PowerPc Little Endian mode. */
92314 + FMAN_DMA_SWP_BE /**< The transferred data should be swapped
92315 + in Big Endian mode */
92316 +};
92317 +
92318 +/**************************************************************************//**
92319 + @Description Enum for defining port DMA cache attributes
92320 +*//***************************************************************************/
92321 +enum fman_dma_cache_option {
92322 + FMAN_DMA_NO_STASH = 0, /**< Cacheable, no Allocate (No Stashing) */
92323 + FMAN_DMA_STASH = 1 /**< Cacheable and Allocate (Stashing on) */
92324 +};
92325 +
92326 +typedef struct t_FmPrsResult fm_prs_result_t;
92327 +typedef enum e_EnetMode enet_mode_t;
92328 +typedef t_Handle handle_t;
92329 +
92330 +struct fman_revision_info {
92331 + uint8_t majorRev; /**< Major revision */
92332 + uint8_t minorRev; /**< Minor revision */
92333 +};
92334 +
92335 +/* sizes */
92336 +#define CAPWAP_FRAG_EXTRA_SPACE 32
92337 +#define OFFSET_UNITS 16
92338 +#define MAX_INT_OFFSET 240
92339 +#define MAX_IC_SIZE 256
92340 +#define MAX_EXT_OFFSET 496
92341 +#define MAX_EXT_BUFFER_OFFSET 511
92342 +
92343 +/**************************************************************************
92344 + @Description Memory Mapped Registers
92345 +***************************************************************************/
92346 +#define FMAN_LIODN_TBL 64 /* size of LIODN table */
92347 +
92348 +struct fman_fpm_regs {
92349 + uint32_t fmfp_tnc; /**< FPM TNUM Control 0x00 */
92350 + uint32_t fmfp_prc; /**< FPM Port_ID FmCtl Association 0x04 */
92351 + uint32_t fmfp_brkc; /**< FPM Breakpoint Control 0x08 */
92352 + uint32_t fmfp_mxd; /**< FPM Flush Control 0x0c */
92353 + uint32_t fmfp_dist1; /**< FPM Dispatch Thresholds1 0x10 */
92354 + uint32_t fmfp_dist2; /**< FPM Dispatch Thresholds2 0x14 */
92355 + uint32_t fm_epi; /**< FM Error Pending Interrupts 0x18 */
92356 + uint32_t fm_rie; /**< FM Error Interrupt Enable 0x1c */
92357 + uint32_t fmfp_fcev[4]; /**< FPM FMan-Controller Event 1-4 0x20-0x2f */
92358 + uint32_t res0030[4]; /**< res 0x30 - 0x3f */
92359 + uint32_t fmfp_cee[4]; /**< PM FMan-Controller Event 1-4 0x40-0x4f */
92360 + uint32_t res0050[4]; /**< res 0x50-0x5f */
92361 + uint32_t fmfp_tsc1; /**< FPM TimeStamp Control1 0x60 */
92362 + uint32_t fmfp_tsc2; /**< FPM TimeStamp Control2 0x64 */
92363 + uint32_t fmfp_tsp; /**< FPM Time Stamp 0x68 */
92364 + uint32_t fmfp_tsf; /**< FPM Time Stamp Fraction 0x6c */
92365 + uint32_t fm_rcr; /**< FM Rams Control 0x70 */
92366 + uint32_t fmfp_extc; /**< FPM External Requests Control 0x74 */
92367 + uint32_t fmfp_ext1; /**< FPM External Requests Config1 0x78 */
92368 + uint32_t fmfp_ext2; /**< FPM External Requests Config2 0x7c */
92369 + uint32_t fmfp_drd[16]; /**< FPM Data_Ram Data 0-15 0x80 - 0xbf */
92370 + uint32_t fmfp_dra; /**< FPM Data Ram Access 0xc0 */
92371 + uint32_t fm_ip_rev_1; /**< FM IP Block Revision 1 0xc4 */
92372 + uint32_t fm_ip_rev_2; /**< FM IP Block Revision 2 0xc8 */
92373 + uint32_t fm_rstc; /**< FM Reset Command 0xcc */
92374 + uint32_t fm_cld; /**< FM Classifier Debug 0xd0 */
92375 + uint32_t fm_npi; /**< FM Normal Pending Interrupts 0xd4 */
92376 + uint32_t fmfp_exte; /**< FPM External Requests Enable 0xd8 */
92377 + uint32_t fmfp_ee; /**< FPM Event & Mask 0xdc */
92378 + uint32_t fmfp_cev[4]; /**< FPM CPU Event 1-4 0xe0-0xef */
92379 + uint32_t res00f0[4]; /**< res 0xf0-0xff */
92380 + uint32_t fmfp_ps[64]; /**< FPM Port Status 0x100-0x1ff */
92381 + uint32_t fmfp_clfabc; /**< FPM CLFABC 0x200 */
92382 + uint32_t fmfp_clfcc; /**< FPM CLFCC 0x204 */
92383 + uint32_t fmfp_clfaval; /**< FPM CLFAVAL 0x208 */
92384 + uint32_t fmfp_clfbval; /**< FPM CLFBVAL 0x20c */
92385 + uint32_t fmfp_clfcval; /**< FPM CLFCVAL 0x210 */
92386 + uint32_t fmfp_clfamsk; /**< FPM CLFAMSK 0x214 */
92387 + uint32_t fmfp_clfbmsk; /**< FPM CLFBMSK 0x218 */
92388 + uint32_t fmfp_clfcmsk; /**< FPM CLFCMSK 0x21c */
92389 + uint32_t fmfp_clfamc; /**< FPM CLFAMC 0x220 */
92390 + uint32_t fmfp_clfbmc; /**< FPM CLFBMC 0x224 */
92391 + uint32_t fmfp_clfcmc; /**< FPM CLFCMC 0x228 */
92392 + uint32_t fmfp_decceh; /**< FPM DECCEH 0x22c */
92393 + uint32_t res0230[116]; /**< res 0x230 - 0x3ff */
92394 + uint32_t fmfp_ts[128]; /**< 0x400: FPM Task Status 0x400 - 0x5ff */
92395 + uint32_t res0600[0x400 - 384];
92396 +};
92397 +
92398 +struct fman_bmi_regs {
92399 + uint32_t fmbm_init; /**< BMI Initialization 0x00 */
92400 + uint32_t fmbm_cfg1; /**< BMI Configuration 1 0x04 */
92401 + uint32_t fmbm_cfg2; /**< BMI Configuration 2 0x08 */
92402 + uint32_t res000c[5]; /**< 0x0c - 0x1f */
92403 + uint32_t fmbm_ievr; /**< Interrupt Event Register 0x20 */
92404 + uint32_t fmbm_ier; /**< Interrupt Enable Register 0x24 */
92405 + uint32_t fmbm_ifr; /**< Interrupt Force Register 0x28 */
92406 + uint32_t res002c[5]; /**< 0x2c - 0x3f */
92407 + uint32_t fmbm_arb[8]; /**< BMI Arbitration 0x40 - 0x5f */
92408 + uint32_t res0060[12]; /**<0x60 - 0x8f */
92409 + uint32_t fmbm_dtc[3]; /**< Debug Trap Counter 0x90 - 0x9b */
92410 + uint32_t res009c; /**< 0x9c */
92411 + uint32_t fmbm_dcv[3][4]; /**< Debug Compare val 0xa0-0xcf */
92412 + uint32_t fmbm_dcm[3][4]; /**< Debug Compare Mask 0xd0-0xff */
92413 + uint32_t fmbm_gde; /**< BMI Global Debug Enable 0x100 */
92414 + uint32_t fmbm_pp[63]; /**< BMI Port Parameters 0x104 - 0x1ff */
92415 + uint32_t res0200; /**< 0x200 */
92416 + uint32_t fmbm_pfs[63]; /**< BMI Port FIFO Size 0x204 - 0x2ff */
92417 + uint32_t res0300; /**< 0x300 */
92418 + uint32_t fmbm_spliodn[63]; /**< Port Partition ID 0x304 - 0x3ff */
92419 +};
92420 +
92421 +struct fman_qmi_regs {
92422 + uint32_t fmqm_gc; /**< General Configuration Register 0x00 */
92423 + uint32_t res0004; /**< 0x04 */
92424 + uint32_t fmqm_eie; /**< Error Interrupt Event Register 0x08 */
92425 + uint32_t fmqm_eien; /**< Error Interrupt Enable Register 0x0c */
92426 + uint32_t fmqm_eif; /**< Error Interrupt Force Register 0x10 */
92427 + uint32_t fmqm_ie; /**< Interrupt Event Register 0x14 */
92428 + uint32_t fmqm_ien; /**< Interrupt Enable Register 0x18 */
92429 + uint32_t fmqm_if; /**< Interrupt Force Register 0x1c */
92430 + uint32_t fmqm_gs; /**< Global Status Register 0x20 */
92431 + uint32_t fmqm_ts; /**< Task Status Register 0x24 */
92432 + uint32_t fmqm_etfc; /**< Enqueue Total Frame Counter 0x28 */
92433 + uint32_t fmqm_dtfc; /**< Dequeue Total Frame Counter 0x2c */
92434 + uint32_t fmqm_dc0; /**< Dequeue Counter 0 0x30 */
92435 + uint32_t fmqm_dc1; /**< Dequeue Counter 1 0x34 */
92436 + uint32_t fmqm_dc2; /**< Dequeue Counter 2 0x38 */
92437 + uint32_t fmqm_dc3; /**< Dequeue Counter 3 0x3c */
92438 + uint32_t fmqm_dfdc; /**< Dequeue FQID from Default Counter 0x40 */
92439 + uint32_t fmqm_dfcc; /**< Dequeue FQID from Context Counter 0x44 */
92440 + uint32_t fmqm_dffc; /**< Dequeue FQID from FD Counter 0x48 */
92441 + uint32_t fmqm_dcc; /**< Dequeue Confirm Counter 0x4c */
92442 + uint32_t res0050[7]; /**< 0x50 - 0x6b */
92443 + uint32_t fmqm_tapc; /**< Tnum Aging Period Control 0x6c */
92444 + uint32_t fmqm_dmcvc; /**< Dequeue MAC Command Valid Counter 0x70 */
92445 + uint32_t fmqm_difdcc; /**< Dequeue Invalid FD Command Counter 0x74 */
92446 + uint32_t fmqm_da1v; /**< Dequeue A1 Valid Counter 0x78 */
92447 + uint32_t res007c; /**< 0x7c */
92448 + uint32_t fmqm_dtc; /**< 0x80 Debug Trap Counter 0x80 */
92449 + uint32_t fmqm_efddd; /**< 0x84 Enqueue Frame desc Dynamic dbg 0x84 */
92450 + uint32_t res0088[2]; /**< 0x88 - 0x8f */
92451 + struct {
92452 + uint32_t fmqm_dtcfg1; /**< 0x90 dbg trap cfg 1 Register 0x00 */
92453 + uint32_t fmqm_dtval1; /**< Debug Trap Value 1 Register 0x04 */
92454 + uint32_t fmqm_dtm1; /**< Debug Trap Mask 1 Register 0x08 */
92455 + uint32_t fmqm_dtc1; /**< Debug Trap Counter 1 Register 0x0c */
92456 + uint32_t fmqm_dtcfg2; /**< dbg Trap cfg 2 Register 0x10 */
92457 + uint32_t fmqm_dtval2; /**< Debug Trap Value 2 Register 0x14 */
92458 + uint32_t fmqm_dtm2; /**< Debug Trap Mask 2 Register 0x18 */
92459 + uint32_t res001c; /**< 0x1c */
92460 + } dbg_traps[3]; /**< 0x90 - 0xef */
92461 + uint8_t res00f0[0x400 - 0xf0]; /**< 0xf0 - 0x3ff */
92462 +};
92463 +
92464 +struct fman_dma_regs {
92465 + uint32_t fmdmsr; /**< FM DMA status register 0x00 */
92466 + uint32_t fmdmmr; /**< FM DMA mode register 0x04 */
92467 + uint32_t fmdmtr; /**< FM DMA bus threshold register 0x08 */
92468 + uint32_t fmdmhy; /**< FM DMA bus hysteresis register 0x0c */
92469 + uint32_t fmdmsetr; /**< FM DMA SOS emergency Threshold Register 0x10 */
92470 + uint32_t fmdmtah; /**< FM DMA transfer bus address high reg 0x14 */
92471 + uint32_t fmdmtal; /**< FM DMA transfer bus address low reg 0x18 */
92472 + uint32_t fmdmtcid; /**< FM DMA transfer bus communication ID reg 0x1c */
92473 + uint32_t fmdmra; /**< FM DMA bus internal ram address register 0x20 */
92474 + uint32_t fmdmrd; /**< FM DMA bus internal ram data register 0x24 */
92475 + uint32_t fmdmwcr; /**< FM DMA CAM watchdog counter value 0x28 */
92476 + uint32_t fmdmebcr; /**< FM DMA CAM base in MURAM register 0x2c */
92477 + uint32_t fmdmccqdr; /**< FM DMA CAM and CMD Queue Debug reg 0x30 */
92478 + uint32_t fmdmccqvr1; /**< FM DMA CAM and CMD Queue Value reg #1 0x34 */
92479 + uint32_t fmdmccqvr2; /**< FM DMA CAM and CMD Queue Value reg #2 0x38 */
92480 + uint32_t fmdmcqvr3; /**< FM DMA CMD Queue Value register #3 0x3c */
92481 + uint32_t fmdmcqvr4; /**< FM DMA CMD Queue Value register #4 0x40 */
92482 + uint32_t fmdmcqvr5; /**< FM DMA CMD Queue Value register #5 0x44 */
92483 + uint32_t fmdmsefrc; /**< FM DMA Semaphore Entry Full Reject Cntr 0x48 */
92484 + uint32_t fmdmsqfrc; /**< FM DMA Semaphore Queue Full Reject Cntr 0x4c */
92485 + uint32_t fmdmssrc; /**< FM DMA Semaphore SYNC Reject Counter 0x50 */
92486 + uint32_t fmdmdcr; /**< FM DMA Debug Counter 0x54 */
92487 + uint32_t fmdmemsr; /**< FM DMA Emergency Smoother Register 0x58 */
92488 + uint32_t res005c; /**< 0x5c */
92489 + uint32_t fmdmplr[FMAN_LIODN_TBL / 2]; /**< DMA LIODN regs 0x60-0xdf */
92490 + uint32_t res00e0[0x400 - 56];
92491 +};
92492 +
92493 +struct fman_rg {
92494 + struct fman_fpm_regs *fpm_rg;
92495 + struct fman_dma_regs *dma_rg;
92496 + struct fman_bmi_regs *bmi_rg;
92497 + struct fman_qmi_regs *qmi_rg;
92498 +};
92499 +
92500 +enum fman_dma_cache_override {
92501 + E_FMAN_DMA_NO_CACHE_OR = 0, /**< No override of the Cache field */
92502 + E_FMAN_DMA_NO_STASH_DATA, /**< No data stashing in system level cache */
92503 + E_FMAN_DMA_MAY_STASH_DATA, /**< Stashing allowed in sys level cache */
92504 + E_FMAN_DMA_STASH_DATA /**< Stashing performed in system level cache */
92505 +};
92506 +
92507 +enum fman_dma_aid_mode {
92508 + E_FMAN_DMA_AID_OUT_PORT_ID = 0, /**< 4 LSB of PORT_ID */
92509 + E_FMAN_DMA_AID_OUT_TNUM /**< 4 LSB of TNUM */
92510 +};
92511 +
92512 +enum fman_dma_dbg_cnt_mode {
92513 + E_FMAN_DMA_DBG_NO_CNT = 0, /**< No counting */
92514 + E_FMAN_DMA_DBG_CNT_DONE, /**< Count DONE commands */
92515 + E_FMAN_DMA_DBG_CNT_COMM_Q_EM, /**< command Q emergency signal */
92516 + E_FMAN_DMA_DBG_CNT_INT_READ_EM, /**< Read buf emergency signal */
92517 + E_FMAN_DMA_DBG_CNT_INT_WRITE_EM, /**< Write buf emergency signal */
92518 + E_FMAN_DMA_DBG_CNT_FPM_WAIT, /**< FPM WAIT signal */
92519 + E_FMAN_DMA_DBG_CNT_SIGLE_BIT_ECC, /**< Single bit ECC errors */
92520 + E_FMAN_DMA_DBG_CNT_RAW_WAR_PROT /**< RAW & WAR protection counter */
92521 +};
92522 +
92523 +enum fman_dma_emergency_level {
92524 + E_FMAN_DMA_EM_EBS = 0, /**< EBS emergency */
92525 + E_FMAN_DMA_EM_SOS /**< SOS emergency */
92526 +};
92527 +
92528 +enum fman_catastrophic_err {
92529 + E_FMAN_CATAST_ERR_STALL_PORT = 0, /**< Port_ID stalled reset required */
92530 + E_FMAN_CATAST_ERR_STALL_TASK /**< Only erroneous task is stalled */
92531 +};
92532 +
92533 +enum fman_dma_err {
92534 + E_FMAN_DMA_ERR_CATASTROPHIC = 0, /**< Catastrophic DMA error */
92535 + E_FMAN_DMA_ERR_REPORT /**< Reported DMA error */
92536 +};
92537 +
92538 +struct fman_cfg {
92539 + uint16_t liodn_bs_pr_port[FMAN_LIODN_TBL];/* base per port */
92540 + bool en_counters;
92541 + uint8_t disp_limit_tsh;
92542 + uint8_t prs_disp_tsh;
92543 + uint8_t plcr_disp_tsh;
92544 + uint8_t kg_disp_tsh;
92545 + uint8_t bmi_disp_tsh;
92546 + uint8_t qmi_enq_disp_tsh;
92547 + uint8_t qmi_deq_disp_tsh;
92548 + uint8_t fm_ctl1_disp_tsh;
92549 + uint8_t fm_ctl2_disp_tsh;
92550 + enum fman_dma_cache_override dma_cache_override;
92551 + enum fman_dma_aid_mode dma_aid_mode;
92552 + bool dma_aid_override;
92553 + uint8_t dma_axi_dbg_num_of_beats;
92554 + uint8_t dma_cam_num_of_entries;
92555 + uint32_t dma_watchdog;
92556 + uint8_t dma_comm_qtsh_asrt_emer;
92557 + uint8_t dma_write_buf_tsh_asrt_emer;
92558 + uint8_t dma_read_buf_tsh_asrt_emer;
92559 + uint8_t dma_comm_qtsh_clr_emer;
92560 + uint8_t dma_write_buf_tsh_clr_emer;
92561 + uint8_t dma_read_buf_tsh_clr_emer;
92562 + uint32_t dma_sos_emergency;
92563 + enum fman_dma_dbg_cnt_mode dma_dbg_cnt_mode;
92564 + bool dma_stop_on_bus_error;
92565 + bool dma_en_emergency;
92566 + uint32_t dma_emergency_bus_select;
92567 + enum fman_dma_emergency_level dma_emergency_level;
92568 + bool dma_en_emergency_smoother;
92569 + uint32_t dma_emergency_switch_counter;
92570 + bool halt_on_external_activ;
92571 + bool halt_on_unrecov_ecc_err;
92572 + enum fman_catastrophic_err catastrophic_err;
92573 + enum fman_dma_err dma_err;
92574 + bool en_muram_test_mode;
92575 + bool en_iram_test_mode;
92576 + bool external_ecc_rams_enable;
92577 + uint16_t tnum_aging_period;
92578 + uint32_t exceptions;
92579 + uint16_t clk_freq;
92580 + bool pedantic_dma;
92581 + uint32_t cam_base_addr;
92582 + uint32_t fifo_base_addr;
92583 + uint32_t total_fifo_size;
92584 + uint8_t total_num_of_tasks;
92585 + bool qmi_deq_option_support;
92586 + uint32_t qmi_def_tnums_thresh;
92587 + bool fman_partition_array;
92588 + uint8_t num_of_fman_ctrl_evnt_regs;
92589 +};
92590 +
92591 +/**************************************************************************//**
92592 + @Description Exceptions
92593 +*//***************************************************************************/
92594 +#define FMAN_EX_DMA_BUS_ERROR 0x80000000
92595 +#define FMAN_EX_DMA_READ_ECC 0x40000000
92596 +#define FMAN_EX_DMA_SYSTEM_WRITE_ECC 0x20000000
92597 +#define FMAN_EX_DMA_FM_WRITE_ECC 0x10000000
92598 +#define FMAN_EX_FPM_STALL_ON_TASKS 0x08000000
92599 +#define FMAN_EX_FPM_SINGLE_ECC 0x04000000
92600 +#define FMAN_EX_FPM_DOUBLE_ECC 0x02000000
92601 +#define FMAN_EX_QMI_SINGLE_ECC 0x01000000
92602 +#define FMAN_EX_QMI_DEQ_FROM_UNKNOWN_PORTID 0x00800000
92603 +#define FMAN_EX_QMI_DOUBLE_ECC 0x00400000
92604 +#define FMAN_EX_BMI_LIST_RAM_ECC 0x00200000
92605 +#define FMAN_EX_BMI_PIPELINE_ECC 0x00100000
92606 +#define FMAN_EX_BMI_STATISTICS_RAM_ECC 0x00080000
92607 +#define FMAN_EX_IRAM_ECC 0x00040000
92608 +#define FMAN_EX_NURAM_ECC 0x00020000
92609 +#define FMAN_EX_BMI_DISPATCH_RAM_ECC 0x00010000
92610 +
92611 +enum fman_exceptions {
92612 + E_FMAN_EX_DMA_BUS_ERROR = 0, /**< DMA bus error. */
92613 + E_FMAN_EX_DMA_READ_ECC, /**< Read Buffer ECC error */
92614 + E_FMAN_EX_DMA_SYSTEM_WRITE_ECC, /**< Write Buffer ECC err on sys side */
92615 + E_FMAN_EX_DMA_FM_WRITE_ECC, /**< Write Buffer ECC error on FM side */
92616 + E_FMAN_EX_FPM_STALL_ON_TASKS, /**< Stall of tasks on FPM */
92617 + E_FMAN_EX_FPM_SINGLE_ECC, /**< Single ECC on FPM. */
92618 + E_FMAN_EX_FPM_DOUBLE_ECC, /**< Double ECC error on FPM ram access */
92619 + E_FMAN_EX_QMI_SINGLE_ECC, /**< Single ECC on QMI. */
92620 + E_FMAN_EX_QMI_DOUBLE_ECC, /**< Double bit ECC occurred on QMI */
92621 + E_FMAN_EX_QMI_DEQ_FROM_UNKNOWN_PORTID,/**< DeQ from unknown port id */
92622 + E_FMAN_EX_BMI_LIST_RAM_ECC, /**< Linked List RAM ECC error */
92623 + E_FMAN_EX_BMI_STORAGE_PROFILE_ECC, /**< storage profile */
92624 + E_FMAN_EX_BMI_STATISTICS_RAM_ECC, /**< Statistics RAM ECC Err Enable */
92625 + E_FMAN_EX_BMI_DISPATCH_RAM_ECC, /**< Dispatch RAM ECC Error Enable */
92626 + E_FMAN_EX_IRAM_ECC, /**< Double bit ECC occurred on IRAM*/
92627 + E_FMAN_EX_MURAM_ECC /**< Double bit ECC occurred on MURAM*/
92628 +};
92629 +
92630 +enum fman_counters {
92631 + E_FMAN_COUNTERS_ENQ_TOTAL_FRAME = 0, /**< QMI tot enQ frames counter */
92632 + E_FMAN_COUNTERS_DEQ_TOTAL_FRAME, /**< QMI tot deQ frames counter */
92633 + E_FMAN_COUNTERS_DEQ_0, /**< QMI 0 frames from QMan counter */
92634 + E_FMAN_COUNTERS_DEQ_1, /**< QMI 1 frames from QMan counter */
92635 + E_FMAN_COUNTERS_DEQ_2, /**< QMI 2 frames from QMan counter */
92636 + E_FMAN_COUNTERS_DEQ_3, /**< QMI 3 frames from QMan counter */
92637 + E_FMAN_COUNTERS_DEQ_FROM_DEFAULT, /**< QMI deQ from dflt queue cntr */
92638 + E_FMAN_COUNTERS_DEQ_FROM_CONTEXT, /**< QMI deQ from FQ context cntr */
92639 + E_FMAN_COUNTERS_DEQ_FROM_FD, /**< QMI deQ from FD command field cntr */
92640 + E_FMAN_COUNTERS_DEQ_CONFIRM, /**< QMI dequeue confirm counter */
92641 + E_FMAN_COUNTERS_SEMAPHOR_ENTRY_FULL_REJECT, /**< DMA full entry cntr */
92642 + E_FMAN_COUNTERS_SEMAPHOR_QUEUE_FULL_REJECT, /**< DMA full CAM Q cntr */
92643 + E_FMAN_COUNTERS_SEMAPHOR_SYNC_REJECT /**< DMA sync counter */
92644 +};
92645 +
92646 +#define FPM_PRT_FM_CTL1 0x00000001
92647 +#define FPM_PRT_FM_CTL2 0x00000002
92648 +
92649 +/**************************************************************************//**
92650 + @Description DMA definitions
92651 +*//***************************************************************************/
92652 +
92653 +/* masks */
92654 +#define DMA_MODE_AID_OR 0x20000000
92655 +#define DMA_MODE_SBER 0x10000000
92656 +#define DMA_MODE_BER 0x00200000
92657 +#define DMA_MODE_EB 0x00100000
92658 +#define DMA_MODE_ECC 0x00000020
92659 +#define DMA_MODE_PRIVILEGE_PROT 0x00001000
92660 +#define DMA_MODE_SECURE_PROT 0x00000800
92661 +#define DMA_MODE_EMER_READ 0x00080000
92662 +#define DMA_MODE_EMER_WRITE 0x00040000
92663 +#define DMA_MODE_CACHE_OR_MASK 0xC0000000
92664 +#define DMA_MODE_CEN_MASK 0x0000E000
92665 +#define DMA_MODE_DBG_MASK 0x00000380
92666 +#define DMA_MODE_AXI_DBG_MASK 0x0F000000
92667 +
92668 +#define DMA_EMSR_EMSTR_MASK 0x0000FFFF
92669 +
92670 +#define DMA_TRANSFER_PORTID_MASK 0xFF000000
92671 +#define DMA_TRANSFER_TNUM_MASK 0x00FF0000
92672 +#define DMA_TRANSFER_LIODN_MASK 0x00000FFF
92673 +
92674 +#define DMA_HIGH_LIODN_MASK 0x0FFF0000
92675 +#define DMA_LOW_LIODN_MASK 0x00000FFF
92676 +
92677 +#define DMA_STATUS_CMD_QUEUE_NOT_EMPTY 0x10000000
92678 +#define DMA_STATUS_BUS_ERR 0x08000000
92679 +#define DMA_STATUS_READ_ECC 0x04000000
92680 +#define DMA_STATUS_SYSTEM_WRITE_ECC 0x02000000
92681 +#define DMA_STATUS_FM_WRITE_ECC 0x01000000
92682 +#define DMA_STATUS_SYSTEM_DPEXT_ECC 0x00800000
92683 +#define DMA_STATUS_FM_DPEXT_ECC 0x00400000
92684 +#define DMA_STATUS_SYSTEM_DPDAT_ECC 0x00200000
92685 +#define DMA_STATUS_FM_DPDAT_ECC 0x00100000
92686 +#define DMA_STATUS_FM_SPDAT_ECC 0x00080000
92687 +
92688 +#define FM_LIODN_BASE_MASK 0x00000FFF
92689 +
92690 +/* shifts */
92691 +#define DMA_MODE_CACHE_OR_SHIFT 30
92692 +#define DMA_MODE_BUS_PRI_SHIFT 16
92693 +#define DMA_MODE_AXI_DBG_SHIFT 24
92694 +#define DMA_MODE_CEN_SHIFT 13
92695 +#define DMA_MODE_BUS_PROT_SHIFT 10
92696 +#define DMA_MODE_DBG_SHIFT 7
92697 +#define DMA_MODE_EMER_LVL_SHIFT 6
92698 +#define DMA_MODE_AID_MODE_SHIFT 4
92699 +#define DMA_MODE_MAX_AXI_DBG_NUM_OF_BEATS 16
92700 +#define DMA_MODE_MAX_CAM_NUM_OF_ENTRIES 32
92701 +
92702 +#define DMA_THRESH_COMMQ_SHIFT 24
92703 +#define DMA_THRESH_READ_INT_BUF_SHIFT 16
92704 +
92705 +#define DMA_LIODN_SHIFT 16
92706 +
92707 +#define DMA_TRANSFER_PORTID_SHIFT 24
92708 +#define DMA_TRANSFER_TNUM_SHIFT 16
92709 +
92710 +/* sizes */
92711 +#define DMA_MAX_WATCHDOG 0xffffffff
92712 +
92713 +/* others */
92714 +#define DMA_CAM_SIZEOF_ENTRY 0x40
92715 +#define DMA_CAM_ALIGN 0x1000
92716 +#define DMA_CAM_UNITS 8
92717 +
92718 +/**************************************************************************//**
92719 + @Description General defines
92720 +*//***************************************************************************/
92721 +
92722 +#define FM_DEBUG_STATUS_REGISTER_OFFSET 0x000d1084UL
92723 +#define FM_UCODE_DEBUG_INSTRUCTION 0x6ffff805UL
92724 +
92725 +/**************************************************************************//**
92726 + @Description FPM defines
92727 +*//***************************************************************************/
92728 +
92729 +/* masks */
92730 +#define FPM_EV_MASK_DOUBLE_ECC 0x80000000
92731 +#define FPM_EV_MASK_STALL 0x40000000
92732 +#define FPM_EV_MASK_SINGLE_ECC 0x20000000
92733 +#define FPM_EV_MASK_RELEASE_FM 0x00010000
92734 +#define FPM_EV_MASK_DOUBLE_ECC_EN 0x00008000
92735 +#define FPM_EV_MASK_STALL_EN 0x00004000
92736 +#define FPM_EV_MASK_SINGLE_ECC_EN 0x00002000
92737 +#define FPM_EV_MASK_EXTERNAL_HALT 0x00000008
92738 +#define FPM_EV_MASK_ECC_ERR_HALT 0x00000004
92739 +
92740 +#define FPM_RAM_RAMS_ECC_EN 0x80000000
92741 +#define FPM_RAM_IRAM_ECC_EN 0x40000000
92742 +#define FPM_RAM_MURAM_ECC 0x00008000
92743 +#define FPM_RAM_IRAM_ECC 0x00004000
92744 +#define FPM_RAM_MURAM_TEST_ECC 0x20000000
92745 +#define FPM_RAM_IRAM_TEST_ECC 0x10000000
92746 +#define FPM_RAM_RAMS_ECC_EN_SRC_SEL 0x08000000
92747 +
92748 +#define FPM_IRAM_ECC_ERR_EX_EN 0x00020000
92749 +#define FPM_MURAM_ECC_ERR_EX_EN 0x00040000
92750 +
92751 +#define FPM_REV1_MAJOR_MASK 0x0000FF00
92752 +#define FPM_REV1_MINOR_MASK 0x000000FF
92753 +
92754 +#define FPM_REV2_INTEG_MASK 0x00FF0000
92755 +#define FPM_REV2_ERR_MASK 0x0000FF00
92756 +#define FPM_REV2_CFG_MASK 0x000000FF
92757 +
92758 +#define FPM_TS_FRACTION_MASK 0x0000FFFF
92759 +#define FPM_TS_CTL_EN 0x80000000
92760 +
92761 +#define FPM_PRC_REALSE_STALLED 0x00800000
92762 +
92763 +#define FPM_PS_STALLED 0x00800000
92764 +#define FPM_PS_FM_CTL1_SEL 0x80000000
92765 +#define FPM_PS_FM_CTL2_SEL 0x40000000
92766 +#define FPM_PS_FM_CTL_SEL_MASK (FPM_PS_FM_CTL1_SEL | FPM_PS_FM_CTL2_SEL)
92767 +
92768 +#define FPM_RSTC_FM_RESET 0x80000000
92769 +#define FPM_RSTC_10G0_RESET 0x04000000
92770 +#define FPM_RSTC_1G0_RESET 0x40000000
92771 +#define FPM_RSTC_1G1_RESET 0x20000000
92772 +#define FPM_RSTC_1G2_RESET 0x10000000
92773 +#define FPM_RSTC_1G3_RESET 0x08000000
92774 +#define FPM_RSTC_1G4_RESET 0x02000000
92775 +
92776 +
92777 +#define FPM_DISP_LIMIT_MASK 0x1F000000
92778 +#define FPM_THR1_PRS_MASK 0xFF000000
92779 +#define FPM_THR1_KG_MASK 0x00FF0000
92780 +#define FPM_THR1_PLCR_MASK 0x0000FF00
92781 +#define FPM_THR1_BMI_MASK 0x000000FF
92782 +
92783 +#define FPM_THR2_QMI_ENQ_MASK 0xFF000000
92784 +#define FPM_THR2_QMI_DEQ_MASK 0x000000FF
92785 +#define FPM_THR2_FM_CTL1_MASK 0x00FF0000
92786 +#define FPM_THR2_FM_CTL2_MASK 0x0000FF00
92787 +
92788 +/* shifts */
92789 +#define FPM_DISP_LIMIT_SHIFT 24
92790 +
92791 +#define FPM_THR1_PRS_SHIFT 24
92792 +#define FPM_THR1_KG_SHIFT 16
92793 +#define FPM_THR1_PLCR_SHIFT 8
92794 +#define FPM_THR1_BMI_SHIFT 0
92795 +
92796 +#define FPM_THR2_QMI_ENQ_SHIFT 24
92797 +#define FPM_THR2_QMI_DEQ_SHIFT 0
92798 +#define FPM_THR2_FM_CTL1_SHIFT 16
92799 +#define FPM_THR2_FM_CTL2_SHIFT 8
92800 +
92801 +#define FPM_EV_MASK_CAT_ERR_SHIFT 1
92802 +#define FPM_EV_MASK_DMA_ERR_SHIFT 0
92803 +
92804 +#define FPM_REV1_MAJOR_SHIFT 8
92805 +#define FPM_REV1_MINOR_SHIFT 0
92806 +
92807 +#define FPM_REV2_INTEG_SHIFT 16
92808 +#define FPM_REV2_ERR_SHIFT 8
92809 +#define FPM_REV2_CFG_SHIFT 0
92810 +
92811 +#define FPM_TS_INT_SHIFT 16
92812 +
92813 +#define FPM_PORT_FM_CTL_PORTID_SHIFT 24
92814 +
92815 +#define FPM_PS_FM_CTL_SEL_SHIFT 30
92816 +#define FPM_PRC_ORA_FM_CTL_SEL_SHIFT 16
92817 +
92818 +#define FPM_DISP_LIMIT_SHIFT 24
92819 +
92820 +/* Interrupts defines */
92821 +#define FPM_EVENT_FM_CTL_0 0x00008000
92822 +#define FPM_EVENT_FM_CTL 0x0000FF00
92823 +#define FPM_EVENT_FM_CTL_BRK 0x00000080
92824 +
92825 +/* others */
92826 +#define FPM_MAX_DISP_LIMIT 31
92827 +#define FPM_RSTC_FM_RESET 0x80000000
92828 +#define FPM_RSTC_1G0_RESET 0x40000000
92829 +#define FPM_RSTC_1G1_RESET 0x20000000
92830 +#define FPM_RSTC_1G2_RESET 0x10000000
92831 +#define FPM_RSTC_1G3_RESET 0x08000000
92832 +#define FPM_RSTC_10G0_RESET 0x04000000
92833 +#define FPM_RSTC_1G4_RESET 0x02000000
92834 +#define FPM_RSTC_1G5_RESET 0x01000000
92835 +#define FPM_RSTC_1G6_RESET 0x00800000
92836 +#define FPM_RSTC_1G7_RESET 0x00400000
92837 +#define FPM_RSTC_10G1_RESET 0x00200000
92838 +/**************************************************************************//**
92839 + @Description BMI defines
92840 +*//***************************************************************************/
92841 +/* masks */
92842 +#define BMI_INIT_START 0x80000000
92843 +#define BMI_ERR_INTR_EN_STORAGE_PROFILE_ECC 0x80000000
92844 +#define BMI_ERR_INTR_EN_LIST_RAM_ECC 0x40000000
92845 +#define BMI_ERR_INTR_EN_STATISTICS_RAM_ECC 0x20000000
92846 +#define BMI_ERR_INTR_EN_DISPATCH_RAM_ECC 0x10000000
92847 +#define BMI_NUM_OF_TASKS_MASK 0x3F000000
92848 +#define BMI_NUM_OF_EXTRA_TASKS_MASK 0x000F0000
92849 +#define BMI_NUM_OF_DMAS_MASK 0x00000F00
92850 +#define BMI_NUM_OF_EXTRA_DMAS_MASK 0x0000000F
92851 +#define BMI_FIFO_SIZE_MASK 0x000003FF
92852 +#define BMI_EXTRA_FIFO_SIZE_MASK 0x03FF0000
92853 +#define BMI_CFG2_DMAS_MASK 0x0000003F
92854 +#define BMI_TOTAL_FIFO_SIZE_MASK 0x07FF0000
92855 +#define BMI_TOTAL_NUM_OF_TASKS_MASK 0x007F0000
92856 +
92857 +/* shifts */
92858 +#define BMI_CFG2_TASKS_SHIFT 16
92859 +#define BMI_CFG2_DMAS_SHIFT 0
92860 +#define BMI_CFG1_FIFO_SIZE_SHIFT 16
92861 +#define BMI_FIFO_SIZE_SHIFT 0
92862 +#define BMI_EXTRA_FIFO_SIZE_SHIFT 16
92863 +#define BMI_NUM_OF_TASKS_SHIFT 24
92864 +#define BMI_EXTRA_NUM_OF_TASKS_SHIFT 16
92865 +#define BMI_NUM_OF_DMAS_SHIFT 8
92866 +#define BMI_EXTRA_NUM_OF_DMAS_SHIFT 0
92867 +
92868 +/* others */
92869 +#define BMI_FIFO_ALIGN 0x100
92870 +#define FMAN_BMI_FIFO_UNITS 0x100
92871 +
92872 +
92873 +/**************************************************************************//**
92874 + @Description QMI defines
92875 +*//***************************************************************************/
92876 +/* masks */
92877 +#define QMI_CFG_ENQ_EN 0x80000000
92878 +#define QMI_CFG_DEQ_EN 0x40000000
92879 +#define QMI_CFG_EN_COUNTERS 0x10000000
92880 +#define QMI_CFG_SOFT_RESET 0x01000000
92881 +#define QMI_CFG_DEQ_MASK 0x0000003F
92882 +#define QMI_CFG_ENQ_MASK 0x00003F00
92883 +
92884 +#define QMI_ERR_INTR_EN_DOUBLE_ECC 0x80000000
92885 +#define QMI_ERR_INTR_EN_DEQ_FROM_DEF 0x40000000
92886 +#define QMI_INTR_EN_SINGLE_ECC 0x80000000
92887 +
92888 +/* shifts */
92889 +#define QMI_CFG_ENQ_SHIFT 8
92890 +#define QMI_TAPC_TAP 22
92891 +
92892 +#define QMI_GS_HALT_NOT_BUSY 0x00000002
92893 +
92894 +/**************************************************************************//**
92895 + @Description IRAM defines
92896 +*//***************************************************************************/
92897 +/* masks */
92898 +#define IRAM_IADD_AIE 0x80000000
92899 +#define IRAM_READY 0x80000000
92900 +
92901 +uint32_t fman_get_bmi_err_event(struct fman_bmi_regs *bmi_rg);
92902 +uint32_t fman_get_qmi_err_event(struct fman_qmi_regs *qmi_rg);
92903 +uint32_t fman_get_dma_com_id(struct fman_dma_regs *dma_rg);
92904 +uint64_t fman_get_dma_addr(struct fman_dma_regs *dma_rg);
92905 +uint32_t fman_get_dma_err_event(struct fman_dma_regs *dma_rg);
92906 +uint32_t fman_get_fpm_err_event(struct fman_fpm_regs *fpm_rg);
92907 +uint32_t fman_get_muram_err_event(struct fman_fpm_regs *fpm_rg);
92908 +uint32_t fman_get_iram_err_event(struct fman_fpm_regs *fpm_rg);
92909 +uint32_t fman_get_qmi_event(struct fman_qmi_regs *qmi_rg);
92910 +uint32_t fman_get_fpm_error_interrupts(struct fman_fpm_regs *fpm_rg);
92911 +uint32_t fman_get_ctrl_intr(struct fman_fpm_regs *fpm_rg,
92912 + uint8_t event_reg_id);
92913 +uint8_t fman_get_qmi_deq_th(struct fman_qmi_regs *qmi_rg);
92914 +uint8_t fman_get_qmi_enq_th(struct fman_qmi_regs *qmi_rg);
92915 +uint16_t fman_get_size_of_fifo(struct fman_bmi_regs *bmi_rg, uint8_t port_id);
92916 +uint32_t fman_get_total_fifo_size(struct fman_bmi_regs *bmi_rg);
92917 +uint16_t fman_get_size_of_extra_fifo(struct fman_bmi_regs *bmi_rg,
92918 + uint8_t port_id);
92919 +uint8_t fman_get_num_of_tasks(struct fman_bmi_regs *bmi_rg, uint8_t port_id);
92920 +uint8_t fman_get_num_extra_tasks(struct fman_bmi_regs *bmi_rg,
92921 + uint8_t port_id);
92922 +uint8_t fman_get_num_of_dmas(struct fman_bmi_regs *bmi_rg, uint8_t port_id);
92923 +uint8_t fman_get_num_extra_dmas(struct fman_bmi_regs *bmi_rg,
92924 + uint8_t port_id);
92925 +uint32_t fman_get_normal_pending(struct fman_fpm_regs *fpm_rg);
92926 +uint32_t fman_get_controller_event(struct fman_fpm_regs *fpm_rg,
92927 + uint8_t reg_id);
92928 +uint32_t fman_get_error_pending(struct fman_fpm_regs *fpm_rg);
92929 +void fman_get_revision(struct fman_fpm_regs *fpm_rg, uint8_t *major,
92930 + uint8_t *minor);
92931 +uint32_t fman_get_counter(struct fman_rg *fman_rg,
92932 + enum fman_counters reg_name);
92933 +uint32_t fman_get_dma_status(struct fman_dma_regs *dma_rg);
92934 +
92935 +
92936 +int fman_set_erratum_10gmac_a004_wa(struct fman_fpm_regs *fpm_rg);
92937 +void fman_set_ctrl_intr(struct fman_fpm_regs *fpm_rg, uint8_t event_reg_id,
92938 + uint32_t enable_events);
92939 +void fman_set_num_of_riscs_per_port(struct fman_fpm_regs *fpm_rg,
92940 + uint8_t port_id,
92941 + uint8_t num_fman_ctrls,
92942 + uint32_t or_fman_ctrl);
92943 +void fman_set_order_restoration_per_port(struct fman_fpm_regs *fpm_rg,
92944 + uint8_t port_id,
92945 + bool independent_mode,
92946 + bool is_rx_port);
92947 +void fman_set_qmi_enq_th(struct fman_qmi_regs *qmi_rg, uint8_t val);
92948 +void fman_set_qmi_deq_th(struct fman_qmi_regs *qmi_rg, uint8_t val);
92949 +void fman_set_liodn_per_port(struct fman_rg *fman_rg,
92950 + uint8_t port_id,
92951 + uint16_t liodn_base,
92952 + uint16_t liodn_offset);
92953 +void fman_set_size_of_fifo(struct fman_bmi_regs *bmi_rg,
92954 + uint8_t port_id,
92955 + uint32_t size_of_fifo,
92956 + uint32_t extra_size_of_fifo);
92957 +void fman_set_num_of_tasks(struct fman_bmi_regs *bmi_rg,
92958 + uint8_t port_id,
92959 + uint8_t num_of_tasks,
92960 + uint8_t num_of_extra_tasks);
92961 +void fman_set_num_of_open_dmas(struct fman_bmi_regs *bmi_rg,
92962 + uint8_t port_id,
92963 + uint8_t num_of_open_dmas,
92964 + uint8_t num_of_extra_open_dmas,
92965 + uint8_t total_num_of_dmas);
92966 +void fman_set_ports_bandwidth(struct fman_bmi_regs *bmi_rg, uint8_t *weights);
92967 +int fman_set_exception(struct fman_rg *fman_rg,
92968 + enum fman_exceptions exception,
92969 + bool enable);
92970 +void fman_set_dma_emergency(struct fman_dma_regs *dma_rg, bool is_write,
92971 + bool enable);
92972 +void fman_set_dma_ext_bus_pri(struct fman_dma_regs *dma_rg, uint32_t pri);
92973 +void fman_set_congestion_group_pfc_priority(uint32_t *cpg_rg,
92974 + uint32_t congestion_group_id,
92975 + uint8_t piority_bit_map,
92976 + uint32_t reg_num);
92977 +
92978 +
92979 +void fman_defconfig(struct fman_cfg *cfg, bool is_master);
92980 +void fman_regconfig(struct fman_rg *fman_rg, struct fman_cfg *cfg);
92981 +int fman_fpm_init(struct fman_fpm_regs *fpm_rg, struct fman_cfg *cfg);
92982 +int fman_bmi_init(struct fman_bmi_regs *bmi_rg, struct fman_cfg *cfg);
92983 +int fman_qmi_init(struct fman_qmi_regs *qmi_rg, struct fman_cfg *cfg);
92984 +int fman_dma_init(struct fman_dma_regs *dma_rg, struct fman_cfg *cfg);
92985 +void fman_free_resources(struct fman_rg *fman_rg);
92986 +int fman_enable(struct fman_rg *fman_rg, struct fman_cfg *cfg);
92987 +void fman_reset(struct fman_fpm_regs *fpm_rg);
92988 +void fman_resume(struct fman_fpm_regs *fpm_rg);
92989 +
92990 +
92991 +void fman_enable_time_stamp(struct fman_fpm_regs *fpm_rg,
92992 + uint8_t count1ubit,
92993 + uint16_t fm_clk_freq);
92994 +void fman_enable_rams_ecc(struct fman_fpm_regs *fpm_rg);
92995 +void fman_qmi_disable_dispatch_limit(struct fman_fpm_regs *fpm_rg);
92996 +void fman_disable_rams_ecc(struct fman_fpm_regs *fpm_rg);
92997 +void fman_resume_stalled_port(struct fman_fpm_regs *fpm_rg, uint8_t port_id);
92998 +int fman_reset_mac(struct fman_fpm_regs *fpm_rg, uint8_t macId, bool is_10g);
92999 +bool fman_is_port_stalled(struct fman_fpm_regs *fpm_rg, uint8_t port_id);
93000 +bool fman_rams_ecc_is_external_ctl(struct fman_fpm_regs *fpm_rg);
93001 +bool fman_is_qmi_halt_not_busy_state(struct fman_qmi_regs *qmi_rg);
93002 +int fman_modify_counter(struct fman_rg *fman_rg,
93003 + enum fman_counters reg_name,
93004 + uint32_t val);
93005 +void fman_force_intr(struct fman_rg *fman_rg,
93006 + enum fman_exceptions exception);
93007 +void fman_set_vsp_window(struct fman_bmi_regs *bmi_rg,
93008 + uint8_t port_id,
93009 + uint8_t base_storage_profile,
93010 + uint8_t log2_num_of_profiles);
93011 +
93012 +/**************************************************************************//**
93013 + @Description default values
93014 +*//***************************************************************************/
93015 +#define DEFAULT_CATASTROPHIC_ERR E_FMAN_CATAST_ERR_STALL_PORT
93016 +#define DEFAULT_DMA_ERR E_FMAN_DMA_ERR_CATASTROPHIC
93017 +#define DEFAULT_HALT_ON_EXTERNAL_ACTIVATION FALSE /* do not change! if changed, must be disabled for rev1 ! */
93018 +#define DEFAULT_HALT_ON_UNRECOVERABLE_ECC_ERROR FALSE /* do not change! if changed, must be disabled for rev1 ! */
93019 +#define DEFAULT_EXTERNAL_ECC_RAMS_ENABLE FALSE
93020 +#define DEFAULT_AID_OVERRIDE FALSE
93021 +#define DEFAULT_AID_MODE E_FMAN_DMA_AID_OUT_TNUM
93022 +#define DEFAULT_DMA_COMM_Q_LOW 0x2A
93023 +#define DEFAULT_DMA_COMM_Q_HIGH 0x3F
93024 +#define DEFAULT_CACHE_OVERRIDE E_FMAN_DMA_NO_CACHE_OR
93025 +#define DEFAULT_DMA_CAM_NUM_OF_ENTRIES 64
93026 +#define DEFAULT_DMA_DBG_CNT_MODE E_FMAN_DMA_DBG_NO_CNT
93027 +#define DEFAULT_DMA_EN_EMERGENCY FALSE
93028 +#define DEFAULT_DMA_SOS_EMERGENCY 0
93029 +#define DEFAULT_DMA_WATCHDOG 0 /* disabled */
93030 +#define DEFAULT_DMA_EN_EMERGENCY_SMOOTHER FALSE
93031 +#define DEFAULT_DMA_EMERGENCY_SWITCH_COUNTER 0
93032 +#define DEFAULT_DISP_LIMIT 0
93033 +#define DEFAULT_PRS_DISP_TH 16
93034 +#define DEFAULT_PLCR_DISP_TH 16
93035 +#define DEFAULT_KG_DISP_TH 16
93036 +#define DEFAULT_BMI_DISP_TH 16
93037 +#define DEFAULT_QMI_ENQ_DISP_TH 16
93038 +#define DEFAULT_QMI_DEQ_DISP_TH 16
93039 +#define DEFAULT_FM_CTL1_DISP_TH 16
93040 +#define DEFAULT_FM_CTL2_DISP_TH 16
93041 +#define DEFAULT_TNUM_AGING_PERIOD 4
93042 +
93043 +
93044 +#endif /* __FSL_FMAN_H */
93045 --- /dev/null
93046 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/flib/fsl_fman_dtsec.h
93047 @@ -0,0 +1,1096 @@
93048 +/*
93049 + * Copyright 2008-2012 Freescale Semiconductor Inc.
93050 + *
93051 + * Redistribution and use in source and binary forms, with or without
93052 + * modification, are permitted provided that the following conditions are met:
93053 + * * Redistributions of source code must retain the above copyright
93054 + * notice, this list of conditions and the following disclaimer.
93055 + * * Redistributions in binary form must reproduce the above copyright
93056 + * notice, this list of conditions and the following disclaimer in the
93057 + * documentation and/or other materials provided with the distribution.
93058 + * * Neither the name of Freescale Semiconductor nor the
93059 + * names of its contributors may be used to endorse or promote products
93060 + * derived from this software without specific prior written permission.
93061 + *
93062 + *
93063 + * ALTERNATIVELY, this software may be distributed under the terms of the
93064 + * GNU General Public License ("GPL") as published by the Free Software
93065 + * Foundation, either version 2 of that License or (at your option) any
93066 + * later version.
93067 + *
93068 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
93069 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
93070 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
93071 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
93072 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
93073 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
93074 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
93075 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
93076 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
93077 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
93078 + */
93079 +
93080 +#ifndef __FSL_FMAN_DTSEC_H
93081 +#define __FSL_FMAN_DTSEC_H
93082 +
93083 +#include "common/general.h"
93084 +#include "fsl_enet.h"
93085 +
93086 +/**
93087 + * DOC: dTSEC Init sequence
93088 + *
93089 + * To prepare dTSEC block for transfer use the following call sequence:
93090 + *
93091 + * - fman_dtsec_defconfig() - This step is optional and yet recommended. Its
93092 + * use is to obtain the default dTSEC configuration parameters.
93093 + *
93094 + * - Change dtsec configuration in &dtsec_cfg. This structure will be used
93095 + * to customize the dTSEC behavior.
93096 + *
93097 + * - fman_dtsec_init() - Applies the configuration on dTSEC hardware. Note that
93098 + * dTSEC is initialized while both Tx and Rx are disabled.
93099 + *
93100 + * - fman_dtsec_set_mac_address() - Set the station address (mac address).
93101 + * This is used by dTSEC to match against received packets.
93102 + *
93103 + * - fman_dtsec_adjust_link() - Set the link speed and duplex parameters
93104 + * after the PHY establishes the link.
93105 + *
93106 + * - dtsec_enable_tx() and dtsec_enable_rx() to enable transmission and
93107 + * reception.
93108 + */
93109 +
93110 +/**
93111 + * DOC: dTSEC Graceful stop
93112 + *
93113 + * To temporary stop dTSEC activity use fman_dtsec_stop_tx() and
93114 + * fman_dtsec_stop_rx(). Note that these functions request dTSEC graceful stop
93115 + * but return before this stop is complete. To query for graceful stop
93116 + * completion use fman_dtsec_get_event() and check DTSEC_IEVENT_GTSC and
93117 + * DTSEC_IEVENT_GRSC bits. Alternatively the dTSEC interrupt mask can be set to
93118 + * enable graceful stop interrupts.
93119 + *
93120 + * To resume operation after graceful stop use fman_dtsec_start_tx() and
93121 + * fman_dtsec_start_rx().
93122 + */
93123 +
93124 +/**
93125 + * DOC: dTSEC interrupt handling
93126 + *
93127 + * This code does not provide an interrupt handler for dTSEC. Instead this
93128 + * handler should be implemented and registered to the operating system by the
93129 + * caller. Some primitives for accessing the event status and mask registers
93130 + * are provided.
93131 + *
93132 + * See "dTSEC Events" section for a list of events that dTSEC can generate.
93133 + */
93134 +
93135 +/**
93136 + * DOC: dTSEC Events
93137 + *
93138 + * Interrupt events cause dTSEC event bits to be set. Software may poll the
93139 + * event register at any time to check for pending interrupts. If an event
93140 + * occurs and its corresponding enable bit is set in the interrupt mask
93141 + * register, the event also causes a hardware interrupt at the PIC.
93142 + *
93143 + * To poll for event status use the fman_dtsec_get_event() function.
93144 + * To configure the interrupt mask use fman_dtsec_enable_interrupt() and
93145 + * fman_dtsec_disable_interrupt() functions.
93146 + * After servicing a dTSEC interrupt use fman_dtsec_ack_event to reset the
93147 + * serviced event bit.
93148 + *
93149 + * The following events may be signaled by dTSEC hardware:
93150 + *
93151 + * %DTSEC_IEVENT_BABR - Babbling receive error. This bit indicates that
93152 + * a frame was received with length in excess of the MAC's maximum frame length
93153 + * register.
93154 + *
93155 + * %DTSEC_IEVENT_RXC - Receive control (pause frame) interrupt. A pause
93156 + * control frame was received while Rx pause frame handling is enabled.
93157 + * Also see fman_dtsec_handle_rx_pause().
93158 + *
93159 + * %DTSEC_IEVENT_MSRO - MIB counter overflow. The count for one of the MIB
93160 + * counters has exceeded the size of its register.
93161 + *
93162 + * %DTSEC_IEVENT_GTSC - Graceful transmit stop complete. Graceful stop is now
93163 + * complete. The transmitter is in a stopped state, in which only pause frames
93164 + * can be transmitted.
93165 + * Also see fman_dtsec_stop_tx().
93166 + *
93167 + * %DTSEC_IEVENT_BABT - Babbling transmit error. The transmitted frame length
93168 + * has exceeded the value in the MAC's Maximum Frame Length register.
93169 + *
93170 + * %DTSEC_IEVENT_TXC - Transmit control (pause frame) interrupt. his bit
93171 + * indicates that a control frame was transmitted.
93172 + *
93173 + * %DTSEC_IEVENT_TXE - Transmit error. This bit indicates that an error
93174 + * occurred on the transmitted channel. This bit is set whenever any transmit
93175 + * error occurs which causes the dTSEC to discard all or part of a frame
93176 + * (LC, CRL, XFUN).
93177 + *
93178 + * %DTSEC_IEVENT_LC - Late collision. This bit indicates that a collision
93179 + * occurred beyond the collision window (slot time) in half-duplex mode.
93180 + * The frame is truncated with a bad CRC and the remainder of the frame
93181 + * is discarded.
93182 + *
93183 + * %DTSEC_IEVENT_CRL - Collision retry limit. is bit indicates that the number
93184 + * of successive transmission collisions has exceeded the MAC's half-duplex
93185 + * register's retransmission maximum count. The frame is discarded without
93186 + * being transmitted and transmission of the next frame commences. This only
93187 + * occurs while in half-duplex mode.
93188 + * The number of retransmit attempts can be set in
93189 + * &dtsec_halfdup_cfg.@retransmit before calling fman_dtsec_init().
93190 + *
93191 + * %DTSEC_IEVENT_XFUN - Transmit FIFO underrun. This bit indicates that the
93192 + * transmit FIFO became empty before the complete frame was transmitted.
93193 + * The frame is truncated with a bad CRC and the remainder of the frame is
93194 + * discarded.
93195 + *
93196 + * %DTSEC_IEVENT_MAG - TBD
93197 + *
93198 + * %DTSEC_IEVENT_MMRD - MII management read completion.
93199 + *
93200 + * %DTSEC_IEVENT_MMWR - MII management write completion.
93201 + *
93202 + * %DTSEC_IEVENT_GRSC - Graceful receive stop complete. It allows the user to
93203 + * know if the system has completed the stop and it is safe to write to receive
93204 + * registers (status, control or configuration registers) that are used by the
93205 + * system during normal operation.
93206 + *
93207 + * %DTSEC_IEVENT_TDPE - Internal data error on transmit. This bit indicates
93208 + * that the dTSEC has detected a parity error on its stored transmit data, which
93209 + * is likely to compromise the validity of recently transferred frames.
93210 + *
93211 + * %DTSEC_IEVENT_RDPE - Internal data error on receive. This bit indicates that
93212 + * the dTSEC has detected a parity error on its stored receive data, which is
93213 + * likely to compromise the validity of recently transferred frames.
93214 + */
93215 +/* Interrupt Mask Register (IMASK) */
93216 +#define DTSEC_IMASK_BREN 0x80000000
93217 +#define DTSEC_IMASK_RXCEN 0x40000000
93218 +#define DTSEC_IMASK_MSROEN 0x04000000
93219 +#define DTSEC_IMASK_GTSCEN 0x02000000
93220 +#define DTSEC_IMASK_BTEN 0x01000000
93221 +#define DTSEC_IMASK_TXCEN 0x00800000
93222 +#define DTSEC_IMASK_TXEEN 0x00400000
93223 +#define DTSEC_IMASK_LCEN 0x00040000
93224 +#define DTSEC_IMASK_CRLEN 0x00020000
93225 +#define DTSEC_IMASK_XFUNEN 0x00010000
93226 +#define DTSEC_IMASK_ABRTEN 0x00008000
93227 +#define DTSEC_IMASK_IFERREN 0x00004000
93228 +#define DTSEC_IMASK_MAGEN 0x00000800
93229 +#define DTSEC_IMASK_MMRDEN 0x00000400
93230 +#define DTSEC_IMASK_MMWREN 0x00000200
93231 +#define DTSEC_IMASK_GRSCEN 0x00000100
93232 +#define DTSEC_IMASK_TDPEEN 0x00000002
93233 +#define DTSEC_IMASK_RDPEEN 0x00000001
93234 +
93235 +#define DTSEC_EVENTS_MASK \
93236 + ((uint32_t)(DTSEC_IMASK_BREN | \
93237 + DTSEC_IMASK_RXCEN | \
93238 + DTSEC_IMASK_BTEN | \
93239 + DTSEC_IMASK_TXCEN | \
93240 + DTSEC_IMASK_TXEEN | \
93241 + DTSEC_IMASK_ABRTEN | \
93242 + DTSEC_IMASK_LCEN | \
93243 + DTSEC_IMASK_CRLEN | \
93244 + DTSEC_IMASK_XFUNEN | \
93245 + DTSEC_IMASK_IFERREN | \
93246 + DTSEC_IMASK_MAGEN | \
93247 + DTSEC_IMASK_TDPEEN | \
93248 + DTSEC_IMASK_RDPEEN))
93249 +
93250 +/* dtsec timestamp event bits */
93251 +#define TMR_PEMASK_TSREEN 0x00010000
93252 +#define TMR_PEVENT_TSRE 0x00010000
93253 +
93254 +/* Group address bit indication */
93255 +#define MAC_GROUP_ADDRESS 0x0000010000000000ULL
93256 +/* size in bytes of L2 address */
93257 +#define MAC_ADDRLEN 6
93258 +
93259 +#define DEFAULT_HALFDUP_ON FALSE
93260 +#define DEFAULT_HALFDUP_RETRANSMIT 0xf
93261 +#define DEFAULT_HALFDUP_COLL_WINDOW 0x37
93262 +#define DEFAULT_HALFDUP_EXCESS_DEFER TRUE
93263 +#define DEFAULT_HALFDUP_NO_BACKOFF FALSE
93264 +#define DEFAULT_HALFDUP_BP_NO_BACKOFF FALSE
93265 +#define DEFAULT_HALFDUP_ALT_BACKOFF_VAL 0x0A
93266 +#define DEFAULT_HALFDUP_ALT_BACKOFF_EN FALSE
93267 +#define DEFAULT_RX_DROP_BCAST FALSE
93268 +#define DEFAULT_RX_SHORT_FRM TRUE
93269 +#define DEFAULT_RX_LEN_CHECK FALSE
93270 +#define DEFAULT_TX_PAD_CRC TRUE
93271 +#define DEFAULT_TX_CRC FALSE
93272 +#define DEFAULT_RX_CTRL_ACC FALSE
93273 +#define DEFAULT_TX_PAUSE_TIME 0xf000
93274 +#define DEFAULT_TBIPA 5
93275 +#define DEFAULT_RX_PREPEND 0
93276 +#define DEFAULT_PTP_TSU_EN TRUE
93277 +#define DEFAULT_PTP_EXCEPTION_EN TRUE
93278 +#define DEFAULT_PREAMBLE_LEN 7
93279 +#define DEFAULT_RX_PREAMBLE FALSE
93280 +#define DEFAULT_TX_PREAMBLE FALSE
93281 +#define DEFAULT_LOOPBACK FALSE
93282 +#define DEFAULT_RX_TIME_STAMP_EN FALSE
93283 +#define DEFAULT_TX_TIME_STAMP_EN FALSE
93284 +#define DEFAULT_RX_FLOW TRUE
93285 +#define DEFAULT_TX_FLOW TRUE
93286 +#define DEFAULT_RX_GROUP_HASH_EXD FALSE
93287 +#define DEFAULT_TX_PAUSE_TIME_EXTD 0
93288 +#define DEFAULT_RX_PROMISC FALSE
93289 +#define DEFAULT_NON_BACK_TO_BACK_IPG1 0x40
93290 +#define DEFAULT_NON_BACK_TO_BACK_IPG2 0x60
93291 +#define DEFAULT_MIN_IFG_ENFORCEMENT 0x50
93292 +#define DEFAULT_BACK_TO_BACK_IPG 0x60
93293 +#define DEFAULT_MAXIMUM_FRAME 0x600
93294 +#define DEFAULT_TBI_PHY_ADDR 5
93295 +#define DEFAULT_WAKE_ON_LAN FALSE
93296 +
93297 +/* register related defines (bits, field offsets..) */
93298 +#define DTSEC_ID1_ID 0xffff0000
93299 +#define DTSEC_ID1_REV_MJ 0x0000FF00
93300 +#define DTSEC_ID1_REV_MN 0x000000ff
93301 +
93302 +#define DTSEC_ID2_INT_REDUCED_OFF 0x00010000
93303 +#define DTSEC_ID2_INT_NORMAL_OFF 0x00020000
93304 +
93305 +#define DTSEC_ECNTRL_CLRCNT 0x00004000
93306 +#define DTSEC_ECNTRL_AUTOZ 0x00002000
93307 +#define DTSEC_ECNTRL_STEN 0x00001000
93308 +#define DTSEC_ECNTRL_CFG_RO 0x80000000
93309 +#define DTSEC_ECNTRL_GMIIM 0x00000040
93310 +#define DTSEC_ECNTRL_TBIM 0x00000020
93311 +#define DTSEC_ECNTRL_SGMIIM 0x00000002
93312 +#define DTSEC_ECNTRL_RPM 0x00000010
93313 +#define DTSEC_ECNTRL_R100M 0x00000008
93314 +#define DTSEC_ECNTRL_RMM 0x00000004
93315 +#define DTSEC_ECNTRL_QSGMIIM 0x00000001
93316 +
93317 +#define DTSEC_TCTRL_THDF 0x00000800
93318 +#define DTSEC_TCTRL_TTSE 0x00000040
93319 +#define DTSEC_TCTRL_GTS 0x00000020
93320 +#define DTSEC_TCTRL_TFC_PAUSE 0x00000010
93321 +
93322 +/* PTV offsets */
93323 +#define PTV_PTE_OFST 16
93324 +
93325 +#define RCTRL_CFA 0x00008000
93326 +#define RCTRL_GHTX 0x00000400
93327 +#define RCTRL_RTSE 0x00000040
93328 +#define RCTRL_GRS 0x00000020
93329 +#define RCTRL_BC_REJ 0x00000010
93330 +#define RCTRL_MPROM 0x00000008
93331 +#define RCTRL_RSF 0x00000004
93332 +#define RCTRL_UPROM 0x00000001
93333 +#define RCTRL_PROM (RCTRL_UPROM | RCTRL_MPROM)
93334 +
93335 +#define TMR_CTL_ESFDP 0x00000800
93336 +#define TMR_CTL_ESFDE 0x00000400
93337 +
93338 +#define MACCFG1_SOFT_RESET 0x80000000
93339 +#define MACCFG1_LOOPBACK 0x00000100
93340 +#define MACCFG1_RX_FLOW 0x00000020
93341 +#define MACCFG1_TX_FLOW 0x00000010
93342 +#define MACCFG1_TX_EN 0x00000001
93343 +#define MACCFG1_RX_EN 0x00000004
93344 +#define MACCFG1_RESET_RxMC 0x00080000
93345 +#define MACCFG1_RESET_TxMC 0x00040000
93346 +#define MACCFG1_RESET_RxFUN 0x00020000
93347 +#define MACCFG1_RESET_TxFUN 0x00010000
93348 +
93349 +#define MACCFG2_NIBBLE_MODE 0x00000100
93350 +#define MACCFG2_BYTE_MODE 0x00000200
93351 +#define MACCFG2_PRE_AM_Rx_EN 0x00000080
93352 +#define MACCFG2_PRE_AM_Tx_EN 0x00000040
93353 +#define MACCFG2_LENGTH_CHECK 0x00000010
93354 +#define MACCFG2_MAGIC_PACKET_EN 0x00000008
93355 +#define MACCFG2_PAD_CRC_EN 0x00000004
93356 +#define MACCFG2_CRC_EN 0x00000002
93357 +#define MACCFG2_FULL_DUPLEX 0x00000001
93358 +
93359 +#define PREAMBLE_LENGTH_SHIFT 12
93360 +
93361 +#define IPGIFG_NON_BACK_TO_BACK_IPG_1_SHIFT 24
93362 +#define IPGIFG_NON_BACK_TO_BACK_IPG_2_SHIFT 16
93363 +#define IPGIFG_MIN_IFG_ENFORCEMENT_SHIFT 8
93364 +
93365 +#define IPGIFG_NON_BACK_TO_BACK_IPG_1 0x7F000000
93366 +#define IPGIFG_NON_BACK_TO_BACK_IPG_2 0x007F0000
93367 +#define IPGIFG_MIN_IFG_ENFORCEMENT 0x0000FF00
93368 +#define IPGIFG_BACK_TO_BACK_IPG 0x0000007F
93369 +
93370 +#define HAFDUP_ALT_BEB 0x00080000
93371 +#define HAFDUP_BP_NO_BACKOFF 0x00040000
93372 +#define HAFDUP_NO_BACKOFF 0x00020000
93373 +#define HAFDUP_EXCESS_DEFER 0x00010000
93374 +#define HAFDUP_COLLISION_WINDOW 0x000003ff
93375 +
93376 +#define HAFDUP_ALTERNATE_BEB_TRUNCATION_SHIFT 20
93377 +#define HAFDUP_RETRANSMISSION_MAX_SHIFT 12
93378 +#define HAFDUP_RETRANSMISSION_MAX 0x0000f000
93379 +
93380 +#define NUM_OF_HASH_REGS 8 /* Number of hash table registers */
93381 +
93382 +/* CAR1/2 bits */
93383 +#define DTSEC_CAR1_TR64 0x80000000
93384 +#define DTSEC_CAR1_TR127 0x40000000
93385 +#define DTSEC_CAR1_TR255 0x20000000
93386 +#define DTSEC_CAR1_TR511 0x10000000
93387 +#define DTSEC_CAR1_TRK1 0x08000000
93388 +#define DTSEC_CAR1_TRMAX 0x04000000
93389 +#define DTSEC_CAR1_TRMGV 0x02000000
93390 +
93391 +#define DTSEC_CAR1_RBYT 0x00010000
93392 +#define DTSEC_CAR1_RPKT 0x00008000
93393 +#define DTSEC_CAR1_RFCS 0x00004000
93394 +#define DTSEC_CAR1_RMCA 0x00002000
93395 +#define DTSEC_CAR1_RBCA 0x00001000
93396 +#define DTSEC_CAR1_RXCF 0x00000800
93397 +#define DTSEC_CAR1_RXPF 0x00000400
93398 +#define DTSEC_CAR1_RXUO 0x00000200
93399 +#define DTSEC_CAR1_RALN 0x00000100
93400 +#define DTSEC_CAR1_RFLR 0x00000080
93401 +#define DTSEC_CAR1_RCDE 0x00000040
93402 +#define DTSEC_CAR1_RCSE 0x00000020
93403 +#define DTSEC_CAR1_RUND 0x00000010
93404 +#define DTSEC_CAR1_ROVR 0x00000008
93405 +#define DTSEC_CAR1_RFRG 0x00000004
93406 +#define DTSEC_CAR1_RJBR 0x00000002
93407 +#define DTSEC_CAR1_RDRP 0x00000001
93408 +
93409 +#define DTSEC_CAR2_TJBR 0x00080000
93410 +#define DTSEC_CAR2_TFCS 0x00040000
93411 +#define DTSEC_CAR2_TXCF 0x00020000
93412 +#define DTSEC_CAR2_TOVR 0x00010000
93413 +#define DTSEC_CAR2_TUND 0x00008000
93414 +#define DTSEC_CAR2_TFRG 0x00004000
93415 +#define DTSEC_CAR2_TBYT 0x00002000
93416 +#define DTSEC_CAR2_TPKT 0x00001000
93417 +#define DTSEC_CAR2_TMCA 0x00000800
93418 +#define DTSEC_CAR2_TBCA 0x00000400
93419 +#define DTSEC_CAR2_TXPF 0x00000200
93420 +#define DTSEC_CAR2_TDFR 0x00000100
93421 +#define DTSEC_CAR2_TEDF 0x00000080
93422 +#define DTSEC_CAR2_TSCL 0x00000040
93423 +#define DTSEC_CAR2_TMCL 0x00000020
93424 +#define DTSEC_CAR2_TLCL 0x00000010
93425 +#define DTSEC_CAR2_TXCL 0x00000008
93426 +#define DTSEC_CAR2_TNCL 0x00000004
93427 +#define DTSEC_CAR2_TDRP 0x00000001
93428 +
93429 +#define CAM1_ERRORS_ONLY \
93430 + (DTSEC_CAR1_RXPF | DTSEC_CAR1_RALN | DTSEC_CAR1_RFLR \
93431 + | DTSEC_CAR1_RCDE | DTSEC_CAR1_RCSE | DTSEC_CAR1_RUND \
93432 + | DTSEC_CAR1_ROVR | DTSEC_CAR1_RFRG | DTSEC_CAR1_RJBR \
93433 + | DTSEC_CAR1_RDRP)
93434 +
93435 +#define CAM2_ERRORS_ONLY (DTSEC_CAR2_TFCS | DTSEC_CAR2_TXPF | DTSEC_CAR2_TDRP)
93436 +
93437 +/*
93438 + * Group of dTSEC specific counters relating to the standard RMON MIB Group 1
93439 + * (or Ethernet) statistics.
93440 + */
93441 +#define CAM1_MIB_GRP_1 \
93442 + (DTSEC_CAR1_RDRP | DTSEC_CAR1_RBYT | DTSEC_CAR1_RPKT | DTSEC_CAR1_RMCA\
93443 + | DTSEC_CAR1_RBCA | DTSEC_CAR1_RALN | DTSEC_CAR1_RUND | DTSEC_CAR1_ROVR\
93444 + | DTSEC_CAR1_RFRG | DTSEC_CAR1_RJBR \
93445 + | DTSEC_CAR1_TR64 | DTSEC_CAR1_TR127 | DTSEC_CAR1_TR255 \
93446 + | DTSEC_CAR1_TR511 | DTSEC_CAR1_TRMAX)
93447 +
93448 +#define CAM2_MIB_GRP_1 (DTSEC_CAR2_TNCL | DTSEC_CAR2_TDRP)
93449 +
93450 +/* memory map */
93451 +
93452 +struct dtsec_regs {
93453 + /* dTSEC General Control and Status Registers */
93454 + uint32_t tsec_id; /* 0x000 ETSEC_ID register */
93455 + uint32_t tsec_id2; /* 0x004 ETSEC_ID2 register */
93456 + uint32_t ievent; /* 0x008 Interrupt event register */
93457 + uint32_t imask; /* 0x00C Interrupt mask register */
93458 + uint32_t reserved0010[1];
93459 + uint32_t ecntrl; /* 0x014 E control register */
93460 + uint32_t ptv; /* 0x018 Pause time value register */
93461 + uint32_t tbipa; /* 0x01C TBI PHY address register */
93462 + uint32_t tmr_ctrl; /* 0x020 Time-stamp Control register */
93463 + uint32_t tmr_pevent; /* 0x024 Time-stamp event register */
93464 + uint32_t tmr_pemask; /* 0x028 Timer event mask register */
93465 + uint32_t reserved002c[5];
93466 + uint32_t tctrl; /* 0x040 Transmit control register */
93467 + uint32_t reserved0044[3];
93468 + uint32_t rctrl; /* 0x050 Receive control register */
93469 + uint32_t reserved0054[11];
93470 + uint32_t igaddr[8]; /* 0x080-0x09C Individual/group address */
93471 + uint32_t gaddr[8]; /* 0x0A0-0x0BC Group address registers 0-7 */
93472 + uint32_t reserved00c0[16];
93473 + uint32_t maccfg1; /* 0x100 MAC configuration #1 */
93474 + uint32_t maccfg2; /* 0x104 MAC configuration #2 */
93475 + uint32_t ipgifg; /* 0x108 IPG/IFG */
93476 + uint32_t hafdup; /* 0x10C Half-duplex */
93477 + uint32_t maxfrm; /* 0x110 Maximum frame */
93478 + uint32_t reserved0114[10];
93479 + uint32_t ifstat; /* 0x13C Interface status */
93480 + uint32_t macstnaddr1; /* 0x140 Station Address,part 1 */
93481 + uint32_t macstnaddr2; /* 0x144 Station Address,part 2 */
93482 + struct {
93483 + uint32_t exact_match1; /* octets 1-4 */
93484 + uint32_t exact_match2; /* octets 5-6 */
93485 + } macaddr[15]; /* 0x148-0x1BC mac exact match addresses 1-15 */
93486 + uint32_t reserved01c0[16];
93487 + uint32_t tr64; /* 0x200 transmit and receive 64 byte frame counter */
93488 + uint32_t tr127; /* 0x204 transmit and receive 65 to 127 byte frame
93489 + * counter */
93490 + uint32_t tr255; /* 0x208 transmit and receive 128 to 255 byte frame
93491 + * counter */
93492 + uint32_t tr511; /* 0x20C transmit and receive 256 to 511 byte frame
93493 + * counter */
93494 + uint32_t tr1k; /* 0x210 transmit and receive 512 to 1023 byte frame
93495 + * counter */
93496 + uint32_t trmax; /* 0x214 transmit and receive 1024 to 1518 byte frame
93497 + * counter */
93498 + uint32_t trmgv; /* 0x218 transmit and receive 1519 to 1522 byte good
93499 + * VLAN frame count */
93500 + uint32_t rbyt; /* 0x21C receive byte counter */
93501 + uint32_t rpkt; /* 0x220 receive packet counter */
93502 + uint32_t rfcs; /* 0x224 receive FCS error counter */
93503 + uint32_t rmca; /* 0x228 RMCA receive multicast packet counter */
93504 + uint32_t rbca; /* 0x22C receive broadcast packet counter */
93505 + uint32_t rxcf; /* 0x230 receive control frame packet counter */
93506 + uint32_t rxpf; /* 0x234 receive pause frame packet counter */
93507 + uint32_t rxuo; /* 0x238 receive unknown OP code counter */
93508 + uint32_t raln; /* 0x23C receive alignment error counter */
93509 + uint32_t rflr; /* 0x240 receive frame length error counter */
93510 + uint32_t rcde; /* 0x244 receive code error counter */
93511 + uint32_t rcse; /* 0x248 receive carrier sense error counter */
93512 + uint32_t rund; /* 0x24C receive undersize packet counter */
93513 + uint32_t rovr; /* 0x250 receive oversize packet counter */
93514 + uint32_t rfrg; /* 0x254 receive fragments counter */
93515 + uint32_t rjbr; /* 0x258 receive jabber counter */
93516 + uint32_t rdrp; /* 0x25C receive drop */
93517 + uint32_t tbyt; /* 0x260 transmit byte counter */
93518 + uint32_t tpkt; /* 0x264 transmit packet counter */
93519 + uint32_t tmca; /* 0x268 transmit multicast packet counter */
93520 + uint32_t tbca; /* 0x26C transmit broadcast packet counter */
93521 + uint32_t txpf; /* 0x270 transmit pause control frame counter */
93522 + uint32_t tdfr; /* 0x274 transmit deferral packet counter */
93523 + uint32_t tedf; /* 0x278 transmit excessive deferral packet counter */
93524 + uint32_t tscl; /* 0x27C transmit single collision packet counter */
93525 + uint32_t tmcl; /* 0x280 transmit multiple collision packet counter */
93526 + uint32_t tlcl; /* 0x284 transmit late collision packet counter */
93527 + uint32_t txcl; /* 0x288 transmit excessive collision packet counter */
93528 + uint32_t tncl; /* 0x28C transmit total collision counter */
93529 + uint32_t reserved0290[1];
93530 + uint32_t tdrp; /* 0x294 transmit drop frame counter */
93531 + uint32_t tjbr; /* 0x298 transmit jabber frame counter */
93532 + uint32_t tfcs; /* 0x29C transmit FCS error counter */
93533 + uint32_t txcf; /* 0x2A0 transmit control frame counter */
93534 + uint32_t tovr; /* 0x2A4 transmit oversize frame counter */
93535 + uint32_t tund; /* 0x2A8 transmit undersize frame counter */
93536 + uint32_t tfrg; /* 0x2AC transmit fragments frame counter */
93537 + uint32_t car1; /* 0x2B0 carry register one register* */
93538 + uint32_t car2; /* 0x2B4 carry register two register* */
93539 + uint32_t cam1; /* 0x2B8 carry register one mask register */
93540 + uint32_t cam2; /* 0x2BC carry register two mask register */
93541 + uint32_t reserved02c0[848];
93542 +};
93543 +
93544 +/**
93545 + * struct dtsec_mib_grp_1_counters - MIB counter overflows
93546 + *
93547 + * @tr64: Transmit and Receive 64 byte frame count. Increment for each
93548 + * good or bad frame, of any type, transmitted or received, which
93549 + * is 64 bytes in length.
93550 + * @tr127: Transmit and Receive 65 to 127 byte frame count. Increments for
93551 + * each good or bad frame of any type, transmitted or received,
93552 + * which is 65-127 bytes in length.
93553 + * @tr255: Transmit and Receive 128 to 255 byte frame count. Increments
93554 + * for each good or bad frame, of any type, transmitted or
93555 + * received, which is 128-255 bytes in length.
93556 + * @tr511: Transmit and Receive 256 to 511 byte frame count. Increments
93557 + * for each good or bad frame, of any type, transmitted or
93558 + * received, which is 256-511 bytes in length.
93559 + * @tr1k: Transmit and Receive 512 to 1023 byte frame count. Increments
93560 + * for each good or bad frame, of any type, transmitted or
93561 + * received, which is 512-1023 bytes in length.
93562 + * @trmax: Transmit and Receive 1024 to 1518 byte frame count. Increments
93563 + * for each good or bad frame, of any type, transmitted or
93564 + * received, which is 1024-1518 bytes in length.
93565 + * @rfrg: Receive fragments count. Increments for each received frame
93566 + * which is less than 64 bytes in length and contains an invalid
93567 + * FCS. This includes integral and non-integral lengths.
93568 + * @rjbr: Receive jabber count. Increments for received frames which
93569 + * exceed 1518 (non VLAN) or 1522 (VLAN) bytes and contain an
93570 + * invalid FCS. This includes alignment errors.
93571 + * @rdrp: Receive dropped packets count. Increments for received frames
93572 + * which are streamed to system but are later dropped due to lack
93573 + * of system resources. Does not increment for frames rejected due
93574 + * to address filtering.
93575 + * @raln: Receive alignment error count. Increments for each received
93576 + * frame from 64 to 1518 (non VLAN) or 1522 (VLAN) which contains
93577 + * an invalid FCS and is not an integral number of bytes.
93578 + * @rund: Receive undersize packet count. Increments each time a frame is
93579 + * received which is less than 64 bytes in length and contains a
93580 + * valid FCS and is otherwise well formed. This count does not
93581 + * include range length errors.
93582 + * @rovr: Receive oversize packet count. Increments each time a frame is
93583 + * received which exceeded 1518 (non VLAN) or 1522 (VLAN) and
93584 + * contains a valid FCS and is otherwise well formed.
93585 + * @rbyt: Receive byte count. Increments by the byte count of frames
93586 + * received, including those in bad packets, excluding preamble and
93587 + * SFD but including FCS bytes.
93588 + * @rpkt: Receive packet count. Increments for each received frame
93589 + * (including bad packets, all unicast, broadcast, and multicast
93590 + * packets).
93591 + * @rmca: Receive multicast packet count. Increments for each multicast
93592 + * frame with valid CRC and of lengths 64 to 1518 (non VLAN) or
93593 + * 1522 (VLAN), excluding broadcast frames. This count does not
93594 + * include range/length errors.
93595 + * @rbca: Receive broadcast packet count. Increments for each broadcast
93596 + * frame with valid CRC and of lengths 64 to 1518 (non VLAN) or
93597 + * 1522 (VLAN), excluding multicast frames. Does not include
93598 + * range/length errors.
93599 + * @tdrp: Transmit drop frame count. Increments each time a memory error
93600 + * or an underrun has occurred.
93601 + * @tncl: Transmit total collision counter. Increments by the number of
93602 + * collisions experienced during the transmission of a frame. Does
93603 + * not increment for aborted frames.
93604 + *
93605 + * The structure contains a group of dTSEC HW specific counters relating to the
93606 + * standard RMON MIB Group 1 (or Ethernet statistics) counters. This structure
93607 + * is counting only the carry events of the corresponding HW counters.
93608 + *
93609 + * tr64 to trmax notes: Frame sizes specified are considered excluding preamble
93610 + * and SFD but including FCS bytes.
93611 + */
93612 +struct dtsec_mib_grp_1_counters {
93613 + uint64_t rdrp;
93614 + uint64_t tdrp;
93615 + uint64_t rbyt;
93616 + uint64_t rpkt;
93617 + uint64_t rbca;
93618 + uint64_t rmca;
93619 + uint64_t raln;
93620 + uint64_t rund;
93621 + uint64_t rovr;
93622 + uint64_t rfrg;
93623 + uint64_t rjbr;
93624 + uint64_t tncl;
93625 + uint64_t tr64;
93626 + uint64_t tr127;
93627 + uint64_t tr255;
93628 + uint64_t tr511;
93629 + uint64_t tr1k;
93630 + uint64_t trmax;
93631 +};
93632 +
93633 +enum dtsec_stat_counters {
93634 + E_DTSEC_STAT_TR64,
93635 + E_DTSEC_STAT_TR127,
93636 + E_DTSEC_STAT_TR255,
93637 + E_DTSEC_STAT_TR511,
93638 + E_DTSEC_STAT_TR1K,
93639 + E_DTSEC_STAT_TRMAX,
93640 + E_DTSEC_STAT_TRMGV,
93641 + E_DTSEC_STAT_RBYT,
93642 + E_DTSEC_STAT_RPKT,
93643 + E_DTSEC_STAT_RMCA,
93644 + E_DTSEC_STAT_RBCA,
93645 + E_DTSEC_STAT_RXPF,
93646 + E_DTSEC_STAT_RALN,
93647 + E_DTSEC_STAT_RFLR,
93648 + E_DTSEC_STAT_RCDE,
93649 + E_DTSEC_STAT_RCSE,
93650 + E_DTSEC_STAT_RUND,
93651 + E_DTSEC_STAT_ROVR,
93652 + E_DTSEC_STAT_RFRG,
93653 + E_DTSEC_STAT_RJBR,
93654 + E_DTSEC_STAT_RDRP,
93655 + E_DTSEC_STAT_TFCS,
93656 + E_DTSEC_STAT_TBYT,
93657 + E_DTSEC_STAT_TPKT,
93658 + E_DTSEC_STAT_TMCA,
93659 + E_DTSEC_STAT_TBCA,
93660 + E_DTSEC_STAT_TXPF,
93661 + E_DTSEC_STAT_TNCL,
93662 + E_DTSEC_STAT_TDRP
93663 +};
93664 +
93665 +enum dtsec_stat_level {
93666 + /* No statistics */
93667 + E_MAC_STAT_NONE = 0,
93668 + /* Only RMON MIB group 1 (ether stats). Optimized for performance */
93669 + E_MAC_STAT_MIB_GRP1,
93670 + /* Only error counters are available. Optimized for performance */
93671 + E_MAC_STAT_PARTIAL,
93672 + /* All counters available. Not optimized for performance */
93673 + E_MAC_STAT_FULL
93674 +};
93675 +
93676 +
93677 +/**
93678 + * struct dtsec_cfg - dTSEC configuration
93679 + *
93680 + * @halfdup_on: Transmit half-duplex flow control, under software
93681 + * control for 10/100-Mbps half-duplex media. If set,
93682 + * back pressure is applied to media by raising carrier.
93683 + * @halfdup_retransmit: Number of retransmission attempts following a collision.
93684 + * If this is exceeded dTSEC aborts transmission due to
93685 + * excessive collisions. The standard specifies the
93686 + * attempt limit to be 15.
93687 + * @halfdup_coll_window:The number of bytes of the frame during which
93688 + * collisions may occur. The default value of 55
93689 + * corresponds to the frame byte at the end of the
93690 + * standard 512-bit slot time window. If collisions are
93691 + * detected after this byte, the late collision event is
93692 + * asserted and transmission of current frame is aborted.
93693 + * @rx_drop_bcast: Discard broadcast frames. If set, all broadcast frames
93694 + * will be discarded by dTSEC.
93695 + * @rx_short_frm: Accept short frames. If set, dTSEC will accept frames
93696 + * of length 14..63 bytes.
93697 + * @rx_len_check: Length check for received frames. If set, the MAC
93698 + * checks the frame's length field on receive to ensure it
93699 + * matches the actual data field length. This only works
93700 + * for received frames with length field less than 1500.
93701 + * No check is performed for larger frames.
93702 + * @tx_pad_crc: Pad and append CRC. If set, the MAC pads all
93703 + * transmitted short frames and appends a CRC to every
93704 + * frame regardless of padding requirement.
93705 + * @tx_crc: Transmission CRC enable. If set, the MAC appends a CRC
93706 + * to all frames. If frames presented to the MAC have a
93707 + * valid length and contain a valid CRC, @tx_crc should be
93708 + * reset.
93709 + * This field is ignored if @tx_pad_crc is set.
93710 + * @rx_ctrl_acc: Control frame accept. If set, this overrides 802.3
93711 + * standard control frame behavior, and all Ethernet frames
93712 + * that have an ethertype of 0x8808 are treated as normal
93713 + * Ethernet frames and passed up to the packet interface on
93714 + * a DA match. Received pause control frames are passed to
93715 + * the packet interface only if Rx flow control is also
93716 + * disabled. See fman_dtsec_handle_rx_pause() function.
93717 + * @tx_pause_time: Transmit pause time value. This pause value is used as
93718 + * part of the pause frame to be sent when a transmit pause
93719 + * frame is initiated. If set to 0 this disables
93720 + * transmission of pause frames.
93721 + * @rx_preamble: Receive preamble enable. If set, the MAC recovers the
93722 + * received Ethernet 7-byte preamble and passes it to the
93723 + * packet interface at the start of each received frame.
93724 + * This field should be reset for internal MAC loop-back
93725 + * mode.
93726 + * @tx_preamble: User defined preamble enable for transmitted frames.
93727 + * If set, a user-defined preamble must passed to the MAC
93728 + * and it is transmitted instead of the standard preamble.
93729 + * @preamble_len: Length, in bytes, of the preamble field preceding each
93730 + * Ethernet start-of-frame delimiter byte. The default
93731 + * value of 0x7 should be used in order to guarantee
93732 + * reliable operation with IEEE 802.3 compliant hardware.
93733 + * @rx_prepend: Packet alignment padding length. The specified number
93734 + * of bytes (1-31) of zero padding are inserted before the
93735 + * start of each received frame. For Ethernet, where
93736 + * optional preamble extraction is enabled, the padding
93737 + * appears before the preamble, otherwise the padding
93738 + * precedes the layer 2 header.
93739 + *
93740 + * This structure contains basic dTSEC configuration and must be passed to
93741 + * fman_dtsec_init() function. A default set of configuration values can be
93742 + * obtained by calling fman_dtsec_defconfig().
93743 + */
93744 +struct dtsec_cfg {
93745 + bool halfdup_on;
93746 + bool halfdup_alt_backoff_en;
93747 + bool halfdup_excess_defer;
93748 + bool halfdup_no_backoff;
93749 + bool halfdup_bp_no_backoff;
93750 + uint8_t halfdup_alt_backoff_val;
93751 + uint16_t halfdup_retransmit;
93752 + uint16_t halfdup_coll_window;
93753 + bool rx_drop_bcast;
93754 + bool rx_short_frm;
93755 + bool rx_len_check;
93756 + bool tx_pad_crc;
93757 + bool tx_crc;
93758 + bool rx_ctrl_acc;
93759 + unsigned short tx_pause_time;
93760 + unsigned short tbipa;
93761 + bool ptp_tsu_en;
93762 + bool ptp_exception_en;
93763 + bool rx_preamble;
93764 + bool tx_preamble;
93765 + unsigned char preamble_len;
93766 + unsigned char rx_prepend;
93767 + bool loopback;
93768 + bool rx_time_stamp_en;
93769 + bool tx_time_stamp_en;
93770 + bool rx_flow;
93771 + bool tx_flow;
93772 + bool rx_group_hash_exd;
93773 + bool rx_promisc;
93774 + uint8_t tbi_phy_addr;
93775 + uint16_t tx_pause_time_extd;
93776 + uint16_t maximum_frame;
93777 + uint32_t non_back_to_back_ipg1;
93778 + uint32_t non_back_to_back_ipg2;
93779 + uint32_t min_ifg_enforcement;
93780 + uint32_t back_to_back_ipg;
93781 + bool wake_on_lan;
93782 +};
93783 +
93784 +
93785 +/**
93786 + * fman_dtsec_defconfig() - Get default dTSEC configuration
93787 + * @cfg: pointer to configuration structure.
93788 + *
93789 + * Call this function to obtain a default set of configuration values for
93790 + * initializing dTSEC. The user can overwrite any of the values before calling
93791 + * fman_dtsec_init(), if specific configuration needs to be applied.
93792 + */
93793 +void fman_dtsec_defconfig(struct dtsec_cfg *cfg);
93794 +
93795 +/**
93796 + * fman_dtsec_init() - Init dTSEC hardware block
93797 + * @regs: Pointer to dTSEC register block
93798 + * @cfg: dTSEC configuration data
93799 + * @iface_mode: dTSEC interface mode, the type of MAC - PHY interface.
93800 + * @iface_speed: 1G or 10G
93801 + * @macaddr: MAC station address to be assigned to the device
93802 + * @fm_rev_maj: major rev number
93803 + * @fm_rev_min: minor rev number
93804 + * @exceptions_mask: initial exceptions mask
93805 + *
93806 + * This function initializes dTSEC and applies basic configuration.
93807 + *
93808 + * dTSEC initialization sequence:
93809 + * Before enabling Rx/Tx call dtsec_set_address() to set MAC address,
93810 + * fman_dtsec_adjust_link() to configure interface speed and duplex and finally
93811 + * dtsec_enable_tx()/dtsec_enable_rx() to start transmission and reception.
93812 + *
93813 + * Returns: 0 if successful, an error code otherwise.
93814 + */
93815 +int fman_dtsec_init(struct dtsec_regs *regs, struct dtsec_cfg *cfg,
93816 + enum enet_interface iface_mode,
93817 + enum enet_speed iface_speed,
93818 + uint8_t *macaddr, uint8_t fm_rev_maj,
93819 + uint8_t fm_rev_min,
93820 + uint32_t exception_mask);
93821 +
93822 +/**
93823 + * fman_dtsec_enable() - Enable dTSEC Tx and Tx
93824 + * @regs: Pointer to dTSEC register block
93825 + * @apply_rx: enable rx side
93826 + * @apply_tx: enable tx side
93827 + *
93828 + * This function resets Tx and Rx graceful stop bit and enables dTSEC Tx and Rx.
93829 + */
93830 +void fman_dtsec_enable(struct dtsec_regs *regs, bool apply_rx, bool apply_tx);
93831 +
93832 +/**
93833 + * fman_dtsec_disable() - Disable dTSEC Tx and Rx
93834 + * @regs: Pointer to dTSEC register block
93835 + * @apply_rx: disable rx side
93836 + * @apply_tx: disable tx side
93837 + *
93838 + * This function disables Tx and Rx in dTSEC.
93839 + */
93840 +void fman_dtsec_disable(struct dtsec_regs *regs, bool apply_rx, bool apply_tx);
93841 +
93842 +/**
93843 + * fman_dtsec_get_revision() - Get dTSEC hardware revision
93844 + * @regs: Pointer to dTSEC register block
93845 + *
93846 + * Returns dtsec_id content
93847 + *
93848 + * Call this function to obtain the dTSEC hardware version.
93849 + */
93850 +uint32_t fman_dtsec_get_revision(struct dtsec_regs *regs);
93851 +
93852 +/**
93853 + * fman_dtsec_set_mac_address() - Set MAC station address
93854 + * @regs: Pointer to dTSEC register block
93855 + * @macaddr: MAC address array
93856 + *
93857 + * This function sets MAC station address. To enable unicast reception call
93858 + * this after fman_dtsec_init(). While promiscuous mode is disabled dTSEC will
93859 + * match the destination address of received unicast frames against this
93860 + * address.
93861 + */
93862 +void fman_dtsec_set_mac_address(struct dtsec_regs *regs, uint8_t *macaddr);
93863 +
93864 +/**
93865 + * fman_dtsec_get_mac_address() - Query MAC station address
93866 + * @regs: Pointer to dTSEC register block
93867 + * @macaddr: MAC address array
93868 + */
93869 +void fman_dtsec_get_mac_address(struct dtsec_regs *regs, uint8_t *macaddr);
93870 +
93871 +/**
93872 + * fman_dtsec_set_uc_promisc() - Sets unicast promiscuous mode
93873 + * @regs: Pointer to dTSEC register block
93874 + * @enable: Enable unicast promiscuous mode
93875 + *
93876 + * Use this function to enable/disable dTSEC L2 address filtering. If the
93877 + * address filtering is disabled all unicast packets are accepted.
93878 + * To set dTSEC in promiscuous mode call both fman_dtsec_set_uc_promisc() and
93879 + * fman_dtsec_set_mc_promisc() to disable filtering for both unicast and
93880 + * multicast addresses.
93881 + */
93882 +void fman_dtsec_set_uc_promisc(struct dtsec_regs *regs, bool enable);
93883 +
93884 +/**
93885 + * fman_dtsec_set_wol() - Enable/Disable wake on lan
93886 + * (magic packet support)
93887 + * @regs: Pointer to dTSEC register block
93888 + * @en: Enable Wake On Lan support in dTSEC
93889 + *
93890 + */
93891 +void fman_dtsec_set_wol(struct dtsec_regs *regs, bool en);
93892 +
93893 +/**
93894 + * fman_dtsec_adjust_link() - Adjust dTSEC speed/duplex settings
93895 + * @regs: Pointer to dTSEC register block
93896 + * @iface_mode: dTSEC interface mode
93897 + * @speed: Link speed
93898 + * @full_dx: True for full-duplex, false for half-duplex.
93899 + *
93900 + * This function configures the MAC to function and the desired rates. Use it
93901 + * to configure dTSEC after fman_dtsec_init() and whenever the link speed
93902 + * changes (for instance following PHY auto-negociation).
93903 + *
93904 + * Returns: 0 if successful, an error code otherwise.
93905 + */
93906 +int fman_dtsec_adjust_link(struct dtsec_regs *regs,
93907 + enum enet_interface iface_mode,
93908 + enum enet_speed speed, bool full_dx);
93909 +
93910 +/**
93911 + * fman_dtsec_set_tbi_phy_addr() - Updates TBI address field
93912 + * @regs: Pointer to dTSEC register block
93913 + * @address: Valid PHY address in the range of 1 to 31. 0 is reserved.
93914 + *
93915 + * In SGMII mode, the dTSEC's TBIPA field must contain a valid TBI PHY address
93916 + * so that the associated TBI PHY (i.e. the link) may be initialized.
93917 + *
93918 + * Returns: 0 if successful, an error code otherwise.
93919 + */
93920 +int fman_dtsec_set_tbi_phy_addr(struct dtsec_regs *regs,
93921 + uint8_t addr);
93922 +
93923 +/**
93924 + * fman_dtsec_set_max_frame_len() - Set max frame length
93925 + * @regs: Pointer to dTSEC register block
93926 + * @length: Max frame length.
93927 + *
93928 + * Sets maximum frame length for received and transmitted frames. Frames that
93929 + * exceeds this length are truncated.
93930 + */
93931 +void fman_dtsec_set_max_frame_len(struct dtsec_regs *regs, uint16_t length);
93932 +
93933 +/**
93934 + * fman_dtsec_get_max_frame_len() - Query max frame length
93935 + * @regs: Pointer to dTSEC register block
93936 + *
93937 + * Returns: the current value of the maximum frame length.
93938 + */
93939 +uint16_t fman_dtsec_get_max_frame_len(struct dtsec_regs *regs);
93940 +
93941 +/**
93942 + * fman_dtsec_handle_rx_pause() - Configure pause frame handling
93943 + * @regs: Pointer to dTSEC register block
93944 + * @en: Enable pause frame handling in dTSEC
93945 + *
93946 + * If enabled, dTSEC will handle pause frames internally. This must be disabled
93947 + * if dTSEC is set in half-duplex mode.
93948 + * If pause frame handling is disabled and &dtsec_cfg.rx_ctrl_acc is set, pause
93949 + * frames will be transferred to the packet interface just like regular Ethernet
93950 + * frames.
93951 + */
93952 +void fman_dtsec_handle_rx_pause(struct dtsec_regs *regs, bool en);
93953 +
93954 +/**
93955 + * fman_dtsec_set_tx_pause_frames() - Configure Tx pause time
93956 + * @regs: Pointer to dTSEC register block
93957 + * @time: Time value included in pause frames
93958 + *
93959 + * Call this function to set the time value used in transmitted pause frames.
93960 + * If time is 0, transmission of pause frames is disabled
93961 + */
93962 +void fman_dtsec_set_tx_pause_frames(struct dtsec_regs *regs, uint16_t time);
93963 +
93964 +/**
93965 + * fman_dtsec_ack_event() - Acknowledge handled events
93966 + * @regs: Pointer to dTSEC register block
93967 + * @ev_mask: Events to acknowledge
93968 + *
93969 + * After handling events signaled by dTSEC in either polling or interrupt mode,
93970 + * call this function to reset the associated status bits in dTSEC event
93971 + * register.
93972 + */
93973 +void fman_dtsec_ack_event(struct dtsec_regs *regs, uint32_t ev_mask);
93974 +
93975 +/**
93976 + * fman_dtsec_get_event() - Returns currently asserted events
93977 + * @regs: Pointer to dTSEC register block
93978 + * @ev_mask: Mask of relevant events
93979 + *
93980 + * Call this function to obtain a bit-mask of events that are currently asserted
93981 + * in dTSEC, taken from IEVENT register.
93982 + *
93983 + * Returns: a bit-mask of events asserted in dTSEC.
93984 + */
93985 +uint32_t fman_dtsec_get_event(struct dtsec_regs *regs, uint32_t ev_mask);
93986 +
93987 +/**
93988 + * fman_dtsec_get_interrupt_mask() - Returns a bit-mask of enabled interrupts
93989 + * @regs: Pointer to dTSEC register block
93990 + *
93991 + * Call this function to obtain a bit-mask of enabled interrupts
93992 + * in dTSEC, taken from IMASK register.
93993 + *
93994 + * Returns: a bit-mask of enabled interrupts in dTSEC.
93995 + */
93996 +uint32_t fman_dtsec_get_interrupt_mask(struct dtsec_regs *regs);
93997 +
93998 +void fman_dtsec_clear_addr_in_paddr(struct dtsec_regs *regs,
93999 + uint8_t paddr_num);
94000 +
94001 +void fman_dtsec_add_addr_in_paddr(struct dtsec_regs *regs,
94002 + uint64_t addr,
94003 + uint8_t paddr_num);
94004 +
94005 +void fman_dtsec_enable_tmr_interrupt (struct dtsec_regs *regs);
94006 +
94007 +void fman_dtsec_disable_tmr_interrupt(struct dtsec_regs *regs);
94008 +
94009 +/**
94010 + * fman_dtsec_disable_interrupt() - Disables interrupts for the specified events
94011 + * @regs: Pointer to dTSEC register block
94012 + * @ev_mask: Mask of relevant events
94013 + *
94014 + * Call this function to disable interrupts in dTSEC for the specified events.
94015 + * To enable interrupts use fman_dtsec_enable_interrupt().
94016 + */
94017 +void fman_dtsec_disable_interrupt(struct dtsec_regs *regs, uint32_t ev_mask);
94018 +
94019 +/**
94020 + * fman_dtsec_enable_interrupt() - Enable interrupts for the specified events
94021 + * @regs: Pointer to dTSEC register block
94022 + * @ev_mask: Mask of relevant events
94023 + *
94024 + * Call this function to enable interrupts in dTSEC for the specified events.
94025 + * To disable interrupts use fman_dtsec_disable_interrupt().
94026 + */
94027 +void fman_dtsec_enable_interrupt(struct dtsec_regs *regs, uint32_t ev_mask);
94028 +
94029 +/**
94030 + * fman_dtsec_set_ts() - Enables dTSEC timestamps
94031 + * @regs: Pointer to dTSEC register block
94032 + * @en: true to enable timestamps, false to disable them
94033 + *
94034 + * Call this function to enable/disable dTSEC timestamps. This affects both
94035 + * Tx and Rx.
94036 + */
94037 +void fman_dtsec_set_ts(struct dtsec_regs *regs, bool en);
94038 +
94039 +/**
94040 + * fman_dtsec_set_bucket() - Enables/disables a filter bucket
94041 + * @regs: Pointer to dTSEC register block
94042 + * @bucket: Bucket index
94043 + * @enable: true/false to enable/disable this bucket
94044 + *
94045 + * This function enables or disables the specified bucket. Enabling a bucket
94046 + * associated with an address configures dTSEC to accept received packets
94047 + * with that destination address.
94048 + * Multiple addresses may be associated with the same bucket. Disabling a
94049 + * bucket will affect all addresses associated with that bucket. A bucket that
94050 + * is enabled requires further filtering and verification in the upper layers
94051 + *
94052 + */
94053 +void fman_dtsec_set_bucket(struct dtsec_regs *regs, int bucket, bool enable);
94054 +
94055 +/**
94056 + * dtsec_set_hash_table() - insert a crc code into thr filter table
94057 + * @regs: Pointer to dTSEC register block
94058 + * @crc: crc to insert
94059 + * @mcast: true is this is a multicast address
94060 + * @ghtx: true if we are in ghtx mode
94061 + *
94062 + * This function inserts a crc code into the filter table.
94063 + */
94064 +void fman_dtsec_set_hash_table(struct dtsec_regs *regs, uint32_t crc,
94065 + bool mcast, bool ghtx);
94066 +
94067 +/**
94068 + * fman_dtsec_reset_filter_table() - Resets the address filtering table
94069 + * @regs: Pointer to dTSEC register block
94070 + * @mcast: Reset multicast entries
94071 + * @ucast: Reset unicast entries
94072 + *
94073 + * Resets all entries in L2 address filter table. After calling this function
94074 + * all buckets enabled using fman_dtsec_set_bucket() will be disabled.
94075 + * If dtsec_init_filter_table() was called with @unicast_hash set to false,
94076 + * @ucast argument is ignored.
94077 + * This does not affect the primary nor the 15 additional addresses configured
94078 + * using dtsec_set_address() or dtsec_set_match_address().
94079 + */
94080 +void fman_dtsec_reset_filter_table(struct dtsec_regs *regs, bool mcast,
94081 + bool ucast);
94082 +
94083 +/**
94084 + * fman_dtsec_set_mc_promisc() - Set multicast promiscuous mode
94085 + * @regs: Pointer to dTSEC register block
94086 + * @enable: Enable multicast promiscuous mode
94087 + *
94088 + * Call this to enable/disable L2 address filtering for multicast packets.
94089 + */
94090 +void fman_dtsec_set_mc_promisc(struct dtsec_regs *regs, bool enable);
94091 +
94092 +/* statistics APIs */
94093 +
94094 +/**
94095 + * fman_dtsec_set_stat_level() - Enable a group of MIB statistics counters
94096 + * @regs: Pointer to dTSEC register block
94097 + * @level: Specifies a certain group of dTSEC MIB HW counters or _all_,
94098 + * to specify all the existing counters.
94099 + * If set to _none_, it disables all the counters.
94100 + *
94101 + * Enables the MIB statistics hw counters and sets up the carry interrupt
94102 + * masks for the counters corresponding to the @level input parameter.
94103 + *
94104 + * Returns: error if invalid @level value given.
94105 + */
94106 +int fman_dtsec_set_stat_level(struct dtsec_regs *regs,
94107 + enum dtsec_stat_level level);
94108 +
94109 +/**
94110 + * fman_dtsec_reset_stat() - Completely resets all dTSEC HW counters
94111 + * @regs: Pointer to dTSEC register block
94112 + */
94113 +void fman_dtsec_reset_stat(struct dtsec_regs *regs);
94114 +
94115 +/**
94116 + * fman_dtsec_get_clear_carry_regs() - Read and clear carry bits (CAR1-2 registers)
94117 + * @regs: Pointer to dTSEC register block
94118 + * @car1: car1 register value
94119 + * @car2: car2 register value
94120 + *
94121 + * When set, the carry bits signal that an overflow occurred on the
94122 + * corresponding counters.
94123 + * Note that the carry bits (CAR1-2 registers) will assert the
94124 + * %DTSEC_IEVENT_MSRO interrupt if unmasked (via CAM1-2 regs).
94125 + *
94126 + * Returns: true if overflow occurred, otherwise - false
94127 + */
94128 +bool fman_dtsec_get_clear_carry_regs(struct dtsec_regs *regs,
94129 + uint32_t *car1, uint32_t *car2);
94130 +
94131 +uint32_t fman_dtsec_check_and_clear_tmr_event(struct dtsec_regs *regs);
94132 +
94133 +uint32_t fman_dtsec_get_stat_counter(struct dtsec_regs *regs,
94134 + enum dtsec_stat_counters reg_name);
94135 +
94136 +void fman_dtsec_start_tx(struct dtsec_regs *regs);
94137 +void fman_dtsec_start_rx(struct dtsec_regs *regs);
94138 +void fman_dtsec_stop_tx(struct dtsec_regs *regs);
94139 +void fman_dtsec_stop_rx(struct dtsec_regs *regs);
94140 +uint32_t fman_dtsec_get_rctrl(struct dtsec_regs *regs);
94141 +
94142 +
94143 +#endif /* __FSL_FMAN_DTSEC_H */
94144 --- /dev/null
94145 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/flib/fsl_fman_dtsec_mii_acc.h
94146 @@ -0,0 +1,107 @@
94147 +/*
94148 + * Copyright 2008-2013 Freescale Semiconductor Inc.
94149 + *
94150 + * Redistribution and use in source and binary forms, with or without
94151 + * modification, are permitted provided that the following conditions are met:
94152 + * * Redistributions of source code must retain the above copyright
94153 + * notice, this list of conditions and the following disclaimer.
94154 + * * Redistributions in binary form must reproduce the above copyright
94155 + * notice, this list of conditions and the following disclaimer in the
94156 + * documentation and/or other materials provided with the distribution.
94157 + * * Neither the name of Freescale Semiconductor nor the
94158 + * names of its contributors may be used to endorse or promote products
94159 + * derived from this software without specific prior written permission.
94160 + *
94161 + *
94162 + * ALTERNATIVELY, this software may be distributed under the terms of the
94163 + * GNU General Public License ("GPL") as published by the Free Software
94164 + * Foundation, either version 2 of that License or (at your option) any
94165 + * later version.
94166 + *
94167 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
94168 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
94169 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
94170 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
94171 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
94172 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
94173 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
94174 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
94175 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
94176 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
94177 + */
94178 +
94179 +#ifndef __FSL_FMAN_DTSEC_MII_ACC_H
94180 +#define __FSL_FMAN_DTSEC_MII_ACC_H
94181 +
94182 +#include "common/general.h"
94183 +
94184 +
94185 +/* MII Management Configuration Register */
94186 +#define MIIMCFG_RESET_MGMT 0x80000000
94187 +#define MIIMCFG_MGNTCLK_MASK 0x00000007
94188 +#define MIIMCFG_MGNTCLK_SHIFT 0
94189 +
94190 +/* MII Management Command Register */
94191 +#define MIIMCOM_SCAN_CYCLE 0x00000002
94192 +#define MIIMCOM_READ_CYCLE 0x00000001
94193 +
94194 +/* MII Management Address Register */
94195 +#define MIIMADD_PHY_ADDR_SHIFT 8
94196 +#define MIIMADD_PHY_ADDR_MASK 0x00001f00
94197 +
94198 +#define MIIMADD_REG_ADDR_SHIFT 0
94199 +#define MIIMADD_REG_ADDR_MASK 0x0000001f
94200 +
94201 +/* MII Management Indicator Register */
94202 +#define MIIMIND_BUSY 0x00000001
94203 +
94204 +
94205 +/* PHY Control Register */
94206 +#define PHY_CR_PHY_RESET 0x8000
94207 +#define PHY_CR_LOOPBACK 0x4000
94208 +#define PHY_CR_SPEED0 0x2000
94209 +#define PHY_CR_ANE 0x1000
94210 +#define PHY_CR_RESET_AN 0x0200
94211 +#define PHY_CR_FULLDUPLEX 0x0100
94212 +#define PHY_CR_SPEED1 0x0040
94213 +
94214 +#define PHY_TBICON_SRESET 0x8000
94215 +#define PHY_TBICON_SPEED2 0x0020
94216 +#define PHY_TBICON_CLK_SEL 0x0020
94217 +#define PHY_TBIANA_SGMII 0x4001
94218 +#define PHY_TBIANA_1000X 0x01a0
94219 +/* register map */
94220 +
94221 +/* MII Configuration Control Memory Map Registers */
94222 +struct dtsec_mii_reg {
94223 + uint32_t reserved1[72];
94224 + uint32_t miimcfg; /* MII Mgmt:configuration */
94225 + uint32_t miimcom; /* MII Mgmt:command */
94226 + uint32_t miimadd; /* MII Mgmt:address */
94227 + uint32_t miimcon; /* MII Mgmt:control 3 */
94228 + uint32_t miimstat; /* MII Mgmt:status */
94229 + uint32_t miimind; /* MII Mgmt:indicators */
94230 +};
94231 +
94232 +/* dTSEC MII API */
94233 +
94234 +/* functions to access the mii registers for phy configuration.
94235 + * this functionality may not be available for all dtsecs in the system.
94236 + * consult the reference manual for details */
94237 +void fman_dtsec_mii_reset(struct dtsec_mii_reg *regs);
94238 +/* frequency is in MHz.
94239 + * note that dtsec clock is 1/2 of fman clock */
94240 +void fman_dtsec_mii_init(struct dtsec_mii_reg *regs, uint16_t dtsec_freq);
94241 +int fman_dtsec_mii_write_reg(struct dtsec_mii_reg *regs,
94242 + uint8_t addr,
94243 + uint8_t reg,
94244 + uint16_t data,
94245 + uint16_t dtsec_freq);
94246 +
94247 +int fman_dtsec_mii_read_reg(struct dtsec_mii_reg *regs,
94248 + uint8_t addr,
94249 + uint8_t reg,
94250 + uint16_t *data,
94251 + uint16_t dtsec_freq);
94252 +
94253 +#endif /* __FSL_FMAN_DTSEC_MII_ACC_H */
94254 --- /dev/null
94255 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/flib/fsl_fman_kg.h
94256 @@ -0,0 +1,514 @@
94257 +/*
94258 + * Copyright 2008-2012 Freescale Semiconductor Inc.
94259 + *
94260 + * Redistribution and use in source and binary forms, with or without
94261 + * modification, are permitted provided that the following conditions are met:
94262 + * * Redistributions of source code must retain the above copyright
94263 + * notice, this list of conditions and the following disclaimer.
94264 + * * Redistributions in binary form must reproduce the above copyright
94265 + * notice, this list of conditions and the following disclaimer in the
94266 + * documentation and/or other materials provided with the distribution.
94267 + * * Neither the name of Freescale Semiconductor nor the
94268 + * names of its contributors may be used to endorse or promote products
94269 + * derived from this software without specific prior written permission.
94270 + *
94271 + *
94272 + * ALTERNATIVELY, this software may be distributed under the terms of the
94273 + * GNU General Public License ("GPL") as published by the Free Software
94274 + * Foundation, either version 2 of that License or (at your option) any
94275 + * later version.
94276 + *
94277 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
94278 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
94279 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
94280 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
94281 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
94282 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
94283 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
94284 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
94285 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
94286 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
94287 + */
94288 +
94289 +#ifndef __FSL_FMAN_KG_H
94290 +#define __FSL_FMAN_KG_H
94291 +
94292 +#include "common/general.h"
94293 +
94294 +#define FM_KG_NUM_OF_GENERIC_REGS 8 /**< Num of generic KeyGen regs */
94295 +#define FMAN_MAX_NUM_OF_HW_PORTS 64
94296 +/**< Total num of masks allowed on KG extractions */
94297 +#define FM_KG_EXTRACT_MASKS_NUM 4
94298 +#define FM_KG_NUM_CLS_PLAN_ENTR 8 /**< Num of class. plan regs */
94299 +#define FM_KG_CLS_PLAN_GRPS_NUM 32 /**< Max num of class. groups */
94300 +
94301 +struct fman_kg_regs {
94302 + uint32_t fmkg_gcr;
94303 + uint32_t res004;
94304 + uint32_t res008;
94305 + uint32_t fmkg_eer;
94306 + uint32_t fmkg_eeer;
94307 + uint32_t res014;
94308 + uint32_t res018;
94309 + uint32_t fmkg_seer;
94310 + uint32_t fmkg_seeer;
94311 + uint32_t fmkg_gsr;
94312 + uint32_t fmkg_tpc;
94313 + uint32_t fmkg_serc;
94314 + uint32_t res030[4];
94315 + uint32_t fmkg_fdor;
94316 + uint32_t fmkg_gdv0r;
94317 + uint32_t fmkg_gdv1r;
94318 + uint32_t res04c[6];
94319 + uint32_t fmkg_feer;
94320 + uint32_t res068[38];
94321 + uint32_t fmkg_indirect[63];
94322 + uint32_t fmkg_ar;
94323 +};
94324 +
94325 +struct fman_kg_scheme_regs {
94326 + uint32_t kgse_mode; /**< MODE */
94327 + uint32_t kgse_ekfc; /**< Extract Known Fields Command */
94328 + uint32_t kgse_ekdv; /**< Extract Known Default Value */
94329 + uint32_t kgse_bmch; /**< Bit Mask Command High */
94330 + uint32_t kgse_bmcl; /**< Bit Mask Command Low */
94331 + uint32_t kgse_fqb; /**< Frame Queue Base */
94332 + uint32_t kgse_hc; /**< Hash Command */
94333 + uint32_t kgse_ppc; /**< Policer Profile Command */
94334 + uint32_t kgse_gec[FM_KG_NUM_OF_GENERIC_REGS];
94335 + /**< Generic Extract Command */
94336 + uint32_t kgse_spc; /**< KeyGen Scheme Entry Statistic Packet Counter */
94337 + uint32_t kgse_dv0; /**< KeyGen Scheme Entry Default Value 0 */
94338 + uint32_t kgse_dv1; /**< KeyGen Scheme Entry Default Value 1 */
94339 + uint32_t kgse_ccbs; /**< KeyGen Scheme Entry Coarse Classification Bit*/
94340 + uint32_t kgse_mv; /**< KeyGen Scheme Entry Match vector */
94341 + uint32_t kgse_om; /**< KeyGen Scheme Entry Operation Mode bits */
94342 + uint32_t kgse_vsp; /**< KeyGen Scheme Entry Virtual Storage Profile */
94343 +};
94344 +
94345 +struct fman_kg_pe_regs{
94346 + uint32_t fmkg_pe_sp;
94347 + uint32_t fmkg_pe_cpp;
94348 +};
94349 +
94350 +struct fman_kg_cp_regs {
94351 + uint32_t kgcpe[FM_KG_NUM_CLS_PLAN_ENTR];
94352 +};
94353 +
94354 +
94355 +#define FM_KG_KGAR_GO 0x80000000
94356 +#define FM_KG_KGAR_READ 0x40000000
94357 +#define FM_KG_KGAR_WRITE 0x00000000
94358 +#define FM_KG_KGAR_SEL_SCHEME_ENTRY 0x00000000
94359 +#define FM_KG_KGAR_SCM_WSEL_UPDATE_CNT 0x00008000
94360 +
94361 +#define KG_SCH_PP_SHIFT_HIGH 0x80000000
94362 +#define KG_SCH_PP_NO_GEN 0x10000000
94363 +#define KG_SCH_PP_SHIFT_LOW 0x0000F000
94364 +#define KG_SCH_MODE_NIA_PLCR 0x40000000
94365 +#define KG_SCH_GEN_EXTRACT_TYPE 0x00008000
94366 +#define KG_SCH_BITMASK_MASK 0x000000FF
94367 +#define KG_SCH_GEN_VALID 0x80000000
94368 +#define KG_SCH_GEN_MASK 0x00FF0000
94369 +#define FM_PCD_KG_KGAR_ERR 0x20000000
94370 +#define FM_PCD_KG_KGAR_SEL_CLS_PLAN_ENTRY 0x01000000
94371 +#define FM_PCD_KG_KGAR_SEL_PORT_ENTRY 0x02000000
94372 +#define FM_PCD_KG_KGAR_SEL_PORT_WSEL_SP 0x00008000
94373 +#define FM_PCD_KG_KGAR_SEL_PORT_WSEL_CPP 0x00004000
94374 +#define FM_PCD_KG_KGAR_WSEL_MASK 0x0000FF00
94375 +#define KG_SCH_HASH_CONFIG_NO_FQID 0x80000000
94376 +#define KG_SCH_HASH_CONFIG_SYM 0x40000000
94377 +
94378 +#define FM_EX_KG_DOUBLE_ECC 0x80000000
94379 +#define FM_EX_KG_KEYSIZE_OVERFLOW 0x40000000
94380 +
94381 +/* ECC capture register */
94382 +#define KG_FMKG_SERC_CAP 0x80000000
94383 +#define KG_FMKG_SERC_CET 0x40000000
94384 +#define KG_FMKG_SERC_CNT_MSK 0x00FF0000
94385 +#define KG_FMKG_SERC_CNT_SHIFT 16
94386 +#define KG_FMKG_SERC_ADDR_MSK 0x000003FF
94387 +
94388 +/* Masks */
94389 +#define FM_KG_KGGCR_EN 0x80000000
94390 +#define KG_SCH_GEN_VALID 0x80000000
94391 +#define KG_SCH_GEN_EXTRACT_TYPE 0x00008000
94392 +#define KG_ERR_TYPE_DOUBLE 0x40000000
94393 +#define KG_ERR_ADDR_MASK 0x00000FFF
94394 +#define KG_SCH_MODE_EN 0x80000000
94395 +
94396 +/* shifts */
94397 +#define FM_KG_KGAR_NUM_SHIFT 16
94398 +#define FM_KG_PE_CPP_MASK_SHIFT 16
94399 +#define FM_KG_KGAR_WSEL_SHIFT 8
94400 +
94401 +#define FM_KG_SCH_GEN_HT_INVALID 0
94402 +
94403 +#define FM_KG_MASK_SEL_GEN_BASE 0x20
94404 +
94405 +#define KG_GET_MASK_SEL_SHIFT(shift, i) \
94406 +switch (i) \
94407 +{ \
94408 + case 0: (shift) = 26; break; \
94409 + case 1: (shift) = 20; break; \
94410 + case 2: (shift) = 10; break; \
94411 + case 3: (shift) = 4; break; \
94412 + default: (shift) = 0; \
94413 +}
94414 +
94415 +#define KG_GET_MASK_OFFSET_SHIFT(shift, i) \
94416 +switch (i) \
94417 +{ \
94418 + case 0: (shift) = 16; break; \
94419 + case 1: (shift) = 0; break; \
94420 + case 2: (shift) = 28; break; \
94421 + case 3: (shift) = 24; break; \
94422 + default: (shift) = 0; \
94423 +}
94424 +
94425 +#define KG_GET_MASK_SHIFT(shift, i) \
94426 +switch (i) \
94427 +{ \
94428 + case 0: shift = 24; break; \
94429 + case 1: shift = 16; break; \
94430 + case 2: shift = 8; break; \
94431 + case 3: shift = 0; break; \
94432 + default: shift = 0; \
94433 +}
94434 +
94435 +/* Port entry CPP register */
94436 +#define FMAN_KG_PE_CPP_MASK_SHIFT 16
94437 +
94438 +/* Scheme registers */
94439 +#define FMAN_KG_SCH_MODE_EN 0x80000000
94440 +#define FMAN_KG_SCH_MODE_NIA_PLCR 0x40000000
94441 +#define FMAN_KG_SCH_MODE_CCOBASE_SHIFT 24
94442 +
94443 +#define FMAN_KG_SCH_DEF_MAC_ADDR_SHIFT 30
94444 +#define FMAN_KG_SCH_DEF_VLAN_TCI_SHIFT 28
94445 +#define FMAN_KG_SCH_DEF_ETYPE_SHIFT 26
94446 +#define FMAN_KG_SCH_DEF_PPP_SID_SHIFT 24
94447 +#define FMAN_KG_SCH_DEF_PPP_PID_SHIFT 22
94448 +#define FMAN_KG_SCH_DEF_MPLS_SHIFT 20
94449 +#define FMAN_KG_SCH_DEF_IP_ADDR_SHIFT 18
94450 +#define FMAN_KG_SCH_DEF_PTYPE_SHIFT 16
94451 +#define FMAN_KG_SCH_DEF_IP_TOS_TC_SHIFT 14
94452 +#define FMAN_KG_SCH_DEF_IPv6_FL_SHIFT 12
94453 +#define FMAN_KG_SCH_DEF_IPSEC_SPI_SHIFT 10
94454 +#define FMAN_KG_SCH_DEF_L4_PORT_SHIFT 8
94455 +#define FMAN_KG_SCH_DEF_TCP_FLG_SHIFT 6
94456 +
94457 +#define FMAN_KG_SCH_GEN_VALID 0x80000000
94458 +#define FMAN_KG_SCH_GEN_SIZE_MAX 16
94459 +#define FMAN_KG_SCH_GEN_OR 0x00008000
94460 +
94461 +#define FMAN_KG_SCH_GEN_DEF_SHIFT 29
94462 +#define FMAN_KG_SCH_GEN_SIZE_SHIFT 24
94463 +#define FMAN_KG_SCH_GEN_MASK_SHIFT 16
94464 +#define FMAN_KG_SCH_GEN_HT_SHIFT 8
94465 +
94466 +#define FMAN_KG_SCH_HASH_HSHIFT_SHIFT 24
94467 +#define FMAN_KG_SCH_HASH_HSHIFT_MAX 0x28
94468 +#define FMAN_KG_SCH_HASH_SYM 0x40000000
94469 +#define FMAN_KG_SCH_HASH_NO_FQID_GEN 0x80000000
94470 +
94471 +#define FMAN_KG_SCH_PP_SH_SHIFT 27
94472 +#define FMAN_KG_SCH_PP_SL_SHIFT 12
94473 +#define FMAN_KG_SCH_PP_SH_MASK 0x80000000
94474 +#define FMAN_KG_SCH_PP_SL_MASK 0x0000F000
94475 +#define FMAN_KG_SCH_PP_SHIFT_MAX 0x17
94476 +#define FMAN_KG_SCH_PP_MASK_SHIFT 16
94477 +#define FMAN_KG_SCH_PP_NO_GEN 0x10000000
94478 +
94479 +enum fman_kg_gen_extract_src {
94480 + E_FMAN_KG_GEN_EXTRACT_ETH,
94481 + E_FMAN_KG_GEN_EXTRACT_ETYPE,
94482 + E_FMAN_KG_GEN_EXTRACT_SNAP,
94483 + E_FMAN_KG_GEN_EXTRACT_VLAN_TCI_1,
94484 + E_FMAN_KG_GEN_EXTRACT_VLAN_TCI_N,
94485 + E_FMAN_KG_GEN_EXTRACT_PPPoE,
94486 + E_FMAN_KG_GEN_EXTRACT_MPLS_1,
94487 + E_FMAN_KG_GEN_EXTRACT_MPLS_2,
94488 + E_FMAN_KG_GEN_EXTRACT_MPLS_3,
94489 + E_FMAN_KG_GEN_EXTRACT_MPLS_N,
94490 + E_FMAN_KG_GEN_EXTRACT_IPv4_1,
94491 + E_FMAN_KG_GEN_EXTRACT_IPv6_1,
94492 + E_FMAN_KG_GEN_EXTRACT_IPv4_2,
94493 + E_FMAN_KG_GEN_EXTRACT_IPv6_2,
94494 + E_FMAN_KG_GEN_EXTRACT_MINENCAP,
94495 + E_FMAN_KG_GEN_EXTRACT_IP_PID,
94496 + E_FMAN_KG_GEN_EXTRACT_GRE,
94497 + E_FMAN_KG_GEN_EXTRACT_TCP,
94498 + E_FMAN_KG_GEN_EXTRACT_UDP,
94499 + E_FMAN_KG_GEN_EXTRACT_SCTP,
94500 + E_FMAN_KG_GEN_EXTRACT_DCCP,
94501 + E_FMAN_KG_GEN_EXTRACT_IPSEC_AH,
94502 + E_FMAN_KG_GEN_EXTRACT_IPSEC_ESP,
94503 + E_FMAN_KG_GEN_EXTRACT_SHIM_1,
94504 + E_FMAN_KG_GEN_EXTRACT_SHIM_2,
94505 + E_FMAN_KG_GEN_EXTRACT_FROM_DFLT,
94506 + E_FMAN_KG_GEN_EXTRACT_FROM_FRAME_START,
94507 + E_FMAN_KG_GEN_EXTRACT_FROM_PARSE_RESULT,
94508 + E_FMAN_KG_GEN_EXTRACT_FROM_END_OF_PARSE,
94509 + E_FMAN_KG_GEN_EXTRACT_FROM_FQID
94510 +};
94511 +
94512 +struct fman_kg_ex_ecc_attr
94513 +{
94514 + bool valid;
94515 + bool double_ecc;
94516 + uint16_t addr;
94517 + uint8_t single_ecc_count;
94518 +};
94519 +
94520 +enum fman_kg_def_select
94521 +{
94522 + E_FMAN_KG_DEF_GLOBAL_0,
94523 + E_FMAN_KG_DEF_GLOBAL_1,
94524 + E_FMAN_KG_DEF_SCHEME_0,
94525 + E_FMAN_KG_DEF_SCHEME_1
94526 +};
94527 +
94528 +struct fman_kg_extract_def
94529 +{
94530 + enum fman_kg_def_select mac_addr;
94531 + enum fman_kg_def_select vlan_tci;
94532 + enum fman_kg_def_select etype;
94533 + enum fman_kg_def_select ppp_sid;
94534 + enum fman_kg_def_select ppp_pid;
94535 + enum fman_kg_def_select mpls;
94536 + enum fman_kg_def_select ip_addr;
94537 + enum fman_kg_def_select ptype;
94538 + enum fman_kg_def_select ip_tos_tc;
94539 + enum fman_kg_def_select ipv6_fl;
94540 + enum fman_kg_def_select ipsec_spi;
94541 + enum fman_kg_def_select l4_port;
94542 + enum fman_kg_def_select tcp_flg;
94543 +};
94544 +
94545 +enum fman_kg_gen_extract_type
94546 +{
94547 + E_FMAN_KG_HASH_EXTRACT,
94548 + E_FMAN_KG_OR_EXTRACT
94549 +};
94550 +
94551 +struct fman_kg_gen_extract_params
94552 +{
94553 + /* Hash or Or-ed extract */
94554 + enum fman_kg_gen_extract_type type;
94555 + enum fman_kg_gen_extract_src src;
94556 + bool no_validation;
94557 + /* Extraction offset from the header location specified above */
94558 + uint8_t offset;
94559 + /* Size of extraction for FMAN_KG_HASH_EXTRACT,
94560 + * hash result shift for FMAN_KG_OR_EXTRACT */
94561 + uint8_t extract;
94562 + uint8_t mask;
94563 + /* Default value to use when header specified
94564 + * by fman_kg_gen_extract_src doesn't present */
94565 + enum fman_kg_def_select def_val;
94566 +};
94567 +
94568 +struct fman_kg_extract_mask
94569 +{
94570 + /**< Indication if mask is on known field extraction or
94571 + * on general extraction; TRUE for known field */
94572 + bool is_known;
94573 + /**< One of FMAN_KG_EXTRACT_xxx defines for known fields mask and
94574 + * generic register index for generic extracts mask */
94575 + uint32_t field_or_gen_idx;
94576 + /**< Byte offset from start of the extracted data specified
94577 + * by field_or_gen_idx */
94578 + uint8_t offset;
94579 + /**< Byte mask (selected bits will be used) */
94580 + uint8_t mask;
94581 +};
94582 +
94583 +struct fman_kg_extract_params
94584 +{
94585 + /* Or-ed mask of FMAN_KG_EXTRACT_xxx defines */
94586 + uint32_t known_fields;
94587 + struct fman_kg_extract_def known_fields_def;
94588 + /* Number of entries in gen_extract */
94589 + uint8_t gen_extract_num;
94590 + struct fman_kg_gen_extract_params gen_extract[FM_KG_NUM_OF_GENERIC_REGS];
94591 + /* Number of entries in masks */
94592 + uint8_t masks_num;
94593 + struct fman_kg_extract_mask masks[FM_KG_EXTRACT_MASKS_NUM];
94594 + uint32_t def_scheme_0;
94595 + uint32_t def_scheme_1;
94596 +};
94597 +
94598 +struct fman_kg_hash_params
94599 +{
94600 + bool use_hash;
94601 + uint8_t shift_r;
94602 + uint32_t mask; /**< 24-bit mask */
94603 + bool sym; /**< Symmetric hash for src and dest pairs */
94604 +};
94605 +
94606 +struct fman_kg_pp_params
94607 +{
94608 + uint8_t base;
94609 + uint8_t shift;
94610 + uint8_t mask;
94611 + bool bypass_pp_gen;
94612 +};
94613 +
94614 +struct fman_kg_cc_params
94615 +{
94616 + uint8_t base_offset;
94617 + uint32_t qlcv_bits_sel;
94618 +};
94619 +
94620 +enum fman_pcd_engine
94621 +{
94622 + E_FMAN_PCD_INVALID = 0, /**< Invalid PCD engine indicated*/
94623 + E_FMAN_PCD_DONE, /**< No PCD Engine indicated */
94624 + E_FMAN_PCD_KG, /**< Keygen indicated */
94625 + E_FMAN_PCD_CC, /**< Coarse classification indicated */
94626 + E_FMAN_PCD_PLCR, /**< Policer indicated */
94627 + E_FMAN_PCD_PRS /**< Parser indicated */
94628 +};
94629 +
94630 +struct fman_kg_cls_plan_params
94631 +{
94632 + uint8_t entries_mask;
94633 + uint32_t mask_vector[FM_KG_NUM_CLS_PLAN_ENTR];
94634 +};
94635 +
94636 +struct fman_kg_scheme_params
94637 +{
94638 + uint32_t match_vector;
94639 + struct fman_kg_extract_params extract_params;
94640 + struct fman_kg_hash_params hash_params;
94641 + uint32_t base_fqid;
94642 + /* What we do w/features supported per FM version ?? */
94643 + bool bypass_fqid_gen;
94644 + struct fman_kg_pp_params policer_params;
94645 + struct fman_kg_cc_params cc_params;
94646 + bool update_counter;
94647 + /**< counter_value: Set scheme counter to the specified value;
94648 + * relevant only when update_counter = TRUE. */
94649 + uint32_t counter_value;
94650 + enum fman_pcd_engine next_engine;
94651 + /**< Next engine action code */
94652 + uint32_t next_engine_action;
94653 +};
94654 +
94655 +
94656 +
94657 +int fman_kg_write_ar_wait(struct fman_kg_regs *regs, uint32_t fmkg_ar);
94658 +void fman_kg_write_sp(struct fman_kg_regs *regs, uint32_t sp, bool add);
94659 +void fman_kg_write_cpp(struct fman_kg_regs *regs, uint32_t cpp);
94660 +void fman_kg_get_event(struct fman_kg_regs *regs,
94661 + uint32_t *event,
94662 + uint32_t *scheme_idx);
94663 +void fman_kg_init(struct fman_kg_regs *regs,
94664 + uint32_t exceptions,
94665 + uint32_t dflt_nia);
94666 +void fman_kg_enable_scheme_interrupts(struct fman_kg_regs *regs);
94667 +void fman_kg_enable(struct fman_kg_regs *regs);
94668 +void fman_kg_disable(struct fman_kg_regs *regs);
94669 +int fman_kg_write_bind_cls_plans(struct fman_kg_regs *regs,
94670 + uint8_t hwport_id,
94671 + uint32_t bind_cls_plans);
94672 +int fman_kg_build_bind_cls_plans(uint8_t grp_base,
94673 + uint8_t grp_mask,
94674 + uint32_t *bind_cls_plans);
94675 +int fman_kg_write_bind_schemes(struct fman_kg_regs *regs,
94676 + uint8_t hwport_id,
94677 + uint32_t schemes);
94678 +int fman_kg_write_cls_plan(struct fman_kg_regs *regs,
94679 + uint8_t grp_id,
94680 + uint8_t entries_mask,
94681 + uint8_t hwport_id,
94682 + struct fman_kg_cp_regs *cls_plan_regs);
94683 +int fman_kg_build_cls_plan(struct fman_kg_cls_plan_params *params,
94684 + struct fman_kg_cp_regs *cls_plan_regs);
94685 +uint32_t fman_kg_get_schemes_total_counter(struct fman_kg_regs *regs);
94686 +int fman_kg_set_scheme_counter(struct fman_kg_regs *regs,
94687 + uint8_t scheme_id,
94688 + uint8_t hwport_id,
94689 + uint32_t counter);
94690 +int fman_kg_get_scheme_counter(struct fman_kg_regs *regs,
94691 + uint8_t scheme_id,
94692 + uint8_t hwport_id,
94693 + uint32_t *counter);
94694 +int fman_kg_delete_scheme(struct fman_kg_regs *regs,
94695 + uint8_t scheme_id,
94696 + uint8_t hwport_id);
94697 +int fman_kg_write_scheme(struct fman_kg_regs *regs,
94698 + uint8_t scheme_id,
94699 + uint8_t hwport_id,
94700 + struct fman_kg_scheme_regs *scheme_regs,
94701 + bool update_counter);
94702 +int fman_kg_build_scheme(struct fman_kg_scheme_params *params,
94703 + struct fman_kg_scheme_regs *scheme_regs);
94704 +void fman_kg_get_capture(struct fman_kg_regs *regs,
94705 + struct fman_kg_ex_ecc_attr *ecc_attr,
94706 + bool clear);
94707 +void fman_kg_get_exception(struct fman_kg_regs *regs,
94708 + uint32_t *events,
94709 + uint32_t *scheme_ids,
94710 + bool clear);
94711 +void fman_kg_set_exception(struct fman_kg_regs *regs,
94712 + uint32_t exception,
94713 + bool enable);
94714 +void fman_kg_set_dflt_val(struct fman_kg_regs *regs,
94715 + uint8_t def_id,
94716 + uint32_t val);
94717 +void fman_kg_set_data_after_prs(struct fman_kg_regs *regs, uint8_t offset);
94718 +
94719 +
94720 +
94721 +/**************************************************************************//**
94722 + @Description NIA Description
94723 +*//***************************************************************************/
94724 +#define KG_NIA_ORDER_RESTOR 0x00800000
94725 +#define KG_NIA_ENG_FM_CTL 0x00000000
94726 +#define KG_NIA_ENG_PRS 0x00440000
94727 +#define KG_NIA_ENG_KG 0x00480000
94728 +#define KG_NIA_ENG_PLCR 0x004C0000
94729 +#define KG_NIA_ENG_BMI 0x00500000
94730 +#define KG_NIA_ENG_QMI_ENQ 0x00540000
94731 +#define KG_NIA_ENG_QMI_DEQ 0x00580000
94732 +#define KG_NIA_ENG_MASK 0x007C0000
94733 +
94734 +#define KG_NIA_AC_MASK 0x0003FFFF
94735 +
94736 +#define KG_NIA_INVALID 0xFFFFFFFF
94737 +
94738 +static __inline__ uint32_t fm_kg_build_nia(enum fman_pcd_engine next_engine,
94739 + uint32_t next_engine_action)
94740 +{
94741 + uint32_t nia;
94742 +
94743 + if (next_engine_action & ~KG_NIA_AC_MASK)
94744 + return KG_NIA_INVALID;
94745 +
94746 + switch (next_engine) {
94747 + case E_FMAN_PCD_DONE:
94748 + nia = KG_NIA_ENG_BMI | next_engine_action;
94749 + break;
94750 +
94751 + case E_FMAN_PCD_KG:
94752 + nia = KG_NIA_ENG_KG | next_engine_action;
94753 + break;
94754 +
94755 + case E_FMAN_PCD_CC:
94756 + nia = KG_NIA_ENG_FM_CTL | next_engine_action;
94757 + break;
94758 +
94759 + case E_FMAN_PCD_PLCR:
94760 + nia = KG_NIA_ENG_PLCR | next_engine_action;
94761 + break;
94762 +
94763 + default:
94764 + nia = KG_NIA_INVALID;
94765 + }
94766 +
94767 + return nia;
94768 +}
94769 +
94770 +#endif /* __FSL_FMAN_KG_H */
94771 --- /dev/null
94772 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/flib/fsl_fman_memac.h
94773 @@ -0,0 +1,434 @@
94774 +/*
94775 + * Copyright 2008-2012 Freescale Semiconductor Inc.
94776 + *
94777 + * Redistribution and use in source and binary forms, with or without
94778 + * modification, are permitted provided that the following conditions are met:
94779 + * * Redistributions of source code must retain the above copyright
94780 + * notice, this list of conditions and the following disclaimer.
94781 + * * Redistributions in binary form must reproduce the above copyright
94782 + * notice, this list of conditions and the following disclaimer in the
94783 + * documentation and/or other materials provided with the distribution.
94784 + * * Neither the name of Freescale Semiconductor nor the
94785 + * names of its contributors may be used to endorse or promote products
94786 + * derived from this software without specific prior written permission.
94787 + *
94788 + *
94789 + * ALTERNATIVELY, this software may be distributed under the terms of the
94790 + * GNU General Public License ("GPL") as published by the Free Software
94791 + * Foundation, either version 2 of that License or (at your option) any
94792 + * later version.
94793 + *
94794 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
94795 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
94796 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
94797 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
94798 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
94799 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
94800 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
94801 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
94802 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
94803 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
94804 + */
94805 +
94806 +
94807 +#ifndef __FSL_FMAN_MEMAC_H
94808 +#define __FSL_FMAN_MEMAC_H
94809 +
94810 +#include "common/general.h"
94811 +#include "fsl_enet.h"
94812 +
94813 +
94814 +#define MEMAC_NUM_OF_PADDRS 7 /* Num of additional exact match MAC adr regs */
94815 +
94816 +/* Control and Configuration Register (COMMAND_CONFIG) */
94817 +#define CMD_CFG_MG 0x80000000 /* 00 Magic Packet detection */
94818 +#define CMD_CFG_REG_LOWP_RXETY 0x01000000 /* 07 Rx low power indication */
94819 +#define CMD_CFG_TX_LOWP_ENA 0x00800000 /* 08 Tx Low Power Idle Enable */
94820 +#define CMD_CFG_SFD_ANY 0x00200000 /* 10 Disable SFD check */
94821 +#define CMD_CFG_PFC_MODE 0x00080000 /* 12 Enable PFC */
94822 +#define CMD_CFG_NO_LEN_CHK 0x00020000 /* 14 Payload length check disable */
94823 +#define CMD_CFG_SEND_IDLE 0x00010000 /* 15 Force idle generation */
94824 +#define CMD_CFG_CNT_FRM_EN 0x00002000 /* 18 Control frame rx enable */
94825 +#define CMD_CFG_SW_RESET 0x00001000 /* 19 S/W Reset, self clearing bit */
94826 +#define CMD_CFG_TX_PAD_EN 0x00000800 /* 20 Enable Tx padding of frames */
94827 +#define CMD_CFG_LOOPBACK_EN 0x00000400 /* 21 XGMII/GMII loopback enable */
94828 +#define CMD_CFG_TX_ADDR_INS 0x00000200 /* 22 Tx source MAC addr insertion */
94829 +#define CMD_CFG_PAUSE_IGNORE 0x00000100 /* 23 Ignore Pause frame quanta */
94830 +#define CMD_CFG_PAUSE_FWD 0x00000080 /* 24 Terminate/frwd Pause frames */
94831 +#define CMD_CFG_CRC_FWD 0x00000040 /* 25 Terminate/frwd CRC of frames */
94832 +#define CMD_CFG_PAD_EN 0x00000020 /* 26 Frame padding removal */
94833 +#define CMD_CFG_PROMIS_EN 0x00000010 /* 27 Promiscuous operation enable */
94834 +#define CMD_CFG_WAN_MODE 0x00000008 /* 28 WAN mode enable */
94835 +#define CMD_CFG_RX_EN 0x00000002 /* 30 MAC receive path enable */
94836 +#define CMD_CFG_TX_EN 0x00000001 /* 31 MAC transmit path enable */
94837 +
94838 +/* Transmit FIFO Sections Register (TX_FIFO_SECTIONS) */
94839 +#define TX_FIFO_SECTIONS_TX_EMPTY_MASK 0xFFFF0000
94840 +#define TX_FIFO_SECTIONS_TX_AVAIL_MASK 0x0000FFFF
94841 +#define TX_FIFO_SECTIONS_TX_EMPTY_DEFAULT_10G 0x00400000
94842 +#define TX_FIFO_SECTIONS_TX_EMPTY_DEFAULT_1G 0x00100000
94843 +#define TX_FIFO_SECTIONS_TX_EMPTY_PFC_10G 0x00360000
94844 +#define TX_FIFO_SECTIONS_TX_EMPTY_PFC_1G 0x00040000
94845 +#define TX_FIFO_SECTIONS_TX_AVAIL_10G 0x00000019
94846 +#define TX_FIFO_SECTIONS_TX_AVAIL_1G 0x00000020
94847 +#define TX_FIFO_SECTIONS_TX_AVAIL_SLOW_10G 0x00000060
94848 +
94849 +#define GET_TX_EMPTY_DEFAULT_VALUE(_val) \
94850 +_val &= ~TX_FIFO_SECTIONS_TX_EMPTY_MASK; \
94851 +((_val == TX_FIFO_SECTIONS_TX_AVAIL_10G) ? \
94852 + (_val |= TX_FIFO_SECTIONS_TX_EMPTY_DEFAULT_10G) : \
94853 + (_val |= TX_FIFO_SECTIONS_TX_EMPTY_DEFAULT_1G));
94854 +
94855 +#define GET_TX_EMPTY_PFC_VALUE(_val) \
94856 +_val &= ~TX_FIFO_SECTIONS_TX_EMPTY_MASK; \
94857 +((_val == TX_FIFO_SECTIONS_TX_AVAIL_10G) ? \
94858 + (_val |= TX_FIFO_SECTIONS_TX_EMPTY_PFC_10G) : \
94859 + (_val |= TX_FIFO_SECTIONS_TX_EMPTY_PFC_1G));
94860 +
94861 +/* Interface Mode Register (IF_MODE) */
94862 +#define IF_MODE_MASK 0x00000003 /* 30-31 Mask on i/f mode bits */
94863 +#define IF_MODE_XGMII 0x00000000 /* 30-31 XGMII (10G) interface */
94864 +#define IF_MODE_GMII 0x00000002 /* 30-31 GMII (1G) interface */
94865 +#define IF_MODE_RGMII 0x00000004
94866 +#define IF_MODE_RGMII_AUTO 0x00008000
94867 +#define IF_MODE_RGMII_1000 0x00004000 /* 10 - 1000Mbps RGMII */
94868 +#define IF_MODE_RGMII_100 0x00000000 /* 00 - 100Mbps RGMII */
94869 +#define IF_MODE_RGMII_10 0x00002000 /* 01 - 10Mbps RGMII */
94870 +#define IF_MODE_RGMII_SP_MASK 0x00006000 /* Setsp mask bits */
94871 +#define IF_MODE_RGMII_FD 0x00001000 /* Full duplex RGMII */
94872 +#define IF_MODE_HD 0x00000040 /* Half duplex operation */
94873 +
94874 +/* Hash table Control Register (HASHTABLE_CTRL) */
94875 +#define HASH_CTRL_MCAST_SHIFT 26
94876 +#define HASH_CTRL_MCAST_EN 0x00000100 /* 23 Mcast frame rx for hash */
94877 +#define HASH_CTRL_ADDR_MASK 0x0000003F /* 26-31 Hash table address code */
94878 +
94879 +#define GROUP_ADDRESS 0x0000010000000000LL /* MAC mcast indication */
94880 +#define HASH_TABLE_SIZE 64 /* Hash tbl size */
94881 +
94882 +/* Transmit Inter-Packet Gap Length Register (TX_IPG_LENGTH) */
94883 +#define MEMAC_TX_IPG_LENGTH_MASK 0x0000003F
94884 +
94885 +/* Statistics Configuration Register (STATN_CONFIG) */
94886 +#define STATS_CFG_CLR 0x00000004 /* 29 Reset all counters */
94887 +#define STATS_CFG_CLR_ON_RD 0x00000002 /* 30 Clear on read */
94888 +#define STATS_CFG_SATURATE 0x00000001 /* 31 Saturate at the maximum val */
94889 +
94890 +/* Interrupt Mask Register (IMASK) */
94891 +#define MEMAC_IMASK_MGI 0x40000000 /* 1 Magic pkt detect indication */
94892 +#define MEMAC_IMASK_TSECC_ER 0x20000000 /* 2 Timestamp FIFO ECC error evnt */
94893 +#define MEMAC_IMASK_TECC_ER 0x02000000 /* 6 Transmit frame ECC error evnt */
94894 +#define MEMAC_IMASK_RECC_ER 0x01000000 /* 7 Receive frame ECC error evnt */
94895 +
94896 +#define MEMAC_ALL_ERRS_IMASK \
94897 + ((uint32_t)(MEMAC_IMASK_TSECC_ER | \
94898 + MEMAC_IMASK_TECC_ER | \
94899 + MEMAC_IMASK_RECC_ER | \
94900 + MEMAC_IMASK_MGI))
94901 +
94902 +#define MEMAC_IEVNT_PCS 0x80000000 /* PCS (XG). Link sync (G) */
94903 +#define MEMAC_IEVNT_AN 0x40000000 /* Auto-negotiation */
94904 +#define MEMAC_IEVNT_LT 0x20000000 /* Link Training/New page */
94905 +#define MEMAC_IEVNT_MGI 0x00004000 /* Magic pkt detection */
94906 +#define MEMAC_IEVNT_TS_ECC_ER 0x00002000 /* Timestamp FIFO ECC error */
94907 +#define MEMAC_IEVNT_RX_FIFO_OVFL 0x00001000 /* Rx FIFO overflow */
94908 +#define MEMAC_IEVNT_TX_FIFO_UNFL 0x00000800 /* Tx FIFO underflow */
94909 +#define MEMAC_IEVNT_TX_FIFO_OVFL 0x00000400 /* Tx FIFO overflow */
94910 +#define MEMAC_IEVNT_TX_ECC_ER 0x00000200 /* Tx frame ECC error */
94911 +#define MEMAC_IEVNT_RX_ECC_ER 0x00000100 /* Rx frame ECC error */
94912 +#define MEMAC_IEVNT_LI_FAULT 0x00000080 /* Link Interruption flt */
94913 +#define MEMAC_IEVNT_RX_EMPTY 0x00000040 /* Rx FIFO empty */
94914 +#define MEMAC_IEVNT_TX_EMPTY 0x00000020 /* Tx FIFO empty */
94915 +#define MEMAC_IEVNT_RX_LOWP 0x00000010 /* Low Power Idle */
94916 +#define MEMAC_IEVNT_PHY_LOS 0x00000004 /* Phy loss of signal */
94917 +#define MEMAC_IEVNT_REM_FAULT 0x00000002 /* Remote fault (XGMII) */
94918 +#define MEMAC_IEVNT_LOC_FAULT 0x00000001 /* Local fault (XGMII) */
94919 +
94920 +enum memac_counters {
94921 + E_MEMAC_COUNTER_R64,
94922 + E_MEMAC_COUNTER_T64,
94923 + E_MEMAC_COUNTER_R127,
94924 + E_MEMAC_COUNTER_T127,
94925 + E_MEMAC_COUNTER_R255,
94926 + E_MEMAC_COUNTER_T255,
94927 + E_MEMAC_COUNTER_R511,
94928 + E_MEMAC_COUNTER_T511,
94929 + E_MEMAC_COUNTER_R1023,
94930 + E_MEMAC_COUNTER_T1023,
94931 + E_MEMAC_COUNTER_R1518,
94932 + E_MEMAC_COUNTER_T1518,
94933 + E_MEMAC_COUNTER_R1519X,
94934 + E_MEMAC_COUNTER_T1519X,
94935 + E_MEMAC_COUNTER_RFRG,
94936 + E_MEMAC_COUNTER_RJBR,
94937 + E_MEMAC_COUNTER_RDRP,
94938 + E_MEMAC_COUNTER_RALN,
94939 + E_MEMAC_COUNTER_TUND,
94940 + E_MEMAC_COUNTER_ROVR,
94941 + E_MEMAC_COUNTER_RXPF,
94942 + E_MEMAC_COUNTER_TXPF,
94943 + E_MEMAC_COUNTER_ROCT,
94944 + E_MEMAC_COUNTER_RMCA,
94945 + E_MEMAC_COUNTER_RBCA,
94946 + E_MEMAC_COUNTER_RPKT,
94947 + E_MEMAC_COUNTER_RUCA,
94948 + E_MEMAC_COUNTER_RERR,
94949 + E_MEMAC_COUNTER_TOCT,
94950 + E_MEMAC_COUNTER_TMCA,
94951 + E_MEMAC_COUNTER_TBCA,
94952 + E_MEMAC_COUNTER_TUCA,
94953 + E_MEMAC_COUNTER_TERR
94954 +};
94955 +
94956 +#define DEFAULT_PAUSE_QUANTA 0xf000
94957 +#define DEFAULT_FRAME_LENGTH 0x600
94958 +#define DEFAULT_TX_IPG_LENGTH 12
94959 +
94960 +/*
94961 + * memory map
94962 + */
94963 +
94964 +struct mac_addr {
94965 + uint32_t mac_addr_l; /* Lower 32 bits of 48-bit MAC address */
94966 + uint32_t mac_addr_u; /* Upper 16 bits of 48-bit MAC address */
94967 +};
94968 +
94969 +struct memac_regs {
94970 + /* General Control and Status */
94971 + uint32_t res0000[2];
94972 + uint32_t command_config; /* 0x008 Ctrl and cfg */
94973 + struct mac_addr mac_addr0; /* 0x00C-0x010 MAC_ADDR_0...1 */
94974 + uint32_t maxfrm; /* 0x014 Max frame length */
94975 + uint32_t res0018[1];
94976 + uint32_t rx_fifo_sections; /* Receive FIFO configuration reg */
94977 + uint32_t tx_fifo_sections; /* Transmit FIFO configuration reg */
94978 + uint32_t res0024[2];
94979 + uint32_t hashtable_ctrl; /* 0x02C Hash table control */
94980 + uint32_t res0030[4];
94981 + uint32_t ievent; /* 0x040 Interrupt event */
94982 + uint32_t tx_ipg_length; /* 0x044 Transmitter inter-packet-gap */
94983 + uint32_t res0048;
94984 + uint32_t imask; /* 0x04C Interrupt mask */
94985 + uint32_t res0050;
94986 + uint32_t pause_quanta[4]; /* 0x054 Pause quanta */
94987 + uint32_t pause_thresh[4]; /* 0x064 Pause quanta threshold */
94988 + uint32_t rx_pause_status; /* 0x074 Receive pause status */
94989 + uint32_t res0078[2];
94990 + struct mac_addr mac_addr[MEMAC_NUM_OF_PADDRS]; /* 0x80-0x0B4 mac padr */
94991 + uint32_t lpwake_timer; /* 0x0B8 Low Power Wakeup Timer */
94992 + uint32_t sleep_timer; /* 0x0BC Transmit EEE Low Power Timer */
94993 + uint32_t res00c0[8];
94994 + uint32_t statn_config; /* 0x0E0 Statistics configuration */
94995 + uint32_t res00e4[7];
94996 + /* Rx Statistics Counter */
94997 + uint32_t reoct_l;
94998 + uint32_t reoct_u;
94999 + uint32_t roct_l;
95000 + uint32_t roct_u;
95001 + uint32_t raln_l;
95002 + uint32_t raln_u;
95003 + uint32_t rxpf_l;
95004 + uint32_t rxpf_u;
95005 + uint32_t rfrm_l;
95006 + uint32_t rfrm_u;
95007 + uint32_t rfcs_l;
95008 + uint32_t rfcs_u;
95009 + uint32_t rvlan_l;
95010 + uint32_t rvlan_u;
95011 + uint32_t rerr_l;
95012 + uint32_t rerr_u;
95013 + uint32_t ruca_l;
95014 + uint32_t ruca_u;
95015 + uint32_t rmca_l;
95016 + uint32_t rmca_u;
95017 + uint32_t rbca_l;
95018 + uint32_t rbca_u;
95019 + uint32_t rdrp_l;
95020 + uint32_t rdrp_u;
95021 + uint32_t rpkt_l;
95022 + uint32_t rpkt_u;
95023 + uint32_t rund_l;
95024 + uint32_t rund_u;
95025 + uint32_t r64_l;
95026 + uint32_t r64_u;
95027 + uint32_t r127_l;
95028 + uint32_t r127_u;
95029 + uint32_t r255_l;
95030 + uint32_t r255_u;
95031 + uint32_t r511_l;
95032 + uint32_t r511_u;
95033 + uint32_t r1023_l;
95034 + uint32_t r1023_u;
95035 + uint32_t r1518_l;
95036 + uint32_t r1518_u;
95037 + uint32_t r1519x_l;
95038 + uint32_t r1519x_u;
95039 + uint32_t rovr_l;
95040 + uint32_t rovr_u;
95041 + uint32_t rjbr_l;
95042 + uint32_t rjbr_u;
95043 + uint32_t rfrg_l;
95044 + uint32_t rfrg_u;
95045 + uint32_t rcnp_l;
95046 + uint32_t rcnp_u;
95047 + uint32_t rdrntp_l;
95048 + uint32_t rdrntp_u;
95049 + uint32_t res01d0[12];
95050 + /* Tx Statistics Counter */
95051 + uint32_t teoct_l;
95052 + uint32_t teoct_u;
95053 + uint32_t toct_l;
95054 + uint32_t toct_u;
95055 + uint32_t res0210[2];
95056 + uint32_t txpf_l;
95057 + uint32_t txpf_u;
95058 + uint32_t tfrm_l;
95059 + uint32_t tfrm_u;
95060 + uint32_t tfcs_l;
95061 + uint32_t tfcs_u;
95062 + uint32_t tvlan_l;
95063 + uint32_t tvlan_u;
95064 + uint32_t terr_l;
95065 + uint32_t terr_u;
95066 + uint32_t tuca_l;
95067 + uint32_t tuca_u;
95068 + uint32_t tmca_l;
95069 + uint32_t tmca_u;
95070 + uint32_t tbca_l;
95071 + uint32_t tbca_u;
95072 + uint32_t res0258[2];
95073 + uint32_t tpkt_l;
95074 + uint32_t tpkt_u;
95075 + uint32_t tund_l;
95076 + uint32_t tund_u;
95077 + uint32_t t64_l;
95078 + uint32_t t64_u;
95079 + uint32_t t127_l;
95080 + uint32_t t127_u;
95081 + uint32_t t255_l;
95082 + uint32_t t255_u;
95083 + uint32_t t511_l;
95084 + uint32_t t511_u;
95085 + uint32_t t1023_l;
95086 + uint32_t t1023_u;
95087 + uint32_t t1518_l;
95088 + uint32_t t1518_u;
95089 + uint32_t t1519x_l;
95090 + uint32_t t1519x_u;
95091 + uint32_t res02a8[6];
95092 + uint32_t tcnp_l;
95093 + uint32_t tcnp_u;
95094 + uint32_t res02c8[14];
95095 + /* Line Interface Control */
95096 + uint32_t if_mode; /* 0x300 Interface Mode Control */
95097 + uint32_t if_status; /* 0x304 Interface Status */
95098 + uint32_t res0308[14];
95099 + /* HiGig/2 */
95100 + uint32_t hg_config; /* 0x340 Control and cfg */
95101 + uint32_t res0344[3];
95102 + uint32_t hg_pause_quanta; /* 0x350 Pause quanta */
95103 + uint32_t res0354[3];
95104 + uint32_t hg_pause_thresh; /* 0x360 Pause quanta threshold */
95105 + uint32_t res0364[3];
95106 + uint32_t hgrx_pause_status; /* 0x370 Receive pause status */
95107 + uint32_t hg_fifos_status; /* 0x374 fifos status */
95108 + uint32_t rhm; /* 0x378 rx messages counter */
95109 + uint32_t thm; /* 0x37C tx messages counter */
95110 +};
95111 +
95112 +struct memac_cfg {
95113 + bool reset_on_init;
95114 + bool rx_error_discard;
95115 + bool pause_ignore;
95116 + bool pause_forward_enable;
95117 + bool no_length_check_enable;
95118 + bool cmd_frame_enable;
95119 + bool send_idle_enable;
95120 + bool wan_mode_enable;
95121 + bool promiscuous_mode_enable;
95122 + bool tx_addr_ins_enable;
95123 + bool loopback_enable;
95124 + bool lgth_check_nostdr;
95125 + bool time_stamp_enable;
95126 + bool pad_enable;
95127 + bool phy_tx_ena_on;
95128 + bool rx_sfd_any;
95129 + bool rx_pbl_fwd;
95130 + bool tx_pbl_fwd;
95131 + bool debug_mode;
95132 + bool wake_on_lan;
95133 + uint16_t max_frame_length;
95134 + uint16_t pause_quanta;
95135 + uint32_t tx_ipg_length;
95136 +};
95137 +
95138 +
95139 +/**
95140 + * fman_memac_defconfig() - Get default MEMAC configuration
95141 + * @cfg: pointer to configuration structure.
95142 + *
95143 + * Call this function to obtain a default set of configuration values for
95144 + * initializing MEMAC. The user can overwrite any of the values before calling
95145 + * fman_memac_init(), if specific configuration needs to be applied.
95146 + */
95147 +void fman_memac_defconfig(struct memac_cfg *cfg);
95148 +
95149 +int fman_memac_init(struct memac_regs *regs,
95150 + struct memac_cfg *cfg,
95151 + enum enet_interface enet_interface,
95152 + enum enet_speed enet_speed,
95153 + bool slow_10g_if,
95154 + uint32_t exceptions);
95155 +
95156 +void fman_memac_enable(struct memac_regs *regs, bool apply_rx, bool apply_tx);
95157 +
95158 +void fman_memac_disable(struct memac_regs *regs, bool apply_rx, bool apply_tx);
95159 +
95160 +void fman_memac_set_promiscuous(struct memac_regs *regs, bool val);
95161 +
95162 +void fman_memac_add_addr_in_paddr(struct memac_regs *regs,
95163 + uint8_t *adr,
95164 + uint8_t paddr_num);
95165 +
95166 +void fman_memac_clear_addr_in_paddr(struct memac_regs *regs,
95167 + uint8_t paddr_num);
95168 +
95169 +uint64_t fman_memac_get_counter(struct memac_regs *regs,
95170 + enum memac_counters reg_name);
95171 +
95172 +void fman_memac_set_tx_pause_frames(struct memac_regs *regs,
95173 + uint8_t priority, uint16_t pauseTime, uint16_t threshTime);
95174 +
95175 +uint16_t fman_memac_get_max_frame_len(struct memac_regs *regs);
95176 +
95177 +void fman_memac_set_exception(struct memac_regs *regs, uint32_t val,
95178 + bool enable);
95179 +
95180 +void fman_memac_reset_stat(struct memac_regs *regs);
95181 +
95182 +void fman_memac_reset(struct memac_regs *regs);
95183 +
95184 +void fman_memac_reset_filter_table(struct memac_regs *regs);
95185 +
95186 +void fman_memac_set_hash_table_entry(struct memac_regs *regs, uint32_t crc);
95187 +
95188 +void fman_memac_set_hash_table(struct memac_regs *regs, uint32_t val);
95189 +
95190 +void fman_memac_set_rx_ignore_pause_frames(struct memac_regs *regs,
95191 + bool enable);
95192 +
95193 +void fman_memac_set_wol(struct memac_regs *regs, bool enable);
95194 +
95195 +uint32_t fman_memac_get_event(struct memac_regs *regs, uint32_t ev_mask);
95196 +
95197 +void fman_memac_ack_event(struct memac_regs *regs, uint32_t ev_mask);
95198 +
95199 +uint32_t fman_memac_get_interrupt_mask(struct memac_regs *regs);
95200 +
95201 +void fman_memac_adjust_link(struct memac_regs *regs,
95202 + enum enet_interface iface_mode,
95203 + enum enet_speed speed, bool full_dx);
95204 +
95205 +
95206 +
95207 +#endif /*__FSL_FMAN_MEMAC_H*/
95208 --- /dev/null
95209 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/flib/fsl_fman_memac_mii_acc.h
95210 @@ -0,0 +1,78 @@
95211 +/*
95212 + * Copyright 2008-2013 Freescale Semiconductor Inc.
95213 + *
95214 + * Redistribution and use in source and binary forms, with or without
95215 + * modification, are permitted provided that the following conditions are met:
95216 + * * Redistributions of source code must retain the above copyright
95217 + * notice, this list of conditions and the following disclaimer.
95218 + * * Redistributions in binary form must reproduce the above copyright
95219 + * notice, this list of conditions and the following disclaimer in the
95220 + * documentation and/or other materials provided with the distribution.
95221 + * * Neither the name of Freescale Semiconductor nor the
95222 + * names of its contributors may be used to endorse or promote products
95223 + * derived from this software without specific prior written permission.
95224 + *
95225 + *
95226 + * ALTERNATIVELY, this software may be distributed under the terms of the
95227 + * GNU General Public License ("GPL") as published by the Free Software
95228 + * Foundation, either version 2 of that License or (at your option) any
95229 + * later version.
95230 + *
95231 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
95232 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
95233 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
95234 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
95235 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
95236 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
95237 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
95238 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
95239 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
95240 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
95241 + */
95242 +
95243 +#ifndef __FSL_FMAN_MEMAC_MII_ACC_H
95244 +#define __FSL_FMAN_MEMAC_MII_ACC_H
95245 +
95246 +#include "common/general.h"
95247 +#include "fsl_enet.h"
95248 +/* MII Management Registers */
95249 +#define MDIO_CFG_CLK_DIV_MASK 0x0080ff80
95250 +#define MDIO_CFG_CLK_DIV_SHIFT 7
95251 +#define MDIO_CFG_HOLD_MASK 0x0000001c
95252 +#define MDIO_CFG_ENC45 0x00000040
95253 +#define MDIO_CFG_READ_ERR 0x00000002
95254 +#define MDIO_CFG_BSY 0x00000001
95255 +
95256 +#define MDIO_CTL_PHY_ADDR_SHIFT 5
95257 +#define MDIO_CTL_READ 0x00008000
95258 +
95259 +#define MDIO_DATA_BSY 0x80000000
95260 +
95261 +/*MEMAC Internal PHY Registers - SGMII */
95262 +#define PHY_SGMII_CR_PHY_RESET 0x8000
95263 +#define PHY_SGMII_CR_RESET_AN 0x0200
95264 +#define PHY_SGMII_CR_DEF_VAL 0x1140
95265 +#define PHY_SGMII_DEV_ABILITY_SGMII 0x4001
95266 +#define PHY_SGMII_DEV_ABILITY_1000X 0x01A0
95267 +#define PHY_SGMII_IF_MODE_AN 0x0002
95268 +#define PHY_SGMII_IF_MODE_SGMII 0x0001
95269 +#define PHY_SGMII_IF_MODE_1000X 0x0000
95270 +
95271 +/*----------------------------------------------------*/
95272 +/* MII Configuration Control Memory Map Registers */
95273 +/*----------------------------------------------------*/
95274 +struct memac_mii_access_mem_map {
95275 + uint32_t mdio_cfg; /* 0x030 */
95276 + uint32_t mdio_ctrl; /* 0x034 */
95277 + uint32_t mdio_data; /* 0x038 */
95278 + uint32_t mdio_addr; /* 0x03c */
95279 +};
95280 +
95281 +int fman_memac_mii_read_phy_reg(struct memac_mii_access_mem_map *mii_regs,
95282 + uint8_t phy_addr, uint8_t reg, uint16_t *data,
95283 + enum enet_speed enet_speed);
95284 +int fman_memac_mii_write_phy_reg(struct memac_mii_access_mem_map *mii_regs,
95285 + uint8_t phy_addr, uint8_t reg, uint16_t data,
95286 + enum enet_speed enet_speed);
95287 +
95288 +#endif /* __MAC_API_MEMAC_MII_ACC_H */
95289 --- /dev/null
95290 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/flib/fsl_fman_port.h
95291 @@ -0,0 +1,593 @@
95292 +/*
95293 + * Copyright 2008-2013 Freescale Semiconductor Inc.
95294 + *
95295 + * Redistribution and use in source and binary forms, with or without
95296 + * modification, are permitted provided that the following conditions are met:
95297 + * * Redistributions of source code must retain the above copyright
95298 + * notice, this list of conditions and the following disclaimer.
95299 + * * Redistributions in binary form must reproduce the above copyright
95300 + * notice, this list of conditions and the following disclaimer in the
95301 + * documentation and/or other materials provided with the distribution.
95302 + * * Neither the name of Freescale Semiconductor nor the
95303 + * names of its contributors may be used to endorse or promote products
95304 + * derived from this software without specific prior written permission.
95305 + *
95306 + *
95307 + * ALTERNATIVELY, this software may be distributed under the terms of the
95308 + * GNU General Public License ("GPL") as published by the Free Software
95309 + * Foundation, either version 2 of that License or (at your option) any
95310 + * later version.
95311 + *
95312 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
95313 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
95314 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
95315 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
95316 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
95317 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
95318 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
95319 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
95320 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
95321 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
95322 + */
95323 +
95324 +#ifndef __FSL_FMAN_PORT_H
95325 +#define __FSL_FMAN_PORT_H
95326 +
95327 +#include "fsl_fman_sp.h"
95328 +
95329 +/** @Collection Registers bit fields */
95330 +
95331 +/** @Description BMI defines */
95332 +#define BMI_EBD_EN 0x80000000
95333 +
95334 +#define BMI_PORT_CFG_EN 0x80000000
95335 +#define BMI_PORT_CFG_FDOVR 0x02000000
95336 +#define BMI_PORT_CFG_IM 0x01000000
95337 +
95338 +#define BMI_PORT_STATUS_BSY 0x80000000
95339 +
95340 +#define BMI_DMA_ATTR_SWP_SHIFT FMAN_SP_DMA_ATTR_SWP_SHIFT
95341 +#define BMI_DMA_ATTR_IC_STASH_ON 0x10000000
95342 +#define BMI_DMA_ATTR_HDR_STASH_ON 0x04000000
95343 +#define BMI_DMA_ATTR_SG_STASH_ON 0x01000000
95344 +#define BMI_DMA_ATTR_WRITE_OPTIMIZE FMAN_SP_DMA_ATTR_WRITE_OPTIMIZE
95345 +
95346 +#define BMI_RX_FIFO_PRI_ELEVATION_SHIFT 16
95347 +#define BMI_RX_FIFO_THRESHOLD_ETHE 0x80000000
95348 +
95349 +#define BMI_TX_FRAME_END_CS_IGNORE_SHIFT 24
95350 +#define BMI_RX_FRAME_END_CS_IGNORE_SHIFT 24
95351 +#define BMI_RX_FRAME_END_CUT_SHIFT 16
95352 +
95353 +#define BMI_IC_TO_EXT_SHIFT FMAN_SP_IC_TO_EXT_SHIFT
95354 +#define BMI_IC_FROM_INT_SHIFT FMAN_SP_IC_FROM_INT_SHIFT
95355 +
95356 +#define BMI_INT_BUF_MARG_SHIFT 28
95357 +#define BMI_EXT_BUF_MARG_START_SHIFT FMAN_SP_EXT_BUF_MARG_START_SHIFT
95358 +
95359 +#define BMI_CMD_MR_LEAC 0x00200000
95360 +#define BMI_CMD_MR_SLEAC 0x00100000
95361 +#define BMI_CMD_MR_MA 0x00080000
95362 +#define BMI_CMD_MR_DEAS 0x00040000
95363 +#define BMI_CMD_RX_MR_DEF (BMI_CMD_MR_LEAC | \
95364 + BMI_CMD_MR_SLEAC | \
95365 + BMI_CMD_MR_MA | \
95366 + BMI_CMD_MR_DEAS)
95367 +#define BMI_CMD_TX_MR_DEF 0
95368 +#define BMI_CMD_OP_MR_DEF (BMI_CMD_MR_DEAS | \
95369 + BMI_CMD_MR_MA)
95370 +
95371 +#define BMI_CMD_ATTR_ORDER 0x80000000
95372 +#define BMI_CMD_ATTR_SYNC 0x02000000
95373 +#define BMI_CMD_ATTR_COLOR_SHIFT 26
95374 +
95375 +#define BMI_FIFO_PIPELINE_DEPTH_SHIFT 12
95376 +#define BMI_NEXT_ENG_FD_BITS_SHIFT 24
95377 +#define BMI_FRAME_END_CS_IGNORE_SHIFT 24
95378 +
95379 +#define BMI_COUNTERS_EN 0x80000000
95380 +
95381 +#define BMI_EXT_BUF_POOL_VALID FMAN_SP_EXT_BUF_POOL_VALID
95382 +#define BMI_EXT_BUF_POOL_EN_COUNTER FMAN_SP_EXT_BUF_POOL_EN_COUNTER
95383 +#define BMI_EXT_BUF_POOL_BACKUP FMAN_SP_EXT_BUF_POOL_BACKUP
95384 +#define BMI_EXT_BUF_POOL_ID_SHIFT 16
95385 +#define BMI_EXT_BUF_POOL_ID_MASK 0x003F0000
95386 +#define BMI_POOL_DEP_NUM_OF_POOLS_SHIFT 16
95387 +
95388 +#define BMI_TX_FIFO_MIN_FILL_SHIFT 16
95389 +#define BMI_TX_FIFO_PIPELINE_DEPTH_SHIFT 12
95390 +
95391 +#define MAX_PERFORMANCE_TASK_COMP 64
95392 +#define MAX_PERFORMANCE_RX_QUEUE_COMP 64
95393 +#define MAX_PERFORMANCE_TX_QUEUE_COMP 8
95394 +#define MAX_PERFORMANCE_DMA_COMP 16
95395 +#define MAX_PERFORMANCE_FIFO_COMP 1024
95396 +
95397 +#define BMI_PERFORMANCE_TASK_COMP_SHIFT 24
95398 +#define BMI_PERFORMANCE_QUEUE_COMP_SHIFT 16
95399 +#define BMI_PERFORMANCE_DMA_COMP_SHIFT 12
95400 +
95401 +#define BMI_RATE_LIMIT_GRAN_TX 16000 /* In Kbps */
95402 +#define BMI_RATE_LIMIT_GRAN_OP 10000 /* In frames */
95403 +#define BMI_RATE_LIMIT_MAX_RATE_IN_GRAN_UNITS 1024
95404 +#define BMI_RATE_LIMIT_MAX_BURST_SIZE 1024 /* In KBytes */
95405 +#define BMI_RATE_LIMIT_MAX_BURST_SHIFT 16
95406 +#define BMI_RATE_LIMIT_HIGH_BURST_SIZE_GRAN 0x80000000
95407 +#define BMI_RATE_LIMIT_SCALE_TSBS_SHIFT 16
95408 +#define BMI_RATE_LIMIT_SCALE_EN 0x80000000
95409 +#define BMI_SG_DISABLE FMAN_SP_SG_DISABLE
95410 +
95411 +/** @Description QMI defines */
95412 +#define QMI_PORT_CFG_EN 0x80000000
95413 +#define QMI_PORT_CFG_EN_COUNTERS 0x10000000
95414 +
95415 +#define QMI_PORT_STATUS_DEQ_TNUM_BSY 0x80000000
95416 +#define QMI_PORT_STATUS_DEQ_FD_BSY 0x20000000
95417 +
95418 +#define QMI_DEQ_CFG_PRI 0x80000000
95419 +#define QMI_DEQ_CFG_TYPE1 0x10000000
95420 +#define QMI_DEQ_CFG_TYPE2 0x20000000
95421 +#define QMI_DEQ_CFG_TYPE3 0x30000000
95422 +#define QMI_DEQ_CFG_PREFETCH_PARTIAL 0x01000000
95423 +#define QMI_DEQ_CFG_PREFETCH_FULL 0x03000000
95424 +#define QMI_DEQ_CFG_SP_MASK 0xf
95425 +#define QMI_DEQ_CFG_SP_SHIFT 20
95426 +
95427 +
95428 +/** @Description General port defines */
95429 +#define FMAN_PORT_EXT_POOLS_NUM(fm_rev_maj) \
95430 + (((fm_rev_maj) == 4) ? 4 : 8)
95431 +#define FMAN_PORT_MAX_EXT_POOLS_NUM 8
95432 +#define FMAN_PORT_OBS_EXT_POOLS_NUM 2
95433 +#define FMAN_PORT_CG_MAP_NUM 8
95434 +#define FMAN_PORT_PRS_RESULT_WORDS_NUM 8
95435 +#define FMAN_PORT_BMI_FIFO_UNITS 0x100
95436 +#define FMAN_PORT_IC_OFFSET_UNITS 0x10
95437 +
95438 +
95439 +/** @Collection FM Port Register Map */
95440 +
95441 +/** @Description BMI Rx port register map */
95442 +struct fman_port_rx_bmi_regs {
95443 + uint32_t fmbm_rcfg; /**< Rx Configuration */
95444 + uint32_t fmbm_rst; /**< Rx Status */
95445 + uint32_t fmbm_rda; /**< Rx DMA attributes*/
95446 + uint32_t fmbm_rfp; /**< Rx FIFO Parameters*/
95447 + uint32_t fmbm_rfed; /**< Rx Frame End Data*/
95448 + uint32_t fmbm_ricp; /**< Rx Internal Context Parameters*/
95449 + uint32_t fmbm_rim; /**< Rx Internal Buffer Margins*/
95450 + uint32_t fmbm_rebm; /**< Rx External Buffer Margins*/
95451 + uint32_t fmbm_rfne; /**< Rx Frame Next Engine*/
95452 + uint32_t fmbm_rfca; /**< Rx Frame Command Attributes.*/
95453 + uint32_t fmbm_rfpne; /**< Rx Frame Parser Next Engine*/
95454 + uint32_t fmbm_rpso; /**< Rx Parse Start Offset*/
95455 + uint32_t fmbm_rpp; /**< Rx Policer Profile */
95456 + uint32_t fmbm_rccb; /**< Rx Coarse Classification Base */
95457 + uint32_t fmbm_reth; /**< Rx Excessive Threshold */
95458 + uint32_t reserved003c[1]; /**< (0x03C 0x03F) */
95459 + uint32_t fmbm_rprai[FMAN_PORT_PRS_RESULT_WORDS_NUM];
95460 + /**< Rx Parse Results Array Init*/
95461 + uint32_t fmbm_rfqid; /**< Rx Frame Queue ID*/
95462 + uint32_t fmbm_refqid; /**< Rx Error Frame Queue ID*/
95463 + uint32_t fmbm_rfsdm; /**< Rx Frame Status Discard Mask*/
95464 + uint32_t fmbm_rfsem; /**< Rx Frame Status Error Mask*/
95465 + uint32_t fmbm_rfene; /**< Rx Frame Enqueue Next Engine */
95466 + uint32_t reserved0074[0x2]; /**< (0x074-0x07C) */
95467 + uint32_t fmbm_rcmne; /**< Rx Frame Continuous Mode Next Engine */
95468 + uint32_t reserved0080[0x20];/**< (0x080 0x0FF) */
95469 + uint32_t fmbm_ebmpi[FMAN_PORT_MAX_EXT_POOLS_NUM];
95470 + /**< Buffer Manager pool Information-*/
95471 + uint32_t fmbm_acnt[FMAN_PORT_MAX_EXT_POOLS_NUM];
95472 + /**< Allocate Counter-*/
95473 + uint32_t reserved0130[8];
95474 + /**< 0x130/0x140 - 0x15F reserved -*/
95475 + uint32_t fmbm_rcgm[FMAN_PORT_CG_MAP_NUM];
95476 + /**< Congestion Group Map*/
95477 + uint32_t fmbm_mpd; /**< BM Pool Depletion */
95478 + uint32_t reserved0184[0x1F]; /**< (0x184 0x1FF) */
95479 + uint32_t fmbm_rstc; /**< Rx Statistics Counters*/
95480 + uint32_t fmbm_rfrc; /**< Rx Frame Counter*/
95481 + uint32_t fmbm_rfbc; /**< Rx Bad Frames Counter*/
95482 + uint32_t fmbm_rlfc; /**< Rx Large Frames Counter*/
95483 + uint32_t fmbm_rffc; /**< Rx Filter Frames Counter*/
95484 + uint32_t fmbm_rfdc; /**< Rx Frame Discard Counter*/
95485 + uint32_t fmbm_rfldec; /**< Rx Frames List DMA Error Counter*/
95486 + uint32_t fmbm_rodc; /**< Rx Out of Buffers Discard nntr*/
95487 + uint32_t fmbm_rbdc; /**< Rx Buffers Deallocate Counter*/
95488 + uint32_t reserved0224[0x17]; /**< (0x224 0x27F) */
95489 + uint32_t fmbm_rpc; /**< Rx Performance Counters*/
95490 + uint32_t fmbm_rpcp; /**< Rx Performance Count Parameters*/
95491 + uint32_t fmbm_rccn; /**< Rx Cycle Counter*/
95492 + uint32_t fmbm_rtuc; /**< Rx Tasks Utilization Counter*/
95493 + uint32_t fmbm_rrquc; /**< Rx Receive Queue Utilization cntr*/
95494 + uint32_t fmbm_rduc; /**< Rx DMA Utilization Counter*/
95495 + uint32_t fmbm_rfuc; /**< Rx FIFO Utilization Counter*/
95496 + uint32_t fmbm_rpac; /**< Rx Pause Activation Counter*/
95497 + uint32_t reserved02a0[0x18]; /**< (0x2A0 0x2FF) */
95498 + uint32_t fmbm_rdbg; /**< Rx Debug-*/
95499 +};
95500 +
95501 +/** @Description BMI Tx port register map */
95502 +struct fman_port_tx_bmi_regs {
95503 + uint32_t fmbm_tcfg; /**< Tx Configuration */
95504 + uint32_t fmbm_tst; /**< Tx Status */
95505 + uint32_t fmbm_tda; /**< Tx DMA attributes */
95506 + uint32_t fmbm_tfp; /**< Tx FIFO Parameters */
95507 + uint32_t fmbm_tfed; /**< Tx Frame End Data */
95508 + uint32_t fmbm_ticp; /**< Tx Internal Context Parameters */
95509 + uint32_t fmbm_tfdne; /**< Tx Frame Dequeue Next Engine. */
95510 + uint32_t fmbm_tfca; /**< Tx Frame Command attribute. */
95511 + uint32_t fmbm_tcfqid; /**< Tx Confirmation Frame Queue ID. */
95512 + uint32_t fmbm_tefqid; /**< Tx Frame Error Queue ID */
95513 + uint32_t fmbm_tfene; /**< Tx Frame Enqueue Next Engine */
95514 + uint32_t fmbm_trlmts; /**< Tx Rate Limiter Scale */
95515 + uint32_t fmbm_trlmt; /**< Tx Rate Limiter */
95516 + uint32_t reserved0034[0x0e]; /**< (0x034-0x6c) */
95517 + uint32_t fmbm_tccb; /**< Tx Coarse Classification base */
95518 + uint32_t fmbm_tfne; /**< Tx Frame Next Engine */
95519 + uint32_t fmbm_tpfcm[0x02]; /**< Tx Priority based Flow Control (PFC) Mapping */
95520 + uint32_t fmbm_tcmne; /**< Tx Frame Continuous Mode Next Engine */
95521 + uint32_t reserved0080[0x60]; /**< (0x080-0x200) */
95522 + uint32_t fmbm_tstc; /**< Tx Statistics Counters */
95523 + uint32_t fmbm_tfrc; /**< Tx Frame Counter */
95524 + uint32_t fmbm_tfdc; /**< Tx Frames Discard Counter */
95525 + uint32_t fmbm_tfledc; /**< Tx Frame len error discard cntr */
95526 + uint32_t fmbm_tfufdc; /**< Tx Frame unsprt frmt discard cntr*/
95527 + uint32_t fmbm_tbdc; /**< Tx Buffers Deallocate Counter */
95528 + uint32_t reserved0218[0x1A]; /**< (0x218-0x280) */
95529 + uint32_t fmbm_tpc; /**< Tx Performance Counters*/
95530 + uint32_t fmbm_tpcp; /**< Tx Performance Count Parameters*/
95531 + uint32_t fmbm_tccn; /**< Tx Cycle Counter*/
95532 + uint32_t fmbm_ttuc; /**< Tx Tasks Utilization Counter*/
95533 + uint32_t fmbm_ttcquc; /**< Tx Transmit conf Q util Counter*/
95534 + uint32_t fmbm_tduc; /**< Tx DMA Utilization Counter*/
95535 + uint32_t fmbm_tfuc; /**< Tx FIFO Utilization Counter*/
95536 +};
95537 +
95538 +/** @Description BMI O/H port register map */
95539 +struct fman_port_oh_bmi_regs {
95540 + uint32_t fmbm_ocfg; /**< O/H Configuration */
95541 + uint32_t fmbm_ost; /**< O/H Status */
95542 + uint32_t fmbm_oda; /**< O/H DMA attributes */
95543 + uint32_t fmbm_oicp; /**< O/H Internal Context Parameters */
95544 + uint32_t fmbm_ofdne; /**< O/H Frame Dequeue Next Engine */
95545 + uint32_t fmbm_ofne; /**< O/H Frame Next Engine */
95546 + uint32_t fmbm_ofca; /**< O/H Frame Command Attributes. */
95547 + uint32_t fmbm_ofpne; /**< O/H Frame Parser Next Engine */
95548 + uint32_t fmbm_opso; /**< O/H Parse Start Offset */
95549 + uint32_t fmbm_opp; /**< O/H Policer Profile */
95550 + uint32_t fmbm_occb; /**< O/H Coarse Classification base */
95551 + uint32_t fmbm_oim; /**< O/H Internal margins*/
95552 + uint32_t fmbm_ofp; /**< O/H Fifo Parameters*/
95553 + uint32_t fmbm_ofed; /**< O/H Frame End Data*/
95554 + uint32_t reserved0030[2]; /**< (0x038 - 0x03F) */
95555 + uint32_t fmbm_oprai[FMAN_PORT_PRS_RESULT_WORDS_NUM];
95556 + /**< O/H Parse Results Array Initialization */
95557 + uint32_t fmbm_ofqid; /**< O/H Frame Queue ID */
95558 + uint32_t fmbm_oefqid; /**< O/H Error Frame Queue ID */
95559 + uint32_t fmbm_ofsdm; /**< O/H Frame Status Discard Mask */
95560 + uint32_t fmbm_ofsem; /**< O/H Frame Status Error Mask */
95561 + uint32_t fmbm_ofene; /**< O/H Frame Enqueue Next Engine */
95562 + uint32_t fmbm_orlmts; /**< O/H Rate Limiter Scale */
95563 + uint32_t fmbm_orlmt; /**< O/H Rate Limiter */
95564 + uint32_t fmbm_ocmne; /**< O/H Continuous Mode Next Engine */
95565 + uint32_t reserved0080[0x20]; /**< 0x080 - 0x0FF Reserved */
95566 + uint32_t fmbm_oebmpi[2]; /**< Buf Mngr Observed Pool Info */
95567 + uint32_t reserved0108[0x16]; /**< 0x108 - 0x15F Reserved */
95568 + uint32_t fmbm_ocgm[FMAN_PORT_CG_MAP_NUM]; /**< Observed Congestion Group Map */
95569 + uint32_t fmbm_ompd; /**< Observed BMan Pool Depletion */
95570 + uint32_t reserved0184[0x1F]; /**< 0x184 - 0x1FF Reserved */
95571 + uint32_t fmbm_ostc; /**< O/H Statistics Counters */
95572 + uint32_t fmbm_ofrc; /**< O/H Frame Counter */
95573 + uint32_t fmbm_ofdc; /**< O/H Frames Discard Counter */
95574 + uint32_t fmbm_ofledc; /**< O/H Frames Len Err Discard Cntr */
95575 + uint32_t fmbm_ofufdc; /**< O/H Frames Unsprtd Discard Cutr */
95576 + uint32_t fmbm_offc; /**< O/H Filter Frames Counter */
95577 + uint32_t fmbm_ofwdc; /**< Rx Frames WRED Discard Counter */
95578 + uint32_t fmbm_ofldec; /**< O/H Frames List DMA Error Cntr */
95579 + uint32_t fmbm_obdc; /**< O/H Buffers Deallocate Counter */
95580 + uint32_t reserved0218[0x17]; /**< (0x218 - 0x27F) */
95581 + uint32_t fmbm_opc; /**< O/H Performance Counters */
95582 + uint32_t fmbm_opcp; /**< O/H Performance Count Parameters */
95583 + uint32_t fmbm_occn; /**< O/H Cycle Counter */
95584 + uint32_t fmbm_otuc; /**< O/H Tasks Utilization Counter */
95585 + uint32_t fmbm_oduc; /**< O/H DMA Utilization Counter */
95586 + uint32_t fmbm_ofuc; /**< O/H FIFO Utilization Counter */
95587 +};
95588 +
95589 +/** @Description BMI port register map */
95590 +union fman_port_bmi_regs {
95591 + struct fman_port_rx_bmi_regs rx;
95592 + struct fman_port_tx_bmi_regs tx;
95593 + struct fman_port_oh_bmi_regs oh;
95594 +};
95595 +
95596 +/** @Description QMI port register map */
95597 +struct fman_port_qmi_regs {
95598 + uint32_t fmqm_pnc; /**< PortID n Configuration Register */
95599 + uint32_t fmqm_pns; /**< PortID n Status Register */
95600 + uint32_t fmqm_pnts; /**< PortID n Task Status Register */
95601 + uint32_t reserved00c[4]; /**< 0xn00C - 0xn01B */
95602 + uint32_t fmqm_pnen; /**< PortID n Enqueue NIA Register */
95603 + uint32_t fmqm_pnetfc; /**< PortID n Enq Total Frame Counter */
95604 + uint32_t reserved024[2]; /**< 0xn024 - 0x02B */
95605 + uint32_t fmqm_pndn; /**< PortID n Dequeue NIA Register */
95606 + uint32_t fmqm_pndc; /**< PortID n Dequeue Config Register */
95607 + uint32_t fmqm_pndtfc; /**< PortID n Dequeue tot Frame cntr */
95608 + uint32_t fmqm_pndfdc; /**< PortID n Dequeue FQID Dflt Cntr */
95609 + uint32_t fmqm_pndcc; /**< PortID n Dequeue Confirm Counter */
95610 +};
95611 +
95612 +
95613 +enum fman_port_dma_swap {
95614 + E_FMAN_PORT_DMA_NO_SWAP, /**< No swap, transfer data as is */
95615 + E_FMAN_PORT_DMA_SWAP_LE,
95616 + /**< The transferred data should be swapped in PPC Little Endian mode */
95617 + E_FMAN_PORT_DMA_SWAP_BE
95618 + /**< The transferred data should be swapped in Big Endian mode */
95619 +};
95620 +
95621 +/* Default port color */
95622 +enum fman_port_color {
95623 + E_FMAN_PORT_COLOR_GREEN, /**< Default port color is green */
95624 + E_FMAN_PORT_COLOR_YELLOW, /**< Default port color is yellow */
95625 + E_FMAN_PORT_COLOR_RED, /**< Default port color is red */
95626 + E_FMAN_PORT_COLOR_OVERRIDE /**< Ignore color */
95627 +};
95628 +
95629 +/* QMI dequeue from the SP channel - types */
95630 +enum fman_port_deq_type {
95631 + E_FMAN_PORT_DEQ_BY_PRI,
95632 + /**< Priority precedence and Intra-Class scheduling */
95633 + E_FMAN_PORT_DEQ_ACTIVE_FQ,
95634 + /**< Active FQ precedence and Intra-Class scheduling */
95635 + E_FMAN_PORT_DEQ_ACTIVE_FQ_NO_ICS
95636 + /**< Active FQ precedence and override Intra-Class scheduling */
95637 +};
95638 +
95639 +/* QMI dequeue prefetch modes */
95640 +enum fman_port_deq_prefetch {
95641 + E_FMAN_PORT_DEQ_NO_PREFETCH, /**< No prefetch mode */
95642 + E_FMAN_PORT_DEQ_PART_PREFETCH, /**< Partial prefetch mode */
95643 + E_FMAN_PORT_DEQ_FULL_PREFETCH /**< Full prefetch mode */
95644 +};
95645 +
95646 +/* Parameters for defining performance counters behavior */
95647 +struct fman_port_perf_cnt_params {
95648 + uint8_t task_val; /**< Task compare value */
95649 + uint8_t queue_val;
95650 + /**< Rx or Tx conf queue compare value (unused for O/H ports) */
95651 + uint8_t dma_val; /**< Dma compare value */
95652 + uint32_t fifo_val; /**< Fifo compare value (in bytes) */
95653 +};
95654 +
95655 +/** @Description FM Port configuration structure, used at init */
95656 +struct fman_port_cfg {
95657 + struct fman_port_perf_cnt_params perf_cnt_params;
95658 + /* BMI parameters */
95659 + enum fman_port_dma_swap dma_swap_data;
95660 + bool dma_ic_stash_on;
95661 + bool dma_header_stash_on;
95662 + bool dma_sg_stash_on;
95663 + bool dma_write_optimize;
95664 + uint16_t ic_ext_offset;
95665 + uint8_t ic_int_offset;
95666 + uint16_t ic_size;
95667 + enum fman_port_color color;
95668 + bool sync_req;
95669 + bool discard_override;
95670 + uint8_t checksum_bytes_ignore;
95671 + uint8_t rx_cut_end_bytes;
95672 + uint32_t rx_pri_elevation;
95673 + uint32_t rx_fifo_thr;
95674 + uint8_t rx_fd_bits;
95675 + uint8_t int_buf_start_margin;
95676 + uint16_t ext_buf_start_margin;
95677 + uint16_t ext_buf_end_margin;
95678 + uint32_t tx_fifo_min_level;
95679 + uint32_t tx_fifo_low_comf_level;
95680 + uint8_t tx_fifo_deq_pipeline_depth;
95681 + bool stats_counters_enable;
95682 + bool perf_counters_enable;
95683 + /* QMI parameters */
95684 + bool deq_high_pri;
95685 + enum fman_port_deq_type deq_type;
95686 + enum fman_port_deq_prefetch deq_prefetch_opt;
95687 + uint16_t deq_byte_cnt;
95688 + bool queue_counters_enable;
95689 + bool no_scatter_gather;
95690 + int errata_A006675;
95691 + int errata_A006320;
95692 + int excessive_threshold_register;
95693 + int fmbm_rebm_has_sgd;
95694 + int fmbm_tfne_has_features;
95695 + int qmi_deq_options_support;
95696 +};
95697 +
95698 +enum fman_port_type {
95699 + E_FMAN_PORT_TYPE_OP = 0,
95700 + /**< Offline parsing port, shares id-s with
95701 + * host command, so must have exclusive id-s */
95702 + E_FMAN_PORT_TYPE_RX, /**< 1G Rx port */
95703 + E_FMAN_PORT_TYPE_RX_10G, /**< 10G Rx port */
95704 + E_FMAN_PORT_TYPE_TX, /**< 1G Tx port */
95705 + E_FMAN_PORT_TYPE_TX_10G, /**< 10G Tx port */
95706 + E_FMAN_PORT_TYPE_DUMMY,
95707 + E_FMAN_PORT_TYPE_HC = E_FMAN_PORT_TYPE_DUMMY
95708 + /**< Host command port, shares id-s with
95709 + * offline parsing ports, so must have exclusive id-s */
95710 +};
95711 +
95712 +struct fman_port_params {
95713 + uint32_t discard_mask;
95714 + uint32_t err_mask;
95715 + uint32_t dflt_fqid;
95716 + uint32_t err_fqid;
95717 + uint8_t deq_sp;
95718 + bool dont_release_buf;
95719 +};
95720 +
95721 +/* Port context - used by most API functions */
95722 +struct fman_port {
95723 + enum fman_port_type type;
95724 + uint8_t fm_rev_maj;
95725 + uint8_t fm_rev_min;
95726 + union fman_port_bmi_regs *bmi_regs;
95727 + struct fman_port_qmi_regs *qmi_regs;
95728 + bool im_en;
95729 + uint8_t ext_pools_num;
95730 +};
95731 +
95732 +/** @Description External buffer pools configuration */
95733 +struct fman_port_bpools {
95734 + uint8_t count; /**< Num of pools to set up */
95735 + bool counters_enable; /**< Enable allocate counters */
95736 + uint8_t grp_bp_depleted_num;
95737 + /**< Number of depleted pools - if reached the BMI indicates
95738 + * the MAC to send a pause frame */
95739 + struct {
95740 + uint8_t bpid; /**< BM pool ID */
95741 + uint16_t size;
95742 + /**< Pool's size - must be in ascending order */
95743 + bool is_backup;
95744 + /**< If this is a backup pool */
95745 + bool grp_bp_depleted;
95746 + /**< Consider this buffer in multiple pools depletion criteria*/
95747 + bool single_bp_depleted;
95748 + /**< Consider this buffer in single pool depletion criteria */
95749 + bool pfc_priorities_en;
95750 + } bpool[FMAN_PORT_MAX_EXT_POOLS_NUM];
95751 +};
95752 +
95753 +enum fman_port_rate_limiter_scale_down {
95754 + E_FMAN_PORT_RATE_DOWN_NONE,
95755 + E_FMAN_PORT_RATE_DOWN_BY_2,
95756 + E_FMAN_PORT_RATE_DOWN_BY_4,
95757 + E_FMAN_PORT_RATE_DOWN_BY_8
95758 +};
95759 +
95760 +/* Rate limiter configuration */
95761 +struct fman_port_rate_limiter {
95762 + uint8_t count_1micro_bit;
95763 + bool high_burst_size_gran;
95764 + /**< Defines burst_size granularity for OP ports; when TRUE,
95765 + * burst_size below counts in frames, otherwise in 10^3 frames */
95766 + uint16_t burst_size;
95767 + /**< Max burst size, in KBytes for Tx port, according to
95768 + * high_burst_size_gran definition for OP port */
95769 + uint32_t rate;
95770 + /**< In Kbps for Tx port, in frames/sec for OP port */
95771 + enum fman_port_rate_limiter_scale_down rate_factor;
95772 +};
95773 +
95774 +/* BMI statistics counters */
95775 +enum fman_port_stats_counters {
95776 + E_FMAN_PORT_STATS_CNT_FRAME,
95777 + /**< Number of processed frames; valid for all ports */
95778 + E_FMAN_PORT_STATS_CNT_DISCARD,
95779 + /**< For Rx ports - frames discarded by QMAN, for Tx or O/H ports -
95780 + * frames discarded due to DMA error; valid for all ports */
95781 + E_FMAN_PORT_STATS_CNT_DEALLOC_BUF,
95782 + /**< Number of buffer deallocate operations; valid for all ports */
95783 + E_FMAN_PORT_STATS_CNT_RX_BAD_FRAME,
95784 + /**< Number of bad Rx frames, like CRC error, Rx FIFO overflow etc;
95785 + * valid for Rx ports only */
95786 + E_FMAN_PORT_STATS_CNT_RX_LARGE_FRAME,
95787 + /**< Number of Rx oversized frames, that is frames exceeding max frame
95788 + * size configured for the corresponding ETH controller;
95789 + * valid for Rx ports only */
95790 + E_FMAN_PORT_STATS_CNT_RX_OUT_OF_BUF,
95791 + /**< Frames discarded due to lack of external buffers; valid for
95792 + * Rx ports only */
95793 + E_FMAN_PORT_STATS_CNT_LEN_ERR,
95794 + /**< Frames discarded due to frame length error; valid for Tx and
95795 + * O/H ports only */
95796 + E_FMAN_PORT_STATS_CNT_UNSUPPORTED_FORMAT,
95797 + /**< Frames discarded due to unsupported FD format; valid for Tx
95798 + * and O/H ports only */
95799 + E_FMAN_PORT_STATS_CNT_FILTERED_FRAME,
95800 + /**< Number of frames filtered out by PCD module; valid for
95801 + * Rx and OP ports only */
95802 + E_FMAN_PORT_STATS_CNT_DMA_ERR,
95803 + /**< Frames rejected by QMAN that were not able to release their
95804 + * buffers due to DMA error; valid for Rx and O/H ports only */
95805 + E_FMAN_PORT_STATS_CNT_WRED_DISCARD
95806 + /**< Frames going through O/H port that were not able to to enter the
95807 + * return queue due to WRED algorithm; valid for O/H ports only */
95808 +};
95809 +
95810 +/* BMI performance counters */
95811 +enum fman_port_perf_counters {
95812 + E_FMAN_PORT_PERF_CNT_CYCLE, /**< Cycle counter */
95813 + E_FMAN_PORT_PERF_CNT_TASK_UTIL, /**< Tasks utilization counter */
95814 + E_FMAN_PORT_PERF_CNT_QUEUE_UTIL,
95815 + /**< For Rx ports - Rx queue utilization, for Tx ports - Tx conf queue
95816 + * utilization; not valid for O/H ports */
95817 + E_FMAN_PORT_PERF_CNT_DMA_UTIL, /**< DMA utilization counter */
95818 + E_FMAN_PORT_PERF_CNT_FIFO_UTIL, /**< FIFO utilization counter */
95819 + E_FMAN_PORT_PERF_CNT_RX_PAUSE
95820 + /**< Number of cycles in which Rx pause activation control is on;
95821 + * valid for Rx ports only */
95822 +};
95823 +
95824 +/* QMI counters */
95825 +enum fman_port_qmi_counters {
95826 + E_FMAN_PORT_ENQ_TOTAL, /**< EnQ tot frame cntr */
95827 + E_FMAN_PORT_DEQ_TOTAL, /**< DeQ tot frame cntr; invalid for Rx ports */
95828 + E_FMAN_PORT_DEQ_FROM_DFLT,
95829 + /**< Dequeue from default FQID counter not valid for Rx ports */
95830 + E_FMAN_PORT_DEQ_CONFIRM /**< DeQ confirm cntr invalid for Rx ports */
95831 +};
95832 +
95833 +
95834 +/** @Collection FM Port API */
95835 +void fman_port_defconfig(struct fman_port_cfg *cfg, enum fman_port_type type);
95836 +int fman_port_init(struct fman_port *port,
95837 + struct fman_port_cfg *cfg,
95838 + struct fman_port_params *params);
95839 +int fman_port_enable(struct fman_port *port);
95840 +int fman_port_disable(const struct fman_port *port);
95841 +int fman_port_set_bpools(const struct fman_port *port,
95842 + const struct fman_port_bpools *bp);
95843 +int fman_port_set_rate_limiter(struct fman_port *port,
95844 + struct fman_port_rate_limiter *rate_limiter);
95845 +int fman_port_delete_rate_limiter(struct fman_port *port);
95846 +int fman_port_set_err_mask(struct fman_port *port, uint32_t err_mask);
95847 +int fman_port_set_discard_mask(struct fman_port *port, uint32_t discard_mask);
95848 +int fman_port_modify_rx_fd_bits(struct fman_port *port,
95849 + uint8_t rx_fd_bits,
95850 + bool add);
95851 +int fman_port_set_perf_cnt_params(struct fman_port *port,
95852 + struct fman_port_perf_cnt_params *params);
95853 +int fman_port_set_stats_cnt_mode(struct fman_port *port, bool enable);
95854 +int fman_port_set_perf_cnt_mode(struct fman_port *port, bool enable);
95855 +int fman_port_set_queue_cnt_mode(struct fman_port *port, bool enable);
95856 +int fman_port_set_bpool_cnt_mode(struct fman_port *port,
95857 + uint8_t bpid,
95858 + bool enable);
95859 +uint32_t fman_port_get_stats_counter(struct fman_port *port,
95860 + enum fman_port_stats_counters counter);
95861 +void fman_port_set_stats_counter(struct fman_port *port,
95862 + enum fman_port_stats_counters counter,
95863 + uint32_t value);
95864 +uint32_t fman_port_get_perf_counter(struct fman_port *port,
95865 + enum fman_port_perf_counters counter);
95866 +void fman_port_set_perf_counter(struct fman_port *port,
95867 + enum fman_port_perf_counters counter,
95868 + uint32_t value);
95869 +uint32_t fman_port_get_qmi_counter(struct fman_port *port,
95870 + enum fman_port_qmi_counters counter);
95871 +void fman_port_set_qmi_counter(struct fman_port *port,
95872 + enum fman_port_qmi_counters counter,
95873 + uint32_t value);
95874 +uint32_t fman_port_get_bpool_counter(struct fman_port *port, uint8_t bpid);
95875 +void fman_port_set_bpool_counter(struct fman_port *port,
95876 + uint8_t bpid,
95877 + uint32_t value);
95878 +int fman_port_add_congestion_grps(struct fman_port *port,
95879 + uint32_t grps_map[FMAN_PORT_CG_MAP_NUM]);
95880 +int fman_port_remove_congestion_grps(struct fman_port *port,
95881 + uint32_t grps_map[FMAN_PORT_CG_MAP_NUM]);
95882 +
95883 +
95884 +#endif /* __FSL_FMAN_PORT_H */
95885 --- /dev/null
95886 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/flib/fsl_fman_prs.h
95887 @@ -0,0 +1,102 @@
95888 +/*
95889 + * Copyright 2008-2012 Freescale Semiconductor Inc.
95890 + *
95891 + * Redistribution and use in source and binary forms, with or without
95892 + * modification, are permitted provided that the following conditions are met:
95893 + * * Redistributions of source code must retain the above copyright
95894 + * notice, this list of conditions and the following disclaimer.
95895 + * * Redistributions in binary form must reproduce the above copyright
95896 + * notice, this list of conditions and the following disclaimer in the
95897 + * documentation and/or other materials provided with the distribution.
95898 + * * Neither the name of Freescale Semiconductor nor the
95899 + * names of its contributors may be used to endorse or promote products
95900 + * derived from this software without specific prior written permission.
95901 + *
95902 + *
95903 + * ALTERNATIVELY, this software may be distributed under the terms of the
95904 + * GNU General Public License ("GPL") as published by the Free Software
95905 + * Foundation, either version 2 of that License or (at your option) any
95906 + * later version.
95907 + *
95908 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
95909 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
95910 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
95911 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
95912 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
95913 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
95914 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
95915 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
95916 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
95917 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
95918 + */
95919 +
95920 +#ifndef __FSL_FMAN_PRS_H
95921 +#define __FSL_FMAN_PRS_H
95922 +
95923 +#include "common/general.h"
95924 +
95925 +#define FM_PCD_EX_PRS_DOUBLE_ECC 0x02000000
95926 +#define FM_PCD_EX_PRS_SINGLE_ECC 0x01000000
95927 +
95928 +#define FM_PCD_PRS_PPSC_ALL_PORTS 0xffff0000
95929 +#define FM_PCD_PRS_RPIMAC_EN 0x00000001
95930 +#define FM_PCD_PRS_PORT_IDLE_STS 0xffff0000
95931 +#define FM_PCD_PRS_SINGLE_ECC 0x00004000
95932 +#define FM_PCD_PRS_DOUBLE_ECC 0x00004000
95933 +#define PRS_MAX_CYCLE_LIMIT 8191
95934 +
95935 +#define DEFAULT_MAX_PRS_CYC_LIM 0
95936 +
95937 +struct fman_prs_regs {
95938 + uint32_t fmpr_rpclim;
95939 + uint32_t fmpr_rpimac;
95940 + uint32_t pmeec;
95941 + uint32_t res00c[5];
95942 + uint32_t fmpr_pevr;
95943 + uint32_t fmpr_pever;
95944 + uint32_t res028;
95945 + uint32_t fmpr_perr;
95946 + uint32_t fmpr_perer;
95947 + uint32_t res034;
95948 + uint32_t res038[10];
95949 + uint32_t fmpr_ppsc;
95950 + uint32_t res064;
95951 + uint32_t fmpr_pds;
95952 + uint32_t fmpr_l2rrs;
95953 + uint32_t fmpr_l3rrs;
95954 + uint32_t fmpr_l4rrs;
95955 + uint32_t fmpr_srrs;
95956 + uint32_t fmpr_l2rres;
95957 + uint32_t fmpr_l3rres;
95958 + uint32_t fmpr_l4rres;
95959 + uint32_t fmpr_srres;
95960 + uint32_t fmpr_spcs;
95961 + uint32_t fmpr_spscs;
95962 + uint32_t fmpr_hxscs;
95963 + uint32_t fmpr_mrcs;
95964 + uint32_t fmpr_mwcs;
95965 + uint32_t fmpr_mrscs;
95966 + uint32_t fmpr_mwscs;
95967 + uint32_t fmpr_fcscs;
95968 +};
95969 +
95970 +struct fman_prs_cfg {
95971 + uint32_t port_id_stat;
95972 + uint16_t max_prs_cyc_lim;
95973 + uint32_t prs_exceptions;
95974 +};
95975 +
95976 +uint32_t fman_prs_get_err_event(struct fman_prs_regs *regs, uint32_t ev_mask);
95977 +uint32_t fman_prs_get_err_ev_mask(struct fman_prs_regs *regs);
95978 +void fman_prs_ack_err_event(struct fman_prs_regs *regs, uint32_t event);
95979 +uint32_t fman_prs_get_expt_event(struct fman_prs_regs *regs, uint32_t ev_mask);
95980 +uint32_t fman_prs_get_expt_ev_mask(struct fman_prs_regs *regs);
95981 +void fman_prs_ack_expt_event(struct fman_prs_regs *regs, uint32_t event);
95982 +void fman_prs_defconfig(struct fman_prs_cfg *cfg);
95983 +int fman_prs_init(struct fman_prs_regs *regs, struct fman_prs_cfg *cfg);
95984 +void fman_prs_enable(struct fman_prs_regs *regs);
95985 +void fman_prs_disable(struct fman_prs_regs *regs);
95986 +int fman_prs_is_enabled(struct fman_prs_regs *regs);
95987 +void fman_prs_set_stst_port_msk(struct fman_prs_regs *regs, uint32_t pid_msk);
95988 +void fman_prs_set_stst(struct fman_prs_regs *regs, bool enable);
95989 +#endif /* __FSL_FMAN_PRS_H */
95990 --- /dev/null
95991 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/flib/fsl_fman_rtc.h
95992 @@ -0,0 +1,449 @@
95993 +/*
95994 + * Copyright 2013 Freescale Semiconductor Inc.
95995 + *
95996 + * Redistribution and use in source and binary forms, with or without
95997 + * modification, are permitted provided that the following conditions are met:
95998 + * * Redistributions of source code must retain the above copyright
95999 + * notice, this list of conditions and the following disclaimer.
96000 + * * Redistributions in binary form must reproduce the above copyright
96001 + * notice, this list of conditions and the following disclaimer in the
96002 + * documentation and/or other materials provided with the distribution.
96003 + * * Neither the name of Freescale Semiconductor nor the
96004 + * names of its contributors may be used to endorse or promote products
96005 + * derived from this software without specific prior written permission.
96006 + *
96007 + *
96008 + * ALTERNATIVELY, this software may be distributed under the terms of the
96009 + * GNU General Public License ("GPL") as published by the Free Software
96010 + * Foundation, either version 2 of that License or (at your option) any
96011 + * later version.
96012 + *
96013 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
96014 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
96015 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
96016 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
96017 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
96018 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
96019 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
96020 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
96021 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
96022 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
96023 + */
96024 +
96025 +#ifndef __FSL_FMAN_RTC_H
96026 +#define __FSL_FMAN_RTC_H
96027 +
96028 +#include "common/general.h"
96029 +
96030 +/* FM RTC Registers definitions */
96031 +#define FMAN_RTC_TMR_CTRL_ALMP1 0x80000000
96032 +#define FMAN_RTC_TMR_CTRL_ALMP2 0x40000000
96033 +#define FMAN_RTC_TMR_CTRL_FS 0x10000000
96034 +#define FMAN_RTC_TMR_CTRL_PP1L 0x08000000
96035 +#define FMAN_RTC_TMR_CTRL_PP2L 0x04000000
96036 +#define FMAN_RTC_TMR_CTRL_TCLK_PERIOD_MASK 0x03FF0000
96037 +#define FMAN_RTC_TMR_CTRL_FRD 0x00004000
96038 +#define FMAN_RTC_TMR_CTRL_SLV 0x00002000
96039 +#define FMAN_RTC_TMR_CTRL_ETEP1 0x00000100
96040 +#define FMAN_RTC_TMR_CTRL_COPH 0x00000080
96041 +#define FMAN_RTC_TMR_CTRL_CIPH 0x00000040
96042 +#define FMAN_RTC_TMR_CTRL_TMSR 0x00000020
96043 +#define FMAN_RTC_TMR_CTRL_DBG 0x00000010
96044 +#define FMAN_RTC_TMR_CTRL_BYP 0x00000008
96045 +#define FMAN_RTC_TMR_CTRL_TE 0x00000004
96046 +#define FMAN_RTC_TMR_CTRL_CKSEL_OSC_CLK 0x00000003
96047 +#define FMAN_RTC_TMR_CTRL_CKSEL_MAC_CLK 0x00000001
96048 +#define FMAN_RTC_TMR_CTRL_CKSEL_EXT_CLK 0x00000000
96049 +#define FMAN_RTC_TMR_CTRL_TCLK_PERIOD_SHIFT 16
96050 +
96051 +#define FMAN_RTC_TMR_TEVENT_ETS2 0x02000000
96052 +#define FMAN_RTC_TMR_TEVENT_ETS1 0x01000000
96053 +#define FMAN_RTC_TMR_TEVENT_ALM2 0x00020000
96054 +#define FMAN_RTC_TMR_TEVENT_ALM1 0x00010000
96055 +#define FMAN_RTC_TMR_TEVENT_PP1 0x00000080
96056 +#define FMAN_RTC_TMR_TEVENT_PP2 0x00000040
96057 +#define FMAN_RTC_TMR_TEVENT_PP3 0x00000020
96058 +#define FMAN_RTC_TMR_TEVENT_ALL (FMAN_RTC_TMR_TEVENT_ETS2 |\
96059 + FMAN_RTC_TMR_TEVENT_ETS1 |\
96060 + FMAN_RTC_TMR_TEVENT_ALM2 |\
96061 + FMAN_RTC_TMR_TEVENT_ALM1 |\
96062 + FMAN_RTC_TMR_TEVENT_PP1 |\
96063 + FMAN_RTC_TMR_TEVENT_PP2 |\
96064 + FMAN_RTC_TMR_TEVENT_PP3)
96065 +
96066 +#define FMAN_RTC_TMR_PRSC_OCK_MASK 0x0000FFFF
96067 +
96068 +/**************************************************************************//**
96069 + @Description FM RTC Alarm Polarity Options.
96070 +*//***************************************************************************/
96071 +enum fman_rtc_alarm_polarity {
96072 + E_FMAN_RTC_ALARM_POLARITY_ACTIVE_HIGH, /**< Active-high output polarity */
96073 + E_FMAN_RTC_ALARM_POLARITY_ACTIVE_LOW /**< Active-low output polarity */
96074 +};
96075 +
96076 +/**************************************************************************//**
96077 + @Description FM RTC Trigger Polarity Options.
96078 +*//***************************************************************************/
96079 +enum fman_rtc_trigger_polarity {
96080 + E_FMAN_RTC_TRIGGER_ON_RISING_EDGE, /**< Trigger on rising edge */
96081 + E_FMAN_RTC_TRIGGER_ON_FALLING_EDGE /**< Trigger on falling edge */
96082 +};
96083 +
96084 +/**************************************************************************//**
96085 + @Description IEEE1588 Timer Module FM RTC Optional Clock Sources.
96086 +*//***************************************************************************/
96087 +enum fman_src_clock {
96088 + E_FMAN_RTC_SOURCE_CLOCK_EXTERNAL, /**< external high precision timer
96089 + reference clock */
96090 + E_FMAN_RTC_SOURCE_CLOCK_SYSTEM, /**< MAC system clock */
96091 + E_FMAN_RTC_SOURCE_CLOCK_OSCILATOR /**< RTC clock oscilator */
96092 +};
96093 +
96094 +/* RTC default values */
96095 +#define DEFAULT_SRC_CLOCK E_FMAN_RTC_SOURCE_CLOCK_SYSTEM
96096 +#define DEFAULT_INVERT_INPUT_CLK_PHASE FALSE
96097 +#define DEFAULT_INVERT_OUTPUT_CLK_PHASE FALSE
96098 +#define DEFAULT_ALARM_POLARITY E_FMAN_RTC_ALARM_POLARITY_ACTIVE_HIGH
96099 +#define DEFAULT_TRIGGER_POLARITY E_FMAN_RTC_TRIGGER_ON_FALLING_EDGE
96100 +#define DEFAULT_PULSE_REALIGN FALSE
96101 +
96102 +#define FMAN_RTC_MAX_NUM_OF_ALARMS 3
96103 +#define FMAN_RTC_MAX_NUM_OF_PERIODIC_PULSES 4
96104 +#define FMAN_RTC_MAX_NUM_OF_EXT_TRIGGERS 3
96105 +
96106 +/**************************************************************************//**
96107 + @Description FM RTC timer alarm
96108 +*//***************************************************************************/
96109 +struct t_tmr_alarm{
96110 + uint32_t tmr_alarm_h; /**< */
96111 + uint32_t tmr_alarm_l; /**< */
96112 +};
96113 +
96114 +/**************************************************************************//**
96115 + @Description FM RTC timer Ex trigger
96116 +*//***************************************************************************/
96117 +struct t_tmr_ext_trigger{
96118 + uint32_t tmr_etts_h; /**< */
96119 + uint32_t tmr_etts_l; /**< */
96120 +};
96121 +
96122 +struct rtc_regs {
96123 + uint32_t tmr_id; /* 0x000 Module ID register */
96124 + uint32_t tmr_id2; /* 0x004 Controller ID register */
96125 + uint32_t reserved0008[30];
96126 + uint32_t tmr_ctrl; /* 0x0080 timer control register */
96127 + uint32_t tmr_tevent; /* 0x0084 timer event register */
96128 + uint32_t tmr_temask; /* 0x0088 timer event mask register */
96129 + uint32_t reserved008c[3];
96130 + uint32_t tmr_cnt_h; /* 0x0098 timer counter high register */
96131 + uint32_t tmr_cnt_l; /* 0x009c timer counter low register */
96132 + uint32_t tmr_add; /* 0x00a0 timer drift compensation addend register */
96133 + uint32_t tmr_acc; /* 0x00a4 timer accumulator register */
96134 + uint32_t tmr_prsc; /* 0x00a8 timer prescale */
96135 + uint32_t reserved00ac;
96136 + uint32_t tmr_off_h; /* 0x00b0 timer offset high */
96137 + uint32_t tmr_off_l; /* 0x00b4 timer offset low */
96138 + struct t_tmr_alarm tmr_alarm[FMAN_RTC_MAX_NUM_OF_ALARMS]; /* 0x00b8 timer
96139 + alarm */
96140 + uint32_t tmr_fiper[FMAN_RTC_MAX_NUM_OF_PERIODIC_PULSES]; /* 0x00d0 timer
96141 + fixed period interval */
96142 + struct t_tmr_ext_trigger tmr_etts[FMAN_RTC_MAX_NUM_OF_EXT_TRIGGERS];
96143 + /* 0x00e0 time stamp general purpose external */
96144 + uint32_t reserved00f0[4];
96145 +};
96146 +
96147 +struct rtc_cfg {
96148 + enum fman_src_clock src_clk;
96149 + uint32_t ext_src_clk_freq;
96150 + uint32_t rtc_freq_hz;
96151 + bool timer_slave_mode;
96152 + bool invert_input_clk_phase;
96153 + bool invert_output_clk_phase;
96154 + uint32_t events_mask;
96155 + bool bypass; /**< Indicates if frequency compensation
96156 + is bypassed */
96157 + bool pulse_realign;
96158 + enum fman_rtc_alarm_polarity alarm_polarity[FMAN_RTC_MAX_NUM_OF_ALARMS];
96159 + enum fman_rtc_trigger_polarity trigger_polarity
96160 + [FMAN_RTC_MAX_NUM_OF_EXT_TRIGGERS];
96161 +};
96162 +
96163 +/**
96164 + * fman_rtc_defconfig() - Get default RTC configuration
96165 + * @cfg: pointer to configuration structure.
96166 + *
96167 + * Call this function to obtain a default set of configuration values for
96168 + * initializing RTC. The user can overwrite any of the values before calling
96169 + * fman_rtc_init(), if specific configuration needs to be applied.
96170 + */
96171 +void fman_rtc_defconfig(struct rtc_cfg *cfg);
96172 +
96173 +/**
96174 + * fman_rtc_get_events() - Get the events
96175 + * @regs: Pointer to RTC register block
96176 + *
96177 + * Returns: The events
96178 + */
96179 +uint32_t fman_rtc_get_events(struct rtc_regs *regs);
96180 +
96181 +/**
96182 + * fman_rtc_get_interrupt_mask() - Get the events mask
96183 + * @regs: Pointer to RTC register block
96184 + *
96185 + * Returns: The events mask
96186 + */
96187 +uint32_t fman_rtc_get_interrupt_mask(struct rtc_regs *regs);
96188 +
96189 +
96190 +/**
96191 + * fman_rtc_set_interrupt_mask() - Set the events mask
96192 + * @regs: Pointer to RTC register block
96193 + * @mask: The mask to set
96194 + */
96195 +void fman_rtc_set_interrupt_mask(struct rtc_regs *regs, uint32_t mask);
96196 +
96197 +/**
96198 + * fman_rtc_get_event() - Check if specific events occurred
96199 + * @regs: Pointer to RTC register block
96200 + * @ev_mask: a mask of the events to check
96201 + *
96202 + * Returns: 0 if the events did not occur. Non zero if one of the events occurred
96203 + */
96204 +uint32_t fman_rtc_get_event(struct rtc_regs *regs, uint32_t ev_mask);
96205 +
96206 +/**
96207 + * fman_rtc_check_and_clear_event() - Clear events which are on
96208 + * @regs: Pointer to RTC register block
96209 + *
96210 + * Returns: A mask of the events which were cleared
96211 + */
96212 +uint32_t fman_rtc_check_and_clear_event(struct rtc_regs *regs);
96213 +
96214 +/**
96215 + * fman_rtc_ack_event() - Clear events
96216 + * @regs: Pointer to RTC register block
96217 + * @events: The events to disable
96218 + */
96219 +void fman_rtc_ack_event(struct rtc_regs *regs, uint32_t events);
96220 +
96221 +/**
96222 + * fman_rtc_enable_interupt() - Enable events interrupts
96223 + * @regs: Pointer to RTC register block
96224 + * @mask: The events to disable
96225 + */
96226 +void fman_rtc_enable_interupt(struct rtc_regs *regs, uint32_t mask);
96227 +
96228 +/**
96229 + * fman_rtc_disable_interupt() - Disable events interrupts
96230 + * @regs: Pointer to RTC register block
96231 + * @mask: The events to disable
96232 + */
96233 +void fman_rtc_disable_interupt(struct rtc_regs *regs, uint32_t mask);
96234 +
96235 +/**
96236 + * fman_rtc_get_timer_ctrl() - Get the control register
96237 + * @regs: Pointer to RTC register block
96238 + *
96239 + * Returns: The control register value
96240 + */
96241 +uint32_t fman_rtc_get_timer_ctrl(struct rtc_regs *regs);
96242 +
96243 +/**
96244 + * fman_rtc_set_timer_ctrl() - Set timer control register
96245 + * @regs: Pointer to RTC register block
96246 + * @val: The value to set
96247 + */
96248 +void fman_rtc_set_timer_ctrl(struct rtc_regs *regs, uint32_t val);
96249 +
96250 +/**
96251 + * fman_rtc_get_frequency_compensation() - Get the frequency compensation
96252 + * @regs: Pointer to RTC register block
96253 + *
96254 + * Returns: The timer counter
96255 + */
96256 +uint32_t fman_rtc_get_frequency_compensation(struct rtc_regs *regs);
96257 +
96258 +/**
96259 + * fman_rtc_set_frequency_compensation() - Set frequency compensation
96260 + * @regs: Pointer to RTC register block
96261 + * @val: The value to set
96262 + */
96263 +void fman_rtc_set_frequency_compensation(struct rtc_regs *regs, uint32_t val);
96264 +
96265 +/**
96266 + * fman_rtc_get_trigger_stamp() - Get a trigger stamp
96267 + * @regs: Pointer to RTC register block
96268 + * @id: The id of the trigger stamp
96269 + *
96270 + * Returns: The time stamp
96271 + */
96272 +uint64_t fman_rtc_get_trigger_stamp(struct rtc_regs *regs, int id);
96273 +
96274 +/**
96275 + * fman_rtc_set_timer_alarm_l() - Set timer alarm low register
96276 + * @regs: Pointer to RTC register block
96277 + * @index: The index of alarm to set
96278 + * @val: The value to set
96279 + */
96280 +void fman_rtc_set_timer_alarm_l(struct rtc_regs *regs, int index,
96281 + uint32_t val);
96282 +
96283 +/**
96284 + * fman_rtc_set_timer_alarm() - Set timer alarm
96285 + * @regs: Pointer to RTC register block
96286 + * @index: The index of alarm to set
96287 + * @val: The value to set
96288 + */
96289 +void fman_rtc_set_timer_alarm(struct rtc_regs *regs, int index, int64_t val);
96290 +
96291 +/**
96292 + * fman_rtc_set_timer_fiper() - Set timer fiper
96293 + * @regs: Pointer to RTC register block
96294 + * @index: The index of fiper to set
96295 + * @val: The value to set
96296 + */
96297 +void fman_rtc_set_timer_fiper(struct rtc_regs *regs, int index, uint32_t val);
96298 +
96299 +/**
96300 + * fman_rtc_set_timer_offset() - Set timer offset
96301 + * @regs: Pointer to RTC register block
96302 + * @val: The value to set
96303 + */
96304 +void fman_rtc_set_timer_offset(struct rtc_regs *regs, int64_t val);
96305 +
96306 +/**
96307 + * fman_rtc_get_timer() - Get the timer counter
96308 + * @regs: Pointer to RTC register block
96309 + *
96310 + * Returns: The timer counter
96311 + */
96312 +static inline uint64_t fman_rtc_get_timer(struct rtc_regs *regs)
96313 +{
96314 + uint64_t time;
96315 + /* TMR_CNT_L must be read first to get an accurate value */
96316 + time = (uint64_t)ioread32be(&regs->tmr_cnt_l);
96317 + time |= ((uint64_t)ioread32be(&regs->tmr_cnt_h) << 32);
96318 +
96319 + return time;
96320 +}
96321 +
96322 +/**
96323 + * fman_rtc_set_timer() - Set timer counter
96324 + * @regs: Pointer to RTC register block
96325 + * @val: The value to set
96326 + */
96327 +static inline void fman_rtc_set_timer(struct rtc_regs *regs, int64_t val)
96328 +{
96329 + iowrite32be((uint32_t)val, &regs->tmr_cnt_l);
96330 + iowrite32be((uint32_t)(val >> 32), &regs->tmr_cnt_h);
96331 +}
96332 +
96333 +/**
96334 + * fman_rtc_timers_soft_reset() - Soft reset
96335 + * @regs: Pointer to RTC register block
96336 + *
96337 + * Resets all the timer registers and state machines for the 1588 IP and
96338 + * the attached client 1588
96339 + */
96340 +void fman_rtc_timers_soft_reset(struct rtc_regs *regs);
96341 +
96342 +/**
96343 + * fman_rtc_clear_external_trigger() - Clear an external trigger
96344 + * @regs: Pointer to RTC register block
96345 + * @id: The id of the trigger to clear
96346 + */
96347 +void fman_rtc_clear_external_trigger(struct rtc_regs *regs, int id);
96348 +
96349 +/**
96350 + * fman_rtc_clear_periodic_pulse() - Clear periodic pulse
96351 + * @regs: Pointer to RTC register block
96352 + * @id: The id of the fiper to clear
96353 + */
96354 +void fman_rtc_clear_periodic_pulse(struct rtc_regs *regs, int id);
96355 +
96356 +/**
96357 + * fman_rtc_enable() - Enable RTC hardware block
96358 + * @regs: Pointer to RTC register block
96359 + */
96360 +void fman_rtc_enable(struct rtc_regs *regs, bool reset_clock);
96361 +
96362 +/**
96363 + * fman_rtc_is_enabled() - Is RTC hardware block enabled
96364 + * @regs: Pointer to RTC register block
96365 + *
96366 + * Return: TRUE if enabled
96367 + */
96368 +bool fman_rtc_is_enabled(struct rtc_regs *regs);
96369 +
96370 +/**
96371 + * fman_rtc_disable() - Disable RTC hardware block
96372 + * @regs: Pointer to RTC register block
96373 + */
96374 +void fman_rtc_disable(struct rtc_regs *regs);
96375 +
96376 +/**
96377 + * fman_rtc_init() - Init RTC hardware block
96378 + * @cfg: RTC configuration data
96379 + * @regs: Pointer to RTC register block
96380 + * @num_alarms: Number of alarms in RTC
96381 + * @num_fipers: Number of fipers in RTC
96382 + * @num_ext_triggers: Number of external triggers in RTC
96383 + * @freq_compensation: Frequency compensation
96384 + * @output_clock_divisor: Output clock divisor
96385 + *
96386 + * This function initializes RTC and applies basic configuration.
96387 + */
96388 +void fman_rtc_init(struct rtc_cfg *cfg, struct rtc_regs *regs, int num_alarms,
96389 + int num_fipers, int num_ext_triggers, bool init_freq_comp,
96390 + uint32_t freq_compensation, uint32_t output_clock_divisor);
96391 +
96392 +/**
96393 + * fman_rtc_set_alarm() - Set an alarm
96394 + * @regs: Pointer to RTC register block
96395 + * @id: id of alarm
96396 + * @val: value to write
96397 + * @enable: should interrupt be enabled
96398 + */
96399 +void fman_rtc_set_alarm(struct rtc_regs *regs, int id, uint32_t val, bool enable);
96400 +
96401 +/**
96402 + * fman_rtc_set_periodic_pulse() - Set an alarm
96403 + * @regs: Pointer to RTC register block
96404 + * @id: id of fiper
96405 + * @val: value to write
96406 + * @enable: should interrupt be enabled
96407 + */
96408 +void fman_rtc_set_periodic_pulse(struct rtc_regs *regs, int id, uint32_t val,
96409 + bool enable);
96410 +
96411 +/**
96412 + * fman_rtc_set_ext_trigger() - Set an external trigger
96413 + * @regs: Pointer to RTC register block
96414 + * @id: id of trigger
96415 + * @enable: should interrupt be enabled
96416 + * @use_pulse_as_input: use the pulse as input
96417 + */
96418 +void fman_rtc_set_ext_trigger(struct rtc_regs *regs, int id, bool enable,
96419 + bool use_pulse_as_input);
96420 +
96421 +struct fm_rtc_alarm_params {
96422 + uint8_t alarm_id; /**< 0 or 1 */
96423 + uint64_t alarm_time; /**< In nanoseconds, the time when the
96424 + alarm should go off - must be a
96425 + multiple of the RTC period */
96426 + void (*f_alarm_callback)(void* app, uint8_t id); /**< This routine will
96427 + be called when RTC reaches alarmTime */
96428 + bool clear_on_expiration; /**< TRUE to turn off the alarm once
96429 + expired.*/
96430 +};
96431 +
96432 +struct fm_rtc_periodic_pulse_params {
96433 + uint8_t periodic_pulse_id; /**< 0 or 1 */
96434 + uint64_t periodic_pulse_period; /**< In Nanoseconds. Must be a multiple
96435 + of the RTC period */
96436 + void (*f_periodic_pulse_callback)(void* app, uint8_t id); /**< This
96437 + routine will be called every
96438 + periodicPulsePeriod. */
96439 +};
96440 +
96441 +#endif /* __FSL_FMAN_RTC_H */
96442 --- /dev/null
96443 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/flib/fsl_fman_sp.h
96444 @@ -0,0 +1,138 @@
96445 +/*
96446 + * Copyright 2013 Freescale Semiconductor Inc.
96447 + *
96448 + * Redistribution and use in source and binary forms, with or without
96449 + * modification, are permitted provided that the following conditions are met:
96450 + * * Redistributions of source code must retain the above copyright
96451 + * notice, this list of conditions and the following disclaimer.
96452 + * * Redistributions in binary form must reproduce the above copyright
96453 + * notice, this list of conditions and the following disclaimer in the
96454 + * documentation and/or other materials provided with the distribution.
96455 + * * Neither the name of Freescale Semiconductor nor the
96456 + * names of its contributors may be used to endorse or promote products
96457 + * derived from this software without specific prior written permission.
96458 + *
96459 + *
96460 + * ALTERNATIVELY, this software may be distributed under the terms of the
96461 + * GNU General Public License ("GPL") as published by the Free Software
96462 + * Foundation, either version 2 of that License or (at your option) any
96463 + * later version.
96464 + *
96465 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
96466 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
96467 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
96468 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
96469 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
96470 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
96471 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
96472 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
96473 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
96474 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
96475 + */
96476 +
96477 +#ifndef __FSL_FMAN_SP_H
96478 +#define __FSL_FMAN_SP_H
96479 +
96480 +#include "common/general.h"
96481 +#include "fsl_fman.h"
96482 +
96483 +
96484 +struct fm_pcd_storage_profile_regs{
96485 + uint32_t fm_sp_ebmpi[8];
96486 + /*offset 0 - 0xc*/
96487 + /**< Buffer Manager pool Information */
96488 +
96489 + uint32_t fm_sp_acnt; /*offset 0x20*/
96490 + uint32_t fm_sp_ebm; /*offset 0x24*/
96491 + uint32_t fm_sp_da; /*offset 0x28*/
96492 + uint32_t fm_sp_icp; /*offset 0x2c*/
96493 + uint32_t fm_sp_mpd; /*offset 0x30*/
96494 + uint32_t res1[2]; /*offset 0x34 - 0x38*/
96495 + uint32_t fm_sp_spliodn; /*offset 0x3c*/
96496 +};
96497 +
96498 +/**************************************************************************//**
96499 + @Description structure for defining internal context copying
96500 +*//***************************************************************************/
96501 +struct fman_sp_int_context_data_copy{
96502 + uint16_t ext_buf_offset; /**< Offset in External buffer to which
96503 + internal context is copied to (Rx)
96504 + or taken from (Tx, Op). */
96505 + uint8_t int_context_offset; /**< Offset within internal context to copy
96506 + from (Rx) or to copy to (Tx, Op).*/
96507 + uint16_t size; /**< Internal offset size to be copied */
96508 +};
96509 +
96510 +/**************************************************************************//**
96511 + @Description struct for defining external buffer margins
96512 +*//***************************************************************************/
96513 +struct fman_sp_buf_margins{
96514 + uint16_t start_margins; /**< Number of bytes to be left at the
96515 + beginning of the external buffer (must be
96516 + divisible by 16) */
96517 + uint16_t end_margins; /**< number of bytes to be left at the end of
96518 + the external buffer(must be divisible by 16)*/
96519 +};
96520 +
96521 +struct fm_storage_profile_params {
96522 + struct fman_ext_pools fm_ext_pools;
96523 + struct fman_backup_bm_pools backup_pools;
96524 + struct fman_sp_int_context_data_copy *int_context;
96525 + struct fman_sp_buf_margins *buf_margins;
96526 + enum fman_dma_swap_option dma_swap_data;
96527 + enum fman_dma_cache_option int_context_cache_attr;
96528 + enum fman_dma_cache_option header_cache_attr;
96529 + enum fman_dma_cache_option scatter_gather_cache_attr;
96530 + bool dma_write_optimize;
96531 + uint16_t liodn_offset;
96532 + bool no_scather_gather;
96533 + struct fman_buf_pool_depletion buf_pool_depletion;
96534 +};
96535 +
96536 +/**************************************************************************//**
96537 + @Description Registers bit fields
96538 +*//***************************************************************************/
96539 +#define FMAN_SP_EXT_BUF_POOL_EN_COUNTER 0x40000000
96540 +#define FMAN_SP_EXT_BUF_POOL_VALID 0x80000000
96541 +#define FMAN_SP_EXT_BUF_POOL_BACKUP 0x20000000
96542 +#define FMAN_SP_DMA_ATTR_WRITE_OPTIMIZE 0x00100000
96543 +#define FMAN_SP_SG_DISABLE 0x80000000
96544 +
96545 +/* shifts */
96546 +#define FMAN_SP_EXT_BUF_POOL_ID_SHIFT 16
96547 +#define FMAN_SP_POOL_DEP_NUM_OF_POOLS_SHIFT 16
96548 +#define FMAN_SP_EXT_BUF_MARG_START_SHIFT 16
96549 +#define FMAN_SP_EXT_BUF_MARG_END_SHIFT 0
96550 +#define FMAN_SP_DMA_ATTR_SWP_SHIFT 30
96551 +#define FMAN_SP_DMA_ATTR_IC_CACHE_SHIFT 28
96552 +#define FMAN_SP_DMA_ATTR_HDR_CACHE_SHIFT 26
96553 +#define FMAN_SP_DMA_ATTR_SG_CACHE_SHIFT 24
96554 +#define FMAN_SP_IC_TO_EXT_SHIFT 16
96555 +#define FMAN_SP_IC_FROM_INT_SHIFT 8
96556 +#define FMAN_SP_IC_SIZE_SHIFT 0
96557 +
96558 +/**************************************************************************//**
96559 + @Description defaults
96560 +*//***************************************************************************/
96561 +#define DEFAULT_FMAN_SP_DMA_SWAP_DATA FMAN_DMA_NO_SWP
96562 +#define DEFAULT_FMAN_SP_DMA_INT_CONTEXT_CACHE_ATTR FMAN_DMA_NO_STASH
96563 +#define DEFAULT_FMAN_SP_DMA_HEADER_CACHE_ATTR FMAN_DMA_NO_STASH
96564 +#define DEFAULT_FMAN_SP_DMA_SCATTER_GATHER_CACHE_ATTR FMAN_DMA_NO_STASH
96565 +#define DEFAULT_FMAN_SP_DMA_WRITE_OPTIMIZE TRUE
96566 +#define DEFAULT_FMAN_SP_NO_SCATTER_GATHER FALSE
96567 +
96568 +void fman_vsp_defconfig(struct fm_storage_profile_params *cfg);
96569 +
96570 +void fman_vsp_init(struct fm_pcd_storage_profile_regs *regs,
96571 + uint16_t index, struct fm_storage_profile_params *fm_vsp_params,
96572 + int port_max_num_of_ext_pools, int bm_max_num_of_pools,
96573 + int max_num_of_pfc_priorities);
96574 +
96575 +uint32_t fman_vsp_get_statistics(struct fm_pcd_storage_profile_regs *regs,
96576 + uint16_t index);
96577 +
96578 +void fman_vsp_set_statistics(struct fm_pcd_storage_profile_regs *regs,
96579 + uint16_t index, uint32_t value);
96580 +
96581 +
96582 +#endif /* __FSL_FMAN_SP_H */
96583 --- /dev/null
96584 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/flib/fsl_fman_tgec.h
96585 @@ -0,0 +1,479 @@
96586 +/*
96587 + * Copyright 2008-2012 Freescale Semiconductor Inc.
96588 + *
96589 + * Redistribution and use in source and binary forms, with or without
96590 + * modification, are permitted provided that the following conditions are met:
96591 + * * Redistributions of source code must retain the above copyright
96592 + * notice, this list of conditions and the following disclaimer.
96593 + * * Redistributions in binary form must reproduce the above copyright
96594 + * notice, this list of conditions and the following disclaimer in the
96595 + * documentation and/or other materials provided with the distribution.
96596 + * * Neither the name of Freescale Semiconductor nor the
96597 + * names of its contributors may be used to endorse or promote products
96598 + * derived from this software without specific prior written permission.
96599 + *
96600 + *
96601 + * ALTERNATIVELY, this software may be distributed under the terms of the
96602 + * GNU General Public License ("GPL") as published by the Free Software
96603 + * Foundation, either version 2 of that License or (at your option) any
96604 + * later version.
96605 + *
96606 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
96607 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
96608 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
96609 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
96610 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
96611 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
96612 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
96613 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
96614 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
96615 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
96616 + */
96617 +
96618 +#ifndef __FSL_FMAN_TGEC_H
96619 +#define __FSL_FMAN_TGEC_H
96620 +
96621 +#include "common/general.h"
96622 +#include "fsl_enet.h"
96623 +
96624 +
96625 +/* Transmit Inter-Packet Gap Length Register (TX_IPG_LENGTH) */
96626 +#define TGEC_TX_IPG_LENGTH_MASK 0x000003ff
96627 +
96628 +enum tgec_counters {
96629 + E_TGEC_COUNTER_R64,
96630 + E_TGEC_COUNTER_R127,
96631 + E_TGEC_COUNTER_R255,
96632 + E_TGEC_COUNTER_R511,
96633 + E_TGEC_COUNTER_R1023,
96634 + E_TGEC_COUNTER_R1518,
96635 + E_TGEC_COUNTER_R1519X,
96636 + E_TGEC_COUNTER_TRFRG,
96637 + E_TGEC_COUNTER_TRJBR,
96638 + E_TGEC_COUNTER_RDRP,
96639 + E_TGEC_COUNTER_RALN,
96640 + E_TGEC_COUNTER_TRUND,
96641 + E_TGEC_COUNTER_TROVR,
96642 + E_TGEC_COUNTER_RXPF,
96643 + E_TGEC_COUNTER_TXPF,
96644 + E_TGEC_COUNTER_ROCT,
96645 + E_TGEC_COUNTER_RMCA,
96646 + E_TGEC_COUNTER_RBCA,
96647 + E_TGEC_COUNTER_RPKT,
96648 + E_TGEC_COUNTER_RUCA,
96649 + E_TGEC_COUNTER_RERR,
96650 + E_TGEC_COUNTER_TOCT,
96651 + E_TGEC_COUNTER_TMCA,
96652 + E_TGEC_COUNTER_TBCA,
96653 + E_TGEC_COUNTER_TUCA,
96654 + E_TGEC_COUNTER_TERR
96655 +};
96656 +
96657 +/* Command and Configuration Register (COMMAND_CONFIG) */
96658 +#define CMD_CFG_EN_TIMESTAMP 0x00100000
96659 +#define CMD_CFG_TX_ADDR_INS_SEL 0x00080000
96660 +#define CMD_CFG_NO_LEN_CHK 0x00020000
96661 +#define CMD_CFG_SEND_IDLE 0x00010000
96662 +#define CMD_CFG_RX_ER_DISC 0x00004000
96663 +#define CMD_CFG_CMD_FRM_EN 0x00002000
96664 +#define CMD_CFG_STAT_CLR 0x00001000
96665 +#define CMD_CFG_LOOPBACK_EN 0x00000400
96666 +#define CMD_CFG_TX_ADDR_INS 0x00000200
96667 +#define CMD_CFG_PAUSE_IGNORE 0x00000100
96668 +#define CMD_CFG_PAUSE_FWD 0x00000080
96669 +#define CMD_CFG_PROMIS_EN 0x00000010
96670 +#define CMD_CFG_WAN_MODE 0x00000008
96671 +#define CMD_CFG_RX_EN 0x00000002
96672 +#define CMD_CFG_TX_EN 0x00000001
96673 +
96674 +/* Interrupt Mask Register (IMASK) */
96675 +#define TGEC_IMASK_MDIO_SCAN_EVENT 0x00010000
96676 +#define TGEC_IMASK_MDIO_CMD_CMPL 0x00008000
96677 +#define TGEC_IMASK_REM_FAULT 0x00004000
96678 +#define TGEC_IMASK_LOC_FAULT 0x00002000
96679 +#define TGEC_IMASK_TX_ECC_ER 0x00001000
96680 +#define TGEC_IMASK_TX_FIFO_UNFL 0x00000800
96681 +#define TGEC_IMASK_TX_FIFO_OVFL 0x00000400
96682 +#define TGEC_IMASK_TX_ER 0x00000200
96683 +#define TGEC_IMASK_RX_FIFO_OVFL 0x00000100
96684 +#define TGEC_IMASK_RX_ECC_ER 0x00000080
96685 +#define TGEC_IMASK_RX_JAB_FRM 0x00000040
96686 +#define TGEC_IMASK_RX_OVRSZ_FRM 0x00000020
96687 +#define TGEC_IMASK_RX_RUNT_FRM 0x00000010
96688 +#define TGEC_IMASK_RX_FRAG_FRM 0x00000008
96689 +#define TGEC_IMASK_RX_LEN_ER 0x00000004
96690 +#define TGEC_IMASK_RX_CRC_ER 0x00000002
96691 +#define TGEC_IMASK_RX_ALIGN_ER 0x00000001
96692 +
96693 +#define TGEC_EVENTS_MASK \
96694 + ((uint32_t)(TGEC_IMASK_MDIO_SCAN_EVENT | \
96695 + TGEC_IMASK_MDIO_CMD_CMPL | \
96696 + TGEC_IMASK_REM_FAULT | \
96697 + TGEC_IMASK_LOC_FAULT | \
96698 + TGEC_IMASK_TX_ECC_ER | \
96699 + TGEC_IMASK_TX_FIFO_UNFL | \
96700 + TGEC_IMASK_TX_FIFO_OVFL | \
96701 + TGEC_IMASK_TX_ER | \
96702 + TGEC_IMASK_RX_FIFO_OVFL | \
96703 + TGEC_IMASK_RX_ECC_ER | \
96704 + TGEC_IMASK_RX_JAB_FRM | \
96705 + TGEC_IMASK_RX_OVRSZ_FRM | \
96706 + TGEC_IMASK_RX_RUNT_FRM | \
96707 + TGEC_IMASK_RX_FRAG_FRM | \
96708 + TGEC_IMASK_RX_LEN_ER | \
96709 + TGEC_IMASK_RX_CRC_ER | \
96710 + TGEC_IMASK_RX_ALIGN_ER))
96711 +
96712 +/* Hashtable Control Register (HASHTABLE_CTRL) */
96713 +#define TGEC_HASH_MCAST_SHIFT 23
96714 +#define TGEC_HASH_MCAST_EN 0x00000200
96715 +#define TGEC_HASH_ADR_MSK 0x000001ff
96716 +
96717 +#define DEFAULT_WAN_MODE_ENABLE FALSE
96718 +#define DEFAULT_PROMISCUOUS_MODE_ENABLE FALSE
96719 +#define DEFAULT_PAUSE_FORWARD_ENABLE FALSE
96720 +#define DEFAULT_PAUSE_IGNORE FALSE
96721 +#define DEFAULT_TX_ADDR_INS_ENABLE FALSE
96722 +#define DEFAULT_LOOPBACK_ENABLE FALSE
96723 +#define DEFAULT_CMD_FRAME_ENABLE FALSE
96724 +#define DEFAULT_RX_ERROR_DISCARD FALSE
96725 +#define DEFAULT_SEND_IDLE_ENABLE FALSE
96726 +#define DEFAULT_NO_LENGTH_CHECK_ENABLE TRUE
96727 +#define DEFAULT_LGTH_CHECK_NOSTDR FALSE
96728 +#define DEFAULT_TIME_STAMP_ENABLE FALSE
96729 +#define DEFAULT_TX_IPG_LENGTH 12
96730 +#define DEFAULT_MAX_FRAME_LENGTH 0x600
96731 +#define DEFAULT_PAUSE_QUANT 0xf000
96732 +
96733 +/*
96734 + * 10G memory map
96735 + */
96736 +struct tgec_regs {
96737 + uint32_t tgec_id; /* 0x000 Controller ID */
96738 + uint32_t reserved001[1]; /* 0x004 */
96739 + uint32_t command_config; /* 0x008 Control and configuration */
96740 + uint32_t mac_addr_0; /* 0x00c Lower 32 bits of the MAC adr */
96741 + uint32_t mac_addr_1; /* 0x010 Upper 16 bits of the MAC adr */
96742 + uint32_t maxfrm; /* 0x014 Maximum frame length */
96743 + uint32_t pause_quant; /* 0x018 Pause quanta */
96744 + uint32_t rx_fifo_sections; /* 0x01c */
96745 + uint32_t tx_fifo_sections; /* 0x020 */
96746 + uint32_t rx_fifo_almost_f_e; /* 0x024 */
96747 + uint32_t tx_fifo_almost_f_e; /* 0x028 */
96748 + uint32_t hashtable_ctrl; /* 0x02c Hash table control*/
96749 + uint32_t mdio_cfg_status; /* 0x030 */
96750 + uint32_t mdio_command; /* 0x034 */
96751 + uint32_t mdio_data; /* 0x038 */
96752 + uint32_t mdio_regaddr; /* 0x03c */
96753 + uint32_t status; /* 0x040 */
96754 + uint32_t tx_ipg_len; /* 0x044 Transmitter inter-packet-gap */
96755 + uint32_t mac_addr_2; /* 0x048 Lower 32 bits of 2nd MAC adr */
96756 + uint32_t mac_addr_3; /* 0x04c Upper 16 bits of 2nd MAC adr */
96757 + uint32_t rx_fifo_ptr_rd; /* 0x050 */
96758 + uint32_t rx_fifo_ptr_wr; /* 0x054 */
96759 + uint32_t tx_fifo_ptr_rd; /* 0x058 */
96760 + uint32_t tx_fifo_ptr_wr; /* 0x05c */
96761 + uint32_t imask; /* 0x060 Interrupt mask */
96762 + uint32_t ievent; /* 0x064 Interrupt event */
96763 + uint32_t udp_port; /* 0x068 Defines a UDP Port number */
96764 + uint32_t type_1588v2; /* 0x06c Type field for 1588v2 */
96765 + uint32_t reserved070[4]; /* 0x070 */
96766 + /*10Ge Statistics Counter */
96767 + uint32_t tfrm_u; /* 80 aFramesTransmittedOK */
96768 + uint32_t tfrm_l; /* 84 aFramesTransmittedOK */
96769 + uint32_t rfrm_u; /* 88 aFramesReceivedOK */
96770 + uint32_t rfrm_l; /* 8c aFramesReceivedOK */
96771 + uint32_t rfcs_u; /* 90 aFrameCheckSequenceErrors */
96772 + uint32_t rfcs_l; /* 94 aFrameCheckSequenceErrors */
96773 + uint32_t raln_u; /* 98 aAlignmentErrors */
96774 + uint32_t raln_l; /* 9c aAlignmentErrors */
96775 + uint32_t txpf_u; /* A0 aPAUSEMACCtrlFramesTransmitted */
96776 + uint32_t txpf_l; /* A4 aPAUSEMACCtrlFramesTransmitted */
96777 + uint32_t rxpf_u; /* A8 aPAUSEMACCtrlFramesReceived */
96778 + uint32_t rxpf_l; /* Ac aPAUSEMACCtrlFramesReceived */
96779 + uint32_t rlong_u; /* B0 aFrameTooLongErrors */
96780 + uint32_t rlong_l; /* B4 aFrameTooLongErrors */
96781 + uint32_t rflr_u; /* B8 aInRangeLengthErrors */
96782 + uint32_t rflr_l; /* Bc aInRangeLengthErrors */
96783 + uint32_t tvlan_u; /* C0 VLANTransmittedOK */
96784 + uint32_t tvlan_l; /* C4 VLANTransmittedOK */
96785 + uint32_t rvlan_u; /* C8 VLANReceivedOK */
96786 + uint32_t rvlan_l; /* Cc VLANReceivedOK */
96787 + uint32_t toct_u; /* D0 ifOutOctets */
96788 + uint32_t toct_l; /* D4 ifOutOctets */
96789 + uint32_t roct_u; /* D8 ifInOctets */
96790 + uint32_t roct_l; /* Dc ifInOctets */
96791 + uint32_t ruca_u; /* E0 ifInUcastPkts */
96792 + uint32_t ruca_l; /* E4 ifInUcastPkts */
96793 + uint32_t rmca_u; /* E8 ifInMulticastPkts */
96794 + uint32_t rmca_l; /* Ec ifInMulticastPkts */
96795 + uint32_t rbca_u; /* F0 ifInBroadcastPkts */
96796 + uint32_t rbca_l; /* F4 ifInBroadcastPkts */
96797 + uint32_t terr_u; /* F8 ifOutErrors */
96798 + uint32_t terr_l; /* Fc ifOutErrors */
96799 + uint32_t reserved100[2]; /* 100-108*/
96800 + uint32_t tuca_u; /* 108 ifOutUcastPkts */
96801 + uint32_t tuca_l; /* 10c ifOutUcastPkts */
96802 + uint32_t tmca_u; /* 110 ifOutMulticastPkts */
96803 + uint32_t tmca_l; /* 114 ifOutMulticastPkts */
96804 + uint32_t tbca_u; /* 118 ifOutBroadcastPkts */
96805 + uint32_t tbca_l; /* 11c ifOutBroadcastPkts */
96806 + uint32_t rdrp_u; /* 120 etherStatsDropEvents */
96807 + uint32_t rdrp_l; /* 124 etherStatsDropEvents */
96808 + uint32_t reoct_u; /* 128 etherStatsOctets */
96809 + uint32_t reoct_l; /* 12c etherStatsOctets */
96810 + uint32_t rpkt_u; /* 130 etherStatsPkts */
96811 + uint32_t rpkt_l; /* 134 etherStatsPkts */
96812 + uint32_t trund_u; /* 138 etherStatsUndersizePkts */
96813 + uint32_t trund_l; /* 13c etherStatsUndersizePkts */
96814 + uint32_t r64_u; /* 140 etherStatsPkts64Octets */
96815 + uint32_t r64_l; /* 144 etherStatsPkts64Octets */
96816 + uint32_t r127_u; /* 148 etherStatsPkts65to127Octets */
96817 + uint32_t r127_l; /* 14c etherStatsPkts65to127Octets */
96818 + uint32_t r255_u; /* 150 etherStatsPkts128to255Octets */
96819 + uint32_t r255_l; /* 154 etherStatsPkts128to255Octets */
96820 + uint32_t r511_u; /* 158 etherStatsPkts256to511Octets */
96821 + uint32_t r511_l; /* 15c etherStatsPkts256to511Octets */
96822 + uint32_t r1023_u; /* 160 etherStatsPkts512to1023Octets */
96823 + uint32_t r1023_l; /* 164 etherStatsPkts512to1023Octets */
96824 + uint32_t r1518_u; /* 168 etherStatsPkts1024to1518Octets */
96825 + uint32_t r1518_l; /* 16c etherStatsPkts1024to1518Octets */
96826 + uint32_t r1519x_u; /* 170 etherStatsPkts1519toX */
96827 + uint32_t r1519x_l; /* 174 etherStatsPkts1519toX */
96828 + uint32_t trovr_u; /* 178 etherStatsOversizePkts */
96829 + uint32_t trovr_l; /* 17c etherStatsOversizePkts */
96830 + uint32_t trjbr_u; /* 180 etherStatsJabbers */
96831 + uint32_t trjbr_l; /* 184 etherStatsJabbers */
96832 + uint32_t trfrg_u; /* 188 etherStatsFragments */
96833 + uint32_t trfrg_l; /* 18C etherStatsFragments */
96834 + uint32_t rerr_u; /* 190 ifInErrors */
96835 + uint32_t rerr_l; /* 194 ifInErrors */
96836 +};
96837 +
96838 +/**
96839 + * struct tgec_cfg - TGEC configuration
96840 + *
96841 + * @rx_error_discard: Receive Erroneous Frame Discard Enable. When set to 1
96842 + * any frame received with an error is discarded in the
96843 + * Core and not forwarded to the Client interface.
96844 + * When set to 0 (Reset value), erroneous Frames are
96845 + * forwarded to the Client interface with ff_rx_err
96846 + * asserted.
96847 + * @pause_ignore: Ignore Pause Frame Quanta. If set to 1 received pause
96848 + * frames are ignored by the MAC. When set to 0
96849 + * (Reset value) the transmit process is stopped for the
96850 + * amount of time specified in the pause quanta received
96851 + * within a pause frame.
96852 + * @pause_forward_enable:
96853 + * Terminate / Forward Pause Frames. If set to 1 pause
96854 + * frames are forwarded to the user application. When set
96855 + * to 0 (Reset value) pause frames are terminated and
96856 + * discarded within the MAC.
96857 + * @no_length_check_enable:
96858 + * Payload Length Check Disable. When set to 0
96859 + * (Reset value), the Core checks the frame's payload
96860 + * length with the Frame Length/Type field, when set to 1
96861 + * the payload length check is disabled.
96862 + * @cmd_frame_enable: Enables reception of all command frames. When set to 1
96863 + * all Command Frames are accepted, when set to 0
96864 + * (Reset Value) only Pause Frames are accepted and all
96865 + * other Command Frames are rejected.
96866 + * @send_idle_enable: Force Idle Generation. When set to 1, the MAC
96867 + * permanently sends XGMII Idle sequences even when faults
96868 + * are received.
96869 + * @wan_mode_enable: WAN Mode Enable. Sets WAN mode (1) or LAN mode
96870 + * (0, default) of operation.
96871 + * @promiscuous_mode_enable:
96872 + * Enables MAC promiscuous operation. When set to 1, all
96873 + * frames are received without any MAC address filtering,
96874 + * when set to 0 (Reset value) Unicast Frames with a
96875 + * destination address not matching the Core MAC Address
96876 + * (MAC Address programmed in Registers MAC_ADDR_0 and
96877 + * MAC_ADDR_1 or the MAC address programmed in Registers
96878 + * MAC_ADDR_2 and MAC_ADDR_3) are rejected.
96879 + * @tx_addr_ins_enable: Set Source MAC Address on Transmit. If set to 1 the
96880 + * MAC overwrites the source MAC address received from the
96881 + * Client Interface with one of the MAC addresses. If set
96882 + * to 0 (Reset value), the source MAC address from the
96883 + * Client Interface is transmitted unmodified to the line.
96884 + * @loopback_enable: PHY Interface Loopback. When set to 1, the signal
96885 + * loop_ena is set to '1', when set to 0 (Reset value)
96886 + * the signal loop_ena is set to 0.
96887 + * @lgth_check_nostdr: The Core interprets the Length/Type field differently
96888 + * depending on the value of this Bit
96889 + * @time_stamp_enable: This bit selects between enabling and disabling the
96890 + * IEEE 1588 functionality. 1: IEEE 1588 is enabled
96891 + * 0: IEEE 1588 is disabled
96892 + * @max_frame_length: Maximum supported received frame length.
96893 + * The 10GEC MAC supports reception of any frame size up
96894 + * to 16,352 bytes (0x3FE0). Typical settings are
96895 + * 0x05EE (1,518 bytes) for standard frames.
96896 + * Default setting is 0x0600 (1,536 bytes).
96897 + * Received frames that exceed this stated maximum
96898 + * are truncated.
96899 + * @pause_quant: Pause quanta value used with transmitted pause frames.
96900 + * Each quanta represents a 512 bit-times.
96901 + * @tx_ipg_length: Transmit Inter-Packet-Gap (IPG) value. A 6-bit value:
96902 + * Depending on LAN or WAN mode of operation the value has
96903 + * the following meaning: - LAN Mode: Number of octets in
96904 + * steps of 4. Valid values are 8, 12, 16, ... 100. DIC is
96905 + * fully supported (see 10.6.1 page 49) for any setting. A
96906 + * default of 12 (reset value) must be set to conform to
96907 + * IEEE802.3ae. Warning: When set to 8, PCS layers may not
96908 + * be able to perform clock rate compensation. - WAN Mode:
96909 + * Stretch factor. Valid values are 4..15. The stretch
96910 + * factor is calculated as (value+1)*8. A default of 12
96911 + * (reset value) must be set to conform to IEEE 802.3ae
96912 + * (i.e. 13*8=104). A larger value shrinks the IPG
96913 + * (increasing bandwidth).
96914 + *
96915 + * This structure contains basic TGEC configuration and must be passed to
96916 + * fman_tgec_init() function. A default set of configuration values can be
96917 + * obtained by calling fman_tgec_defconfig().
96918 + */
96919 +struct tgec_cfg {
96920 + bool rx_error_discard;
96921 + bool pause_ignore;
96922 + bool pause_forward_enable;
96923 + bool no_length_check_enable;
96924 + bool cmd_frame_enable;
96925 + bool send_idle_enable;
96926 + bool wan_mode_enable;
96927 + bool promiscuous_mode_enable;
96928 + bool tx_addr_ins_enable;
96929 + bool loopback_enable;
96930 + bool lgth_check_nostdr;
96931 + bool time_stamp_enable;
96932 + uint16_t max_frame_length;
96933 + uint16_t pause_quant;
96934 + uint32_t tx_ipg_length;
96935 + bool skip_fman11_workaround;
96936 +};
96937 +
96938 +
96939 +void fman_tgec_defconfig(struct tgec_cfg *cfg);
96940 +
96941 +/**
96942 + * fman_tgec_init() - Init tgec hardware block
96943 + * @regs: Pointer to tgec register block
96944 + * @cfg: tgec configuration data
96945 + * @exceptions_mask: initial exceptions mask
96946 + *
96947 + * This function initializes the tgec controller and applies its
96948 + * basic configuration.
96949 + *
96950 + * Returns: 0 if successful, an error code otherwise.
96951 + */
96952 +
96953 +int fman_tgec_init(struct tgec_regs *regs, struct tgec_cfg *cfg,
96954 + uint32_t exception_mask);
96955 +
96956 +void fman_tgec_enable(struct tgec_regs *regs, bool apply_rx, bool apply_tx);
96957 +
96958 +void fman_tgec_disable(struct tgec_regs *regs, bool apply_rx, bool apply_tx);
96959 +
96960 +uint32_t fman_tgec_get_revision(struct tgec_regs *regs);
96961 +
96962 +void fman_tgec_set_mac_address(struct tgec_regs *regs, uint8_t *macaddr);
96963 +
96964 +void fman_tgec_set_promiscuous(struct tgec_regs *regs, bool val);
96965 +
96966 +/**
96967 + * fman_tgec_reset_stat() - Completely resets all TGEC HW counters
96968 + * @regs: Pointer to TGEC register block
96969 + */
96970 +void fman_tgec_reset_stat(struct tgec_regs *regs);
96971 +
96972 +/**
96973 + * fman_tgec_get_counter() - Reads TGEC HW counters
96974 + * @regs: Pointer to TGEC register block
96975 + * @reg_name: Counter name according to the appropriate enum
96976 + *
96977 + * Returns: Required counter value
96978 + */
96979 +uint64_t fman_tgec_get_counter(struct tgec_regs *regs,
96980 + enum tgec_counters reg_name);
96981 +
96982 +/**
96983 + * fman_tgec_set_hash_table() - Sets the Hashtable Control Register
96984 + * @regs: Pointer to TGEC register block
96985 + * @value: Value to be written in Hashtable Control Register
96986 + */
96987 +void fman_tgec_set_hash_table(struct tgec_regs *regs, uint32_t value);
96988 +
96989 +/**
96990 + * fman_tgec_set_tx_pause_frames() - Sets the Pause Quanta Register
96991 + * @regs: Pointer to TGEC register block
96992 + * @pause_time: Pause quanta value used with transmitted pause frames.
96993 + * Each quanta represents a 512 bit-times
96994 + */
96995 +void fman_tgec_set_tx_pause_frames(struct tgec_regs *regs, uint16_t pause_time);
96996 +
96997 +/**
96998 + * fman_tgec_set_rx_ignore_pause_frames() - Changes the policy WRT pause frames
96999 + * @regs: Pointer to TGEC register block
97000 + * @en: Ignore/Respond to pause frame quanta
97001 + *
97002 + * Sets the value of PAUSE_IGNORE field in the COMMAND_CONFIG Register
97003 + * 0 - MAC stops transmit process for the duration specified
97004 + * in the Pause frame quanta of a received Pause frame.
97005 + * 1 - MAC ignores received Pause frames.
97006 + */
97007 +void fman_tgec_set_rx_ignore_pause_frames(struct tgec_regs *regs, bool en);
97008 +
97009 +/**
97010 + * fman_tgec_enable_1588_time_stamp() - change timestamp functionality
97011 + * @regs: Pointer to TGEC register block
97012 + * @en: enable/disable timestamp functionality
97013 + *
97014 + * Sets the value of EN_TIMESTAMP field in the COMMAND_CONFIG Register
97015 + * IEEE 1588 timestamp functionality control:
97016 + * 0 disabled, 1 enabled
97017 + */
97018 +
97019 +void fman_tgec_enable_1588_time_stamp(struct tgec_regs *regs, bool en);
97020 +
97021 +uint32_t fman_tgec_get_event(struct tgec_regs *regs, uint32_t ev_mask);
97022 +
97023 +void fman_tgec_ack_event(struct tgec_regs *regs, uint32_t ev_mask);
97024 +
97025 +uint32_t fman_tgec_get_interrupt_mask(struct tgec_regs *regs);
97026 +
97027 +/**
97028 + * fman_tgec_add_addr_in_paddr() - Sets additional exact match MAC address
97029 + * @regs: Pointer to TGEC register block
97030 + * @addr_ptr: Pointer to 6-byte array containing the MAC address
97031 + *
97032 + * Sets the additional station MAC address
97033 + */
97034 +void fman_tgec_add_addr_in_paddr(struct tgec_regs *regs, uint8_t *addr_ptr);
97035 +
97036 +void fman_tgec_clear_addr_in_paddr(struct tgec_regs *regs);
97037 +
97038 +void fman_tgec_enable_interrupt(struct tgec_regs *regs, uint32_t ev_mask);
97039 +
97040 +void fman_tgec_disable_interrupt(struct tgec_regs *regs, uint32_t ev_mask);
97041 +
97042 +void fman_tgec_reset_filter_table(struct tgec_regs *regs);
97043 +
97044 +void fman_tgec_set_hash_table_entry(struct tgec_regs *regs, uint32_t crc);
97045 +
97046 +
97047 +/**
97048 + * fman_tgec_get_max_frame_len() - Returns the maximum frame length value
97049 + * @regs: Pointer to TGEC register block
97050 + */
97051 +uint16_t fman_tgec_get_max_frame_len(struct tgec_regs *regs);
97052 +
97053 +/**
97054 + * fman_tgec_set_erratum_tx_fifo_corruption_10gmac_a007() - Initialize the
97055 + * main tgec configuration parameters
97056 + * @regs: Pointer to TGEC register block
97057 + *
97058 + * TODO
97059 + */
97060 +void fman_tgec_set_erratum_tx_fifo_corruption_10gmac_a007(struct tgec_regs
97061 + *regs);
97062 +
97063 +
97064 +#endif /* __FSL_FMAN_TGEC_H */
97065 --- /dev/null
97066 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/integrations/FMANV3H/dpaa_integration_ext.h
97067 @@ -0,0 +1,291 @@
97068 +/*
97069 + * Copyright 2012 Freescale Semiconductor Inc.
97070 + *
97071 + * Redistribution and use in source and binary forms, with or without
97072 + * modification, are permitted provided that the following conditions are met:
97073 + * * Redistributions of source code must retain the above copyright
97074 + * notice, this list of conditions and the following disclaimer.
97075 + * * Redistributions in binary form must reproduce the above copyright
97076 + * notice, this list of conditions and the following disclaimer in the
97077 + * documentation and/or other materials provided with the distribution.
97078 + * * Neither the name of Freescale Semiconductor nor the
97079 + * names of its contributors may be used to endorse or promote products
97080 + * derived from this software without specific prior written permission.
97081 + *
97082 + *
97083 + * ALTERNATIVELY, this software may be distributed under the terms of the
97084 + * GNU General Public License ("GPL") as published by the Free Software
97085 + * Foundation, either version 2 of that License or (at your option) any
97086 + * later version.
97087 + *
97088 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
97089 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
97090 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
97091 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
97092 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
97093 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
97094 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
97095 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
97096 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
97097 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
97098 + */
97099 +
97100 +/**
97101 +
97102 + @File dpaa_integration_ext.h
97103 +
97104 + @Description T4240 FM external definitions and structures.
97105 +*//***************************************************************************/
97106 +#ifndef __DPAA_INTEGRATION_EXT_H
97107 +#define __DPAA_INTEGRATION_EXT_H
97108 +
97109 +#include "std_ext.h"
97110 +
97111 +
97112 +#define DPAA_VERSION 11
97113 +
97114 +/**************************************************************************//**
97115 + @Description DPAA SW Portals Enumeration.
97116 +*//***************************************************************************/
97117 +typedef enum
97118 +{
97119 + e_DPAA_SWPORTAL0 = 0,
97120 + e_DPAA_SWPORTAL1,
97121 + e_DPAA_SWPORTAL2,
97122 + e_DPAA_SWPORTAL3,
97123 + e_DPAA_SWPORTAL4,
97124 + e_DPAA_SWPORTAL5,
97125 + e_DPAA_SWPORTAL6,
97126 + e_DPAA_SWPORTAL7,
97127 + e_DPAA_SWPORTAL8,
97128 + e_DPAA_SWPORTAL9,
97129 + e_DPAA_SWPORTAL10,
97130 + e_DPAA_SWPORTAL11,
97131 + e_DPAA_SWPORTAL12,
97132 + e_DPAA_SWPORTAL13,
97133 + e_DPAA_SWPORTAL14,
97134 + e_DPAA_SWPORTAL15,
97135 + e_DPAA_SWPORTAL16,
97136 + e_DPAA_SWPORTAL17,
97137 + e_DPAA_SWPORTAL18,
97138 + e_DPAA_SWPORTAL19,
97139 + e_DPAA_SWPORTAL20,
97140 + e_DPAA_SWPORTAL21,
97141 + e_DPAA_SWPORTAL22,
97142 + e_DPAA_SWPORTAL23,
97143 + e_DPAA_SWPORTAL24,
97144 + e_DPAA_SWPORTAL_DUMMY_LAST
97145 +} e_DpaaSwPortal;
97146 +
97147 +/**************************************************************************//**
97148 + @Description DPAA Direct Connect Portals Enumeration.
97149 +*//***************************************************************************/
97150 +typedef enum
97151 +{
97152 + e_DPAA_DCPORTAL0 = 0,
97153 + e_DPAA_DCPORTAL1,
97154 + e_DPAA_DCPORTAL2,
97155 + e_DPAA_DCPORTAL_DUMMY_LAST
97156 +} e_DpaaDcPortal;
97157 +
97158 +#define DPAA_MAX_NUM_OF_SW_PORTALS e_DPAA_SWPORTAL_DUMMY_LAST
97159 +#define DPAA_MAX_NUM_OF_DC_PORTALS e_DPAA_DCPORTAL_DUMMY_LAST
97160 +
97161 +/*****************************************************************************
97162 + QMan INTEGRATION-SPECIFIC DEFINITIONS
97163 +******************************************************************************/
97164 +#define QM_MAX_NUM_OF_POOL_CHANNELS 15 /**< Total number of channels, dedicated and pool */
97165 +#define QM_MAX_NUM_OF_WQ 8 /**< Number of work queues per channel */
97166 +#define QM_MAX_NUM_OF_CGS 256 /**< Congestion groups number */
97167 +#define QM_MAX_NUM_OF_FQIDS (16 * MEGABYTE)
97168 + /**< FQIDs range - 24 bits */
97169 +
97170 +/**************************************************************************//**
97171 + @Description Work Queue Channel assignments in QMan.
97172 +*//***************************************************************************/
97173 +typedef enum
97174 +{
97175 + e_QM_FQ_CHANNEL_SWPORTAL0 = 0x0, /**< Dedicated channels serviced by software portals 0 to 24 */
97176 + e_QM_FQ_CHANNEL_SWPORTAL1,
97177 + e_QM_FQ_CHANNEL_SWPORTAL2,
97178 + e_QM_FQ_CHANNEL_SWPORTAL3,
97179 + e_QM_FQ_CHANNEL_SWPORTAL4,
97180 + e_QM_FQ_CHANNEL_SWPORTAL5,
97181 + e_QM_FQ_CHANNEL_SWPORTAL6,
97182 + e_QM_FQ_CHANNEL_SWPORTAL7,
97183 + e_QM_FQ_CHANNEL_SWPORTAL8,
97184 + e_QM_FQ_CHANNEL_SWPORTAL9,
97185 + e_QM_FQ_CHANNEL_SWPORTAL10,
97186 + e_QM_FQ_CHANNEL_SWPORTAL11,
97187 + e_QM_FQ_CHANNEL_SWPORTAL12,
97188 + e_QM_FQ_CHANNEL_SWPORTAL13,
97189 + e_QM_FQ_CHANNEL_SWPORTAL14,
97190 + e_QM_FQ_CHANNEL_SWPORTAL15,
97191 + e_QM_FQ_CHANNEL_SWPORTAL16,
97192 + e_QM_FQ_CHANNEL_SWPORTAL17,
97193 + e_QM_FQ_CHANNEL_SWPORTAL18,
97194 + e_QM_FQ_CHANNEL_SWPORTAL19,
97195 + e_QM_FQ_CHANNEL_SWPORTAL20,
97196 + e_QM_FQ_CHANNEL_SWPORTAL21,
97197 + e_QM_FQ_CHANNEL_SWPORTAL22,
97198 + e_QM_FQ_CHANNEL_SWPORTAL23,
97199 + e_QM_FQ_CHANNEL_SWPORTAL24,
97200 +
97201 + e_QM_FQ_CHANNEL_POOL1 = 0x401, /**< Pool channels that can be serviced by any of the software portals */
97202 + e_QM_FQ_CHANNEL_POOL2,
97203 + e_QM_FQ_CHANNEL_POOL3,
97204 + e_QM_FQ_CHANNEL_POOL4,
97205 + e_QM_FQ_CHANNEL_POOL5,
97206 + e_QM_FQ_CHANNEL_POOL6,
97207 + e_QM_FQ_CHANNEL_POOL7,
97208 + e_QM_FQ_CHANNEL_POOL8,
97209 + e_QM_FQ_CHANNEL_POOL9,
97210 + e_QM_FQ_CHANNEL_POOL10,
97211 + e_QM_FQ_CHANNEL_POOL11,
97212 + e_QM_FQ_CHANNEL_POOL12,
97213 + e_QM_FQ_CHANNEL_POOL13,
97214 + e_QM_FQ_CHANNEL_POOL14,
97215 + e_QM_FQ_CHANNEL_POOL15,
97216 +
97217 + e_QM_FQ_CHANNEL_FMAN0_SP0 = 0x800, /**< Dedicated channels serviced by Direct Connect Portal 0:
97218 + connected to FMan 0; assigned in incrementing order to
97219 + each sub-portal (SP) in the portal */
97220 + e_QM_FQ_CHANNEL_FMAN0_SP1,
97221 + e_QM_FQ_CHANNEL_FMAN0_SP2,
97222 + e_QM_FQ_CHANNEL_FMAN0_SP3,
97223 + e_QM_FQ_CHANNEL_FMAN0_SP4,
97224 + e_QM_FQ_CHANNEL_FMAN0_SP5,
97225 + e_QM_FQ_CHANNEL_FMAN0_SP6,
97226 + e_QM_FQ_CHANNEL_FMAN0_SP7,
97227 + e_QM_FQ_CHANNEL_FMAN0_SP8,
97228 + e_QM_FQ_CHANNEL_FMAN0_SP9,
97229 + e_QM_FQ_CHANNEL_FMAN0_SP10,
97230 + e_QM_FQ_CHANNEL_FMAN0_SP11,
97231 + e_QM_FQ_CHANNEL_FMAN0_SP12,
97232 + e_QM_FQ_CHANNEL_FMAN0_SP13,
97233 + e_QM_FQ_CHANNEL_FMAN0_SP14,
97234 + e_QM_FQ_CHANNEL_FMAN0_SP15,
97235 +
97236 + e_QM_FQ_CHANNEL_RMAN_SP0 = 0x820, /**< Dedicated channels serviced by Direct Connect Portal 1: connected to RMan */
97237 + e_QM_FQ_CHANNEL_RMAN_SP1,
97238 +
97239 + e_QM_FQ_CHANNEL_CAAM = 0x840 /**< Dedicated channel serviced by Direct Connect Portal 2:
97240 + connected to SEC */
97241 +} e_QmFQChannel;
97242 +
97243 +/*****************************************************************************
97244 + BMan INTEGRATION-SPECIFIC DEFINITIONS
97245 +******************************************************************************/
97246 +#define BM_MAX_NUM_OF_POOLS 64 /**< Number of buffers pools */
97247 +
97248 +/*****************************************************************************
97249 + SEC INTEGRATION-SPECIFIC DEFINITIONS
97250 +******************************************************************************/
97251 +#define SEC_NUM_OF_DECOS 3
97252 +#define SEC_ALL_DECOS_MASK 0x00000003
97253 +
97254 +
97255 +/*****************************************************************************
97256 + FM INTEGRATION-SPECIFIC DEFINITIONS
97257 +******************************************************************************/
97258 +#define INTG_MAX_NUM_OF_FM 2
97259 +/* Ports defines */
97260 +#define FM_MAX_NUM_OF_1G_MACS 6
97261 +#define FM_MAX_NUM_OF_10G_MACS 2
97262 +#define FM_MAX_NUM_OF_MACS (FM_MAX_NUM_OF_1G_MACS + FM_MAX_NUM_OF_10G_MACS)
97263 +#define FM_MAX_NUM_OF_OH_PORTS 6
97264 +
97265 +#define FM_MAX_NUM_OF_1G_RX_PORTS FM_MAX_NUM_OF_1G_MACS
97266 +#define FM_MAX_NUM_OF_10G_RX_PORTS FM_MAX_NUM_OF_10G_MACS
97267 +#define FM_MAX_NUM_OF_RX_PORTS (FM_MAX_NUM_OF_10G_RX_PORTS + FM_MAX_NUM_OF_1G_RX_PORTS)
97268 +
97269 +#define FM_MAX_NUM_OF_1G_TX_PORTS FM_MAX_NUM_OF_1G_MACS
97270 +#define FM_MAX_NUM_OF_10G_TX_PORTS FM_MAX_NUM_OF_10G_MACS
97271 +#define FM_MAX_NUM_OF_TX_PORTS (FM_MAX_NUM_OF_10G_TX_PORTS + FM_MAX_NUM_OF_1G_TX_PORTS)
97272 +
97273 +#define FM_PORT_MAX_NUM_OF_EXT_POOLS 4 /**< Number of external BM pools per Rx port */
97274 +#define FM_PORT_NUM_OF_CONGESTION_GRPS 256 /**< Total number of congestion groups in QM */
97275 +#define FM_MAX_NUM_OF_SUB_PORTALS 16
97276 +#define FM_PORT_MAX_NUM_OF_OBSERVED_EXT_POOLS 0
97277 +
97278 +#define FM_VSP_MAX_NUM_OF_ENTRIES 64
97279 +#define FM_MAX_NUM_OF_PFC_PRIORITIES 8
97280 +
97281 +/* RAMs defines */
97282 +#define FM_MURAM_SIZE (384 * KILOBYTE)
97283 +#define FM_IRAM_SIZE(major, minor) (64 * KILOBYTE)
97284 +#define FM_NUM_OF_CTRL 4
97285 +
97286 +/* PCD defines */
97287 +#define FM_PCD_PLCR_NUM_ENTRIES 256 /**< Total number of policer profiles */
97288 +#define FM_PCD_KG_NUM_OF_SCHEMES 32 /**< Total number of KG schemes */
97289 +#define FM_PCD_MAX_NUM_OF_CLS_PLANS 256 /**< Number of classification plan entries. */
97290 +#define FM_PCD_PRS_SW_PATCHES_SIZE 0x00000600 /**< Number of bytes saved for patches */
97291 +#define FM_PCD_SW_PRS_SIZE 0x00000800 /**< Total size of SW parser area */
97292 +
97293 +/* RTC defines */
97294 +#define FM_RTC_NUM_OF_ALARMS 2 /**< RTC number of alarms */
97295 +#define FM_RTC_NUM_OF_PERIODIC_PULSES 3 /**< RTC number of periodic pulses */
97296 +#define FM_RTC_NUM_OF_EXT_TRIGGERS 2 /**< RTC number of external triggers */
97297 +
97298 +/* QMI defines */
97299 +#define QMI_MAX_NUM_OF_TNUMS 64
97300 +#define QMI_DEF_TNUMS_THRESH 32
97301 +/* FPM defines */
97302 +#define FM_NUM_OF_FMAN_CTRL_EVENT_REGS 4
97303 +
97304 +/* DMA defines */
97305 +#define DMA_THRESH_MAX_COMMQ 83
97306 +#define DMA_THRESH_MAX_BUF 127
97307 +
97308 +/* BMI defines */
97309 +#define BMI_MAX_NUM_OF_TASKS 128
97310 +#define BMI_MAX_NUM_OF_DMAS 84
97311 +
97312 +#define BMI_MAX_FIFO_SIZE (FM_MURAM_SIZE)
97313 +#define PORT_MAX_WEIGHT 16
97314 +
97315 +#define FM_CHECK_PORT_RESTRICTIONS(__validPorts, __newPortIndx) TRUE
97316 +
97317 +/* Unique T4240 */
97318 +#define FM_OP_OPEN_DMA_MIN_LIMIT
97319 +#define FM_NO_RESTRICT_ON_ACCESS_RSRC
97320 +#define FM_NO_OP_OBSERVED_POOLS
97321 +#define FM_FRAME_END_PARAMS_FOR_OP
97322 +#define FM_DEQ_PIPELINE_PARAMS_FOR_OP
97323 +#define FM_QMI_NO_SINGLE_ECC_EXCEPTION
97324 +
97325 +#define FM_NO_GUARANTEED_RESET_VALUES
97326 +
97327 +/* FM errata */
97328 +#define FM_HEAVY_TRAFFIC_HANG_ERRATA_FMAN_A005669
97329 +#define FM_WRONG_RESET_VALUES_ERRATA_FMAN_A005127
97330 +#define FM_RX_FIFO_CORRUPT_ERRATA_10GMAC_A006320
97331 +#define FM_OP_NO_VSP_NO_RELEASE_ERRATA_FMAN_A006675
97332 +#define FM_HEAVY_TRAFFIC_SEQUENCER_HANG_ERRATA_FMAN_A006981
97333 +#define FM_HANG_AT_RESET_MAC_CLK_DISABLED_ERRATA_FMAN_A007273
97334 +
97335 +#define FM_BCB_ERRATA_BMI_SW001
97336 +#define FM_LEN_CHECK_ERRATA_FMAN_SW002
97337 +#define FM_AID_MODE_NO_TNUM_SW005 /* refer to pdm TKT068794 - only support of port_id on aid */
97338 +#define FM_ERROR_VSP_NO_MATCH_SW006 /* refer to pdm TKT174304 - no match between errorQ and VSP */
97339 +
97340 +/*****************************************************************************
97341 + RMan INTEGRATION-SPECIFIC DEFINITIONS
97342 +******************************************************************************/
97343 +#define RM_MAX_NUM_OF_IB 4 /**< Number of inbound blocks */
97344 +#define RM_NUM_OF_IBCU 8 /**< NUmber of classification units in an inbound block */
97345 +
97346 +/* RMan erratas */
97347 +#define RM_ERRONEOUS_ACK_ERRATA_RMAN_A006756
97348 +
97349 +/*****************************************************************************
97350 + FM MACSEC INTEGRATION-SPECIFIC DEFINITIONS
97351 +******************************************************************************/
97352 +#define NUM_OF_RX_SC 16
97353 +#define NUM_OF_TX_SC 16
97354 +
97355 +#define NUM_OF_SA_PER_RX_SC 2
97356 +#define NUM_OF_SA_PER_TX_SC 2
97357 +
97358 +#endif /* __DPAA_INTEGRATION_EXT_H */
97359 --- /dev/null
97360 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/integrations/FMANV3H/part_ext.h
97361 @@ -0,0 +1,71 @@
97362 +/*
97363 + * Copyright 2012 Freescale Semiconductor Inc.
97364 + *
97365 + * Redistribution and use in source and binary forms, with or without
97366 + * modification, are permitted provided that the following conditions are met:
97367 + * * Redistributions of source code must retain the above copyright
97368 + * notice, this list of conditions and the following disclaimer.
97369 + * * Redistributions in binary form must reproduce the above copyright
97370 + * notice, this list of conditions and the following disclaimer in the
97371 + * documentation and/or other materials provided with the distribution.
97372 + * * Neither the name of Freescale Semiconductor nor the
97373 + * names of its contributors may be used to endorse or promote products
97374 + * derived from this software without specific prior written permission.
97375 + *
97376 + *
97377 + * ALTERNATIVELY, this software may be distributed under the terms of the
97378 + * GNU General Public License ("GPL") as published by the Free Software
97379 + * Foundation, either version 2 of that License or (at your option) any
97380 + * later version.
97381 + *
97382 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
97383 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
97384 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
97385 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
97386 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
97387 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
97388 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
97389 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
97390 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
97391 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
97392 + */
97393 +
97394 +/**************************************************************************//**
97395 +
97396 + @File part_ext.h
97397 +
97398 + @Description Definitions for the part (integration) module.
97399 +*//***************************************************************************/
97400 +
97401 +#ifndef __PART_EXT_H
97402 +#define __PART_EXT_H
97403 +
97404 +#include "std_ext.h"
97405 +#include "part_integration_ext.h"
97406 +
97407 +#if !(defined(P1023) || \
97408 + defined(P2041) || \
97409 + defined(P3041) || \
97410 + defined(P4080) || \
97411 + defined(P5020) || \
97412 + defined(P5040) || \
97413 + defined(B4860) || \
97414 + defined(T4240))
97415 +#error "unable to proceed without chip-definition"
97416 +#endif
97417 +
97418 +
97419 +/**************************************************************************//*
97420 + @Description Part data structure - must be contained in any integration
97421 + data structure.
97422 +*//***************************************************************************/
97423 +typedef struct t_Part
97424 +{
97425 + uintptr_t (* f_GetModuleBase)(t_Handle h_Part, e_ModuleId moduleId);
97426 + /**< Returns the address of the module's memory map base. */
97427 + e_ModuleId (* f_GetModuleIdByBase)(t_Handle h_Part, uintptr_t baseAddress);
97428 + /**< Returns the module's ID according to its memory map base. */
97429 +} t_Part;
97430 +
97431 +
97432 +#endif /* __PART_EXT_H */
97433 --- /dev/null
97434 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/integrations/FMANV3H/part_integration_ext.h
97435 @@ -0,0 +1,304 @@
97436 +/*
97437 + * Copyright 2008-2012 Freescale Semiconductor Inc.
97438 + *
97439 + * Redistribution and use in source and binary forms, with or without
97440 + * modification, are permitted provided that the following conditions are met:
97441 + * * Redistributions of source code must retain the above copyright
97442 + * notice, this list of conditions and the following disclaimer.
97443 + * * Redistributions in binary form must reproduce the above copyright
97444 + * notice, this list of conditions and the following disclaimer in the
97445 + * documentation and/or other materials provided with the distribution.
97446 + * * Neither the name of Freescale Semiconductor nor the
97447 + * names of its contributors may be used to endorse or promote products
97448 + * derived from this software without specific prior written permission.
97449 + *
97450 + *
97451 + * ALTERNATIVELY, this software may be distributed under the terms of the
97452 + * GNU General Public License ("GPL") as published by the Free Software
97453 + * Foundation, either version 2 of that License or (at your option) any
97454 + * later version.
97455 + *
97456 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
97457 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
97458 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
97459 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
97460 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
97461 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
97462 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
97463 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
97464 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
97465 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
97466 + */
97467 +
97468 +/**
97469 +
97470 + @File part_integration_ext.h
97471 +
97472 + @Description T4240 external definitions and structures.
97473 +*//***************************************************************************/
97474 +#ifndef __PART_INTEGRATION_EXT_H
97475 +#define __PART_INTEGRATION_EXT_H
97476 +
97477 +#include "std_ext.h"
97478 +#include "ddr_std_ext.h"
97479 +#include "enet_ext.h"
97480 +#include "dpaa_integration_ext.h"
97481 +
97482 +
97483 +/**************************************************************************//**
97484 + @Group T4240_chip_id T4240 Application Programming Interface
97485 +
97486 + @Description T4240 Chip functions,definitions and enums.
97487 +
97488 + @{
97489 +*//***************************************************************************/
97490 +
97491 +#define CORE_E6500
97492 +
97493 +#define INTG_MAX_NUM_OF_CORES 24
97494 +
97495 +
97496 +/**************************************************************************//**
97497 + @Description Module types.
97498 +*//***************************************************************************/
97499 +typedef enum e_ModuleId
97500 +{
97501 + e_MODULE_ID_DUART_1 = 0,
97502 + e_MODULE_ID_DUART_2,
97503 + e_MODULE_ID_DUART_3,
97504 + e_MODULE_ID_DUART_4,
97505 + e_MODULE_ID_LAW,
97506 + e_MODULE_ID_IFC,
97507 + e_MODULE_ID_PAMU,
97508 + e_MODULE_ID_QM, /**< Queue manager module */
97509 + e_MODULE_ID_BM, /**< Buffer manager module */
97510 + e_MODULE_ID_QM_CE_PORTAL_0,
97511 + e_MODULE_ID_QM_CI_PORTAL_0,
97512 + e_MODULE_ID_QM_CE_PORTAL_1,
97513 + e_MODULE_ID_QM_CI_PORTAL_1,
97514 + e_MODULE_ID_QM_CE_PORTAL_2,
97515 + e_MODULE_ID_QM_CI_PORTAL_2,
97516 + e_MODULE_ID_QM_CE_PORTAL_3,
97517 + e_MODULE_ID_QM_CI_PORTAL_3,
97518 + e_MODULE_ID_QM_CE_PORTAL_4,
97519 + e_MODULE_ID_QM_CI_PORTAL_4,
97520 + e_MODULE_ID_QM_CE_PORTAL_5,
97521 + e_MODULE_ID_QM_CI_PORTAL_5,
97522 + e_MODULE_ID_QM_CE_PORTAL_6,
97523 + e_MODULE_ID_QM_CI_PORTAL_6,
97524 + e_MODULE_ID_QM_CE_PORTAL_7,
97525 + e_MODULE_ID_QM_CI_PORTAL_7,
97526 + e_MODULE_ID_QM_CE_PORTAL_8,
97527 + e_MODULE_ID_QM_CI_PORTAL_8,
97528 + e_MODULE_ID_QM_CE_PORTAL_9,
97529 + e_MODULE_ID_QM_CI_PORTAL_9,
97530 + e_MODULE_ID_BM_CE_PORTAL_0,
97531 + e_MODULE_ID_BM_CI_PORTAL_0,
97532 + e_MODULE_ID_BM_CE_PORTAL_1,
97533 + e_MODULE_ID_BM_CI_PORTAL_1,
97534 + e_MODULE_ID_BM_CE_PORTAL_2,
97535 + e_MODULE_ID_BM_CI_PORTAL_2,
97536 + e_MODULE_ID_BM_CE_PORTAL_3,
97537 + e_MODULE_ID_BM_CI_PORTAL_3,
97538 + e_MODULE_ID_BM_CE_PORTAL_4,
97539 + e_MODULE_ID_BM_CI_PORTAL_4,
97540 + e_MODULE_ID_BM_CE_PORTAL_5,
97541 + e_MODULE_ID_BM_CI_PORTAL_5,
97542 + e_MODULE_ID_BM_CE_PORTAL_6,
97543 + e_MODULE_ID_BM_CI_PORTAL_6,
97544 + e_MODULE_ID_BM_CE_PORTAL_7,
97545 + e_MODULE_ID_BM_CI_PORTAL_7,
97546 + e_MODULE_ID_BM_CE_PORTAL_8,
97547 + e_MODULE_ID_BM_CI_PORTAL_8,
97548 + e_MODULE_ID_BM_CE_PORTAL_9,
97549 + e_MODULE_ID_BM_CI_PORTAL_9,
97550 + e_MODULE_ID_FM, /**< Frame manager module */
97551 + e_MODULE_ID_FM_RTC, /**< FM Real-Time-Clock */
97552 + e_MODULE_ID_FM_MURAM, /**< FM Multi-User-RAM */
97553 + e_MODULE_ID_FM_BMI, /**< FM BMI block */
97554 + e_MODULE_ID_FM_QMI, /**< FM QMI block */
97555 + e_MODULE_ID_FM_PARSER, /**< FM parser block */
97556 + e_MODULE_ID_FM_PORT_HO1, /**< FM Host-command/offline-parsing port block */
97557 + e_MODULE_ID_FM_PORT_HO2, /**< FM Host-command/offline-parsing port block */
97558 + e_MODULE_ID_FM_PORT_HO3, /**< FM Host-command/offline-parsing port block */
97559 + e_MODULE_ID_FM_PORT_HO4, /**< FM Host-command/offline-parsing port block */
97560 + e_MODULE_ID_FM_PORT_HO5, /**< FM Host-command/offline-parsing port block */
97561 + e_MODULE_ID_FM_PORT_HO6, /**< FM Host-command/offline-parsing port block */
97562 + e_MODULE_ID_FM_PORT_HO7, /**< FM Host-command/offline-parsing port block */
97563 + e_MODULE_ID_FM_PORT_1GRx1, /**< FM Rx 1G MAC port block */
97564 + e_MODULE_ID_FM_PORT_1GRx2, /**< FM Rx 1G MAC port block */
97565 + e_MODULE_ID_FM_PORT_1GRx3, /**< FM Rx 1G MAC port block */
97566 + e_MODULE_ID_FM_PORT_1GRx4, /**< FM Rx 1G MAC port block */
97567 + e_MODULE_ID_FM_PORT_1GRx5, /**< FM Rx 1G MAC port block */
97568 + e_MODULE_ID_FM_PORT_1GRx6, /**< FM Rx 1G MAC port block */
97569 + e_MODULE_ID_FM_PORT_10GRx1, /**< FM Rx 10G MAC port block */
97570 + e_MODULE_ID_FM_PORT_10GRx2, /**< FM Rx 10G MAC port block */
97571 + e_MODULE_ID_FM_PORT_1GTx1, /**< FM Tx 1G MAC port block */
97572 + e_MODULE_ID_FM_PORT_1GTx2, /**< FM Tx 1G MAC port block */
97573 + e_MODULE_ID_FM_PORT_1GTx3, /**< FM Tx 1G MAC port block */
97574 + e_MODULE_ID_FM_PORT_1GTx4, /**< FM Tx 1G MAC port block */
97575 + e_MODULE_ID_FM_PORT_1GTx5, /**< FM Tx 1G MAC port block */
97576 + e_MODULE_ID_FM_PORT_1GTx6, /**< FM Tx 1G MAC port block */
97577 + e_MODULE_ID_FM_PORT_10GTx1, /**< FM Tx 10G MAC port block */
97578 + e_MODULE_ID_FM_PORT_10GTx2, /**< FM Tx 10G MAC port block */
97579 + e_MODULE_ID_FM_PLCR, /**< FM Policer */
97580 + e_MODULE_ID_FM_KG, /**< FM Keygen */
97581 + e_MODULE_ID_FM_DMA, /**< FM DMA */
97582 + e_MODULE_ID_FM_FPM, /**< FM FPM */
97583 + e_MODULE_ID_FM_IRAM, /**< FM Instruction-RAM */
97584 + e_MODULE_ID_FM_1GMDIO, /**< FM 1G MDIO MAC */
97585 + e_MODULE_ID_FM_10GMDIO, /**< FM 10G MDIO */
97586 + e_MODULE_ID_FM_PRS_IRAM, /**< FM SW-parser Instruction-RAM */
97587 + e_MODULE_ID_FM_1GMAC1, /**< FM 1G MAC #1 */
97588 + e_MODULE_ID_FM_1GMAC2, /**< FM 1G MAC #2 */
97589 + e_MODULE_ID_FM_1GMAC3, /**< FM 1G MAC #3 */
97590 + e_MODULE_ID_FM_1GMAC4, /**< FM 1G MAC #4 */
97591 + e_MODULE_ID_FM_1GMAC5, /**< FM 1G MAC #5 */
97592 + e_MODULE_ID_FM_1GMAC6, /**< FM 1G MAC #6 */
97593 + e_MODULE_ID_FM_10GMAC1, /**< FM 10G MAC */
97594 + e_MODULE_ID_FM_10GMAC2, /**< FM 10G MAC */
97595 +
97596 + e_MODULE_ID_SEC_GEN, /**< SEC 4.0 General registers */
97597 + e_MODULE_ID_SEC_QI, /**< SEC 4.0 QI registers */
97598 + e_MODULE_ID_SEC_JQ0, /**< SEC 4.0 JQ-0 registers */
97599 + e_MODULE_ID_SEC_JQ1, /**< SEC 4.0 JQ-1 registers */
97600 + e_MODULE_ID_SEC_JQ2, /**< SEC 4.0 JQ-2 registers */
97601 + e_MODULE_ID_SEC_JQ3, /**< SEC 4.0 JQ-3 registers */
97602 + e_MODULE_ID_SEC_RTIC, /**< SEC 4.0 RTIC registers */
97603 + e_MODULE_ID_SEC_DECO0_CCB0, /**< SEC 4.0 DECO-0/CCB-0 registers */
97604 + e_MODULE_ID_SEC_DECO1_CCB1, /**< SEC 4.0 DECO-1/CCB-1 registers */
97605 + e_MODULE_ID_SEC_DECO2_CCB2, /**< SEC 4.0 DECO-2/CCB-2 registers */
97606 + e_MODULE_ID_SEC_DECO3_CCB3, /**< SEC 4.0 DECO-3/CCB-3 registers */
97607 + e_MODULE_ID_SEC_DECO4_CCB4, /**< SEC 4.0 DECO-4/CCB-4 registers */
97608 +
97609 + e_MODULE_ID_PIC, /**< PIC */
97610 + e_MODULE_ID_GPIO, /**< GPIO */
97611 + e_MODULE_ID_SERDES, /**< SERDES */
97612 + e_MODULE_ID_CPC_1, /**< CoreNet-Platform-Cache 1 */
97613 + e_MODULE_ID_CPC_2, /**< CoreNet-Platform-Cache 2 */
97614 +
97615 + e_MODULE_ID_SRIO_PORTS, /**< RapidIO controller */
97616 +
97617 + e_MODULE_ID_DUMMY_LAST
97618 +} e_ModuleId;
97619 +
97620 +#define NUM_OF_MODULES e_MODULE_ID_DUMMY_LAST
97621 +
97622 +#if 0 /* using unified values */
97623 +/*****************************************************************************
97624 + INTEGRATION-SPECIFIC MODULE CODES
97625 +******************************************************************************/
97626 +#define MODULE_UNKNOWN 0x00000000
97627 +#define MODULE_MEM 0x00010000
97628 +#define MODULE_MM 0x00020000
97629 +#define MODULE_CORE 0x00030000
97630 +#define MODULE_T4240 0x00040000
97631 +#define MODULE_T4240_PLATFORM 0x00050000
97632 +#define MODULE_PM 0x00060000
97633 +#define MODULE_MMU 0x00070000
97634 +#define MODULE_PIC 0x00080000
97635 +#define MODULE_CPC 0x00090000
97636 +#define MODULE_DUART 0x000a0000
97637 +#define MODULE_SERDES 0x000b0000
97638 +#define MODULE_PIO 0x000c0000
97639 +#define MODULE_QM 0x000d0000
97640 +#define MODULE_BM 0x000e0000
97641 +#define MODULE_SEC 0x000f0000
97642 +#define MODULE_LAW 0x00100000
97643 +#define MODULE_LBC 0x00110000
97644 +#define MODULE_PAMU 0x00120000
97645 +#define MODULE_FM 0x00130000
97646 +#define MODULE_FM_MURAM 0x00140000
97647 +#define MODULE_FM_PCD 0x00150000
97648 +#define MODULE_FM_RTC 0x00160000
97649 +#define MODULE_FM_MAC 0x00170000
97650 +#define MODULE_FM_PORT 0x00180000
97651 +#define MODULE_FM_SP 0x00190000
97652 +#define MODULE_DPA_PORT 0x001a0000
97653 +#define MODULE_MII 0x001b0000
97654 +#define MODULE_I2C 0x001c0000
97655 +#define MODULE_DMA 0x001d0000
97656 +#define MODULE_DDR 0x001e0000
97657 +#define MODULE_ESPI 0x001f0000
97658 +#define MODULE_DPAA_IPSEC 0x00200000
97659 +#endif /* using unified values */
97660 +
97661 +/*****************************************************************************
97662 + PAMU INTEGRATION-SPECIFIC DEFINITIONS
97663 +******************************************************************************/
97664 +#define PAMU_NUM_OF_PARTITIONS 4
97665 +
97666 +/*****************************************************************************
97667 + LAW INTEGRATION-SPECIFIC DEFINITIONS
97668 +******************************************************************************/
97669 +#define LAW_NUM_OF_WINDOWS 32
97670 +#define LAW_MIN_WINDOW_SIZE 0x0000000000001000LL /**< 4 Kbytes */
97671 +#define LAW_MAX_WINDOW_SIZE 0x0000010000000000LL /**< 1 Tbytes for 40-bit address space */
97672 +
97673 +
97674 +/*****************************************************************************
97675 + LBC INTEGRATION-SPECIFIC DEFINITIONS
97676 +******************************************************************************/
97677 +/**************************************************************************//**
97678 + @Group lbc_exception_grp LBC Exception Unit
97679 +
97680 + @Description LBC Exception unit API functions, definitions and enums
97681 +
97682 + @{
97683 +*//***************************************************************************/
97684 +
97685 +/**************************************************************************//**
97686 + @Anchor lbc_exbm
97687 +
97688 + @Collection LBC Errors Bit Mask
97689 +
97690 + These errors are reported through the exceptions callback..
97691 + The values can be or'ed in any combination in the errors mask
97692 + parameter of the errors report structure.
97693 +
97694 + These errors can also be passed as a bit-mask to
97695 + LBC_EnableErrorChecking() or LBC_DisableErrorChecking(),
97696 + for enabling or disabling error checking.
97697 + @{
97698 +*//***************************************************************************/
97699 +#define LBC_ERR_BUS_MONITOR 0x80000000 /**< Bus monitor error */
97700 +#define LBC_ERR_PARITY_ECC 0x20000000 /**< Parity error for GPCM/UPM */
97701 +#define LBC_ERR_WRITE_PROTECT 0x04000000 /**< Write protection error */
97702 +#define LBC_ERR_CHIP_SELECT 0x00080000 /**< Unrecognized chip select */
97703 +
97704 +#define LBC_ERR_ALL (LBC_ERR_BUS_MONITOR | LBC_ERR_PARITY_ECC | \
97705 + LBC_ERR_WRITE_PROTECT | LBC_ERR_CHIP_SELECT)
97706 + /**< All possible errors */
97707 +/* @} */
97708 +/** @} */ /* end of lbc_exception_grp group */
97709 +
97710 +#define LBC_INCORRECT_ERROR_REPORT_ERRATA
97711 +
97712 +#define LBC_NUM_OF_BANKS 8
97713 +#define LBC_MAX_CS_SIZE 0x0000000100000000LL /* Up to 4G memory block size */
97714 +#define LBC_PARITY_SUPPORT
97715 +#define LBC_ADDRESS_HOLD_TIME_CTRL
97716 +#define LBC_HIGH_CLK_DIVIDERS
97717 +#define LBC_FCM_AVAILABLE
97718 +
97719 +/*****************************************************************************
97720 + GPIO INTEGRATION-SPECIFIC DEFINITIONS
97721 +******************************************************************************/
97722 +#define GPIO_PORT_OFFSET_0x1000
97723 +
97724 +#define GPIO_NUM_OF_PORTS 3 /**< Number of ports in GPIO module;
97725 + Each port contains up to 32 I/O pins. */
97726 +
97727 +#define GPIO_VALID_PIN_MASKS \
97728 + { /* Port A */ 0xFFFFFFFF, \
97729 + /* Port B */ 0xFFFFFFFF, \
97730 + /* Port C */ 0xFFFFFFFF }
97731 +
97732 +#define GPIO_VALID_INTR_MASKS \
97733 + { /* Port A */ 0xFFFFFFFF, \
97734 + /* Port B */ 0xFFFFFFFF, \
97735 + /* Port C */ 0xFFFFFFFF }
97736 +
97737 +
97738 +
97739 +#endif /* __PART_INTEGRATION_EXT_H */
97740 --- /dev/null
97741 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/integrations/FMANV3L/dpaa_integration_ext.h
97742 @@ -0,0 +1,293 @@
97743 +/*
97744 + * Copyright 2012 Freescale Semiconductor Inc.
97745 + *
97746 + * Redistribution and use in source and binary forms, with or without
97747 + * modification, are permitted provided that the following conditions are met:
97748 + * * Redistributions of source code must retain the above copyright
97749 + * notice, this list of conditions and the following disclaimer.
97750 + * * Redistributions in binary form must reproduce the above copyright
97751 + * notice, this list of conditions and the following disclaimer in the
97752 + * documentation and/or other materials provided with the distribution.
97753 + * * Neither the name of Freescale Semiconductor nor the
97754 + * names of its contributors may be used to endorse or promote products
97755 + * derived from this software without specific prior written permission.
97756 + *
97757 + *
97758 + * ALTERNATIVELY, this software may be distributed under the terms of the
97759 + * GNU General Public License ("GPL") as published by the Free Software
97760 + * Foundation, either version 2 of that License or (at your option) any
97761 + * later version.
97762 + *
97763 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
97764 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
97765 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
97766 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
97767 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
97768 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
97769 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
97770 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
97771 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
97772 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
97773 + */
97774 +
97775 +/**
97776 +
97777 + @File dpaa_integration_ext.h
97778 +
97779 + @Description T4240 FM external definitions and structures.
97780 +*//***************************************************************************/
97781 +#ifndef __DPAA_INTEGRATION_EXT_H
97782 +#define __DPAA_INTEGRATION_EXT_H
97783 +
97784 +#include "std_ext.h"
97785 +
97786 +
97787 +#define DPAA_VERSION 11
97788 +
97789 +/**************************************************************************//**
97790 + @Description DPAA SW Portals Enumeration.
97791 +*//***************************************************************************/
97792 +typedef enum
97793 +{
97794 + e_DPAA_SWPORTAL0 = 0,
97795 + e_DPAA_SWPORTAL1,
97796 + e_DPAA_SWPORTAL2,
97797 + e_DPAA_SWPORTAL3,
97798 + e_DPAA_SWPORTAL4,
97799 + e_DPAA_SWPORTAL5,
97800 + e_DPAA_SWPORTAL6,
97801 + e_DPAA_SWPORTAL7,
97802 + e_DPAA_SWPORTAL8,
97803 + e_DPAA_SWPORTAL9,
97804 + e_DPAA_SWPORTAL10,
97805 + e_DPAA_SWPORTAL11,
97806 + e_DPAA_SWPORTAL12,
97807 + e_DPAA_SWPORTAL13,
97808 + e_DPAA_SWPORTAL14,
97809 + e_DPAA_SWPORTAL15,
97810 + e_DPAA_SWPORTAL16,
97811 + e_DPAA_SWPORTAL17,
97812 + e_DPAA_SWPORTAL18,
97813 + e_DPAA_SWPORTAL19,
97814 + e_DPAA_SWPORTAL20,
97815 + e_DPAA_SWPORTAL21,
97816 + e_DPAA_SWPORTAL22,
97817 + e_DPAA_SWPORTAL23,
97818 + e_DPAA_SWPORTAL24,
97819 + e_DPAA_SWPORTAL_DUMMY_LAST
97820 +} e_DpaaSwPortal;
97821 +
97822 +/**************************************************************************//**
97823 + @Description DPAA Direct Connect Portals Enumeration.
97824 +*//***************************************************************************/
97825 +typedef enum
97826 +{
97827 + e_DPAA_DCPORTAL0 = 0,
97828 + e_DPAA_DCPORTAL1,
97829 + e_DPAA_DCPORTAL2,
97830 + e_DPAA_DCPORTAL_DUMMY_LAST
97831 +} e_DpaaDcPortal;
97832 +
97833 +#define DPAA_MAX_NUM_OF_SW_PORTALS e_DPAA_SWPORTAL_DUMMY_LAST
97834 +#define DPAA_MAX_NUM_OF_DC_PORTALS e_DPAA_DCPORTAL_DUMMY_LAST
97835 +
97836 +/*****************************************************************************
97837 + QMan INTEGRATION-SPECIFIC DEFINITIONS
97838 +******************************************************************************/
97839 +#define QM_MAX_NUM_OF_POOL_CHANNELS 15 /**< Total number of channels, dedicated and pool */
97840 +#define QM_MAX_NUM_OF_WQ 8 /**< Number of work queues per channel */
97841 +#define QM_MAX_NUM_OF_CGS 256 /**< Congestion groups number */
97842 +#define QM_MAX_NUM_OF_FQIDS (16 * MEGABYTE)
97843 + /**< FQIDs range - 24 bits */
97844 +
97845 +/**************************************************************************//**
97846 + @Description Work Queue Channel assignments in QMan.
97847 +*//***************************************************************************/
97848 +typedef enum
97849 +{
97850 + e_QM_FQ_CHANNEL_SWPORTAL0 = 0x0, /**< Dedicated channels serviced by software portals 0 to 24 */
97851 + e_QM_FQ_CHANNEL_SWPORTAL1,
97852 + e_QM_FQ_CHANNEL_SWPORTAL2,
97853 + e_QM_FQ_CHANNEL_SWPORTAL3,
97854 + e_QM_FQ_CHANNEL_SWPORTAL4,
97855 + e_QM_FQ_CHANNEL_SWPORTAL5,
97856 + e_QM_FQ_CHANNEL_SWPORTAL6,
97857 + e_QM_FQ_CHANNEL_SWPORTAL7,
97858 + e_QM_FQ_CHANNEL_SWPORTAL8,
97859 + e_QM_FQ_CHANNEL_SWPORTAL9,
97860 + e_QM_FQ_CHANNEL_SWPORTAL10,
97861 + e_QM_FQ_CHANNEL_SWPORTAL11,
97862 + e_QM_FQ_CHANNEL_SWPORTAL12,
97863 + e_QM_FQ_CHANNEL_SWPORTAL13,
97864 + e_QM_FQ_CHANNEL_SWPORTAL14,
97865 + e_QM_FQ_CHANNEL_SWPORTAL15,
97866 + e_QM_FQ_CHANNEL_SWPORTAL16,
97867 + e_QM_FQ_CHANNEL_SWPORTAL17,
97868 + e_QM_FQ_CHANNEL_SWPORTAL18,
97869 + e_QM_FQ_CHANNEL_SWPORTAL19,
97870 + e_QM_FQ_CHANNEL_SWPORTAL20,
97871 + e_QM_FQ_CHANNEL_SWPORTAL21,
97872 + e_QM_FQ_CHANNEL_SWPORTAL22,
97873 + e_QM_FQ_CHANNEL_SWPORTAL23,
97874 + e_QM_FQ_CHANNEL_SWPORTAL24,
97875 +
97876 + e_QM_FQ_CHANNEL_POOL1 = 0x401, /**< Pool channels that can be serviced by any of the software portals */
97877 + e_QM_FQ_CHANNEL_POOL2,
97878 + e_QM_FQ_CHANNEL_POOL3,
97879 + e_QM_FQ_CHANNEL_POOL4,
97880 + e_QM_FQ_CHANNEL_POOL5,
97881 + e_QM_FQ_CHANNEL_POOL6,
97882 + e_QM_FQ_CHANNEL_POOL7,
97883 + e_QM_FQ_CHANNEL_POOL8,
97884 + e_QM_FQ_CHANNEL_POOL9,
97885 + e_QM_FQ_CHANNEL_POOL10,
97886 + e_QM_FQ_CHANNEL_POOL11,
97887 + e_QM_FQ_CHANNEL_POOL12,
97888 + e_QM_FQ_CHANNEL_POOL13,
97889 + e_QM_FQ_CHANNEL_POOL14,
97890 + e_QM_FQ_CHANNEL_POOL15,
97891 +
97892 + e_QM_FQ_CHANNEL_FMAN0_SP0 = 0x800, /**< Dedicated channels serviced by Direct Connect Portal 0:
97893 + connected to FMan 0; assigned in incrementing order to
97894 + each sub-portal (SP) in the portal */
97895 + e_QM_FQ_CHANNEL_FMAN0_SP1,
97896 + e_QM_FQ_CHANNEL_FMAN0_SP2,
97897 + e_QM_FQ_CHANNEL_FMAN0_SP3,
97898 + e_QM_FQ_CHANNEL_FMAN0_SP4,
97899 + e_QM_FQ_CHANNEL_FMAN0_SP5,
97900 + e_QM_FQ_CHANNEL_FMAN0_SP6,
97901 + e_QM_FQ_CHANNEL_FMAN0_SP7,
97902 + e_QM_FQ_CHANNEL_FMAN0_SP8,
97903 + e_QM_FQ_CHANNEL_FMAN0_SP9,
97904 + e_QM_FQ_CHANNEL_FMAN0_SP10,
97905 + e_QM_FQ_CHANNEL_FMAN0_SP11,
97906 + e_QM_FQ_CHANNEL_FMAN0_SP12,
97907 + e_QM_FQ_CHANNEL_FMAN0_SP13,
97908 + e_QM_FQ_CHANNEL_FMAN0_SP14,
97909 + e_QM_FQ_CHANNEL_FMAN0_SP15,
97910 +
97911 + e_QM_FQ_CHANNEL_RMAN_SP0 = 0x820, /**< Dedicated channels serviced by Direct Connect Portal 1: connected to RMan */
97912 + e_QM_FQ_CHANNEL_RMAN_SP1,
97913 +
97914 + e_QM_FQ_CHANNEL_CAAM = 0x840 /**< Dedicated channel serviced by Direct Connect Portal 2:
97915 + connected to SEC */
97916 +} e_QmFQChannel;
97917 +
97918 +/*****************************************************************************
97919 + BMan INTEGRATION-SPECIFIC DEFINITIONS
97920 +******************************************************************************/
97921 +#define BM_MAX_NUM_OF_POOLS 64 /**< Number of buffers pools */
97922 +
97923 +/*****************************************************************************
97924 + SEC INTEGRATION-SPECIFIC DEFINITIONS
97925 +******************************************************************************/
97926 +#define SEC_NUM_OF_DECOS 3
97927 +#define SEC_ALL_DECOS_MASK 0x00000003
97928 +
97929 +
97930 +/*****************************************************************************
97931 + FM INTEGRATION-SPECIFIC DEFINITIONS
97932 +******************************************************************************/
97933 +#define INTG_MAX_NUM_OF_FM 1
97934 +/* Ports defines */
97935 +#define FM_MAX_NUM_OF_1G_MACS 5
97936 +#define FM_MAX_NUM_OF_10G_MACS 1
97937 +#define FM_MAX_NUM_OF_MACS (FM_MAX_NUM_OF_1G_MACS + FM_MAX_NUM_OF_10G_MACS)
97938 +#define FM_MAX_NUM_OF_OH_PORTS 4
97939 +
97940 +#define FM_MAX_NUM_OF_1G_RX_PORTS FM_MAX_NUM_OF_1G_MACS
97941 +#define FM_MAX_NUM_OF_10G_RX_PORTS FM_MAX_NUM_OF_10G_MACS
97942 +#define FM_MAX_NUM_OF_RX_PORTS (FM_MAX_NUM_OF_10G_RX_PORTS + FM_MAX_NUM_OF_1G_RX_PORTS)
97943 +
97944 +#define FM_MAX_NUM_OF_1G_TX_PORTS FM_MAX_NUM_OF_1G_MACS
97945 +#define FM_MAX_NUM_OF_10G_TX_PORTS FM_MAX_NUM_OF_10G_MACS
97946 +#define FM_MAX_NUM_OF_TX_PORTS (FM_MAX_NUM_OF_10G_TX_PORTS + FM_MAX_NUM_OF_1G_TX_PORTS)
97947 +
97948 +#define FM_MAX_NUM_OF_MACSECS 1 /* Should be updated */
97949 +
97950 +#define FM_PORT_MAX_NUM_OF_EXT_POOLS 4 /**< Number of external BM pools per Rx port */
97951 +#define FM_PORT_NUM_OF_CONGESTION_GRPS 256 /**< Total number of congestion groups in QM */
97952 +#define FM_MAX_NUM_OF_SUB_PORTALS 16
97953 +#define FM_PORT_MAX_NUM_OF_OBSERVED_EXT_POOLS 0
97954 +
97955 +#define FM_VSP_MAX_NUM_OF_ENTRIES 32
97956 +#define FM_MAX_NUM_OF_PFC_PRIORITIES 8
97957 +
97958 +/* RAMs defines */
97959 +#define FM_MURAM_SIZE (192 * KILOBYTE)
97960 +#define FM_IRAM_SIZE(major, minor) \
97961 + (((major == 6) && ((minor == 4) )) ? (64 * KILOBYTE) : (32 * KILOBYTE))
97962 +#define FM_NUM_OF_CTRL 2
97963 +
97964 +/* PCD defines */
97965 +#define FM_PCD_PLCR_NUM_ENTRIES 256 /**< Total number of policer profiles */
97966 +#define FM_PCD_KG_NUM_OF_SCHEMES 32 /**< Total number of KG schemes */
97967 +#define FM_PCD_MAX_NUM_OF_CLS_PLANS 256 /**< Number of classification plan entries. */
97968 +#define FM_PCD_PRS_SW_PATCHES_SIZE 0x00000600 /**< Number of bytes saved for patches */
97969 +#define FM_PCD_SW_PRS_SIZE 0x00000800 /**< Total size of SW parser area */
97970 +
97971 +/* RTC defines */
97972 +#define FM_RTC_NUM_OF_ALARMS 2 /**< RTC number of alarms */
97973 +#define FM_RTC_NUM_OF_PERIODIC_PULSES 3 /**< RTC number of periodic pulses */
97974 +#define FM_RTC_NUM_OF_EXT_TRIGGERS 2 /**< RTC number of external triggers */
97975 +
97976 +/* QMI defines */
97977 +#define QMI_MAX_NUM_OF_TNUMS 64
97978 +#define QMI_DEF_TNUMS_THRESH 32
97979 +/* FPM defines */
97980 +#define FM_NUM_OF_FMAN_CTRL_EVENT_REGS 4
97981 +
97982 +/* DMA defines */
97983 +#define DMA_THRESH_MAX_COMMQ 83
97984 +#define DMA_THRESH_MAX_BUF 127
97985 +
97986 +/* BMI defines */
97987 +#define BMI_MAX_NUM_OF_TASKS 64
97988 +#define BMI_MAX_NUM_OF_DMAS 32
97989 +
97990 +#define BMI_MAX_FIFO_SIZE (FM_MURAM_SIZE)
97991 +#define PORT_MAX_WEIGHT 16
97992 +
97993 +#define FM_CHECK_PORT_RESTRICTIONS(__validPorts, __newPortIndx) TRUE
97994 +
97995 +/* Unique T4240 */
97996 +#define FM_OP_OPEN_DMA_MIN_LIMIT
97997 +#define FM_NO_RESTRICT_ON_ACCESS_RSRC
97998 +#define FM_NO_OP_OBSERVED_POOLS
97999 +#define FM_FRAME_END_PARAMS_FOR_OP
98000 +#define FM_DEQ_PIPELINE_PARAMS_FOR_OP
98001 +#define FM_QMI_NO_SINGLE_ECC_EXCEPTION
98002 +
98003 +#define FM_NO_GUARANTEED_RESET_VALUES
98004 +
98005 +/* FM errata */
98006 +#define FM_HEAVY_TRAFFIC_HANG_ERRATA_FMAN_A005669
98007 +#define FM_RX_FIFO_CORRUPT_ERRATA_10GMAC_A006320
98008 +#define FM_OP_NO_VSP_NO_RELEASE_ERRATA_FMAN_A006675
98009 +#define FM_HEAVY_TRAFFIC_SEQUENCER_HANG_ERRATA_FMAN_A006981
98010 +#define FM_HANG_AT_RESET_MAC_CLK_DISABLED_ERRATA_FMAN_A007273
98011 +
98012 +#define FM_BCB_ERRATA_BMI_SW001
98013 +#define FM_LEN_CHECK_ERRATA_FMAN_SW002
98014 +#define FM_AID_MODE_NO_TNUM_SW005 /* refer to pdm TKT068794 - only support of port_id on aid */
98015 +#define FM_ERROR_VSP_NO_MATCH_SW006 /* refer to pdm TKT174304 - no match between errorQ and VSP */
98016 +
98017 +/*****************************************************************************
98018 + RMan INTEGRATION-SPECIFIC DEFINITIONS
98019 +******************************************************************************/
98020 +#define RM_MAX_NUM_OF_IB 4 /**< Number of inbound blocks */
98021 +#define RM_NUM_OF_IBCU 8 /**< NUmber of classification units in an inbound block */
98022 +
98023 +/* RMan erratas */
98024 +#define RM_ERRONEOUS_ACK_ERRATA_RMAN_A006756
98025 +
98026 +/*****************************************************************************
98027 + FM MACSEC INTEGRATION-SPECIFIC DEFINITIONS
98028 +******************************************************************************/
98029 +#define NUM_OF_RX_SC 16
98030 +#define NUM_OF_TX_SC 16
98031 +
98032 +#define NUM_OF_SA_PER_RX_SC 2
98033 +#define NUM_OF_SA_PER_TX_SC 2
98034 +
98035 +#endif /* __DPAA_INTEGRATION_EXT_H */
98036 --- /dev/null
98037 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/integrations/FMANV3L/part_ext.h
98038 @@ -0,0 +1,59 @@
98039 +/*
98040 + * Copyright 2012 Freescale Semiconductor Inc.
98041 + *
98042 + * Redistribution and use in source and binary forms, with or without
98043 + * modification, are permitted provided that the following conditions are met:
98044 + * * Redistributions of source code must retain the above copyright
98045 + * notice, this list of conditions and the following disclaimer.
98046 + * * Redistributions in binary form must reproduce the above copyright
98047 + * notice, this list of conditions and the following disclaimer in the
98048 + * documentation and/or other materials provided with the distribution.
98049 + * * Neither the name of Freescale Semiconductor nor the
98050 + * names of its contributors may be used to endorse or promote products
98051 + * derived from this software without specific prior written permission.
98052 + *
98053 + *
98054 + * ALTERNATIVELY, this software may be distributed under the terms of the
98055 + * GNU General Public License ("GPL") as published by the Free Software
98056 + * Foundation, either version 2 of that License or (at your option) any
98057 + * later version.
98058 + *
98059 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
98060 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
98061 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
98062 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
98063 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
98064 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
98065 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
98066 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
98067 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
98068 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
98069 + */
98070 +
98071 +/**************************************************************************//**
98072 +
98073 + @File part_ext.h
98074 +
98075 + @Description Definitions for the part (integration) module.
98076 +*//***************************************************************************/
98077 +
98078 +#ifndef __PART_EXT_H
98079 +#define __PART_EXT_H
98080 +
98081 +#include "std_ext.h"
98082 +#include "part_integration_ext.h"
98083 +
98084 +/**************************************************************************//*
98085 + @Description Part data structure - must be contained in any integration
98086 + data structure.
98087 +*//***************************************************************************/
98088 +typedef struct t_Part
98089 +{
98090 + uintptr_t (* f_GetModuleBase)(t_Handle h_Part, e_ModuleId moduleId);
98091 + /**< Returns the address of the module's memory map base. */
98092 + e_ModuleId (* f_GetModuleIdByBase)(t_Handle h_Part, uintptr_t baseAddress);
98093 + /**< Returns the module's ID according to its memory map base. */
98094 +} t_Part;
98095 +
98096 +
98097 +#endif /* __PART_EXT_H */
98098 --- /dev/null
98099 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/integrations/FMANV3L/part_integration_ext.h
98100 @@ -0,0 +1,304 @@
98101 +/*
98102 + * Copyright 2008-2012 Freescale Semiconductor Inc.
98103 + *
98104 + * Redistribution and use in source and binary forms, with or without
98105 + * modification, are permitted provided that the following conditions are met:
98106 + * * Redistributions of source code must retain the above copyright
98107 + * notice, this list of conditions and the following disclaimer.
98108 + * * Redistributions in binary form must reproduce the above copyright
98109 + * notice, this list of conditions and the following disclaimer in the
98110 + * documentation and/or other materials provided with the distribution.
98111 + * * Neither the name of Freescale Semiconductor nor the
98112 + * names of its contributors may be used to endorse or promote products
98113 + * derived from this software without specific prior written permission.
98114 + *
98115 + *
98116 + * ALTERNATIVELY, this software may be distributed under the terms of the
98117 + * GNU General Public License ("GPL") as published by the Free Software
98118 + * Foundation, either version 2 of that License or (at your option) any
98119 + * later version.
98120 + *
98121 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
98122 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
98123 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
98124 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
98125 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
98126 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
98127 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
98128 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
98129 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
98130 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
98131 + */
98132 +
98133 +/**
98134 +
98135 + @File part_integration_ext.h
98136 +
98137 + @Description T4240 external definitions and structures.
98138 +*//***************************************************************************/
98139 +#ifndef __PART_INTEGRATION_EXT_H
98140 +#define __PART_INTEGRATION_EXT_H
98141 +
98142 +#include "std_ext.h"
98143 +#include "ddr_std_ext.h"
98144 +#include "enet_ext.h"
98145 +#include "dpaa_integration_ext.h"
98146 +
98147 +
98148 +/**************************************************************************//**
98149 + @Group T4240_chip_id T4240 Application Programming Interface
98150 +
98151 + @Description T4240 Chip functions,definitions and enums.
98152 +
98153 + @{
98154 +*//***************************************************************************/
98155 +
98156 +#define CORE_E6500
98157 +
98158 +#define INTG_MAX_NUM_OF_CORES 24
98159 +
98160 +
98161 +/**************************************************************************//**
98162 + @Description Module types.
98163 +*//***************************************************************************/
98164 +typedef enum e_ModuleId
98165 +{
98166 + e_MODULE_ID_DUART_1 = 0,
98167 + e_MODULE_ID_DUART_2,
98168 + e_MODULE_ID_DUART_3,
98169 + e_MODULE_ID_DUART_4,
98170 + e_MODULE_ID_LAW,
98171 + e_MODULE_ID_IFC,
98172 + e_MODULE_ID_PAMU,
98173 + e_MODULE_ID_QM, /**< Queue manager module */
98174 + e_MODULE_ID_BM, /**< Buffer manager module */
98175 + e_MODULE_ID_QM_CE_PORTAL_0,
98176 + e_MODULE_ID_QM_CI_PORTAL_0,
98177 + e_MODULE_ID_QM_CE_PORTAL_1,
98178 + e_MODULE_ID_QM_CI_PORTAL_1,
98179 + e_MODULE_ID_QM_CE_PORTAL_2,
98180 + e_MODULE_ID_QM_CI_PORTAL_2,
98181 + e_MODULE_ID_QM_CE_PORTAL_3,
98182 + e_MODULE_ID_QM_CI_PORTAL_3,
98183 + e_MODULE_ID_QM_CE_PORTAL_4,
98184 + e_MODULE_ID_QM_CI_PORTAL_4,
98185 + e_MODULE_ID_QM_CE_PORTAL_5,
98186 + e_MODULE_ID_QM_CI_PORTAL_5,
98187 + e_MODULE_ID_QM_CE_PORTAL_6,
98188 + e_MODULE_ID_QM_CI_PORTAL_6,
98189 + e_MODULE_ID_QM_CE_PORTAL_7,
98190 + e_MODULE_ID_QM_CI_PORTAL_7,
98191 + e_MODULE_ID_QM_CE_PORTAL_8,
98192 + e_MODULE_ID_QM_CI_PORTAL_8,
98193 + e_MODULE_ID_QM_CE_PORTAL_9,
98194 + e_MODULE_ID_QM_CI_PORTAL_9,
98195 + e_MODULE_ID_BM_CE_PORTAL_0,
98196 + e_MODULE_ID_BM_CI_PORTAL_0,
98197 + e_MODULE_ID_BM_CE_PORTAL_1,
98198 + e_MODULE_ID_BM_CI_PORTAL_1,
98199 + e_MODULE_ID_BM_CE_PORTAL_2,
98200 + e_MODULE_ID_BM_CI_PORTAL_2,
98201 + e_MODULE_ID_BM_CE_PORTAL_3,
98202 + e_MODULE_ID_BM_CI_PORTAL_3,
98203 + e_MODULE_ID_BM_CE_PORTAL_4,
98204 + e_MODULE_ID_BM_CI_PORTAL_4,
98205 + e_MODULE_ID_BM_CE_PORTAL_5,
98206 + e_MODULE_ID_BM_CI_PORTAL_5,
98207 + e_MODULE_ID_BM_CE_PORTAL_6,
98208 + e_MODULE_ID_BM_CI_PORTAL_6,
98209 + e_MODULE_ID_BM_CE_PORTAL_7,
98210 + e_MODULE_ID_BM_CI_PORTAL_7,
98211 + e_MODULE_ID_BM_CE_PORTAL_8,
98212 + e_MODULE_ID_BM_CI_PORTAL_8,
98213 + e_MODULE_ID_BM_CE_PORTAL_9,
98214 + e_MODULE_ID_BM_CI_PORTAL_9,
98215 + e_MODULE_ID_FM, /**< Frame manager module */
98216 + e_MODULE_ID_FM_RTC, /**< FM Real-Time-Clock */
98217 + e_MODULE_ID_FM_MURAM, /**< FM Multi-User-RAM */
98218 + e_MODULE_ID_FM_BMI, /**< FM BMI block */
98219 + e_MODULE_ID_FM_QMI, /**< FM QMI block */
98220 + e_MODULE_ID_FM_PARSER, /**< FM parser block */
98221 + e_MODULE_ID_FM_PORT_HO1, /**< FM Host-command/offline-parsing port block */
98222 + e_MODULE_ID_FM_PORT_HO2, /**< FM Host-command/offline-parsing port block */
98223 + e_MODULE_ID_FM_PORT_HO3, /**< FM Host-command/offline-parsing port block */
98224 + e_MODULE_ID_FM_PORT_HO4, /**< FM Host-command/offline-parsing port block */
98225 + e_MODULE_ID_FM_PORT_HO5, /**< FM Host-command/offline-parsing port block */
98226 + e_MODULE_ID_FM_PORT_HO6, /**< FM Host-command/offline-parsing port block */
98227 + e_MODULE_ID_FM_PORT_HO7, /**< FM Host-command/offline-parsing port block */
98228 + e_MODULE_ID_FM_PORT_1GRx1, /**< FM Rx 1G MAC port block */
98229 + e_MODULE_ID_FM_PORT_1GRx2, /**< FM Rx 1G MAC port block */
98230 + e_MODULE_ID_FM_PORT_1GRx3, /**< FM Rx 1G MAC port block */
98231 + e_MODULE_ID_FM_PORT_1GRx4, /**< FM Rx 1G MAC port block */
98232 + e_MODULE_ID_FM_PORT_1GRx5, /**< FM Rx 1G MAC port block */
98233 + e_MODULE_ID_FM_PORT_1GRx6, /**< FM Rx 1G MAC port block */
98234 + e_MODULE_ID_FM_PORT_10GRx1, /**< FM Rx 10G MAC port block */
98235 + e_MODULE_ID_FM_PORT_10GRx2, /**< FM Rx 10G MAC port block */
98236 + e_MODULE_ID_FM_PORT_1GTx1, /**< FM Tx 1G MAC port block */
98237 + e_MODULE_ID_FM_PORT_1GTx2, /**< FM Tx 1G MAC port block */
98238 + e_MODULE_ID_FM_PORT_1GTx3, /**< FM Tx 1G MAC port block */
98239 + e_MODULE_ID_FM_PORT_1GTx4, /**< FM Tx 1G MAC port block */
98240 + e_MODULE_ID_FM_PORT_1GTx5, /**< FM Tx 1G MAC port block */
98241 + e_MODULE_ID_FM_PORT_1GTx6, /**< FM Tx 1G MAC port block */
98242 + e_MODULE_ID_FM_PORT_10GTx1, /**< FM Tx 10G MAC port block */
98243 + e_MODULE_ID_FM_PORT_10GTx2, /**< FM Tx 10G MAC port block */
98244 + e_MODULE_ID_FM_PLCR, /**< FM Policer */
98245 + e_MODULE_ID_FM_KG, /**< FM Keygen */
98246 + e_MODULE_ID_FM_DMA, /**< FM DMA */
98247 + e_MODULE_ID_FM_FPM, /**< FM FPM */
98248 + e_MODULE_ID_FM_IRAM, /**< FM Instruction-RAM */
98249 + e_MODULE_ID_FM_1GMDIO, /**< FM 1G MDIO MAC */
98250 + e_MODULE_ID_FM_10GMDIO, /**< FM 10G MDIO */
98251 + e_MODULE_ID_FM_PRS_IRAM, /**< FM SW-parser Instruction-RAM */
98252 + e_MODULE_ID_FM_1GMAC1, /**< FM 1G MAC #1 */
98253 + e_MODULE_ID_FM_1GMAC2, /**< FM 1G MAC #2 */
98254 + e_MODULE_ID_FM_1GMAC3, /**< FM 1G MAC #3 */
98255 + e_MODULE_ID_FM_1GMAC4, /**< FM 1G MAC #4 */
98256 + e_MODULE_ID_FM_1GMAC5, /**< FM 1G MAC #5 */
98257 + e_MODULE_ID_FM_1GMAC6, /**< FM 1G MAC #6 */
98258 + e_MODULE_ID_FM_10GMAC1, /**< FM 10G MAC */
98259 + e_MODULE_ID_FM_10GMAC2, /**< FM 10G MAC */
98260 +
98261 + e_MODULE_ID_SEC_GEN, /**< SEC 4.0 General registers */
98262 + e_MODULE_ID_SEC_QI, /**< SEC 4.0 QI registers */
98263 + e_MODULE_ID_SEC_JQ0, /**< SEC 4.0 JQ-0 registers */
98264 + e_MODULE_ID_SEC_JQ1, /**< SEC 4.0 JQ-1 registers */
98265 + e_MODULE_ID_SEC_JQ2, /**< SEC 4.0 JQ-2 registers */
98266 + e_MODULE_ID_SEC_JQ3, /**< SEC 4.0 JQ-3 registers */
98267 + e_MODULE_ID_SEC_RTIC, /**< SEC 4.0 RTIC registers */
98268 + e_MODULE_ID_SEC_DECO0_CCB0, /**< SEC 4.0 DECO-0/CCB-0 registers */
98269 + e_MODULE_ID_SEC_DECO1_CCB1, /**< SEC 4.0 DECO-1/CCB-1 registers */
98270 + e_MODULE_ID_SEC_DECO2_CCB2, /**< SEC 4.0 DECO-2/CCB-2 registers */
98271 + e_MODULE_ID_SEC_DECO3_CCB3, /**< SEC 4.0 DECO-3/CCB-3 registers */
98272 + e_MODULE_ID_SEC_DECO4_CCB4, /**< SEC 4.0 DECO-4/CCB-4 registers */
98273 +
98274 + e_MODULE_ID_PIC, /**< PIC */
98275 + e_MODULE_ID_GPIO, /**< GPIO */
98276 + e_MODULE_ID_SERDES, /**< SERDES */
98277 + e_MODULE_ID_CPC_1, /**< CoreNet-Platform-Cache 1 */
98278 + e_MODULE_ID_CPC_2, /**< CoreNet-Platform-Cache 2 */
98279 +
98280 + e_MODULE_ID_SRIO_PORTS, /**< RapidIO controller */
98281 +
98282 + e_MODULE_ID_DUMMY_LAST
98283 +} e_ModuleId;
98284 +
98285 +#define NUM_OF_MODULES e_MODULE_ID_DUMMY_LAST
98286 +
98287 +#if 0 /* using unified values */
98288 +/*****************************************************************************
98289 + INTEGRATION-SPECIFIC MODULE CODES
98290 +******************************************************************************/
98291 +#define MODULE_UNKNOWN 0x00000000
98292 +#define MODULE_MEM 0x00010000
98293 +#define MODULE_MM 0x00020000
98294 +#define MODULE_CORE 0x00030000
98295 +#define MODULE_T4240 0x00040000
98296 +#define MODULE_T4240_PLATFORM 0x00050000
98297 +#define MODULE_PM 0x00060000
98298 +#define MODULE_MMU 0x00070000
98299 +#define MODULE_PIC 0x00080000
98300 +#define MODULE_CPC 0x00090000
98301 +#define MODULE_DUART 0x000a0000
98302 +#define MODULE_SERDES 0x000b0000
98303 +#define MODULE_PIO 0x000c0000
98304 +#define MODULE_QM 0x000d0000
98305 +#define MODULE_BM 0x000e0000
98306 +#define MODULE_SEC 0x000f0000
98307 +#define MODULE_LAW 0x00100000
98308 +#define MODULE_LBC 0x00110000
98309 +#define MODULE_PAMU 0x00120000
98310 +#define MODULE_FM 0x00130000
98311 +#define MODULE_FM_MURAM 0x00140000
98312 +#define MODULE_FM_PCD 0x00150000
98313 +#define MODULE_FM_RTC 0x00160000
98314 +#define MODULE_FM_MAC 0x00170000
98315 +#define MODULE_FM_PORT 0x00180000
98316 +#define MODULE_FM_SP 0x00190000
98317 +#define MODULE_DPA_PORT 0x001a0000
98318 +#define MODULE_MII 0x001b0000
98319 +#define MODULE_I2C 0x001c0000
98320 +#define MODULE_DMA 0x001d0000
98321 +#define MODULE_DDR 0x001e0000
98322 +#define MODULE_ESPI 0x001f0000
98323 +#define MODULE_DPAA_IPSEC 0x00200000
98324 +#endif /* using unified values */
98325 +
98326 +/*****************************************************************************
98327 + PAMU INTEGRATION-SPECIFIC DEFINITIONS
98328 +******************************************************************************/
98329 +#define PAMU_NUM_OF_PARTITIONS 4
98330 +
98331 +/*****************************************************************************
98332 + LAW INTEGRATION-SPECIFIC DEFINITIONS
98333 +******************************************************************************/
98334 +#define LAW_NUM_OF_WINDOWS 32
98335 +#define LAW_MIN_WINDOW_SIZE 0x0000000000001000LL /**< 4 Kbytes */
98336 +#define LAW_MAX_WINDOW_SIZE 0x0000010000000000LL /**< 1 Tbytes for 40-bit address space */
98337 +
98338 +
98339 +/*****************************************************************************
98340 + LBC INTEGRATION-SPECIFIC DEFINITIONS
98341 +******************************************************************************/
98342 +/**************************************************************************//**
98343 + @Group lbc_exception_grp LBC Exception Unit
98344 +
98345 + @Description LBC Exception unit API functions, definitions and enums
98346 +
98347 + @{
98348 +*//***************************************************************************/
98349 +
98350 +/**************************************************************************//**
98351 + @Anchor lbc_exbm
98352 +
98353 + @Collection LBC Errors Bit Mask
98354 +
98355 + These errors are reported through the exceptions callback..
98356 + The values can be or'ed in any combination in the errors mask
98357 + parameter of the errors report structure.
98358 +
98359 + These errors can also be passed as a bit-mask to
98360 + LBC_EnableErrorChecking() or LBC_DisableErrorChecking(),
98361 + for enabling or disabling error checking.
98362 + @{
98363 +*//***************************************************************************/
98364 +#define LBC_ERR_BUS_MONITOR 0x80000000 /**< Bus monitor error */
98365 +#define LBC_ERR_PARITY_ECC 0x20000000 /**< Parity error for GPCM/UPM */
98366 +#define LBC_ERR_WRITE_PROTECT 0x04000000 /**< Write protection error */
98367 +#define LBC_ERR_CHIP_SELECT 0x00080000 /**< Unrecognized chip select */
98368 +
98369 +#define LBC_ERR_ALL (LBC_ERR_BUS_MONITOR | LBC_ERR_PARITY_ECC | \
98370 + LBC_ERR_WRITE_PROTECT | LBC_ERR_CHIP_SELECT)
98371 + /**< All possible errors */
98372 +/* @} */
98373 +/** @} */ /* end of lbc_exception_grp group */
98374 +
98375 +#define LBC_INCORRECT_ERROR_REPORT_ERRATA
98376 +
98377 +#define LBC_NUM_OF_BANKS 8
98378 +#define LBC_MAX_CS_SIZE 0x0000000100000000LL /* Up to 4G memory block size */
98379 +#define LBC_PARITY_SUPPORT
98380 +#define LBC_ADDRESS_HOLD_TIME_CTRL
98381 +#define LBC_HIGH_CLK_DIVIDERS
98382 +#define LBC_FCM_AVAILABLE
98383 +
98384 +/*****************************************************************************
98385 + GPIO INTEGRATION-SPECIFIC DEFINITIONS
98386 +******************************************************************************/
98387 +#define GPIO_PORT_OFFSET_0x1000
98388 +
98389 +#define GPIO_NUM_OF_PORTS 3 /**< Number of ports in GPIO module;
98390 + Each port contains up to 32 I/O pins. */
98391 +
98392 +#define GPIO_VALID_PIN_MASKS \
98393 + { /* Port A */ 0xFFFFFFFF, \
98394 + /* Port B */ 0xFFFFFFFF, \
98395 + /* Port C */ 0xFFFFFFFF }
98396 +
98397 +#define GPIO_VALID_INTR_MASKS \
98398 + { /* Port A */ 0xFFFFFFFF, \
98399 + /* Port B */ 0xFFFFFFFF, \
98400 + /* Port C */ 0xFFFFFFFF }
98401 +
98402 +
98403 +
98404 +#endif /* __PART_INTEGRATION_EXT_H */
98405 --- /dev/null
98406 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/integrations/LS1043/dpaa_integration_ext.h
98407 @@ -0,0 +1,291 @@
98408 +/*
98409 + * Copyright 2012 Freescale Semiconductor Inc.
98410 + *
98411 + * Redistribution and use in source and binary forms, with or without
98412 + * modification, are permitted provided that the following conditions are met:
98413 + * * Redistributions of source code must retain the above copyright
98414 + * notice, this list of conditions and the following disclaimer.
98415 + * * Redistributions in binary form must reproduce the above copyright
98416 + * notice, this list of conditions and the following disclaimer in the
98417 + * documentation and/or other materials provided with the distribution.
98418 + * * Neither the name of Freescale Semiconductor nor the
98419 + * names of its contributors may be used to endorse or promote products
98420 + * derived from this software without specific prior written permission.
98421 + *
98422 + *
98423 + * ALTERNATIVELY, this software may be distributed under the terms of the
98424 + * GNU General Public License ("GPL") as published by the Free Software
98425 + * Foundation, either version 2 of that License or (at your option) any
98426 + * later version.
98427 + *
98428 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
98429 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
98430 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
98431 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
98432 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
98433 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
98434 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
98435 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
98436 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
98437 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
98438 + */
98439 +
98440 +/**
98441 +
98442 + @File dpaa_integration_ext.h
98443 +
98444 + @Description T4240 FM external definitions and structures.
98445 +*//***************************************************************************/
98446 +#ifndef __DPAA_INTEGRATION_EXT_H
98447 +#define __DPAA_INTEGRATION_EXT_H
98448 +
98449 +#include "std_ext.h"
98450 +
98451 +
98452 +#define DPAA_VERSION 11
98453 +
98454 +/**************************************************************************//**
98455 + @Description DPAA SW Portals Enumeration.
98456 +*//***************************************************************************/
98457 +typedef enum
98458 +{
98459 + e_DPAA_SWPORTAL0 = 0,
98460 + e_DPAA_SWPORTAL1,
98461 + e_DPAA_SWPORTAL2,
98462 + e_DPAA_SWPORTAL3,
98463 + e_DPAA_SWPORTAL4,
98464 + e_DPAA_SWPORTAL5,
98465 + e_DPAA_SWPORTAL6,
98466 + e_DPAA_SWPORTAL7,
98467 + e_DPAA_SWPORTAL8,
98468 + e_DPAA_SWPORTAL9,
98469 + e_DPAA_SWPORTAL10,
98470 + e_DPAA_SWPORTAL11,
98471 + e_DPAA_SWPORTAL12,
98472 + e_DPAA_SWPORTAL13,
98473 + e_DPAA_SWPORTAL14,
98474 + e_DPAA_SWPORTAL15,
98475 + e_DPAA_SWPORTAL16,
98476 + e_DPAA_SWPORTAL17,
98477 + e_DPAA_SWPORTAL18,
98478 + e_DPAA_SWPORTAL19,
98479 + e_DPAA_SWPORTAL20,
98480 + e_DPAA_SWPORTAL21,
98481 + e_DPAA_SWPORTAL22,
98482 + e_DPAA_SWPORTAL23,
98483 + e_DPAA_SWPORTAL24,
98484 + e_DPAA_SWPORTAL_DUMMY_LAST
98485 +} e_DpaaSwPortal;
98486 +
98487 +/**************************************************************************//**
98488 + @Description DPAA Direct Connect Portals Enumeration.
98489 +*//***************************************************************************/
98490 +typedef enum
98491 +{
98492 + e_DPAA_DCPORTAL0 = 0,
98493 + e_DPAA_DCPORTAL1,
98494 + e_DPAA_DCPORTAL2,
98495 + e_DPAA_DCPORTAL_DUMMY_LAST
98496 +} e_DpaaDcPortal;
98497 +
98498 +#define DPAA_MAX_NUM_OF_SW_PORTALS e_DPAA_SWPORTAL_DUMMY_LAST
98499 +#define DPAA_MAX_NUM_OF_DC_PORTALS e_DPAA_DCPORTAL_DUMMY_LAST
98500 +
98501 +/*****************************************************************************
98502 + QMan INTEGRATION-SPECIFIC DEFINITIONS
98503 +******************************************************************************/
98504 +#define QM_MAX_NUM_OF_POOL_CHANNELS 15 /**< Total number of channels, dedicated and pool */
98505 +#define QM_MAX_NUM_OF_WQ 8 /**< Number of work queues per channel */
98506 +#define QM_MAX_NUM_OF_CGS 256 /**< Congestion groups number */
98507 +#define QM_MAX_NUM_OF_FQIDS (16 * MEGABYTE)
98508 + /**< FQIDs range - 24 bits */
98509 +
98510 +/**************************************************************************//**
98511 + @Description Work Queue Channel assignments in QMan.
98512 +*//***************************************************************************/
98513 +typedef enum
98514 +{
98515 + e_QM_FQ_CHANNEL_SWPORTAL0 = 0x0, /**< Dedicated channels serviced by software portals 0 to 24 */
98516 + e_QM_FQ_CHANNEL_SWPORTAL1,
98517 + e_QM_FQ_CHANNEL_SWPORTAL2,
98518 + e_QM_FQ_CHANNEL_SWPORTAL3,
98519 + e_QM_FQ_CHANNEL_SWPORTAL4,
98520 + e_QM_FQ_CHANNEL_SWPORTAL5,
98521 + e_QM_FQ_CHANNEL_SWPORTAL6,
98522 + e_QM_FQ_CHANNEL_SWPORTAL7,
98523 + e_QM_FQ_CHANNEL_SWPORTAL8,
98524 + e_QM_FQ_CHANNEL_SWPORTAL9,
98525 + e_QM_FQ_CHANNEL_SWPORTAL10,
98526 + e_QM_FQ_CHANNEL_SWPORTAL11,
98527 + e_QM_FQ_CHANNEL_SWPORTAL12,
98528 + e_QM_FQ_CHANNEL_SWPORTAL13,
98529 + e_QM_FQ_CHANNEL_SWPORTAL14,
98530 + e_QM_FQ_CHANNEL_SWPORTAL15,
98531 + e_QM_FQ_CHANNEL_SWPORTAL16,
98532 + e_QM_FQ_CHANNEL_SWPORTAL17,
98533 + e_QM_FQ_CHANNEL_SWPORTAL18,
98534 + e_QM_FQ_CHANNEL_SWPORTAL19,
98535 + e_QM_FQ_CHANNEL_SWPORTAL20,
98536 + e_QM_FQ_CHANNEL_SWPORTAL21,
98537 + e_QM_FQ_CHANNEL_SWPORTAL22,
98538 + e_QM_FQ_CHANNEL_SWPORTAL23,
98539 + e_QM_FQ_CHANNEL_SWPORTAL24,
98540 +
98541 + e_QM_FQ_CHANNEL_POOL1 = 0x401, /**< Pool channels that can be serviced by any of the software portals */
98542 + e_QM_FQ_CHANNEL_POOL2,
98543 + e_QM_FQ_CHANNEL_POOL3,
98544 + e_QM_FQ_CHANNEL_POOL4,
98545 + e_QM_FQ_CHANNEL_POOL5,
98546 + e_QM_FQ_CHANNEL_POOL6,
98547 + e_QM_FQ_CHANNEL_POOL7,
98548 + e_QM_FQ_CHANNEL_POOL8,
98549 + e_QM_FQ_CHANNEL_POOL9,
98550 + e_QM_FQ_CHANNEL_POOL10,
98551 + e_QM_FQ_CHANNEL_POOL11,
98552 + e_QM_FQ_CHANNEL_POOL12,
98553 + e_QM_FQ_CHANNEL_POOL13,
98554 + e_QM_FQ_CHANNEL_POOL14,
98555 + e_QM_FQ_CHANNEL_POOL15,
98556 +
98557 + e_QM_FQ_CHANNEL_FMAN0_SP0 = 0x800, /**< Dedicated channels serviced by Direct Connect Portal 0:
98558 + connected to FMan 0; assigned in incrementing order to
98559 + each sub-portal (SP) in the portal */
98560 + e_QM_FQ_CHANNEL_FMAN0_SP1,
98561 + e_QM_FQ_CHANNEL_FMAN0_SP2,
98562 + e_QM_FQ_CHANNEL_FMAN0_SP3,
98563 + e_QM_FQ_CHANNEL_FMAN0_SP4,
98564 + e_QM_FQ_CHANNEL_FMAN0_SP5,
98565 + e_QM_FQ_CHANNEL_FMAN0_SP6,
98566 + e_QM_FQ_CHANNEL_FMAN0_SP7,
98567 + e_QM_FQ_CHANNEL_FMAN0_SP8,
98568 + e_QM_FQ_CHANNEL_FMAN0_SP9,
98569 + e_QM_FQ_CHANNEL_FMAN0_SP10,
98570 + e_QM_FQ_CHANNEL_FMAN0_SP11,
98571 + e_QM_FQ_CHANNEL_FMAN0_SP12,
98572 + e_QM_FQ_CHANNEL_FMAN0_SP13,
98573 + e_QM_FQ_CHANNEL_FMAN0_SP14,
98574 + e_QM_FQ_CHANNEL_FMAN0_SP15,
98575 +
98576 + e_QM_FQ_CHANNEL_RMAN_SP0 = 0x820, /**< Dedicated channels serviced by Direct Connect Portal 1: connected to RMan */
98577 + e_QM_FQ_CHANNEL_RMAN_SP1,
98578 +
98579 + e_QM_FQ_CHANNEL_CAAM = 0x840 /**< Dedicated channel serviced by Direct Connect Portal 2:
98580 + connected to SEC */
98581 +} e_QmFQChannel;
98582 +
98583 +/*****************************************************************************
98584 + BMan INTEGRATION-SPECIFIC DEFINITIONS
98585 +******************************************************************************/
98586 +#define BM_MAX_NUM_OF_POOLS 64 /**< Number of buffers pools */
98587 +
98588 +/*****************************************************************************
98589 + SEC INTEGRATION-SPECIFIC DEFINITIONS
98590 +******************************************************************************/
98591 +#define SEC_NUM_OF_DECOS 3
98592 +#define SEC_ALL_DECOS_MASK 0x00000003
98593 +
98594 +
98595 +/*****************************************************************************
98596 + FM INTEGRATION-SPECIFIC DEFINITIONS
98597 +******************************************************************************/
98598 +#define INTG_MAX_NUM_OF_FM 2
98599 +
98600 +/* Ports defines */
98601 +#define FM_MAX_NUM_OF_1G_MACS 6
98602 +#define FM_MAX_NUM_OF_10G_MACS 2
98603 +#define FM_MAX_NUM_OF_MACS (FM_MAX_NUM_OF_1G_MACS + FM_MAX_NUM_OF_10G_MACS)
98604 +#define FM_MAX_NUM_OF_OH_PORTS 6
98605 +
98606 +#define FM_MAX_NUM_OF_1G_RX_PORTS FM_MAX_NUM_OF_1G_MACS
98607 +#define FM_MAX_NUM_OF_10G_RX_PORTS FM_MAX_NUM_OF_10G_MACS
98608 +#define FM_MAX_NUM_OF_RX_PORTS (FM_MAX_NUM_OF_10G_RX_PORTS + FM_MAX_NUM_OF_1G_RX_PORTS)
98609 +
98610 +#define FM_MAX_NUM_OF_1G_TX_PORTS FM_MAX_NUM_OF_1G_MACS
98611 +#define FM_MAX_NUM_OF_10G_TX_PORTS FM_MAX_NUM_OF_10G_MACS
98612 +#define FM_MAX_NUM_OF_TX_PORTS (FM_MAX_NUM_OF_10G_TX_PORTS + FM_MAX_NUM_OF_1G_TX_PORTS)
98613 +
98614 +#define FM_PORT_MAX_NUM_OF_EXT_POOLS 4 /**< Number of external BM pools per Rx port */
98615 +#define FM_PORT_NUM_OF_CONGESTION_GRPS 256 /**< Total number of congestion groups in QM */
98616 +#define FM_MAX_NUM_OF_SUB_PORTALS 16
98617 +#define FM_PORT_MAX_NUM_OF_OBSERVED_EXT_POOLS 0
98618 +
98619 +#define FM_VSP_MAX_NUM_OF_ENTRIES 64
98620 +#define FM_MAX_NUM_OF_PFC_PRIORITIES 8
98621 +
98622 +/* RAMs defines */
98623 +#define FM_MURAM_SIZE (384 * KILOBYTE)
98624 +#define FM_IRAM_SIZE(major, minor) (64 * KILOBYTE)
98625 +#define FM_NUM_OF_CTRL 4
98626 +
98627 +/* PCD defines */
98628 +#define FM_PCD_PLCR_NUM_ENTRIES 256 /**< Total number of policer profiles */
98629 +#define FM_PCD_KG_NUM_OF_SCHEMES 32 /**< Total number of KG schemes */
98630 +#define FM_PCD_MAX_NUM_OF_CLS_PLANS 256 /**< Number of classification plan entries. */
98631 +#define FM_PCD_PRS_SW_PATCHES_SIZE 0x00000600 /**< Number of bytes saved for patches */
98632 +#define FM_PCD_SW_PRS_SIZE 0x00000800 /**< Total size of SW parser area */
98633 +
98634 +/* RTC defines */
98635 +#define FM_RTC_NUM_OF_ALARMS 2 /**< RTC number of alarms */
98636 +#define FM_RTC_NUM_OF_PERIODIC_PULSES 3 /**< RTC number of periodic pulses */
98637 +#define FM_RTC_NUM_OF_EXT_TRIGGERS 2 /**< RTC number of external triggers */
98638 +
98639 +/* QMI defines */
98640 +#define QMI_MAX_NUM_OF_TNUMS 64
98641 +#define QMI_DEF_TNUMS_THRESH 32
98642 +/* FPM defines */
98643 +#define FM_NUM_OF_FMAN_CTRL_EVENT_REGS 4
98644 +
98645 +/* DMA defines */
98646 +#define DMA_THRESH_MAX_COMMQ 83
98647 +#define DMA_THRESH_MAX_BUF 127
98648 +
98649 +/* BMI defines */
98650 +#define BMI_MAX_NUM_OF_TASKS 128
98651 +#define BMI_MAX_NUM_OF_DMAS 84
98652 +
98653 +#define BMI_MAX_FIFO_SIZE (FM_MURAM_SIZE)
98654 +#define PORT_MAX_WEIGHT 16
98655 +
98656 +#define FM_CHECK_PORT_RESTRICTIONS(__validPorts, __newPortIndx) TRUE
98657 +
98658 +/* Unique T4240 */
98659 +#define FM_OP_OPEN_DMA_MIN_LIMIT
98660 +#define FM_NO_RESTRICT_ON_ACCESS_RSRC
98661 +#define FM_NO_OP_OBSERVED_POOLS
98662 +#define FM_FRAME_END_PARAMS_FOR_OP
98663 +#define FM_DEQ_PIPELINE_PARAMS_FOR_OP
98664 +#define FM_QMI_NO_SINGLE_ECC_EXCEPTION
98665 +
98666 +#define FM_NO_GUARANTEED_RESET_VALUES
98667 +
98668 +/* FM errata */
98669 +#define FM_HEAVY_TRAFFIC_HANG_ERRATA_FMAN_A005669
98670 +#define FM_WRONG_RESET_VALUES_ERRATA_FMAN_A005127
98671 +#define FM_RX_FIFO_CORRUPT_ERRATA_10GMAC_A006320
98672 +#define FM_OP_NO_VSP_NO_RELEASE_ERRATA_FMAN_A006675
98673 +#define FM_HEAVY_TRAFFIC_SEQUENCER_HANG_ERRATA_FMAN_A006981
98674 +
98675 +#define FM_BCB_ERRATA_BMI_SW001
98676 +#define FM_LEN_CHECK_ERRATA_FMAN_SW002
98677 +#define FM_AID_MODE_NO_TNUM_SW005 /* refer to pdm TKT068794 - only support of port_id on aid */
98678 +#define FM_ERROR_VSP_NO_MATCH_SW006 /* refer to pdm TKT174304 - no match between errorQ and VSP */
98679 +
98680 +/*****************************************************************************
98681 + RMan INTEGRATION-SPECIFIC DEFINITIONS
98682 +******************************************************************************/
98683 +#define RM_MAX_NUM_OF_IB 4 /**< Number of inbound blocks */
98684 +#define RM_NUM_OF_IBCU 8 /**< NUmber of classification units in an inbound block */
98685 +
98686 +/* RMan erratas */
98687 +#define RM_ERRONEOUS_ACK_ERRATA_RMAN_A006756
98688 +
98689 +/*****************************************************************************
98690 + FM MACSEC INTEGRATION-SPECIFIC DEFINITIONS
98691 +******************************************************************************/
98692 +#define NUM_OF_RX_SC 16
98693 +#define NUM_OF_TX_SC 16
98694 +
98695 +#define NUM_OF_SA_PER_RX_SC 2
98696 +#define NUM_OF_SA_PER_TX_SC 2
98697 +
98698 +#endif /* __DPAA_INTEGRATION_EXT_H */
98699 --- /dev/null
98700 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/integrations/LS1043/part_ext.h
98701 @@ -0,0 +1,64 @@
98702 +/*
98703 + * Copyright 2012 Freescale Semiconductor Inc.
98704 + *
98705 + * Redistribution and use in source and binary forms, with or without
98706 + * modification, are permitted provided that the following conditions are met:
98707 + * * Redistributions of source code must retain the above copyright
98708 + * notice, this list of conditions and the following disclaimer.
98709 + * * Redistributions in binary form must reproduce the above copyright
98710 + * notice, this list of conditions and the following disclaimer in the
98711 + * documentation and/or other materials provided with the distribution.
98712 + * * Neither the name of Freescale Semiconductor nor the
98713 + * names of its contributors may be used to endorse or promote products
98714 + * derived from this software without specific prior written permission.
98715 + *
98716 + *
98717 + * ALTERNATIVELY, this software may be distributed under the terms of the
98718 + * GNU General Public License ("GPL") as published by the Free Software
98719 + * Foundation, either version 2 of that License or (at your option) any
98720 + * later version.
98721 + *
98722 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
98723 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
98724 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
98725 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
98726 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
98727 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
98728 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
98729 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
98730 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
98731 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
98732 + */
98733 +
98734 +/**************************************************************************//**
98735 +
98736 + @File part_ext.h
98737 +
98738 + @Description Definitions for the part (integration) module.
98739 +*//***************************************************************************/
98740 +
98741 +#ifndef __PART_EXT_H
98742 +#define __PART_EXT_H
98743 +
98744 +#include "std_ext.h"
98745 +#include "part_integration_ext.h"
98746 +
98747 +#if !(defined(LS1043))
98748 +#error "unable to proceed without chip-definition"
98749 +#endif
98750 +
98751 +
98752 +/**************************************************************************//*
98753 + @Description Part data structure - must be contained in any integration
98754 + data structure.
98755 +*//***************************************************************************/
98756 +typedef struct t_Part
98757 +{
98758 + uintptr_t (* f_GetModuleBase)(t_Handle h_Part, e_ModuleId moduleId);
98759 + /**< Returns the address of the module's memory map base. */
98760 + e_ModuleId (* f_GetModuleIdByBase)(t_Handle h_Part, uintptr_t baseAddress);
98761 + /**< Returns the module's ID according to its memory map base. */
98762 +} t_Part;
98763 +
98764 +
98765 +#endif /* __PART_EXT_H */
98766 --- /dev/null
98767 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/integrations/LS1043/part_integration_ext.h
98768 @@ -0,0 +1,185 @@
98769 +/*
98770 + * Copyright 2008-2012 Freescale Semiconductor Inc.
98771 + *
98772 + * Redistribution and use in source and binary forms, with or without
98773 + * modification, are permitted provided that the following conditions are met:
98774 + * * Redistributions of source code must retain the above copyright
98775 + * notice, this list of conditions and the following disclaimer.
98776 + * * Redistributions in binary form must reproduce the above copyright
98777 + * notice, this list of conditions and the following disclaimer in the
98778 + * documentation and/or other materials provided with the distribution.
98779 + * * Neither the name of Freescale Semiconductor nor the
98780 + * names of its contributors may be used to endorse or promote products
98781 + * derived from this software without specific prior written permission.
98782 + *
98783 + *
98784 + * ALTERNATIVELY, this software may be distributed under the terms of the
98785 + * GNU General Public License ("GPL") as published by the Free Software
98786 + * Foundation, either version 2 of that License or (at your option) any
98787 + * later version.
98788 + *
98789 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
98790 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
98791 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
98792 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
98793 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
98794 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
98795 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
98796 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
98797 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
98798 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
98799 + */
98800 +
98801 +/**
98802 +
98803 + @File part_integration_ext.h
98804 +
98805 + @Description T4240 external definitions and structures.
98806 +*//***************************************************************************/
98807 +#ifndef __PART_INTEGRATION_EXT_H
98808 +#define __PART_INTEGRATION_EXT_H
98809 +
98810 +#include "std_ext.h"
98811 +#include "ddr_std_ext.h"
98812 +#include "enet_ext.h"
98813 +#include "dpaa_integration_ext.h"
98814 +
98815 +
98816 +/**************************************************************************//**
98817 + @Group T4240_chip_id T4240 Application Programming Interface
98818 +
98819 + @Description T4240 Chip functions,definitions and enums.
98820 +
98821 + @{
98822 +*//***************************************************************************/
98823 +
98824 +#define INTG_MAX_NUM_OF_CORES 4
98825 +
98826 +/**************************************************************************//**
98827 + @Description Module types.
98828 +*//***************************************************************************/
98829 +typedef enum e_ModuleId
98830 +{
98831 + e_MODULE_ID_DUART_1 = 0,
98832 + e_MODULE_ID_DUART_2,
98833 + e_MODULE_ID_DUART_3,
98834 + e_MODULE_ID_DUART_4,
98835 + e_MODULE_ID_LAW,
98836 + e_MODULE_ID_IFC,
98837 + e_MODULE_ID_PAMU,
98838 + e_MODULE_ID_QM, /**< Queue manager module */
98839 + e_MODULE_ID_BM, /**< Buffer manager module */
98840 + e_MODULE_ID_QM_CE_PORTAL_0,
98841 + e_MODULE_ID_QM_CI_PORTAL_0,
98842 + e_MODULE_ID_QM_CE_PORTAL_1,
98843 + e_MODULE_ID_QM_CI_PORTAL_1,
98844 + e_MODULE_ID_QM_CE_PORTAL_2,
98845 + e_MODULE_ID_QM_CI_PORTAL_2,
98846 + e_MODULE_ID_QM_CE_PORTAL_3,
98847 + e_MODULE_ID_QM_CI_PORTAL_3,
98848 + e_MODULE_ID_QM_CE_PORTAL_4,
98849 + e_MODULE_ID_QM_CI_PORTAL_4,
98850 + e_MODULE_ID_QM_CE_PORTAL_5,
98851 + e_MODULE_ID_QM_CI_PORTAL_5,
98852 + e_MODULE_ID_QM_CE_PORTAL_6,
98853 + e_MODULE_ID_QM_CI_PORTAL_6,
98854 + e_MODULE_ID_QM_CE_PORTAL_7,
98855 + e_MODULE_ID_QM_CI_PORTAL_7,
98856 + e_MODULE_ID_QM_CE_PORTAL_8,
98857 + e_MODULE_ID_QM_CI_PORTAL_8,
98858 + e_MODULE_ID_QM_CE_PORTAL_9,
98859 + e_MODULE_ID_QM_CI_PORTAL_9,
98860 + e_MODULE_ID_BM_CE_PORTAL_0,
98861 + e_MODULE_ID_BM_CI_PORTAL_0,
98862 + e_MODULE_ID_BM_CE_PORTAL_1,
98863 + e_MODULE_ID_BM_CI_PORTAL_1,
98864 + e_MODULE_ID_BM_CE_PORTAL_2,
98865 + e_MODULE_ID_BM_CI_PORTAL_2,
98866 + e_MODULE_ID_BM_CE_PORTAL_3,
98867 + e_MODULE_ID_BM_CI_PORTAL_3,
98868 + e_MODULE_ID_BM_CE_PORTAL_4,
98869 + e_MODULE_ID_BM_CI_PORTAL_4,
98870 + e_MODULE_ID_BM_CE_PORTAL_5,
98871 + e_MODULE_ID_BM_CI_PORTAL_5,
98872 + e_MODULE_ID_BM_CE_PORTAL_6,
98873 + e_MODULE_ID_BM_CI_PORTAL_6,
98874 + e_MODULE_ID_BM_CE_PORTAL_7,
98875 + e_MODULE_ID_BM_CI_PORTAL_7,
98876 + e_MODULE_ID_BM_CE_PORTAL_8,
98877 + e_MODULE_ID_BM_CI_PORTAL_8,
98878 + e_MODULE_ID_BM_CE_PORTAL_9,
98879 + e_MODULE_ID_BM_CI_PORTAL_9,
98880 + e_MODULE_ID_FM, /**< Frame manager module */
98881 + e_MODULE_ID_FM_RTC, /**< FM Real-Time-Clock */
98882 + e_MODULE_ID_FM_MURAM, /**< FM Multi-User-RAM */
98883 + e_MODULE_ID_FM_BMI, /**< FM BMI block */
98884 + e_MODULE_ID_FM_QMI, /**< FM QMI block */
98885 + e_MODULE_ID_FM_PARSER, /**< FM parser block */
98886 + e_MODULE_ID_FM_PORT_HO1, /**< FM Host-command/offline-parsing port block */
98887 + e_MODULE_ID_FM_PORT_HO2, /**< FM Host-command/offline-parsing port block */
98888 + e_MODULE_ID_FM_PORT_HO3, /**< FM Host-command/offline-parsing port block */
98889 + e_MODULE_ID_FM_PORT_HO4, /**< FM Host-command/offline-parsing port block */
98890 + e_MODULE_ID_FM_PORT_HO5, /**< FM Host-command/offline-parsing port block */
98891 + e_MODULE_ID_FM_PORT_HO6, /**< FM Host-command/offline-parsing port block */
98892 + e_MODULE_ID_FM_PORT_HO7, /**< FM Host-command/offline-parsing port block */
98893 + e_MODULE_ID_FM_PORT_1GRx1, /**< FM Rx 1G MAC port block */
98894 + e_MODULE_ID_FM_PORT_1GRx2, /**< FM Rx 1G MAC port block */
98895 + e_MODULE_ID_FM_PORT_1GRx3, /**< FM Rx 1G MAC port block */
98896 + e_MODULE_ID_FM_PORT_1GRx4, /**< FM Rx 1G MAC port block */
98897 + e_MODULE_ID_FM_PORT_1GRx5, /**< FM Rx 1G MAC port block */
98898 + e_MODULE_ID_FM_PORT_1GRx6, /**< FM Rx 1G MAC port block */
98899 + e_MODULE_ID_FM_PORT_10GRx1, /**< FM Rx 10G MAC port block */
98900 + e_MODULE_ID_FM_PORT_10GRx2, /**< FM Rx 10G MAC port block */
98901 + e_MODULE_ID_FM_PORT_1GTx1, /**< FM Tx 1G MAC port block */
98902 + e_MODULE_ID_FM_PORT_1GTx2, /**< FM Tx 1G MAC port block */
98903 + e_MODULE_ID_FM_PORT_1GTx3, /**< FM Tx 1G MAC port block */
98904 + e_MODULE_ID_FM_PORT_1GTx4, /**< FM Tx 1G MAC port block */
98905 + e_MODULE_ID_FM_PORT_1GTx5, /**< FM Tx 1G MAC port block */
98906 + e_MODULE_ID_FM_PORT_1GTx6, /**< FM Tx 1G MAC port block */
98907 + e_MODULE_ID_FM_PORT_10GTx1, /**< FM Tx 10G MAC port block */
98908 + e_MODULE_ID_FM_PORT_10GTx2, /**< FM Tx 10G MAC port block */
98909 + e_MODULE_ID_FM_PLCR, /**< FM Policer */
98910 + e_MODULE_ID_FM_KG, /**< FM Keygen */
98911 + e_MODULE_ID_FM_DMA, /**< FM DMA */
98912 + e_MODULE_ID_FM_FPM, /**< FM FPM */
98913 + e_MODULE_ID_FM_IRAM, /**< FM Instruction-RAM */
98914 + e_MODULE_ID_FM_1GMDIO, /**< FM 1G MDIO MAC */
98915 + e_MODULE_ID_FM_10GMDIO, /**< FM 10G MDIO */
98916 + e_MODULE_ID_FM_PRS_IRAM, /**< FM SW-parser Instruction-RAM */
98917 + e_MODULE_ID_FM_1GMAC1, /**< FM 1G MAC #1 */
98918 + e_MODULE_ID_FM_1GMAC2, /**< FM 1G MAC #2 */
98919 + e_MODULE_ID_FM_1GMAC3, /**< FM 1G MAC #3 */
98920 + e_MODULE_ID_FM_1GMAC4, /**< FM 1G MAC #4 */
98921 + e_MODULE_ID_FM_1GMAC5, /**< FM 1G MAC #5 */
98922 + e_MODULE_ID_FM_1GMAC6, /**< FM 1G MAC #6 */
98923 + e_MODULE_ID_FM_10GMAC1, /**< FM 10G MAC */
98924 + e_MODULE_ID_FM_10GMAC2, /**< FM 10G MAC */
98925 +
98926 + e_MODULE_ID_SEC_GEN, /**< SEC 4.0 General registers */
98927 + e_MODULE_ID_SEC_QI, /**< SEC 4.0 QI registers */
98928 + e_MODULE_ID_SEC_JQ0, /**< SEC 4.0 JQ-0 registers */
98929 + e_MODULE_ID_SEC_JQ1, /**< SEC 4.0 JQ-1 registers */
98930 + e_MODULE_ID_SEC_JQ2, /**< SEC 4.0 JQ-2 registers */
98931 + e_MODULE_ID_SEC_JQ3, /**< SEC 4.0 JQ-3 registers */
98932 + e_MODULE_ID_SEC_RTIC, /**< SEC 4.0 RTIC registers */
98933 + e_MODULE_ID_SEC_DECO0_CCB0, /**< SEC 4.0 DECO-0/CCB-0 registers */
98934 + e_MODULE_ID_SEC_DECO1_CCB1, /**< SEC 4.0 DECO-1/CCB-1 registers */
98935 + e_MODULE_ID_SEC_DECO2_CCB2, /**< SEC 4.0 DECO-2/CCB-2 registers */
98936 + e_MODULE_ID_SEC_DECO3_CCB3, /**< SEC 4.0 DECO-3/CCB-3 registers */
98937 + e_MODULE_ID_SEC_DECO4_CCB4, /**< SEC 4.0 DECO-4/CCB-4 registers */
98938 +
98939 + e_MODULE_ID_PIC, /**< PIC */
98940 + e_MODULE_ID_GPIO, /**< GPIO */
98941 + e_MODULE_ID_SERDES, /**< SERDES */
98942 + e_MODULE_ID_CPC_1, /**< CoreNet-Platform-Cache 1 */
98943 + e_MODULE_ID_CPC_2, /**< CoreNet-Platform-Cache 2 */
98944 +
98945 + e_MODULE_ID_SRIO_PORTS, /**< RapidIO controller */
98946 +
98947 + e_MODULE_ID_DUMMY_LAST
98948 +} e_ModuleId;
98949 +
98950 +#define NUM_OF_MODULES e_MODULE_ID_DUMMY_LAST
98951 +
98952 +
98953 +#endif /* __PART_INTEGRATION_EXT_H */
98954 --- /dev/null
98955 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/integrations/P1023/dpaa_integration_ext.h
98956 @@ -0,0 +1,213 @@
98957 +/*
98958 + * Copyright 2008-2012 Freescale Semiconductor Inc.
98959 + *
98960 + * Redistribution and use in source and binary forms, with or without
98961 + * modification, are permitted provided that the following conditions are met:
98962 + * * Redistributions of source code must retain the above copyright
98963 + * notice, this list of conditions and the following disclaimer.
98964 + * * Redistributions in binary form must reproduce the above copyright
98965 + * notice, this list of conditions and the following disclaimer in the
98966 + * documentation and/or other materials provided with the distribution.
98967 + * * Neither the name of Freescale Semiconductor nor the
98968 + * names of its contributors may be used to endorse or promote products
98969 + * derived from this software without specific prior written permission.
98970 + *
98971 + *
98972 + * ALTERNATIVELY, this software may be distributed under the terms of the
98973 + * GNU General Public License ("GPL") as published by the Free Software
98974 + * Foundation, either version 2 of that License or (at your option) any
98975 + * later version.
98976 + *
98977 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
98978 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
98979 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
98980 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
98981 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
98982 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
98983 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
98984 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
98985 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
98986 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
98987 + */
98988 +
98989 +
98990 +/**
98991 +
98992 + @File dpaa_integration_ext.h
98993 +
98994 + @Description P1023 FM external definitions and structures.
98995 +*//***************************************************************************/
98996 +#ifndef __DPAA_INTEGRATION_EXT_H
98997 +#define __DPAA_INTEGRATION_EXT_H
98998 +
98999 +#include "std_ext.h"
99000 +
99001 +
99002 +#define DPAA_VERSION 10
99003 +
99004 +typedef enum e_DpaaSwPortal {
99005 + e_DPAA_SWPORTAL0 = 0,
99006 + e_DPAA_SWPORTAL1,
99007 + e_DPAA_SWPORTAL2,
99008 + e_DPAA_SWPORTAL_DUMMY_LAST
99009 +} e_DpaaSwPortal;
99010 +
99011 +typedef enum {
99012 + e_DPAA_DCPORTAL0 = 0,
99013 + e_DPAA_DCPORTAL2,
99014 + e_DPAA_DCPORTAL_DUMMY_LAST
99015 +} e_DpaaDcPortal;
99016 +
99017 +#define DPAA_MAX_NUM_OF_SW_PORTALS e_DPAA_SWPORTAL_DUMMY_LAST
99018 +#define DPAA_MAX_NUM_OF_DC_PORTALS e_DPAA_DCPORTAL_DUMMY_LAST
99019 +
99020 +/*****************************************************************************
99021 + QMAN INTEGRATION-SPECIFIC DEFINITIONS
99022 +******************************************************************************/
99023 +#define QM_MAX_NUM_OF_POOL_CHANNELS 3
99024 +#define QM_MAX_NUM_OF_WQ 8
99025 +#define QM_MAX_NUM_OF_SWP_AS 2
99026 +#define QM_MAX_NUM_OF_CGS 64
99027 +#define QM_MAX_NUM_OF_FQIDS (16*MEGABYTE)
99028 +
99029 +typedef enum {
99030 + e_QM_FQ_CHANNEL_SWPORTAL0 = 0,
99031 + e_QM_FQ_CHANNEL_SWPORTAL1,
99032 + e_QM_FQ_CHANNEL_SWPORTAL2,
99033 +
99034 + e_QM_FQ_CHANNEL_POOL1 = 0x21,
99035 + e_QM_FQ_CHANNEL_POOL2,
99036 + e_QM_FQ_CHANNEL_POOL3,
99037 +
99038 + e_QM_FQ_CHANNEL_FMAN0_SP0 = 0x40,
99039 + e_QM_FQ_CHANNEL_FMAN0_SP1,
99040 + e_QM_FQ_CHANNEL_FMAN0_SP2,
99041 + e_QM_FQ_CHANNEL_FMAN0_SP3,
99042 + e_QM_FQ_CHANNEL_FMAN0_SP4,
99043 + e_QM_FQ_CHANNEL_FMAN0_SP5,
99044 + e_QM_FQ_CHANNEL_FMAN0_SP6,
99045 +
99046 +
99047 + e_QM_FQ_CHANNEL_CAAM = 0x80
99048 +} e_QmFQChannel;
99049 +
99050 +/*****************************************************************************
99051 + BMAN INTEGRATION-SPECIFIC DEFINITIONS
99052 +******************************************************************************/
99053 +#define BM_MAX_NUM_OF_POOLS 8
99054 +
99055 +/*****************************************************************************
99056 + SEC INTEGRATION-SPECIFIC DEFINITIONS
99057 +******************************************************************************/
99058 +#define SEC_NUM_OF_DECOS 2
99059 +#define SEC_ALL_DECOS_MASK 0x00000003
99060 +#define SEC_RNGB
99061 +#define SEC_NO_ESP_TRAILER_REMOVAL
99062 +
99063 +/*****************************************************************************
99064 + FM INTEGRATION-SPECIFIC DEFINITIONS
99065 +******************************************************************************/
99066 +#define INTG_MAX_NUM_OF_FM 1
99067 +
99068 +/* Ports defines */
99069 +#define FM_MAX_NUM_OF_1G_MACS 2
99070 +#define FM_MAX_NUM_OF_10G_MACS 0
99071 +#define FM_MAX_NUM_OF_MACS (FM_MAX_NUM_OF_1G_MACS + FM_MAX_NUM_OF_10G_MACS)
99072 +#define FM_MAX_NUM_OF_OH_PORTS 5
99073 +
99074 +#define FM_MAX_NUM_OF_1G_RX_PORTS FM_MAX_NUM_OF_1G_MACS
99075 +#define FM_MAX_NUM_OF_10G_RX_PORTS FM_MAX_NUM_OF_10G_MACS
99076 +#define FM_MAX_NUM_OF_RX_PORTS (FM_MAX_NUM_OF_10G_RX_PORTS + FM_MAX_NUM_OF_1G_RX_PORTS)
99077 +
99078 +#define FM_MAX_NUM_OF_1G_TX_PORTS FM_MAX_NUM_OF_1G_MACS
99079 +#define FM_MAX_NUM_OF_10G_TX_PORTS FM_MAX_NUM_OF_10G_MACS
99080 +#define FM_MAX_NUM_OF_TX_PORTS (FM_MAX_NUM_OF_10G_TX_PORTS + FM_MAX_NUM_OF_1G_TX_PORTS)
99081 +
99082 +#define FM_MAX_NUM_OF_MACSECS 1
99083 +
99084 +#define FM_MACSEC_SUPPORT
99085 +
99086 +#define FM_LOW_END_RESTRICTION /* prevents the use of TX port 1 with OP port 0 */
99087 +
99088 +#define FM_PORT_MAX_NUM_OF_EXT_POOLS 4 /**< Number of external BM pools per Rx port */
99089 +#define FM_PORT_MAX_NUM_OF_OBSERVED_EXT_POOLS 2 /**< Number of Offline parsing port external BM pools per Rx port */
99090 +#define FM_PORT_NUM_OF_CONGESTION_GRPS 32 /**< Total number of congestion groups in QM */
99091 +#define FM_MAX_NUM_OF_SUB_PORTALS 7
99092 +
99093 +/* Rams defines */
99094 +#define FM_MURAM_SIZE (64*KILOBYTE)
99095 +#define FM_IRAM_SIZE(major, minor) (32 * KILOBYTE)
99096 +#define FM_NUM_OF_CTRL 2
99097 +
99098 +/* PCD defines */
99099 +#define FM_PCD_PLCR_NUM_ENTRIES 32 /**< Total number of policer profiles */
99100 +#define FM_PCD_KG_NUM_OF_SCHEMES 16 /**< Total number of KG schemes */
99101 +#define FM_PCD_MAX_NUM_OF_CLS_PLANS 128 /**< Number of classification plan entries. */
99102 +#define FM_PCD_PRS_SW_PATCHES_SIZE 0x00000240 /**< Number of bytes saved for patches */
99103 +#define FM_PCD_SW_PRS_SIZE 0x00000800 /**< Total size of SW parser area */
99104 +
99105 +/* RTC defines */
99106 +#define FM_RTC_NUM_OF_ALARMS 2
99107 +#define FM_RTC_NUM_OF_PERIODIC_PULSES 2
99108 +#define FM_RTC_NUM_OF_EXT_TRIGGERS 2
99109 +
99110 +/* QMI defines */
99111 +#define QMI_MAX_NUM_OF_TNUMS 15
99112 +
99113 +/* FPM defines */
99114 +#define FM_NUM_OF_FMAN_CTRL_EVENT_REGS 4
99115 +
99116 +/* DMA defines */
99117 +#define DMA_THRESH_MAX_COMMQ 15
99118 +#define DMA_THRESH_MAX_BUF 7
99119 +
99120 +/* BMI defines */
99121 +#define BMI_MAX_NUM_OF_TASKS 64
99122 +#define BMI_MAX_NUM_OF_DMAS 16
99123 +#define BMI_MAX_FIFO_SIZE (FM_MURAM_SIZE)
99124 +#define PORT_MAX_WEIGHT 4
99125 +
99126 +/*****************************************************************************
99127 + FM MACSEC INTEGRATION-SPECIFIC DEFINITIONS
99128 +******************************************************************************/
99129 +#define NUM_OF_RX_SC 16
99130 +#define NUM_OF_TX_SC 16
99131 +
99132 +#define NUM_OF_SA_PER_RX_SC 2
99133 +#define NUM_OF_SA_PER_TX_SC 2
99134 +
99135 +/**************************************************************************//**
99136 + @Description Enum for inter-module interrupts registration
99137 +*//***************************************************************************/
99138 +
99139 +/* 1023 unique features */
99140 +#define FM_QMI_NO_ECC_EXCEPTIONS
99141 +#define FM_CSI_CFED_LIMIT
99142 +#define FM_PEDANTIC_DMA
99143 +#define FM_QMI_NO_DEQ_OPTIONS_SUPPORT
99144 +#define FM_FIFO_ALLOCATION_ALG
99145 +#define FM_DEQ_PIPELINE_PARAMS_FOR_OP
99146 +#define FM_HAS_TOTAL_DMAS
99147 +#define FM_KG_NO_IPPID_SUPPORT
99148 +#define FM_NO_GUARANTEED_RESET_VALUES
99149 +#define FM_MAC_RESET
99150 +
99151 +/* FM erratas */
99152 +#define FM_RX_PREAM_4_ERRATA_DTSEC_A001
99153 +#define FM_MAGIC_PACKET_UNRECOGNIZED_ERRATA_DTSEC2 /* No implementation, Out of LLD scope */
99154 +
99155 +#define FM_DEBUG_TRACE_FMAN_A004 /* No implementation, Out of LLD scope */
99156 +#define FM_INT_BUF_LEAK_FMAN_A005 /* No implementation, Out of LLD scope. App must avoid S/G */
99157 +
99158 +#define FM_GTS_AFTER_DROPPED_FRAME_ERRATA_DTSEC_A004839
99159 +
99160 +/* #define FM_UCODE_NOT_RESET_ERRATA_BUGZILLA6173 */
99161 +
99162 +/*
99163 +TKT056919 - axi12axi0 can hang if read request follows the single byte write on the very next cycle
99164 +TKT038900 - FM dma lockup occur due to AXI slave protocol violation
99165 +*/
99166 +#define FM_LOCKUP_ALIGNMENT_ERRATA_FMAN_SW004
99167 +
99168 +
99169 +#endif /* __DPAA_INTEGRATION_EXT_H */
99170 --- /dev/null
99171 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/integrations/P1023/part_ext.h
99172 @@ -0,0 +1,82 @@
99173 +/*
99174 + * Copyright 2008-2012 Freescale Semiconductor Inc.
99175 + *
99176 + * Redistribution and use in source and binary forms, with or without
99177 + * modification, are permitted provided that the following conditions are met:
99178 + * * Redistributions of source code must retain the above copyright
99179 + * notice, this list of conditions and the following disclaimer.
99180 + * * Redistributions in binary form must reproduce the above copyright
99181 + * notice, this list of conditions and the following disclaimer in the
99182 + * documentation and/or other materials provided with the distribution.
99183 + * * Neither the name of Freescale Semiconductor nor the
99184 + * names of its contributors may be used to endorse or promote products
99185 + * derived from this software without specific prior written permission.
99186 + *
99187 + *
99188 + * ALTERNATIVELY, this software may be distributed under the terms of the
99189 + * GNU General Public License ("GPL") as published by the Free Software
99190 + * Foundation, either version 2 of that License or (at your option) any
99191 + * later version.
99192 + *
99193 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
99194 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
99195 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
99196 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
99197 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
99198 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
99199 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
99200 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
99201 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
99202 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
99203 + */
99204 +
99205 +
99206 +/**************************************************************************//**
99207 +
99208 + @File part_ext.h
99209 +
99210 + @Description Definitions for the part (integration) module.
99211 +*//***************************************************************************/
99212 +
99213 +#ifndef __PART_EXT_H
99214 +#define __PART_EXT_H
99215 +
99216 +#include "std_ext.h"
99217 +#include "part_integration_ext.h"
99218 +
99219 +
99220 +#if !(defined(MPC8306) || \
99221 + defined(MPC8309) || \
99222 + defined(MPC834x) || \
99223 + defined(MPC836x) || \
99224 + defined(MPC832x) || \
99225 + defined(MPC837x) || \
99226 + defined(MPC8568) || \
99227 + defined(MPC8569) || \
99228 + defined(P1020) || \
99229 + defined(P1021) || \
99230 + defined(P1022) || \
99231 + defined(P1023) || \
99232 + defined(P2020) || \
99233 + defined(P3041) || \
99234 + defined(P4080) || \
99235 + defined(P5020) || \
99236 + defined(MSC814x))
99237 +#error "unable to proceed without chip-definition"
99238 +#endif
99239 +
99240 +
99241 +/**************************************************************************//*
99242 + @Description Part data structure - must be contained in any integration
99243 + data structure.
99244 +*//***************************************************************************/
99245 +typedef struct t_Part
99246 +{
99247 + uint64_t (* f_GetModuleBase)(t_Handle h_Part, e_ModuleId moduleId);
99248 + /**< Returns the address of the module's memory map base. */
99249 + e_ModuleId (* f_GetModuleIdByBase)(t_Handle h_Part, uint64_t baseAddress);
99250 + /**< Returns the module's ID according to its memory map base. */
99251 +} t_Part;
99252 +
99253 +
99254 +#endif /* __PART_EXT_H */
99255 --- /dev/null
99256 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/integrations/P1023/part_integration_ext.h
99257 @@ -0,0 +1,635 @@
99258 +/* Copyright (c) 2008-2012 Freescale Semiconductor, Inc
99259 + * All rights reserved.
99260 + *
99261 + * Redistribution and use in source and binary forms, with or without
99262 + * modification, are permitted provided that the following conditions are met:
99263 + * * Redistributions of source code must retain the above copyright
99264 + * notice, this list of conditions and the following disclaimer.
99265 + * * Redistributions in binary form must reproduce the above copyright
99266 + * notice, this list of conditions and the following disclaimer in the
99267 + * documentation and/or other materials provided with the distribution.
99268 + * * Neither the name of Freescale Semiconductor nor the
99269 + * names of its contributors may be used to endorse or promote products
99270 + * derived from this software without specific prior written permission.
99271 + *
99272 + *
99273 + * ALTERNATIVELY, this software may be distributed under the terms of the
99274 + * GNU General Public License ("GPL") as published by the Free Software
99275 + * Foundation, either version 2 of that License or (at your option) any
99276 + * later version.
99277 + *
99278 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
99279 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
99280 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
99281 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
99282 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
99283 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
99284 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
99285 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
99286 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
99287 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
99288 + */
99289 +
99290 +/**************************************************************************//**
99291 + @File part_integration_ext.h
99292 +
99293 + @Description P1023 external definitions and structures.
99294 +*//***************************************************************************/
99295 +#ifndef __PART_INTEGRATION_EXT_H
99296 +#define __PART_INTEGRATION_EXT_H
99297 +
99298 +#include "std_ext.h"
99299 +#include "dpaa_integration_ext.h"
99300 +
99301 +
99302 +/**************************************************************************//**
99303 + @Group 1023_chip_id P1023 Application Programming Interface
99304 +
99305 + @Description P1023 Chip functions,definitions and enums.
99306 +
99307 + @{
99308 +*//***************************************************************************/
99309 +
99310 +#define INTG_MAX_NUM_OF_CORES 2
99311 +
99312 +
99313 +/**************************************************************************//**
99314 + @Description Module types.
99315 +*//***************************************************************************/
99316 +typedef enum e_ModuleId
99317 +{
99318 + e_MODULE_ID_LAW, /**< Local Access module */
99319 + e_MODULE_ID_ECM, /**< e500 Coherency Module */
99320 + e_MODULE_ID_DDR, /**< DDR memory controller */
99321 + e_MODULE_ID_I2C_1, /**< I2C 1 */
99322 + e_MODULE_ID_I2C_2, /**< I2C 1 */
99323 + e_MODULE_ID_DUART_1, /**< DUART module 1 */
99324 + e_MODULE_ID_DUART_2, /**< DUART module 2 */
99325 + e_MODULE_ID_LBC, /**< Local bus memory controller module */
99326 + e_MODULE_ID_PCIE_1, /**< PCI Express 1 controller module */
99327 + e_MODULE_ID_PCIE_ATMU_1, /**< PCI 1 ATMU Window */
99328 + e_MODULE_ID_PCIE_2, /**< PCI Express 2 controller module */
99329 + e_MODULE_ID_PCIE_ATMU_2, /**< PCI 2 ATMU Window */
99330 + e_MODULE_ID_PCIE_3, /**< PCI Express 3 controller module */
99331 + e_MODULE_ID_PCIE_ATMU_3, /**< PCI 3 ATMU Window */
99332 + e_MODULE_ID_MSI, /**< MSI registers */
99333 + e_MODULE_ID_L2_SRAM, /**< L2/SRAM Memory-Mapped controller module */
99334 + e_MODULE_ID_DMA_1, /**< DMA controller 1 */
99335 + e_MODULE_ID_DMA_2, /**< DMA controller 2 */
99336 + e_MODULE_ID_EPIC, /**< Programmable interrupt controller */
99337 + e_MODULE_ID_ESPI, /**< ESPI module */
99338 + e_MODULE_ID_GPIO, /**< General Purpose I/O */
99339 + e_MODULE_ID_SEC_GEN, /**< SEC 4.0 General registers */
99340 + e_MODULE_ID_SEC_QI, /**< SEC 4.0 QI registers */
99341 + e_MODULE_ID_SEC_JQ0, /**< SEC 4.0 JQ-0 registers */
99342 + e_MODULE_ID_SEC_JQ1, /**< SEC 4.0 JQ-1 registers */
99343 + e_MODULE_ID_SEC_JQ2, /**< SEC 4.0 JQ-2 registers */
99344 + e_MODULE_ID_SEC_JQ3, /**< SEC 4.0 JQ-3 registers */
99345 + e_MODULE_ID_SEC_RTIC, /**< SEC 4.0 RTIC registers */
99346 + e_MODULE_ID_SEC_DECO0_CCB0, /**< SEC 4.0 DECO-0/CCB-0 registers */
99347 + e_MODULE_ID_SEC_DECO1_CCB1, /**< SEC 4.0 DECO-1/CCB-1 registers */
99348 + e_MODULE_ID_SEC_DECO2_CCB2, /**< SEC 4.0 DECO-2/CCB-2 registers */
99349 + e_MODULE_ID_SEC_DECO3_CCB3, /**< SEC 4.0 DECO-3/CCB-3 registers */
99350 + e_MODULE_ID_SEC_DECO4_CCB4, /**< SEC 4.0 DECO-4/CCB-4 registers */
99351 + e_MODULE_ID_USB_DR_1, /**< USB 2.0 module 1 */
99352 + e_MODULE_ID_USB_DR_2, /**< USB 2.0 module 2 */
99353 + e_MODULE_ID_ETSEC_MII_MNG, /**< MII MNG registers */
99354 + e_MODULE_ID_ETSEC_1, /**< ETSEC module 1 */
99355 + e_MODULE_ID_ETSEC_2, /**< ETSEC module 2 */
99356 + e_MODULE_ID_GUTS, /**< Serial DMA */
99357 + e_MODULE_ID_PM, /**< Performance Monitor module */
99358 + e_MODULE_ID_QM, /**< Queue manager module */
99359 + e_MODULE_ID_BM, /**< Buffer manager module */
99360 + e_MODULE_ID_QM_CE_PORTAL,
99361 + e_MODULE_ID_QM_CI_PORTAL,
99362 + e_MODULE_ID_BM_CE_PORTAL,
99363 + e_MODULE_ID_BM_CI_PORTAL,
99364 + e_MODULE_ID_FM, /**< Frame manager #1 module */
99365 + e_MODULE_ID_FM_RTC, /**< FM Real-Time-Clock */
99366 + e_MODULE_ID_FM_MURAM, /**< FM Multi-User-RAM */
99367 + e_MODULE_ID_FM_BMI, /**< FM BMI block */
99368 + e_MODULE_ID_FM_QMI, /**< FM QMI block */
99369 + e_MODULE_ID_FM_PRS, /**< FM parser block */
99370 + e_MODULE_ID_FM_PORT_HO0, /**< FM Host-command/offline-parsing port block */
99371 + e_MODULE_ID_FM_PORT_HO1, /**< FM Host-command/offline-parsing port block */
99372 + e_MODULE_ID_FM_PORT_HO2, /**< FM Host-command/offline-parsing port block */
99373 + e_MODULE_ID_FM_PORT_HO3, /**< FM Host-command/offline-parsing port block */
99374 + e_MODULE_ID_FM_PORT_HO4, /**< FM Host-command/offline-parsing port block */
99375 + e_MODULE_ID_FM_PORT_1GRx0, /**< FM Rx 1G MAC port block */
99376 + e_MODULE_ID_FM_PORT_1GRx1, /**< FM Rx 1G MAC port block */
99377 + e_MODULE_ID_FM_PORT_1GTx0, /**< FM Tx 1G MAC port block */
99378 + e_MODULE_ID_FM_PORT_1GTx1, /**< FM Tx 1G MAC port block */
99379 + e_MODULE_ID_FM_PLCR, /**< FM Policer */
99380 + e_MODULE_ID_FM_KG, /**< FM Keygen */
99381 + e_MODULE_ID_FM_DMA, /**< FM DMA */
99382 + e_MODULE_ID_FM_FPM, /**< FM FPM */
99383 + e_MODULE_ID_FM_IRAM, /**< FM Instruction-RAM */
99384 + e_MODULE_ID_FM_1GMDIO0, /**< FM 1G MDIO MAC 0*/
99385 + e_MODULE_ID_FM_1GMDIO1, /**< FM 1G MDIO MAC 1*/
99386 + e_MODULE_ID_FM_PRS_IRAM, /**< FM SW-parser Instruction-RAM */
99387 + e_MODULE_ID_FM_RISC0, /**< FM risc #0 */
99388 + e_MODULE_ID_FM_RISC1, /**< FM risc #1 */
99389 + e_MODULE_ID_FM_1GMAC0, /**< FM 1G MAC #0 */
99390 + e_MODULE_ID_FM_1GMAC1, /**< FM 1G MAC #1 */
99391 + e_MODULE_ID_FM_MACSEC, /**< FM MACSEC */
99392 +
99393 + e_MODULE_ID_DUMMY_LAST
99394 +} e_ModuleId;
99395 +
99396 +#define NUM_OF_MODULES e_MODULE_ID_DUMMY_LAST
99397 +
99398 +
99399 +#define P1023_OFFSET_LAW 0x00000C08
99400 +#define P1023_OFFSET_ECM 0x00001000
99401 +#define P1023_OFFSET_DDR 0x00002000
99402 +#define P1023_OFFSET_I2C1 0x00003000
99403 +#define P1023_OFFSET_I2C2 0x00003100
99404 +#define P1023_OFFSET_DUART1 0x00004500
99405 +#define P1023_OFFSET_DUART2 0x00004600
99406 +#define P1023_OFFSET_LBC 0x00005000
99407 +#define P1023_OFFSET_ESPI 0x00007000
99408 +#define P1023_OFFSET_PCIE2 0x00009000
99409 +#define P1023_OFFSET_PCIE2_ATMU 0x00009C00
99410 +#define P1023_OFFSET_PCIE1 0x0000A000
99411 +#define P1023_OFFSET_PCIE1_ATMU 0x0000AC00
99412 +#define P1023_OFFSET_PCIE3 0x0000B000
99413 +#define P1023_OFFSET_PCIE3_ATMU 0x0000BC00
99414 +#define P1023_OFFSET_DMA2 0x0000C100
99415 +#define P1023_OFFSET_GPIO 0x0000F000
99416 +#define P1023_OFFSET_L2_SRAM 0x00020000
99417 +#define P1023_OFFSET_DMA1 0x00021100
99418 +#define P1023_OFFSET_USB1 0x00022000
99419 +#define P1023_OFFSET_SEC_GEN 0x00030000
99420 +#define P1023_OFFSET_SEC_JQ0 0x00031000
99421 +#define P1023_OFFSET_SEC_JQ1 0x00032000
99422 +#define P1023_OFFSET_SEC_JQ2 0x00033000
99423 +#define P1023_OFFSET_SEC_JQ3 0x00034000
99424 +#define P1023_OFFSET_SEC_RTIC 0x00036000
99425 +#define P1023_OFFSET_SEC_QI 0x00037000
99426 +#define P1023_OFFSET_SEC_DECO0_CCB0 0x00038000
99427 +#define P1023_OFFSET_SEC_DECO1_CCB1 0x00039000
99428 +#define P1023_OFFSET_SEC_DECO2_CCB2 0x0003a000
99429 +#define P1023_OFFSET_SEC_DECO3_CCB3 0x0003b000
99430 +#define P1023_OFFSET_SEC_DECO4_CCB4 0x0003c000
99431 +#define P1023_OFFSET_PIC 0x00040000
99432 +#define P1023_OFFSET_MSI 0x00041600
99433 +#define P1023_OFFSET_AXI 0x00081000
99434 +#define P1023_OFFSET_QM 0x00088000
99435 +#define P1023_OFFSET_BM 0x0008A000
99436 +#define P1022_OFFSET_PM 0x000E1000
99437 +
99438 +#define P1023_OFFSET_GUTIL 0x000E0000
99439 +#define P1023_OFFSET_PM 0x000E1000
99440 +#define P1023_OFFSET_DEBUG 0x000E2000
99441 +#define P1023_OFFSET_SERDES 0x000E3000
99442 +#define P1023_OFFSET_ROM 0x000F0000
99443 +#define P1023_OFFSET_FM 0x00100000
99444 +
99445 +#define P1023_OFFSET_FM_MURAM (P1023_OFFSET_FM + 0x00000000)
99446 +#define P1023_OFFSET_FM_BMI (P1023_OFFSET_FM + 0x00080000)
99447 +#define P1023_OFFSET_FM_QMI (P1023_OFFSET_FM + 0x00080400)
99448 +#define P1023_OFFSET_FM_PRS (P1023_OFFSET_FM + 0x00080800)
99449 +#define P1023_OFFSET_FM_PORT_HO0 (P1023_OFFSET_FM + 0x00081000)
99450 +#define P1023_OFFSET_FM_PORT_HO1 (P1023_OFFSET_FM + 0x00082000)
99451 +#define P1023_OFFSET_FM_PORT_HO2 (P1023_OFFSET_FM + 0x00083000)
99452 +#define P1023_OFFSET_FM_PORT_HO3 (P1023_OFFSET_FM + 0x00084000)
99453 +#define P1023_OFFSET_FM_PORT_HO4 (P1023_OFFSET_FM + 0x00085000)
99454 +#define P1023_OFFSET_FM_PORT_1GRX0 (P1023_OFFSET_FM + 0x00088000)
99455 +#define P1023_OFFSET_FM_PORT_1GRX1 (P1023_OFFSET_FM + 0x00089000)
99456 +#define P1023_OFFSET_FM_PORT_1GTX0 (P1023_OFFSET_FM + 0x000A8000)
99457 +#define P1023_OFFSET_FM_PORT_1GTX1 (P1023_OFFSET_FM + 0x000A9000)
99458 +#define P1023_OFFSET_FM_PLCR (P1023_OFFSET_FM + 0x000C0000)
99459 +#define P1023_OFFSET_FM_KG (P1023_OFFSET_FM + 0x000C1000)
99460 +#define P1023_OFFSET_FM_DMA (P1023_OFFSET_FM + 0x000C2000)
99461 +#define P1023_OFFSET_FM_FPM (P1023_OFFSET_FM + 0x000C3000)
99462 +#define P1023_OFFSET_FM_IRAM (P1023_OFFSET_FM + 0x000C4000)
99463 +#define P1023_OFFSET_FM_PRS_IRAM (P1023_OFFSET_FM + 0x000C7000)
99464 +#define P1023_OFFSET_FM_RISC0 (P1023_OFFSET_FM + 0x000D0000)
99465 +#define P1023_OFFSET_FM_RISC1 (P1023_OFFSET_FM + 0x000D0400)
99466 +#define P1023_OFFSET_FM_MACSEC (P1023_OFFSET_FM + 0x000D8000)
99467 +#define P1023_OFFSET_FM_1GMAC0 (P1023_OFFSET_FM + 0x000E0000)
99468 +#define P1023_OFFSET_FM_1GMDIO0 (P1023_OFFSET_FM + 0x000E1120)
99469 +#define P1023_OFFSET_FM_1GMAC1 (P1023_OFFSET_FM + 0x000E2000)
99470 +#define P1023_OFFSET_FM_1GMDIO1 (P1023_OFFSET_FM + 0x000E3000)
99471 +#define P1023_OFFSET_FM_RTC (P1023_OFFSET_FM + 0x000FE000)
99472 +
99473 +/* Offsets relative to QM or BM portals base */
99474 +#define P1023_OFFSET_PORTALS_CE_AREA 0x00000000 /* cache enabled area */
99475 +#define P1023_OFFSET_PORTALS_CI_AREA 0x00100000 /* cache inhibited area */
99476 +
99477 +#define P1023_OFFSET_PORTALS_CE(portal) (P1023_OFFSET_PORTALS_CE_AREA + 0x4000 * (portal))
99478 +#define P1023_OFFSET_PORTALS_CI(portal) (P1023_OFFSET_PORTALS_CI_AREA + 0x1000 * (portal))
99479 +
99480 +/**************************************************************************//**
99481 + @Description Transaction source ID (for memory controllers error reporting).
99482 +*//***************************************************************************/
99483 +typedef enum e_TransSrc
99484 +{
99485 + e_TRANS_SRC_PCIE_2 = 0x01, /**< PCIe port 2 */
99486 + e_TRANS_SRC_PCIE_1 = 0x02, /**< PCIe port 1 */
99487 + e_TRANS_SRC_PCIE_3 = 0x03, /**< PCIe port 3 */
99488 + e_TRANS_SRC_LBC = 0x04, /**< Enhanced local bus */
99489 + e_TRANS_SRC_DPAA_SW_PORTALS = 0x0E, /**< DPAA software portals or SRAM */
99490 + e_TRANS_SRC_DDR = 0x0F, /**< DDR controller */
99491 + e_TRANS_SRC_CORE_INS_FETCH = 0x10, /**< Processor (instruction) */
99492 + e_TRANS_SRC_CORE_DATA = 0x11, /**< Processor (data) */
99493 + e_TRANS_SRC_DMA = 0x15 /**< DMA */
99494 +} e_TransSrc;
99495 +
99496 +/**************************************************************************//**
99497 + @Description Local Access Window Target interface ID
99498 +*//***************************************************************************/
99499 +typedef enum e_P1023LawTargetId
99500 +{
99501 + e_P1023_LAW_TARGET_PCIE_2 = 0x01, /**< PCI Express 2 target interface */
99502 + e_P1023_LAW_TARGET_PCIE_1 = 0x02, /**< PCI Express 1 target interface */
99503 + e_P1023_LAW_TARGET_PCIE_3 = 0x03, /**< PCI Express 3 target interface */
99504 + e_P1023_LAW_TARGET_LBC = 0x04, /**< Local bus target interface */
99505 + e_P1023_LAW_TARGET_QM_PORTALS = 0x0E, /**< Queue Manager Portals */
99506 + e_P1023_LAW_TARGET_BM_PORTALS = 0x0E, /**< Buffer Manager Portals */
99507 + e_P1023_LAW_TARGET_SRAM = 0x0E, /**< SRAM scratchpad */
99508 + e_P1023_LAW_TARGET_DDR = 0x0F, /**< DDR target interface */
99509 + e_P1023_LAW_TARGET_NONE = 0xFF /**< Invalid target interface */
99510 +} e_P1023LawTargetId;
99511 +
99512 +
99513 +/**************************************************************************//**
99514 + @Group 1023_init_grp P1023 Initialization Unit
99515 +
99516 + @Description P1023 initialization unit API functions, definitions and enums
99517 +
99518 + @{
99519 +*//***************************************************************************/
99520 +
99521 +/**************************************************************************//**
99522 + @Description Part ID and revision number
99523 +*//***************************************************************************/
99524 +typedef enum e_P1023DeviceName
99525 +{
99526 + e_P1023_REV_INVALID = 0x00000000, /**< Invalid revision */
99527 + e_SC1023_REV_1_0 = (int)0x80FC0010, /**< SC1023 rev 1.0 */
99528 + e_SC1023_REV_1_1 = (int)0x80FC0011, /**< SC1023 rev 1.1 */
99529 + e_P1023_REV_1_0 = (int)0x80FE0010, /**< P1023 rev 1.0 with security */
99530 + e_P1023_REV_1_1 = (int)0x80FE0011, /**< P1023 rev 1.1 with security */
99531 + e_P1017_REV_1_1 = (int)0x80FF0011, /**< P1017 rev 1.1 with security */
99532 + e_P1023_REV_1_0_NO_SEC = (int)0x80F60010, /**< P1023 rev 1.0 without security */
99533 + e_P1023_REV_1_1_NO_SEC = (int)0x80F60011, /**< P1023 rev 1.1 without security */
99534 + e_P1017_REV_1_1_NO_SEC = (int)0x80F70011 /**< P1017 rev 1.1 without security */
99535 +} e_P1023DeviceName;
99536 +
99537 +/**************************************************************************//**
99538 + @Description structure representing P1023 initialization parameters
99539 +*//***************************************************************************/
99540 +typedef struct t_P1023Params
99541 +{
99542 + uintptr_t ccsrBaseAddress; /**< CCSR base address (virtual) */
99543 + uintptr_t bmPortalsBaseAddress; /**< Portals base address (virtual) */
99544 + uintptr_t qmPortalsBaseAddress; /**< Portals base address (virtual) */
99545 +} t_P1023Params;
99546 +
99547 +/**************************************************************************//**
99548 + @Function P1023_ConfigAndInit
99549 +
99550 + @Description General initiation of the chip registers.
99551 +
99552 + @Param[in] p_P1023Params - A pointer to data structure of parameters
99553 +
99554 + @Return A handle to the P1023 data structure.
99555 +*//***************************************************************************/
99556 +t_Handle P1023_ConfigAndInit(t_P1023Params *p_P1023Params);
99557 +
99558 +/**************************************************************************//**
99559 + @Function P1023_Free
99560 +
99561 + @Description Free all resources.
99562 +
99563 + @Param h_P1023 - (In) The handle of the initialized P1023 object.
99564 +
99565 + @Return E_OK on success; Other value otherwise.
99566 +*//***************************************************************************/
99567 +t_Error P1023_Free(t_Handle h_P1023);
99568 +
99569 +/**************************************************************************//**
99570 + @Function P1023_GetRevInfo
99571 +
99572 + @Description This routine enables access to chip and revision information.
99573 +
99574 + @Param[in] gutilBase - Base address of P1023 GUTIL registers.
99575 +
99576 + @Return Part ID and revision.
99577 +*//***************************************************************************/
99578 +e_P1023DeviceName P1023_GetRevInfo(uintptr_t gutilBase);
99579 +
99580 +/**************************************************************************//**
99581 + @Function P1023_GetE500Factor
99582 +
99583 + @Description Returns E500 core clock multiplication factor.
99584 +
99585 + @Param[in] gutilBase - Base address of P1023 GUTIL registers.
99586 + @Param[in] coreId - Id of the requested core.
99587 + @Param[out] p_E500MulFactor - Returns E500 to CCB multification factor.
99588 + @Param[out] p_E500DivFactor - Returns E500 to CCB division factor.
99589 +
99590 + @Return E_OK on success; Other value otherwise.
99591 +*
99592 +*//***************************************************************************/
99593 +t_Error P1023_GetE500Factor(uintptr_t gutilBase,
99594 + uint32_t coreId,
99595 + uint32_t *p_E500MulFactor,
99596 + uint32_t *p_E500DivFactor);
99597 +
99598 +/**************************************************************************//**
99599 + @Function P1023_GetFmFactor
99600 +
99601 + @Description returns FM multiplication factors. (This value is returned using
99602 + two parameters to avoid using float parameter).
99603 +
99604 + @Param[in] gutilBase - Base address of P1023 GUTIL registers.
99605 + @Param[out] p_FmMulFactor - returns E500 to CCB multification factor.
99606 + @Param[out] p_FmDivFactor - returns E500 to CCB division factor.
99607 +
99608 + @Return E_OK on success; Other value otherwise.
99609 +*//***************************************************************************/
99610 +t_Error P1023_GetFmFactor(uintptr_t gutilBase, uint32_t *p_FmMulFactor, uint32_t *p_FmDivFactor);
99611 +
99612 +/**************************************************************************//**
99613 + @Function P1023_GetCcbFactor
99614 +
99615 + @Description returns system multiplication factor.
99616 +
99617 + @Param[in] gutilBase - Base address of P1023 GUTIL registers.
99618 +
99619 + @Return System multiplication factor.
99620 +*//***************************************************************************/
99621 +uint32_t P1023_GetCcbFactor(uintptr_t gutilBase);
99622 +
99623 +#if 0
99624 +/**************************************************************************//**
99625 + @Function P1023_GetDdrFactor
99626 +
99627 + @Description returns the multiplication factor of the clock in for the DDR clock .
99628 + Note: assumes the ddr_in_clk is identical to the sys_in_clk
99629 +
99630 + @Param[in] gutilBase - Base address of P1023 GUTIL registers.
99631 + @Param p_DdrMulFactor - returns DDR in clk multification factor.
99632 + @Param p_DdrDivFactor - returns DDR division factor.
99633 +
99634 + @Return E_OK on success; Other value otherwise..
99635 +*//***************************************************************************/
99636 +t_Error P1023_GetDdrFactor( uintptr_t gutilBase,
99637 + uint32_t *p_DdrMulFactor,
99638 + uint32_t *p_DdrDivFactor);
99639 +
99640 +/**************************************************************************//**
99641 + @Function P1023_GetDdrType
99642 +
99643 + @Description returns the multiplication factor of the clock in for the DDR clock .
99644 +
99645 + @Param[in] gutilBase - Base address of P1023 GUTIL registers.
99646 + @Param p_DdrType - (Out) returns DDR type DDR1/DDR2/DDR3.
99647 +
99648 + @Return E_OK on success; Other value otherwise.
99649 +*//***************************************************************************/
99650 +t_Error P1023_GetDdrType(uintptr_t gutilBase, e_DdrType *p_DdrType );
99651 +#endif
99652 +
99653 +/** @} */ /* end of 1023_init_grp group */
99654 +/** @} */ /* end of 1023_grp group */
99655 +
99656 +#define CORE_E500V2
99657 +
99658 +#if 0 /* using unified values */
99659 +/*****************************************************************************
99660 + INTEGRATION-SPECIFIC MODULE CODES
99661 +******************************************************************************/
99662 +#define MODULE_UNKNOWN 0x00000000
99663 +#define MODULE_MEM 0x00010000
99664 +#define MODULE_MM 0x00020000
99665 +#define MODULE_CORE 0x00030000
99666 +#define MODULE_P1023 0x00040000
99667 +#define MODULE_MII 0x00050000
99668 +#define MODULE_PM 0x00060000
99669 +#define MODULE_MMU 0x00070000
99670 +#define MODULE_PIC 0x00080000
99671 +#define MODULE_L2_CACHE 0x00090000
99672 +#define MODULE_DUART 0x000a0000
99673 +#define MODULE_SERDES 0x000b0000
99674 +#define MODULE_PIO 0x000c0000
99675 +#define MODULE_QM 0x000d0000
99676 +#define MODULE_BM 0x000e0000
99677 +#define MODULE_SEC 0x000f0000
99678 +#define MODULE_FM 0x00100000
99679 +#define MODULE_FM_MURAM 0x00110000
99680 +#define MODULE_FM_PCD 0x00120000
99681 +#define MODULE_FM_RTC 0x00130000
99682 +#define MODULE_FM_MAC 0x00140000
99683 +#define MODULE_FM_PORT 0x00150000
99684 +#define MODULE_FM_MACSEC 0x00160000
99685 +#define MODULE_FM_MACSEC_SECY 0x00170000
99686 +#define MODULE_FM_SP 0x00280000
99687 +#define MODULE_ECM 0x00190000
99688 +#define MODULE_DMA 0x001a0000
99689 +#define MODULE_DDR 0x001b0000
99690 +#define MODULE_LAW 0x001c0000
99691 +#define MODULE_LBC 0x001d0000
99692 +#define MODULE_I2C 0x001e0000
99693 +#define MODULE_ESPI 0x001f0000
99694 +#define MODULE_PCI 0x00200000
99695 +#define MODULE_DPA_PORT 0x00210000
99696 +#define MODULE_USB 0x00220000
99697 +#endif /* using unified values */
99698 +
99699 +/*****************************************************************************
99700 + LBC INTEGRATION-SPECIFIC DEFINITIONS
99701 +******************************************************************************/
99702 +/**************************************************************************//**
99703 + @Group lbc_exception_grp LBC Exception Unit
99704 +
99705 + @Description LBC Exception unit API functions, definitions and enums
99706 +
99707 + @{
99708 +*//***************************************************************************/
99709 +
99710 +/**************************************************************************//**
99711 + @Anchor lbc_exbm
99712 +
99713 + @Collection LBC Errors Bit Mask
99714 +
99715 + These errors are reported through the exceptions callback..
99716 + The values can be or'ed in any combination in the errors mask
99717 + parameter of the errors report structure.
99718 +
99719 + These errors can also be passed as a bit-mask to
99720 + LBC_EnableErrorChecking() or LBC_DisableErrorChecking(),
99721 + for enabling or disabling error checking.
99722 + @{
99723 +*//***************************************************************************/
99724 +#define LBC_ERR_BUS_MONITOR 0x80000000 /**< Bus monitor error */
99725 +#define LBC_ERR_PARITY_ECC 0x20000000 /**< Parity error for GPCM/UPM */
99726 +#define LBC_ERR_WRITE_PROTECT 0x04000000 /**< Write protection error */
99727 +#define LBC_ERR_CHIP_SELECT 0x00080000 /**< Unrecognized chip select */
99728 +
99729 +#define LBC_ERR_ALL (LBC_ERR_BUS_MONITOR | LBC_ERR_PARITY_ECC | \
99730 + LBC_ERR_WRITE_PROTECT | LBC_ERR_CHIP_SELECT)
99731 + /**< All possible errors */
99732 +/* @} */
99733 +/** @} */ /* end of lbc_exception_grp group */
99734 +
99735 +#define LBC_NUM_OF_BANKS 2
99736 +#define LBC_MAX_CS_SIZE 0x0000000100000000LL
99737 +#define LBC_ATOMIC_OPERATION_SUPPORT
99738 +#define LBC_PARITY_SUPPORT
99739 +#define LBC_ADDRESS_SHIFT_SUPPORT
99740 +#define LBC_ADDRESS_HOLD_TIME_CTRL
99741 +#define LBC_HIGH_CLK_DIVIDERS
99742 +#define LBC_FCM_AVAILABLE
99743 +
99744 +
99745 +/*****************************************************************************
99746 + LAW INTEGRATION-SPECIFIC DEFINITIONS
99747 +******************************************************************************/
99748 +#define LAW_ARCH_CCB
99749 +#define LAW_NUM_OF_WINDOWS 12
99750 +#define LAW_MIN_WINDOW_SIZE 0x0000000000001000LL /**< 4KB */
99751 +#define LAW_MAX_WINDOW_SIZE 0x0000001000000000LL /**< 32GB */
99752 +
99753 +
99754 +/*****************************************************************************
99755 + SPI INTEGRATION-SPECIFIC DEFINITIONS
99756 +******************************************************************************/
99757 +#define SPI_NUM_OF_CONTROLLERS 1
99758 +
99759 +/*****************************************************************************
99760 + PCI/PCIe INTEGRATION-SPECIFIC DEFINITIONS
99761 +******************************************************************************/
99762 +
99763 +#define PCI_MAX_INBOUND_WINDOWS_NUM 4
99764 +#define PCI_MAX_OUTBOUND_WINDOWS_NUM 5
99765 +
99766 +/**************************************************************************//**
99767 + @Description Target interface of an inbound window
99768 +*//***************************************************************************/
99769 +typedef enum e_PciTargetInterface
99770 +{
99771 + e_PCI_TARGET_PCIE_2 = 0x1, /**< PCI Express target interface 2 */
99772 + e_PCI_TARGET_PCIE_1 = 0x2, /**< PCI Express target interface 1 */
99773 + e_PCI_TARGET_PCIE_3 = 0x3, /**< PCI Express target interface 3 */
99774 + e_PCI_TARGET_LOCAL_MEMORY = 0xF /**< Local Memory (DDR SDRAM, Local Bus, SRAM) target interface */
99775 +
99776 +} e_PciTargetInterface;
99777 +
99778 +/*****************************************************************************
99779 + DDR INTEGRATION-SPECIFIC DEFINITIONS
99780 +******************************************************************************/
99781 +#define DDR_NUM_OF_VALID_CS 2
99782 +
99783 +/*****************************************************************************
99784 + SEC INTEGRATION-SPECIFIC DEFINITIONS
99785 +******************************************************************************/
99786 +#define SEC_ERRATA_STAT_REGS_UNUSABLE
99787 +
99788 +/*****************************************************************************
99789 + DMA INTEGRATION-SPECIFIC DEFINITIONS
99790 +******************************************************************************/
99791 +#define DMA_NUM_OF_CONTROLLERS 2
99792 +
99793 +
99794 +
99795 +
99796 +/*****************************************************************************
99797 + 1588 INTEGRATION-SPECIFIC DEFINITIONS
99798 +******************************************************************************/
99799 +#define PTP_V2
99800 +
99801 +/**************************************************************************//**
99802 + @Function P1023_GetMuxControlReg
99803 +
99804 + @Description Returns the value of PMUXCR (Alternate Function Signal Multiplex
99805 + Control Register)
99806 +
99807 + @Param[in] gutilBase - Base address of P1023 GUTIL registers.
99808 +
99809 + @Return Value of PMUXCR
99810 +*//***************************************************************************/
99811 +uint32_t P1023_GetMuxControlReg(uintptr_t gutilBase);
99812 +
99813 +/**************************************************************************//**
99814 + @Function P1023_SetMuxControlReg
99815 +
99816 + @Description Sets the value of PMUXCR (Alternate Function Signal Multiplex
99817 + Control Register)
99818 +
99819 + @Param[in] gutilBase - Base address of P1023 GUTIL registers.
99820 + @Param[in] val - the new value for PMUXCR.
99821 +
99822 + @Return None
99823 +*//***************************************************************************/
99824 +void P1023_SetMuxControlReg(uintptr_t gutilBase, uint32_t val);
99825 +
99826 +/**************************************************************************//**
99827 + @Function P1023_GetDeviceDisableStatusRegister
99828 +
99829 + @Description Returns the value of DEVDISR (Device Disable Register)
99830 +
99831 + @Param[in] gutilBase - Base address of P1023 GUTIL registers.
99832 +
99833 + @Return Value of DEVDISR
99834 +*//***************************************************************************/
99835 +uint32_t P1023_GetDeviceDisableStatusRegister(uintptr_t gutilBase);
99836 +
99837 +/**************************************************************************//**
99838 + @Function P1023_GetPorDeviceStatusRegister
99839 +
99840 + @Description Returns the value of POR Device Status Register
99841 +
99842 + @Param[in] gutilBase - Base address of P1023 GUTIL registers.
99843 +
99844 + @Return POR Device Status Register
99845 +*//***************************************************************************/
99846 +uint32_t P1023_GetPorDeviceStatusRegister(uintptr_t gutilBase);
99847 +
99848 +/**************************************************************************//**
99849 + @Function P1023_GetPorBootModeStatusRegister
99850 +
99851 + @Description Returns the value of POR Boot Mode Status Register
99852 +
99853 + @Param[in] gutilBase - Base address of P1023 GUTIL registers.
99854 +
99855 + @Return POR Boot Mode Status Register value
99856 +*//***************************************************************************/
99857 +uint32_t P1023_GetPorBootModeStatusRegister(uintptr_t gutilBase);
99858 +
99859 +
99860 +#define PORDEVSR_SGMII1_DIS 0x10000000
99861 +#define PORDEVSR_SGMII2_DIS 0x08000000
99862 +#define PORDEVSR_ECP1 0x02000000
99863 +#define PORDEVSR_IO_SEL 0x00780000
99864 +#define PORDEVSR_IO_SEL_SHIFT 19
99865 +#define PORBMSR_HA 0x00070000
99866 +#define PORBMSR_HA_SHIFT 16
99867 +
99868 +#define DEVDISR_QM_BM 0x80000000
99869 +#define DEVDISR_FM 0x40000000
99870 +#define DEVDISR_PCIE1 0x20000000
99871 +#define DEVDISR_MAC_SEC 0x10000000
99872 +#define DEVDISR_ELBC 0x08000000
99873 +#define DEVDISR_PCIE2 0x04000000
99874 +#define DEVDISR_PCIE3 0x02000000
99875 +#define DEVDISR_CAAM 0x01000000
99876 +#define DEVDISR_USB0 0x00800000
99877 +#define DEVDISR_1588 0x00020000
99878 +#define DEVDISR_CORE0 0x00008000
99879 +#define DEVDISR_TB0 0x00004000
99880 +#define DEVDISR_CORE1 0x00002000
99881 +#define DEVDISR_TB1 0x00001000
99882 +#define DEVDISR_DMA1 0x00000400
99883 +#define DEVDISR_DMA2 0x00000200
99884 +#define DEVDISR_DDR 0x00000010
99885 +#define DEVDISR_TSEC1 0x00000080
99886 +#define DEVDISR_TSEC2 0x00000040
99887 +#define DEVDISR_SPI 0x00000008
99888 +#define DEVDISR_I2C 0x00000004
99889 +#define DEVDISR_DUART 0x00000002
99890 +
99891 +
99892 +#endif /* __PART_INTEGRATION_EXT_H */
99893 --- /dev/null
99894 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/integrations/P3040_P4080_P5020/dpaa_integration_ext.h
99895 @@ -0,0 +1,276 @@
99896 +/* Copyright (c) 2009-2012 Freescale Semiconductor, Inc
99897 + * All rights reserved.
99898 + *
99899 + * Redistribution and use in source and binary forms, with or without
99900 + * modification, are permitted provided that the following conditions are met:
99901 + * * Redistributions of source code must retain the above copyright
99902 + * notice, this list of conditions and the following disclaimer.
99903 + * * Redistributions in binary form must reproduce the above copyright
99904 + * notice, this list of conditions and the following disclaimer in the
99905 + * documentation and/or other materials provided with the distribution.
99906 + * * Neither the name of Freescale Semiconductor nor the
99907 + * names of its contributors may be used to endorse or promote products
99908 + * derived from this software without specific prior written permission.
99909 + *
99910 + *
99911 + * ALTERNATIVELY, this software may be distributed under the terms of the
99912 + * GNU General Public License ("GPL") as published by the Free Software
99913 + * Foundation, either version 2 of that License or (at your option) any
99914 + * later version.
99915 + *
99916 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
99917 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
99918 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
99919 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
99920 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
99921 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
99922 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
99923 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
99924 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
99925 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
99926 + */
99927 +
99928 +/**************************************************************************//**
99929 + @File dpaa_integration_ext.h
99930 +
99931 + @Description P3040/P4080/P5020 FM external definitions and structures.
99932 +*//***************************************************************************/
99933 +#ifndef __DPAA_INTEGRATION_EXT_H
99934 +#define __DPAA_INTEGRATION_EXT_H
99935 +
99936 +#include "std_ext.h"
99937 +
99938 +
99939 +#define DPAA_VERSION 10
99940 +
99941 +typedef enum {
99942 + e_DPAA_SWPORTAL0 = 0,
99943 + e_DPAA_SWPORTAL1,
99944 + e_DPAA_SWPORTAL2,
99945 + e_DPAA_SWPORTAL3,
99946 + e_DPAA_SWPORTAL4,
99947 + e_DPAA_SWPORTAL5,
99948 + e_DPAA_SWPORTAL6,
99949 + e_DPAA_SWPORTAL7,
99950 + e_DPAA_SWPORTAL8,
99951 + e_DPAA_SWPORTAL9,
99952 + e_DPAA_SWPORTAL_DUMMY_LAST
99953 +} e_DpaaSwPortal;
99954 +
99955 +typedef enum {
99956 + e_DPAA_DCPORTAL0 = 0,
99957 + e_DPAA_DCPORTAL1,
99958 + e_DPAA_DCPORTAL2,
99959 + e_DPAA_DCPORTAL3,
99960 + e_DPAA_DCPORTAL4,
99961 + e_DPAA_DCPORTAL_DUMMY_LAST
99962 +} e_DpaaDcPortal;
99963 +
99964 +#define DPAA_MAX_NUM_OF_SW_PORTALS e_DPAA_SWPORTAL_DUMMY_LAST
99965 +#define DPAA_MAX_NUM_OF_DC_PORTALS e_DPAA_DCPORTAL_DUMMY_LAST
99966 +
99967 +/*****************************************************************************
99968 + QMan INTEGRATION-SPECIFIC DEFINITIONS
99969 +******************************************************************************/
99970 +#define QM_MAX_NUM_OF_POOL_CHANNELS 15 /**< Total number of channels, dedicated and pool */
99971 +#define QM_MAX_NUM_OF_WQ 8 /**< Number of work queues per channel */
99972 +#define QM_MAX_NUM_OF_SWP_AS 4
99973 +#define QM_MAX_NUM_OF_CGS 256 /**< Number of congestion groups */
99974 +#define QM_MAX_NUM_OF_FQIDS (16 * MEGABYTE) /**< FQIDs range - 24 bits */
99975 +
99976 +/**************************************************************************//**
99977 + @Description Work Queue Channel assignments in QMan.
99978 +*//***************************************************************************/
99979 +typedef enum
99980 +{
99981 + e_QM_FQ_CHANNEL_SWPORTAL0 = 0, /**< Dedicated channels serviced by software portals 0 to 9 */
99982 + e_QM_FQ_CHANNEL_SWPORTAL1,
99983 + e_QM_FQ_CHANNEL_SWPORTAL2,
99984 + e_QM_FQ_CHANNEL_SWPORTAL3,
99985 + e_QM_FQ_CHANNEL_SWPORTAL4,
99986 + e_QM_FQ_CHANNEL_SWPORTAL5,
99987 + e_QM_FQ_CHANNEL_SWPORTAL6,
99988 + e_QM_FQ_CHANNEL_SWPORTAL7,
99989 + e_QM_FQ_CHANNEL_SWPORTAL8,
99990 + e_QM_FQ_CHANNEL_SWPORTAL9,
99991 +
99992 + e_QM_FQ_CHANNEL_POOL1 = 0x21, /**< Pool channels that can be serviced by any of the software portals */
99993 + e_QM_FQ_CHANNEL_POOL2,
99994 + e_QM_FQ_CHANNEL_POOL3,
99995 + e_QM_FQ_CHANNEL_POOL4,
99996 + e_QM_FQ_CHANNEL_POOL5,
99997 + e_QM_FQ_CHANNEL_POOL6,
99998 + e_QM_FQ_CHANNEL_POOL7,
99999 + e_QM_FQ_CHANNEL_POOL8,
100000 + e_QM_FQ_CHANNEL_POOL9,
100001 + e_QM_FQ_CHANNEL_POOL10,
100002 + e_QM_FQ_CHANNEL_POOL11,
100003 + e_QM_FQ_CHANNEL_POOL12,
100004 + e_QM_FQ_CHANNEL_POOL13,
100005 + e_QM_FQ_CHANNEL_POOL14,
100006 + e_QM_FQ_CHANNEL_POOL15,
100007 +
100008 + e_QM_FQ_CHANNEL_FMAN0_SP0 = 0x40, /**< Dedicated channels serviced by Direct Connect Portal 0:
100009 + connected to FMan 0; assigned in incrementing order to
100010 + each sub-portal (SP) in the portal */
100011 + e_QM_FQ_CHANNEL_FMAN0_SP1,
100012 + e_QM_FQ_CHANNEL_FMAN0_SP2,
100013 + e_QM_FQ_CHANNEL_FMAN0_SP3,
100014 + e_QM_FQ_CHANNEL_FMAN0_SP4,
100015 + e_QM_FQ_CHANNEL_FMAN0_SP5,
100016 + e_QM_FQ_CHANNEL_FMAN0_SP6,
100017 + e_QM_FQ_CHANNEL_FMAN0_SP7,
100018 + e_QM_FQ_CHANNEL_FMAN0_SP8,
100019 + e_QM_FQ_CHANNEL_FMAN0_SP9,
100020 + e_QM_FQ_CHANNEL_FMAN0_SP10,
100021 + e_QM_FQ_CHANNEL_FMAN0_SP11,
100022 +/* difference between 5020 and 4080 :) */
100023 + e_QM_FQ_CHANNEL_FMAN1_SP0 = 0x60,
100024 + e_QM_FQ_CHANNEL_FMAN1_SP1,
100025 + e_QM_FQ_CHANNEL_FMAN1_SP2,
100026 + e_QM_FQ_CHANNEL_FMAN1_SP3,
100027 + e_QM_FQ_CHANNEL_FMAN1_SP4,
100028 + e_QM_FQ_CHANNEL_FMAN1_SP5,
100029 + e_QM_FQ_CHANNEL_FMAN1_SP6,
100030 + e_QM_FQ_CHANNEL_FMAN1_SP7,
100031 + e_QM_FQ_CHANNEL_FMAN1_SP8,
100032 + e_QM_FQ_CHANNEL_FMAN1_SP9,
100033 + e_QM_FQ_CHANNEL_FMAN1_SP10,
100034 + e_QM_FQ_CHANNEL_FMAN1_SP11,
100035 +
100036 + e_QM_FQ_CHANNEL_CAAM = 0x80, /**< Dedicated channel serviced by Direct Connect Portal 2:
100037 + connected to SEC 4.x */
100038 +
100039 + e_QM_FQ_CHANNEL_PME = 0xA0, /**< Dedicated channel serviced by Direct Connect Portal 3:
100040 + connected to PME */
100041 + e_QM_FQ_CHANNEL_RAID = 0xC0 /**< Dedicated channel serviced by Direct Connect Portal 4:
100042 + connected to RAID */
100043 +} e_QmFQChannel;
100044 +
100045 +/*****************************************************************************
100046 + BMan INTEGRATION-SPECIFIC DEFINITIONS
100047 +******************************************************************************/
100048 +#define BM_MAX_NUM_OF_POOLS 64 /**< Number of buffers pools */
100049 +
100050 +
100051 +/*****************************************************************************
100052 + FM INTEGRATION-SPECIFIC DEFINITIONS
100053 +******************************************************************************/
100054 +#define INTG_MAX_NUM_OF_FM 2
100055 +
100056 +/* Ports defines */
100057 +#define FM_MAX_NUM_OF_1G_MACS 5
100058 +#define FM_MAX_NUM_OF_10G_MACS 1
100059 +#define FM_MAX_NUM_OF_MACS (FM_MAX_NUM_OF_1G_MACS + FM_MAX_NUM_OF_10G_MACS)
100060 +#define FM_MAX_NUM_OF_OH_PORTS 7
100061 +
100062 +#define FM_MAX_NUM_OF_1G_RX_PORTS FM_MAX_NUM_OF_1G_MACS
100063 +#define FM_MAX_NUM_OF_10G_RX_PORTS FM_MAX_NUM_OF_10G_MACS
100064 +#define FM_MAX_NUM_OF_RX_PORTS (FM_MAX_NUM_OF_10G_RX_PORTS + FM_MAX_NUM_OF_1G_RX_PORTS)
100065 +
100066 +#define FM_MAX_NUM_OF_1G_TX_PORTS FM_MAX_NUM_OF_1G_MACS
100067 +#define FM_MAX_NUM_OF_10G_TX_PORTS FM_MAX_NUM_OF_10G_MACS
100068 +#define FM_MAX_NUM_OF_TX_PORTS (FM_MAX_NUM_OF_10G_TX_PORTS + FM_MAX_NUM_OF_1G_TX_PORTS)
100069 +
100070 +#define FM_PORT_MAX_NUM_OF_EXT_POOLS 8 /**< Number of external BM pools per Rx port */
100071 +#define FM_PORT_NUM_OF_CONGESTION_GRPS 256 /**< Total number of congestion groups in QM */
100072 +#define FM_MAX_NUM_OF_SUB_PORTALS 12
100073 +#define FM_PORT_MAX_NUM_OF_OBSERVED_EXT_POOLS 0
100074 +
100075 +/* Rams defines */
100076 +#define FM_MURAM_SIZE (160*KILOBYTE)
100077 +#define FM_IRAM_SIZE(major, minor) (64 * KILOBYTE)
100078 +#define FM_NUM_OF_CTRL 2
100079 +
100080 +/* PCD defines */
100081 +#define FM_PCD_PLCR_NUM_ENTRIES 256 /**< Total number of policer profiles */
100082 +#define FM_PCD_KG_NUM_OF_SCHEMES 32 /**< Total number of KG schemes */
100083 +#define FM_PCD_MAX_NUM_OF_CLS_PLANS 256 /**< Number of classification plan entries. */
100084 +#define FM_PCD_PRS_SW_PATCHES_SIZE 0x00000200 /**< Number of bytes saved for patches */
100085 +#define FM_PCD_SW_PRS_SIZE 0x00000800 /**< Total size of SW parser area */
100086 +
100087 +/* RTC defines */
100088 +#define FM_RTC_NUM_OF_ALARMS 2 /**< RTC number of alarms */
100089 +#define FM_RTC_NUM_OF_PERIODIC_PULSES 2 /**< RTC number of periodic pulses */
100090 +#define FM_RTC_NUM_OF_EXT_TRIGGERS 2 /**< RTC number of external triggers */
100091 +
100092 +/* QMI defines */
100093 +#define QMI_MAX_NUM_OF_TNUMS 64
100094 +#define QMI_DEF_TNUMS_THRESH 48
100095 +
100096 +/* FPM defines */
100097 +#define FM_NUM_OF_FMAN_CTRL_EVENT_REGS 4
100098 +
100099 +/* DMA defines */
100100 +#define DMA_THRESH_MAX_COMMQ 31
100101 +#define DMA_THRESH_MAX_BUF 127
100102 +
100103 +/* BMI defines */
100104 +#define BMI_MAX_NUM_OF_TASKS 128
100105 +#define BMI_MAX_NUM_OF_DMAS 32
100106 +#define BMI_MAX_FIFO_SIZE (FM_MURAM_SIZE)
100107 +#define PORT_MAX_WEIGHT 16
100108 +
100109 +
100110 +#define FM_CHECK_PORT_RESTRICTIONS(__validPorts, __newPortIndx) TRUE
100111 +
100112 +/* p4080-rev1 unique features */
100113 +#define QM_CGS_NO_FRAME_MODE
100114 +
100115 +/* p4080 unique features */
100116 +#define FM_NO_DISPATCH_RAM_ECC
100117 +#define FM_NO_WATCHDOG
100118 +#define FM_NO_TNUM_AGING
100119 +#define FM_KG_NO_BYPASS_FQID_GEN
100120 +#define FM_KG_NO_BYPASS_PLCR_PROFILE_GEN
100121 +#define FM_NO_BACKUP_POOLS
100122 +#define FM_NO_OP_OBSERVED_POOLS
100123 +#define FM_NO_ADVANCED_RATE_LIMITER
100124 +#define FM_NO_OP_OBSERVED_CGS
100125 +#define FM_HAS_TOTAL_DMAS
100126 +#define FM_KG_NO_IPPID_SUPPORT
100127 +#define FM_NO_GUARANTEED_RESET_VALUES
100128 +#define FM_MAC_RESET
100129 +
100130 +/* FM erratas */
100131 +#define FM_TX_ECC_FRMS_ERRATA_10GMAC_A004
100132 +#define FM_TX_SHORT_FRAME_BAD_TS_ERRATA_10GMAC_A006 /* No implementation, Out of LLD scope */
100133 +#define FM_TX_FIFO_CORRUPTION_ERRATA_10GMAC_A007
100134 +#define FM_ECC_HALT_NO_SYNC_ERRATA_10GMAC_A008
100135 +#define FM_TX_INVALID_ECC_ERRATA_10GMAC_A009 /* Out of LLD scope, user may disable ECC exceptions using FM_DisableRamsEcc */
100136 +#define FM_BAD_VLAN_DETECT_ERRATA_10GMAC_A010
100137 +
100138 +#define FM_RX_PREAM_4_ERRATA_DTSEC_A001
100139 +#define FM_GRS_ERRATA_DTSEC_A002
100140 +#define FM_BAD_TX_TS_IN_B_2_B_ERRATA_DTSEC_A003
100141 +#define FM_GTS_ERRATA_DTSEC_A004
100142 +#define FM_GTS_AFTER_MAC_ABORTED_FRAME_ERRATA_DTSEC_A0012
100143 +#define FM_GTS_UNDERRUN_ERRATA_DTSEC_A0014
100144 +#define FM_GTS_AFTER_DROPPED_FRAME_ERRATA_DTSEC_A004839
100145 +
100146 +#define FM_MAGIC_PACKET_UNRECOGNIZED_ERRATA_DTSEC2 /* No implementation, Out of LLD scope */
100147 +#define FM_TX_LOCKUP_ERRATA_DTSEC6
100148 +
100149 +#define FM_HC_DEF_FQID_ONLY_ERRATA_FMAN_A003 /* Implemented by ucode */
100150 +#define FM_DEBUG_TRACE_FMAN_A004 /* No implementation, Out of LLD scope */
100151 +
100152 +#define FM_UCODE_NOT_RESET_ERRATA_BUGZILLA6173
100153 +
100154 +#define FM_10G_REM_N_LCL_FLT_EX_10GMAC_ERRATA_SW005
100155 +
100156 +#define FM_LEN_CHECK_ERRATA_FMAN_SW002
100157 +
100158 +#define FM_NO_CTXA_COPY_ERRATA_FMAN_SW001
100159 +#define FM_KG_ERASE_FLOW_ID_ERRATA_FMAN_SW004
100160 +
100161 +/*****************************************************************************
100162 + FM MACSEC INTEGRATION-SPECIFIC DEFINITIONS
100163 +******************************************************************************/
100164 +#define NUM_OF_RX_SC 16
100165 +#define NUM_OF_TX_SC 16
100166 +
100167 +#define NUM_OF_SA_PER_RX_SC 2
100168 +#define NUM_OF_SA_PER_TX_SC 2
100169 +
100170 +
100171 +#endif /* __DPAA_INTEGRATION_EXT_H */
100172 --- /dev/null
100173 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/integrations/P3040_P4080_P5020/part_ext.h
100174 @@ -0,0 +1,83 @@
100175 +/*
100176 + * Copyright 2008-2012 Freescale Semiconductor Inc.
100177 + *
100178 + * Redistribution and use in source and binary forms, with or without
100179 + * modification, are permitted provided that the following conditions are met:
100180 + * * Redistributions of source code must retain the above copyright
100181 + * notice, this list of conditions and the following disclaimer.
100182 + * * Redistributions in binary form must reproduce the above copyright
100183 + * notice, this list of conditions and the following disclaimer in the
100184 + * documentation and/or other materials provided with the distribution.
100185 + * * Neither the name of Freescale Semiconductor nor the
100186 + * names of its contributors may be used to endorse or promote products
100187 + * derived from this software without specific prior written permission.
100188 + *
100189 + *
100190 + * ALTERNATIVELY, this software may be distributed under the terms of the
100191 + * GNU General Public License ("GPL") as published by the Free Software
100192 + * Foundation, either version 2 of that License or (at your option) any
100193 + * later version.
100194 + *
100195 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
100196 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
100197 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
100198 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
100199 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
100200 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
100201 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
100202 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
100203 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
100204 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
100205 + */
100206 +
100207 +/**************************************************************************//**
100208 +
100209 + @File part_ext.h
100210 +
100211 + @Description Definitions for the part (integration) module.
100212 +*//***************************************************************************/
100213 +
100214 +#ifndef __PART_EXT_H
100215 +#define __PART_EXT_H
100216 +
100217 +#include "std_ext.h"
100218 +#include "part_integration_ext.h"
100219 +
100220 +
100221 +#if !(defined(MPC8306) || \
100222 + defined(MPC8309) || \
100223 + defined(MPC834x) || \
100224 + defined(MPC836x) || \
100225 + defined(MPC832x) || \
100226 + defined(MPC837x) || \
100227 + defined(MPC8568) || \
100228 + defined(MPC8569) || \
100229 + defined(P1020) || \
100230 + defined(P1021) || \
100231 + defined(P1022) || \
100232 + defined(P1023) || \
100233 + defined(P2020) || \
100234 + defined(P2040) || \
100235 + defined(P3041) || \
100236 + defined(P4080) || \
100237 + defined(SC4080) || \
100238 + defined(P5020) || \
100239 + defined(MSC814x))
100240 +#error "unable to proceed without chip-definition"
100241 +#endif /* !(defined(MPC834x) || ... */
100242 +
100243 +
100244 +/**************************************************************************//*
100245 + @Description Part data structure - must be contained in any integration
100246 + data structure.
100247 +*//***************************************************************************/
100248 +typedef struct t_Part
100249 +{
100250 + uintptr_t (* f_GetModuleBase)(t_Handle h_Part, e_ModuleId moduleId);
100251 + /**< Returns the address of the module's memory map base. */
100252 + e_ModuleId (* f_GetModuleIdByBase)(t_Handle h_Part, uintptr_t baseAddress);
100253 + /**< Returns the module's ID according to its memory map base. */
100254 +} t_Part;
100255 +
100256 +
100257 +#endif /* __PART_EXT_H */
100258 --- /dev/null
100259 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/integrations/P3040_P4080_P5020/part_integration_ext.h
100260 @@ -0,0 +1,336 @@
100261 +/* Copyright (c) 2008-2012 Freescale Semiconductor, Inc
100262 + * All rights reserved.
100263 + *
100264 + * Redistribution and use in source and binary forms, with or without
100265 + * modification, are permitted provided that the following conditions are met:
100266 + * * Redistributions of source code must retain the above copyright
100267 + * notice, this list of conditions and the following disclaimer.
100268 + * * Redistributions in binary form must reproduce the above copyright
100269 + * notice, this list of conditions and the following disclaimer in the
100270 + * documentation and/or other materials provided with the distribution.
100271 + * * Neither the name of Freescale Semiconductor nor the
100272 + * names of its contributors may be used to endorse or promote products
100273 + * derived from this software without specific prior written permission.
100274 + *
100275 + *
100276 + * ALTERNATIVELY, this software may be distributed under the terms of the
100277 + * GNU General Public License ("GPL") as published by the Free Software
100278 + * Foundation, either version 2 of that License or (at your option) any
100279 + * later version.
100280 + *
100281 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
100282 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
100283 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
100284 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
100285 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
100286 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
100287 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
100288 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
100289 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
100290 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
100291 + */
100292 +
100293 +/**************************************************************************//**
100294 + @File part_integration_ext.h
100295 +
100296 + @Description P3040/P4080/P5020 external definitions and structures.
100297 +*//***************************************************************************/
100298 +#ifndef __PART_INTEGRATION_EXT_H
100299 +#define __PART_INTEGRATION_EXT_H
100300 +
100301 +#include "std_ext.h"
100302 +#include "dpaa_integration_ext.h"
100303 +
100304 +
100305 +/**************************************************************************//**
100306 + @Group P3040/P4080/P5020_chip_id P5020 Application Programming Interface
100307 +
100308 + @Description P3040/P4080/P5020 Chip functions,definitions and enums.
100309 +
100310 + @{
100311 +*//***************************************************************************/
100312 +
100313 +#define CORE_E500MC
100314 +
100315 +#define INTG_MAX_NUM_OF_CORES 1
100316 +
100317 +
100318 +/**************************************************************************//**
100319 + @Description Module types.
100320 +*//***************************************************************************/
100321 +typedef enum e_ModuleId
100322 +{
100323 + e_MODULE_ID_DUART_1 = 0,
100324 + e_MODULE_ID_DUART_2,
100325 + e_MODULE_ID_DUART_3,
100326 + e_MODULE_ID_DUART_4,
100327 + e_MODULE_ID_LAW,
100328 + e_MODULE_ID_LBC,
100329 + e_MODULE_ID_PAMU,
100330 + e_MODULE_ID_QM, /**< Queue manager module */
100331 + e_MODULE_ID_BM, /**< Buffer manager module */
100332 + e_MODULE_ID_QM_CE_PORTAL_0,
100333 + e_MODULE_ID_QM_CI_PORTAL_0,
100334 + e_MODULE_ID_QM_CE_PORTAL_1,
100335 + e_MODULE_ID_QM_CI_PORTAL_1,
100336 + e_MODULE_ID_QM_CE_PORTAL_2,
100337 + e_MODULE_ID_QM_CI_PORTAL_2,
100338 + e_MODULE_ID_QM_CE_PORTAL_3,
100339 + e_MODULE_ID_QM_CI_PORTAL_3,
100340 + e_MODULE_ID_QM_CE_PORTAL_4,
100341 + e_MODULE_ID_QM_CI_PORTAL_4,
100342 + e_MODULE_ID_QM_CE_PORTAL_5,
100343 + e_MODULE_ID_QM_CI_PORTAL_5,
100344 + e_MODULE_ID_QM_CE_PORTAL_6,
100345 + e_MODULE_ID_QM_CI_PORTAL_6,
100346 + e_MODULE_ID_QM_CE_PORTAL_7,
100347 + e_MODULE_ID_QM_CI_PORTAL_7,
100348 + e_MODULE_ID_QM_CE_PORTAL_8,
100349 + e_MODULE_ID_QM_CI_PORTAL_8,
100350 + e_MODULE_ID_QM_CE_PORTAL_9,
100351 + e_MODULE_ID_QM_CI_PORTAL_9,
100352 + e_MODULE_ID_BM_CE_PORTAL_0,
100353 + e_MODULE_ID_BM_CI_PORTAL_0,
100354 + e_MODULE_ID_BM_CE_PORTAL_1,
100355 + e_MODULE_ID_BM_CI_PORTAL_1,
100356 + e_MODULE_ID_BM_CE_PORTAL_2,
100357 + e_MODULE_ID_BM_CI_PORTAL_2,
100358 + e_MODULE_ID_BM_CE_PORTAL_3,
100359 + e_MODULE_ID_BM_CI_PORTAL_3,
100360 + e_MODULE_ID_BM_CE_PORTAL_4,
100361 + e_MODULE_ID_BM_CI_PORTAL_4,
100362 + e_MODULE_ID_BM_CE_PORTAL_5,
100363 + e_MODULE_ID_BM_CI_PORTAL_5,
100364 + e_MODULE_ID_BM_CE_PORTAL_6,
100365 + e_MODULE_ID_BM_CI_PORTAL_6,
100366 + e_MODULE_ID_BM_CE_PORTAL_7,
100367 + e_MODULE_ID_BM_CI_PORTAL_7,
100368 + e_MODULE_ID_BM_CE_PORTAL_8,
100369 + e_MODULE_ID_BM_CI_PORTAL_8,
100370 + e_MODULE_ID_BM_CE_PORTAL_9,
100371 + e_MODULE_ID_BM_CI_PORTAL_9,
100372 + e_MODULE_ID_FM1, /**< Frame manager #1 module */
100373 + e_MODULE_ID_FM1_RTC, /**< FM Real-Time-Clock */
100374 + e_MODULE_ID_FM1_MURAM, /**< FM Multi-User-RAM */
100375 + e_MODULE_ID_FM1_BMI, /**< FM BMI block */
100376 + e_MODULE_ID_FM1_QMI, /**< FM QMI block */
100377 + e_MODULE_ID_FM1_PRS, /**< FM parser block */
100378 + e_MODULE_ID_FM1_PORT_HO0, /**< FM Host-command/offline-parsing port block */
100379 + e_MODULE_ID_FM1_PORT_HO1, /**< FM Host-command/offline-parsing port block */
100380 + e_MODULE_ID_FM1_PORT_HO2, /**< FM Host-command/offline-parsing port block */
100381 + e_MODULE_ID_FM1_PORT_HO3, /**< FM Host-command/offline-parsing port block */
100382 + e_MODULE_ID_FM1_PORT_HO4, /**< FM Host-command/offline-parsing port block */
100383 + e_MODULE_ID_FM1_PORT_HO5, /**< FM Host-command/offline-parsing port block */
100384 + e_MODULE_ID_FM1_PORT_HO6, /**< FM Host-command/offline-parsing port block */
100385 + e_MODULE_ID_FM1_PORT_1GRx0, /**< FM Rx 1G MAC port block */
100386 + e_MODULE_ID_FM1_PORT_1GRx1, /**< FM Rx 1G MAC port block */
100387 + e_MODULE_ID_FM1_PORT_1GRx2, /**< FM Rx 1G MAC port block */
100388 + e_MODULE_ID_FM1_PORT_1GRx3, /**< FM Rx 1G MAC port block */
100389 + e_MODULE_ID_FM1_PORT_1GRx4, /**< FM Rx 1G MAC port block */
100390 + e_MODULE_ID_FM1_PORT_10GRx0, /**< FM Rx 10G MAC port block */
100391 + e_MODULE_ID_FM1_PORT_1GTx0, /**< FM Tx 1G MAC port block */
100392 + e_MODULE_ID_FM1_PORT_1GTx1, /**< FM Tx 1G MAC port block */
100393 + e_MODULE_ID_FM1_PORT_1GTx2, /**< FM Tx 1G MAC port block */
100394 + e_MODULE_ID_FM1_PORT_1GTx3, /**< FM Tx 1G MAC port block */
100395 + e_MODULE_ID_FM1_PORT_1GTx4, /**< FM Tx 1G MAC port block */
100396 + e_MODULE_ID_FM1_PORT_10GTx0, /**< FM Tx 10G MAC port block */
100397 + e_MODULE_ID_FM1_PLCR, /**< FM Policer */
100398 + e_MODULE_ID_FM1_KG, /**< FM Keygen */
100399 + e_MODULE_ID_FM1_DMA, /**< FM DMA */
100400 + e_MODULE_ID_FM1_FPM, /**< FM FPM */
100401 + e_MODULE_ID_FM1_IRAM, /**< FM Instruction-RAM */
100402 + e_MODULE_ID_FM1_1GMDIO0, /**< FM 1G MDIO MAC 0*/
100403 + e_MODULE_ID_FM1_1GMDIO1, /**< FM 1G MDIO MAC 1*/
100404 + e_MODULE_ID_FM1_1GMDIO2, /**< FM 1G MDIO MAC 2*/
100405 + e_MODULE_ID_FM1_1GMDIO3, /**< FM 1G MDIO MAC 3*/
100406 + e_MODULE_ID_FM1_10GMDIO, /**< FM 10G MDIO */
100407 + e_MODULE_ID_FM1_PRS_IRAM, /**< FM SW-parser Instruction-RAM */
100408 + e_MODULE_ID_FM1_1GMAC0, /**< FM 1G MAC #0 */
100409 + e_MODULE_ID_FM1_1GMAC1, /**< FM 1G MAC #1 */
100410 + e_MODULE_ID_FM1_1GMAC2, /**< FM 1G MAC #2 */
100411 + e_MODULE_ID_FM1_1GMAC3, /**< FM 1G MAC #3 */
100412 + e_MODULE_ID_FM1_10GMAC0, /**< FM 10G MAC #0 */
100413 +
100414 + e_MODULE_ID_FM2, /**< Frame manager #2 module */
100415 + e_MODULE_ID_FM2_RTC, /**< FM Real-Time-Clock */
100416 + e_MODULE_ID_FM2_MURAM, /**< FM Multi-User-RAM */
100417 + e_MODULE_ID_FM2_BMI, /**< FM BMI block */
100418 + e_MODULE_ID_FM2_QMI, /**< FM QMI block */
100419 + e_MODULE_ID_FM2_PRS, /**< FM parser block */
100420 + e_MODULE_ID_FM2_PORT_HO0, /**< FM Host-command/offline-parsing port block */
100421 + e_MODULE_ID_FM2_PORT_HO1, /**< FM Host-command/offline-parsing port block */
100422 + e_MODULE_ID_FM2_PORT_HO2, /**< FM Host-command/offline-parsing port block */
100423 + e_MODULE_ID_FM2_PORT_HO3, /**< FM Host-command/offline-parsing port block */
100424 + e_MODULE_ID_FM2_PORT_HO4, /**< FM Host-command/offline-parsing port block */
100425 + e_MODULE_ID_FM2_PORT_HO5, /**< FM Host-command/offline-parsing port block */
100426 + e_MODULE_ID_FM2_PORT_HO6, /**< FM Host-command/offline-parsing port block */
100427 + e_MODULE_ID_FM2_PORT_1GRx0, /**< FM Rx 1G MAC port block */
100428 + e_MODULE_ID_FM2_PORT_1GRx1, /**< FM Rx 1G MAC port block */
100429 + e_MODULE_ID_FM2_PORT_1GRx2, /**< FM Rx 1G MAC port block */
100430 + e_MODULE_ID_FM2_PORT_1GRx3, /**< FM Rx 1G MAC port block */
100431 + e_MODULE_ID_FM2_PORT_10GRx0, /**< FM Rx 10G MAC port block */
100432 + e_MODULE_ID_FM2_PORT_1GTx0, /**< FM Tx 1G MAC port block */
100433 + e_MODULE_ID_FM2_PORT_1GTx1, /**< FM Tx 1G MAC port block */
100434 + e_MODULE_ID_FM2_PORT_1GTx2, /**< FM Tx 1G MAC port block */
100435 + e_MODULE_ID_FM2_PORT_1GTx3, /**< FM Tx 1G MAC port block */
100436 + e_MODULE_ID_FM2_PORT_10GTx0, /**< FM Tx 10G MAC port block */
100437 + e_MODULE_ID_FM2_PLCR, /**< FM Policer */
100438 + e_MODULE_ID_FM2_KG, /**< FM Keygen */
100439 + e_MODULE_ID_FM2_DMA, /**< FM DMA */
100440 + e_MODULE_ID_FM2_FPM, /**< FM FPM */
100441 + e_MODULE_ID_FM2_IRAM, /**< FM Instruction-RAM */
100442 + e_MODULE_ID_FM2_1GMDIO0, /**< FM 1G MDIO MAC 0*/
100443 + e_MODULE_ID_FM2_1GMDIO1, /**< FM 1G MDIO MAC 1*/
100444 + e_MODULE_ID_FM2_1GMDIO2, /**< FM 1G MDIO MAC 2*/
100445 + e_MODULE_ID_FM2_1GMDIO3, /**< FM 1G MDIO MAC 3*/
100446 + e_MODULE_ID_FM2_10GMDIO, /**< FM 10G MDIO */
100447 + e_MODULE_ID_FM2_PRS_IRAM, /**< FM SW-parser Instruction-RAM */
100448 + e_MODULE_ID_FM2_1GMAC0, /**< FM 1G MAC #0 */
100449 + e_MODULE_ID_FM2_1GMAC1, /**< FM 1G MAC #1 */
100450 + e_MODULE_ID_FM2_1GMAC2, /**< FM 1G MAC #2 */
100451 + e_MODULE_ID_FM2_1GMAC3, /**< FM 1G MAC #3 */
100452 + e_MODULE_ID_FM2_10GMAC0, /**< FM 10G MAC #0 */
100453 +
100454 + e_MODULE_ID_SEC_GEN, /**< SEC 4.0 General registers */
100455 + e_MODULE_ID_SEC_QI, /**< SEC 4.0 QI registers */
100456 + e_MODULE_ID_SEC_JQ0, /**< SEC 4.0 JQ-0 registers */
100457 + e_MODULE_ID_SEC_JQ1, /**< SEC 4.0 JQ-1 registers */
100458 + e_MODULE_ID_SEC_JQ2, /**< SEC 4.0 JQ-2 registers */
100459 + e_MODULE_ID_SEC_JQ3, /**< SEC 4.0 JQ-3 registers */
100460 + e_MODULE_ID_SEC_RTIC, /**< SEC 4.0 RTIC registers */
100461 + e_MODULE_ID_SEC_DECO0_CCB0, /**< SEC 4.0 DECO-0/CCB-0 registers */
100462 + e_MODULE_ID_SEC_DECO1_CCB1, /**< SEC 4.0 DECO-1/CCB-1 registers */
100463 + e_MODULE_ID_SEC_DECO2_CCB2, /**< SEC 4.0 DECO-2/CCB-2 registers */
100464 + e_MODULE_ID_SEC_DECO3_CCB3, /**< SEC 4.0 DECO-3/CCB-3 registers */
100465 + e_MODULE_ID_SEC_DECO4_CCB4, /**< SEC 4.0 DECO-4/CCB-4 registers */
100466 +
100467 + e_MODULE_ID_MPIC, /**< MPIC */
100468 + e_MODULE_ID_GPIO, /**< GPIO */
100469 + e_MODULE_ID_SERDES, /**< SERDES */
100470 + e_MODULE_ID_CPC_1, /**< CoreNet-Platform-Cache 1 */
100471 + e_MODULE_ID_CPC_2, /**< CoreNet-Platform-Cache 2 */
100472 +
100473 + e_MODULE_ID_SRIO_PORTS, /**< RapidIO controller */
100474 + e_MODULE_ID_SRIO_MU, /**< RapidIO messaging unit module */
100475 +
100476 + e_MODULE_ID_DUMMY_LAST
100477 +} e_ModuleId;
100478 +
100479 +#define NUM_OF_MODULES e_MODULE_ID_DUMMY_LAST
100480 +
100481 +#if 0 /* using unified values */
100482 +/*****************************************************************************
100483 + INTEGRATION-SPECIFIC MODULE CODES
100484 +******************************************************************************/
100485 +#define MODULE_UNKNOWN 0x00000000
100486 +#define MODULE_MEM 0x00010000
100487 +#define MODULE_MM 0x00020000
100488 +#define MODULE_CORE 0x00030000
100489 +#define MODULE_CHIP 0x00040000
100490 +#define MODULE_PLTFRM 0x00050000
100491 +#define MODULE_PM 0x00060000
100492 +#define MODULE_MMU 0x00070000
100493 +#define MODULE_PIC 0x00080000
100494 +#define MODULE_CPC 0x00090000
100495 +#define MODULE_DUART 0x000a0000
100496 +#define MODULE_SERDES 0x000b0000
100497 +#define MODULE_PIO 0x000c0000
100498 +#define MODULE_QM 0x000d0000
100499 +#define MODULE_BM 0x000e0000
100500 +#define MODULE_SEC 0x000f0000
100501 +#define MODULE_LAW 0x00100000
100502 +#define MODULE_LBC 0x00110000
100503 +#define MODULE_PAMU 0x00120000
100504 +#define MODULE_FM 0x00130000
100505 +#define MODULE_FM_MURAM 0x00140000
100506 +#define MODULE_FM_PCD 0x00150000
100507 +#define MODULE_FM_RTC 0x00160000
100508 +#define MODULE_FM_MAC 0x00170000
100509 +#define MODULE_FM_PORT 0x00180000
100510 +#define MODULE_FM_SP 0x00190000
100511 +#define MODULE_DPA_PORT 0x001a0000
100512 +#define MODULE_MII 0x001b0000
100513 +#define MODULE_I2C 0x001c0000
100514 +#define MODULE_DMA 0x001d0000
100515 +#define MODULE_DDR 0x001e0000
100516 +#define MODULE_ESPI 0x001f0000
100517 +#define MODULE_DPAA_IPSEC 0x00200000
100518 +#endif /* using unified values */
100519 +
100520 +/*****************************************************************************
100521 + PAMU INTEGRATION-SPECIFIC DEFINITIONS
100522 +******************************************************************************/
100523 +#define PAMU_NUM_OF_PARTITIONS 5
100524 +
100525 +#define PAMU_PICS_AVICS_ERRATA_PAMU3
100526 +
100527 +/*****************************************************************************
100528 + LAW INTEGRATION-SPECIFIC DEFINITIONS
100529 +******************************************************************************/
100530 +#define LAW_NUM_OF_WINDOWS 32
100531 +#define LAW_MIN_WINDOW_SIZE 0x0000000000001000LL /**< 4KB */
100532 +#define LAW_MAX_WINDOW_SIZE 0x0000002000000000LL /**< 64GB */
100533 +
100534 +
100535 +/*****************************************************************************
100536 + LBC INTEGRATION-SPECIFIC DEFINITIONS
100537 +******************************************************************************/
100538 +/**************************************************************************//**
100539 + @Group lbc_exception_grp LBC Exception Unit
100540 +
100541 + @Description LBC Exception unit API functions, definitions and enums
100542 +
100543 + @{
100544 +*//***************************************************************************/
100545 +
100546 +/**************************************************************************//**
100547 + @Anchor lbc_exbm
100548 +
100549 + @Collection LBC Errors Bit Mask
100550 +
100551 + These errors are reported through the exceptions callback..
100552 + The values can be or'ed in any combination in the errors mask
100553 + parameter of the errors report structure.
100554 +
100555 + These errors can also be passed as a bit-mask to
100556 + LBC_EnableErrorChecking() or LBC_DisableErrorChecking(),
100557 + for enabling or disabling error checking.
100558 + @{
100559 +*//***************************************************************************/
100560 +#define LBC_ERR_BUS_MONITOR 0x80000000 /**< Bus monitor error */
100561 +#define LBC_ERR_PARITY_ECC 0x20000000 /**< Parity error for GPCM/UPM */
100562 +#define LBC_ERR_WRITE_PROTECT 0x04000000 /**< Write protection error */
100563 +#define LBC_ERR_ATOMIC_WRITE 0x00800000 /**< Atomic write error */
100564 +#define LBC_ERR_ATOMIC_READ 0x00400000 /**< Atomic read error */
100565 +#define LBC_ERR_CHIP_SELECT 0x00080000 /**< Unrecognized chip select */
100566 +
100567 +#define LBC_ERR_ALL (LBC_ERR_BUS_MONITOR | LBC_ERR_PARITY_ECC | \
100568 + LBC_ERR_WRITE_PROTECT | LBC_ERR_ATOMIC_WRITE | \
100569 + LBC_ERR_ATOMIC_READ | LBC_ERR_CHIP_SELECT)
100570 + /**< All possible errors */
100571 +/* @} */
100572 +/** @} */ /* end of lbc_exception_grp group */
100573 +
100574 +#define LBC_INCORRECT_ERROR_REPORT_ERRATA
100575 +
100576 +#define LBC_NUM_OF_BANKS 8
100577 +#define LBC_MAX_CS_SIZE 0x0000000100000000LL
100578 +#define LBC_ATOMIC_OPERATION_SUPPORT
100579 +#define LBC_PARITY_SUPPORT
100580 +#define LBC_ADDRESS_HOLD_TIME_CTRL
100581 +#define LBC_HIGH_CLK_DIVIDERS
100582 +#define LBC_FCM_AVAILABLE
100583 +
100584 +/*****************************************************************************
100585 + GPIO INTEGRATION-SPECIFIC DEFINITIONS
100586 +******************************************************************************/
100587 +#define GPIO_NUM_OF_PORTS 1 /**< Number of ports in GPIO module;
100588 + Each port contains up to 32 i/O pins. */
100589 +
100590 +#define GPIO_VALID_PIN_MASKS \
100591 + { /* Port A */ 0xFFFFFFFF }
100592 +
100593 +#define GPIO_VALID_INTR_MASKS \
100594 + { /* Port A */ 0xFFFFFFFF }
100595 +
100596 +#endif /* __PART_INTEGRATION_EXT_H */
100597 --- /dev/null
100598 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/math_ext.h
100599 @@ -0,0 +1,100 @@
100600 +/*
100601 + * Copyright 2008-2012 Freescale Semiconductor Inc.
100602 + *
100603 + * Redistribution and use in source and binary forms, with or without
100604 + * modification, are permitted provided that the following conditions are met:
100605 + * * Redistributions of source code must retain the above copyright
100606 + * notice, this list of conditions and the following disclaimer.
100607 + * * Redistributions in binary form must reproduce the above copyright
100608 + * notice, this list of conditions and the following disclaimer in the
100609 + * documentation and/or other materials provided with the distribution.
100610 + * * Neither the name of Freescale Semiconductor nor the
100611 + * names of its contributors may be used to endorse or promote products
100612 + * derived from this software without specific prior written permission.
100613 + *
100614 + *
100615 + * ALTERNATIVELY, this software may be distributed under the terms of the
100616 + * GNU General Public License ("GPL") as published by the Free Software
100617 + * Foundation, either version 2 of that License or (at your option) any
100618 + * later version.
100619 + *
100620 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
100621 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
100622 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
100623 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
100624 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
100625 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
100626 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
100627 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
100628 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
100629 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
100630 + */
100631 +
100632 +
100633 +#ifndef __MATH_EXT_H
100634 +#define __MATH_EXT_H
100635 +
100636 +
100637 +#if defined(NCSW_LINUX) && defined(__KERNEL__)
100638 +#include <linux/math.h>
100639 +#include <linux/math64.h>
100640 +
100641 +#elif defined(__MWERKS__)
100642 +#define LOW(x) ( sizeof(x)==8 ? *(1+(int32_t*)&x) : (*(int32_t*)&x))
100643 +#define HIGH(x) (*(int32_t*)&x)
100644 +#define ULOW(x) ( sizeof(x)==8 ? *(1+(uint32_t*)&x) : (*(uint32_t*)&x))
100645 +#define UHIGH(x) (*(uint32_t*)&x)
100646 +
100647 +static const double big = 1.0e300;
100648 +
100649 +/* Macro for checking if a number is a power of 2 */
100650 +static __inline__ double ceil(double x)
100651 +{
100652 + int32_t i0,i1,j0; /*- cc 020130 -*/
100653 + uint32_t i,j; /*- cc 020130 -*/
100654 + i0 = HIGH(x);
100655 + i1 = LOW(x);
100656 + j0 = ((i0>>20)&0x7ff)-0x3ff;
100657 + if(j0<20) {
100658 + if(j0<0) { /* raise inexact if x != 0 */
100659 + if(big+x>0.0) {/* return 0*sign(x) if |x|<1 */
100660 + if(i0<0) {i0=0x80000000;i1=0;}
100661 + else if((i0|i1)!=0) { i0=0x3ff00000;i1=0;}
100662 + }
100663 + } else {
100664 + i = (uint32_t)(0x000fffff)>>j0;
100665 + if(((i0&i)|i1)==0) return x; /* x is integral */
100666 + if(big+x>0.0) { /* raise inexact flag */
100667 + if(i0>0) i0 += (0x00100000)>>j0;
100668 + i0 &= (~i); i1=0;
100669 + }
100670 + }
100671 + } else if (j0>51) {
100672 + if(j0==0x400) return x+x; /* inf or NaN */
100673 + else return x; /* x is integral */
100674 + } else {
100675 + i = ((uint32_t)(0xffffffff))>>(j0-20); /*- cc 020130 -*/
100676 + if((i1&i)==0) return x; /* x is integral */
100677 + if(big+x>0.0) { /* raise inexact flag */
100678 + if(i0>0) {
100679 + if(j0==20) i0+=1;
100680 + else {
100681 + j = (uint32_t)(i1 + (1<<(52-j0)));
100682 + if(j<i1) i0+=1; /* got a carry */
100683 + i1 = (int32_t)j;
100684 + }
100685 + }
100686 + i1 &= (~i);
100687 + }
100688 + }
100689 + HIGH(x) = i0;
100690 + LOW(x) = i1;
100691 + return x;
100692 +}
100693 +
100694 +#else
100695 +#include <math.h>
100696 +#endif /* defined(NCSW_LINUX) && defined(__KERNEL__) */
100697 +
100698 +
100699 +#endif /* __MATH_EXT_H */
100700 --- /dev/null
100701 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/ncsw_ext.h
100702 @@ -0,0 +1,435 @@
100703 +/* Copyright (c) 2008-2012 Freescale Semiconductor, Inc
100704 + * All rights reserved.
100705 + *
100706 + * Redistribution and use in source and binary forms, with or without
100707 + * modification, are permitted provided that the following conditions are met:
100708 + * * Redistributions of source code must retain the above copyright
100709 + * notice, this list of conditions and the following disclaimer.
100710 + * * Redistributions in binary form must reproduce the above copyright
100711 + * notice, this list of conditions and the following disclaimer in the
100712 + * documentation and/or other materials provided with the distribution.
100713 + * * Neither the name of Freescale Semiconductor nor the
100714 + * names of its contributors may be used to endorse or promote products
100715 + * derived from this software without specific prior written permission.
100716 + *
100717 + *
100718 + * ALTERNATIVELY, this software may be distributed under the terms of the
100719 + * GNU General Public License ("GPL") as published by the Free Software
100720 + * Foundation, either version 2 of that License or (at your option) any
100721 + * later version.
100722 + *
100723 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
100724 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
100725 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
100726 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
100727 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
100728 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
100729 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
100730 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
100731 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
100732 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
100733 + */
100734 +
100735 +
100736 +/**************************************************************************//**
100737 + @File ncsw_ext.h
100738 +
100739 + @Description General NetCommSw Standard Definitions
100740 +*//***************************************************************************/
100741 +
100742 +#ifndef __NCSW_EXT_H
100743 +#define __NCSW_EXT_H
100744 +
100745 +
100746 +#include "memcpy_ext.h"
100747 +
100748 +#define WRITE_BLOCK IOMemSet32 /* include memcpy_ext.h */
100749 +#define COPY_BLOCK Mem2IOCpy32 /* include memcpy_ext.h */
100750 +
100751 +#define PTR_TO_UINT(_ptr) ((uintptr_t)(_ptr))
100752 +#define UINT_TO_PTR(_val) ((void*)(uintptr_t)(_val))
100753 +
100754 +#define PTR_MOVE(_ptr, _offset) (void*)((uint8_t*)(_ptr) + (_offset))
100755 +
100756 +
100757 +#define WRITE_UINT8_UINT24(arg, data08, data24) \
100758 + WRITE_UINT32(arg,((uint32_t)(data08)<<24)|((uint32_t)(data24)&0x00FFFFFF))
100759 +#define WRITE_UINT24_UINT8(arg, data24, data08) \
100760 + WRITE_UINT32(arg,((uint32_t)(data24)<< 8)|((uint32_t)(data08)&0x000000FF))
100761 +
100762 +/* Little-Endian access macros */
100763 +
100764 +#define WRITE_UINT16_LE(arg, data) \
100765 + WRITE_UINT16((arg), SwapUint16(data))
100766 +
100767 +#define WRITE_UINT32_LE(arg, data) \
100768 + WRITE_UINT32((arg), SwapUint32(data))
100769 +
100770 +#define WRITE_UINT64_LE(arg, data) \
100771 + WRITE_UINT64((arg), SwapUint64(data))
100772 +
100773 +#define GET_UINT16_LE(arg) \
100774 + SwapUint16(GET_UINT16(arg))
100775 +
100776 +#define GET_UINT32_LE(arg) \
100777 + SwapUint32(GET_UINT32(arg))
100778 +
100779 +#define GET_UINT64_LE(arg) \
100780 + SwapUint64(GET_UINT64(arg))
100781 +
100782 +/* Write and Read again macros */
100783 +#define WRITE_UINT_SYNC(size, arg, data) \
100784 + do { \
100785 + WRITE_UINT##size((arg), (data)); \
100786 + CORE_MemoryBarrier(); \
100787 + } while (0)
100788 +
100789 +#define WRITE_UINT8_SYNC(arg, data) WRITE_UINT_SYNC(8, (arg), (data))
100790 +
100791 +#define WRITE_UINT16_SYNC(arg, data) WRITE_UINT_SYNC(16, (arg), (data))
100792 +#define WRITE_UINT32_SYNC(arg, data) WRITE_UINT_SYNC(32, (arg), (data))
100793 +
100794 +#define MAKE_UINT64(high32, low32) (((uint64_t)high32 << 32) | (low32))
100795 +
100796 +
100797 +/*----------------------*/
100798 +/* Miscellaneous macros */
100799 +/*----------------------*/
100800 +
100801 +#define UNUSED(_x) ((void)(_x))
100802 +
100803 +#define KILOBYTE 0x400UL /* 1024 */
100804 +#define MEGABYTE (KILOBYTE * KILOBYTE) /* 1024*1024 */
100805 +#define GIGABYTE ((uint64_t)(KILOBYTE * MEGABYTE)) /* 1024*1024*1024 */
100806 +#define TERABYTE ((uint64_t)(KILOBYTE * GIGABYTE)) /* 1024*1024*1024*1024 */
100807 +
100808 +#ifndef NO_IRQ
100809 +#define NO_IRQ (0)
100810 +#endif
100811 +#define NCSW_MASTER_ID (0)
100812 +
100813 +/* Macro for checking if a number is a power of 2 */
100814 +#define POWER_OF_2(n) (!((n) & ((n)-1)))
100815 +
100816 +/* Macro for calculating log of base 2 */
100817 +#define LOG2(num, log2Num) \
100818 + do \
100819 + { \
100820 + uint64_t tmp = (num); \
100821 + log2Num = 0; \
100822 + while (tmp > 1) \
100823 + { \
100824 + log2Num++; \
100825 + tmp >>= 1; \
100826 + } \
100827 + } while (0)
100828 +
100829 +#define NEXT_POWER_OF_2(_num, _nextPow) \
100830 +do \
100831 +{ \
100832 + if (POWER_OF_2(_num)) \
100833 + _nextPow = (_num); \
100834 + else \
100835 + { \
100836 + uint64_t tmp = (_num); \
100837 + _nextPow = 1; \
100838 + while (tmp) \
100839 + { \
100840 + _nextPow <<= 1; \
100841 + tmp >>= 1; \
100842 + } \
100843 + } \
100844 +} while (0)
100845 +
100846 +/* Ceiling division - not the fastest way, but safer in terms of overflow */
100847 +#define DIV_CEIL(x,y) (div64_u64((x),(y)) + (((div64_u64((x),(y))*(y)) == (x)) ? 0 : 1))
100848 +
100849 +/* Round up a number to be a multiple of a second number */
100850 +#define ROUND_UP(x,y) ((((x) + (y) - 1) / (y)) * (y))
100851 +
100852 +/* Timing macro for converting usec units to number of ticks. */
100853 +/* (number of usec * clock_Hz) / 1,000,000) - since */
100854 +/* clk is in MHz units, no division needed. */
100855 +#define USEC_TO_CLK(usec,clk) ((usec) * (clk))
100856 +#define CYCLES_TO_USEC(cycles,clk) ((cycles) / (clk))
100857 +
100858 +/* Timing macros for converting between nsec units and number of clocks. */
100859 +#define NSEC_TO_CLK(nsec,clk) DIV_CEIL(((nsec) * (clk)), 1000)
100860 +#define CYCLES_TO_NSEC(cycles,clk) (((cycles) * 1000) / (clk))
100861 +
100862 +/* Timing macros for converting between psec units and number of clocks. */
100863 +#define PSEC_TO_CLK(psec,clk) DIV_CEIL(((psec) * (clk)), 1000000)
100864 +#define CYCLES_TO_PSEC(cycles,clk) (((cycles) * 1000000) / (clk))
100865 +
100866 +/* Min, Max macros */
100867 +#define MIN(a,b) ((a) < (b) ? (a) : (b))
100868 +#define MAX(a,b) ((a) > (b) ? (a) : (b))
100869 +#define IN_RANGE(min,val,max) ((min)<=(val) && (val)<=(max))
100870 +
100871 +#define ABS(a) ((a<0)?(a*-1):a)
100872 +
100873 +#if !(defined(ARRAY_SIZE))
100874 +#define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]))
100875 +#endif /* !defined(ARRAY_SIZE) */
100876 +
100877 +
100878 +/* possible alignments */
100879 +#define HALF_WORD_ALIGNMENT 2
100880 +#define WORD_ALIGNMENT 4
100881 +#define DOUBLE_WORD_ALIGNMENT 8
100882 +#define BURST_ALIGNMENT 32
100883 +
100884 +#define HALF_WORD_ALIGNED 0x00000001
100885 +#define WORD_ALIGNED 0x00000003
100886 +#define DOUBLE_WORD_ALIGNED 0x00000007
100887 +#define BURST_ALIGNED 0x0000001f
100888 +#ifndef IS_ALIGNED
100889 +#define IS_ALIGNED(n,align) (!((uint32_t)(n) & (align - 1)))
100890 +#endif /* IS_ALIGNED */
100891 +
100892 +
100893 +#define LAST_BUF 1
100894 +#define FIRST_BUF 2
100895 +#define SINGLE_BUF (LAST_BUF | FIRST_BUF)
100896 +#define MIDDLE_BUF 4
100897 +
100898 +#define ARRAY_END -1
100899 +
100900 +#define ILLEGAL_BASE (~0)
100901 +
100902 +#define BUF_POSITION(first, last) state[(!!(last))<<1 | !!(first)]
100903 +#define DECLARE_POSITION static uint8_t state[4] = { (uint8_t)MIDDLE_BUF, (uint8_t)FIRST_BUF, (uint8_t)LAST_BUF, (uint8_t)SINGLE_BUF };
100904 +
100905 +
100906 +/**************************************************************************//**
100907 + @Description Timers operation mode
100908 +*//***************************************************************************/
100909 +typedef enum e_TimerMode
100910 +{
100911 + e_TIMER_MODE_INVALID = 0,
100912 + e_TIMER_MODE_FREE_RUN, /**< Free run - counter continues to increase
100913 + after reaching the reference value. */
100914 + e_TIMER_MODE_PERIODIC, /**< Periodic - counter restarts counting from 0
100915 + after reaching the reference value. */
100916 + e_TIMER_MODE_SINGLE /**< Single (one-shot) - counter stops counting
100917 + after reaching the reference value. */
100918 +} e_TimerMode;
100919 +
100920 +
100921 +/**************************************************************************//**
100922 + @Description Enumeration (bit flags) of communication modes (Transmit,
100923 + receive or both).
100924 +*//***************************************************************************/
100925 +typedef enum e_CommMode
100926 +{
100927 + e_COMM_MODE_NONE = 0, /**< No transmit/receive communication */
100928 + e_COMM_MODE_RX = 1, /**< Only receive communication */
100929 + e_COMM_MODE_TX = 2, /**< Only transmit communication */
100930 + e_COMM_MODE_RX_AND_TX = 3 /**< Both transmit and receive communication */
100931 +} e_CommMode;
100932 +
100933 +/**************************************************************************//**
100934 + @Description General Diagnostic Mode
100935 +*//***************************************************************************/
100936 +typedef enum e_DiagMode
100937 +{
100938 + e_DIAG_MODE_NONE = 0, /**< Normal operation; no diagnostic mode */
100939 + e_DIAG_MODE_CTRL_LOOPBACK, /**< Loopback in the controller */
100940 + e_DIAG_MODE_CHIP_LOOPBACK, /**< Loopback in the chip but not in the
100941 + controller; e.g. IO-pins, SerDes, etc. */
100942 + e_DIAG_MODE_PHY_LOOPBACK, /**< Loopback in the external PHY */
100943 + e_DIAG_MODE_EXT_LOOPBACK, /**< Loopback in the external line (beyond the PHY) */
100944 + e_DIAG_MODE_CTRL_ECHO, /**< Echo incoming data by the controller */
100945 + e_DIAG_MODE_PHY_ECHO /**< Echo incoming data by the PHY */
100946 +} e_DiagMode;
100947 +
100948 +/**************************************************************************//**
100949 + @Description Possible RxStore callback responses.
100950 +*//***************************************************************************/
100951 +typedef enum e_RxStoreResponse
100952 +{
100953 + e_RX_STORE_RESPONSE_PAUSE /**< Pause invoking callback with received data;
100954 + in polling mode, start again invoking callback
100955 + only next time user invokes the receive routine;
100956 + in interrupt mode, start again invoking callback
100957 + only next time a receive event triggers an interrupt;
100958 + in all cases, received data that are pending are not
100959 + lost, rather, their processing is temporarily deferred;
100960 + in all cases, received data are processed in the order
100961 + in which they were received. */
100962 + , e_RX_STORE_RESPONSE_CONTINUE /**< Continue invoking callback with received data. */
100963 +} e_RxStoreResponse;
100964 +
100965 +
100966 +/**************************************************************************//**
100967 + @Description General Handle
100968 +*//***************************************************************************/
100969 +typedef void * t_Handle; /**< handle, used as object's descriptor */
100970 +
100971 +/**************************************************************************//**
100972 + @Description MUTEX type
100973 +*//***************************************************************************/
100974 +typedef uint32_t t_Mutex;
100975 +
100976 +/**************************************************************************//**
100977 + @Description Error Code.
100978 +
100979 + The high word of the error code is the code of the software
100980 + module (driver). The low word is the error type (e_ErrorType).
100981 + To get the values from the error code, use GET_ERROR_TYPE()
100982 + and GET_ERROR_MODULE().
100983 +*//***************************************************************************/
100984 +typedef uint32_t t_Error;
100985 +
100986 +/**************************************************************************//**
100987 + @Description General prototype of interrupt service routine (ISR).
100988 +
100989 + @Param[in] handle - Optional handle of the module handling the interrupt.
100990 +
100991 + @Return None
100992 + *//***************************************************************************/
100993 +typedef void (t_Isr)(t_Handle handle);
100994 +
100995 +/**************************************************************************//**
100996 + @Anchor mem_attr
100997 +
100998 + @Collection Memory Attributes
100999 +
101000 + Various attributes of memory partitions. These values may be
101001 + or'ed together to create a mask of all memory attributes.
101002 + @{
101003 +*//***************************************************************************/
101004 +#define MEMORY_ATTR_CACHEABLE 0x00000001
101005 + /**< Memory is cacheable */
101006 +#define MEMORY_ATTR_QE_2ND_BUS_ACCESS 0x00000002
101007 + /**< Memory can be accessed by QUICC Engine
101008 + through its secondary bus interface */
101009 +
101010 +/* @} */
101011 +
101012 +
101013 +/**************************************************************************//**
101014 + @Function t_GetBufFunction
101015 +
101016 + @Description User callback function called by driver to get data buffer.
101017 +
101018 + User provides this function. Driver invokes it.
101019 +
101020 + @Param[in] h_BufferPool - A handle to buffer pool manager
101021 + @Param[out] p_BufContextHandle - Returns the user's private context that
101022 + should be associated with the buffer
101023 +
101024 + @Return Pointer to data buffer, NULL if error
101025 + *//***************************************************************************/
101026 +typedef uint8_t * (t_GetBufFunction)(t_Handle h_BufferPool,
101027 + t_Handle *p_BufContextHandle);
101028 +
101029 +/**************************************************************************//**
101030 + @Function t_PutBufFunction
101031 +
101032 + @Description User callback function called by driver to return data buffer.
101033 +
101034 + User provides this function. Driver invokes it.
101035 +
101036 + @Param[in] h_BufferPool - A handle to buffer pool manager
101037 + @Param[in] p_Buffer - A pointer to buffer to return
101038 + @Param[in] h_BufContext - The user's private context associated with
101039 + the returned buffer
101040 +
101041 + @Return E_OK on success; Error code otherwise
101042 + *//***************************************************************************/
101043 +typedef t_Error (t_PutBufFunction)(t_Handle h_BufferPool,
101044 + uint8_t *p_Buffer,
101045 + t_Handle h_BufContext);
101046 +
101047 +/**************************************************************************//**
101048 + @Function t_PhysToVirt
101049 +
101050 + @Description Translates a physical address to the matching virtual address.
101051 +
101052 + @Param[in] addr - The physical address to translate.
101053 +
101054 + @Return Virtual address.
101055 +*//***************************************************************************/
101056 +typedef void * t_PhysToVirt(physAddress_t addr);
101057 +
101058 +/**************************************************************************//**
101059 + @Function t_VirtToPhys
101060 +
101061 + @Description Translates a virtual address to the matching physical address.
101062 +
101063 + @Param[in] addr - The virtual address to translate.
101064 +
101065 + @Return Physical address.
101066 +*//***************************************************************************/
101067 +typedef physAddress_t t_VirtToPhys(void *addr);
101068 +
101069 +/**************************************************************************//**
101070 + @Description Buffer Pool Information Structure.
101071 +*//***************************************************************************/
101072 +typedef struct t_BufferPoolInfo
101073 +{
101074 + t_Handle h_BufferPool; /**< A handle to the buffer pool manager */
101075 + t_GetBufFunction *f_GetBuf; /**< User callback to get a free buffer */
101076 + t_PutBufFunction *f_PutBuf; /**< User callback to return a buffer */
101077 + uint16_t bufferSize; /**< Buffer size (in bytes) */
101078 +
101079 + t_PhysToVirt *f_PhysToVirt; /**< User callback to translate pool buffers
101080 + physical addresses to virtual addresses */
101081 + t_VirtToPhys *f_VirtToPhys; /**< User callback to translate pool buffers
101082 + virtual addresses to physical addresses */
101083 +} t_BufferPoolInfo;
101084 +
101085 +
101086 +/**************************************************************************//**
101087 + @Description User callback function called by driver when transmit completed.
101088 +
101089 + User provides this function. Driver invokes it.
101090 +
101091 + @Param[in] h_App - Application's handle, as was provided to the
101092 + driver by the user
101093 + @Param[in] queueId - Transmit queue ID
101094 + @Param[in] p_Data - Pointer to the data buffer
101095 + @Param[in] h_BufContext - The user's private context associated with
101096 + the given data buffer
101097 + @Param[in] status - Transmit status and errors
101098 + @Param[in] flags - Driver-dependent information
101099 + *//***************************************************************************/
101100 +typedef void (t_TxConfFunction)(t_Handle h_App,
101101 + uint32_t queueId,
101102 + uint8_t *p_Data,
101103 + t_Handle h_BufContext,
101104 + uint16_t status,
101105 + uint32_t flags);
101106 +
101107 +/**************************************************************************//**
101108 + @Description User callback function called by driver with receive data.
101109 +
101110 + User provides this function. Driver invokes it.
101111 +
101112 + @Param[in] h_App - Application's handle, as was provided to the
101113 + driver by the user
101114 + @Param[in] queueId - Receive queue ID
101115 + @Param[in] p_Data - Pointer to the buffer with received data
101116 + @Param[in] h_BufContext - The user's private context associated with
101117 + the given data buffer
101118 + @Param[in] length - Length of received data
101119 + @Param[in] status - Receive status and errors
101120 + @Param[in] position - Position of buffer in frame
101121 + @Param[in] flags - Driver-dependent information
101122 +
101123 + @Retval e_RX_STORE_RESPONSE_CONTINUE - order the driver to continue Rx
101124 + operation for all ready data.
101125 + @Retval e_RX_STORE_RESPONSE_PAUSE - order the driver to stop Rx operation.
101126 + *//***************************************************************************/
101127 +typedef e_RxStoreResponse (t_RxStoreFunction)(t_Handle h_App,
101128 + uint32_t queueId,
101129 + uint8_t *p_Data,
101130 + t_Handle h_BufContext,
101131 + uint32_t length,
101132 + uint16_t status,
101133 + uint8_t position,
101134 + uint32_t flags);
101135 +
101136 +
101137 +#endif /* __NCSW_EXT_H */
101138 --- /dev/null
101139 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/net_ext.h
101140 @@ -0,0 +1,430 @@
101141 +/*
101142 + * Copyright 2008-2012 Freescale Semiconductor Inc.
101143 + *
101144 + * Redistribution and use in source and binary forms, with or without
101145 + * modification, are permitted provided that the following conditions are met:
101146 + * * Redistributions of source code must retain the above copyright
101147 + * notice, this list of conditions and the following disclaimer.
101148 + * * Redistributions in binary form must reproduce the above copyright
101149 + * notice, this list of conditions and the following disclaimer in the
101150 + * documentation and/or other materials provided with the distribution.
101151 + * * Neither the name of Freescale Semiconductor nor the
101152 + * names of its contributors may be used to endorse or promote products
101153 + * derived from this software without specific prior written permission.
101154 + *
101155 + *
101156 + * ALTERNATIVELY, this software may be distributed under the terms of the
101157 + * GNU General Public License ("GPL") as published by the Free Software
101158 + * Foundation, either version 2 of that License or (at your option) any
101159 + * later version.
101160 + *
101161 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
101162 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
101163 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
101164 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
101165 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
101166 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
101167 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
101168 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
101169 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
101170 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
101171 + */
101172 +
101173 +
101174 +/**************************************************************************//**
101175 + @File net_ext.h
101176 +
101177 + @Description This file contains common and general netcomm headers definitions.
101178 +*//***************************************************************************/
101179 +#ifndef __NET_EXT_H
101180 +#define __NET_EXT_H
101181 +
101182 +#include "std_ext.h"
101183 +
101184 +
101185 +typedef uint8_t headerFieldPpp_t;
101186 +
101187 +#define NET_HEADER_FIELD_PPP_PID (1)
101188 +#define NET_HEADER_FIELD_PPP_COMPRESSED (NET_HEADER_FIELD_PPP_PID << 1)
101189 +#define NET_HEADER_FIELD_PPP_ALL_FIELDS ((NET_HEADER_FIELD_PPP_PID << 2) - 1)
101190 +
101191 +
101192 +typedef uint8_t headerFieldPppoe_t;
101193 +
101194 +#define NET_HEADER_FIELD_PPPoE_VER (1)
101195 +#define NET_HEADER_FIELD_PPPoE_TYPE (NET_HEADER_FIELD_PPPoE_VER << 1)
101196 +#define NET_HEADER_FIELD_PPPoE_CODE (NET_HEADER_FIELD_PPPoE_VER << 2)
101197 +#define NET_HEADER_FIELD_PPPoE_SID (NET_HEADER_FIELD_PPPoE_VER << 3)
101198 +#define NET_HEADER_FIELD_PPPoE_LEN (NET_HEADER_FIELD_PPPoE_VER << 4)
101199 +#define NET_HEADER_FIELD_PPPoE_SESSION (NET_HEADER_FIELD_PPPoE_VER << 5)
101200 +#define NET_HEADER_FIELD_PPPoE_PID (NET_HEADER_FIELD_PPPoE_VER << 6)
101201 +#define NET_HEADER_FIELD_PPPoE_ALL_FIELDS ((NET_HEADER_FIELD_PPPoE_VER << 7) - 1)
101202 +
101203 +#define NET_HEADER_FIELD_PPPMUX_PID (1)
101204 +#define NET_HEADER_FIELD_PPPMUX_CKSUM (NET_HEADER_FIELD_PPPMUX_PID << 1)
101205 +#define NET_HEADER_FIELD_PPPMUX_COMPRESSED (NET_HEADER_FIELD_PPPMUX_PID << 2)
101206 +#define NET_HEADER_FIELD_PPPMUX_ALL_FIELDS ((NET_HEADER_FIELD_PPPMUX_PID << 3) - 1)
101207 +
101208 +#define NET_HEADER_FIELD_PPPMUX_SUBFRAME_PFF (1)
101209 +#define NET_HEADER_FIELD_PPPMUX_SUBFRAME_LXT (NET_HEADER_FIELD_PPPMUX_SUBFRAME_PFF << 1)
101210 +#define NET_HEADER_FIELD_PPPMUX_SUBFRAME_LEN (NET_HEADER_FIELD_PPPMUX_SUBFRAME_PFF << 2)
101211 +#define NET_HEADER_FIELD_PPPMUX_SUBFRAME_PID (NET_HEADER_FIELD_PPPMUX_SUBFRAME_PFF << 3)
101212 +#define NET_HEADER_FIELD_PPPMUX_SUBFRAME_USE_PID (NET_HEADER_FIELD_PPPMUX_SUBFRAME_PFF << 4)
101213 +#define NET_HEADER_FIELD_PPPMUX_SUBFRAME_ALL_FIELDS ((NET_HEADER_FIELD_PPPMUX_SUBFRAME_PFF << 5) - 1)
101214 +
101215 +
101216 +typedef uint8_t headerFieldEth_t;
101217 +
101218 +#define NET_HEADER_FIELD_ETH_DA (1)
101219 +#define NET_HEADER_FIELD_ETH_SA (NET_HEADER_FIELD_ETH_DA << 1)
101220 +#define NET_HEADER_FIELD_ETH_LENGTH (NET_HEADER_FIELD_ETH_DA << 2)
101221 +#define NET_HEADER_FIELD_ETH_TYPE (NET_HEADER_FIELD_ETH_DA << 3)
101222 +#define NET_HEADER_FIELD_ETH_FINAL_CKSUM (NET_HEADER_FIELD_ETH_DA << 4)
101223 +#define NET_HEADER_FIELD_ETH_PADDING (NET_HEADER_FIELD_ETH_DA << 5)
101224 +#define NET_HEADER_FIELD_ETH_ALL_FIELDS ((NET_HEADER_FIELD_ETH_DA << 6) - 1)
101225 +
101226 +#define NET_HEADER_FIELD_ETH_ADDR_SIZE 6
101227 +
101228 +typedef uint16_t headerFieldIp_t;
101229 +
101230 +#define NET_HEADER_FIELD_IP_VER (1)
101231 +#define NET_HEADER_FIELD_IP_DSCP (NET_HEADER_FIELD_IP_VER << 2)
101232 +#define NET_HEADER_FIELD_IP_ECN (NET_HEADER_FIELD_IP_VER << 3)
101233 +#define NET_HEADER_FIELD_IP_PROTO (NET_HEADER_FIELD_IP_VER << 4)
101234 +
101235 +#define NET_HEADER_FIELD_IP_PROTO_SIZE 1
101236 +
101237 +typedef uint16_t headerFieldIpv4_t;
101238 +
101239 +#define NET_HEADER_FIELD_IPv4_VER (1)
101240 +#define NET_HEADER_FIELD_IPv4_HDR_LEN (NET_HEADER_FIELD_IPv4_VER << 1)
101241 +#define NET_HEADER_FIELD_IPv4_TOS (NET_HEADER_FIELD_IPv4_VER << 2)
101242 +#define NET_HEADER_FIELD_IPv4_TOTAL_LEN (NET_HEADER_FIELD_IPv4_VER << 3)
101243 +#define NET_HEADER_FIELD_IPv4_ID (NET_HEADER_FIELD_IPv4_VER << 4)
101244 +#define NET_HEADER_FIELD_IPv4_FLAG_D (NET_HEADER_FIELD_IPv4_VER << 5)
101245 +#define NET_HEADER_FIELD_IPv4_FLAG_M (NET_HEADER_FIELD_IPv4_VER << 6)
101246 +#define NET_HEADER_FIELD_IPv4_OFFSET (NET_HEADER_FIELD_IPv4_VER << 7)
101247 +#define NET_HEADER_FIELD_IPv4_TTL (NET_HEADER_FIELD_IPv4_VER << 8)
101248 +#define NET_HEADER_FIELD_IPv4_PROTO (NET_HEADER_FIELD_IPv4_VER << 9)
101249 +#define NET_HEADER_FIELD_IPv4_CKSUM (NET_HEADER_FIELD_IPv4_VER << 10)
101250 +#define NET_HEADER_FIELD_IPv4_SRC_IP (NET_HEADER_FIELD_IPv4_VER << 11)
101251 +#define NET_HEADER_FIELD_IPv4_DST_IP (NET_HEADER_FIELD_IPv4_VER << 12)
101252 +#define NET_HEADER_FIELD_IPv4_OPTS (NET_HEADER_FIELD_IPv4_VER << 13)
101253 +#define NET_HEADER_FIELD_IPv4_OPTS_COUNT (NET_HEADER_FIELD_IPv4_VER << 14)
101254 +#define NET_HEADER_FIELD_IPv4_ALL_FIELDS ((NET_HEADER_FIELD_IPv4_VER << 15) - 1)
101255 +
101256 +#define NET_HEADER_FIELD_IPv4_ADDR_SIZE 4
101257 +#define NET_HEADER_FIELD_IPv4_PROTO_SIZE 1
101258 +
101259 +
101260 +typedef uint8_t headerFieldIpv6_t;
101261 +
101262 +#define NET_HEADER_FIELD_IPv6_VER (1)
101263 +#define NET_HEADER_FIELD_IPv6_TC (NET_HEADER_FIELD_IPv6_VER << 1)
101264 +#define NET_HEADER_FIELD_IPv6_SRC_IP (NET_HEADER_FIELD_IPv6_VER << 2)
101265 +#define NET_HEADER_FIELD_IPv6_DST_IP (NET_HEADER_FIELD_IPv6_VER << 3)
101266 +#define NET_HEADER_FIELD_IPv6_NEXT_HDR (NET_HEADER_FIELD_IPv6_VER << 4)
101267 +#define NET_HEADER_FIELD_IPv6_FL (NET_HEADER_FIELD_IPv6_VER << 5)
101268 +#define NET_HEADER_FIELD_IPv6_HOP_LIMIT (NET_HEADER_FIELD_IPv6_VER << 6)
101269 +#define NET_HEADER_FIELD_IPv6_ALL_FIELDS ((NET_HEADER_FIELD_IPv6_VER << 7) - 1)
101270 +
101271 +#define NET_HEADER_FIELD_IPv6_ADDR_SIZE 16
101272 +#define NET_HEADER_FIELD_IPv6_NEXT_HDR_SIZE 1
101273 +
101274 +#define NET_HEADER_FIELD_ICMP_TYPE (1)
101275 +#define NET_HEADER_FIELD_ICMP_CODE (NET_HEADER_FIELD_ICMP_TYPE << 1)
101276 +#define NET_HEADER_FIELD_ICMP_CKSUM (NET_HEADER_FIELD_ICMP_TYPE << 2)
101277 +#define NET_HEADER_FIELD_ICMP_ID (NET_HEADER_FIELD_ICMP_TYPE << 3)
101278 +#define NET_HEADER_FIELD_ICMP_SQ_NUM (NET_HEADER_FIELD_ICMP_TYPE << 4)
101279 +#define NET_HEADER_FIELD_ICMP_ALL_FIELDS ((NET_HEADER_FIELD_ICMP_TYPE << 5) - 1)
101280 +
101281 +#define NET_HEADER_FIELD_ICMP_CODE_SIZE 1
101282 +#define NET_HEADER_FIELD_ICMP_TYPE_SIZE 1
101283 +
101284 +#define NET_HEADER_FIELD_IGMP_VERSION (1)
101285 +#define NET_HEADER_FIELD_IGMP_TYPE (NET_HEADER_FIELD_IGMP_VERSION << 1)
101286 +#define NET_HEADER_FIELD_IGMP_CKSUM (NET_HEADER_FIELD_IGMP_VERSION << 2)
101287 +#define NET_HEADER_FIELD_IGMP_DATA (NET_HEADER_FIELD_IGMP_VERSION << 3)
101288 +#define NET_HEADER_FIELD_IGMP_ALL_FIELDS ((NET_HEADER_FIELD_IGMP_VERSION << 4) - 1)
101289 +
101290 +
101291 +typedef uint16_t headerFieldTcp_t;
101292 +
101293 +#define NET_HEADER_FIELD_TCP_PORT_SRC (1)
101294 +#define NET_HEADER_FIELD_TCP_PORT_DST (NET_HEADER_FIELD_TCP_PORT_SRC << 1)
101295 +#define NET_HEADER_FIELD_TCP_SEQ (NET_HEADER_FIELD_TCP_PORT_SRC << 2)
101296 +#define NET_HEADER_FIELD_TCP_ACK (NET_HEADER_FIELD_TCP_PORT_SRC << 3)
101297 +#define NET_HEADER_FIELD_TCP_OFFSET (NET_HEADER_FIELD_TCP_PORT_SRC << 4)
101298 +#define NET_HEADER_FIELD_TCP_FLAGS (NET_HEADER_FIELD_TCP_PORT_SRC << 5)
101299 +#define NET_HEADER_FIELD_TCP_WINDOW (NET_HEADER_FIELD_TCP_PORT_SRC << 6)
101300 +#define NET_HEADER_FIELD_TCP_CKSUM (NET_HEADER_FIELD_TCP_PORT_SRC << 7)
101301 +#define NET_HEADER_FIELD_TCP_URGPTR (NET_HEADER_FIELD_TCP_PORT_SRC << 8)
101302 +#define NET_HEADER_FIELD_TCP_OPTS (NET_HEADER_FIELD_TCP_PORT_SRC << 9)
101303 +#define NET_HEADER_FIELD_TCP_OPTS_COUNT (NET_HEADER_FIELD_TCP_PORT_SRC << 10)
101304 +#define NET_HEADER_FIELD_TCP_ALL_FIELDS ((NET_HEADER_FIELD_TCP_PORT_SRC << 11) - 1)
101305 +
101306 +#define NET_HEADER_FIELD_TCP_PORT_SIZE 2
101307 +
101308 +
101309 +typedef uint8_t headerFieldSctp_t;
101310 +
101311 +#define NET_HEADER_FIELD_SCTP_PORT_SRC (1)
101312 +#define NET_HEADER_FIELD_SCTP_PORT_DST (NET_HEADER_FIELD_SCTP_PORT_SRC << 1)
101313 +#define NET_HEADER_FIELD_SCTP_VER_TAG (NET_HEADER_FIELD_SCTP_PORT_SRC << 2)
101314 +#define NET_HEADER_FIELD_SCTP_CKSUM (NET_HEADER_FIELD_SCTP_PORT_SRC << 3)
101315 +#define NET_HEADER_FIELD_SCTP_ALL_FIELDS ((NET_HEADER_FIELD_SCTP_PORT_SRC << 4) - 1)
101316 +
101317 +#define NET_HEADER_FIELD_SCTP_PORT_SIZE 2
101318 +
101319 +typedef uint8_t headerFieldDccp_t;
101320 +
101321 +#define NET_HEADER_FIELD_DCCP_PORT_SRC (1)
101322 +#define NET_HEADER_FIELD_DCCP_PORT_DST (NET_HEADER_FIELD_DCCP_PORT_SRC << 1)
101323 +#define NET_HEADER_FIELD_DCCP_ALL_FIELDS ((NET_HEADER_FIELD_DCCP_PORT_SRC << 2) - 1)
101324 +
101325 +#define NET_HEADER_FIELD_DCCP_PORT_SIZE 2
101326 +
101327 +
101328 +typedef uint8_t headerFieldUdp_t;
101329 +
101330 +#define NET_HEADER_FIELD_UDP_PORT_SRC (1)
101331 +#define NET_HEADER_FIELD_UDP_PORT_DST (NET_HEADER_FIELD_UDP_PORT_SRC << 1)
101332 +#define NET_HEADER_FIELD_UDP_LEN (NET_HEADER_FIELD_UDP_PORT_SRC << 2)
101333 +#define NET_HEADER_FIELD_UDP_CKSUM (NET_HEADER_FIELD_UDP_PORT_SRC << 3)
101334 +#define NET_HEADER_FIELD_UDP_ALL_FIELDS ((NET_HEADER_FIELD_UDP_PORT_SRC << 4) - 1)
101335 +
101336 +#define NET_HEADER_FIELD_UDP_PORT_SIZE 2
101337 +
101338 +typedef uint8_t headerFieldUdpLite_t;
101339 +
101340 +#define NET_HEADER_FIELD_UDP_LITE_PORT_SRC (1)
101341 +#define NET_HEADER_FIELD_UDP_LITE_PORT_DST (NET_HEADER_FIELD_UDP_LITE_PORT_SRC << 1)
101342 +#define NET_HEADER_FIELD_UDP_LITE_ALL_FIELDS ((NET_HEADER_FIELD_UDP_LITE_PORT_SRC << 2) - 1)
101343 +
101344 +#define NET_HEADER_FIELD_UDP_LITE_PORT_SIZE 2
101345 +
101346 +typedef uint8_t headerFieldUdpEncapEsp_t;
101347 +
101348 +#define NET_HEADER_FIELD_UDP_ENCAP_ESP_PORT_SRC (1)
101349 +#define NET_HEADER_FIELD_UDP_ENCAP_ESP_PORT_DST (NET_HEADER_FIELD_UDP_ENCAP_ESP_PORT_SRC << 1)
101350 +#define NET_HEADER_FIELD_UDP_ENCAP_ESP_LEN (NET_HEADER_FIELD_UDP_ENCAP_ESP_PORT_SRC << 2)
101351 +#define NET_HEADER_FIELD_UDP_ENCAP_ESP_CKSUM (NET_HEADER_FIELD_UDP_ENCAP_ESP_PORT_SRC << 3)
101352 +#define NET_HEADER_FIELD_UDP_ENCAP_ESP_SPI (NET_HEADER_FIELD_UDP_ENCAP_ESP_PORT_SRC << 4)
101353 +#define NET_HEADER_FIELD_UDP_ENCAP_ESP_SEQUENCE_NUM (NET_HEADER_FIELD_UDP_ENCAP_ESP_PORT_SRC << 5)
101354 +#define NET_HEADER_FIELD_UDP_ENCAP_ESP_ALL_FIELDS ((NET_HEADER_FIELD_UDP_ENCAP_ESP_PORT_SRC << 6) - 1)
101355 +
101356 +#define NET_HEADER_FIELD_UDP_ENCAP_ESP_PORT_SIZE 2
101357 +#define NET_HEADER_FIELD_UDP_ENCAP_ESP_SPI_SIZE 4
101358 +
101359 +#define NET_HEADER_FIELD_IPHC_CID (1)
101360 +#define NET_HEADER_FIELD_IPHC_CID_TYPE (NET_HEADER_FIELD_IPHC_CID << 1)
101361 +#define NET_HEADER_FIELD_IPHC_HCINDEX (NET_HEADER_FIELD_IPHC_CID << 2)
101362 +#define NET_HEADER_FIELD_IPHC_GEN (NET_HEADER_FIELD_IPHC_CID << 3)
101363 +#define NET_HEADER_FIELD_IPHC_D_BIT (NET_HEADER_FIELD_IPHC_CID << 4)
101364 +#define NET_HEADER_FIELD_IPHC_ALL_FIELDS ((NET_HEADER_FIELD_IPHC_CID << 5) - 1)
101365 +
101366 +#define NET_HEADER_FIELD_SCTP_CHUNK_DATA_TYPE (1)
101367 +#define NET_HEADER_FIELD_SCTP_CHUNK_DATA_FLAGS (NET_HEADER_FIELD_SCTP_CHUNK_DATA_TYPE << 1)
101368 +#define NET_HEADER_FIELD_SCTP_CHUNK_DATA_LENGTH (NET_HEADER_FIELD_SCTP_CHUNK_DATA_TYPE << 2)
101369 +#define NET_HEADER_FIELD_SCTP_CHUNK_DATA_TSN (NET_HEADER_FIELD_SCTP_CHUNK_DATA_TYPE << 3)
101370 +#define NET_HEADER_FIELD_SCTP_CHUNK_DATA_STREAM_ID (NET_HEADER_FIELD_SCTP_CHUNK_DATA_TYPE << 4)
101371 +#define NET_HEADER_FIELD_SCTP_CHUNK_DATA_STREAM_SQN (NET_HEADER_FIELD_SCTP_CHUNK_DATA_TYPE << 5)
101372 +#define NET_HEADER_FIELD_SCTP_CHUNK_DATA_PAYLOAD_PID (NET_HEADER_FIELD_SCTP_CHUNK_DATA_TYPE << 6)
101373 +#define NET_HEADER_FIELD_SCTP_CHUNK_DATA_UNORDERED (NET_HEADER_FIELD_SCTP_CHUNK_DATA_TYPE << 7)
101374 +#define NET_HEADER_FIELD_SCTP_CHUNK_DATA_BEGGINING (NET_HEADER_FIELD_SCTP_CHUNK_DATA_TYPE << 8)
101375 +#define NET_HEADER_FIELD_SCTP_CHUNK_DATA_END (NET_HEADER_FIELD_SCTP_CHUNK_DATA_TYPE << 9)
101376 +#define NET_HEADER_FIELD_SCTP_CHUNK_DATA_ALL_FIELDS ((NET_HEADER_FIELD_SCTP_CHUNK_DATA_TYPE << 10) - 1)
101377 +
101378 +#define NET_HEADER_FIELD_L2TPv2_TYPE_BIT (1)
101379 +#define NET_HEADER_FIELD_L2TPv2_LENGTH_BIT (NET_HEADER_FIELD_L2TPv2_TYPE_BIT << 1)
101380 +#define NET_HEADER_FIELD_L2TPv2_SEQUENCE_BIT (NET_HEADER_FIELD_L2TPv2_TYPE_BIT << 2)
101381 +#define NET_HEADER_FIELD_L2TPv2_OFFSET_BIT (NET_HEADER_FIELD_L2TPv2_TYPE_BIT << 3)
101382 +#define NET_HEADER_FIELD_L2TPv2_PRIORITY_BIT (NET_HEADER_FIELD_L2TPv2_TYPE_BIT << 4)
101383 +#define NET_HEADER_FIELD_L2TPv2_VERSION (NET_HEADER_FIELD_L2TPv2_TYPE_BIT << 5)
101384 +#define NET_HEADER_FIELD_L2TPv2_LEN (NET_HEADER_FIELD_L2TPv2_TYPE_BIT << 6)
101385 +#define NET_HEADER_FIELD_L2TPv2_TUNNEL_ID (NET_HEADER_FIELD_L2TPv2_TYPE_BIT << 7)
101386 +#define NET_HEADER_FIELD_L2TPv2_SESSION_ID (NET_HEADER_FIELD_L2TPv2_TYPE_BIT << 8)
101387 +#define NET_HEADER_FIELD_L2TPv2_NS (NET_HEADER_FIELD_L2TPv2_TYPE_BIT << 9)
101388 +#define NET_HEADER_FIELD_L2TPv2_NR (NET_HEADER_FIELD_L2TPv2_TYPE_BIT << 10)
101389 +#define NET_HEADER_FIELD_L2TPv2_OFFSET_SIZE (NET_HEADER_FIELD_L2TPv2_TYPE_BIT << 11)
101390 +#define NET_HEADER_FIELD_L2TPv2_FIRST_BYTE (NET_HEADER_FIELD_L2TPv2_TYPE_BIT << 12)
101391 +#define NET_HEADER_FIELD_L2TPv2_ALL_FIELDS ((NET_HEADER_FIELD_L2TPv2_TYPE_BIT << 13) - 1)
101392 +
101393 +#define NET_HEADER_FIELD_L2TPv3_CTRL_TYPE_BIT (1)
101394 +#define NET_HEADER_FIELD_L2TPv3_CTRL_LENGTH_BIT (NET_HEADER_FIELD_L2TPv3_CTRL_TYPE_BIT << 1)
101395 +#define NET_HEADER_FIELD_L2TPv3_CTRL_SEQUENCE_BIT (NET_HEADER_FIELD_L2TPv3_CTRL_TYPE_BIT << 2)
101396 +#define NET_HEADER_FIELD_L2TPv3_CTRL_VERSION (NET_HEADER_FIELD_L2TPv3_CTRL_TYPE_BIT << 3)
101397 +#define NET_HEADER_FIELD_L2TPv3_CTRL_LENGTH (NET_HEADER_FIELD_L2TPv3_CTRL_TYPE_BIT << 4)
101398 +#define NET_HEADER_FIELD_L2TPv3_CTRL_CONTROL (NET_HEADER_FIELD_L2TPv3_CTRL_TYPE_BIT << 5)
101399 +#define NET_HEADER_FIELD_L2TPv3_CTRL_SENT (NET_HEADER_FIELD_L2TPv3_CTRL_TYPE_BIT << 6)
101400 +#define NET_HEADER_FIELD_L2TPv3_CTRL_RECV (NET_HEADER_FIELD_L2TPv3_CTRL_TYPE_BIT << 7)
101401 +#define NET_HEADER_FIELD_L2TPv3_CTRL_FIRST_BYTE (NET_HEADER_FIELD_L2TPv3_CTRL_TYPE_BIT << 8)
101402 +#define NET_HEADER_FIELD_L2TPv3_CTRL_ALL_FIELDS ((NET_HEADER_FIELD_L2TPv3_CTRL_TYPE_BIT << 9) - 1)
101403 +
101404 +#define NET_HEADER_FIELD_L2TPv3_SESS_TYPE_BIT (1)
101405 +#define NET_HEADER_FIELD_L2TPv3_SESS_VERSION (NET_HEADER_FIELD_L2TPv3_SESS_TYPE_BIT << 1)
101406 +#define NET_HEADER_FIELD_L2TPv3_SESS_ID (NET_HEADER_FIELD_L2TPv3_SESS_TYPE_BIT << 2)
101407 +#define NET_HEADER_FIELD_L2TPv3_SESS_COOKIE (NET_HEADER_FIELD_L2TPv3_SESS_TYPE_BIT << 3)
101408 +#define NET_HEADER_FIELD_L2TPv3_SESS_ALL_FIELDS ((NET_HEADER_FIELD_L2TPv3_SESS_TYPE_BIT << 4) - 1)
101409 +
101410 +
101411 +typedef uint8_t headerFieldVlan_t;
101412 +
101413 +#define NET_HEADER_FIELD_VLAN_VPRI (1)
101414 +#define NET_HEADER_FIELD_VLAN_CFI (NET_HEADER_FIELD_VLAN_VPRI << 1)
101415 +#define NET_HEADER_FIELD_VLAN_VID (NET_HEADER_FIELD_VLAN_VPRI << 2)
101416 +#define NET_HEADER_FIELD_VLAN_LENGTH (NET_HEADER_FIELD_VLAN_VPRI << 3)
101417 +#define NET_HEADER_FIELD_VLAN_TYPE (NET_HEADER_FIELD_VLAN_VPRI << 4)
101418 +#define NET_HEADER_FIELD_VLAN_ALL_FIELDS ((NET_HEADER_FIELD_VLAN_VPRI << 5) - 1)
101419 +
101420 +#define NET_HEADER_FIELD_VLAN_TCI (NET_HEADER_FIELD_VLAN_VPRI | \
101421 + NET_HEADER_FIELD_VLAN_CFI | \
101422 + NET_HEADER_FIELD_VLAN_VID)
101423 +
101424 +
101425 +typedef uint8_t headerFieldLlc_t;
101426 +
101427 +#define NET_HEADER_FIELD_LLC_DSAP (1)
101428 +#define NET_HEADER_FIELD_LLC_SSAP (NET_HEADER_FIELD_LLC_DSAP << 1)
101429 +#define NET_HEADER_FIELD_LLC_CTRL (NET_HEADER_FIELD_LLC_DSAP << 2)
101430 +#define NET_HEADER_FIELD_LLC_ALL_FIELDS ((NET_HEADER_FIELD_LLC_DSAP << 3) - 1)
101431 +
101432 +#define NET_HEADER_FIELD_NLPID_NLPID (1)
101433 +#define NET_HEADER_FIELD_NLPID_ALL_FIELDS ((NET_HEADER_FIELD_NLPID_NLPID << 1) - 1)
101434 +
101435 +
101436 +typedef uint8_t headerFieldSnap_t;
101437 +
101438 +#define NET_HEADER_FIELD_SNAP_OUI (1)
101439 +#define NET_HEADER_FIELD_SNAP_PID (NET_HEADER_FIELD_SNAP_OUI << 1)
101440 +#define NET_HEADER_FIELD_SNAP_ALL_FIELDS ((NET_HEADER_FIELD_SNAP_OUI << 2) - 1)
101441 +
101442 +
101443 +typedef uint8_t headerFieldLlcSnap_t;
101444 +
101445 +#define NET_HEADER_FIELD_LLC_SNAP_TYPE (1)
101446 +#define NET_HEADER_FIELD_LLC_SNAP_ALL_FIELDS ((NET_HEADER_FIELD_LLC_SNAP_TYPE << 1) - 1)
101447 +
101448 +#define NET_HEADER_FIELD_ARP_HTYPE (1)
101449 +#define NET_HEADER_FIELD_ARP_PTYPE (NET_HEADER_FIELD_ARP_HTYPE << 1)
101450 +#define NET_HEADER_FIELD_ARP_HLEN (NET_HEADER_FIELD_ARP_HTYPE << 2)
101451 +#define NET_HEADER_FIELD_ARP_PLEN (NET_HEADER_FIELD_ARP_HTYPE << 3)
101452 +#define NET_HEADER_FIELD_ARP_OPER (NET_HEADER_FIELD_ARP_HTYPE << 4)
101453 +#define NET_HEADER_FIELD_ARP_SHA (NET_HEADER_FIELD_ARP_HTYPE << 5)
101454 +#define NET_HEADER_FIELD_ARP_SPA (NET_HEADER_FIELD_ARP_HTYPE << 6)
101455 +#define NET_HEADER_FIELD_ARP_THA (NET_HEADER_FIELD_ARP_HTYPE << 7)
101456 +#define NET_HEADER_FIELD_ARP_TPA (NET_HEADER_FIELD_ARP_HTYPE << 8)
101457 +#define NET_HEADER_FIELD_ARP_ALL_FIELDS ((NET_HEADER_FIELD_ARP_HTYPE << 9) - 1)
101458 +
101459 +#define NET_HEADER_FIELD_RFC2684_LLC (1)
101460 +#define NET_HEADER_FIELD_RFC2684_NLPID (NET_HEADER_FIELD_RFC2684_LLC << 1)
101461 +#define NET_HEADER_FIELD_RFC2684_OUI (NET_HEADER_FIELD_RFC2684_LLC << 2)
101462 +#define NET_HEADER_FIELD_RFC2684_PID (NET_HEADER_FIELD_RFC2684_LLC << 3)
101463 +#define NET_HEADER_FIELD_RFC2684_VPN_OUI (NET_HEADER_FIELD_RFC2684_LLC << 4)
101464 +#define NET_HEADER_FIELD_RFC2684_VPN_IDX (NET_HEADER_FIELD_RFC2684_LLC << 5)
101465 +#define NET_HEADER_FIELD_RFC2684_ALL_FIELDS ((NET_HEADER_FIELD_RFC2684_LLC << 6) - 1)
101466 +
101467 +#define NET_HEADER_FIELD_USER_DEFINED_SRCPORT (1)
101468 +#define NET_HEADER_FIELD_USER_DEFINED_PCDID (NET_HEADER_FIELD_USER_DEFINED_SRCPORT << 1)
101469 +#define NET_HEADER_FIELD_USER_DEFINED_ALL_FIELDS ((NET_HEADER_FIELD_USER_DEFINED_SRCPORT << 2) - 1)
101470 +
101471 +#define NET_HEADER_FIELD_PAYLOAD_BUFFER (1)
101472 +#define NET_HEADER_FIELD_PAYLOAD_SIZE (NET_HEADER_FIELD_PAYLOAD_BUFFER << 1)
101473 +#define NET_HEADER_FIELD_MAX_FRM_SIZE (NET_HEADER_FIELD_PAYLOAD_BUFFER << 2)
101474 +#define NET_HEADER_FIELD_MIN_FRM_SIZE (NET_HEADER_FIELD_PAYLOAD_BUFFER << 3)
101475 +#define NET_HEADER_FIELD_PAYLOAD_TYPE (NET_HEADER_FIELD_PAYLOAD_BUFFER << 4)
101476 +#define NET_HEADER_FIELD_FRAME_SIZE (NET_HEADER_FIELD_PAYLOAD_BUFFER << 5)
101477 +#define NET_HEADER_FIELD_PAYLOAD_ALL_FIELDS ((NET_HEADER_FIELD_PAYLOAD_BUFFER << 6) - 1)
101478 +
101479 +
101480 +typedef uint8_t headerFieldGre_t;
101481 +
101482 +#define NET_HEADER_FIELD_GRE_TYPE (1)
101483 +#define NET_HEADER_FIELD_GRE_ALL_FIELDS ((NET_HEADER_FIELD_GRE_TYPE << 1) - 1)
101484 +
101485 +
101486 +typedef uint8_t headerFieldMinencap_t;
101487 +
101488 +#define NET_HEADER_FIELD_MINENCAP_SRC_IP (1)
101489 +#define NET_HEADER_FIELD_MINENCAP_DST_IP (NET_HEADER_FIELD_MINENCAP_SRC_IP << 1)
101490 +#define NET_HEADER_FIELD_MINENCAP_TYPE (NET_HEADER_FIELD_MINENCAP_SRC_IP << 2)
101491 +#define NET_HEADER_FIELD_MINENCAP_ALL_FIELDS ((NET_HEADER_FIELD_MINENCAP_SRC_IP << 3) - 1)
101492 +
101493 +
101494 +typedef uint8_t headerFieldIpsecAh_t;
101495 +
101496 +#define NET_HEADER_FIELD_IPSEC_AH_SPI (1)
101497 +#define NET_HEADER_FIELD_IPSEC_AH_NH (NET_HEADER_FIELD_IPSEC_AH_SPI << 1)
101498 +#define NET_HEADER_FIELD_IPSEC_AH_ALL_FIELDS ((NET_HEADER_FIELD_IPSEC_AH_SPI << 2) - 1)
101499 +
101500 +
101501 +typedef uint8_t headerFieldIpsecEsp_t;
101502 +
101503 +#define NET_HEADER_FIELD_IPSEC_ESP_SPI (1)
101504 +#define NET_HEADER_FIELD_IPSEC_ESP_SEQUENCE_NUM (NET_HEADER_FIELD_IPSEC_ESP_SPI << 1)
101505 +#define NET_HEADER_FIELD_IPSEC_ESP_ALL_FIELDS ((NET_HEADER_FIELD_IPSEC_ESP_SPI << 2) - 1)
101506 +
101507 +#define NET_HEADER_FIELD_IPSEC_ESP_SPI_SIZE 4
101508 +
101509 +
101510 +typedef uint8_t headerFieldMpls_t;
101511 +
101512 +#define NET_HEADER_FIELD_MPLS_LABEL_STACK (1)
101513 +#define NET_HEADER_FIELD_MPLS_LABEL_STACK_ALL_FIELDS ((NET_HEADER_FIELD_MPLS_LABEL_STACK << 1) - 1)
101514 +
101515 +
101516 +typedef uint8_t headerFieldMacsec_t;
101517 +
101518 +#define NET_HEADER_FIELD_MACSEC_SECTAG (1)
101519 +#define NET_HEADER_FIELD_MACSEC_ALL_FIELDS ((NET_HEADER_FIELD_MACSEC_SECTAG << 1) - 1)
101520 +
101521 +
101522 +typedef enum {
101523 + HEADER_TYPE_NONE = 0,
101524 + HEADER_TYPE_PAYLOAD,
101525 + HEADER_TYPE_ETH,
101526 + HEADER_TYPE_VLAN,
101527 + HEADER_TYPE_IPv4,
101528 + HEADER_TYPE_IPv6,
101529 + HEADER_TYPE_IP,
101530 + HEADER_TYPE_TCP,
101531 + HEADER_TYPE_UDP,
101532 + HEADER_TYPE_UDP_LITE,
101533 + HEADER_TYPE_IPHC,
101534 + HEADER_TYPE_SCTP,
101535 + HEADER_TYPE_SCTP_CHUNK_DATA,
101536 + HEADER_TYPE_PPPoE,
101537 + HEADER_TYPE_PPP,
101538 + HEADER_TYPE_PPPMUX,
101539 + HEADER_TYPE_PPPMUX_SUBFRAME,
101540 + HEADER_TYPE_L2TPv2,
101541 + HEADER_TYPE_L2TPv3_CTRL,
101542 + HEADER_TYPE_L2TPv3_SESS,
101543 + HEADER_TYPE_LLC,
101544 + HEADER_TYPE_LLC_SNAP,
101545 + HEADER_TYPE_NLPID,
101546 + HEADER_TYPE_SNAP,
101547 + HEADER_TYPE_MPLS,
101548 + HEADER_TYPE_IPSEC_AH,
101549 + HEADER_TYPE_IPSEC_ESP,
101550 + HEADER_TYPE_UDP_ENCAP_ESP, /* RFC 3948 */
101551 + HEADER_TYPE_MACSEC,
101552 + HEADER_TYPE_GRE,
101553 + HEADER_TYPE_MINENCAP,
101554 + HEADER_TYPE_DCCP,
101555 + HEADER_TYPE_ICMP,
101556 + HEADER_TYPE_IGMP,
101557 + HEADER_TYPE_ARP,
101558 + HEADER_TYPE_CAPWAP,
101559 + HEADER_TYPE_CAPWAP_DTLS,
101560 + HEADER_TYPE_RFC2684,
101561 + HEADER_TYPE_USER_DEFINED_L2,
101562 + HEADER_TYPE_USER_DEFINED_L3,
101563 + HEADER_TYPE_USER_DEFINED_L4,
101564 + HEADER_TYPE_USER_DEFINED_SHIM1,
101565 + HEADER_TYPE_USER_DEFINED_SHIM2,
101566 + MAX_HEADER_TYPE_COUNT
101567 +} e_NetHeaderType;
101568 +
101569 +
101570 +#endif /* __NET_EXT_H */
101571 --- /dev/null
101572 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/std_ext.h
101573 @@ -0,0 +1,48 @@
101574 +/* Copyright (c) 2008-2012 Freescale Semiconductor, Inc
101575 + * All rights reserved.
101576 + *
101577 + * Redistribution and use in source and binary forms, with or without
101578 + * modification, are permitted provided that the following conditions are met:
101579 + * * Redistributions of source code must retain the above copyright
101580 + * notice, this list of conditions and the following disclaimer.
101581 + * * Redistributions in binary form must reproduce the above copyright
101582 + * notice, this list of conditions and the following disclaimer in the
101583 + * documentation and/or other materials provided with the distribution.
101584 + * * Neither the name of Freescale Semiconductor nor the
101585 + * names of its contributors may be used to endorse or promote products
101586 + * derived from this software without specific prior written permission.
101587 + *
101588 + *
101589 + * ALTERNATIVELY, this software may be distributed under the terms of the
101590 + * GNU General Public License ("GPL") as published by the Free Software
101591 + * Foundation, either version 2 of that License or (at your option) any
101592 + * later version.
101593 + *
101594 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
101595 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
101596 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
101597 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
101598 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
101599 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
101600 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
101601 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
101602 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
101603 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
101604 + */
101605 +
101606 +
101607 +/**************************************************************************//**
101608 + @File std_ext.h
101609 +
101610 + @Description General Standard Definitions
101611 +*//***************************************************************************/
101612 +
101613 +#ifndef __STD_EXT_H
101614 +#define __STD_EXT_H
101615 +
101616 +
101617 +#include "types_ext.h"
101618 +#include "ncsw_ext.h"
101619 +
101620 +
101621 +#endif /* __STD_EXT_H */
101622 --- /dev/null
101623 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/stdarg_ext.h
101624 @@ -0,0 +1,49 @@
101625 +/*
101626 + * Copyright 2008-2012 Freescale Semiconductor Inc.
101627 + *
101628 + * Redistribution and use in source and binary forms, with or without
101629 + * modification, are permitted provided that the following conditions are met:
101630 + * * Redistributions of source code must retain the above copyright
101631 + * notice, this list of conditions and the following disclaimer.
101632 + * * Redistributions in binary form must reproduce the above copyright
101633 + * notice, this list of conditions and the following disclaimer in the
101634 + * documentation and/or other materials provided with the distribution.
101635 + * * Neither the name of Freescale Semiconductor nor the
101636 + * names of its contributors may be used to endorse or promote products
101637 + * derived from this software without specific prior written permission.
101638 + *
101639 + *
101640 + * ALTERNATIVELY, this software may be distributed under the terms of the
101641 + * GNU General Public License ("GPL") as published by the Free Software
101642 + * Foundation, either version 2 of that License or (at your option) any
101643 + * later version.
101644 + *
101645 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
101646 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
101647 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
101648 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
101649 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
101650 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
101651 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
101652 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
101653 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
101654 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
101655 + */
101656 +
101657 +
101658 +#ifndef __STDARG_EXT_H
101659 +#define __STDARG_EXT_H
101660 +
101661 +
101662 +#if defined(NCSW_LINUX) && defined(__KERNEL__)
101663 +#include <stdarg.h>
101664 +
101665 +#else
101666 +#include <stdarg.h>
101667 +
101668 +#endif /* defined(NCSW_LINUX) && defined(__KERNEL__) */
101669 +
101670 +#include "std_ext.h"
101671 +
101672 +
101673 +#endif /* __STDARG_EXT_H */
101674 --- /dev/null
101675 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/stdlib_ext.h
101676 @@ -0,0 +1,162 @@
101677 +/*
101678 + * Copyright 2008-2012 Freescale Semiconductor Inc.
101679 + *
101680 + * Redistribution and use in source and binary forms, with or without
101681 + * modification, are permitted provided that the following conditions are met:
101682 + * * Redistributions of source code must retain the above copyright
101683 + * notice, this list of conditions and the following disclaimer.
101684 + * * Redistributions in binary form must reproduce the above copyright
101685 + * notice, this list of conditions and the following disclaimer in the
101686 + * documentation and/or other materials provided with the distribution.
101687 + * * Neither the name of Freescale Semiconductor nor the
101688 + * names of its contributors may be used to endorse or promote products
101689 + * derived from this software without specific prior written permission.
101690 + *
101691 + *
101692 + * ALTERNATIVELY, this software may be distributed under the terms of the
101693 + * GNU General Public License ("GPL") as published by the Free Software
101694 + * Foundation, either version 2 of that License or (at your option) any
101695 + * later version.
101696 + *
101697 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
101698 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
101699 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
101700 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
101701 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
101702 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
101703 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
101704 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
101705 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
101706 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
101707 + */
101708 +
101709 +
101710 +
101711 +#ifndef __STDLIB_EXT_H
101712 +#define __STDLIB_EXT_H
101713 +
101714 +
101715 +#if (defined(NCSW_LINUX)) && defined(__KERNEL__)
101716 +#include "stdarg_ext.h"
101717 +#include "std_ext.h"
101718 +
101719 +
101720 +/**
101721 + * strtoul - convert a string to an uint32_t
101722 + * @cp: The start of the string
101723 + * @endp: A pointer to the end of the parsed string will be placed here
101724 + * @base: The number base to use
101725 + */
101726 +uint32_t strtoul(const char *cp,char **endp,uint32_t base);
101727 +
101728 +/**
101729 + * strtol - convert a string to a int32_t
101730 + * @cp: The start of the string
101731 + * @endp: A pointer to the end of the parsed string will be placed here
101732 + * @base: The number base to use
101733 + */
101734 +long strtol(const char *cp,char **endp,uint32_t base);
101735 +
101736 +/**
101737 + * strtoull - convert a string to an uint64_t
101738 + * @cp: The start of the string
101739 + * @endp: A pointer to the end of the parsed string will be placed here
101740 + * @base: The number base to use
101741 + */
101742 +uint64_t strtoull(const char *cp,char **endp,uint32_t base);
101743 +
101744 +/**
101745 + * strtoll - convert a string to a int64 long
101746 + * @cp: The start of the string
101747 + * @endp: A pointer to the end of the parsed string will be placed here
101748 + * @base: The number base to use
101749 + */
101750 +long long strtoll(const char *cp,char **endp,uint32_t base);
101751 +
101752 +/**
101753 + * atoi - convert a character to a int
101754 + * @s: The start of the string
101755 + */
101756 +int atoi(const char *s);
101757 +
101758 +/**
101759 + * strnlen - Find the length of a length-limited string
101760 + * @s: The string to be sized
101761 + * @count: The maximum number of bytes to search
101762 + */
101763 +size_t strnlen(const char * s, size_t count);
101764 +
101765 +/**
101766 + * strlen - Find the length of a string
101767 + * @s: The string to be sized
101768 + */
101769 +size_t strlen(const char * s);
101770 +
101771 +/**
101772 + * strtok - Split a string into tokens
101773 + * @s: The string to be searched
101774 + * @ct: The characters to search for
101775 + *
101776 + * WARNING: strtok is deprecated, use strsep instead.
101777 + */
101778 +char * strtok(char * s,const char * ct);
101779 +
101780 +/**
101781 + * strncpy - Copy a length-limited, %NUL-terminated string
101782 + * @dest: Where to copy the string to
101783 + * @src: Where to copy the string from
101784 + * @count: The maximum number of bytes to copy
101785 + *
101786 + * Note that unlike userspace strncpy, this does not %NUL-pad the buffer.
101787 + * However, the result is not %NUL-terminated if the source exceeds
101788 + * @count bytes.
101789 + */
101790 +char * strncpy(char * dest,const char *src,size_t count);
101791 +
101792 +/**
101793 + * strcpy - Copy a %NUL terminated string
101794 + * @dest: Where to copy the string to
101795 + * @src: Where to copy the string from
101796 + */
101797 +char * strcpy(char * dest,const char *src);
101798 +
101799 +/**
101800 + * vsscanf - Unformat a buffer into a list of arguments
101801 + * @buf: input buffer
101802 + * @fmt: format of buffer
101803 + * @args: arguments
101804 + */
101805 +int vsscanf(const char * buf, const char * fmt, va_list args);
101806 +
101807 +/**
101808 + * vsnprintf - Format a string and place it in a buffer
101809 + * @buf: The buffer to place the result into
101810 + * @size: The size of the buffer, including the trailing null space
101811 + * @fmt: The format string to use
101812 + * @args: Arguments for the format string
101813 + *
101814 + * Call this function if you are already dealing with a va_list.
101815 + * You probably want snprintf instead.
101816 + */
101817 +int vsnprintf(char *buf, size_t size, const char *fmt, va_list args);
101818 +
101819 +/**
101820 + * vsprintf - Format a string and place it in a buffer
101821 + * @buf: The buffer to place the result into
101822 + * @fmt: The format string to use
101823 + * @args: Arguments for the format string
101824 + *
101825 + * Call this function if you are already dealing with a va_list.
101826 + * You probably want sprintf instead.
101827 + */
101828 +int vsprintf(char *buf, const char *fmt, va_list args);
101829 +
101830 +#else
101831 +#include <stdlib.h>
101832 +#include <stdio.h>
101833 +#endif /* defined(NCSW_LINUX) && defined(__KERNEL__) */
101834 +
101835 +#include "std_ext.h"
101836 +
101837 +
101838 +#endif /* __STDLIB_EXT_H */
101839 --- /dev/null
101840 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/string_ext.h
101841 @@ -0,0 +1,56 @@
101842 +/*
101843 + * Copyright 2008-2012 Freescale Semiconductor Inc.
101844 + *
101845 + * Redistribution and use in source and binary forms, with or without
101846 + * modification, are permitted provided that the following conditions are met:
101847 + * * Redistributions of source code must retain the above copyright
101848 + * notice, this list of conditions and the following disclaimer.
101849 + * * Redistributions in binary form must reproduce the above copyright
101850 + * notice, this list of conditions and the following disclaimer in the
101851 + * documentation and/or other materials provided with the distribution.
101852 + * * Neither the name of Freescale Semiconductor nor the
101853 + * names of its contributors may be used to endorse or promote products
101854 + * derived from this software without specific prior written permission.
101855 + *
101856 + *
101857 + * ALTERNATIVELY, this software may be distributed under the terms of the
101858 + * GNU General Public License ("GPL") as published by the Free Software
101859 + * Foundation, either version 2 of that License or (at your option) any
101860 + * later version.
101861 + *
101862 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
101863 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
101864 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
101865 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
101866 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
101867 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
101868 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
101869 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
101870 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
101871 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
101872 + */
101873 +
101874 +
101875 +#ifndef __STRING_EXT_H
101876 +#define __STRING_EXT_H
101877 +
101878 +
101879 +#if defined(NCSW_LINUX) && defined(__KERNEL__)
101880 +#include <linux/kernel.h>
101881 +#include <linux/string.h>
101882 +extern char * strtok ( char * str, const char * delimiters );
101883 +
101884 +#elif defined(__KERNEL__)
101885 +#include "linux/types.h"
101886 +#include "linux/posix_types.h"
101887 +#include "linux/string.h"
101888 +
101889 +#else
101890 +#include <string.h>
101891 +
101892 +#endif /* defined(NCSW_LINUX) && defined(__KERNEL__) */
101893 +
101894 +#include "std_ext.h"
101895 +
101896 +
101897 +#endif /* __STRING_EXT_H */
101898 --- /dev/null
101899 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/types_ext.h
101900 @@ -0,0 +1,62 @@
101901 +/* Copyright (c) 2008-2012 Freescale Semiconductor, Inc
101902 + * All rights reserved.
101903 + *
101904 + * Redistribution and use in source and binary forms, with or without
101905 + * modification, are permitted provided that the following conditions are met:
101906 + * * Redistributions of source code must retain the above copyright
101907 + * notice, this list of conditions and the following disclaimer.
101908 + * * Redistributions in binary form must reproduce the above copyright
101909 + * notice, this list of conditions and the following disclaimer in the
101910 + * documentation and/or other materials provided with the distribution.
101911 + * * Neither the name of Freescale Semiconductor nor the
101912 + * names of its contributors may be used to endorse or promote products
101913 + * derived from this software without specific prior written permission.
101914 + *
101915 + *
101916 + * ALTERNATIVELY, this software may be distributed under the terms of the
101917 + * GNU General Public License ("GPL") as published by the Free Software
101918 + * Foundation, either version 2 of that License or (at your option) any
101919 + * later version.
101920 + *
101921 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
101922 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
101923 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
101924 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
101925 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
101926 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
101927 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
101928 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
101929 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
101930 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
101931 + */
101932 +
101933 +
101934 +/**************************************************************************//**
101935 + @File types_ext.h
101936 +
101937 + @Description General types Standard Definitions
101938 +*//***************************************************************************/
101939 +
101940 +#ifndef __TYPES_EXT_H
101941 +#define __TYPES_EXT_H
101942 +
101943 +#if defined(NCSW_LINUX)
101944 +#include "types_linux.h"
101945 +
101946 +#elif defined(NCSW_VXWORKS)
101947 +#include "types_vxworks.h"
101948 +
101949 +#elif defined(__GNUC__) && defined(__cplusplus)
101950 +#include "types_bb_gpp.h"
101951 +
101952 +#elif defined(__GNUC__)
101953 +#include "types_bb_gcc.h"
101954 +
101955 +#elif defined(__ghs__)
101956 +#include "types_ghs.h"
101957 +
101958 +#else
101959 +#include "types_dflt.h"
101960 +#endif /* defined (__ROCOO__) */
101961 +
101962 +#endif /* __TYPES_EXT_H */
101963 --- /dev/null
101964 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/xx_common.h
101965 @@ -0,0 +1,56 @@
101966 +/*
101967 + * Copyright 2012 Freescale Semiconductor Inc.
101968 + *
101969 + * Redistribution and use in source and binary forms, with or without
101970 + * modification, are permitted provided that the following conditions are met:
101971 + * * Redistributions of source code must retain the above copyright
101972 + * notice, this list of conditions and the following disclaimer.
101973 + * * Redistributions in binary form must reproduce the above copyright
101974 + * notice, this list of conditions and the following disclaimer in the
101975 + * documentation and/or other materials provided with the distribution.
101976 + * * Neither the name of Freescale Semiconductor nor the
101977 + * names of its contributors may be used to endorse or promote products
101978 + * derived from this software without specific prior written permission.
101979 + *
101980 + *
101981 + * ALTERNATIVELY, this software may be distributed under the terms of the
101982 + * GNU General Public License ("GPL") as published by the Free Software
101983 + * Foundation, either version 2 of that License or (at your option) any
101984 + * later version.
101985 + *
101986 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
101987 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
101988 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
101989 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
101990 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
101991 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
101992 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
101993 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
101994 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
101995 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
101996 + */
101997 +
101998 +
101999 +/**************************************************************************//**
102000 + @File debug_ext.h
102001 +
102002 + @Description Debug mode definitions.
102003 +*//***************************************************************************/
102004 +
102005 +#ifndef __XX_COMMON_H
102006 +#define __XX_COMMON_H
102007 +
102008 +/*****************************************************************************
102009 + * UNIFIED MODULE CODES
102010 + *****************************************************************************/
102011 +#define MODULE_UNKNOWN 0x00000000
102012 +#define MODULE_FM 0x00010000
102013 +#define MODULE_FM_MURAM 0x00020000
102014 +#define MODULE_FM_PCD 0x00030000
102015 +#define MODULE_FM_RTC 0x00040000
102016 +#define MODULE_FM_MAC 0x00050000
102017 +#define MODULE_FM_PORT 0x00060000
102018 +#define MODULE_MM 0x00070000
102019 +#define MODULE_FM_SP 0x00080000
102020 +#define MODULE_FM_MACSEC 0x00090000
102021 +#endif /* __XX_COMMON_H */
102022 --- /dev/null
102023 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/xx_ext.h
102024 @@ -0,0 +1,791 @@
102025 +/* Copyright (c) 2008-2012 Freescale Semiconductor, Inc
102026 + * All rights reserved.
102027 + *
102028 + * Redistribution and use in source and binary forms, with or without
102029 + * modification, are permitted provided that the following conditions are met:
102030 + * * Redistributions of source code must retain the above copyright
102031 + * notice, this list of conditions and the following disclaimer.
102032 + * * Redistributions in binary form must reproduce the above copyright
102033 + * notice, this list of conditions and the following disclaimer in the
102034 + * documentation and/or other materials provided with the distribution.
102035 + * * Neither the name of Freescale Semiconductor nor the
102036 + * names of its contributors may be used to endorse or promote products
102037 + * derived from this software without specific prior written permission.
102038 + *
102039 + *
102040 + * ALTERNATIVELY, this software may be distributed under the terms of the
102041 + * GNU General Public License ("GPL") as published by the Free Software
102042 + * Foundation, either version 2 of that License or (at your option) any
102043 + * later version.
102044 + *
102045 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
102046 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
102047 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
102048 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
102049 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
102050 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
102051 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
102052 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
102053 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
102054 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
102055 + */
102056 +
102057 +
102058 +/**************************************************************************//**
102059 + @File xx_ext.h
102060 +
102061 + @Description Prototypes, externals and typedefs for system-supplied
102062 + (external) routines
102063 +*//***************************************************************************/
102064 +
102065 +#ifndef __XX_EXT_H
102066 +#define __XX_EXT_H
102067 +
102068 +#include "std_ext.h"
102069 +#include "xx_common.h"
102070 +#include "part_ext.h"
102071 +
102072 +
102073 +
102074 +/**************************************************************************//**
102075 + @Group xx_id XX Interface (System call hooks)
102076 +
102077 + @Description Prototypes, externals and typedefs for system-supplied
102078 + (external) routines
102079 +
102080 + @{
102081 +*//***************************************************************************/
102082 +
102083 +#ifdef DEBUG_XX_MALLOC
102084 +void * XX_MallocDebug(uint32_t size, char *fname, int line);
102085 +
102086 +void * XX_MallocSmartDebug(uint32_t size,
102087 + int memPartitionId,
102088 + uint32_t alignment,
102089 + char *fname,
102090 + int line);
102091 +
102092 +#define XX_Malloc(sz) \
102093 + XX_MallocDebug((sz), __FILE__, __LINE__)
102094 +
102095 +#define XX_MallocSmart(sz, memt, al) \
102096 + XX_MallocSmartDebug((sz), (memt), (al), __FILE__, __LINE__)
102097 +
102098 +#else /* not DEBUG_XX_MALLOC */
102099 +/**************************************************************************//**
102100 + @Function XX_Malloc
102101 +
102102 + @Description allocates contiguous block of memory.
102103 +
102104 + @Param[in] size - Number of bytes to allocate.
102105 +
102106 + @Return The address of the newly allocated block on success, NULL on failure.
102107 +*//***************************************************************************/
102108 +void * XX_Malloc(uint32_t size);
102109 +
102110 +/**************************************************************************//**
102111 + @Function XX_MallocSmart
102112 +
102113 + @Description Allocates contiguous block of memory in a specified
102114 + alignment and from the specified segment.
102115 +
102116 + @Param[in] size - Number of bytes to allocate.
102117 + @Param[in] memPartitionId - Memory partition ID; The value zero must
102118 + be mapped to the default heap partition.
102119 + @Param[in] alignment - Required memory alignment (in bytes).
102120 +
102121 + @Return The address of the newly allocated block on success, NULL on failure.
102122 +*//***************************************************************************/
102123 +void * XX_MallocSmart(uint32_t size, int memPartitionId, uint32_t alignment);
102124 +#endif /* not DEBUG_XX_MALLOC */
102125 +
102126 +/**************************************************************************//**
102127 + @Function XX_FreeSmart
102128 +
102129 + @Description Frees the memory block pointed to by "p".
102130 + Only for memory allocated by XX_MallocSmart
102131 +
102132 + @Param[in] p_Memory - pointer to the memory block.
102133 +
102134 + @Return None.
102135 +*//***************************************************************************/
102136 +void XX_FreeSmart(void *p_Memory);
102137 +
102138 +/**************************************************************************//**
102139 + @Function XX_Free
102140 +
102141 + @Description frees the memory block pointed to by "p".
102142 +
102143 + @Param[in] p_Memory - pointer to the memory block.
102144 +
102145 + @Return None.
102146 +*//***************************************************************************/
102147 +void XX_Free(void *p_Memory);
102148 +
102149 +/**************************************************************************//**
102150 + @Function XX_Print
102151 +
102152 + @Description print a string.
102153 +
102154 + @Param[in] str - string to print.
102155 +
102156 + @Return None.
102157 +*//***************************************************************************/
102158 +void XX_Print(char *str, ...);
102159 +
102160 +/**************************************************************************//**
102161 + @Function XX_SetIntr
102162 +
102163 + @Description Set an interrupt service routine for a specific interrupt source.
102164 +
102165 + @Param[in] irq - Interrupt ID (system-specific number).
102166 + @Param[in] f_Isr - Callback routine that will be called when the interrupt occurs.
102167 + @Param[in] handle - The argument for the user callback routine.
102168 +
102169 + @Return E_OK on success; error code otherwise..
102170 +*//***************************************************************************/
102171 +t_Error XX_SetIntr(int irq, t_Isr *f_Isr, t_Handle handle);
102172 +
102173 +/**************************************************************************//**
102174 + @Function XX_FreeIntr
102175 +
102176 + @Description Free a specific interrupt and a specific callback routine.
102177 +
102178 + @Param[in] irq - Interrupt ID (system-specific number).
102179 +
102180 + @Return E_OK on success; error code otherwise..
102181 +*//***************************************************************************/
102182 +t_Error XX_FreeIntr(int irq);
102183 +
102184 +/**************************************************************************//**
102185 + @Function XX_EnableIntr
102186 +
102187 + @Description Enable a specific interrupt.
102188 +
102189 + @Param[in] irq - Interrupt ID (system-specific number).
102190 +
102191 + @Return E_OK on success; error code otherwise..
102192 +*//***************************************************************************/
102193 +t_Error XX_EnableIntr(int irq);
102194 +
102195 +/**************************************************************************//**
102196 + @Function XX_DisableIntr
102197 +
102198 + @Description Disable a specific interrupt.
102199 +
102200 + @Param[in] irq - Interrupt ID (system-specific number).
102201 +
102202 + @Return E_OK on success; error code otherwise..
102203 +*//***************************************************************************/
102204 +t_Error XX_DisableIntr(int irq);
102205 +
102206 +/**************************************************************************//**
102207 + @Function XX_DisableAllIntr
102208 +
102209 + @Description Disable all interrupts by masking them at the CPU.
102210 +
102211 + @Return A value that represents the interrupts state before the
102212 + operation, and should be passed to the matching
102213 + XX_RestoreAllIntr() call.
102214 +*//***************************************************************************/
102215 +uint32_t XX_DisableAllIntr(void);
102216 +
102217 +/**************************************************************************//**
102218 + @Function XX_RestoreAllIntr
102219 +
102220 + @Description Restore previous state of interrupts level at the CPU.
102221 +
102222 + @Param[in] flags - A value that represents the interrupts state to restore,
102223 + as returned by the matching call for XX_DisableAllIntr().
102224 +
102225 + @Return None.
102226 +*//***************************************************************************/
102227 +void XX_RestoreAllIntr(uint32_t flags);
102228 +
102229 +
102230 +/**************************************************************************//**
102231 + @Function XX_Exit
102232 +
102233 + @Description Stop execution and report status (where it is applicable)
102234 +
102235 + @Param[in] status - exit status
102236 +*//***************************************************************************/
102237 +void XX_Exit(int status);
102238 +
102239 +
102240 +/*****************************************************************************/
102241 +/* Tasklet Service Routines */
102242 +/*****************************************************************************/
102243 +typedef t_Handle t_TaskletHandle;
102244 +
102245 +/**************************************************************************//**
102246 + @Function XX_InitTasklet
102247 +
102248 + @Description Create and initialize a tasklet object.
102249 +
102250 + @Param[in] routine - A routine to be ran as a tasklet.
102251 + @Param[in] data - An argument to pass to the tasklet.
102252 +
102253 + @Return Tasklet handle is returned on success. NULL is returned otherwise.
102254 +*//***************************************************************************/
102255 +t_TaskletHandle XX_InitTasklet (void (*routine)(void *), void *data);
102256 +
102257 +/**************************************************************************//**
102258 + @Function XX_FreeTasklet
102259 +
102260 + @Description Free a tasklet object.
102261 +
102262 + @Param[in] h_Tasklet - A handle to a tasklet to be free.
102263 +
102264 + @Return None.
102265 +*//***************************************************************************/
102266 +void XX_FreeTasklet (t_TaskletHandle h_Tasklet);
102267 +
102268 +/**************************************************************************//**
102269 + @Function XX_ScheduleTask
102270 +
102271 + @Description Schedule a tasklet object.
102272 +
102273 + @Param[in] h_Tasklet - A handle to a tasklet to be scheduled.
102274 + @Param[in] immediate - Indicate whether to schedule this tasklet on
102275 + the immediate queue or on the delayed one.
102276 +
102277 + @Return 0 - on success. Error code - otherwise.
102278 +*//***************************************************************************/
102279 +int XX_ScheduleTask(t_TaskletHandle h_Tasklet, int immediate);
102280 +
102281 +/**************************************************************************//**
102282 + @Function XX_FlushScheduledTasks
102283 +
102284 + @Description Flush all tasks there are in the scheduled tasks queue.
102285 +
102286 + @Return None.
102287 +*//***************************************************************************/
102288 +void XX_FlushScheduledTasks(void);
102289 +
102290 +/**************************************************************************//**
102291 + @Function XX_TaskletIsQueued
102292 +
102293 + @Description Check if task is queued.
102294 +
102295 + @Param[in] h_Tasklet - A handle to a tasklet to be scheduled.
102296 +
102297 + @Return 1 - task is queued. 0 - otherwise.
102298 +*//***************************************************************************/
102299 +int XX_TaskletIsQueued(t_TaskletHandle h_Tasklet);
102300 +
102301 +/**************************************************************************//**
102302 + @Function XX_SetTaskletData
102303 +
102304 + @Description Set data to a scheduled task. Used to change data of already
102305 + scheduled task.
102306 +
102307 + @Param[in] h_Tasklet - A handle to a tasklet to be scheduled.
102308 + @Param[in] data - Data to be set.
102309 +*//***************************************************************************/
102310 +void XX_SetTaskletData(t_TaskletHandle h_Tasklet, t_Handle data);
102311 +
102312 +/**************************************************************************//**
102313 + @Function XX_GetTaskletData
102314 +
102315 + @Description Get the data of scheduled task.
102316 +
102317 + @Param[in] h_Tasklet - A handle to a tasklet to be scheduled.
102318 +
102319 + @Return handle to the data of the task.
102320 +*//***************************************************************************/
102321 +t_Handle XX_GetTaskletData(t_TaskletHandle h_Tasklet);
102322 +
102323 +/**************************************************************************//**
102324 + @Function XX_BottomHalf
102325 +
102326 + @Description Bottom half implementation, invoked by the interrupt handler.
102327 +
102328 + This routine handles all bottom-half tasklets with interrupts
102329 + enabled.
102330 +
102331 + @Return None.
102332 +*//***************************************************************************/
102333 +void XX_BottomHalf(void);
102334 +
102335 +
102336 +/*****************************************************************************/
102337 +/* Spinlock Service Routines */
102338 +/*****************************************************************************/
102339 +
102340 +/**************************************************************************//**
102341 + @Function XX_InitSpinlock
102342 +
102343 + @Description Creates a spinlock.
102344 +
102345 + @Return Spinlock handle is returned on success; NULL otherwise.
102346 +*//***************************************************************************/
102347 +t_Handle XX_InitSpinlock(void);
102348 +
102349 +/**************************************************************************//**
102350 + @Function XX_FreeSpinlock
102351 +
102352 + @Description Frees the memory allocated for the spinlock creation.
102353 +
102354 + @Param[in] h_Spinlock - A handle to a spinlock.
102355 +
102356 + @Return None.
102357 +*//***************************************************************************/
102358 +void XX_FreeSpinlock(t_Handle h_Spinlock);
102359 +
102360 +/**************************************************************************//**
102361 + @Function XX_LockSpinlock
102362 +
102363 + @Description Locks a spinlock.
102364 +
102365 + @Param[in] h_Spinlock - A handle to a spinlock.
102366 +
102367 + @Return None.
102368 +*//***************************************************************************/
102369 +void XX_LockSpinlock(t_Handle h_Spinlock);
102370 +
102371 +/**************************************************************************//**
102372 + @Function XX_UnlockSpinlock
102373 +
102374 + @Description Unlocks a spinlock.
102375 +
102376 + @Param[in] h_Spinlock - A handle to a spinlock.
102377 +
102378 + @Return None.
102379 +*//***************************************************************************/
102380 +void XX_UnlockSpinlock(t_Handle h_Spinlock);
102381 +
102382 +/**************************************************************************//**
102383 + @Function XX_LockIntrSpinlock
102384 +
102385 + @Description Locks a spinlock (interrupt safe).
102386 +
102387 + @Param[in] h_Spinlock - A handle to a spinlock.
102388 +
102389 + @Return A value that represents the interrupts state before the
102390 + operation, and should be passed to the matching
102391 + XX_UnlockIntrSpinlock() call.
102392 +*//***************************************************************************/
102393 +uint32_t XX_LockIntrSpinlock(t_Handle h_Spinlock);
102394 +
102395 +/**************************************************************************//**
102396 + @Function XX_UnlockIntrSpinlock
102397 +
102398 + @Description Unlocks a spinlock (interrupt safe).
102399 +
102400 + @Param[in] h_Spinlock - A handle to a spinlock.
102401 + @Param[in] intrFlags - A value that represents the interrupts state to
102402 + restore, as returned by the matching call for
102403 + XX_LockIntrSpinlock().
102404 +
102405 + @Return None.
102406 +*//***************************************************************************/
102407 +void XX_UnlockIntrSpinlock(t_Handle h_Spinlock, uint32_t intrFlags);
102408 +
102409 +
102410 +/*****************************************************************************/
102411 +/* Timers Service Routines */
102412 +/*****************************************************************************/
102413 +
102414 +/**************************************************************************//**
102415 + @Function XX_CurrentTime
102416 +
102417 + @Description Returns current system time.
102418 +
102419 + @Return Current system time (in milliseconds).
102420 +*//***************************************************************************/
102421 +uint32_t XX_CurrentTime(void);
102422 +
102423 +/**************************************************************************//**
102424 + @Function XX_CreateTimer
102425 +
102426 + @Description Creates a timer.
102427 +
102428 + @Return Timer handle is returned on success; NULL otherwise.
102429 +*//***************************************************************************/
102430 +t_Handle XX_CreateTimer(void);
102431 +
102432 +/**************************************************************************//**
102433 + @Function XX_FreeTimer
102434 +
102435 + @Description Frees the memory allocated for the timer creation.
102436 +
102437 + @Param[in] h_Timer - A handle to a timer.
102438 +
102439 + @Return None.
102440 +*//***************************************************************************/
102441 +void XX_FreeTimer(t_Handle h_Timer);
102442 +
102443 +/**************************************************************************//**
102444 + @Function XX_StartTimer
102445 +
102446 + @Description Starts a timer.
102447 +
102448 + The user can select to start the timer as periodic timer or as
102449 + one-shot timer. The user should provide a callback routine that
102450 + will be called when the timer expires.
102451 +
102452 + @Param[in] h_Timer - A handle to a timer.
102453 + @Param[in] msecs - Timer expiration period (in milliseconds).
102454 + @Param[in] periodic - TRUE for a periodic timer;
102455 + FALSE for a one-shot timer..
102456 + @Param[in] f_TimerExpired - A callback routine to be called when the
102457 + timer expires.
102458 + @Param[in] h_Arg - The argument to pass in the timer-expired
102459 + callback routine.
102460 +
102461 + @Return None.
102462 +*//***************************************************************************/
102463 +void XX_StartTimer(t_Handle h_Timer,
102464 + uint32_t msecs,
102465 + bool periodic,
102466 + void (*f_TimerExpired)(t_Handle h_Arg),
102467 + t_Handle h_Arg);
102468 +
102469 +/**************************************************************************//**
102470 + @Function XX_StopTimer
102471 +
102472 + @Description Frees the memory allocated for the timer creation.
102473 +
102474 + @Param[in] h_Timer - A handle to a timer.
102475 +
102476 + @Return None.
102477 +*//***************************************************************************/
102478 +void XX_StopTimer(t_Handle h_Timer);
102479 +
102480 +/**************************************************************************//**
102481 + @Function XX_ModTimer
102482 +
102483 + @Description Updates the expiration time of a timer.
102484 +
102485 + This routine adds the given time to the current system time,
102486 + and sets this value as the new expiration time of the timer.
102487 +
102488 + @Param[in] h_Timer - A handle to a timer.
102489 + @Param[in] msecs - The new interval until timer expiration
102490 + (in milliseconds).
102491 +
102492 + @Return None.
102493 +*//***************************************************************************/
102494 +void XX_ModTimer(t_Handle h_Timer, uint32_t msecs);
102495 +
102496 +/**************************************************************************//**
102497 + @Function XX_Sleep
102498 +
102499 + @Description Non-busy wait until the desired time (in milliseconds) has passed.
102500 +
102501 + @Param[in] msecs - The requested sleep time (in milliseconds).
102502 +
102503 + @Return Zero if the requested time has elapsed; Otherwise, the value
102504 + returned will be the unslept amount) in milliseconds.
102505 +
102506 + @Cautions This routine enables interrupts during its wait time.
102507 +*//***************************************************************************/
102508 +uint32_t XX_Sleep(uint32_t msecs);
102509 +
102510 +/**************************************************************************//**
102511 + @Function XX_UDelay
102512 +
102513 + @Description Busy-wait until the desired time (in microseconds) has passed.
102514 +
102515 + @Param[in] usecs - The requested delay time (in microseconds).
102516 +
102517 + @Return None.
102518 +
102519 + @Cautions It is highly unrecommended to call this routine during interrupt
102520 + time, because the system time may not be updated properly during
102521 + the delay loop. The behavior of this routine during interrupt
102522 + time is unexpected.
102523 +*//***************************************************************************/
102524 +void XX_UDelay(uint32_t usecs);
102525 +
102526 +
102527 +/*****************************************************************************/
102528 +/* Other Service Routines */
102529 +/*****************************************************************************/
102530 +
102531 +/**************************************************************************//**
102532 + @Function XX_PhysToVirt
102533 +
102534 + @Description Translates a physical address to the matching virtual address.
102535 +
102536 + @Param[in] addr - The physical address to translate.
102537 +
102538 + @Return Virtual address.
102539 +*//***************************************************************************/
102540 +void * XX_PhysToVirt(physAddress_t addr);
102541 +
102542 +/**************************************************************************//**
102543 + @Function XX_VirtToPhys
102544 +
102545 + @Description Translates a virtual address to the matching physical address.
102546 +
102547 + @Param[in] addr - The virtual address to translate.
102548 +
102549 + @Return Physical address.
102550 +*//***************************************************************************/
102551 +physAddress_t XX_VirtToPhys(void *addr);
102552 +
102553 +
102554 +/**************************************************************************//**
102555 + @Group xx_ipc XX Inter-Partition-Communication API
102556 +
102557 + @Description The following API is to be used when working with multiple
102558 + partitions configuration.
102559 +
102560 + @{
102561 +*//***************************************************************************/
102562 +
102563 +#define XX_IPC_MAX_ADDR_NAME_LENGTH 16 /**< Maximum length of an endpoint name string;
102564 + The IPC service can use this constant to limit
102565 + the storage space for IPC endpoint names. */
102566 +
102567 +
102568 +/**************************************************************************//**
102569 + @Function t_IpcMsgCompletion
102570 +
102571 + @Description Callback function used upon IPC non-blocking transaction completion
102572 + to return message buffer to the caller and to forward reply if available.
102573 +
102574 + This callback function may be attached by the source endpoint to any outgoing
102575 + IPC message to indicate a non-blocking send (see also XX_IpcSendMessage() routine).
102576 + Upon completion of an IPC transaction (consisting of a message and an optional reply),
102577 + the IPC service invokes this callback routine to return the message buffer to the sender
102578 + and to provide the received reply, if requested.
102579 +
102580 + User provides this function. Driver invokes it.
102581 +
102582 + @Param[in] h_Module - Abstract handle to the sending module - the same handle as was passed
102583 + in the XX_IpcSendMessage() function; This handle is typically used to point
102584 + to the internal data structure of the source endpoint.
102585 + @Param[in] p_Msg - Pointer to original (sent) message buffer;
102586 + The source endpoint can free (or reuse) this buffer when message
102587 + completion callback is called.
102588 + @Param[in] p_Reply - Pointer to (received) reply buffer;
102589 + This pointer is the same as was provided by the source endpoint in
102590 + XX_IpcSendMessage().
102591 + @Param[in] replyLength - Length (in bytes) of actual data in the reply buffer.
102592 + @Param[in] status - Completion status - E_OK or failure indication, e.g. IPC transaction completion
102593 + timeout.
102594 +
102595 + @Return None
102596 + *//***************************************************************************/
102597 +typedef void (t_IpcMsgCompletion)(t_Handle h_Module,
102598 + uint8_t *p_Msg,
102599 + uint8_t *p_Reply,
102600 + uint32_t replyLength,
102601 + t_Error status);
102602 +
102603 +/**************************************************************************//**
102604 + @Function t_IpcMsgHandler
102605 +
102606 + @Description Callback function used as IPC message handler.
102607 +
102608 + The IPC service invokes message handlers for each IPC message received.
102609 + The actual function pointer should be registered by each destination endpoint
102610 + via the XX_IpcRegisterMsgHandler() routine.
102611 +
102612 + User provides this function. Driver invokes it.
102613 +
102614 + @Param[in] h_Module - Abstract handle to the message handling module - the same handle as
102615 + was passed in the XX_IpcRegisterMsgHandler() function; this handle is
102616 + typically used to point to the internal data structure of the destination
102617 + endpoint.
102618 + @Param[in] p_Msg - Pointer to message buffer with data received from peer.
102619 + @Param[in] msgLength - Length (in bytes) of message data.
102620 + @Param[in] p_Reply - Pointer to reply buffer, to be filled by the message handler and then sent
102621 + by the IPC service;
102622 + The reply buffer is allocated by the IPC service with size equals to the
102623 + replyLength parameter provided in message handler registration (see
102624 + XX_IpcRegisterMsgHandler() function);
102625 + If replyLength was initially specified as zero during message handler registration,
102626 + the IPC service may set this pointer to NULL and assume that a reply is not needed;
102627 + The IPC service is also responsible for freeing the reply buffer after the
102628 + reply has been sent or dismissed.
102629 + @Param[in,out] p_ReplyLength - Pointer to reply length, which has a dual role in this function:
102630 + [In] equals the replyLength parameter provided in message handler
102631 + registration (see XX_IpcRegisterMsgHandler() function), and
102632 + [Out] should be updated by message handler to the actual reply length; if
102633 + this value is set to zero, the IPC service must assume that a reply should
102634 + not be sent;
102635 + Note: If p_Reply is not NULL, p_ReplyLength must not be NULL as well.
102636 +
102637 + @Return E_OK on success; Error code otherwise.
102638 + *//***************************************************************************/
102639 +typedef t_Error (t_IpcMsgHandler)(t_Handle h_Module,
102640 + uint8_t *p_Msg,
102641 + uint32_t msgLength,
102642 + uint8_t *p_Reply,
102643 + uint32_t *p_ReplyLength);
102644 +
102645 +/**************************************************************************//**
102646 + @Function XX_IpcRegisterMsgHandler
102647 +
102648 + @Description IPC mailbox registration.
102649 +
102650 + This function is used for registering an IPC message handler in the IPC service.
102651 + This function is called by each destination endpoint to indicate that it is ready
102652 + to handle incoming messages. The IPC service invokes the message handler upon receiving
102653 + a message addressed to the specified destination endpoint.
102654 +
102655 + @Param[in] addr - The address name string associated with the destination endpoint;
102656 + This address must be unique across the IPC service domain to ensure
102657 + correct message routing.
102658 + @Param[in] f_MsgHandler - Pointer to the message handler callback for processing incoming
102659 + message; invoked by the IPC service upon receiving a message
102660 + addressed to the destination endpoint specified by the addr
102661 + parameter.
102662 + @Param[in] h_Module - Abstract handle to the message handling module, passed unchanged
102663 + to f_MsgHandler callback function.
102664 + @Param[in] replyLength - The maximal data length (in bytes) of any reply that the specified message handler
102665 + may generate; the IPC service provides the message handler with buffer
102666 + for reply according to the length specified here (refer also to the description
102667 + of #t_IpcMsgHandler callback function type);
102668 + This size shall be zero if the message handler never generates replies.
102669 +
102670 + @Return E_OK on success; Error code otherwise.
102671 +*//***************************************************************************/
102672 +t_Error XX_IpcRegisterMsgHandler(char addr[XX_IPC_MAX_ADDR_NAME_LENGTH],
102673 + t_IpcMsgHandler *f_MsgHandler,
102674 + t_Handle h_Module,
102675 + uint32_t replyLength);
102676 +
102677 +/**************************************************************************//**
102678 + @Function XX_IpcUnregisterMsgHandler
102679 +
102680 + @Description Release IPC mailbox routine.
102681 +
102682 + This function is used for unregistering an IPC message handler from the IPC service.
102683 + This function is called by each destination endpoint to indicate that it is no longer
102684 + capable of handling incoming messages.
102685 +
102686 + @Param[in] addr - The address name string associated with the destination endpoint;
102687 + This address is the same as was used when the message handler was
102688 + registered via XX_IpcRegisterMsgHandler().
102689 +
102690 + @Return E_OK on success; Error code otherwise.
102691 +*//***************************************************************************/
102692 +t_Error XX_IpcUnregisterMsgHandler(char addr[XX_IPC_MAX_ADDR_NAME_LENGTH]);
102693 +
102694 +/**************************************************************************//**
102695 + @Function XX_IpcInitSession
102696 +
102697 + @Description This function is used for creating an IPC session between the source endpoint
102698 + and the destination endpoint.
102699 +
102700 + The actual implementation and representation of a session is left for the IPC service.
102701 + The function returns an abstract handle to the created session. This handle shall be used
102702 + by the source endpoint in subsequent calls to XX_IpcSendMessage().
102703 + The IPC service assumes that before this function is called, no messages are sent from
102704 + the specified source endpoint to the specified destination endpoint.
102705 +
102706 + The IPC service may use a connection-oriented approach or a connectionless approach (or both)
102707 + as described below.
102708 +
102709 + @par Connection-Oriented Approach
102710 +
102711 + The IPC service may implement a session in a connection-oriented approach - when this function is called,
102712 + the IPC service should take the necessary steps to bring up a source-to-destination channel for messages
102713 + and a destination-to-source channel for replies. The returned handle should represent the internal
102714 + representation of these channels.
102715 +
102716 + @par Connectionless Approach
102717 +
102718 + The IPC service may implement a session in a connectionless approach - when this function is called, the
102719 + IPC service should not perform any particular steps, but it must store the pair of source and destination
102720 + addresses in some session representation and return it as a handle. When XX_IpcSendMessage() shall be
102721 + called, the IPC service may use this handle to provide the necessary identifiers for routing the messages
102722 + through the connectionless medium.
102723 +
102724 + @Param[in] destAddr - The address name string associated with the destination endpoint.
102725 + @Param[in] srcAddr - The address name string associated with the source endpoint.
102726 +
102727 + @Return Abstract handle to the initialized session, or NULL on error.
102728 +*//***************************************************************************/
102729 +t_Handle XX_IpcInitSession(char destAddr[XX_IPC_MAX_ADDR_NAME_LENGTH],
102730 + char srcAddr[XX_IPC_MAX_ADDR_NAME_LENGTH]);
102731 +
102732 +/**************************************************************************//**
102733 + @Function XX_IpcFreeSession
102734 +
102735 + @Description This function is used for terminating an existing IPC session between a source endpoint
102736 + and a destination endpoint.
102737 +
102738 + The IPC service assumes that after this function is called, no messages shall be sent from
102739 + the associated source endpoint to the associated destination endpoint.
102740 +
102741 + @Param[in] h_Session - Abstract handle to the IPC session - the same handle as was originally
102742 + returned by the XX_IpcInitSession() function.
102743 +
102744 + @Return E_OK on success; Error code otherwise.
102745 +*//***************************************************************************/
102746 +t_Error XX_IpcFreeSession(t_Handle h_Session);
102747 +
102748 +/**************************************************************************//**
102749 + @Function XX_IpcSendMessage
102750 +
102751 + @Description IPC message send routine.
102752 +
102753 + This function may be used by a source endpoint to send an IPC message to a destination
102754 + endpoint. The source endpoint cannot send a message to the destination endpoint without
102755 + first initiating a session with that destination endpoint via XX_IpcInitSession() routine.
102756 +
102757 + The source endpoint must provide the buffer pointer and length of the outgoing message.
102758 + Optionally, it may also provide a buffer for an expected reply. In the latter case, the
102759 + transaction is not considered complete by the IPC service until the reply has been received.
102760 + If the source endpoint does not provide a reply buffer, the transaction is considered
102761 + complete after the message has been sent. The source endpoint must keep the message (and
102762 + optional reply) buffers valid until the transaction is complete.
102763 +
102764 + @par Non-blocking mode
102765 +
102766 + The source endpoint may request a non-blocking send by providing a non-NULL pointer to a message
102767 + completion callback function (f_Completion). Upon completion of the IPC transaction (consisting of a
102768 + message and an optional reply), the IPC service invokes this callback routine to return the message
102769 + buffer to the sender and to provide the received reply, if requested.
102770 +
102771 + @par Blocking mode
102772 +
102773 + The source endpoint may request a blocking send by setting f_Completion to NULL. The function is
102774 + expected to block until the IPC transaction is complete - either the reply has been received or (if no reply
102775 + was requested) the message has been sent.
102776 +
102777 + @Param[in] h_Session - Abstract handle to the IPC session - the same handle as was originally
102778 + returned by the XX_IpcInitSession() function.
102779 + @Param[in] p_Msg - Pointer to message buffer to send.
102780 + @Param[in] msgLength - Length (in bytes) of actual data in the message buffer.
102781 + @Param[in] p_Reply - Pointer to reply buffer - if this buffer is not NULL, the IPC service
102782 + fills this buffer with the received reply data;
102783 + In blocking mode, the reply data must be valid when the function returns;
102784 + In non-blocking mode, the reply data is valid when f_Completion is called;
102785 + If this pointer is NULL, no reply is expected.
102786 + @Param[in,out] p_ReplyLength - Pointer to reply length, which has a dual role in this function:
102787 + [In] specifies the maximal length (in bytes) of the reply buffer pointed by
102788 + p_Reply, and
102789 + [Out] in non-blocking mode this value is updated by the IPC service to the
102790 + actual reply length (in bytes).
102791 + @Param[in] f_Completion - Pointer to a completion callback to be used in non-blocking send mode;
102792 + The completion callback is invoked by the IPC service upon
102793 + completion of the IPC transaction (consisting of a message and an optional
102794 + reply);
102795 + If this pointer is NULL, the function is expected to block until the IPC
102796 + transaction is complete.
102797 + @Param[in] h_Arg - Abstract handle to the sending module; passed unchanged to the f_Completion
102798 + callback function as the first argument.
102799 +
102800 + @Return E_OK on success; Error code otherwise.
102801 +*//***************************************************************************/
102802 +t_Error XX_IpcSendMessage(t_Handle h_Session,
102803 + uint8_t *p_Msg,
102804 + uint32_t msgLength,
102805 + uint8_t *p_Reply,
102806 + uint32_t *p_ReplyLength,
102807 + t_IpcMsgCompletion *f_Completion,
102808 + t_Handle h_Arg);
102809 +
102810 +
102811 +/** @} */ /* end of xx_ipc group */
102812 +/** @} */ /* end of xx_id group */
102813 +
102814 +
102815 +#endif /* __XX_EXT_H */
102816 --- /dev/null
102817 +++ b/drivers/net/ethernet/freescale/sdk_fman/ls1043_dflags.h
102818 @@ -0,0 +1,56 @@
102819 +/*
102820 + * Copyright 2012 Freescale Semiconductor Inc.
102821 + *
102822 + * Redistribution and use in source and binary forms, with or without
102823 + * modification, are permitted provided that the following conditions are met:
102824 + * * Redistributions of source code must retain the above copyright
102825 + * notice, this list of conditions and the following disclaimer.
102826 + * * Redistributions in binary form must reproduce the above copyright
102827 + * notice, this list of conditions and the following disclaimer in the
102828 + * documentation and/or other materials provided with the distribution.
102829 + * * Neither the name of Freescale Semiconductor nor the
102830 + * names of its contributors may be used to endorse or promote products
102831 + * derived from this software without specific prior written permission.
102832 + *
102833 + *
102834 + * ALTERNATIVELY, this software may be distributed under the terms of the
102835 + * GNU General Public License ("GPL") as published by the Free Software
102836 + * Foundation, either version 2 of that License or (at your option) any
102837 + * later version.
102838 + *
102839 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
102840 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
102841 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
102842 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
102843 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
102844 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
102845 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
102846 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
102847 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
102848 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
102849 + */
102850 +
102851 +#ifndef __dflags_h
102852 +#define __dflags_h
102853 +
102854 +
102855 +#define NCSW_LINUX
102856 +
102857 +#define LS1043
102858 +
102859 +#define DEBUG_ERRORS 1
102860 +
102861 +#if defined(DEBUG)
102862 +#define DEBUG_GLOBAL_LEVEL REPORT_LEVEL_INFO
102863 +
102864 +#define DEBUG_XX_MALLOC
102865 +#define DEBUG_MEM_LEAKS
102866 +
102867 +#else
102868 +#define DEBUG_GLOBAL_LEVEL REPORT_LEVEL_WARNING
102869 +#endif /* (DEBUG) */
102870 +
102871 +#define REPORT_EVENTS 1
102872 +#define EVENT_GLOBAL_LEVEL REPORT_LEVEL_MINOR
102873 +
102874 +#endif /* __dflags_h */
102875 --- /dev/null
102876 +++ b/drivers/net/ethernet/freescale/sdk_fman/ncsw_config.mk
102877 @@ -0,0 +1,53 @@
102878 +#
102879 +# Makefile config for the Freescale NetcommSW
102880 +#
102881 +NET_DPA = $(srctree)/drivers/net
102882 +DRV_DPA = $(srctree)/drivers/net/ethernet/freescale/sdk_dpaa
102883 +FMAN = $(srctree)/drivers/net/ethernet/freescale/sdk_fman
102884 +
102885 +ifeq ("$(CONFIG_FMAN_P3040_P4080_P5020)", "y")
102886 +ccflags-y +=-include $(FMAN)/p3040_4080_5020_dflags.h
102887 +endif
102888 +ifeq ("$(CONFIG_FMAN_P1023)", "y")
102889 +ccflags-y +=-include $(FMAN)/p1023_dflags.h
102890 +endif
102891 +ifdef CONFIG_FMAN_V3H
102892 +ccflags-y +=-include $(FMAN)/fmanv3h_dflags.h
102893 +endif
102894 +ifdef CONFIG_FMAN_V3L
102895 +ccflags-y +=-include $(FMAN)/fmanv3l_dflags.h
102896 +endif
102897 +ifdef CONFIG_FMAN_ARM
102898 +ccflags-y +=-include $(FMAN)/ls1043_dflags.h
102899 +endif
102900 +
102901 +ccflags-y += -I$(DRV_DPA)/
102902 +ccflags-y += -I$(FMAN)/inc
102903 +ccflags-y += -I$(FMAN)/inc/cores
102904 +ccflags-y += -I$(FMAN)/inc/etc
102905 +ccflags-y += -I$(FMAN)/inc/Peripherals
102906 +ccflags-y += -I$(FMAN)/inc/flib
102907 +
102908 +ifeq ("$(CONFIG_FMAN_P3040_P4080_P5020)", "y")
102909 +ccflags-y += -I$(FMAN)/inc/integrations/P3040_P4080_P5020
102910 +endif
102911 +ifeq ("$(CONFIG_FMAN_P1023)", "y")
102912 +ccflags-y += -I$(FMAN)/inc/integrations/P1023
102913 +endif
102914 +ifdef CONFIG_FMAN_V3H
102915 +ccflags-y += -I$(FMAN)/inc/integrations/FMANV3H
102916 +endif
102917 +ifdef CONFIG_FMAN_V3L
102918 +ccflags-y += -I$(FMAN)/inc/integrations/FMANV3L
102919 +endif
102920 +ifdef CONFIG_FMAN_ARM
102921 +ccflags-y += -I$(FMAN)/inc/integrations/LS1043
102922 +endif
102923 +
102924 +ccflags-y += -I$(FMAN)/src/inc
102925 +ccflags-y += -I$(FMAN)/src/inc/system
102926 +ccflags-y += -I$(FMAN)/src/inc/wrapper
102927 +ccflags-y += -I$(FMAN)/src/inc/xx
102928 +ccflags-y += -I$(srctree)/include/uapi/linux/fmd
102929 +ccflags-y += -I$(srctree)/include/uapi/linux/fmd/Peripherals
102930 +ccflags-y += -I$(srctree)/include/uapi/linux/fmd/integrations
102931 --- /dev/null
102932 +++ b/drivers/net/ethernet/freescale/sdk_fman/p1023_dflags.h
102933 @@ -0,0 +1,65 @@
102934 +/*
102935 + * Copyright 2008-2012 Freescale Semiconductor Inc.
102936 + *
102937 + * Redistribution and use in source and binary forms, with or without
102938 + * modification, are permitted provided that the following conditions are met:
102939 + * * Redistributions of source code must retain the above copyright
102940 + * notice, this list of conditions and the following disclaimer.
102941 + * * Redistributions in binary form must reproduce the above copyright
102942 + * notice, this list of conditions and the following disclaimer in the
102943 + * documentation and/or other materials provided with the distribution.
102944 + * * Neither the name of Freescale Semiconductor nor the
102945 + * names of its contributors may be used to endorse or promote products
102946 + * derived from this software without specific prior written permission.
102947 + *
102948 + *
102949 + * ALTERNATIVELY, this software may be distributed under the terms of the
102950 + * GNU General Public License ("GPL") as published by the Free Software
102951 + * Foundation, either version 2 of that License or (at your option) any
102952 + * later version.
102953 + *
102954 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
102955 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
102956 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
102957 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
102958 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
102959 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
102960 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
102961 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
102962 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
102963 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
102964 + */
102965 +
102966 +#ifndef __dflags_h
102967 +#define __dflags_h
102968 +
102969 +
102970 +#define NCSW_LINUX
102971 +#if 0
102972 +#define DEBUG
102973 +#endif
102974 +
102975 +#define P1023
102976 +#define NCSW_PPC_CORE
102977 +
102978 +#define DEBUG_ERRORS 1
102979 +
102980 +#if defined(DEBUG)
102981 +#define DEBUG_GLOBAL_LEVEL REPORT_LEVEL_INFO
102982 +
102983 +#define DEBUG_XX_MALLOC
102984 +#define DEBUG_MEM_LEAKS
102985 +
102986 +#else
102987 +#define DEBUG_GLOBAL_LEVEL REPORT_LEVEL_WARNING
102988 +#endif /* (DEBUG) */
102989 +
102990 +#define REPORT_EVENTS 1
102991 +#define EVENT_GLOBAL_LEVEL REPORT_LEVEL_MINOR
102992 +
102993 +#ifdef CONFIG_P4080_SIM
102994 +#error "Do not define CONFIG_P4080_SIM..."
102995 +#endif
102996 +
102997 +
102998 +#endif /* __dflags_h */
102999 --- /dev/null
103000 +++ b/drivers/net/ethernet/freescale/sdk_fman/p3040_4080_5020_dflags.h
103001 @@ -0,0 +1,62 @@
103002 +/*
103003 + * Copyright 2008-2012 Freescale Semiconductor Inc.
103004 + *
103005 + * Redistribution and use in source and binary forms, with or without
103006 + * modification, are permitted provided that the following conditions are met:
103007 + * * Redistributions of source code must retain the above copyright
103008 + * notice, this list of conditions and the following disclaimer.
103009 + * * Redistributions in binary form must reproduce the above copyright
103010 + * notice, this list of conditions and the following disclaimer in the
103011 + * documentation and/or other materials provided with the distribution.
103012 + * * Neither the name of Freescale Semiconductor nor the
103013 + * names of its contributors may be used to endorse or promote products
103014 + * derived from this software without specific prior written permission.
103015 + *
103016 + *
103017 + * ALTERNATIVELY, this software may be distributed under the terms of the
103018 + * GNU General Public License ("GPL") as published by the Free Software
103019 + * Foundation, either version 2 of that License or (at your option) any
103020 + * later version.
103021 + *
103022 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
103023 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
103024 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
103025 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
103026 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
103027 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
103028 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
103029 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
103030 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
103031 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
103032 + */
103033 +
103034 +#ifndef __dflags_h
103035 +#define __dflags_h
103036 +
103037 +
103038 +#define NCSW_LINUX
103039 +
103040 +#define P4080
103041 +#define NCSW_PPC_CORE
103042 +
103043 +#define DEBUG_ERRORS 1
103044 +
103045 +#if defined(DEBUG)
103046 +#define DEBUG_GLOBAL_LEVEL REPORT_LEVEL_INFO
103047 +
103048 +#define DEBUG_XX_MALLOC
103049 +#define DEBUG_MEM_LEAKS
103050 +
103051 +#else
103052 +#define DEBUG_GLOBAL_LEVEL REPORT_LEVEL_WARNING
103053 +#endif /* (DEBUG) */
103054 +
103055 +#define REPORT_EVENTS 1
103056 +#define EVENT_GLOBAL_LEVEL REPORT_LEVEL_MINOR
103057 +
103058 +#ifdef CONFIG_P4080_SIM
103059 +#define SIMULATOR
103060 +#endif /* CONFIG_P4080_SIM */
103061 +
103062 +
103063 +#endif /* __dflags_h */
103064 --- /dev/null
103065 +++ b/drivers/net/ethernet/freescale/sdk_fman/src/Makefile
103066 @@ -0,0 +1,11 @@
103067 +#
103068 +# Makefile for the Freescale Ethernet controllers
103069 +#
103070 +ccflags-y += -DVERSION=\"\"
103071 +#
103072 +#Include netcomm SW specific definitions
103073 +include $(srctree)/drivers/net/ethernet/freescale/sdk_fman/ncsw_config.mk
103074 +#
103075 +obj-y += system/
103076 +obj-y += wrapper/
103077 +obj-y += xx/
103078 --- /dev/null
103079 +++ b/drivers/net/ethernet/freescale/sdk_fman/src/inc/system/sys_ext.h
103080 @@ -0,0 +1,118 @@
103081 +/*
103082 + * Copyright 2008-2012 Freescale Semiconductor Inc.
103083 + *
103084 + * Redistribution and use in source and binary forms, with or without
103085 + * modification, are permitted provided that the following conditions are met:
103086 + * * Redistributions of source code must retain the above copyright
103087 + * notice, this list of conditions and the following disclaimer.
103088 + * * Redistributions in binary form must reproduce the above copyright
103089 + * notice, this list of conditions and the following disclaimer in the
103090 + * documentation and/or other materials provided with the distribution.
103091 + * * Neither the name of Freescale Semiconductor nor the
103092 + * names of its contributors may be used to endorse or promote products
103093 + * derived from this software without specific prior written permission.
103094 + *
103095 + *
103096 + * ALTERNATIVELY, this software may be distributed under the terms of the
103097 + * GNU General Public License ("GPL") as published by the Free Software
103098 + * Foundation, either version 2 of that License or (at your option) any
103099 + * later version.
103100 + *
103101 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
103102 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
103103 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
103104 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
103105 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
103106 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
103107 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
103108 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
103109 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
103110 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
103111 + */
103112 +
103113 +#ifndef __SYS_EXT_H
103114 +#define __SYS_EXT_H
103115 +
103116 +#include "std_ext.h"
103117 +
103118 +
103119 +/**************************************************************************//**
103120 + @Group sys_grp System Interfaces
103121 +
103122 + @Description Linux system programming interfaces.
103123 +
103124 + @{
103125 +*//***************************************************************************/
103126 +
103127 +/**************************************************************************//**
103128 + @Group sys_gen_grp System General Interface
103129 +
103130 + @Description General definitions, structures and routines of the linux
103131 + system programming interface.
103132 +
103133 + @{
103134 +*//***************************************************************************/
103135 +
103136 +/**************************************************************************//**
103137 + @Collection Macros for Advanced Configuration Requests
103138 + @{
103139 +*//***************************************************************************/
103140 +#define SYS_MAX_ADV_CONFIG_ARGS 4
103141 + /**< Maximum number of arguments in
103142 + an advanced configuration entry */
103143 +/* @} */
103144 +
103145 +/**************************************************************************//**
103146 + @Description System Object Advanced Configuration Entry
103147 +
103148 + This structure represents a single request for an advanced
103149 + configuration call on the initialized object. An array of such
103150 + requests may be contained in the settings structure of the
103151 + corresponding object.
103152 +
103153 + The maximum number of arguments is limited to #SYS_MAX_ADV_CONFIG_ARGS.
103154 +*//***************************************************************************/
103155 +typedef struct t_SysObjectAdvConfigEntry
103156 +{
103157 + void *p_Function; /**< Pointer to advanced configuration routine */
103158 +
103159 + uintptr_t args[SYS_MAX_ADV_CONFIG_ARGS];
103160 + /**< Array of arguments for the specified routine;
103161 + All arguments should be casted to uint32_t. */
103162 +} t_SysObjectAdvConfigEntry;
103163 +
103164 +
103165 +/** @} */ /* end of sys_gen_grp */
103166 +/** @} */ /* end of sys_grp */
103167 +
103168 +#define NCSW_PARAMS(_num, _params) ADV_CONFIG_PARAMS_##_num _params
103169 +
103170 +#define ADV_CONFIG_PARAMS_1(_type) \
103171 + , (_type)p_Entry->args[0]
103172 +
103173 +#define SET_ADV_CONFIG_ARGS_1(_arg0) \
103174 + p_Entry->args[0] = (uintptr_t )(_arg0); \
103175 +
103176 +#define ARGS(_num, _params) SET_ADV_CONFIG_ARGS_##_num _params
103177 +
103178 +#define ADD_ADV_CONFIG_START(_p_Entries, _maxEntries) \
103179 + { \
103180 + t_SysObjectAdvConfigEntry *p_Entry; \
103181 + t_SysObjectAdvConfigEntry *p_Entrys = (_p_Entries); \
103182 + int i=0, max = (_maxEntries); \
103183 +
103184 +#define ADD_ADV_CONFIG_END \
103185 + }
103186 +
103187 +#define ADV_CONFIG_CHECK_START(_p_Entry) \
103188 + { \
103189 + t_SysObjectAdvConfigEntry *p_Entry = _p_Entry; \
103190 + t_Error errCode; \
103191 +
103192 +#define ADV_CONFIG_CHECK(_handle, _func, _params) \
103193 + if (p_Entry->p_Function == _func) \
103194 + { \
103195 + errCode = _func(_handle _params); \
103196 + } else
103197 +
103198 +#endif /* __SYS_EXT_H */
103199 --- /dev/null
103200 +++ b/drivers/net/ethernet/freescale/sdk_fman/src/inc/system/sys_io_ext.h
103201 @@ -0,0 +1,46 @@
103202 +/*
103203 + * Copyright 2008-2012 Freescale Semiconductor Inc.
103204 + *
103205 + * Redistribution and use in source and binary forms, with or without
103206 + * modification, are permitted provided that the following conditions are met:
103207 + * * Redistributions of source code must retain the above copyright
103208 + * notice, this list of conditions and the following disclaimer.
103209 + * * Redistributions in binary form must reproduce the above copyright
103210 + * notice, this list of conditions and the following disclaimer in the
103211 + * documentation and/or other materials provided with the distribution.
103212 + * * Neither the name of Freescale Semiconductor nor the
103213 + * names of its contributors may be used to endorse or promote products
103214 + * derived from this software without specific prior written permission.
103215 + *
103216 + *
103217 + * ALTERNATIVELY, this software may be distributed under the terms of the
103218 + * GNU General Public License ("GPL") as published by the Free Software
103219 + * Foundation, either version 2 of that License or (at your option) any
103220 + * later version.
103221 + *
103222 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
103223 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
103224 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
103225 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
103226 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
103227 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
103228 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
103229 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
103230 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
103231 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
103232 + */
103233 +
103234 +#ifndef __SYS_IO_EXT_H
103235 +#define __SYS_IO_EXT_H
103236 +
103237 +#include "std_ext.h"
103238 +#include "error_ext.h"
103239 +
103240 +
103241 +t_Error SYS_RegisterIoMap (uint64_t virtAddr, uint64_t physAddr, uint32_t size);
103242 +t_Error SYS_UnregisterIoMap (uint64_t virtAddr);
103243 +uint64_t SYS_PhysToVirt (uint64_t addr);
103244 +uint64_t SYS_VirtToPhys (uint64_t addr);
103245 +
103246 +
103247 +#endif /* __SYS_IO_EXT_H */
103248 --- /dev/null
103249 +++ b/drivers/net/ethernet/freescale/sdk_fman/src/inc/types_linux.h
103250 @@ -0,0 +1,208 @@
103251 +/*
103252 + * Copyright 2008-2012 Freescale Semiconductor Inc.
103253 + *
103254 + * Redistribution and use in source and binary forms, with or without
103255 + * modification, are permitted provided that the following conditions are met:
103256 + * * Redistributions of source code must retain the above copyright
103257 + * notice, this list of conditions and the following disclaimer.
103258 + * * Redistributions in binary form must reproduce the above copyright
103259 + * notice, this list of conditions and the following disclaimer in the
103260 + * documentation and/or other materials provided with the distribution.
103261 + * * Neither the name of Freescale Semiconductor nor the
103262 + * names of its contributors may be used to endorse or promote products
103263 + * derived from this software without specific prior written permission.
103264 + *
103265 + *
103266 + * ALTERNATIVELY, this software may be distributed under the terms of the
103267 + * GNU General Public License ("GPL") as published by the Free Software
103268 + * Foundation, either version 2 of that License or (at your option) any
103269 + * later version.
103270 + *
103271 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
103272 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
103273 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
103274 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
103275 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
103276 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
103277 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
103278 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
103279 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
103280 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
103281 + */
103282 +
103283 +#ifndef __TYPES_LINUX_H__
103284 +#define __TYPES_LINUX_H__
103285 +
103286 +#include <linux/version.h>
103287 +
103288 +#if defined(CONFIG_MODVERSIONS) && !defined(MODVERSIONS)
103289 +#define MODVERSIONS
103290 +#endif
103291 +#ifdef MODVERSIONS
103292 +#include <config/modversions.h>
103293 +#endif /* MODVERSIONS */
103294 +
103295 +#include <linux/kernel.h>
103296 +#include <linux/types.h>
103297 +#include <asm/io.h>
103298 +#include <linux/delay.h>
103299 +
103300 +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,11)
103301 + #error "This kernel is probably not supported!!!"
103302 +#elif (!((LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,19)) || \
103303 + (LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,27)) || \
103304 + (LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,30))))
103305 + #warning "This kernel is probably not supported!!! You may need to add some fixes."
103306 +#endif /* LINUX_VERSION_CODE */
103307 +
103308 +
103309 +typedef float float_t; /* Single precision floating point */
103310 +typedef double double_t; /* Double precision floating point */
103311 +
103312 +
103313 +#define _Packed
103314 +#define _PackedType __attribute__ ((packed))
103315 +
103316 +typedef phys_addr_t physAddress_t;
103317 +
103318 +#define UINT8_MAX 0xFF
103319 +#define UINT8_MIN 0
103320 +#define UINT16_MAX 0xFFFF
103321 +#define UINT16_MIN 0
103322 +#define UINT32_MAX 0xFFFFFFFF
103323 +#define UINT32_MIN 0
103324 +#define UINT64_MAX 0xFFFFFFFFFFFFFFFFLL
103325 +#define UINT64_MIN 0
103326 +#define INT8_MAX 0x7F
103327 +#define INT8_MIN 0x80
103328 +#define INT16_MAX 0x7FFF
103329 +#define INT16_MIN 0x8000
103330 +#define INT32_MAX 0x7FFFFFFF
103331 +#define INT32_MIN 0x80000000
103332 +#define INT64_MAX 0x7FFFFFFFFFFFFFFFLL
103333 +#define INT64_MIN 0x8000000000000000LL
103334 +
103335 +#define ON 1
103336 +#define OFF 0
103337 +
103338 +#define FALSE false
103339 +#define TRUE true
103340 +
103341 +
103342 +/************************/
103343 +/* memory access macros */
103344 +/************************/
103345 +#ifdef CONFIG_FMAN_ARM
103346 +#define in_be16(a) __be16_to_cpu(__raw_readw(a))
103347 +#define in_be32(a) __be32_to_cpu(__raw_readl(a))
103348 +#define out_be16(a, v) __raw_writew(__cpu_to_be16(v), a)
103349 +#define out_be32(a, v) __raw_writel(__cpu_to_be32(v), a)
103350 +#endif
103351 +
103352 +#define GET_UINT8(arg) *(volatile uint8_t *)(&(arg))
103353 +#define GET_UINT16(arg) in_be16(&(arg))//*(volatile uint16_t*)(&(arg))
103354 +#define GET_UINT32(arg) in_be32(&(arg))//*(volatile uint32_t*)(&(arg))
103355 +#define GET_UINT64(arg) *(volatile uint64_t*)(&(arg))
103356 +
103357 +#ifdef VERBOSE_WRITE
103358 +void XX_Print(char *str, ...);
103359 +#define WRITE_UINT8(arg, data) \
103360 + do { XX_Print("ADDR: 0x%08x, VAL: 0x%02x\r\n", (uint32_t)&(arg), (data)); *(volatile uint8_t *)(&(arg)) = (data); } while (0)
103361 +#define WRITE_UINT16(arg, data) \
103362 + 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)
103363 +#define WRITE_UINT32(arg, data) \
103364 + 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)
103365 +#define WRITE_UINT64(arg, data) \
103366 + do { XX_Print("ADDR: 0x%08x, VAL: 0x%016llx\r\n", (uint32_t)&(arg), (data)); *(volatile uint64_t*)(&(arg)) = (data); } while (0)
103367 +
103368 +#else /* not VERBOSE_WRITE */
103369 +#define WRITE_UINT8(arg, data) *(volatile uint8_t *)(&(arg)) = (data)
103370 +#define WRITE_UINT16(arg, data) out_be16(&(arg), data)//*(volatile uint16_t*)(&(arg)) = (data)
103371 +#define WRITE_UINT32(arg, data) out_be32(&(arg), data)//*(volatile unsigned int *)(&(arg)) = (data)
103372 +#define WRITE_UINT64(arg, data) *(volatile uint64_t*)(&(arg)) = (data)
103373 +#endif /* not VERBOSE_WRITE */
103374 +
103375 +
103376 +/*****************************************************************************/
103377 +/* General stuff */
103378 +/*****************************************************************************/
103379 +#ifdef ARRAY_SIZE
103380 +#undef ARRAY_SIZE
103381 +#endif /* ARRAY_SIZE */
103382 +
103383 +#ifdef MAJOR
103384 +#undef MAJOR
103385 +#endif /* MAJOR */
103386 +
103387 +#ifdef MINOR
103388 +#undef MINOR
103389 +#endif /* MINOR */
103390 +
103391 +#ifdef QE_SIZEOF_BD
103392 +#undef QE_SIZEOF_BD
103393 +#endif /* QE_SIZEOF_BD */
103394 +
103395 +#ifdef BD_BUFFER_CLEAR
103396 +#undef BD_BUFFER_CLEAR
103397 +#endif /* BD_BUFFER_CLEAR */
103398 +
103399 +#ifdef BD_BUFFER
103400 +#undef BD_BUFFER
103401 +#endif /* BD_BUFFER */
103402 +
103403 +#ifdef BD_STATUS_AND_LENGTH_SET
103404 +#undef BD_STATUS_AND_LENGTH_SET
103405 +#endif /* BD_STATUS_AND_LENGTH_SET */
103406 +
103407 +#ifdef BD_STATUS_AND_LENGTH
103408 +#undef BD_STATUS_AND_LENGTH
103409 +#endif /* BD_STATUS_AND_LENGTH */
103410 +
103411 +#ifdef BD_BUFFER_ARG
103412 +#undef BD_BUFFER_ARG
103413 +#endif /* BD_BUFFER_ARG */
103414 +
103415 +#ifdef BD_GET_NEXT
103416 +#undef BD_GET_NEXT
103417 +#endif /* BD_GET_NEXT */
103418 +
103419 +#ifdef QE_SDEBCR_BA_MASK
103420 +#undef QE_SDEBCR_BA_MASK
103421 +#endif /* QE_SDEBCR_BA_MASK */
103422 +
103423 +#ifdef BD_BUFFER_SET
103424 +#undef BD_BUFFER_SET
103425 +#endif /* BD_BUFFER_SET */
103426 +
103427 +#ifdef UPGCR_PROTOCOL
103428 +#undef UPGCR_PROTOCOL
103429 +#endif /* UPGCR_PROTOCOL */
103430 +
103431 +#ifdef UPGCR_TMS
103432 +#undef UPGCR_TMS
103433 +#endif /* UPGCR_TMS */
103434 +
103435 +#ifdef UPGCR_RMS
103436 +#undef UPGCR_RMS
103437 +#endif /* UPGCR_RMS */
103438 +
103439 +#ifdef UPGCR_ADDR
103440 +#undef UPGCR_ADDR
103441 +#endif /* UPGCR_ADDR */
103442 +
103443 +#ifdef UPGCR_DIAG
103444 +#undef UPGCR_DIAG
103445 +#endif /* UPGCR_DIAG */
103446 +
103447 +#ifdef NCSW_PARAMS
103448 +#undef NCSW_PARAMS
103449 +#endif /* NCSW_PARAMS */
103450 +
103451 +#ifdef NO_IRQ
103452 +#undef NO_IRQ
103453 +#endif /* NO_IRQ */
103454 +
103455 +#define PRINT_LINE XX_Print("%s:\n %s [%d]\n",__FILE__,__FUNCTION__,__LINE__);
103456 +
103457 +
103458 +#endif /* __TYPES_LINUX_H__ */
103459 --- /dev/null
103460 +++ b/drivers/net/ethernet/freescale/sdk_fman/src/inc/wrapper/fsl_fman_test.h
103461 @@ -0,0 +1,84 @@
103462 +/* Copyright (c) 2008-2011 Freescale Semiconductor, Inc.
103463 + * All rights reserved.
103464 + *
103465 + * Redistribution and use in source and binary forms, with or without
103466 + * modification, are permitted provided that the following conditions are met:
103467 + * * Redistributions of source code must retain the above copyright
103468 + * notice, this list of conditions and the following disclaimer.
103469 + * * Redistributions in binary form must reproduce the above copyright
103470 + * notice, this list of conditions and the following disclaimer in the
103471 + * documentation and/or other materials provided with the distribution.
103472 + * * Neither the name of Freescale Semiconductor nor the
103473 + * names of its contributors may be used to endorse or promote products
103474 + * derived from this software without specific prior written permission.
103475 + *
103476 + *
103477 + * ALTERNATIVELY, this software may be distributed under the terms of the
103478 + * GNU General Public License ("GPL") as published by the Free Software
103479 + * Foundation, either version 2 of that License or (at your option) any
103480 + * later version.
103481 + *
103482 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
103483 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
103484 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
103485 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
103486 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
103487 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
103488 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
103489 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
103490 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
103491 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
103492 + */
103493 +
103494 +/******************************************************************************
103495 + @File fsl_fman_test.h
103496 +
103497 + @Description
103498 +*//***************************************************************************/
103499 +
103500 +#ifndef __FSL_FMAN_TEST_H
103501 +#define __FSL_FMAN_TEST_H
103502 +
103503 +#include <linux/types.h>
103504 +#include <linux/smp.h> /* raw_smp_processor_id() */
103505 +
103506 +//#define FMT_K_DBG
103507 +//#define FMT_K_DBG_RUNTIME
103508 +
103509 +#define _fmt_prk(stage, format, arg...) \
103510 + printk(stage "fmt (cpu:%u): " format, raw_smp_processor_id(), ##arg)
103511 +
103512 +#define _fmt_inf(format, arg...) _fmt_prk(KERN_INFO, format, ##arg)
103513 +#define _fmt_wrn(format, arg...) _fmt_prk(KERN_WARNING, format, ##arg)
103514 +#define _fmt_err(format, arg...) _fmt_prk(KERN_ERR, format, ##arg)
103515 +
103516 +/* there are two macros for debugging: for runtime and generic.
103517 + * Helps when the runtime functions are not targeted for debugging,
103518 + * thus all the unnecessary information will be skipped.
103519 + */
103520 +/* used for generic debugging */
103521 +#if defined(FMT_K_DBG)
103522 + #define _fmt_dbg(format, arg...) \
103523 + printk("fmt [%s:%u](cpu:%u) - " format, \
103524 + __func__, __LINE__, raw_smp_processor_id(), ##arg)
103525 +#else
103526 +# define _fmt_dbg(arg...)
103527 +#endif
103528 +
103529 +/* used for debugging runtime functions */
103530 +#if defined(FMT_K_DBG_RUNTIME)
103531 + #define _fmt_dbgr(format, arg...) \
103532 + printk("fmt [%s:%u](cpu:%u) - " format, \
103533 + __func__, __LINE__, raw_smp_processor_id(), ##arg)
103534 +#else
103535 +# define _fmt_dbgr(arg...)
103536 +#endif
103537 +
103538 +#define FMT_RX_ERR_Q 0xffffffff
103539 +#define FMT_RX_DFLT_Q 0xfffffffe
103540 +#define FMT_TX_ERR_Q 0xfffffffd
103541 +#define FMT_TX_CONF_Q 0xfffffffc
103542 +
103543 +#define FMAN_TEST_MAX_TX_FQS 8
103544 +
103545 +#endif /* __FSL_FMAN_TEST_H */
103546 --- /dev/null
103547 +++ b/drivers/net/ethernet/freescale/sdk_fman/src/inc/wrapper/lnxwrp_exp_sym.h
103548 @@ -0,0 +1,130 @@
103549 +/* Copyright (c) 2008-2012 Freescale Semiconductor, Inc.
103550 + * All rights reserved.
103551 + *
103552 + * Redistribution and use in source and binary forms, with or without
103553 + * modification, are permitted provided that the following conditions are met:
103554 + * * Redistributions of source code must retain the above copyright
103555 + * notice, this list of conditions and the following disclaimer.
103556 + * * Redistributions in binary form must reproduce the above copyright
103557 + * notice, this list of conditions and the following disclaimer in the
103558 + * documentation and/or other materials provided with the distribution.
103559 + * * Neither the name of Freescale Semiconductor nor the
103560 + * names of its contributors may be used to endorse or promote products
103561 + * derived from this software without specific prior written permission.
103562 + *
103563 + *
103564 + * ALTERNATIVELY, this software may be distributed under the terms of the
103565 + * GNU General Public License ("GPL") as published by the Free Software
103566 + * Foundation, either version 2 of that License or (at your option) any
103567 + * later version.
103568 + *
103569 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
103570 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
103571 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
103572 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
103573 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
103574 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
103575 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
103576 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
103577 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
103578 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
103579 + */
103580 +
103581 +/*
103582 + @File lnxwrp_exp_sym.h
103583 + @Description FMan exported routines
103584 +*/
103585 +
103586 +#ifndef __LNXWRP_EXP_SYM_H
103587 +#define __LNXWRP_EXP_SYM_H
103588 +
103589 +#include "fm_port_ext.h"
103590 +#include "fm_pcd_ext.h"
103591 +#include "fm_mac_ext.h"
103592 +
103593 +
103594 +/* FMAN Port exported routines */
103595 +EXPORT_SYMBOL(FM_PORT_Disable);
103596 +EXPORT_SYMBOL(FM_PORT_Enable);
103597 +EXPORT_SYMBOL(FM_PORT_SetPCD);
103598 +EXPORT_SYMBOL(FM_PORT_DeletePCD);
103599 +
103600 +/* Runtime PCD exported routines */
103601 +EXPORT_SYMBOL(FM_PCD_Enable);
103602 +EXPORT_SYMBOL(FM_PCD_Disable);
103603 +EXPORT_SYMBOL(FM_PCD_GetCounter);
103604 +EXPORT_SYMBOL(FM_PCD_PrsLoadSw);
103605 +EXPORT_SYMBOL(FM_PCD_KgSetDfltValue);
103606 +EXPORT_SYMBOL(FM_PCD_KgSetAdditionalDataAfterParsing);
103607 +EXPORT_SYMBOL(FM_PCD_SetException);
103608 +EXPORT_SYMBOL(FM_PCD_ModifyCounter);
103609 +EXPORT_SYMBOL(FM_PCD_SetPlcrStatistics);
103610 +EXPORT_SYMBOL(FM_PCD_SetPrsStatistics);
103611 +EXPORT_SYMBOL(FM_PCD_ForceIntr);
103612 +EXPORT_SYMBOL(FM_PCD_HcTxConf);
103613 +
103614 +EXPORT_SYMBOL(FM_PCD_NetEnvCharacteristicsSet);
103615 +EXPORT_SYMBOL(FM_PCD_NetEnvCharacteristicsDelete);
103616 +EXPORT_SYMBOL(FM_PCD_KgSchemeSet);
103617 +EXPORT_SYMBOL(FM_PCD_KgSchemeDelete);
103618 +EXPORT_SYMBOL(FM_PCD_KgSchemeGetCounter);
103619 +EXPORT_SYMBOL(FM_PCD_KgSchemeSetCounter);
103620 +EXPORT_SYMBOL(FM_PCD_CcRootBuild);
103621 +EXPORT_SYMBOL(FM_PCD_CcRootDelete);
103622 +EXPORT_SYMBOL(FM_PCD_MatchTableSet);
103623 +EXPORT_SYMBOL(FM_PCD_MatchTableDelete);
103624 +EXPORT_SYMBOL(FM_PCD_CcRootModifyNextEngine);
103625 +EXPORT_SYMBOL(FM_PCD_MatchTableModifyNextEngine);
103626 +EXPORT_SYMBOL(FM_PCD_MatchTableFindNModifyNextEngine);
103627 +EXPORT_SYMBOL(FM_PCD_MatchTableModifyMissNextEngine);
103628 +EXPORT_SYMBOL(FM_PCD_MatchTableRemoveKey);
103629 +EXPORT_SYMBOL(FM_PCD_MatchTableFindNRemoveKey);
103630 +EXPORT_SYMBOL(FM_PCD_MatchTableAddKey);
103631 +EXPORT_SYMBOL(FM_PCD_MatchTableModifyKeyAndNextEngine);
103632 +EXPORT_SYMBOL(FM_PCD_MatchTableFindNModifyKeyAndNextEngine);
103633 +EXPORT_SYMBOL(FM_PCD_MatchTableModifyKey);
103634 +EXPORT_SYMBOL(FM_PCD_MatchTableFindNModifyKey);
103635 +EXPORT_SYMBOL(FM_PCD_MatchTableGetIndexedHashBucket);
103636 +EXPORT_SYMBOL(FM_PCD_MatchTableGetNextEngine);
103637 +EXPORT_SYMBOL(FM_PCD_MatchTableGetKeyCounter);
103638 +EXPORT_SYMBOL(FM_PCD_MatchTableGetKeyStatistics);
103639 +EXPORT_SYMBOL(FM_PCD_MatchTableFindNGetKeyStatistics);
103640 +EXPORT_SYMBOL(FM_PCD_MatchTableGetMissStatistics);
103641 +EXPORT_SYMBOL(FM_PCD_HashTableGetMissStatistics);
103642 +EXPORT_SYMBOL(FM_PCD_HashTableSet);
103643 +EXPORT_SYMBOL(FM_PCD_HashTableDelete);
103644 +EXPORT_SYMBOL(FM_PCD_HashTableAddKey);
103645 +EXPORT_SYMBOL(FM_PCD_HashTableRemoveKey);
103646 +EXPORT_SYMBOL(FM_PCD_HashTableModifyNextEngine);
103647 +EXPORT_SYMBOL(FM_PCD_HashTableModifyMissNextEngine);
103648 +EXPORT_SYMBOL(FM_PCD_HashTableGetMissNextEngine);
103649 +EXPORT_SYMBOL(FM_PCD_HashTableFindNGetKeyStatistics);
103650 +EXPORT_SYMBOL(FM_PCD_PlcrProfileSet);
103651 +EXPORT_SYMBOL(FM_PCD_PlcrProfileDelete);
103652 +EXPORT_SYMBOL(FM_PCD_PlcrProfileGetCounter);
103653 +EXPORT_SYMBOL(FM_PCD_PlcrProfileSetCounter);
103654 +EXPORT_SYMBOL(FM_PCD_ManipNodeSet);
103655 +EXPORT_SYMBOL(FM_PCD_ManipNodeDelete);
103656 +EXPORT_SYMBOL(FM_PCD_ManipGetStatistics);
103657 +EXPORT_SYMBOL(FM_PCD_ManipNodeReplace);
103658 +#if (DPAA_VERSION >= 11)
103659 +EXPORT_SYMBOL(FM_PCD_FrmReplicSetGroup);
103660 +EXPORT_SYMBOL(FM_PCD_FrmReplicDeleteGroup);
103661 +EXPORT_SYMBOL(FM_PCD_FrmReplicAddMember);
103662 +EXPORT_SYMBOL(FM_PCD_FrmReplicRemoveMember);
103663 +#endif /* DPAA_VERSION >= 11 */
103664 +
103665 +#ifdef FM_CAPWAP_SUPPORT
103666 +EXPORT_SYMBOL(FM_PCD_StatisticsSetNode);
103667 +#endif /* FM_CAPWAP_SUPPORT */
103668 +
103669 +EXPORT_SYMBOL(FM_PCD_SetAdvancedOffloadSupport);
103670 +
103671 +/* FMAN MAC exported routines */
103672 +EXPORT_SYMBOL(FM_MAC_GetStatistics);
103673 +
103674 +EXPORT_SYMBOL(FM_MAC_GetFrameSizeCounters);
103675 +
103676 +EXPORT_SYMBOL(FM_GetSpecialOperationCoding);
103677 +
103678 +#endif /* __LNXWRP_EXP_SYM_H */
103679 --- /dev/null
103680 +++ b/drivers/net/ethernet/freescale/sdk_fman/src/inc/wrapper/lnxwrp_fm_ext.h
103681 @@ -0,0 +1,163 @@
103682 +/*
103683 + * Copyright 2008-2012 Freescale Semiconductor Inc.
103684 + *
103685 + * Redistribution and use in source and binary forms, with or without
103686 + * modification, are permitted provided that the following conditions are met:
103687 + * * Redistributions of source code must retain the above copyright
103688 + * notice, this list of conditions and the following disclaimer.
103689 + * * Redistributions in binary form must reproduce the above copyright
103690 + * notice, this list of conditions and the following disclaimer in the
103691 + * documentation and/or other materials provided with the distribution.
103692 + * * Neither the name of Freescale Semiconductor nor the
103693 + * names of its contributors may be used to endorse or promote products
103694 + * derived from this software without specific prior written permission.
103695 + *
103696 + *
103697 + * ALTERNATIVELY, this software may be distributed under the terms of the
103698 + * GNU General Public License ("GPL") as published by the Free Software
103699 + * Foundation, either version 2 of that License or (at your option) any
103700 + * later version.
103701 + *
103702 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
103703 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
103704 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
103705 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
103706 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
103707 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
103708 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
103709 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
103710 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
103711 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
103712 + */
103713 +
103714 +/******************************************************************************
103715 + @File lnxwrp_fm_ext.h
103716 +
103717 + @Description TODO
103718 +*//***************************************************************************/
103719 +
103720 +#ifndef __LNXWRP_FM_EXT_H
103721 +#define __LNXWRP_FM_EXT_H
103722 +
103723 +#include "std_ext.h"
103724 +#include "sys_ext.h"
103725 +#include "fm_ext.h"
103726 +#include "fm_muram_ext.h"
103727 +#include "fm_pcd_ext.h"
103728 +#include "fm_port_ext.h"
103729 +#include "fm_mac_ext.h"
103730 +#include "fm_rtc_ext.h"
103731 +
103732 +
103733 +/**************************************************************************//**
103734 + @Group FM_LnxKern_grp Frame Manager Linux wrapper API
103735 +
103736 + @Description FM API functions, definitions and enums.
103737 +
103738 + @{
103739 +*//***************************************************************************/
103740 +
103741 +/**************************************************************************//**
103742 + @Group FM_LnxKern_init_grp Initialization Unit
103743 +
103744 + @Description Initialization Unit
103745 +
103746 + Initialization Flow:
103747 + Initialization of the FM Module will be carried out by the Linux
103748 + kernel according to the following sequence:
103749 + a. Calling the initialization routine with no parameters.
103750 + b. The driver will register to the Device-Tree.
103751 + c. The Linux Device-Tree will initiate a call to the driver for
103752 + initialization.
103753 + d. The driver will read the appropriate information from the Device-Tree
103754 + e. [Optional] Calling the advance initialization routines to change
103755 + driver's defaults.
103756 + f. Initialization of the device will be automatically upon using it.
103757 +
103758 + @{
103759 +*//***************************************************************************/
103760 +
103761 +typedef struct t_WrpFmDevSettings
103762 +{
103763 + t_FmParams param;
103764 + t_SysObjectAdvConfigEntry *advConfig;
103765 +} t_WrpFmDevSettings;
103766 +
103767 +typedef struct t_WrpFmPcdDevSettings
103768 +{
103769 + t_FmPcdParams param;
103770 + t_SysObjectAdvConfigEntry *advConfig;
103771 +} t_WrpFmPcdDevSettings;
103772 +
103773 +typedef struct t_WrpFmPortDevSettings
103774 +{
103775 + bool frag_enabled;
103776 + t_FmPortParams param;
103777 + t_SysObjectAdvConfigEntry *advConfig;
103778 +} t_WrpFmPortDevSettings;
103779 +
103780 +typedef struct t_WrpFmMacDevSettings
103781 +{
103782 + t_FmMacParams param;
103783 + t_SysObjectAdvConfigEntry *advConfig;
103784 +} t_WrpFmMacDevSettings;
103785 +
103786 +
103787 +/**************************************************************************//**
103788 + @Function LNXWRP_FM_Init
103789 +
103790 + @Description Initialize the FM linux wrapper.
103791 +
103792 + @Return A handle (descriptor) of the newly created FM Linux wrapper
103793 + structure.
103794 +*//***************************************************************************/
103795 +t_Handle LNXWRP_FM_Init(void);
103796 +
103797 +/**************************************************************************//**
103798 + @Function LNXWRP_FM_Free
103799 +
103800 + @Description Free the FM linux wrapper.
103801 +
103802 + @Param[in] h_LnxWrpFm - A handle to the FM linux wrapper.
103803 +
103804 + @Return E_OK on success; Error code otherwise.
103805 +*//***************************************************************************/
103806 +t_Error LNXWRP_FM_Free(t_Handle h_LnxWrpFm);
103807 +
103808 +/**************************************************************************//**
103809 + @Function LNXWRP_FM_GetMacHandle
103810 +
103811 + @Description Get the FM-MAC LLD handle from the FM linux wrapper.
103812 +
103813 + @Param[in] h_LnxWrpFm - A handle to the FM linux wrapper.
103814 + @Param[in] fmId - Index of the FM device to get the MAC handle from.
103815 + @Param[in] macId - Index of the mac handle.
103816 +
103817 + @Return A handle of the LLD compressor.
103818 +*//***************************************************************************/
103819 +t_Handle LNXWRP_FM_GetMacHandle(t_Handle h_LnxWrpFm, uint8_t fmId, uint8_t macId);
103820 +
103821 +#ifdef CONFIG_FSL_SDK_FMAN_TEST
103822 +t_Handle LNXWRP_FM_TEST_Init(void);
103823 +t_Error LNXWRP_FM_TEST_Free(t_Handle h_FmTestLnxWrp);
103824 +#endif /* CONFIG_FSL_SDK_FMAN_TEST */
103825 +
103826 +/** @} */ /* end of FM_LnxKern_init_grp group */
103827 +
103828 +
103829 +/**************************************************************************//**
103830 + @Group FM_LnxKern_ctrl_grp Control Unit
103831 +
103832 + @Description Control Unit
103833 +
103834 + TODO
103835 + @{
103836 +*//***************************************************************************/
103837 +
103838 +#include "lnxwrp_fsl_fman.h"
103839 +
103840 +/** @} */ /* end of FM_LnxKern_ctrl_grp group */
103841 +/** @} */ /* end of FM_LnxKern_grp group */
103842 +
103843 +
103844 +#endif /* __LNXWRP_FM_EXT_H */
103845 --- /dev/null
103846 +++ b/drivers/net/ethernet/freescale/sdk_fman/src/inc/wrapper/lnxwrp_fsl_fman.h
103847 @@ -0,0 +1,921 @@
103848 +/*
103849 + * Copyright 2008-2012 Freescale Semiconductor Inc.
103850 + *
103851 + * Redistribution and use in source and binary forms, with or without
103852 + * modification, are permitted provided that the following conditions are met:
103853 + * * Redistributions of source code must retain the above copyright
103854 + * notice, this list of conditions and the following disclaimer.
103855 + * * Redistributions in binary form must reproduce the above copyright
103856 + * notice, this list of conditions and the following disclaimer in the
103857 + * documentation and/or other materials provided with the distribution.
103858 + * * Neither the name of Freescale Semiconductor nor the
103859 + * names of its contributors may be used to endorse or promote products
103860 + * derived from this software without specific prior written permission.
103861 + *
103862 + *
103863 + * ALTERNATIVELY, this software may be distributed under the terms of the
103864 + * GNU General Public License ("GPL") as published by the Free Software
103865 + * Foundation, either version 2 of that License or (at your option) any
103866 + * later version.
103867 + *
103868 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
103869 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
103870 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
103871 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
103872 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
103873 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
103874 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
103875 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
103876 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
103877 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
103878 + */
103879 +
103880 +/******************************************************************************
103881 + @File lnxwrp_fsl_fman.h
103882 +
103883 + @Description Linux internal kernel API
103884 +*//***************************************************************************/
103885 +
103886 +#ifndef __LNXWRP_FSL_FMAN_H
103887 +#define __LNXWRP_FSL_FMAN_H
103888 +
103889 +#include <linux/types.h>
103890 +#include <linux/device.h> /* struct device */
103891 +#include <linux/fsl_qman.h> /* struct qman_fq */
103892 +#include "dpaa_integration_ext.h"
103893 +#include "fm_port_ext.h"
103894 +#include "fm_mac_ext.h"
103895 +#include "fm_macsec_ext.h"
103896 +#include "fm_rtc_ext.h"
103897 +
103898 +/**************************************************************************//**
103899 + @Group FM_LnxKern_grp Frame Manager Linux wrapper API
103900 +
103901 + @Description FM API functions, definitions and enums.
103902 +
103903 + @{
103904 +*//***************************************************************************/
103905 +
103906 +/**************************************************************************//**
103907 + @Group FM_LnxKern_ctrl_grp Control Unit
103908 +
103909 + @Description Control Unit
103910 +
103911 + Internal Kernel Control Unit API
103912 + @{
103913 +*//***************************************************************************/
103914 +
103915 +/*****************************************************************************/
103916 +/* Internal Linux kernel routines */
103917 +/*****************************************************************************/
103918 +
103919 +/**************************************************************************//**
103920 + @Description MACSEC Exceptions wrapper
103921 +*//***************************************************************************/
103922 +typedef enum fm_macsec_exception {
103923 + SINGLE_BIT_ECC = e_FM_MACSEC_EX_SINGLE_BIT_ECC,
103924 + MULTI_BIT_ECC = e_FM_MACSEC_EX_MULTI_BIT_ECC
103925 +} fm_macsec_exception;
103926 +
103927 +/**************************************************************************//**
103928 + @Description Unknown sci frame treatment wrapper
103929 +*//***************************************************************************/
103930 +typedef enum fm_macsec_unknown_sci_frame_treatment {
103931 + SCI_DISCARD_BOTH = e_FM_MACSEC_UNKNOWN_SCI_FRAME_TREATMENT_DISCARD_BOTH,
103932 + SCI_DISCARD_UNCTRL_DELIVER_DISCARD_CTRL = \
103933 + e_FM_MACSEC_UNKNOWN_SCI_FRAME_TREATMENT_DISCARD_UNCONTROLLED_DELIVER_OR_DISCARD_CONTROLLED,
103934 + SCI_DELIVER_UNCTRL_DISCARD_CTRL = \
103935 + e_FM_MACSEC_UNKNOWN_SCI_FRAME_TREATMENT_DELIVER_UNCONTROLLED_DISCARD_CONTROLLED,
103936 + SCI_DELIVER_DISCARD_UNCTRL_DELIVER_DISCARD_CTRL = \
103937 + e_FM_MACSEC_UNKNOWN_SCI_FRAME_TREATMENT_DELIVER_OR_DISCARD_UNCONTROLLED_DELIVER_OR_DISCARD_CONTROLLED
103938 +} fm_macsec_unknown_sci_frame_treatment;
103939 +
103940 +/**************************************************************************//**
103941 + @Description Untag frame treatment wrapper
103942 +*//***************************************************************************/
103943 +typedef enum fm_macsec_untag_frame_treatment {
103944 + UNTAG_DELIVER_UNCTRL_DISCARD_CTRL = \
103945 + e_FM_MACSEC_UNTAG_FRAME_TREATMENT_DELIVER_UNCONTROLLED_DISCARD_CONTROLLED,
103946 + UNTAG_DISCARD_BOTH = e_FM_MACSEC_UNTAG_FRAME_TREATMENT_DISCARD_BOTH,
103947 + UNTAG_DISCARD_UNCTRL_DELIVER_CTRL_UNMODIFIED = \
103948 + e_FM_MACSEC_UNTAG_FRAME_TREATMENT_DISCARD_UNCONTROLLED_DELIVER_CONTROLLED_UNMODIFIED
103949 +} fm_macsec_untag_frame_treatment;
103950 +
103951 +/**************************************************************************//**
103952 +@Description MACSEC SECY Cipher Suite wrapper
103953 +*//***************************************************************************/
103954 +typedef enum fm_macsec_secy_cipher_suite {
103955 + SECY_GCM_AES_128 = e_FM_MACSEC_SECY_GCM_AES_128, /**< GCM-AES-128 */
103956 +#if (DPAA_VERSION >= 11)
103957 + SECY_GCM_AES_256 = e_FM_MACSEC_SECY_GCM_AES_256 /**< GCM-AES-256 */
103958 +#endif /* (DPAA_VERSION >= 11) */
103959 +} fm_macsec_secy_cipher_suite;
103960 +
103961 +/**************************************************************************//**
103962 + @Description MACSEC SECY Exceptions wrapper
103963 +*//***************************************************************************/
103964 +typedef enum fm_macsec_secy_exception {
103965 + SECY_EX_FRAME_DISCARDED = e_FM_MACSEC_SECY_EX_FRAME_DISCARDED
103966 +} fm_macsec_secy_exception;
103967 +
103968 +/**************************************************************************//**
103969 + @Description MACSEC SECY Events wrapper
103970 +*//***************************************************************************/
103971 +typedef enum fm_macsec_secy_event {
103972 + SECY_EV_NEXT_PN = e_FM_MACSEC_SECY_EV_NEXT_PN
103973 +} fm_macsec_secy_event;
103974 +
103975 +/**************************************************************************//**
103976 + @Description Valid frame behaviors wrapper
103977 +*//***************************************************************************/
103978 +typedef enum fm_macsec_valid_frame_behavior {
103979 + VALID_FRAME_BEHAVIOR_DISABLE = e_FM_MACSEC_VALID_FRAME_BEHAVIOR_DISABLE,
103980 + VALID_FRAME_BEHAVIOR_CHECK = e_FM_MACSEC_VALID_FRAME_BEHAVIOR_CHECK,
103981 + VALID_FRAME_BEHAVIOR_STRICT = e_FM_MACSEC_VALID_FRAME_BEHAVIOR_STRICT
103982 +} fm_macsec_valid_frame_behavior;
103983 +
103984 +/**************************************************************************//**
103985 + @Description SCI insertion modes wrapper
103986 +*//***************************************************************************/
103987 +typedef enum fm_macsec_sci_insertion_mode {
103988 + SCI_INSERTION_MODE_EXPLICIT_SECTAG = \
103989 + e_FM_MACSEC_SCI_INSERTION_MODE_EXPLICIT_SECTAG,
103990 + SCI_INSERTION_MODE_EXPLICIT_MAC_SA = \
103991 + e_FM_MACSEC_SCI_INSERTION_MODE_EXPLICIT_MAC_SA,
103992 + SCI_INSERTION_MODE_IMPLICT_PTP = e_FM_MACSEC_SCI_INSERTION_MODE_IMPLICT_PTP
103993 +} fm_macsec_sci_insertion_mode;
103994 +
103995 +typedef macsecSAKey_t macsec_sa_key_t;
103996 +typedef macsecSCI_t macsec_sci_t;
103997 +typedef macsecAN_t macsec_an_t;
103998 +typedef t_Handle handle_t;
103999 +
104000 +/**************************************************************************//**
104001 + @Function fm_macsec_secy_exception_callback wrapper
104002 + @Description Exceptions user callback routine, will be called upon an
104003 + exception passing the exception identification.
104004 + @Param[in] app_h A handle to an application layer object; This handle
104005 + will be passed by the driver upon calling this callback.
104006 + @Param[in] exception The exception.
104007 +*//***************************************************************************/
104008 +typedef void (fm_macsec_secy_exception_callback) (handle_t app_h,
104009 + fm_macsec_secy_exception exception);
104010 +
104011 +/**************************************************************************//**
104012 + @Function fm_macsec_secy_event_callback wrapper
104013 + @Description Events user callback routine, will be called upon an
104014 + event passing the event identification.
104015 + @Param[in] app_h A handle to an application layer object; This handle
104016 + will be passed by the driver upon calling this callback.
104017 + @Param[in] event The event.
104018 +*//***************************************************************************/
104019 +typedef void (fm_macsec_secy_event_callback) (handle_t app_h,
104020 + fm_macsec_secy_event event);
104021 +
104022 +/**************************************************************************//**
104023 + @Function fm_macsec_exception_callback wrapper
104024 + @Description Exceptions user callback routine, will be called upon an
104025 + exception passing the exception identification.
104026 + @Param[in] app_h A handle to an application layer object; This handle
104027 + will be passed by the driver upon calling this callback.
104028 + @Param[in] exception The exception.
104029 +*//***************************************************************************/
104030 +typedef void (fm_macsec_exception_callback) (handle_t app_h,
104031 + fm_macsec_exception exception);
104032 +
104033 +/**************************************************************************//**
104034 + @Description MACSEC SecY SC Params wrapper
104035 +*//***************************************************************************/
104036 +struct fm_macsec_secy_sc_params {
104037 + macsec_sci_t sci;
104038 + fm_macsec_secy_cipher_suite cipher_suite;
104039 +};
104040 +
104041 +/**************************************************************************//**
104042 + @Description FM MACSEC SecY config input wrapper
104043 +*//***************************************************************************/
104044 +struct fm_macsec_secy_params {
104045 + handle_t fm_macsec_h;
104046 + struct fm_macsec_secy_sc_params tx_sc_params;
104047 + uint32_t num_receive_channels;
104048 + fm_macsec_secy_exception_callback *exception_f;
104049 + fm_macsec_secy_event_callback *event_f;
104050 + handle_t app_h;
104051 +};
104052 +
104053 +/**************************************************************************//**
104054 + @Description FM MACSEC config input wrapper
104055 +*//***************************************************************************/
104056 +struct fm_macsec_params {
104057 + handle_t fm_h;
104058 + bool guest_mode;
104059 +
104060 + union {
104061 + struct {
104062 + uint8_t fm_mac_id;
104063 + } guest_params;
104064 +
104065 + struct {
104066 + uintptr_t base_addr;
104067 + handle_t fm_mac_h;
104068 + fm_macsec_exception_callback *exception_f;
104069 + handle_t app_h;
104070 + } non_guest_params;
104071 + };
104072 +
104073 +};
104074 +
104075 +/**************************************************************************//**
104076 + @Description FM device opaque structure used for type checking
104077 +*//***************************************************************************/
104078 +struct fm;
104079 +
104080 +/**************************************************************************//**
104081 + @Description FM MAC device opaque structure used for type checking
104082 +*//***************************************************************************/
104083 +struct fm_mac_dev;
104084 +
104085 +/**************************************************************************//**
104086 + @Description FM MACSEC device opaque structure used for type checking
104087 +*//***************************************************************************/
104088 +struct fm_macsec_dev;
104089 +struct fm_macsec_secy_dev;
104090 +
104091 +/**************************************************************************//**
104092 + @Description A structure ..,
104093 +*//***************************************************************************/
104094 +struct fm_port;
104095 +
104096 +typedef int (*alloc_pcd_fqids)(struct device *dev, uint32_t num,
104097 + uint8_t alignment, uint32_t *base_fqid);
104098 +
104099 +typedef int (*free_pcd_fqids)(struct device *dev, uint32_t base_fqid);
104100 +
104101 +struct fm_port_pcd_param {
104102 + alloc_pcd_fqids cba;
104103 + free_pcd_fqids cbf;
104104 + struct device *dev;
104105 +};
104106 +
104107 +/**************************************************************************//**
104108 + @Description A structure of information about each of the external
104109 + buffer pools used by the port,
104110 +*//***************************************************************************/
104111 +struct fm_port_pool_param {
104112 + uint8_t id; /**< External buffer pool id */
104113 + uint16_t size; /**< External buffer pool buffer size */
104114 +};
104115 +
104116 +/**************************************************************************//**
104117 + @Description structure for additional port parameters
104118 +*//***************************************************************************/
104119 +struct fm_port_params {
104120 + uint32_t errq; /**< Error Queue Id. */
104121 + uint32_t defq; /**< For Tx and HC - Default Confirmation queue,
104122 + 0 means no Tx conf for processed frames.
104123 + For Rx and OP - default Rx queue. */
104124 + uint8_t num_pools; /**< Number of pools use by this port */
104125 + struct fm_port_pool_param pool_param[FM_PORT_MAX_NUM_OF_EXT_POOLS];
104126 + /**< Parameters for each pool */
104127 + uint16_t priv_data_size; /**< Area that user may save for his own
104128 + need (E.g. save the SKB) */
104129 + bool parse_results; /**< Put the parser-results in the Rx/Tx buffer */
104130 + bool hash_results; /**< Put the hash-results in the Rx/Tx buffer */
104131 + bool time_stamp; /**< Put the time-stamp in the Rx/Tx buffer */
104132 + bool frag_enable; /**< Fragmentation support, for OP only */
104133 + uint16_t data_align; /**< value for selecting a data alignment (must be a power of 2);
104134 + if write optimization is used, must be >= 16. */
104135 + uint8_t manip_extra_space; /**< Maximum extra size needed (insertion-size minus removal-size);
104136 + Note that this field impacts the size of the buffer-prefix
104137 + (i.e. it pushes the data offset); */
104138 +};
104139 +
104140 +/**************************************************************************//**
104141 + @Function fm_bind
104142 +
104143 + @Description Bind to a specific FM device.
104144 +
104145 + @Param[in] fm_dev - the OF handle of the FM device.
104146 +
104147 + @Return A handle of the FM device.
104148 +
104149 + @Cautions Allowed only after the port was created.
104150 +*//***************************************************************************/
104151 +struct fm *fm_bind(struct device *fm_dev);
104152 +
104153 +/**************************************************************************//**
104154 + @Function fm_unbind
104155 +
104156 + @Description Un-bind from a specific FM device.
104157 +
104158 + @Param[in] fm - A handle of the FM device.
104159 +
104160 + @Cautions Allowed only after the port was created.
104161 +*//***************************************************************************/
104162 +void fm_unbind(struct fm *fm);
104163 +
104164 +void *fm_get_handle(struct fm *fm);
104165 +void *fm_get_rtc_handle(struct fm *fm);
104166 +struct resource *fm_get_mem_region(struct fm *fm);
104167 +
104168 +/**************************************************************************//**
104169 + @Function fm_port_bind
104170 +
104171 + @Description Bind to a specific FM-port device (may be Rx or Tx port).
104172 +
104173 + @Param[in] fm_port_dev - the OF handle of the FM port device.
104174 +
104175 + @Return A handle of the FM port device.
104176 +
104177 + @Cautions Allowed only after the port was created.
104178 +*//***************************************************************************/
104179 +struct fm_port *fm_port_bind(struct device *fm_port_dev);
104180 +
104181 +/**************************************************************************//**
104182 + @Function fm_port_unbind
104183 +
104184 + @Description Un-bind from a specific FM-port device (may be Rx or Tx port).
104185 +
104186 + @Param[in] port - A handle of the FM port device.
104187 +
104188 + @Cautions Allowed only after the port was created.
104189 +*//***************************************************************************/
104190 +void fm_port_unbind(struct fm_port *port);
104191 +
104192 +/**************************************************************************//**
104193 + @Function fm_set_rx_port_params
104194 +
104195 + @Description Configure parameters for a specific Rx FM-port device.
104196 +
104197 + @Param[in] port - A handle of the FM port device.
104198 + @Param[in] params - Rx port parameters
104199 +
104200 + @Cautions Allowed only after the port is binded.
104201 +*//***************************************************************************/
104202 +void fm_set_rx_port_params(struct fm_port *port,
104203 + struct fm_port_params *params);
104204 +
104205 +/**************************************************************************//**
104206 + @Function fm_port_pcd_bind
104207 +
104208 + @Description Bind as a listener on a port PCD.
104209 +
104210 + @Param[in] port - A handle of the FM port device.
104211 + @Param[in] params - PCD port parameters
104212 +
104213 + @Cautions Allowed only after the port is binded.
104214 +*//***************************************************************************/
104215 +void fm_port_pcd_bind (struct fm_port *port, struct fm_port_pcd_param *params);
104216 +
104217 +/**************************************************************************//**
104218 + @Function fm_port_get_buff_layout_ext_params
104219 +
104220 + @Description Get data_align and manip_extra_space from the device tree
104221 + chosen node if applied.
104222 + This function will only update these two parameters.
104223 + When this port has no such parameters in the device tree
104224 + values will be set to 0.
104225 +
104226 + @Param[in] port - A handle of the FM port device.
104227 + @Param[in] params - PCD port parameters
104228 +
104229 + @Cautions Allowed only after the port is binded.
104230 +*//***************************************************************************/
104231 +void fm_port_get_buff_layout_ext_params(struct fm_port *port, struct fm_port_params *params);
104232 +
104233 +/**************************************************************************//**
104234 + @Function fm_get_tx_port_channel
104235 +
104236 + @Description Get qman-channel number for this Tx port.
104237 +
104238 + @Param[in] port - A handle of the FM port device.
104239 +
104240 + @Return qman-channel number for this Tx port.
104241 +
104242 + @Cautions Allowed only after the port is binded.
104243 +*//***************************************************************************/
104244 +uint16_t fm_get_tx_port_channel(struct fm_port *port);
104245 +
104246 +/**************************************************************************//**
104247 + @Function fm_set_tx_port_params
104248 +
104249 + @Description Configure parameters for a specific Tx FM-port device
104250 +
104251 + @Param[in] port - A handle of the FM port device.
104252 + @Param[in] params - Tx port parameters
104253 +
104254 + @Cautions Allowed only after the port is binded.
104255 +*//***************************************************************************/
104256 +void fm_set_tx_port_params(struct fm_port *port, struct fm_port_params *params);
104257 +
104258 +
104259 +/**************************************************************************//**
104260 + @Function fm_mac_set_handle
104261 +
104262 + @Description Set mac handle
104263 +
104264 + @Param[in] h_lnx_wrp_fm_dev - A handle of the LnxWrp FM device.
104265 + @Param[in] h_fm_mac - A handle of the LnxWrp FM MAC device.
104266 + @Param[in] mac_id - MAC id.
104267 +*//***************************************************************************/
104268 +void fm_mac_set_handle(t_Handle h_lnx_wrp_fm_dev, t_Handle h_fm_mac,
104269 + int mac_id);
104270 +
104271 +/**************************************************************************//**
104272 + @Function fm_port_enable
104273 +
104274 + @Description Enable specific FM-port device (may be Rx or Tx port).
104275 +
104276 + @Param[in] port - A handle of the FM port device.
104277 +
104278 + @Cautions Allowed only after the port is initialized.
104279 +*//***************************************************************************/
104280 +int fm_port_enable(struct fm_port *port);
104281 +
104282 +/**************************************************************************//**
104283 + @Function fm_port_disable
104284 +
104285 + @Description Disable specific FM-port device (may be Rx or Tx port).
104286 +
104287 + @Param[in] port - A handle of the FM port device.
104288 +
104289 + @Cautions Allowed only after the port is initialized.
104290 +*//***************************************************************************/
104291 +int fm_port_disable(struct fm_port *port);
104292 +
104293 +void *fm_port_get_handle(const struct fm_port *port);
104294 +
104295 +u64 *fm_port_get_buffer_time_stamp(const struct fm_port *port,
104296 + const void *data);
104297 +
104298 +/**************************************************************************//**
104299 + @Function fm_port_get_base_address
104300 +
104301 + @Description Get base address of this port. Useful for accessing
104302 + port-specific registers (i.e., not common ones).
104303 +
104304 + @Param[in] port - A handle of the FM port device.
104305 +
104306 + @Param[out] base_addr - The port's base addr (virtual address).
104307 +*//***************************************************************************/
104308 +void fm_port_get_base_addr(const struct fm_port *port, uint64_t *base_addr);
104309 +
104310 +/**************************************************************************//**
104311 + @Function fm_mutex_lock
104312 +
104313 + @Description Lock function required before any FMD/LLD call.
104314 +*//***************************************************************************/
104315 +void fm_mutex_lock(void);
104316 +
104317 +/**************************************************************************//**
104318 + @Function fm_mutex_unlock
104319 +
104320 + @Description Unlock function required after any FMD/LLD call.
104321 +*//***************************************************************************/
104322 +void fm_mutex_unlock(void);
104323 +
104324 +/**************************************************************************//**
104325 + @Function fm_get_max_frm
104326 +
104327 + @Description Get the maximum frame size
104328 +*//***************************************************************************/
104329 +int fm_get_max_frm(void);
104330 +
104331 +/**************************************************************************//**
104332 + @Function fm_get_rx_extra_headroom
104333 +
104334 + @Description Get the extra headroom size
104335 +*//***************************************************************************/
104336 +int fm_get_rx_extra_headroom(void);
104337 +
104338 +/**************************************************************************//**
104339 +@Function fm_port_set_rate_limit
104340 +
104341 +@Description Configure Shaper parameter on FM-port device (Tx port).
104342 +
104343 +@Param[in] port - A handle of the FM port device.
104344 +@Param[in] max_burst_size - Value of maximum burst size allowed.
104345 +@Param[in] rate_limit - The required rate value.
104346 +
104347 +@Cautions Allowed only after the port is initialized.
104348 +*//***************************************************************************/
104349 +int fm_port_set_rate_limit(struct fm_port *port,
104350 + uint16_t max_burst_size,
104351 + uint32_t rate_limit);
104352 +/**************************************************************************//**
104353 +@Function fm_port_set_rate_limit
104354 +
104355 +@Description Delete Shaper configuration on FM-port device (Tx port).
104356 +
104357 +@Param[in] port - A handle of the FM port device.
104358 +
104359 +@Cautions Allowed only after the port is initialized.
104360 +*//***************************************************************************/
104361 +int fm_port_del_rate_limit(struct fm_port *port);
104362 +
104363 +struct auto_res_tables_sizes
104364 +{
104365 + uint16_t max_num_of_arp_entries;
104366 + uint16_t max_num_of_echo_ipv4_entries;
104367 + uint16_t max_num_of_ndp_entries;
104368 + uint16_t max_num_of_echo_ipv6_entries;
104369 + uint16_t max_num_of_snmp_ipv4_entries;
104370 + uint16_t max_num_of_snmp_ipv6_entries;
104371 + uint16_t max_num_of_snmp_oid_entries;
104372 + uint16_t max_num_of_snmp_char; /* total amount of character needed
104373 + for the snmp table */
104374 + uint16_t max_num_of_ip_prot_filtering;
104375 + uint16_t max_num_of_tcp_port_filtering;
104376 + uint16_t max_num_of_udp_port_filtering;
104377 +};
104378 +/* ARP */
104379 +struct auto_res_arp_entry
104380 +{
104381 + uint32_t ip_address;
104382 + uint8_t mac[6];
104383 + bool is_vlan;
104384 + uint16_t vid;
104385 +};
104386 +struct auto_res_arp_info
104387 +{
104388 + uint8_t table_size;
104389 + struct auto_res_arp_entry *auto_res_table;
104390 + bool enable_conflict_detection; /* when TRUE
104391 + Conflict Detection will be checked and wake the host if
104392 + needed */
104393 +};
104394 +
104395 +/* NDP */
104396 +struct auto_res_ndp_entry
104397 +{
104398 + uint32_t ip_address[4];
104399 + uint8_t mac[6];
104400 + bool is_vlan;
104401 + uint16_t vid;
104402 +};
104403 +struct auto_res_ndp_info
104404 +{
104405 + uint32_t multicast_group;
104406 + uint8_t table_size_assigned;
104407 + struct auto_res_ndp_entry *auto_res_table_assigned; /* This list
104408 + refer to solicitation IP addresses. Note that all IP adresses
104409 + must be from the same multicast group. This will be checked and
104410 + if not operation will fail. */
104411 + uint8_t table_size_tmp;
104412 + struct auto_res_ndp_entry *auto_res_table_tmp; /* This list
104413 + refer to temp IP addresses. Note that all temp IP adresses must
104414 + be from the same multicast group. This will be checked and if
104415 + not operation will fail. */
104416 +
104417 + bool enable_conflict_detection; /* when TRUE
104418 + Conflict Detection will be checked and wake the host if
104419 + needed */
104420 +};
104421 +
104422 +/* ICMP ECHO */
104423 +struct auto_res_echo_ipv4_info
104424 +{
104425 + uint8_t table_size;
104426 + struct auto_res_arp_entry *auto_res_table;
104427 +};
104428 +
104429 +struct auto_res_echo_ipv6_info
104430 +{
104431 + uint8_t table_size;
104432 + struct auto_res_ndp_entry *auto_res_table;
104433 +};
104434 +
104435 +/* SNMP */
104436 +struct auto_res_snmp_entry
104437 +{
104438 + uint16_t oidSize;
104439 + uint8_t *oidVal; /* only the oid string */
104440 + uint16_t resSize;
104441 + uint8_t *resVal; /* resVal will be the entire reply,
104442 + i.e. "Type|Length|Value" */
104443 +};
104444 +
104445 +/**************************************************************************//**
104446 + @Description Deep Sleep Auto Response SNMP IPv4 Addresses Table Entry
104447 + Refer to the FMan Controller spec for more details.
104448 +*//***************************************************************************/
104449 +struct auto_res_snmp_ipv4addr_tbl_entry
104450 +{
104451 + uint32_t ipv4addr; /*!< 32 bit IPv4 Address. */
104452 + bool is_vlan;
104453 + uint16_t vid; /*!< 12 bits VLAN ID. The 4 left-most bits should be cleared */
104454 + /*!< This field should be 0x0000 for an entry with no VLAN tag or a null VLAN ID. */
104455 +};
104456 +
104457 +/**************************************************************************//**
104458 + @Description Deep Sleep Auto Response SNMP IPv6 Addresses Table Entry
104459 + Refer to the FMan Controller spec for more details.
104460 +*//***************************************************************************/
104461 +struct auto_res_snmp_ipv6addr_tbl_entry
104462 +{
104463 + uint32_t ipv6Addr[4]; /*!< 4 * 32 bit IPv6 Address. */
104464 + bool isVlan;
104465 + uint16_t vid; /*!< 12 bits VLAN ID. The 4 left-most bits should be cleared */
104466 + /*!< This field should be 0x0000 for an entry with no VLAN tag or a null VLAN ID. */
104467 +};
104468 +
104469 +struct auto_res_snmp_info
104470 +{
104471 + uint16_t control; /**< Control bits [0-15]. */
104472 + uint16_t max_snmp_msg_length; /**< Maximal allowed SNMP message length. */
104473 + uint16_t num_ipv4_addresses; /**< Number of entries in IPv4 addresses table. */
104474 + uint16_t num_ipv6_addresses; /**< Number of entries in IPv6 addresses table. */
104475 + struct auto_res_snmp_ipv4addr_tbl_entry *ipv4addr_tbl; /**< Pointer to IPv4 addresses table. */
104476 + struct auto_res_snmp_ipv6addr_tbl_entry *ipv6addr_tbl; /**< Pointer to IPv6 addresses table. */
104477 + char *community_read_write_string;
104478 + char *community_read_only_string;
104479 + struct auto_res_snmp_entry *oid_table;
104480 + uint32_t oid_table_size;
104481 + uint32_t *statistics;
104482 +};
104483 +
104484 +/* Filtering */
104485 +struct auto_res_port_filtering_entry
104486 +{
104487 + uint16_t src_port;
104488 + uint16_t dst_port;
104489 + uint16_t src_port_mask;
104490 + uint16_t dst_port_mask;
104491 +};
104492 +struct auto_res_filtering_info
104493 +{
104494 + /* IP protocol filtering parameters */
104495 + uint8_t ip_prot_table_size;
104496 + uint8_t *ip_prot_table_ptr;
104497 + bool ip_prot_pass_on_hit; /* when TRUE, miss in the table will
104498 + cause the packet to be droped, hit will pass the packet to
104499 + UDP/TCP filters if needed and if not to the classification
104500 + tree. If the classification tree will pass the packet to a
104501 + queue it will cause a wake interupt. When FALSE it the other
104502 + way around. */
104503 + /* UDP port filtering parameters */
104504 + uint8_t udp_ports_table_size;
104505 + struct auto_res_port_filtering_entry *udp_ports_table_ptr;
104506 + bool udp_port_pass_on_hit; /* when TRUE, miss in the table will
104507 + cause the packet to be droped, hit will pass the packet to
104508 + classification tree. If the classification tree will pass the
104509 + packet to a queue it will cause a wake interupt. When FALSE it
104510 + the other way around. */
104511 + /* TCP port filtering parameters */
104512 + uint16_t tcp_flags_mask;
104513 + uint8_t tcp_ports_table_size;
104514 + struct auto_res_port_filtering_entry *tcp_ports_table_ptr;
104515 + bool tcp_port_pass_on_hit; /* when TRUE, miss in the table will
104516 + cause the packet to be droped, hit will pass the packet to
104517 + classification tree. If the classification tree will pass the
104518 + packet to a queue it will cause a wake interupt. When FALSE it
104519 + the other way around. */
104520 +};
104521 +
104522 +struct auto_res_port_params
104523 +{
104524 + t_Handle h_FmPortTx;
104525 + struct auto_res_arp_info *p_auto_res_arp_info;
104526 + struct auto_res_echo_ipv4_info *p_auto_res_echo_ipv4_info;
104527 + struct auto_res_ndp_info *p_auto_res_ndp_info;
104528 + struct auto_res_echo_ipv6_info *p_auto_res_echo_ipv6_info;
104529 + struct auto_res_snmp_info *p_auto_res_snmp_info;
104530 + struct auto_res_filtering_info *p_auto_res_filtering_info;
104531 +};
104532 +
104533 +struct auto_res_port_stats
104534 +{
104535 + uint32_t arp_ar_cnt;
104536 + uint32_t echo_icmpv4_ar_cnt;
104537 + uint32_t ndp_ar_cnt;
104538 + uint32_t echo_icmpv6_ar_cnt;
104539 +};
104540 +
104541 +int fm_port_config_autores_for_deepsleep_support(struct fm_port *port,
104542 + struct auto_res_tables_sizes *params);
104543 +
104544 +int fm_port_enter_autores_for_deepsleep(struct fm_port *port,
104545 + struct auto_res_port_params *params);
104546 +
104547 +void fm_port_exit_auto_res_for_deep_sleep(struct fm_port *port_rx,
104548 + struct fm_port *port_tx);
104549 +
104550 +bool fm_port_is_in_auto_res_mode(struct fm_port *port);
104551 +
104552 +struct auto_res_tables_sizes *fm_port_get_autores_maxsize(
104553 + struct fm_port *port);
104554 +
104555 +int fm_port_get_autores_stats(struct fm_port *port, struct auto_res_port_stats
104556 + *stats);
104557 +
104558 +int fm_port_resume(struct fm_port *port);
104559 +
104560 +int fm_port_suspend(struct fm_port *port);
104561 +
104562 +#ifdef CONFIG_FMAN_PFC
104563 +/**************************************************************************//**
104564 +@Function fm_port_set_pfc_priorities_mapping_to_qman_wq
104565 +
104566 +@Description Associate a QMan Work Queue with a PFC priority on this
104567 + FM-port device (Tx port).
104568 +
104569 +@Param[in] port - A handle of the FM port device.
104570 +
104571 +@Param[in] prio - The PFC priority.
104572 +
104573 +@Param[in] wq - The Work Queue associated with the PFC priority.
104574 +
104575 +@Cautions Allowed only after the port is initialized.
104576 +*//***************************************************************************/
104577 +int fm_port_set_pfc_priorities_mapping_to_qman_wq(struct fm_port *port,
104578 + uint8_t prio, uint8_t wq);
104579 +#endif
104580 +
104581 +/**************************************************************************//**
104582 +@Function fm_mac_set_exception
104583 +
104584 +@Description Set MAC exception state.
104585 +
104586 +@Param[in] fm_mac_dev - A handle of the FM MAC device.
104587 +@Param[in] exception - FM MAC exception type.
104588 +@Param[in] enable - new state.
104589 +
104590 +*//***************************************************************************/
104591 +int fm_mac_set_exception(struct fm_mac_dev *fm_mac_dev,
104592 + e_FmMacExceptions exception, bool enable);
104593 +
104594 +int fm_mac_free(struct fm_mac_dev *fm_mac_dev);
104595 +
104596 +struct fm_mac_dev *fm_mac_config(t_FmMacParams *params);
104597 +
104598 +int fm_mac_config_max_frame_length(struct fm_mac_dev *fm_mac_dev,
104599 + int len);
104600 +
104601 +int fm_mac_config_pad_and_crc(struct fm_mac_dev *fm_mac_dev, bool enable);
104602 +
104603 +int fm_mac_config_half_duplex(struct fm_mac_dev *fm_mac_dev, bool enable);
104604 +
104605 +int fm_mac_config_reset_on_init(struct fm_mac_dev *fm_mac_dev, bool enable);
104606 +
104607 +int fm_mac_init(struct fm_mac_dev *fm_mac_dev);
104608 +
104609 +int fm_mac_get_version(struct fm_mac_dev *fm_mac_dev, uint32_t *version);
104610 +
104611 +int fm_mac_enable(struct fm_mac_dev *fm_mac_dev);
104612 +
104613 +int fm_mac_disable(struct fm_mac_dev *fm_mac_dev);
104614 +
104615 +int fm_mac_resume(struct fm_mac_dev *fm_mac_dev);
104616 +
104617 +int fm_mac_set_promiscuous(struct fm_mac_dev *fm_mac_dev,
104618 + bool enable);
104619 +
104620 +int fm_mac_remove_hash_mac_addr(struct fm_mac_dev *fm_mac_dev,
104621 + t_EnetAddr *mac_addr);
104622 +
104623 +int fm_mac_add_hash_mac_addr(struct fm_mac_dev *fm_mac_dev,
104624 + t_EnetAddr *mac_addr);
104625 +
104626 +int fm_mac_modify_mac_addr(struct fm_mac_dev *fm_mac_dev,
104627 + uint8_t *addr);
104628 +
104629 +int fm_mac_adjust_link(struct fm_mac_dev *fm_mac_dev,
104630 + bool link, int speed, bool duplex);
104631 +
104632 +int fm_mac_enable_1588_time_stamp(struct fm_mac_dev *fm_mac_dev);
104633 +
104634 +int fm_mac_disable_1588_time_stamp(struct fm_mac_dev *fm_mac_dev);
104635 +
104636 +int fm_mac_set_rx_pause_frames(
104637 + struct fm_mac_dev *fm_mac_dev, bool en);
104638 +
104639 +int fm_mac_set_tx_pause_frames(struct fm_mac_dev *fm_mac_dev,
104640 + bool en);
104641 +
104642 +int fm_rtc_enable(struct fm *fm_dev);
104643 +
104644 +int fm_rtc_disable(struct fm *fm_dev);
104645 +
104646 +int fm_rtc_get_cnt(struct fm *fm_dev, uint64_t *ts);
104647 +
104648 +int fm_rtc_set_cnt(struct fm *fm_dev, uint64_t ts);
104649 +
104650 +int fm_rtc_get_drift(struct fm *fm_dev, uint32_t *drift);
104651 +
104652 +int fm_rtc_set_drift(struct fm *fm_dev, uint32_t drift);
104653 +
104654 +int fm_rtc_set_alarm(struct fm *fm_dev, uint32_t id,
104655 + uint64_t time);
104656 +
104657 +int fm_rtc_set_fiper(struct fm *fm_dev, uint32_t id,
104658 + uint64_t fiper);
104659 +
104660 +int fm_mac_set_wol(struct fm_port *port, struct fm_mac_dev *fm_mac_dev,
104661 + bool en);
104662 +
104663 +/**************************************************************************//**
104664 +@Function fm_macsec_set_exception
104665 +
104666 +@Description Set MACSEC exception state.
104667 +
104668 +@Param[in] fm_macsec_dev - A handle of the FM MACSEC device.
104669 +@Param[in] exception - FM MACSEC exception type.
104670 +@Param[in] enable - new state.
104671 +
104672 +*//***************************************************************************/
104673 +
104674 +int fm_macsec_set_exception(struct fm_macsec_dev *fm_macsec_dev,
104675 + fm_macsec_exception exception, bool enable);
104676 +int fm_macsec_free(struct fm_macsec_dev *fm_macsec_dev);
104677 +struct fm_macsec_dev *fm_macsec_config(struct fm_macsec_params *fm_params);
104678 +int fm_macsec_init(struct fm_macsec_dev *fm_macsec_dev);
104679 +int fm_macsec_config_unknown_sci_frame_treatment(struct fm_macsec_dev
104680 + *fm_macsec_dev,
104681 + fm_macsec_unknown_sci_frame_treatment treat_mode);
104682 +int fm_macsec_config_invalid_tags_frame_treatment(struct fm_macsec_dev *fm_macsec_dev,
104683 + bool deliver_uncontrolled);
104684 +int fm_macsec_config_kay_frame_treatment(struct fm_macsec_dev *fm_macsec_dev,
104685 + bool discard_uncontrolled);
104686 +int fm_macsec_config_untag_frame_treatment(struct fm_macsec_dev *fm_macsec_dev,
104687 + fm_macsec_untag_frame_treatment treat_mode);
104688 +int fm_macsec_config_pn_exhaustion_threshold(struct fm_macsec_dev *fm_macsec_dev,
104689 + uint32_t pnExhThr);
104690 +int fm_macsec_config_keys_unreadable(struct fm_macsec_dev *fm_macsec_dev);
104691 +int fm_macsec_config_sectag_without_sci(struct fm_macsec_dev *fm_macsec_dev);
104692 +int fm_macsec_config_exception(struct fm_macsec_dev *fm_macsec_dev,
104693 + fm_macsec_exception exception, bool enable);
104694 +int fm_macsec_get_revision(struct fm_macsec_dev *fm_macsec_dev,
104695 + int *macsec_revision);
104696 +int fm_macsec_enable(struct fm_macsec_dev *fm_macsec_dev);
104697 +int fm_macsec_disable(struct fm_macsec_dev *fm_macsec_dev);
104698 +
104699 +
104700 +int fm_macsec_secy_config_exception(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
104701 + fm_macsec_secy_exception exception,
104702 + bool enable);
104703 +int fm_macsec_secy_free(struct fm_macsec_secy_dev *fm_macsec_secy_dev);
104704 +struct fm_macsec_secy_dev *fm_macsec_secy_config(struct fm_macsec_secy_params *secy_params);
104705 +int fm_macsec_secy_init(struct fm_macsec_secy_dev *fm_macsec_secy_dev);
104706 +int fm_macsec_secy_config_sci_insertion_mode(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
104707 + fm_macsec_sci_insertion_mode sci_insertion_mode);
104708 +int fm_macsec_secy_config_protect_frames(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
104709 + bool protect_frames);
104710 +int fm_macsec_secy_config_replay_window(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
104711 + bool replay_protect, uint32_t replay_window);
104712 +int fm_macsec_secy_config_validation_mode(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
104713 + fm_macsec_valid_frame_behavior validate_frames);
104714 +int fm_macsec_secy_config_confidentiality(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
104715 + bool confidentiality_enable,
104716 + uint32_t confidentiality_offset);
104717 +int fm_macsec_secy_config_point_to_point(struct fm_macsec_secy_dev *fm_macsec_secy_dev);
104718 +int fm_macsec_secy_config_event(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
104719 + fm_macsec_secy_event event,
104720 + bool enable);
104721 +struct rx_sc_dev *fm_macsec_secy_create_rxsc(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
104722 + struct fm_macsec_secy_sc_params *params);
104723 +int fm_macsec_secy_delete_rxsc(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
104724 + struct rx_sc_dev *sc);
104725 +int fm_macsec_secy_create_rx_sa(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
104726 + struct rx_sc_dev *sc, macsec_an_t an,
104727 + uint32_t lowest_pn, macsec_sa_key_t key);
104728 +int fm_macsec_secy_delete_rx_sa(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
104729 + struct rx_sc_dev *sc, macsec_an_t an);
104730 +int fm_macsec_secy_rxsa_enable_receive(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
104731 + struct rx_sc_dev *sc,
104732 + macsec_an_t an);
104733 +int fm_macsec_secy_rxsa_disable_receive(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
104734 + struct rx_sc_dev *sc,
104735 + macsec_an_t an);
104736 +int fm_macsec_secy_rxsa_update_next_pn(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
104737 + struct rx_sc_dev *sc,
104738 + macsec_an_t an, uint32_t updt_next_pn);
104739 +int fm_macsec_secy_rxsa_update_lowest_pn(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
104740 + struct rx_sc_dev *sc,
104741 + macsec_an_t an, uint32_t updt_lowest_pn);
104742 +int fm_macsec_secy_rxsa_modify_key(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
104743 + struct rx_sc_dev *sc,
104744 + macsec_an_t an, macsec_sa_key_t key);
104745 +int fm_macsec_secy_create_tx_sa(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
104746 + macsec_an_t an, macsec_sa_key_t key);
104747 +int fm_macsec_secy_delete_tx_sa(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
104748 + macsec_an_t an);
104749 +int fm_macsec_secy_txsa_modify_key(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
104750 + macsec_an_t next_active_an,
104751 + macsec_sa_key_t key);
104752 +int fm_macsec_secy_txsa_set_active(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
104753 + macsec_an_t an);
104754 +int fm_macsec_secy_txsa_get_active(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
104755 + macsec_an_t *p_an);
104756 +int fm_macsec_secy_get_rxsc_phys_id(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
104757 + struct rx_sc_dev *sc, uint32_t *sc_phys_id);
104758 +int fm_macsec_secy_get_txsc_phys_id(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
104759 + uint32_t *sc_phys_id);
104760 +
104761 +/** @} */ /* end of FM_LnxKern_ctrl_grp group */
104762 +/** @} */ /* end of FM_LnxKern_grp group */
104763 +
104764 +/* default values for initializing PTP 1588 timer clock */
104765 +#define DPA_PTP_NOMINAL_FREQ_PERIOD_SHIFT 2 /* power of 2 for better performance */
104766 +#define DPA_PTP_NOMINAL_FREQ_PERIOD_NS (1 << DPA_PTP_NOMINAL_FREQ_PERIOD_SHIFT) /* 4ns,250MHz */
104767 +
104768 +#endif /* __LNXWRP_FSL_FMAN_H */
104769 --- /dev/null
104770 +++ b/drivers/net/ethernet/freescale/sdk_fman/src/inc/xx/xx.h
104771 @@ -0,0 +1,50 @@
104772 +/*
104773 + * Copyright 2008-2012 Freescale Semiconductor Inc.
104774 + *
104775 + * Redistribution and use in source and binary forms, with or without
104776 + * modification, are permitted provided that the following conditions are met:
104777 + * * Redistributions of source code must retain the above copyright
104778 + * notice, this list of conditions and the following disclaimer.
104779 + * * Redistributions in binary form must reproduce the above copyright
104780 + * notice, this list of conditions and the following disclaimer in the
104781 + * documentation and/or other materials provided with the distribution.
104782 + * * Neither the name of Freescale Semiconductor nor the
104783 + * names of its contributors may be used to endorse or promote products
104784 + * derived from this software without specific prior written permission.
104785 + *
104786 + *
104787 + * ALTERNATIVELY, this software may be distributed under the terms of the
104788 + * GNU General Public License ("GPL") as published by the Free Software
104789 + * Foundation, either version 2 of that License or (at your option) any
104790 + * later version.
104791 + *
104792 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
104793 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
104794 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
104795 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
104796 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
104797 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
104798 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
104799 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
104800 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
104801 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
104802 + */
104803 +
104804 +#ifndef __XX_H
104805 +#define __XX_H
104806 +
104807 +#include "xx_ext.h"
104808 +
104809 +void * xx_Malloc(uint32_t n);
104810 +void xx_Free(void *p);
104811 +
104812 +void *xx_MallocSmart(uint32_t size, int memPartitionId, uint32_t align);
104813 +void xx_FreeSmart(void *p);
104814 +
104815 +/* never used: */
104816 +#define GetDeviceName(irq) ((char *)NULL)
104817 +
104818 +int GetDeviceIrqNum(int irq);
104819 +
104820 +
104821 +#endif /* __XX_H */
104822 --- /dev/null
104823 +++ b/drivers/net/ethernet/freescale/sdk_fman/src/system/Makefile
104824 @@ -0,0 +1,10 @@
104825 +#
104826 +# Makefile for the Freescale Ethernet controllers
104827 +#
104828 +ccflags-y += -DVERSION=\"\"
104829 +#
104830 +#Include netcomm SW specific definitions
104831 +include $(srctree)/drivers/net/ethernet/freescale/sdk_fman/ncsw_config.mk
104832 +#
104833 +
104834 +obj-y += sys_io.o
104835 --- /dev/null
104836 +++ b/drivers/net/ethernet/freescale/sdk_fman/src/system/sys_io.c
104837 @@ -0,0 +1,171 @@
104838 +/*
104839 + * Copyright 2008-2012 Freescale Semiconductor Inc.
104840 + *
104841 + * Redistribution and use in source and binary forms, with or without
104842 + * modification, are permitted provided that the following conditions are met:
104843 + * * Redistributions of source code must retain the above copyright
104844 + * notice, this list of conditions and the following disclaimer.
104845 + * * Redistributions in binary form must reproduce the above copyright
104846 + * notice, this list of conditions and the following disclaimer in the
104847 + * documentation and/or other materials provided with the distribution.
104848 + * * Neither the name of Freescale Semiconductor nor the
104849 + * names of its contributors may be used to endorse or promote products
104850 + * derived from this software without specific prior written permission.
104851 + *
104852 + *
104853 + * ALTERNATIVELY, this software may be distributed under the terms of the
104854 + * GNU General Public License ("GPL") as published by the Free Software
104855 + * Foundation, either version 2 of that License or (at your option) any
104856 + * later version.
104857 + *
104858 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
104859 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
104860 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
104861 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
104862 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
104863 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
104864 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
104865 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
104866 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
104867 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
104868 + */
104869 +
104870 +#include <linux/version.h>
104871 +
104872 +#if defined(CONFIG_MODVERSIONS) && !defined(MODVERSIONS)
104873 +#define MODVERSIONS
104874 +#endif
104875 +#ifdef MODVERSIONS
104876 +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
104877 +#include <linux/modversions.h>
104878 +#else
104879 +#include <config/modversions.h>
104880 +#endif /* LINUX_VERSION_CODE */
104881 +#endif /* MODVERSIONS */
104882 +
104883 +#include <linux/module.h>
104884 +#include <linux/kernel.h>
104885 +
104886 +#include <asm/io.h>
104887 +
104888 +#include "std_ext.h"
104889 +#include "error_ext.h"
104890 +#include "string_ext.h"
104891 +#include "list_ext.h"
104892 +#include "sys_io_ext.h"
104893 +
104894 +
104895 +#define __ERR_MODULE__ MODULE_UNKNOWN
104896 +
104897 +
104898 +typedef struct {
104899 + uint64_t virtAddr;
104900 + uint64_t physAddr;
104901 + uint32_t size;
104902 + t_List node;
104903 +} t_IoMap;
104904 +#define IOMAP_OBJECT(ptr) LIST_OBJECT(ptr, t_IoMap, node)
104905 +
104906 +LIST(mapsList);
104907 +
104908 +
104909 +static void EnqueueIoMap(t_IoMap *p_IoMap)
104910 +{
104911 + uint32_t intFlags;
104912 +
104913 + intFlags = XX_DisableAllIntr();
104914 + LIST_AddToTail(&p_IoMap->node, &mapsList);
104915 + XX_RestoreAllIntr(intFlags);
104916 +}
104917 +
104918 +static t_IoMap * FindIoMapByVirtAddr(uint64_t addr)
104919 +{
104920 + t_IoMap *p_IoMap;
104921 + t_List *p_Pos;
104922 +
104923 + LIST_FOR_EACH(p_Pos, &mapsList)
104924 + {
104925 + p_IoMap = IOMAP_OBJECT(p_Pos);
104926 + if ((addr >= p_IoMap->virtAddr) && (addr < p_IoMap->virtAddr+p_IoMap->size))
104927 + return p_IoMap;
104928 + }
104929 +
104930 + return NULL;
104931 +}
104932 +
104933 +static t_IoMap * FindIoMapByPhysAddr(uint64_t addr)
104934 +{
104935 + t_IoMap *p_IoMap;
104936 + t_List *p_Pos;
104937 +
104938 + LIST_FOR_EACH(p_Pos, &mapsList)
104939 + {
104940 + p_IoMap = IOMAP_OBJECT(p_Pos);
104941 + if ((addr >= p_IoMap->physAddr) && (addr < p_IoMap->physAddr+p_IoMap->size))
104942 + return p_IoMap;
104943 + }
104944 +
104945 + return NULL;
104946 +}
104947 +
104948 +t_Error SYS_RegisterIoMap (uint64_t virtAddr, uint64_t physAddr, uint32_t size)
104949 +{
104950 + t_IoMap *p_IoMap;
104951 +
104952 + p_IoMap = (t_IoMap*)XX_Malloc(sizeof(t_IoMap));
104953 + if (!p_IoMap)
104954 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("message handler object!!!"));
104955 + memset(p_IoMap, 0, sizeof(t_IoMap));
104956 +
104957 + p_IoMap->virtAddr = virtAddr;
104958 + p_IoMap->physAddr = physAddr;
104959 + p_IoMap->size = size;
104960 +
104961 + INIT_LIST(&p_IoMap->node);
104962 + EnqueueIoMap(p_IoMap);
104963 +
104964 + return E_OK;
104965 +}
104966 +
104967 +t_Error SYS_UnregisterIoMap (uint64_t virtAddr)
104968 +{
104969 + t_IoMap *p_IoMap = FindIoMapByVirtAddr(virtAddr);
104970 + if (!p_IoMap)
104971 + RETURN_ERROR(MINOR, E_NO_DEVICE, ("message handler not found in list!!!"));
104972 +
104973 + LIST_Del(&p_IoMap->node);
104974 + XX_Free(p_IoMap);
104975 +
104976 + return E_OK;
104977 +}
104978 +
104979 +uint64_t SYS_PhysToVirt(uint64_t addr)
104980 +{
104981 + t_IoMap *p_IoMap = FindIoMapByPhysAddr(addr);
104982 + if (p_IoMap)
104983 + {
104984 + /* This is optimization - put the latest in the list-head - like a cache */
104985 + if (mapsList.p_Next != &p_IoMap->node)
104986 + {
104987 + uint32_t intFlags = XX_DisableAllIntr();
104988 + LIST_DelAndInit(&p_IoMap->node);
104989 + LIST_Add(&p_IoMap->node, &mapsList);
104990 + XX_RestoreAllIntr(intFlags);
104991 + }
104992 + return (uint64_t)(addr - p_IoMap->physAddr + p_IoMap->virtAddr);
104993 + }
104994 + return PTR_TO_UINT(phys_to_virt((unsigned long)addr));
104995 +}
104996 +
104997 +uint64_t SYS_VirtToPhys(uint64_t addr)
104998 +{
104999 + t_IoMap *p_IoMap;
105000 +
105001 + if (addr == 0)
105002 + return 0;
105003 +
105004 + p_IoMap = FindIoMapByVirtAddr(addr);
105005 + if (p_IoMap)
105006 + return (uint64_t)(addr - p_IoMap->virtAddr + p_IoMap->physAddr);
105007 + return (uint64_t)virt_to_phys(UINT_TO_PTR(addr));
105008 +}
105009 --- /dev/null
105010 +++ b/drivers/net/ethernet/freescale/sdk_fman/src/wrapper/Makefile
105011 @@ -0,0 +1,19 @@
105012 +#
105013 +# Makefile for the Freescale Ethernet controllers
105014 +#
105015 +ccflags-y += -DVERSION=\"\"
105016 +#
105017 +#Include netcomm SW specific definitions
105018 +include $(srctree)/drivers/net/ethernet/freescale/sdk_fman/ncsw_config.mk
105019 +
105020 +NCSW_FM_INC = $(srctree)/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/inc
105021 +
105022 +ccflags-y += -I$(NCSW_FM_INC)
105023 +ccflags-y += -I$(NET_DPA)
105024 +
105025 +obj-y += fsl-ncsw-PFM.o
105026 +obj-$(CONFIG_FSL_SDK_FMAN_TEST) += fman_test.o
105027 +
105028 +fsl-ncsw-PFM-objs := lnxwrp_fm.o lnxwrp_fm_port.o lnxwrp_ioctls_fm.o \
105029 + lnxwrp_sysfs.o lnxwrp_sysfs_fm.o lnxwrp_sysfs_fm_port.o
105030 +obj-$(CONFIG_COMPAT) += lnxwrp_ioctls_fm_compat.o
105031 --- /dev/null
105032 +++ b/drivers/net/ethernet/freescale/sdk_fman/src/wrapper/fman_test.c
105033 @@ -0,0 +1,1665 @@
105034 +/* Copyright (c) 2008-2011 Freescale Semiconductor, Inc.
105035 + * All rights reserved.
105036 + *
105037 + * Redistribution and use in source and binary forms, with or without
105038 + * modification, are permitted provided that the following conditions are met:
105039 + * * Redistributions of source code must retain the above copyright
105040 + * notice, this list of conditions and the following disclaimer.
105041 + * * Redistributions in binary form must reproduce the above copyright
105042 + * notice, this list of conditions and the following disclaimer in the
105043 + * documentation and/or other materials provided with the distribution.
105044 + * * Neither the name of Freescale Semiconductor nor the
105045 + * names of its contributors may be used to endorse or promote products
105046 + * derived from this software without specific prior written permission.
105047 + *
105048 + *
105049 + * ALTERNATIVELY, this software may be distributed under the terms of the
105050 + * GNU General Public License ("GPL") as published by the Free Software
105051 + * Foundation, either version 2 of that License or (at your option) any
105052 + * later version.
105053 + *
105054 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
105055 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
105056 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
105057 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
105058 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
105059 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
105060 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
105061 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
105062 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
105063 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
105064 + */
105065 +
105066 +/*
105067 + @File fman_test.c
105068 + @Authors Pistirica Sorin Andrei
105069 + @Description FM Linux test environment
105070 +*/
105071 +
105072 +#include <linux/kernel.h>
105073 +#include <linux/module.h>
105074 +#include <linux/fs.h>
105075 +#include <linux/cdev.h>
105076 +#include <linux/device.h>
105077 +#include <linux/io.h>
105078 +#include <linux/ioport.h>
105079 +#include <linux/of_platform.h>
105080 +#include <linux/ip.h>
105081 +#include <linux/compat.h>
105082 +#include <linux/uaccess.h>
105083 +#include <linux/errno.h>
105084 +#include <linux/netdevice.h>
105085 +#include <linux/spinlock.h>
105086 +#include <linux/types.h>
105087 +#include <linux/fsl_qman.h>
105088 +#include <linux/fsl_bman.h>
105089 +
105090 +/* private headers */
105091 +#include "fm_ext.h"
105092 +#include "lnxwrp_fsl_fman.h"
105093 +#include "fm_port_ext.h"
105094 +#if (DPAA_VERSION == 11)
105095 +#include "../../Peripherals/FM/MAC/memac.h"
105096 +#endif
105097 +#include "fm_test_ioctls.h"
105098 +#include "fsl_fman_test.h"
105099 +
105100 +#include "dpaa_eth.h"
105101 +#include "dpaa_eth_common.h"
105102 +
105103 +#define FMT_FRM_WATERMARK 0xdeadbeefdeadbeeaLL
105104 +
105105 +struct fmt_frame_s {
105106 + ioc_fmt_buff_desc_t buff;
105107 + struct list_head list;
105108 +};
105109 +
105110 +struct fmt_fqs_s {
105111 + struct qman_fq fq_base;
105112 + bool init;
105113 + struct fmt_port_s *fmt_port_priv;
105114 +};
105115 +
105116 +struct fmt_port_pcd_s {
105117 + int num_queues;
105118 + struct fmt_fqs_s *fmt_pcd_fqs;
105119 + uint32_t fqid_base;
105120 +};
105121 +
105122 +/* char dev structure: fm test port */
105123 +struct fmt_port_s {
105124 + bool valid;
105125 + uint8_t id;
105126 + ioc_fmt_port_type port_type;
105127 + ioc_diag_mode diag;
105128 + bool compat_test_type;
105129 +
105130 + /* fm ports */
105131 + /* ! for oh ports p_tx_fm_port_dev == p_rx_fm_port_dev &&
105132 + * p_tx_port == p_rx_port */
105133 + /* t_LnxWrpFmPortDev */
105134 + struct fm_port *p_tx_port;
105135 + /* t_LnxWrpFmPortDev->h_Dev: t_FmPort */
105136 + void *p_tx_fm_port_dev;
105137 + /* t_LnxWrpFmPortDev */
105138 + struct fm_port *p_rx_port;
105139 + /* t_LnxWrpFmPortDev->h_Dev: t_FmPort */
105140 + void *p_rx_fm_port_dev;
105141 +
105142 + void *p_mac_dev;
105143 + uint64_t fm_phys_base_addr;
105144 +
105145 + /* read/write queue manipulation */
105146 + spinlock_t rx_q_lock;
105147 + struct list_head rx_q;
105148 +
105149 + /* tx queuee for injecting traffic */
105150 + int num_of_tx_fqs;
105151 + struct fmt_fqs_s p_tx_fqs[FMAN_TEST_MAX_TX_FQS];
105152 +
105153 + /* pcd private queues manipulation */
105154 + struct fmt_port_pcd_s fmt_port_pcd;
105155 +
105156 + /* debugging stuff */
105157 +
105158 +#if defined(FMT_K_DBG) || defined(FMT_K_DBG_RUNTIME)
105159 + atomic_t enqueue_to_qman_frm;
105160 + atomic_t enqueue_to_rxq;
105161 + atomic_t dequeue_from_rxq;
105162 + atomic_t not_enqueue_to_rxq_wrong_frm;
105163 +#endif
105164 +
105165 +};
105166 +
105167 +/* The devices. */
105168 +struct fmt_s {
105169 + int major;
105170 + struct fmt_port_s ports[IOC_FMT_MAX_NUM_OF_PORTS];
105171 + struct class *fmt_class;
105172 +};
105173 +
105174 +/* fm test structure */
105175 +static struct fmt_s fm_test;
105176 +
105177 +#if (DPAA_VERSION == 11)
105178 +struct mac_priv_s {
105179 + t_Handle mac;
105180 +};
105181 +#endif
105182 +
105183 +#define DTSEC_BASE_ADDR 0x000e0000
105184 +#define DTSEC_MEM_RANGE 0x00002000
105185 +#define MAC_1G_MACCFG1 0x00000100
105186 +#define MAC_1G_LOOP_MASK 0x00000100
105187 +static int set_1gmac_loopback(
105188 + struct fmt_port_s *fmt_port,
105189 + bool en)
105190 +{
105191 +#if (DPAA_VERSION <= 10)
105192 + uint32_t dtsec_idx = fmt_port->id; /* dtsec for which port */
105193 + uint32_t dtsec_idx_off = dtsec_idx * DTSEC_MEM_RANGE;
105194 + phys_addr_t maccfg1_hw;
105195 + void *maccfg1_map;
105196 + uint32_t maccfg1_val;
105197 +
105198 + /* compute the maccfg1 register address */
105199 + maccfg1_hw = fmt_port->fm_phys_base_addr +
105200 + (phys_addr_t)(DTSEC_BASE_ADDR +
105201 + dtsec_idx_off +
105202 + MAC_1G_MACCFG1);
105203 +
105204 + /* map register */
105205 + maccfg1_map = ioremap(maccfg1_hw, sizeof(u32));
105206 +
105207 + /* set register */
105208 + maccfg1_val = in_be32(maccfg1_map);
105209 + if (en)
105210 + maccfg1_val |= MAC_1G_LOOP_MASK;
105211 + else
105212 + maccfg1_val &= ~MAC_1G_LOOP_MASK;
105213 + out_be32(maccfg1_map, maccfg1_val);
105214 +
105215 + /* unmap register */
105216 + iounmap(maccfg1_map);
105217 +#else
105218 + struct mac_device *mac_dev;
105219 + struct mac_priv_s *priv;
105220 + t_Memac *p_memac;
105221 +
105222 + if (!fmt_port)
105223 + return -EINVAL;
105224 +
105225 + mac_dev = (struct mac_device *)fmt_port->p_mac_dev;
105226 +
105227 + if (!mac_dev)
105228 + return -EINVAL;
105229 +
105230 + priv = macdev_priv(mac_dev);
105231 +
105232 + if (!priv)
105233 + return -EINVAL;
105234 +
105235 + p_memac = priv->mac;
105236 +
105237 + if (!p_memac)
105238 + return -EINVAL;
105239 +
105240 + memac_set_loopback(p_memac->p_MemMap, en);
105241 +#endif
105242 + return 0;
105243 +}
105244 +
105245 +/* TODO: re-write this function */
105246 +static int set_10gmac_int_loopback(
105247 + struct fmt_port_s *fmt_port,
105248 + bool en)
105249 +{
105250 +#ifndef FM_10G_MAC_NO_CTRL_LOOPBACK
105251 +#define FM_10GMAC0_OFFSET 0x000f0000
105252 +#define FM_10GMAC_CMD_CONF_CTRL_OFFSET 0x8
105253 +#define CMD_CFG_LOOPBACK_EN 0x00000400
105254 +
105255 + uint64_t base_addr, reg_addr;
105256 + uint32_t tmp_val;
105257 +
105258 + base_addr = fmt_port->fm_phys_base_addr + (FM_10GMAC0_OFFSET +
105259 + ((fmt_port->id-FM_MAX_NUM_OF_1G_RX_PORTS)*0x2000));
105260 +
105261 + base_addr = PTR_TO_UINT(ioremap(base_addr, 0x1000));
105262 +
105263 + reg_addr = base_addr + FM_10GMAC_CMD_CONF_CTRL_OFFSET;
105264 + tmp_val = GET_UINT32(*((uint32_t *)UINT_TO_PTR(reg_addr)));
105265 + if (en)
105266 + tmp_val |= CMD_CFG_LOOPBACK_EN;
105267 + else
105268 + tmp_val &= ~CMD_CFG_LOOPBACK_EN;
105269 + WRITE_UINT32(*((uint32_t *)UINT_TO_PTR(reg_addr)), tmp_val);
105270 +
105271 + iounmap(UINT_TO_PTR(base_addr));
105272 +
105273 + return 0;
105274 +#else
105275 + _fmt_err("TGEC don't have internal-loopback.\n");
105276 + return -EPERM;
105277 +#endif
105278 +}
105279 +
105280 +static int set_mac_int_loopback(struct fmt_port_s *fmt_port, bool en)
105281 +{
105282 + int _err = 0;
105283 +
105284 + switch (fmt_port->port_type) {
105285 +
105286 + case e_IOC_FMT_PORT_T_RXTX:
105287 + /* 1G port */
105288 + if (fmt_port->id < FM_MAX_NUM_OF_1G_RX_PORTS)
105289 + _err = set_1gmac_loopback(fmt_port, en);
105290 + /* 10g port */
105291 + else if ((fmt_port->id >= FM_MAX_NUM_OF_1G_RX_PORTS) &&
105292 + (fmt_port->id < FM_MAX_NUM_OF_1G_RX_PORTS +
105293 + FM_MAX_NUM_OF_10G_RX_PORTS)) {
105294 +
105295 + _err = set_10gmac_int_loopback(fmt_port, en);
105296 + } else
105297 + _err = -EINVAL;
105298 + break;
105299 + /* op port does not have MAC (loopback mode) */
105300 + case e_IOC_FMT_PORT_T_OP:
105301 +
105302 + _err = 0;
105303 + break;
105304 + default:
105305 +
105306 + _err = -EPERM;
105307 + break;
105308 + }
105309 +
105310 + return _err;
105311 +}
105312 +
105313 +static void enqueue_fmt_frame(
105314 + struct fmt_port_s *fmt_port,
105315 + struct fmt_frame_s *p_fmt_frame)
105316 +{
105317 + spinlock_t *rx_q_lock = NULL;
105318 +
105319 + rx_q_lock = &fmt_port->rx_q_lock;
105320 +
105321 + spin_lock(rx_q_lock);
105322 + list_add_tail(&p_fmt_frame->list, &fmt_port->rx_q);
105323 + spin_unlock(rx_q_lock);
105324 +
105325 +#if defined(FMT_K_DBG) || defined(FMT_K_DBG_RUNTIME)
105326 + atomic_inc(&fmt_port->enqueue_to_rxq);
105327 +#endif
105328 +}
105329 +
105330 +static struct fmt_frame_s *dequeue_fmt_frame(
105331 + struct fmt_port_s *fmt_port)
105332 +{
105333 + struct fmt_frame_s *p_fmt_frame = NULL;
105334 + spinlock_t *rx_q_lock = NULL;
105335 +
105336 + rx_q_lock = &fmt_port->rx_q_lock;
105337 +
105338 + spin_lock(rx_q_lock);
105339 +
105340 +#define list_last_entry(ptr, type, member) list_entry((ptr)->prev, type, member)
105341 +
105342 + if (!list_empty(&fmt_port->rx_q)) {
105343 + p_fmt_frame = list_last_entry(&fmt_port->rx_q,
105344 + struct fmt_frame_s,
105345 + list);
105346 + list_del(&p_fmt_frame->list);
105347 +
105348 +#if defined(FMT_K_DBG) || defined(FMT_K_DBG_RUNTIME)
105349 + atomic_inc(&fmt_port->dequeue_from_rxq);
105350 +#endif
105351 + }
105352 +
105353 + spin_unlock(rx_q_lock);
105354 +
105355 + return p_fmt_frame;
105356 +}
105357 +
105358 +/* eth-dev -to- fmt port association */
105359 +struct fmt_port_s *match_dpa_to_fmt_port(
105360 + struct dpa_priv_s *dpa_priv) {
105361 + struct mac_device *mac_dev = dpa_priv->mac_dev;
105362 + struct fm_port *fm_port = (struct fm_port *) mac_dev;
105363 + struct fmt_port_s *fmt_port = NULL;
105364 + int i;
105365 +
105366 + _fmt_dbgr("calling...\n");
105367 +
105368 + /* find the FM-test-port object */
105369 + for (i = 0; i < IOC_FMT_MAX_NUM_OF_PORTS; i++)
105370 + if ((fm_test.ports[i].p_mac_dev &&
105371 + mac_dev == fm_test.ports[i].p_mac_dev) ||
105372 + fm_port == fm_test.ports[i].p_tx_port) {
105373 +
105374 + fmt_port = &fm_test.ports[i];
105375 + break;
105376 + }
105377 +
105378 + _fmt_dbgr("called\n");
105379 + return fmt_port;
105380 +}
105381 +
105382 +void dump_frame(
105383 + uint8_t *buffer,
105384 + uint32_t size)
105385 +{
105386 +#if defined(FMT_K_DBG) || defined(FMT_K_DBG_RUNTIME)
105387 + unsigned int i;
105388 +
105389 + for (i = 0; i < size; i++) {
105390 + if (i%16 == 0)
105391 + printk(KERN_DEBUG "\n");
105392 + printk(KERN_DEBUG "%2x ", *(buffer+i));
105393 + }
105394 +#endif
105395 + return;
105396 +}
105397 +
105398 +bool test_and_steal_frame(struct fmt_port_s *fmt_port,
105399 + uint32_t fqid,
105400 + uint8_t *buffer,
105401 + uint32_t size)
105402 +{
105403 + struct fmt_frame_s *p_fmt_frame = NULL;
105404 + bool test_and_steal_frame_frame;
105405 + uint32_t data_offset;
105406 + uint32_t i;
105407 +
105408 + _fmt_dbgr("calling...\n");
105409 +
105410 + if (!fmt_port || !fmt_port->p_rx_fm_port_dev)
105411 + return false;
105412 +
105413 + /* check watermark */
105414 + test_and_steal_frame_frame = false;
105415 + for (i = 0; i < size; i++) {
105416 + uint64_t temp = *((uint64_t *)(buffer + i));
105417 +
105418 + if (temp == (uint64_t) FMT_FRM_WATERMARK) {
105419 + _fmt_dbgr("watermark found!\n");
105420 + test_and_steal_frame_frame = true;
105421 + break;
105422 + }
105423 + }
105424 +
105425 + if (!test_and_steal_frame_frame) {
105426 +#if defined(FMT_K_DBG) || defined(FMT_K_DBG_RUNTIME)
105427 + atomic_inc(&fmt_port->not_enqueue_to_rxq_wrong_frm);
105428 +#endif
105429 + _fmt_dbgr("NOT watermark found!\n");
105430 + return false;
105431 + }
105432 +
105433 + /* do not enqueue the tx conf/err frames */
105434 + if ((fqid == FMT_TX_CONF_Q) || (fqid == FMT_TX_ERR_Q))
105435 + goto _test_and_steal_frame_return_true;
105436 +
105437 + _fmt_dbgr("on port %d got FMUC frame\n", fmt_port->id);
105438 + data_offset = FM_PORT_GetBufferDataOffset(
105439 + fmt_port->p_rx_fm_port_dev);
105440 +
105441 + p_fmt_frame = kmalloc(sizeof(struct fmt_frame_s), GFP_KERNEL);
105442 +
105443 + /* dump frame... no more space left on device */
105444 + if (p_fmt_frame == NULL) {
105445 + _fmt_err("no space left on device!\n");
105446 + goto _test_and_steal_frame_return_true;
105447 + }
105448 +
105449 + memset(p_fmt_frame, 0, sizeof(struct fmt_frame_s));
105450 + p_fmt_frame->buff.p_data = kmalloc(size * sizeof(uint8_t), GFP_KERNEL);
105451 +
105452 + /* No more space left on device*/
105453 + if (p_fmt_frame->buff.p_data == NULL) {
105454 + _fmt_err("no space left on device!\n");
105455 + kfree(p_fmt_frame);
105456 + goto _test_and_steal_frame_return_true;
105457 + }
105458 +
105459 + p_fmt_frame->buff.size = size-data_offset;
105460 + p_fmt_frame->buff.qid = fqid;
105461 +
105462 + memcpy(p_fmt_frame->buff.p_data,
105463 + (uint8_t *)PTR_MOVE(buffer, data_offset),
105464 + p_fmt_frame->buff.size);
105465 +
105466 + memcpy(p_fmt_frame->buff.buff_context.fm_prs_res,
105467 + FM_PORT_GetBufferPrsResult(fmt_port->p_rx_fm_port_dev,
105468 + (char *)buffer),
105469 + 32);
105470 +
105471 + /* enqueue frame - this frame will go to us */
105472 + enqueue_fmt_frame(fmt_port, p_fmt_frame);
105473 +
105474 +_test_and_steal_frame_return_true:
105475 + return true;
105476 +}
105477 +
105478 +static int fmt_fq_release(const struct qm_fd *fd)
105479 +{
105480 + struct dpa_bp *_dpa_bp;
105481 + struct bm_buffer _bmb;
105482 +
105483 + if (fd->format == qm_fd_contig) {
105484 + _dpa_bp = dpa_bpid2pool(fd->bpid);
105485 + BUG_ON(IS_ERR(_dpa_bp));
105486 +
105487 + _bmb.hi = fd->addr_hi;
105488 + _bmb.lo = fd->addr_lo;
105489 +
105490 + while (bman_release(_dpa_bp->pool, &_bmb, 1, 0))
105491 + cpu_relax();
105492 +
105493 + } else {
105494 + _fmt_err("frame not supported !\n");
105495 + return -1;
105496 + }
105497 +
105498 + return 0;
105499 +}
105500 +
105501 +/* sync it w/ dpaa_eth.c: DPA_BP_HEAD */
105502 +#define DPA_BP_HEADROOM (DPA_TX_PRIV_DATA_SIZE + \
105503 + fm_get_rx_extra_headroom() + \
105504 + DPA_PARSE_RESULTS_SIZE + \
105505 + DPA_HASH_RESULTS_SIZE)
105506 +#define MAC_HEADER_LENGTH 14
105507 +#define L2_AND_HEADROOM_OFF ((DPA_BP_HEADROOM) + (MAC_HEADER_LENGTH))
105508 +
105509 +/* dpa ingress hooks definition */
105510 +enum dpaa_eth_hook_result fmt_rx_default_hook(
105511 + struct sk_buff *skb,
105512 + struct net_device *net_dev,
105513 + u32 fqid)
105514 +{
105515 + struct dpa_priv_s *dpa_priv = NULL;
105516 + struct fmt_port_s *fmt_port = NULL;
105517 + uint8_t *buffer;
105518 + uint32_t buffer_len;
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 + /* conversion from skb to fd:
105526 + * skb cames processed for L3, so we need to go back for
105527 + * layer 2 offset */
105528 + buffer = (uint8_t *)(skb->data - ((int)L2_AND_HEADROOM_OFF));
105529 + buffer_len = skb->len + ((int)L2_AND_HEADROOM_OFF);
105530 +
105531 + /* if is not out frame let dpa to handle it */
105532 + if (test_and_steal_frame(fmt_port,
105533 + FMT_RX_DFLT_Q,
105534 + buffer,
105535 + buffer_len))
105536 + goto _fmt_rx_default_hook_stolen;
105537 +
105538 + _fmt_dbgr("called:DPAA_ETH_CONTINUE.\n");
105539 + return DPAA_ETH_CONTINUE;
105540 +
105541 +_fmt_rx_default_hook_stolen:
105542 + dev_kfree_skb(skb);
105543 +
105544 + _fmt_dbgr("called:DPAA_ETH_STOLEN.\n");
105545 + return DPAA_ETH_STOLEN;
105546 +}
105547 +
105548 +enum dpaa_eth_hook_result fmt_rx_error_hook(
105549 + struct net_device *net_dev,
105550 + const struct qm_fd *fd,
105551 + u32 fqid)
105552 +{
105553 + struct dpa_priv_s *dpa_priv = NULL;
105554 + struct dpa_bp *dpa_bp = NULL;
105555 + struct fmt_port_s *fmt_port = NULL;
105556 + void *fd_virt_addr = NULL;
105557 + dma_addr_t addr = qm_fd_addr(fd);
105558 +
105559 + _fmt_dbgr("calling...\n");
105560 +
105561 + dpa_priv = netdev_priv(net_dev);
105562 + fmt_port = match_dpa_to_fmt_port(dpa_priv);
105563 +
105564 + /* dpaa doesn't do this... we have to do it here */
105565 + dpa_bp = dpa_bpid2pool(fd->bpid);
105566 + dma_unmap_single(dpa_bp->dev, addr, dpa_bp->size, DMA_BIDIRECTIONAL);
105567 +
105568 + fd_virt_addr = phys_to_virt(addr);
105569 + /* if is not out frame let dpa to handle it */
105570 + if (test_and_steal_frame(fmt_port,
105571 + FMT_RX_ERR_Q,
105572 + fd_virt_addr,
105573 + fd->length20 + fd->offset)) {
105574 + goto _fmt_rx_error_hook_stolen;
105575 + }
105576 +
105577 + _fmt_dbgr("called:DPAA_ETH_CONTINUE.\n");
105578 + return DPAA_ETH_CONTINUE;
105579 +
105580 +_fmt_rx_error_hook_stolen:
105581 + /* the frame data doesn't matter,
105582 + * so, no mapping is needed */
105583 + fmt_fq_release(fd);
105584 +
105585 + _fmt_dbgr("called:DPAA_ETH_STOLEN.\n");
105586 + return DPAA_ETH_STOLEN;
105587 +}
105588 +
105589 +enum dpaa_eth_hook_result fmt_tx_confirm_hook(
105590 + struct net_device *net_dev,
105591 + const struct qm_fd *fd,
105592 + u32 fqid)
105593 +{
105594 + struct dpa_priv_s *dpa_priv = NULL;
105595 + struct fmt_port_s *fmt_port = NULL;
105596 + dma_addr_t addr = qm_fd_addr(fd);
105597 + void *fd_virt_addr = NULL;
105598 + uint32_t fd_len = 0;
105599 +
105600 + _fmt_dbgr("calling...\n");
105601 +
105602 + dpa_priv = netdev_priv(net_dev);
105603 + fmt_port = match_dpa_to_fmt_port(dpa_priv);
105604 +
105605 + fd_virt_addr = phys_to_virt(addr);
105606 + fd_len = fd->length20 + fd->offset;
105607 +
105608 + if (fd_len > fm_get_max_frm()) {
105609 + _fmt_err("tx confirm bad frame size: %u!\n", fd_len);
105610 + goto _fmt_tx_confirm_hook_continue;
105611 + }
105612 +
105613 + if (test_and_steal_frame(fmt_port,
105614 + FMT_TX_CONF_Q,
105615 + fd_virt_addr,
105616 + fd_len))
105617 + goto _fmt_tx_confirm_hook_stolen;
105618 +
105619 +_fmt_tx_confirm_hook_continue:
105620 + _fmt_dbgr("called:DPAA_ETH_CONTINUE.\n");
105621 + return DPAA_ETH_CONTINUE;
105622 +
105623 +_fmt_tx_confirm_hook_stolen:
105624 + kfree(fd_virt_addr);
105625 +
105626 + _fmt_dbgr("called:DPAA_ETH_STOLEN.\n");
105627 + return DPAA_ETH_STOLEN;
105628 +}
105629 +
105630 +enum dpaa_eth_hook_result fmt_tx_confirm_error_hook(
105631 + struct net_device *net_dev,
105632 + const struct qm_fd *fd,
105633 + u32 fqid)
105634 +{
105635 + struct dpa_priv_s *dpa_priv = NULL;
105636 + struct fmt_port_s *fmt_port = NULL;
105637 + dma_addr_t addr = qm_fd_addr(fd);
105638 + void *fd_virt_addr = NULL;
105639 + uint32_t fd_len = 0;
105640 +
105641 + _fmt_dbgr("calling...\n");
105642 +
105643 + dpa_priv = netdev_priv(net_dev);
105644 + fmt_port = match_dpa_to_fmt_port(dpa_priv);
105645 +
105646 + fd_virt_addr = phys_to_virt(addr);
105647 + fd_len = fd->length20 + fd->offset;
105648 +
105649 + if (fd_len > fm_get_max_frm()) {
105650 + _fmt_err("tx confirm err bad frame size: %u !\n", fd_len);
105651 + goto _priv_ingress_tx_err_continue;
105652 + }
105653 +
105654 + if (test_and_steal_frame(fmt_port, FMT_TX_ERR_Q, fd_virt_addr, fd_len))
105655 + goto _priv_ingress_tx_err_stolen;
105656 +
105657 +_priv_ingress_tx_err_continue:
105658 + _fmt_dbgr("called:DPAA_ETH_CONTINUE.\n");
105659 + return DPAA_ETH_CONTINUE;
105660 +
105661 +_priv_ingress_tx_err_stolen:
105662 + kfree(fd_virt_addr);
105663 +
105664 + _fmt_dbgr("called:DPAA_ETH_STOLEN.\n");
105665 + return DPAA_ETH_STOLEN;
105666 +}
105667 +
105668 +/* egress callbacks definition */
105669 +enum qman_cb_dqrr_result fmt_egress_dqrr(
105670 + struct qman_portal *portal,
105671 + struct qman_fq *fq,
105672 + const struct qm_dqrr_entry *dqrr)
105673 +{
105674 + /* this callback should never be called */
105675 + BUG();
105676 + return qman_cb_dqrr_consume;
105677 +}
105678 +
105679 +static void fmt_egress_error_dqrr(
105680 + struct qman_portal *p,
105681 + struct qman_fq *fq,
105682 + const struct qm_mr_entry *msg)
105683 +{
105684 + uint8_t *fd_virt_addr = NULL;
105685 +
105686 + /* tx failure, on the ern callback - release buffer */
105687 + fd_virt_addr = (uint8_t *)phys_to_virt(qm_fd_addr(&msg->ern.fd));
105688 + kfree(fd_virt_addr);
105689 +
105690 + return;
105691 +}
105692 +
105693 +static const struct qman_fq fmt_egress_fq = {
105694 + .cb = { .dqrr = fmt_egress_dqrr,
105695 + .ern = fmt_egress_error_dqrr,
105696 + .fqs = NULL}
105697 +};
105698 +
105699 +int fmt_fq_alloc(
105700 + struct fmt_fqs_s *fmt_fqs,
105701 + const struct qman_fq *qman_fq,
105702 + uint32_t fqid, uint32_t flags,
105703 + uint16_t channel, uint8_t wq)
105704 +{
105705 + int _errno = 0;
105706 +
105707 + _fmt_dbg("calling...\n");
105708 +
105709 + fmt_fqs->fq_base = *qman_fq;
105710 +
105711 + if (fqid == 0) {
105712 + flags |= QMAN_FQ_FLAG_DYNAMIC_FQID;
105713 + flags &= ~QMAN_FQ_FLAG_NO_MODIFY;
105714 + } else
105715 + flags &= ~QMAN_FQ_FLAG_DYNAMIC_FQID;
105716 +
105717 + fmt_fqs->init = !(flags & QMAN_FQ_FLAG_NO_MODIFY);
105718 +
105719 + _errno = qman_create_fq(fqid, flags, &fmt_fqs->fq_base);
105720 + if (_errno < 0) {
105721 + _fmt_err("frame queues create failed.\n");
105722 + return -EINVAL;
105723 + }
105724 +
105725 + if (fmt_fqs->init) {
105726 + struct qm_mcc_initfq initfq;
105727 +
105728 + initfq.we_mask = QM_INITFQ_WE_DESTWQ;
105729 + initfq.fqd.dest.channel = channel;
105730 + initfq.fqd.dest.wq = wq;
105731 +
105732 + _errno = qman_init_fq(&fmt_fqs->fq_base,
105733 + QMAN_INITFQ_FLAG_SCHED,
105734 + &initfq);
105735 + if (_errno < 0) {
105736 + _fmt_err("frame queues init erorr.\n");
105737 + qman_destroy_fq(&fmt_fqs->fq_base, 0);
105738 + return -EINVAL;
105739 + }
105740 + }
105741 +
105742 + _fmt_dbg("called.\n");
105743 + return 0;
105744 +}
105745 +
105746 +static int fmt_fq_free(struct fmt_fqs_s *fmt_fq)
105747 +{
105748 + int _err = 0;
105749 +
105750 + _fmt_dbg("calling...\n");
105751 +
105752 + if (fmt_fq->init) {
105753 + _err = qman_retire_fq(&fmt_fq->fq_base, NULL);
105754 + if (unlikely(_err < 0))
105755 + _fmt_err("qman_retire_fq(%u) = %d\n",
105756 + qman_fq_fqid(&fmt_fq->fq_base), _err);
105757 +
105758 + _err = qman_oos_fq(&fmt_fq->fq_base);
105759 + if (unlikely(_err < 0))
105760 + _fmt_err("qman_oos_fq(%u) = %d\n",
105761 + qman_fq_fqid(&fmt_fq->fq_base), _err);
105762 + }
105763 +
105764 + qman_destroy_fq(&fmt_fq->fq_base, 0);
105765 +
105766 + _fmt_dbg("called.\n");
105767 + return _err;
105768 +}
105769 +
105770 +/* private pcd dqrr calbacks */
105771 +static enum qman_cb_dqrr_result fmt_pcd_dqrr(
105772 + struct qman_portal *portal,
105773 + struct qman_fq *fq,
105774 + const struct qm_dqrr_entry *dq)
105775 +{
105776 + struct dpa_bp *dpa_bp = NULL;
105777 + dma_addr_t addr = qm_fd_addr(&dq->fd);
105778 + uint8_t *fd_virt_addr = NULL;
105779 + struct fmt_port_s *fmt_port;
105780 + struct fmt_port_pcd_s *fmt_port_pcd;
105781 + uint32_t relative_fqid = 0;
105782 + uint32_t fd_len = 0;
105783 +
105784 + _fmt_dbgr("calling...\n");
105785 +
105786 + /* upcast - from pcd_alloc_fq */
105787 + fmt_port = ((struct fmt_fqs_s *)fq)->fmt_port_priv;
105788 + if (!fmt_port) {
105789 + _fmt_err(" wrong fmt port -to- fq match.\n");
105790 + goto _fmt_pcd_dqrr_return;
105791 + }
105792 + fmt_port_pcd = &fmt_port->fmt_port_pcd;
105793 +
105794 + relative_fqid = dq->fqid - fmt_port_pcd->fqid_base;
105795 + _fmt_dbgr("pcd dqrr got frame on relative fq:%u@base:%u\n",
105796 + relative_fqid, fmt_port_pcd->fqid_base);
105797 +
105798 + fd_len = dq->fd.length20 + dq->fd.offset;
105799 +
105800 + if (fd_len > fm_get_max_frm()) {
105801 + _fmt_err("pcd dqrr wrong frame size: %u (%u:%u)!\n",
105802 + fd_len, dq->fd.length20, dq->fd.offset);
105803 + goto _fmt_pcd_dqrr_return;
105804 + }
105805 +
105806 + dpa_bp = dpa_bpid2pool(dq->fd.bpid);
105807 + dma_unmap_single(dpa_bp->dev, addr, dpa_bp->size, DMA_BIDIRECTIONAL);
105808 +
105809 + fd_virt_addr = phys_to_virt(addr);
105810 + if (!test_and_steal_frame(fmt_port, relative_fqid, fd_virt_addr,
105811 + fd_len)) {
105812 +
105813 +#if defined(FMT_K_DBG) || defined(FMT_K_DBG_RUNTIME)
105814 + atomic_inc(&fmt_port->not_enqueue_to_rxq_wrong_frm);
105815 +#endif
105816 + _fmt_wrn("pcd dqrr unrecognized frame@fqid: %u,"
105817 + " frame len: %u (dropped).\n",
105818 + dq->fqid, dq->fd.length20);
105819 + dump_frame(fd_virt_addr, fd_len);
105820 + }
105821 +
105822 +_fmt_pcd_dqrr_return:
105823 + /* no need to map again here */
105824 + fmt_fq_release(&dq->fd);
105825 +
105826 + _fmt_dbgr("calle.\n");
105827 + return qman_cb_dqrr_consume;
105828 +}
105829 +
105830 +static void fmt_pcd_err_dqrr(
105831 + struct qman_portal *qm,
105832 + struct qman_fq *fq,
105833 + const struct qm_mr_entry *msg)
105834 +{
105835 + _fmt_err("this callback should never be called.\n");
105836 + BUG();
105837 + return;
105838 +}
105839 +
105840 +static void fmt_pcd_fqs_dqrr(
105841 + struct qman_portal *qm,
105842 + struct qman_fq *fq,
105843 + const struct qm_mr_entry *msg)
105844 +{
105845 + _fmt_dbg(" fq state(0x%x)@fqid(%u.\n", msg->fq.fqs, msg->fq.fqid);
105846 + return;
105847 +}
105848 +
105849 +/* private pcd queue template */
105850 +static const struct qman_fq pcd_fq = {
105851 + .cb = { .dqrr = fmt_pcd_dqrr,
105852 + .ern = fmt_pcd_err_dqrr,
105853 + .fqs = fmt_pcd_fqs_dqrr}
105854 +};
105855 +
105856 +/* defined as weak in dpaa driver. */
105857 +/* ! parameters come from IOCTL call - US */
105858 +int dpa_alloc_pcd_fqids(
105859 + struct device *dev,
105860 + uint32_t num, uint8_t alignment,
105861 + uint32_t *base_fqid)
105862 +{
105863 + int _err = 0, i;
105864 + struct net_device *net_dev = NULL;
105865 + struct dpa_priv_s *dpa_priv = NULL;
105866 + struct fmt_port_pcd_s *fmt_port_pcd = NULL;
105867 + struct fmt_fqs_s *fmt_fqs = NULL;
105868 + struct fmt_port_s *fmt_port = NULL;
105869 + int num_allocated = 0;
105870 +
105871 + _fmt_dbg("calling...\n");
105872 +
105873 + net_dev = (typeof(net_dev))dev_get_drvdata(dev);
105874 + dpa_priv = (typeof(dpa_priv))netdev_priv(net_dev);
105875 +
105876 + if (!netif_msg_probe(dpa_priv)) {
105877 + _fmt_err("dpa not probe.\n");
105878 + _err = -ENODEV;
105879 + goto _pcd_alloc_fqs_err;
105880 + }
105881 +
105882 + fmt_port = match_dpa_to_fmt_port(dpa_priv);
105883 + if (!fmt_port) {
105884 + _fmt_err("fmt port not found.");
105885 + _err = -EINVAL;
105886 + goto _pcd_alloc_fqs_err;
105887 + }
105888 +
105889 + fmt_port_pcd = &fmt_port->fmt_port_pcd;
105890 +
105891 + num_allocated = qman_alloc_fqid_range(base_fqid, num, alignment, 0);
105892 +
105893 + if ((num_allocated <= 0) ||
105894 + (num_allocated < num) ||
105895 + (alignment && (*base_fqid) % alignment)) {
105896 + *base_fqid = 0;
105897 + _fmt_err("Failed to alloc pcd fqs rang.\n");
105898 + _err = -EINVAL;
105899 + goto _pcd_alloc_fqs_err;
105900 + }
105901 +
105902 + _fmt_dbg("wanted %d fqs(align %d), got %d fqids@%u.\n",
105903 + num, alignment, num_allocated, *base_fqid);
105904 +
105905 + /* alloc pcd queues */
105906 + fmt_port_pcd->fmt_pcd_fqs = kmalloc(num_allocated *
105907 + sizeof(struct fmt_fqs_s),
105908 + GFP_KERNEL);
105909 + fmt_port_pcd->num_queues = num_allocated;
105910 + fmt_port_pcd->fqid_base = *base_fqid;
105911 + fmt_fqs = fmt_port_pcd->fmt_pcd_fqs;
105912 +
105913 + /* alloc the pcd queues */
105914 + for (i = 0; i < num_allocated; i++, fmt_fqs++) {
105915 + _err = fmt_fq_alloc(
105916 + fmt_fqs,
105917 + &pcd_fq,
105918 + (*base_fqid) + i, QMAN_FQ_FLAG_NO_ENQUEUE,
105919 + dpa_priv->channel, 7);
105920 +
105921 + if (_err < 0)
105922 + goto _pcd_alloc_fqs_err;
105923 +
105924 + /* upcast to identify from where the frames came from */
105925 + fmt_fqs->fmt_port_priv = fmt_port;
105926 + }
105927 +
105928 + _fmt_dbg("called.\n");
105929 + return _err;
105930 +_pcd_alloc_fqs_err:
105931 + if (num_allocated > 0)
105932 + qman_release_fqid_range(*base_fqid, num_allocated);
105933 + /*TODO: free fmt_pcd_fqs if are any */
105934 +
105935 + _fmt_dbg("called(_err:%d).\n", _err);
105936 + return _err;
105937 +}
105938 +
105939 +/* defined as weak in dpaa driver. */
105940 +int dpa_free_pcd_fqids(
105941 + struct device *dev,
105942 + uint32_t base_fqid)
105943 +{
105944 +
105945 + int _err = 0, i;
105946 + struct net_device *net_dev = NULL;
105947 + struct dpa_priv_s *dpa_priv = NULL;
105948 + struct fmt_port_pcd_s *fmt_port_pcd = NULL;
105949 + struct fmt_fqs_s *fmt_fqs = NULL;
105950 + struct fmt_port_s *fmt_port = NULL;
105951 + int num_allocated = 0;
105952 +
105953 + _fmt_dbg("calling...\n");
105954 +
105955 + net_dev = (typeof(net_dev))dev_get_drvdata(dev);
105956 + dpa_priv = (typeof(dpa_priv))netdev_priv(net_dev);
105957 +
105958 + if (!netif_msg_probe(dpa_priv)) {
105959 + _fmt_err("dpa not probe.\n");
105960 + _err = -ENODEV;
105961 + goto _pcd_free_fqs_err;
105962 + }
105963 +
105964 + fmt_port = match_dpa_to_fmt_port(dpa_priv);
105965 + if (!fmt_port) {
105966 + _fmt_err("fmt port not found.");
105967 + _err = -EINVAL;
105968 + goto _pcd_free_fqs_err;
105969 + }
105970 +
105971 + fmt_port_pcd = &fmt_port->fmt_port_pcd;
105972 + num_allocated = fmt_port_pcd->num_queues;
105973 + fmt_fqs = fmt_port_pcd->fmt_pcd_fqs;
105974 +
105975 + for (i = 0; i < num_allocated; i++, fmt_fqs++)
105976 + fmt_fq_free(fmt_fqs);
105977 +
105978 + qman_release_fqid_range(base_fqid,num_allocated);
105979 +
105980 + kfree(fmt_port_pcd->fmt_pcd_fqs);
105981 + memset(fmt_port_pcd, 0, sizeof(*fmt_port_pcd));
105982 +
105983 + /* debugging stuff */
105984 +#if defined(FMT_K_DBG) || defined(FMT_K_DBG_RUNTIME)
105985 + _fmt_dbg(" portid: %u.\n", fmt_port->id);
105986 + _fmt_dbg(" frames enqueue to qman: %u.\n",
105987 + atomic_read(&fmt_port->enqueue_to_qman_frm));
105988 + _fmt_dbg(" frames enqueue to rxq: %u.\n",
105989 + atomic_read(&fmt_port->enqueue_to_rxq));
105990 + _fmt_dbg(" frames dequeue from rxq: %u.\n",
105991 + atomic_read(&fmt_port->dequeue_from_rxq));
105992 + _fmt_dbg(" frames not enqueue to rxq - wrong frm: %u.\n",
105993 + atomic_read(&fmt_port->not_enqueue_to_rxq_wrong_frm));
105994 + atomic_set(&fmt_port->enqueue_to_qman_frm, 0);
105995 + atomic_set(&fmt_port->enqueue_to_rxq, 0);
105996 + atomic_set(&fmt_port->dequeue_from_rxq, 0);
105997 + atomic_set(&fmt_port->not_enqueue_to_rxq_wrong_frm, 0);
105998 +#endif
105999 + return 0;
106000 +
106001 +_pcd_free_fqs_err:
106002 + return _err;
106003 +}
106004 +
106005 +static int fmt_port_init(
106006 + struct fmt_port_s *fmt_port,
106007 + ioc_fmt_port_param_t *p_Params)
106008 +{
106009 + struct device_node *fm_node, *fm_port_node;
106010 + const uint32_t *uint32_prop;
106011 + int _errno = 0, lenp = 0, i;
106012 + static struct of_device_id fm_node_of_match[] = {
106013 + { .compatible = "fsl,fman", },
106014 + { /* end of list */ },
106015 + };
106016 +
106017 + _fmt_dbg("calling...\n");
106018 +
106019 + /* init send/receive tu US list */
106020 + INIT_LIST_HEAD(&fmt_port->rx_q);
106021 +
106022 + /* check parameters */
106023 + if (p_Params->num_tx_queues > FMAN_TEST_MAX_TX_FQS ||
106024 + p_Params->fm_port_id > IOC_FMT_MAX_NUM_OF_PORTS) {
106025 + _fmt_dbg("wrong test parameters.\n");
106026 + return -EINVAL;
106027 + }
106028 +
106029 + /* set port parameters */
106030 + fmt_port->num_of_tx_fqs = p_Params->num_tx_queues;
106031 + fmt_port->id = p_Params->fm_port_id;
106032 + fmt_port->port_type = p_Params->fm_port_type;
106033 + fmt_port->diag = e_IOC_DIAG_MODE_NONE;
106034 +
106035 + /* init debugging stuff */
106036 +#if defined(FMT_K_DBG) || defined(FMT_K_DBG_RUNTIME)
106037 + atomic_set(&fmt_port->enqueue_to_qman_frm, 0);
106038 + atomic_set(&fmt_port->enqueue_to_rxq, 0);
106039 + atomic_set(&fmt_port->dequeue_from_rxq, 0);
106040 + atomic_set(&fmt_port->not_enqueue_to_rxq_wrong_frm, 0);
106041 +#endif
106042 +
106043 + /* TODO: This should be done at probe time not at runtime
106044 + * very ugly function */
106045 + /* fill fmt port properties from dts */
106046 + for_each_matching_node(fm_node, fm_node_of_match) {
106047 +
106048 + uint32_prop = (uint32_t *)of_get_property(fm_node,
106049 + "cell-index", &lenp);
106050 + if (unlikely(uint32_prop == NULL)) {
106051 + _fmt_wrn("of_get_property(%s, cell-index) invalid",
106052 + fm_node->full_name);
106053 + return -EINVAL;
106054 + }
106055 + if (WARN_ON(lenp != sizeof(uint32_t))) {
106056 + _fmt_wrn("of_get_property(%s, cell-index) invalid",
106057 + fm_node->full_name);
106058 + return -EINVAL;
106059 + }
106060 +
106061 + if (*uint32_prop == p_Params->fm_id) {
106062 + struct resource res;
106063 +
106064 + /* Get the FM address */
106065 + _errno = of_address_to_resource(fm_node, 0, &res);
106066 + if (unlikely(_errno < 0)) {
106067 + _fmt_wrn("of_address_to_resource() = %u.\n", _errno);
106068 + return -EINVAL;
106069 + }
106070 +
106071 + fmt_port->fm_phys_base_addr = res.start;
106072 +
106073 + for_each_child_of_node(fm_node, fm_port_node) {
106074 + struct platform_device *of_dev;
106075 +
106076 + if (!of_device_is_available(fm_port_node))
106077 + continue;
106078 +
106079 + uint32_prop = (uint32_t *)of_get_property(
106080 + fm_port_node,
106081 + "cell-index",
106082 + &lenp);
106083 + if (uint32_prop == NULL)
106084 + continue;
106085 +
106086 + if (of_device_is_compatible(fm_port_node,
106087 + "fsl,fman-port-oh") &&
106088 + (fmt_port->port_type == e_IOC_FMT_PORT_T_OP)) {
106089 +
106090 + if (*uint32_prop == fmt_port->id) {
106091 + of_dev = of_find_device_by_node(fm_port_node);
106092 + if (unlikely(of_dev == NULL)) {
106093 + _fmt_wrn("fm id invalid\n");
106094 + return -EINVAL;
106095 + }
106096 +
106097 + fmt_port->p_tx_port =
106098 + fm_port_bind(&of_dev->dev);
106099 + fmt_port->p_tx_fm_port_dev =
106100 + (void *)fm_port_get_handle(
106101 + fmt_port->p_tx_port);
106102 + fmt_port->p_rx_port =
106103 + fmt_port->p_tx_port;
106104 + fmt_port->p_rx_fm_port_dev =
106105 + fmt_port->p_tx_fm_port_dev;
106106 + fmt_port->p_mac_dev = NULL;
106107 + break;
106108 + }
106109 + } else if ((*uint32_prop == fmt_port->id) &&
106110 + fmt_port->port_type == e_IOC_FMT_PORT_T_RXTX) {
106111 +
106112 + of_dev = of_find_device_by_node(fm_port_node);
106113 + if (unlikely(of_dev == NULL)) {
106114 + _fmt_wrn("dtb fm id invalid value");
106115 + return -EINVAL;
106116 + }
106117 +
106118 + if (of_device_is_compatible(fm_port_node,
106119 + "fsl,fman-port-1g-tx")) {
106120 + fmt_port->p_tx_port =
106121 + fm_port_bind(&of_dev->dev);
106122 + fmt_port->p_tx_fm_port_dev = (void *)
106123 + fm_port_get_handle(
106124 + fmt_port->p_tx_port);
106125 + } else if (of_device_is_compatible(fm_port_node,
106126 + "fsl,fman-port-1g-rx")) {
106127 + fmt_port->p_rx_port =
106128 + fm_port_bind(&of_dev->dev);
106129 + fmt_port->p_rx_fm_port_dev = (void *)
106130 + fm_port_get_handle(
106131 + fmt_port->p_rx_port);
106132 + } else if (of_device_is_compatible(fm_port_node,
106133 + "fsl,fman-1g-mac") ||
106134 + of_device_is_compatible(fm_port_node,
106135 + "fsl,fman-memac"))
106136 + fmt_port->p_mac_dev =
106137 + (typeof(fmt_port->p_mac_dev))
106138 + dev_get_drvdata(&of_dev->dev);
106139 + else
106140 + continue;
106141 +
106142 + if (fmt_port->p_tx_fm_port_dev &&
106143 + fmt_port->p_rx_fm_port_dev && fmt_port->p_mac_dev)
106144 + break;
106145 + } else if (((*uint32_prop + FM_MAX_NUM_OF_1G_RX_PORTS) ==
106146 + fmt_port->id) &&
106147 + fmt_port->port_type == e_IOC_FMT_PORT_T_RXTX) {
106148 +
106149 + of_dev = of_find_device_by_node(fm_port_node);
106150 + if (unlikely(of_dev == NULL)) {
106151 + _fmt_wrn("dtb fm id invalid value\n");
106152 + return -EINVAL;
106153 + }
106154 +
106155 + if (of_device_is_compatible(fm_port_node,
106156 + "fsl,fman-port-10g-tx")) {
106157 + fmt_port->p_tx_port =
106158 + fm_port_bind(&of_dev->dev);
106159 + fmt_port->p_tx_fm_port_dev = (void *)
106160 + fm_port_get_handle(
106161 + fmt_port->p_tx_port);
106162 + } else if (of_device_is_compatible(fm_port_node,
106163 + "fsl,fman-port-10g-rx")) {
106164 + fmt_port->p_rx_port =
106165 + fm_port_bind(&of_dev->dev);
106166 + fmt_port->p_rx_fm_port_dev = (void *)
106167 + fm_port_get_handle(
106168 + fmt_port->p_rx_port);
106169 + } else if (of_device_is_compatible(fm_port_node,
106170 + "fsl,fman-10g-mac") ||
106171 + of_device_is_compatible(fm_port_node,
106172 + "fsl,fman-memac"))
106173 + fmt_port->p_mac_dev =
106174 + (typeof(fmt_port->p_mac_dev))
106175 + dev_get_drvdata(&of_dev->dev);
106176 + else
106177 + continue;
106178 +
106179 + if (fmt_port->p_tx_fm_port_dev &&
106180 + fmt_port->p_rx_fm_port_dev && fmt_port->p_mac_dev)
106181 + break;
106182 + }
106183 + } /* for_each_child */
106184 + }
106185 + } /* for each matching node */
106186 +
106187 + if (fmt_port->p_tx_fm_port_dev == 0 ||
106188 + fmt_port->p_rx_fm_port_dev == 0) {
106189 +
106190 + _fmt_err("bad fm port pointers.\n");
106191 + return -EINVAL;
106192 + }
106193 +
106194 + _fmt_dbg("alloc %u tx queues.\n", fmt_port->num_of_tx_fqs);
106195 +
106196 + /* init fman test egress dynamic frame queues */
106197 + for (i = 0; i < fmt_port->num_of_tx_fqs; i++) {
106198 + int _errno;
106199 + _errno = fmt_fq_alloc(
106200 + &fmt_port->p_tx_fqs[i],
106201 + &fmt_egress_fq,
106202 + 0,
106203 + QMAN_FQ_FLAG_TO_DCPORTAL,
106204 + fm_get_tx_port_channel(fmt_port->p_tx_port),
106205 + i);
106206 +
106207 + if (_errno < 0) {
106208 + _fmt_err("tx queues allocation failed.\n");
106209 + /* TODO: memory leak here if 1 queue is allocated and
106210 + * next queues are failing ... */
106211 + return -EINVAL;
106212 + }
106213 + }
106214 +
106215 + /* port is valid and ready to use. */
106216 + fmt_port->valid = TRUE;
106217 +
106218 + _fmt_dbg("called.\n");
106219 + return 0;
106220 +}
106221 +
106222 +/* fm test chardev functions */
106223 +static int fmt_open(struct inode *inode, struct file *file)
106224 +{
106225 + unsigned int minor = iminor(inode);
106226 +
106227 + _fmt_dbg("calling...\n");
106228 +
106229 + if (file->private_data != NULL)
106230 + return 0;
106231 +
106232 + /* The minor represent the port number.
106233 + * Set the port structure accordingly, thus all the operations
106234 + * will be done on this port. */
106235 + if ((minor >= DEV_FM_TEST_PORTS_MINOR_BASE) &&
106236 + (minor < DEV_FM_TEST_MAX_MINORS))
106237 + file->private_data = &fm_test.ports[minor];
106238 + else
106239 + return -ENXIO;
106240 +
106241 + _fmt_dbg("called.\n");
106242 + return 0;
106243 +}
106244 +
106245 +static int fmt_close(struct inode *inode, struct file *file)
106246 +{
106247 + struct fmt_port_s *fmt_port = NULL;
106248 + struct fmt_frame_s *fmt_frame = NULL;
106249 +
106250 + int err = 0;
106251 +
106252 + _fmt_dbg("calling...\n");
106253 +
106254 + fmt_port = file->private_data;
106255 + if (!fmt_port)
106256 + return -ENODEV;
106257 +
106258 + /* Close the current test port by invalidating it. */
106259 + fmt_port->valid = FALSE;
106260 +
106261 + /* clean the fmt port queue */
106262 + while ((fmt_frame = dequeue_fmt_frame(fmt_port)) != NULL) {
106263 + if (fmt_frame && fmt_frame->buff.p_data){
106264 + kfree(fmt_frame->buff.p_data);
106265 + kfree(fmt_frame);
106266 + }
106267 + }
106268 +
106269 + /* !!! the qman queues are cleaning from fm_ioctl...
106270 + * - very ugly */
106271 +
106272 + _fmt_dbg("called.\n");
106273 + return err;
106274 +}
106275 +
106276 +static int fmt_ioctls(unsigned int minor,
106277 + struct file *file,
106278 + unsigned int cmd,
106279 + unsigned long arg,
106280 + bool compat)
106281 +{
106282 + struct fmt_port_s *fmt_port = NULL;
106283 +
106284 + _fmt_dbg("IOCTL minor:%u "
106285 + " arg:0x%08lx ioctl cmd (0x%08x):(0x%02x:0x%02x.\n",
106286 + minor, arg, cmd, _IOC_TYPE(cmd), _IOC_NR(cmd));
106287 +
106288 + fmt_port = file->private_data;
106289 + if (!fmt_port) {
106290 + _fmt_err("invalid fmt port.\n");
106291 + return -ENODEV;
106292 + }
106293 +
106294 + /* set test type properly */
106295 + if (compat)
106296 + fmt_port->compat_test_type = true;
106297 + else
106298 + fmt_port->compat_test_type = false;
106299 +
106300 + switch (cmd) {
106301 + case FMT_PORT_IOC_INIT:
106302 + {
106303 + ioc_fmt_port_param_t param;
106304 +
106305 + if (fmt_port->valid) {
106306 + _fmt_wrn("port is already initialized.\n");
106307 + return -EFAULT;
106308 + }
106309 +#if defined(CONFIG_COMPAT)
106310 + if (compat) {
106311 + if (copy_from_user(&param,
106312 + (ioc_fmt_port_param_t *)compat_ptr(arg),
106313 + sizeof(ioc_fmt_port_param_t)))
106314 +
106315 + return -EFAULT;
106316 + } else
106317 +#endif
106318 + {
106319 + if (copy_from_user(&param,
106320 + (ioc_fmt_port_param_t *) arg,
106321 + sizeof(ioc_fmt_port_param_t)))
106322 +
106323 + return -EFAULT;
106324 + }
106325 +
106326 + return fmt_port_init(fmt_port, &param);
106327 + }
106328 +
106329 + case FMT_PORT_IOC_SET_DIAG_MODE:
106330 + if (get_user(fmt_port->diag, (ioc_diag_mode *)arg))
106331 + return -EFAULT;
106332 +
106333 + if (fmt_port->diag == e_IOC_DIAG_MODE_CTRL_LOOPBACK)
106334 + return set_mac_int_loopback(fmt_port, TRUE);
106335 + else
106336 + return set_mac_int_loopback(fmt_port, FALSE);
106337 + break;
106338 +
106339 + case FMT_PORT_IOC_SET_DPAECHO_MODE:
106340 + case FMT_PORT_IOC_SET_IP_HEADER_MANIP:
106341 + default:
106342 + _fmt_wrn("ioctl unimplemented minor:%u@ioctl"
106343 + " cmd:0x%08x(type:0x%02x, nr:0x%02x.\n",
106344 + minor, cmd, _IOC_TYPE(cmd), _IOC_NR(cmd));
106345 + return -EFAULT;
106346 + }
106347 +
106348 + return 0;
106349 +}
106350 +
106351 +#ifdef CONFIG_COMPAT
106352 +static long fmt_compat_ioctl(
106353 + struct file *file,
106354 + unsigned int cmd,
106355 + unsigned long arg)
106356 +{
106357 + unsigned int minor = iminor(file->f_path.dentry->d_inode);
106358 +
106359 + _fmt_dbg("calling...\n");
106360 + return fmt_ioctls(minor, file, cmd, arg, true);
106361 +}
106362 +#endif
106363 +
106364 +static long fmt_ioctl(
106365 + struct file *file,
106366 + unsigned int cmd,
106367 + unsigned long arg)
106368 +{
106369 + unsigned int minor = iminor(file->f_path.dentry->d_inode);
106370 + unsigned int res;
106371 +
106372 + _fmt_dbg("calling...\n");
106373 +
106374 + fm_mutex_lock();
106375 + res = fmt_ioctls(minor, file, cmd, arg, false);
106376 + fm_mutex_unlock();
106377 +
106378 + _fmt_dbg("called.\n");
106379 +
106380 + return res;
106381 +}
106382 +
106383 +#ifdef CONFIG_COMPAT
106384 +void copy_compat_test_frame_buffer(
106385 + ioc_fmt_buff_desc_t *buff,
106386 + ioc_fmt_compat_buff_desc_t *compat_buff)
106387 +{
106388 + compat_buff->qid = buff->qid;
106389 + compat_buff->p_data = ptr_to_compat(buff->p_data);
106390 + compat_buff->size = buff->size;
106391 + compat_buff->status = buff->status;
106392 +
106393 + compat_buff->buff_context.p_user_priv =
106394 + ptr_to_compat(buff->buff_context.p_user_priv);
106395 + memcpy(compat_buff->buff_context.fm_prs_res,
106396 + buff->buff_context.fm_prs_res,
106397 + FM_PRS_MAX * sizeof(uint8_t));
106398 + memcpy(compat_buff->buff_context.fm_time_stamp,
106399 + buff->buff_context.fm_time_stamp,
106400 + FM_TIME_STAMP_MAX * sizeof(uint8_t));
106401 +}
106402 +#endif
106403 +
106404 +ssize_t fmt_read(
106405 + struct file *file,
106406 + char __user *buf,
106407 + size_t size,
106408 + loff_t *ppos)
106409 +{
106410 + struct fmt_port_s *fmt_port = NULL;
106411 + struct fmt_frame_s *p_fmt_frame = NULL;
106412 + ssize_t cnt = 0;
106413 +
106414 + fmt_port = file->private_data;
106415 + if (!fmt_port || !fmt_port->valid) {
106416 + _fmt_err("fmt port not valid!\n");
106417 + return -ENODEV;
106418 + }
106419 +
106420 + p_fmt_frame = dequeue_fmt_frame(fmt_port);
106421 + if (p_fmt_frame == NULL)
106422 + return 0;
106423 +
106424 + _fmt_dbgr("calling...\n");
106425 +
106426 +#ifdef CONFIG_COMPAT
106427 + if (fmt_port->compat_test_type){
106428 + cnt = sizeof(ioc_fmt_compat_buff_desc_t);
106429 + }
106430 + else
106431 +#endif
106432 + {
106433 + cnt = sizeof(ioc_fmt_buff_desc_t);
106434 + }
106435 +
106436 + if (size < cnt) {
106437 + _fmt_err("illegal buffer-size!\n");
106438 + cnt = 0;
106439 + goto _fmt_read_return;
106440 + }
106441 +
106442 + /* Copy structure */
106443 +#ifdef CONFIG_COMPAT
106444 + if (fmt_port->compat_test_type) {
106445 + {
106446 + ioc_fmt_compat_buff_desc_t compat_buff;
106447 + copy_compat_test_frame_buffer(&p_fmt_frame->buff,
106448 + &compat_buff);
106449 +
106450 + if (copy_to_user(buf, &compat_buff, cnt)) {
106451 + _fmt_err("copy_to_user failed!\n");
106452 + goto _fmt_read_return;
106453 + }
106454 + }
106455 +
106456 + ((ioc_fmt_compat_buff_desc_t *)buf)->p_data =
106457 + ptr_to_compat(buf+sizeof(ioc_fmt_compat_buff_desc_t));
106458 + cnt += MIN(p_fmt_frame->buff.size, size-cnt);
106459 + } else
106460 +#endif
106461 + {
106462 + if (copy_to_user(buf, &p_fmt_frame->buff, cnt)) {
106463 + _fmt_err("copy_to_user failed!\n");
106464 + goto _fmt_read_return;
106465 + }
106466 +
106467 + ((ioc_fmt_buff_desc_t *)buf)->p_data =
106468 + buf + sizeof(ioc_fmt_buff_desc_t);
106469 + cnt += MIN(p_fmt_frame->buff.size, size-cnt);
106470 + }
106471 +
106472 + if (size < cnt) {
106473 + _fmt_err("illegal buffer-size!\n");
106474 + goto _fmt_read_return;
106475 + }
106476 +
106477 + /* copy frame */
106478 +#ifdef CONFIG_COMPAT
106479 + if (fmt_port->compat_test_type) {
106480 + if (copy_to_user(buf+sizeof(ioc_fmt_compat_buff_desc_t),
106481 + p_fmt_frame->buff.p_data, cnt)) {
106482 + _fmt_err("copy_to_user failed!\n");
106483 + goto _fmt_read_return;
106484 + }
106485 + } else
106486 +#endif
106487 + {
106488 + if (copy_to_user(buf+sizeof(ioc_fmt_buff_desc_t),
106489 + p_fmt_frame->buff.p_data, cnt)) {
106490 + _fmt_err("copy_to_user failed!\n");
106491 + goto _fmt_read_return;
106492 + }
106493 + }
106494 +
106495 +_fmt_read_return:
106496 + kfree(p_fmt_frame->buff.p_data);
106497 + kfree(p_fmt_frame);
106498 +
106499 + _fmt_dbgr("called.\n");
106500 + return cnt;
106501 +}
106502 +
106503 +ssize_t fmt_write(
106504 + struct file *file,
106505 + const char __user *buf,
106506 + size_t size,
106507 + loff_t *ppos)
106508 +{
106509 + struct fmt_port_s *fmt_port = NULL;
106510 + ioc_fmt_buff_desc_t buff_desc;
106511 +#ifdef CONFIG_COMPAT
106512 + ioc_fmt_compat_buff_desc_t buff_desc_compat;
106513 +#endif
106514 + uint8_t *p_data = NULL;
106515 + uint32_t data_offset;
106516 + int _errno;
106517 + t_DpaaFD fd;
106518 +
106519 + _fmt_dbgr("calling...\n");
106520 +
106521 + fmt_port = file->private_data;
106522 + if (!fmt_port || !fmt_port->valid) {
106523 + _fmt_err("fmt port not valid.\n");
106524 + return -EINVAL;
106525 + }
106526 +
106527 + /* If Compat (32B UserSpace - 64B KernelSpace) */
106528 +#ifdef CONFIG_COMPAT
106529 + if (fmt_port->compat_test_type) {
106530 + if (size < sizeof(ioc_fmt_compat_buff_desc_t)) {
106531 + _fmt_err("invalid buff_desc size.\n");
106532 + return -EFAULT;
106533 + }
106534 +
106535 + if (copy_from_user(&buff_desc_compat, buf,
106536 + sizeof(ioc_fmt_compat_buff_desc_t)))
106537 + return -EFAULT;
106538 +
106539 + buff_desc.qid = buff_desc_compat.qid;
106540 + buff_desc.p_data = compat_ptr(buff_desc_compat.p_data);
106541 + buff_desc.size = buff_desc_compat.size;
106542 + buff_desc.status = buff_desc_compat.status;
106543 +
106544 + buff_desc.buff_context.p_user_priv =
106545 + compat_ptr(buff_desc_compat.buff_context.p_user_priv);
106546 + memcpy(buff_desc.buff_context.fm_prs_res,
106547 + buff_desc_compat.buff_context.fm_prs_res,
106548 + FM_PRS_MAX * sizeof(uint8_t));
106549 + memcpy(buff_desc.buff_context.fm_time_stamp,
106550 + buff_desc_compat.buff_context.fm_time_stamp,
106551 + FM_TIME_STAMP_MAX * sizeof(uint8_t));
106552 + } else
106553 +#endif
106554 + {
106555 + if (size < sizeof(ioc_fmt_buff_desc_t)) {
106556 + _fmt_err("invalid buff_desc size.\n");
106557 + return -EFAULT;
106558 + }
106559 +
106560 + if (copy_from_user(&buff_desc, (ioc_fmt_buff_desc_t *)buf,
106561 + sizeof(ioc_fmt_buff_desc_t)))
106562 + return -EFAULT;
106563 + }
106564 +
106565 + data_offset = FM_PORT_GetBufferDataOffset(fmt_port->p_tx_fm_port_dev);
106566 + p_data = kmalloc(buff_desc.size+data_offset, GFP_KERNEL);
106567 + if (!p_data)
106568 + return -ENOMEM;
106569 +
106570 + /* If Compat (32UserSpace - 64KernelSpace) the buff_desc.p_data is ok */
106571 + if (copy_from_user((uint8_t *)PTR_MOVE(p_data, data_offset),
106572 + buff_desc.p_data,
106573 + buff_desc.size)) {
106574 + kfree(p_data);
106575 + return -EFAULT;
106576 + }
106577 +
106578 + /* TODO: dma_map_single here (cannot access the bpool struct) */
106579 +
106580 + /* prepare fd */
106581 + memset(&fd, 0, sizeof(fd));
106582 + DPAA_FD_SET_ADDR(&fd, p_data);
106583 + DPAA_FD_SET_OFFSET(&fd, data_offset);
106584 + DPAA_FD_SET_LENGTH(&fd, buff_desc.size);
106585 +
106586 + _errno = qman_enqueue(&fmt_port->p_tx_fqs[buff_desc.qid].fq_base,
106587 + (struct qm_fd *)&fd, 0);
106588 + if (_errno) {
106589 + buff_desc.status = (uint32_t)_errno;
106590 + if (copy_to_user((ioc_fmt_buff_desc_t *)buf, &buff_desc,
106591 + sizeof(ioc_fmt_buff_desc_t))) {
106592 + kfree(p_data);
106593 + return -EFAULT;
106594 + }
106595 + }
106596 +
106597 + /* for debugging */
106598 +#if defined(FMT_K_DBG) || defined(FMT_K_DBG_RUNTIME)
106599 + atomic_inc(&fmt_port->enqueue_to_qman_frm);
106600 +#endif
106601 + _fmt_dbgr("called.\n");
106602 + return buff_desc.size;
106603 +}
106604 +
106605 +/* fm test character device definition */
106606 +static const struct file_operations fmt_fops =
106607 +{
106608 + .owner = THIS_MODULE,
106609 +#ifdef CONFIG_COMPAT
106610 + .compat_ioctl = fmt_compat_ioctl,
106611 +#endif
106612 + .unlocked_ioctl = fmt_ioctl,
106613 + .open = fmt_open,
106614 + .release = fmt_close,
106615 + .read = fmt_read,
106616 + .write = fmt_write,
106617 +};
106618 +
106619 +static int fmt_init(void)
106620 +{
106621 + int id;
106622 +
106623 + _fmt_dbg("calling...\n");
106624 +
106625 + /* Register to the /dev for IOCTL API */
106626 + /* Register dynamically a new major number for the character device: */
106627 + fm_test.major = register_chrdev(0, DEV_FM_TEST_NAME, &fmt_fops);
106628 + if (fm_test.major <= 0) {
106629 + _fmt_wrn("Failed to allocate major number for device %s.\n",
106630 + DEV_FM_TEST_NAME);
106631 + return -ENODEV;
106632 + }
106633 +
106634 + /* Creating class for FMan_test */
106635 + fm_test.fmt_class = class_create(THIS_MODULE, DEV_FM_TEST_NAME);
106636 + if (IS_ERR(fm_test.fmt_class)) {
106637 + unregister_chrdev(fm_test.major, DEV_FM_TEST_NAME);
106638 + _fmt_wrn("Error creating %s class.\n", DEV_FM_TEST_NAME);
106639 + return -ENODEV;
106640 + }
106641 +
106642 + for (id = 0; id < IOC_FMT_MAX_NUM_OF_PORTS; id++)
106643 + if (NULL == device_create(fm_test.fmt_class, NULL,
106644 + MKDEV(fm_test.major,
106645 + DEV_FM_TEST_PORTS_MINOR_BASE + id), NULL,
106646 + DEV_FM_TEST_NAME "%d", id)) {
106647 +
106648 + _fmt_err("Error creating %s device.\n",
106649 + DEV_FM_TEST_NAME);
106650 + return -ENODEV;
106651 + }
106652 +
106653 + return 0;
106654 +}
106655 +
106656 +static void fmt_free(void)
106657 +{
106658 + int id;
106659 +
106660 + for (id = 0; id < IOC_FMT_MAX_NUM_OF_PORTS; id++)
106661 + device_destroy(fm_test.fmt_class, MKDEV(fm_test.major,
106662 + DEV_FM_TEST_PORTS_MINOR_BASE + id));
106663 + class_destroy(fm_test.fmt_class);
106664 +}
106665 +
106666 +static int __init __cold fmt_load(void)
106667 +{
106668 + struct dpaa_eth_hooks_s priv_dpaa_eth_hooks;
106669 +
106670 + /* set dpaa hooks for default queues */
106671 + memset(&priv_dpaa_eth_hooks, 0, sizeof(priv_dpaa_eth_hooks));
106672 + priv_dpaa_eth_hooks.rx_default = fmt_rx_default_hook;
106673 + priv_dpaa_eth_hooks.rx_error = fmt_rx_error_hook;
106674 + priv_dpaa_eth_hooks.tx_confirm = fmt_tx_confirm_hook;
106675 + priv_dpaa_eth_hooks.tx_error = fmt_tx_confirm_error_hook;
106676 +
106677 + fsl_dpaa_eth_set_hooks(&priv_dpaa_eth_hooks);
106678 +
106679 + /* initialize the fman test environment */
106680 + if (fmt_init() < 0) {
106681 + _fmt_err("Failed to init FM-test modul.\n");
106682 + fmt_free();
106683 + return -ENODEV;
106684 + }
106685 +
106686 + _fmt_inf("FSL FM test module loaded.\n");
106687 +
106688 + return 0;
106689 +}
106690 +
106691 +static void __exit __cold fmt_unload(void)
106692 +{
106693 + fmt_free();
106694 + _fmt_inf("FSL FM test module unloaded.\n");
106695 +}
106696 +
106697 +module_init(fmt_load);
106698 +module_exit(fmt_unload);
106699 --- /dev/null
106700 +++ b/drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_fm.c
106701 @@ -0,0 +1,2908 @@
106702 +/*
106703 + * Copyright 2008-2012 Freescale Semiconductor Inc.
106704 + *
106705 + * Redistribution and use in source and binary forms, with or without
106706 + * modification, are permitted provided that the following conditions are met:
106707 + * * Redistributions of source code must retain the above copyright
106708 + * notice, this list of conditions and the following disclaimer.
106709 + * * Redistributions in binary form must reproduce the above copyright
106710 + * notice, this list of conditions and the following disclaimer in the
106711 + * documentation and/or other materials provided with the distribution.
106712 + * * Neither the name of Freescale Semiconductor nor the
106713 + * names of its contributors may be used to endorse or promote products
106714 + * derived from this software without specific prior written permission.
106715 + *
106716 + *
106717 + * ALTERNATIVELY, this software may be distributed under the terms of the
106718 + * GNU General Public License ("GPL") as published by the Free Software
106719 + * Foundation, either version 2 of that License or (at your option) any
106720 + * later version.
106721 + *
106722 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
106723 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
106724 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
106725 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
106726 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
106727 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
106728 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
106729 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
106730 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
106731 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
106732 + */
106733 +
106734 +/*
106735 + @File lnxwrp_fm.c
106736 + @Author Shlomi Gridish
106737 + @Description FM Linux wrapper functions.
106738 +*/
106739 +
106740 +#include <linux/version.h>
106741 +#include <linux/slab.h>
106742 +#if defined(CONFIG_MODVERSIONS) && !defined(MODVERSIONS)
106743 +#define MODVERSIONS
106744 +#endif
106745 +#ifdef MODVERSIONS
106746 +#include <config/modversions.h>
106747 +#endif /* MODVERSIONS */
106748 +#include <linux/kernel.h>
106749 +#include <linux/module.h>
106750 +#include <linux/fs.h>
106751 +#include <linux/cdev.h>
106752 +#include <linux/device.h>
106753 +#include <linux/irq.h>
106754 +#include <linux/interrupt.h>
106755 +#include <linux/io.h>
106756 +#include <linux/ioport.h>
106757 +#include <linux/of_platform.h>
106758 +#include <linux/of_address.h>
106759 +#include <linux/of_irq.h>
106760 +#include <linux/clk.h>
106761 +#include <asm/uaccess.h>
106762 +#include <asm/errno.h>
106763 +#ifndef CONFIG_FMAN_ARM
106764 +#include <sysdev/fsl_soc.h>
106765 +#include <linux/fsl/guts.h>
106766 +#include <linux/fsl/svr.h>
106767 +#endif
106768 +#include <linux/stat.h> /* For file access mask */
106769 +#include <linux/skbuff.h>
106770 +#include <linux/proc_fs.h>
106771 +
106772 +/* NetCommSw Headers --------------- */
106773 +#include "std_ext.h"
106774 +#include "error_ext.h"
106775 +#include "sprint_ext.h"
106776 +#include "debug_ext.h"
106777 +#include "sys_io_ext.h"
106778 +
106779 +#include "fm_ioctls.h"
106780 +
106781 +#include "lnxwrp_fm.h"
106782 +#include "lnxwrp_resources.h"
106783 +#include "lnxwrp_sysfs_fm.h"
106784 +#include "lnxwrp_sysfs_fm_port.h"
106785 +#include "lnxwrp_exp_sym.h"
106786 +#include "fm_common.h"
106787 +#include "../../sdk_fman/Peripherals/FM/fm.h"
106788 +#define __ERR_MODULE__ MODULE_FM
106789 +
106790 +extern struct device_node *GetFmPortAdvArgsDevTreeNode (struct device_node *fm_node,
106791 + e_FmPortType portType,
106792 + uint8_t portId);
106793 +
106794 +#define PROC_PRINT(args...) offset += sprintf(buf+offset,args)
106795 +
106796 +#define ADD_ADV_CONFIG_NO_RET(_func, _param) \
106797 + do { \
106798 + if (i<max){ \
106799 + p_Entry = &p_Entrys[i]; \
106800 + p_Entry->p_Function = _func; \
106801 + _param \
106802 + i++; \
106803 + } \
106804 + else \
106805 + REPORT_ERROR(MAJOR, E_INVALID_VALUE,\
106806 + ("Number of advanced-configuration entries exceeded"));\
106807 + } while (0)
106808 +
106809 +/* Bootarg used to override the Kconfig FSL_FM_MAX_FRAME_SIZE value */
106810 +#define FSL_FM_MAX_FRM_BOOTARG "fsl_fm_max_frm"
106811 +
106812 +/* Bootarg used to override FSL_FM_RX_EXTRA_HEADROOM Kconfig value */
106813 +#define FSL_FM_RX_EXTRA_HEADROOM_BOOTARG "fsl_fm_rx_extra_headroom"
106814 +
106815 +/* Minimum and maximum value for the fsl_fm_rx_extra_headroom bootarg */
106816 +#define FSL_FM_RX_EXTRA_HEADROOM_MIN 16
106817 +#define FSL_FM_RX_EXTRA_HEADROOM_MAX 384
106818 +
106819 +#define FSL_FM_PAUSE_TIME_ENABLE 0xf000
106820 +#define FSL_FM_PAUSE_TIME_DISABLE 0
106821 +#define FSL_FM_PAUSE_THRESH_DEFAULT 0
106822 +
106823 +/*
106824 + * Max frame size, across all interfaces.
106825 + * Configurable from Kconfig or bootargs, to avoid allocating
106826 + * oversized (socket) buffers when not using jumbo frames.
106827 + * Must be large enough to accommodate the network MTU, but small enough
106828 + * to avoid wasting skb memory.
106829 + *
106830 + * Could be overridden once, at boot-time, via the
106831 + * fm_set_max_frm() callback.
106832 + */
106833 +int fsl_fm_max_frm = CONFIG_FSL_FM_MAX_FRAME_SIZE;
106834 +
106835 +/*
106836 + * Extra headroom for Rx buffers.
106837 + * FMan is instructed to allocate, on the Rx path, this amount of
106838 + * space at the beginning of a data buffer, beside the DPA private
106839 + * data area and the IC fields.
106840 + * Does not impact Tx buffer layout.
106841 + *
106842 + * Configurable from Kconfig or bootargs. Zero by default, it's needed
106843 + * on particular forwarding scenarios that add extra headers to the
106844 + * forwarded frame.
106845 + */
106846 +int fsl_fm_rx_extra_headroom = CONFIG_FSL_FM_RX_EXTRA_HEADROOM;
106847 +
106848 +#ifdef CONFIG_FMAN_PFC
106849 +static int fsl_fm_pfc_quanta[] = {
106850 + CONFIG_FMAN_PFC_QUANTA_0,
106851 + CONFIG_FMAN_PFC_QUANTA_1,
106852 + CONFIG_FMAN_PFC_QUANTA_2,
106853 + CONFIG_FMAN_PFC_QUANTA_3
106854 +};
106855 +#endif
106856 +
106857 +static t_LnxWrpFm lnxWrpFm;
106858 +
106859 +int fm_get_max_frm()
106860 +{
106861 + return fsl_fm_max_frm;
106862 +}
106863 +EXPORT_SYMBOL(fm_get_max_frm);
106864 +
106865 +int fm_get_rx_extra_headroom()
106866 +{
106867 + return ALIGN(fsl_fm_rx_extra_headroom, 16);
106868 +}
106869 +EXPORT_SYMBOL(fm_get_rx_extra_headroom);
106870 +
106871 +static int __init fm_set_max_frm(char *str)
106872 +{
106873 + int ret = 0;
106874 +
106875 + ret = get_option(&str, &fsl_fm_max_frm);
106876 + if (ret != 1) {
106877 + /*
106878 + * This will only work if CONFIG_EARLY_PRINTK is compiled in,
106879 + * and something like "earlyprintk=serial,uart0,115200" is
106880 + * specified in the bootargs
106881 + */
106882 + printk(KERN_WARNING "No suitable %s=<int> prop in bootargs; "
106883 + "will use the default FSL_FM_MAX_FRAME_SIZE (%d) "
106884 + "from Kconfig.\n", FSL_FM_MAX_FRM_BOOTARG,
106885 + CONFIG_FSL_FM_MAX_FRAME_SIZE);
106886 +
106887 + fsl_fm_max_frm = CONFIG_FSL_FM_MAX_FRAME_SIZE;
106888 + return 1;
106889 + }
106890 +
106891 + /* Don't allow invalid bootargs; fallback to the Kconfig value */
106892 + if (fsl_fm_max_frm < 64 || fsl_fm_max_frm > 9600) {
106893 + printk(KERN_WARNING "Invalid %s=%d in bootargs, valid range is "
106894 + "64-9600. Falling back to the FSL_FM_MAX_FRAME_SIZE (%d) "
106895 + "from Kconfig.\n",
106896 + FSL_FM_MAX_FRM_BOOTARG, fsl_fm_max_frm,
106897 + CONFIG_FSL_FM_MAX_FRAME_SIZE);
106898 +
106899 + fsl_fm_max_frm = CONFIG_FSL_FM_MAX_FRAME_SIZE;
106900 + return 1;
106901 + }
106902 +
106903 + printk(KERN_INFO "Using fsl_fm_max_frm=%d from bootargs\n",
106904 + fsl_fm_max_frm);
106905 + return 0;
106906 +}
106907 +early_param(FSL_FM_MAX_FRM_BOOTARG, fm_set_max_frm);
106908 +
106909 +static int __init fm_set_rx_extra_headroom(char *str)
106910 +{
106911 + int ret;
106912 +
106913 + ret = get_option(&str, &fsl_fm_rx_extra_headroom);
106914 +
106915 + if (ret != 1) {
106916 + printk(KERN_WARNING "No suitable %s=<int> prop in bootargs; "
106917 + "will use the default FSL_FM_RX_EXTRA_HEADROOM (%d) "
106918 + "from Kconfig.\n", FSL_FM_RX_EXTRA_HEADROOM_BOOTARG,
106919 + CONFIG_FSL_FM_RX_EXTRA_HEADROOM);
106920 + fsl_fm_rx_extra_headroom = CONFIG_FSL_FM_RX_EXTRA_HEADROOM;
106921 +
106922 + return 1;
106923 + }
106924 +
106925 + if (fsl_fm_rx_extra_headroom < FSL_FM_RX_EXTRA_HEADROOM_MIN ||
106926 + fsl_fm_rx_extra_headroom > FSL_FM_RX_EXTRA_HEADROOM_MAX) {
106927 + printk(KERN_WARNING "Invalid value for %s=%d prop in "
106928 + "bootargs; will use the default "
106929 + "FSL_FM_RX_EXTRA_HEADROOM (%d) from Kconfig.\n",
106930 + FSL_FM_RX_EXTRA_HEADROOM_BOOTARG,
106931 + fsl_fm_rx_extra_headroom,
106932 + CONFIG_FSL_FM_RX_EXTRA_HEADROOM);
106933 + fsl_fm_rx_extra_headroom = CONFIG_FSL_FM_RX_EXTRA_HEADROOM;
106934 + }
106935 +
106936 + printk(KERN_INFO "Using fsl_fm_rx_extra_headroom=%d from bootargs\n",
106937 + fsl_fm_rx_extra_headroom);
106938 +
106939 + return 0;
106940 +}
106941 +early_param(FSL_FM_RX_EXTRA_HEADROOM_BOOTARG, fm_set_rx_extra_headroom);
106942 +
106943 +static irqreturn_t fm_irq(int irq, void *_dev)
106944 +{
106945 + t_LnxWrpFmDev *p_LnxWrpFmDev = (t_LnxWrpFmDev *)_dev;
106946 +#ifdef CONFIG_PM_SLEEP
106947 + t_Fm *p_Fm = (t_Fm*)p_LnxWrpFmDev->h_Dev;
106948 +#endif
106949 + if (!p_LnxWrpFmDev || !p_LnxWrpFmDev->h_Dev)
106950 + return IRQ_NONE;
106951 +
106952 +#ifdef CONFIG_PM_SLEEP
106953 + if (fman_get_normal_pending(p_Fm->p_FmFpmRegs) & INTR_EN_WAKEUP)
106954 + {
106955 + pm_wakeup_event(p_LnxWrpFmDev->dev, 200);
106956 + }
106957 +#endif
106958 + FM_EventIsr(p_LnxWrpFmDev->h_Dev);
106959 + return IRQ_HANDLED;
106960 +}
106961 +
106962 +static irqreturn_t fm_err_irq(int irq, void *_dev)
106963 +{
106964 + t_LnxWrpFmDev *p_LnxWrpFmDev = (t_LnxWrpFmDev *)_dev;
106965 +
106966 + if (!p_LnxWrpFmDev || !p_LnxWrpFmDev->h_Dev)
106967 + return IRQ_NONE;
106968 +
106969 + if (FM_ErrorIsr(p_LnxWrpFmDev->h_Dev) == E_OK)
106970 + return IRQ_HANDLED;
106971 +
106972 + return IRQ_NONE;
106973 +}
106974 +
106975 +/* used to protect FMD/LLD from concurrent calls in functions fm_mutex_lock / fm_mutex_unlock */
106976 +static struct mutex lnxwrp_mutex;
106977 +
106978 +static t_LnxWrpFmDev * CreateFmDev(uint8_t id)
106979 +{
106980 + t_LnxWrpFmDev *p_LnxWrpFmDev;
106981 + int j;
106982 +
106983 + p_LnxWrpFmDev = (t_LnxWrpFmDev *)XX_Malloc(sizeof(t_LnxWrpFmDev));
106984 + if (!p_LnxWrpFmDev)
106985 + {
106986 + REPORT_ERROR(MAJOR, E_NO_MEMORY, NO_MSG);
106987 + return NULL;
106988 + }
106989 +
106990 + memset(p_LnxWrpFmDev, 0, sizeof(t_LnxWrpFmDev));
106991 + p_LnxWrpFmDev->fmDevSettings.advConfig = (t_SysObjectAdvConfigEntry*)XX_Malloc(FM_MAX_NUM_OF_ADV_SETTINGS*sizeof(t_SysObjectAdvConfigEntry));
106992 + memset(p_LnxWrpFmDev->fmDevSettings.advConfig, 0, (FM_MAX_NUM_OF_ADV_SETTINGS*sizeof(t_SysObjectAdvConfigEntry)));
106993 + p_LnxWrpFmDev->fmPcdDevSettings.advConfig = (t_SysObjectAdvConfigEntry*)XX_Malloc(FM_MAX_NUM_OF_ADV_SETTINGS*sizeof(t_SysObjectAdvConfigEntry));
106994 + memset(p_LnxWrpFmDev->fmPcdDevSettings.advConfig, 0, (FM_MAX_NUM_OF_ADV_SETTINGS*sizeof(t_SysObjectAdvConfigEntry)));
106995 + p_LnxWrpFmDev->hcPort.settings.advConfig = (t_SysObjectAdvConfigEntry*)XX_Malloc(FM_MAX_NUM_OF_ADV_SETTINGS*sizeof(t_SysObjectAdvConfigEntry));
106996 + memset(p_LnxWrpFmDev->hcPort.settings.advConfig, 0, (FM_MAX_NUM_OF_ADV_SETTINGS*sizeof(t_SysObjectAdvConfigEntry)));
106997 + for (j=0; j<FM_MAX_NUM_OF_RX_PORTS; j++)
106998 + {
106999 + p_LnxWrpFmDev->rxPorts[j].settings.advConfig = (t_SysObjectAdvConfigEntry*)XX_Malloc(FM_MAX_NUM_OF_ADV_SETTINGS*sizeof(t_SysObjectAdvConfigEntry));
107000 + memset(p_LnxWrpFmDev->rxPorts[j].settings.advConfig, 0, (FM_MAX_NUM_OF_ADV_SETTINGS*sizeof(t_SysObjectAdvConfigEntry)));
107001 + }
107002 + for (j=0; j<FM_MAX_NUM_OF_TX_PORTS; j++)
107003 + {
107004 + p_LnxWrpFmDev->txPorts[j].settings.advConfig = (t_SysObjectAdvConfigEntry*)XX_Malloc(FM_MAX_NUM_OF_ADV_SETTINGS*sizeof(t_SysObjectAdvConfigEntry));
107005 + memset(p_LnxWrpFmDev->txPorts[j].settings.advConfig, 0, (FM_MAX_NUM_OF_ADV_SETTINGS*sizeof(t_SysObjectAdvConfigEntry)));
107006 + }
107007 + for (j=0; j<FM_MAX_NUM_OF_OH_PORTS-1; j++)
107008 + {
107009 + p_LnxWrpFmDev->opPorts[j].settings.advConfig = (t_SysObjectAdvConfigEntry*)XX_Malloc(FM_MAX_NUM_OF_ADV_SETTINGS*sizeof(t_SysObjectAdvConfigEntry));
107010 + memset(p_LnxWrpFmDev->opPorts[j].settings.advConfig, 0, (FM_MAX_NUM_OF_ADV_SETTINGS*sizeof(t_SysObjectAdvConfigEntry)));
107011 + }
107012 +
107013 + return p_LnxWrpFmDev;
107014 +}
107015 +
107016 +static void DestroyFmDev(t_LnxWrpFmDev *p_LnxWrpFmDev)
107017 +{
107018 + int j;
107019 +
107020 + for (j=0; j<FM_MAX_NUM_OF_OH_PORTS-1; j++)
107021 + if (p_LnxWrpFmDev->opPorts[j].settings.advConfig)
107022 + XX_Free(p_LnxWrpFmDev->opPorts[j].settings.advConfig);
107023 + for (j=0; j<FM_MAX_NUM_OF_TX_PORTS; j++)
107024 + if (p_LnxWrpFmDev->txPorts[j].settings.advConfig)
107025 + XX_Free(p_LnxWrpFmDev->txPorts[j].settings.advConfig);
107026 + for (j=0; j<FM_MAX_NUM_OF_RX_PORTS; j++)
107027 + if (p_LnxWrpFmDev->rxPorts[j].settings.advConfig)
107028 + XX_Free(p_LnxWrpFmDev->rxPorts[j].settings.advConfig);
107029 + if (p_LnxWrpFmDev->hcPort.settings.advConfig)
107030 + XX_Free(p_LnxWrpFmDev->hcPort.settings.advConfig);
107031 + if (p_LnxWrpFmDev->fmPcdDevSettings.advConfig)
107032 + XX_Free(p_LnxWrpFmDev->fmPcdDevSettings.advConfig);
107033 + if (p_LnxWrpFmDev->fmDevSettings.advConfig)
107034 + XX_Free(p_LnxWrpFmDev->fmDevSettings.advConfig);
107035 +
107036 + XX_Free(p_LnxWrpFmDev);
107037 +}
107038 +
107039 +static t_Error FillRestFmInfo(t_LnxWrpFmDev *p_LnxWrpFmDev)
107040 +{
107041 +#define FM_BMI_PPIDS_OFFSET 0x00080304
107042 +#define FM_DMA_PLR_OFFSET 0x000c2060
107043 +#define FM_FPM_IP_REV_1_OFFSET 0x000c30c4
107044 +#define DMA_HIGH_LIODN_MASK 0x0FFF0000
107045 +#define DMA_LOW_LIODN_MASK 0x00000FFF
107046 +#define DMA_LIODN_SHIFT 16
107047 +
107048 +typedef _Packed struct {
107049 + uint32_t plr[32];
107050 +} _PackedType t_Plr;
107051 +
107052 +typedef _Packed struct {
107053 + volatile uint32_t fmbm_ppid[63];
107054 +} _PackedType t_Ppids;
107055 +
107056 + t_Plr *p_Plr;
107057 + t_Ppids *p_Ppids;
107058 + int i,j;
107059 + uint32_t fmRev;
107060 +
107061 + static const uint8_t phys1GRxPortId[] = {0x8,0x9,0xa,0xb,0xc,0xd,0xe,0xf};
107062 + static const uint8_t phys10GRxPortId[] = {0x10,0x11};
107063 +#if (DPAA_VERSION >= 11)
107064 + static const uint8_t physOhPortId[] = {/* 0x1, */0x2,0x3,0x4,0x5,0x6,0x7};
107065 +#else
107066 + static const uint8_t physOhPortId[] = {0x1,0x2,0x3,0x4,0x5,0x6,0x7};
107067 +#endif
107068 + static const uint8_t phys1GTxPortId[] = {0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f};
107069 + static const uint8_t phys10GTxPortId[] = {0x30,0x31};
107070 +
107071 + fmRev = (uint32_t)(*((volatile uint32_t *)UINT_TO_PTR(p_LnxWrpFmDev->fmBaseAddr+FM_FPM_IP_REV_1_OFFSET)));
107072 + fmRev &= 0xffff;
107073 +
107074 + p_Plr = (t_Plr *)UINT_TO_PTR(p_LnxWrpFmDev->fmBaseAddr+FM_DMA_PLR_OFFSET);
107075 +#ifdef MODULE
107076 + for (i=0;i<FM_MAX_NUM_OF_PARTITIONS/2;i++)
107077 + p_Plr->plr[i] = 0;
107078 +#endif /* MODULE */
107079 +
107080 + for (i=0; i<FM_MAX_NUM_OF_PARTITIONS; i++)
107081 + {
107082 + uint16_t liodnBase = (uint16_t)((i%2) ?
107083 + (p_Plr->plr[i/2] & DMA_LOW_LIODN_MASK) :
107084 + ((p_Plr->plr[i/2] & DMA_HIGH_LIODN_MASK) >> DMA_LIODN_SHIFT));
107085 +#ifdef FM_PARTITION_ARRAY
107086 + /* TODO: this was .liodnPerPartition[i] = liodnBase; is the index meaning the same? */
107087 + p_LnxWrpFmDev->fmDevSettings.param.liodnBasePerPort[i] = liodnBase;
107088 +#endif /* FM_PARTITION_ARRAY */
107089 +
107090 + if ((i >= phys1GRxPortId[0]) &&
107091 + (i <= phys1GRxPortId[FM_MAX_NUM_OF_1G_RX_PORTS-1]))
107092 + {
107093 + for (j=0; j<ARRAY_SIZE(phys1GRxPortId); j++)
107094 + if (phys1GRxPortId[j] == i)
107095 + break;
107096 + ASSERT_COND(j<ARRAY_SIZE(phys1GRxPortId));
107097 + p_LnxWrpFmDev->rxPorts[j].settings.param.liodnBase = liodnBase;
107098 + }
107099 + else if (FM_MAX_NUM_OF_10G_RX_PORTS &&
107100 + (i >= phys10GRxPortId[0]) &&
107101 + (i <= phys10GRxPortId[FM_MAX_NUM_OF_10G_RX_PORTS-1]))
107102 + {
107103 + for (j=0; j<ARRAY_SIZE(phys10GRxPortId); j++)
107104 + if (phys10GRxPortId[j] == i)
107105 + break;
107106 + ASSERT_COND(j<ARRAY_SIZE(phys10GRxPortId));
107107 + p_LnxWrpFmDev->rxPorts[FM_MAX_NUM_OF_1G_RX_PORTS+j].settings.param.liodnBase = liodnBase;
107108 + }
107109 + else if ((i >= physOhPortId[0]) &&
107110 + (i <= physOhPortId[FM_MAX_NUM_OF_OH_PORTS-1]))
107111 + {
107112 + for (j=0; j<ARRAY_SIZE(physOhPortId); j++)
107113 + if (physOhPortId[j] == i)
107114 + break;
107115 + ASSERT_COND(j<ARRAY_SIZE(physOhPortId));
107116 + if (j == 0)
107117 + p_LnxWrpFmDev->hcPort.settings.param.liodnBase = liodnBase;
107118 + else
107119 + p_LnxWrpFmDev->opPorts[j - 1].settings.param.liodnBase = liodnBase;
107120 + }
107121 + else if ((i >= phys1GTxPortId[0]) &&
107122 + (i <= phys1GTxPortId[FM_MAX_NUM_OF_1G_TX_PORTS-1]))
107123 + {
107124 + for (j=0; j<ARRAY_SIZE(phys1GTxPortId); j++)
107125 + if (phys1GTxPortId[j] == i)
107126 + break;
107127 + ASSERT_COND(j<ARRAY_SIZE(phys1GTxPortId));
107128 + p_LnxWrpFmDev->txPorts[j].settings.param.liodnBase = liodnBase;
107129 + }
107130 + else if (FM_MAX_NUM_OF_10G_TX_PORTS &&
107131 + (i >= phys10GTxPortId[0]) &&
107132 + (i <= phys10GTxPortId[FM_MAX_NUM_OF_10G_TX_PORTS-1]))
107133 + {
107134 + for (j=0; j<ARRAY_SIZE(phys10GTxPortId); j++)
107135 + if (phys10GTxPortId[j] == i)
107136 + break;
107137 + ASSERT_COND(j<ARRAY_SIZE(phys10GTxPortId));
107138 + p_LnxWrpFmDev->txPorts[FM_MAX_NUM_OF_1G_TX_PORTS+j].settings.param.liodnBase = liodnBase;
107139 + }
107140 + }
107141 +
107142 + p_Ppids = (t_Ppids *)UINT_TO_PTR(p_LnxWrpFmDev->fmBaseAddr+FM_BMI_PPIDS_OFFSET);
107143 +
107144 + for (i=0; i<FM_MAX_NUM_OF_1G_RX_PORTS; i++)
107145 + p_LnxWrpFmDev->rxPorts[i].settings.param.specificParams.rxParams.liodnOffset =
107146 + p_Ppids->fmbm_ppid[phys1GRxPortId[i]-1];
107147 +
107148 + for (i=0; i<FM_MAX_NUM_OF_10G_RX_PORTS; i++)
107149 + p_LnxWrpFmDev->rxPorts[FM_MAX_NUM_OF_1G_RX_PORTS+i].settings.param.specificParams.rxParams.liodnOffset =
107150 + p_Ppids->fmbm_ppid[phys10GRxPortId[i]-1];
107151 +
107152 + return E_OK;
107153 +}
107154 +
107155 +/* Structure that defines QE firmware binary files.
107156 + *
107157 + * See Documentation/powerpc/qe_firmware.txt for a description of these
107158 + * fields.
107159 + */
107160 +struct qe_firmware {
107161 + struct qe_header {
107162 + __be32 length; /* Length of the entire structure, in bytes */
107163 + u8 magic[3]; /* Set to { 'Q', 'E', 'F' } */
107164 + u8 version; /* Version of this layout. First ver is '1' */
107165 + } header;
107166 + u8 id[62]; /* Null-terminated identifier string */
107167 + u8 split; /* 0 = shared I-RAM, 1 = split I-RAM */
107168 + u8 count; /* Number of microcode[] structures */
107169 + struct {
107170 + __be16 model; /* The SOC model */
107171 + u8 major; /* The SOC revision major */
107172 + u8 minor; /* The SOC revision minor */
107173 + } __attribute__ ((packed)) soc;
107174 + u8 padding[4]; /* Reserved, for alignment */
107175 + __be64 extended_modes; /* Extended modes */
107176 + __be32 vtraps[8]; /* Virtual trap addresses */
107177 + u8 reserved[4]; /* Reserved, for future expansion */
107178 + struct qe_microcode {
107179 + u8 id[32]; /* Null-terminated identifier */
107180 + __be32 traps[16]; /* Trap addresses, 0 == ignore */
107181 + __be32 eccr; /* The value for the ECCR register */
107182 + __be32 iram_offset; /* Offset into I-RAM for the code */
107183 + __be32 count; /* Number of 32-bit words of the code */
107184 + __be32 code_offset; /* Offset of the actual microcode */
107185 + u8 major; /* The microcode version major */
107186 + u8 minor; /* The microcode version minor */
107187 + u8 revision; /* The microcode version revision */
107188 + u8 padding; /* Reserved, for alignment */
107189 + u8 reserved[4]; /* Reserved, for future expansion */
107190 + } __attribute__ ((packed)) microcode[1];
107191 + /* All microcode binaries should be located here */
107192 + /* CRC32 should be located here, after the microcode binaries */
107193 +} __attribute__ ((packed));
107194 +
107195 +
107196 +/**
107197 + * FindFmanMicrocode - find the Fman microcode
107198 + *
107199 + * This function returns a pointer to the QE Firmware blob that holds
107200 + * the Fman microcode. We use the QE Firmware structure because Fman microcode
107201 + * is similar to QE microcode, so there's no point in defining a new layout.
107202 + *
107203 + * Current versions of U-Boot embed the Fman firmware into the device tree,
107204 + * so we check for that first. Each Fman node in the device tree contains a
107205 + * node or a pointer to node that holds the firmware. Technically, we should
107206 + * be fetching the firmware node for the current Fman, but we don't have that
107207 + * information any more, so we assume that there is only one firmware node in
107208 + * the device tree, and that all Fmen use the same firmware.
107209 + */
107210 +static const struct qe_firmware *FindFmanMicrocode(void)
107211 +{
107212 + static const struct qe_firmware *P4080_UCPatch;
107213 + struct device_node *np;
107214 +
107215 + if (P4080_UCPatch)
107216 + return P4080_UCPatch;
107217 +
107218 + /* The firmware should be inside the device tree. */
107219 + np = of_find_compatible_node(NULL, NULL, "fsl,fman-firmware");
107220 + if (np) {
107221 + P4080_UCPatch = of_get_property(np, "fsl,firmware", NULL);
107222 + of_node_put(np);
107223 + if (P4080_UCPatch)
107224 + return P4080_UCPatch;
107225 + else
107226 + REPORT_ERROR(WARNING, E_NOT_FOUND, ("firmware node is incomplete"));
107227 + }
107228 +
107229 + /* Returning NULL here forces the reuse of the IRAM content */
107230 + return NULL;
107231 +}
107232 +#define SVR_SECURITY_MASK 0x00080000
107233 +#define SVR_PERSONALITY_MASK 0x0000FF00
107234 +#define SVR_VER_IGNORE_MASK (SVR_SECURITY_MASK | SVR_PERSONALITY_MASK)
107235 +#define SVR_B4860_REV1_VALUE 0x86800010
107236 +#define SVR_B4860_REV2_VALUE 0x86800020
107237 +#define SVR_T4240_VALUE 0x82400000
107238 +#define SVR_T4120_VALUE 0x82400100
107239 +#define SVR_T4160_VALUE 0x82410000
107240 +#define SVR_T4080_VALUE 0x82410200
107241 +#define SVR_T4_DEVICE_ID 0x82400000
107242 +#define SVR_DEVICE_ID_MASK 0xFFF00000
107243 +
107244 +#define OF_DEV_ID_NUM 2 /* one used, another one zeroed */
107245 +
107246 +/* searches for a subnode with the given name/compatible */
107247 +static bool HasFmPcdOfNode(struct device_node *fm_node,
107248 + struct of_device_id *ids,
107249 + const char *name,
107250 + const char *compatible)
107251 +{
107252 + struct device_node *dev_node;
107253 + bool ret = false;
107254 +
107255 + memset(ids, 0, OF_DEV_ID_NUM*sizeof(struct of_device_id));
107256 + if (WARN_ON(strlen(name) >= sizeof(ids[0].name)))
107257 + return false;
107258 + strcpy(ids[0].name, name);
107259 + if (WARN_ON(strlen(compatible) >= sizeof(ids[0].compatible)))
107260 + return false;
107261 + strcpy(ids[0].compatible, compatible);
107262 + for_each_child_of_node(fm_node, dev_node)
107263 + if (of_match_node(ids, dev_node) != NULL)
107264 + ret = true;
107265 + return ret;
107266 +}
107267 +
107268 +static t_LnxWrpFmDev * ReadFmDevTreeNode (struct platform_device *of_dev)
107269 +{
107270 + t_LnxWrpFmDev *p_LnxWrpFmDev;
107271 + struct device_node *fm_node, *dev_node;
107272 + struct of_device_id ids[OF_DEV_ID_NUM];
107273 + struct resource res;
107274 + struct clk *clk;
107275 + u32 clk_rate;
107276 + const uint32_t *uint32_prop;
107277 + int _errno=0, lenp;
107278 + uint32_t tmp_prop;
107279 +
107280 + fm_node = of_node_get(of_dev->dev.of_node);
107281 +
107282 + uint32_prop = (uint32_t *)of_get_property(fm_node, "cell-index", &lenp);
107283 + if (unlikely(uint32_prop == NULL)) {
107284 + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("of_get_property(%s, cell-index) failed", fm_node->full_name));
107285 + return NULL;
107286 + }
107287 + tmp_prop = be32_to_cpu(*uint32_prop);
107288 +
107289 + if (WARN_ON(lenp != sizeof(uint32_t)))
107290 + return NULL;
107291 +
107292 + if (tmp_prop > INTG_MAX_NUM_OF_FM) {
107293 + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("fm id!"));
107294 + return NULL;
107295 + }
107296 + p_LnxWrpFmDev = CreateFmDev(tmp_prop);
107297 + if (!p_LnxWrpFmDev) {
107298 + REPORT_ERROR(MAJOR, E_NULL_POINTER, NO_MSG);
107299 + return NULL;
107300 + }
107301 + p_LnxWrpFmDev->dev = &of_dev->dev;
107302 + p_LnxWrpFmDev->id = tmp_prop;
107303 +
107304 + /* Get the FM interrupt */
107305 + p_LnxWrpFmDev->irq = of_irq_to_resource(fm_node, 0, NULL);
107306 + if (unlikely(p_LnxWrpFmDev->irq == /*NO_IRQ*/0)) {
107307 + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("of_irq_to_resource() = %d", NO_IRQ));
107308 + DestroyFmDev(p_LnxWrpFmDev);
107309 + return NULL;
107310 + }
107311 +
107312 + /* Get the FM error interrupt */
107313 + p_LnxWrpFmDev->err_irq = of_irq_to_resource(fm_node, 1, NULL);
107314 +
107315 + if (unlikely(p_LnxWrpFmDev->err_irq == /*NO_IRQ*/0)) {
107316 + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("of_irq_to_resource() = %d", NO_IRQ));
107317 + DestroyFmDev(p_LnxWrpFmDev);
107318 + return NULL;
107319 + }
107320 +
107321 + /* Get the FM address */
107322 + _errno = of_address_to_resource(fm_node, 0, &res);
107323 + if (unlikely(_errno < 0)) {
107324 + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("of_address_to_resource() = %d", _errno));
107325 + DestroyFmDev(p_LnxWrpFmDev);
107326 + return NULL;
107327 + }
107328 +
107329 +
107330 + p_LnxWrpFmDev->fmBaseAddr = 0;
107331 + p_LnxWrpFmDev->fmPhysBaseAddr = res.start;
107332 + p_LnxWrpFmDev->fmMemSize = res.end + 1 - res.start;
107333 +
107334 + clk = of_clk_get(fm_node, 0);
107335 + if (IS_ERR(clk)) {
107336 + dev_err(&of_dev->dev, "%s: Failed to get FM clock structure\n",
107337 + __func__);
107338 + of_node_put(fm_node);
107339 + DestroyFmDev(p_LnxWrpFmDev);
107340 + return NULL;
107341 + }
107342 +
107343 + clk_rate = clk_get_rate(clk);
107344 + if (!clk_rate) {
107345 + dev_err(&of_dev->dev, "%s: Failed to determine FM clock rate\n",
107346 + __func__);
107347 + of_node_put(fm_node);
107348 + DestroyFmDev(p_LnxWrpFmDev);
107349 + return NULL;
107350 + }
107351 +
107352 + p_LnxWrpFmDev->fmDevSettings.param.fmClkFreq = DIV_ROUND_UP(clk_rate, 1000000); /* In MHz, rounded */
107353 + /* Get the MURAM base address and size */
107354 + memset(ids, 0, sizeof(ids));
107355 + if (WARN_ON(strlen("muram") >= sizeof(ids[0].name)))
107356 + return NULL;
107357 + strcpy(ids[0].name, "muram");
107358 + if (WARN_ON(strlen("fsl,fman-muram") >= sizeof(ids[0].compatible)))
107359 + return NULL;
107360 + strcpy(ids[0].compatible, "fsl,fman-muram");
107361 + for_each_child_of_node(fm_node, dev_node) {
107362 + if (likely(of_match_node(ids, dev_node) != NULL)) {
107363 + _errno = of_address_to_resource(dev_node, 0, &res);
107364 + if (unlikely(_errno < 0)) {
107365 + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("of_address_to_resource() = %d", _errno));
107366 + DestroyFmDev(p_LnxWrpFmDev);
107367 + return NULL;
107368 + }
107369 +
107370 + p_LnxWrpFmDev->fmMuramBaseAddr = 0;
107371 + p_LnxWrpFmDev->fmMuramPhysBaseAddr = res.start;
107372 + p_LnxWrpFmDev->fmMuramMemSize = res.end + 1 - res.start;
107373 +
107374 +#ifndef CONFIG_FMAN_ARM
107375 + {
107376 + uint32_t svr;
107377 + svr = mfspr(SPRN_SVR);
107378 +
107379 + if ((svr & ~SVR_VER_IGNORE_MASK) >= SVR_B4860_REV2_VALUE)
107380 + p_LnxWrpFmDev->fmMuramMemSize = 0x80000;
107381 + }
107382 +#endif
107383 + }
107384 + }
107385 +
107386 + /* Get the RTC base address and size */
107387 + memset(ids, 0, sizeof(ids));
107388 + if (WARN_ON(strlen("ptp-timer") >= sizeof(ids[0].name)))
107389 + return NULL;
107390 + strcpy(ids[0].name, "ptp-timer");
107391 + if (WARN_ON(strlen("fsl,fman-rtc") >= sizeof(ids[0].compatible)))
107392 + return NULL;
107393 + strcpy(ids[0].compatible, "fsl,fman-rtc");
107394 + for_each_child_of_node(fm_node, dev_node) {
107395 + if (likely(of_match_node(ids, dev_node) != NULL)) {
107396 + _errno = of_address_to_resource(dev_node, 0, &res);
107397 + if (unlikely(_errno < 0)) {
107398 + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("of_address_to_resource() = %d", _errno));
107399 + DestroyFmDev(p_LnxWrpFmDev);
107400 + return NULL;
107401 + }
107402 +
107403 + p_LnxWrpFmDev->fmRtcBaseAddr = 0;
107404 + p_LnxWrpFmDev->fmRtcPhysBaseAddr = res.start;
107405 + p_LnxWrpFmDev->fmRtcMemSize = res.end + 1 - res.start;
107406 + }
107407 + }
107408 +
107409 +#if (DPAA_VERSION >= 11)
107410 + /* Get the VSP base address */
107411 + for_each_child_of_node(fm_node, dev_node) {
107412 + if (of_device_is_compatible(dev_node, "fsl,fman-vsps")) {
107413 + _errno = of_address_to_resource(dev_node, 0, &res);
107414 + if (unlikely(_errno < 0)) {
107415 + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("of_address_to_resource() = %d", _errno));
107416 + DestroyFmDev(p_LnxWrpFmDev);
107417 + return NULL;
107418 + }
107419 + p_LnxWrpFmDev->fmVspBaseAddr = 0;
107420 + p_LnxWrpFmDev->fmVspPhysBaseAddr = res.start;
107421 + p_LnxWrpFmDev->fmVspMemSize = res.end + 1 - res.start;
107422 + }
107423 + }
107424 +#endif
107425 +
107426 + /* Get all PCD nodes */
107427 + p_LnxWrpFmDev->prsActive = HasFmPcdOfNode(fm_node, ids, "parser", "fsl,fman-parser");
107428 + p_LnxWrpFmDev->kgActive = HasFmPcdOfNode(fm_node, ids, "keygen", "fsl,fman-keygen");
107429 + p_LnxWrpFmDev->ccActive = HasFmPcdOfNode(fm_node, ids, "cc", "fsl,fman-cc");
107430 + p_LnxWrpFmDev->plcrActive = HasFmPcdOfNode(fm_node, ids, "policer", "fsl,fman-policer");
107431 +
107432 + if (p_LnxWrpFmDev->prsActive || p_LnxWrpFmDev->kgActive ||
107433 + p_LnxWrpFmDev->ccActive || p_LnxWrpFmDev->plcrActive)
107434 + p_LnxWrpFmDev->pcdActive = TRUE;
107435 +
107436 + if (p_LnxWrpFmDev->pcdActive)
107437 + {
107438 + const char *str_prop = (char *)of_get_property(fm_node, "fsl,default-pcd", &lenp);
107439 + if (str_prop) {
107440 + if (strncmp(str_prop, "3-tuple", strlen("3-tuple")) == 0)
107441 + p_LnxWrpFmDev->defPcd = e_FM_PCD_3_TUPLE;
107442 + }
107443 + else
107444 + p_LnxWrpFmDev->defPcd = e_NO_PCD;
107445 + }
107446 +
107447 + of_node_put(fm_node);
107448 +
107449 + p_LnxWrpFmDev->hcCh =
107450 + qman_affine_channel(cpumask_first(qman_affine_cpus()));
107451 +
107452 + p_LnxWrpFmDev->active = TRUE;
107453 +
107454 + return p_LnxWrpFmDev;
107455 +}
107456 +
107457 +struct device_node *GetFmAdvArgsDevTreeNode (uint8_t fmIndx)
107458 +{
107459 + struct device_node *dev_node;
107460 + const uint32_t *uint32_prop;
107461 + int lenp;
107462 + uint32_t tmp_prop;
107463 +
107464 + for_each_compatible_node(dev_node, NULL, "fsl,fman-extended-args") {
107465 + uint32_prop = (uint32_t *)of_get_property(dev_node, "cell-index", &lenp);
107466 + if (unlikely(uint32_prop == NULL)) {
107467 + REPORT_ERROR(MAJOR, E_INVALID_VALUE,
107468 + ("of_get_property(%s, cell-index) failed",
107469 + dev_node->full_name));
107470 + return NULL;
107471 + }
107472 + tmp_prop = be32_to_cpu(*uint32_prop);
107473 + if (WARN_ON(lenp != sizeof(uint32_t)))
107474 + return NULL;
107475 + if (tmp_prop > INTG_MAX_NUM_OF_FM) {
107476 + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("fm id!"));
107477 + return NULL;
107478 + }
107479 + if (fmIndx == tmp_prop)
107480 + return dev_node;
107481 + }
107482 +
107483 + return NULL;
107484 +}
107485 +
107486 +static t_Error CheckNConfigFmAdvArgs (t_LnxWrpFmDev *p_LnxWrpFmDev)
107487 +{
107488 + struct device_node *dev_node;
107489 + t_Error err = E_INVALID_VALUE;
107490 + const uint32_t *uint32_prop;
107491 + const char *str_prop;
107492 + int lenp;
107493 + uint32_t tmp_prop;
107494 +
107495 + dev_node = GetFmAdvArgsDevTreeNode(p_LnxWrpFmDev->id);
107496 + if (!dev_node) /* no advance parameters for FMan */
107497 + return E_OK;
107498 +
107499 + str_prop = (char *)of_get_property(dev_node, "dma-aid-mode", &lenp);
107500 + if (str_prop) {
107501 + if (strcmp(str_prop, "port") == 0)
107502 + err = FM_ConfigDmaAidMode(p_LnxWrpFmDev->h_Dev, e_FM_DMA_AID_OUT_PORT_ID);
107503 + else if (strcmp(str_prop, "tnum") == 0)
107504 + err = FM_ConfigDmaAidMode(p_LnxWrpFmDev->h_Dev, e_FM_DMA_AID_OUT_TNUM);
107505 +
107506 + if (err != E_OK)
107507 + RETURN_ERROR(MINOR, err, NO_MSG);
107508 + }
107509 +
107510 + uint32_prop = (uint32_t *)of_get_property(dev_node,
107511 + "total-fifo-size", &lenp);
107512 + if (uint32_prop) {
107513 + tmp_prop = be32_to_cpu(*uint32_prop);
107514 + if (WARN_ON(lenp != sizeof(uint32_t)))
107515 + RETURN_ERROR(MINOR, E_INVALID_VALUE, NO_MSG);
107516 +
107517 + if (FM_ConfigTotalFifoSize(p_LnxWrpFmDev->h_Dev,
107518 + tmp_prop) != E_OK)
107519 + RETURN_ERROR(MINOR, E_INVALID_VALUE, NO_MSG);
107520 + }
107521 +
107522 + uint32_prop = (uint32_t *)of_get_property(dev_node, "tnum-aging-period",
107523 + &lenp);
107524 + if (uint32_prop) {
107525 + tmp_prop = be32_to_cpu(*uint32_prop);
107526 + if (WARN_ON(lenp != sizeof(uint32_t)))
107527 + RETURN_ERROR(MINOR, E_INVALID_VALUE, NO_MSG);
107528 +
107529 + err = FM_ConfigTnumAgingPeriod(p_LnxWrpFmDev->h_Dev,
107530 + (uint16_t)tmp_prop/*tnumAgingPeriod*/);
107531 +
107532 + if (err != E_OK)
107533 + RETURN_ERROR(MINOR, err, NO_MSG);
107534 + }
107535 +
107536 + of_node_put(dev_node);
107537 +
107538 + return E_OK;
107539 +}
107540 +
107541 +static void LnxwrpFmDevExceptionsCb(t_Handle h_App, e_FmExceptions exception)
107542 +{
107543 + t_LnxWrpFmDev *p_LnxWrpFmDev = (t_LnxWrpFmDev *)h_App;
107544 +
107545 + ASSERT_COND(p_LnxWrpFmDev);
107546 +
107547 + DBG(INFO, ("got fm exception %d", exception));
107548 +
107549 + /* do nothing */
107550 + UNUSED(exception);
107551 +}
107552 +
107553 +static void LnxwrpFmDevBusErrorCb(t_Handle h_App,
107554 + e_FmPortType portType,
107555 + uint8_t portId,
107556 + uint64_t addr,
107557 + uint8_t tnum,
107558 + uint16_t liodn)
107559 +{
107560 + t_LnxWrpFmDev *p_LnxWrpFmDev = (t_LnxWrpFmDev *)h_App;
107561 +
107562 + ASSERT_COND(p_LnxWrpFmDev);
107563 +
107564 + /* do nothing */
107565 + UNUSED(portType);UNUSED(portId);UNUSED(addr);UNUSED(tnum);UNUSED(liodn);
107566 +}
107567 +
107568 +static t_Error ConfigureFmDev(t_LnxWrpFmDev *p_LnxWrpFmDev)
107569 +{
107570 + struct resource *dev_res;
107571 + int _errno;
107572 +
107573 + if (!p_LnxWrpFmDev->active)
107574 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("FM not configured!!!"));
107575 +
107576 +#ifndef MODULE
107577 + _errno = can_request_irq(p_LnxWrpFmDev->irq, 0);
107578 + if (unlikely(_errno < 0))
107579 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("can_request_irq() = %d", _errno));
107580 +#endif
107581 + _errno = devm_request_irq(p_LnxWrpFmDev->dev, p_LnxWrpFmDev->irq, fm_irq, 0, "fman", p_LnxWrpFmDev);
107582 + if (unlikely(_errno < 0))
107583 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("request_irq(%d) = %d", p_LnxWrpFmDev->irq, _errno));
107584 +
107585 + enable_irq_wake(p_LnxWrpFmDev->irq);
107586 +
107587 + if (p_LnxWrpFmDev->err_irq != 0) {
107588 +#ifndef MODULE
107589 + _errno = can_request_irq(p_LnxWrpFmDev->err_irq, 0);
107590 + if (unlikely(_errno < 0))
107591 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("can_request_irq() = %d", _errno));
107592 +#endif
107593 + _errno = devm_request_irq(p_LnxWrpFmDev->dev, p_LnxWrpFmDev->err_irq, fm_err_irq, IRQF_SHARED, "fman-err", p_LnxWrpFmDev);
107594 + if (unlikely(_errno < 0))
107595 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("request_irq(%d) = %d", p_LnxWrpFmDev->err_irq, _errno));
107596 +
107597 + enable_irq_wake(p_LnxWrpFmDev->err_irq);
107598 + }
107599 +
107600 + p_LnxWrpFmDev->res = devm_request_mem_region(p_LnxWrpFmDev->dev, p_LnxWrpFmDev->fmPhysBaseAddr, p_LnxWrpFmDev->fmMemSize, "fman");
107601 + if (unlikely(p_LnxWrpFmDev->res == NULL))
107602 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("request_mem_region() failed"));
107603 +
107604 + p_LnxWrpFmDev->fmBaseAddr = PTR_TO_UINT(devm_ioremap(p_LnxWrpFmDev->dev, p_LnxWrpFmDev->fmPhysBaseAddr, p_LnxWrpFmDev->fmMemSize));
107605 + if (unlikely(p_LnxWrpFmDev->fmBaseAddr == 0))
107606 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("devm_ioremap() failed"));
107607 +
107608 + if (SYS_RegisterIoMap((uint64_t)p_LnxWrpFmDev->fmBaseAddr, (uint64_t)p_LnxWrpFmDev->fmPhysBaseAddr, p_LnxWrpFmDev->fmMemSize) != E_OK)
107609 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("FM memory map"));
107610 +
107611 + dev_res = __devm_request_region(p_LnxWrpFmDev->dev, p_LnxWrpFmDev->res, p_LnxWrpFmDev->fmMuramPhysBaseAddr, p_LnxWrpFmDev->fmMuramMemSize, "fman-muram");
107612 + if (unlikely(dev_res == NULL))
107613 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("__devm_request_region() failed"));
107614 +
107615 + p_LnxWrpFmDev->fmMuramBaseAddr = PTR_TO_UINT(devm_ioremap(p_LnxWrpFmDev->dev, p_LnxWrpFmDev->fmMuramPhysBaseAddr, p_LnxWrpFmDev->fmMuramMemSize));
107616 + if (unlikely(p_LnxWrpFmDev->fmMuramBaseAddr == 0))
107617 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("devm_ioremap() failed"));
107618 +
107619 + if (SYS_RegisterIoMap((uint64_t)p_LnxWrpFmDev->fmMuramBaseAddr, (uint64_t)p_LnxWrpFmDev->fmMuramPhysBaseAddr, p_LnxWrpFmDev->fmMuramMemSize) != E_OK)
107620 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("FM MURAM memory map"));
107621 +
107622 + if (p_LnxWrpFmDev->fmRtcPhysBaseAddr)
107623 + {
107624 + dev_res = __devm_request_region(p_LnxWrpFmDev->dev, p_LnxWrpFmDev->res, p_LnxWrpFmDev->fmRtcPhysBaseAddr, p_LnxWrpFmDev->fmRtcMemSize, "fman-rtc");
107625 + if (unlikely(dev_res == NULL))
107626 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("__devm_request_region() failed"));
107627 +
107628 + p_LnxWrpFmDev->fmRtcBaseAddr = PTR_TO_UINT(devm_ioremap(p_LnxWrpFmDev->dev, p_LnxWrpFmDev->fmRtcPhysBaseAddr, p_LnxWrpFmDev->fmRtcMemSize));
107629 + if (unlikely(p_LnxWrpFmDev->fmRtcBaseAddr == 0))
107630 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("devm_ioremap() failed"));
107631 +
107632 + if (SYS_RegisterIoMap((uint64_t)p_LnxWrpFmDev->fmRtcBaseAddr, (uint64_t)p_LnxWrpFmDev->fmRtcPhysBaseAddr, p_LnxWrpFmDev->fmRtcMemSize) != E_OK)
107633 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("FM-RTC memory map"));
107634 + }
107635 +
107636 +#if (DPAA_VERSION >= 11)
107637 + if (p_LnxWrpFmDev->fmVspPhysBaseAddr) {
107638 + dev_res = __devm_request_region(p_LnxWrpFmDev->dev, p_LnxWrpFmDev->res, p_LnxWrpFmDev->fmVspPhysBaseAddr, p_LnxWrpFmDev->fmVspMemSize, "fman-vsp");
107639 + if (unlikely(dev_res == NULL))
107640 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("__devm_request_region() failed"));
107641 +
107642 + p_LnxWrpFmDev->fmVspBaseAddr = PTR_TO_UINT(devm_ioremap(p_LnxWrpFmDev->dev, p_LnxWrpFmDev->fmVspPhysBaseAddr, p_LnxWrpFmDev->fmVspMemSize));
107643 + if (unlikely(p_LnxWrpFmDev->fmVspBaseAddr == 0))
107644 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("devm_ioremap() failed"));
107645 + }
107646 +#endif
107647 +
107648 + p_LnxWrpFmDev->fmDevSettings.param.baseAddr = p_LnxWrpFmDev->fmBaseAddr;
107649 + p_LnxWrpFmDev->fmDevSettings.param.fmId = p_LnxWrpFmDev->id;
107650 + p_LnxWrpFmDev->fmDevSettings.param.irq = NO_IRQ;
107651 + p_LnxWrpFmDev->fmDevSettings.param.errIrq = NO_IRQ;
107652 + p_LnxWrpFmDev->fmDevSettings.param.f_Exception = LnxwrpFmDevExceptionsCb;
107653 + p_LnxWrpFmDev->fmDevSettings.param.f_BusError = LnxwrpFmDevBusErrorCb;
107654 + p_LnxWrpFmDev->fmDevSettings.param.h_App = p_LnxWrpFmDev;
107655 +
107656 + return FillRestFmInfo(p_LnxWrpFmDev);
107657 +}
107658 +
107659 +#ifndef CONFIG_FMAN_ARM
107660 +/*
107661 + * Table for matching compatible strings, for device tree
107662 + * guts node, for QorIQ SOCs.
107663 + * "fsl,qoriq-device-config-2.0" corresponds to T4 & B4
107664 + * SOCs. For the older SOCs "fsl,qoriq-device-config-1.0"
107665 + * string would be used.
107666 +*/
107667 +static const struct of_device_id guts_device_ids[] = {
107668 + { .compatible = "fsl,qoriq-device-config-1.0", },
107669 + { .compatible = "fsl,qoriq-device-config-2.0", },
107670 + {}
107671 +};
107672 +
107673 +static unsigned int get_rcwsr(int regnum)
107674 +{
107675 + struct ccsr_guts __iomem *guts_regs = NULL;
107676 + struct device_node *guts_node;
107677 +
107678 + guts_node = of_find_matching_node(NULL, guts_device_ids);
107679 + if (!guts_node) {
107680 + pr_err("could not find GUTS node\n");
107681 + return 0;
107682 + }
107683 + guts_regs = of_iomap(guts_node, 0);
107684 + of_node_put(guts_node);
107685 + if (!guts_regs) {
107686 + pr_err("ioremap of GUTS node failed\n");
107687 + return 0;
107688 + }
107689 +
107690 + return ioread32be(&guts_regs->rcwsr[regnum]);
107691 +}
107692 +
107693 +#define FMAN1_ALL_MACS_MASK 0xFCC00000
107694 +#define FMAN2_ALL_MACS_MASK 0x000FCC00
107695 +
107696 +/**
107697 + * @Function ResetOnInitErrata_A007273
107698 + *
107699 + * @Description Workaround for Errata A-007273
107700 + * This workaround is required to avoid a FMan hang during reset on initialization.
107701 + * Enable all MACs in guts.devdisr2 register,
107702 + * then perform a regular FMan reset and then restore MACs to their original state.
107703 + *
107704 + * @Param[in] h_Fm - FM module descriptor
107705 + *
107706 + * @Return None.
107707 + */
107708 +void ResetOnInitErrata_A007273(t_Handle h_Fm)
107709 +{
107710 + struct ccsr_guts __iomem *guts_regs = NULL;
107711 + struct device_node *guts_node;
107712 + u32 devdisr2, enableMacs;
107713 +
107714 + /* Get guts registers */
107715 + guts_node = of_find_matching_node(NULL, guts_device_ids);
107716 + if (!guts_node) {
107717 + pr_err("could not find GUTS node\n");
107718 + return;
107719 + }
107720 + guts_regs = of_iomap(guts_node, 0);
107721 + of_node_put(guts_node);
107722 + if (!guts_regs) {
107723 + pr_err("ioremap of GUTS node failed\n");
107724 + return;
107725 + }
107726 +
107727 + /* Read current state */
107728 + devdisr2 = ioread32be(&guts_regs->devdisr2);
107729 +
107730 + if (FmGetId(h_Fm) == 0)
107731 + enableMacs = devdisr2 & ~FMAN1_ALL_MACS_MASK;
107732 + else
107733 + enableMacs = devdisr2 & ~FMAN2_ALL_MACS_MASK;
107734 +
107735 + /* Enable all MACs */
107736 + iowrite32be(enableMacs, &guts_regs->devdisr2);
107737 +
107738 + /* Perform standard FMan reset */
107739 + FmReset(h_Fm);
107740 +
107741 + /* Restore devdisr2 value */
107742 + iowrite32be(devdisr2, &guts_regs->devdisr2);
107743 +
107744 + iounmap(guts_regs);
107745 +}
107746 +#endif
107747 +
107748 +static t_Error InitFmDev(t_LnxWrpFmDev *p_LnxWrpFmDev)
107749 +{
107750 + const struct qe_firmware *fw;
107751 +
107752 + if (!p_LnxWrpFmDev->active)
107753 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("FM not configured!!!"));
107754 +
107755 + if ((p_LnxWrpFmDev->h_MuramDev = FM_MURAM_ConfigAndInit(p_LnxWrpFmDev->fmMuramBaseAddr, p_LnxWrpFmDev->fmMuramMemSize)) == NULL)
107756 + RETURN_ERROR(MAJOR, E_INVALID_HANDLE, ("FM-MURAM!"));
107757 +
107758 + /* Loading the fman-controller code */
107759 + fw = FindFmanMicrocode();
107760 +
107761 + if (!fw) {
107762 + /* this forces the reuse of the current IRAM content */
107763 + p_LnxWrpFmDev->fmDevSettings.param.firmware.size = 0;
107764 + p_LnxWrpFmDev->fmDevSettings.param.firmware.p_Code = NULL;
107765 + } else {
107766 + p_LnxWrpFmDev->fmDevSettings.param.firmware.p_Code =
107767 + (void *) fw + be32_to_cpu(fw->microcode[0].code_offset);
107768 + p_LnxWrpFmDev->fmDevSettings.param.firmware.size =
107769 + sizeof(u32) * be32_to_cpu(fw->microcode[0].count);
107770 + DBG(INFO, ("Loading fman-controller code version %d.%d.%d",
107771 + fw->microcode[0].major,
107772 + fw->microcode[0].minor,
107773 + fw->microcode[0].revision));
107774 + }
107775 +
107776 +#ifdef CONFIG_FMAN_ARM
107777 + { /* endianness adjustments: byteswap the ucode retrieved from the f/w blob */
107778 + int i;
107779 + int usz = p_LnxWrpFmDev->fmDevSettings.param.firmware.size;
107780 + void * p_Code = p_LnxWrpFmDev->fmDevSettings.param.firmware.p_Code;
107781 + u32 *dest = kzalloc(usz, GFP_KERNEL);
107782 +
107783 + if (p_Code && dest)
107784 + for(i=0; i < usz / 4; ++i)
107785 + dest[i] = be32_to_cpu(((u32 *)p_Code)[i]);
107786 +
107787 + p_LnxWrpFmDev->fmDevSettings.param.firmware.p_Code = dest;
107788 + }
107789 +#endif
107790 +
107791 + p_LnxWrpFmDev->fmDevSettings.param.h_FmMuram = p_LnxWrpFmDev->h_MuramDev;
107792 +
107793 +#if (DPAA_VERSION >= 11)
107794 + if (p_LnxWrpFmDev->fmVspBaseAddr) {
107795 + p_LnxWrpFmDev->fmDevSettings.param.vspBaseAddr = p_LnxWrpFmDev->fmVspBaseAddr;
107796 + p_LnxWrpFmDev->fmDevSettings.param.partVSPBase = 0;
107797 + p_LnxWrpFmDev->fmDevSettings.param.partNumOfVSPs = FM_VSP_MAX_NUM_OF_ENTRIES;
107798 + }
107799 +#endif
107800 +
107801 +#ifdef CONFIG_FMAN_ARM
107802 + p_LnxWrpFmDev->fmDevSettings.param.fmMacClkRatio = 1;
107803 +#else
107804 + if(p_LnxWrpFmDev->fmDevSettings.param.fmId == 0)
107805 + p_LnxWrpFmDev->fmDevSettings.param.fmMacClkRatio =
107806 + !!(get_rcwsr(4) & 0x2); /* RCW[FM_MAC_RAT0] */
107807 + else
107808 + p_LnxWrpFmDev->fmDevSettings.param.fmMacClkRatio =
107809 + !!(get_rcwsr(4) & 0x1); /* RCW[FM_MAC_RAT1] */
107810 +
107811 + {
107812 + /* T4 Devices ClkRatio is always 1 regardless of RCW[FM_MAC_RAT1] */
107813 + uint32_t svr;
107814 + svr = mfspr(SPRN_SVR);
107815 +
107816 + if ((svr & SVR_DEVICE_ID_MASK) == SVR_T4_DEVICE_ID)
107817 + p_LnxWrpFmDev->fmDevSettings.param.fmMacClkRatio = 1;
107818 + }
107819 +#endif /* CONFIG_FMAN_ARM */
107820 +
107821 + if ((p_LnxWrpFmDev->h_Dev = FM_Config(&p_LnxWrpFmDev->fmDevSettings.param)) == NULL)
107822 + RETURN_ERROR(MAJOR, E_INVALID_HANDLE, ("FM"));
107823 +
107824 +
107825 + if (FM_ConfigResetOnInit(p_LnxWrpFmDev->h_Dev, TRUE) != E_OK)
107826 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("FM"));
107827 +
107828 +#ifndef CONFIG_FMAN_ARM
107829 +#ifdef FM_HANG_AT_RESET_MAC_CLK_DISABLED_ERRATA_FMAN_A007273
107830 + if (FM_ConfigResetOnInitOverrideCallback(p_LnxWrpFmDev->h_Dev, ResetOnInitErrata_A007273) != E_OK)
107831 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("FM"));
107832 +#endif /* FM_HANG_AT_RESET_MAC_CLK_DISABLED_ERRATA_FMAN_A007273 */
107833 +#endif /* CONFIG_FMAN_ARM */
107834 +
107835 +#ifdef CONFIG_FMAN_P1023
107836 + if (FM_ConfigDmaAidOverride(p_LnxWrpFmDev->h_Dev, TRUE) != E_OK)
107837 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("FM"));
107838 +#endif
107839 +
107840 +
107841 + CheckNConfigFmAdvArgs(p_LnxWrpFmDev);
107842 +
107843 + if (FM_Init(p_LnxWrpFmDev->h_Dev) != E_OK)
107844 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("FM"));
107845 +
107846 + /* TODO: Why we mask these interrupts? */
107847 + if (p_LnxWrpFmDev->err_irq == 0) {
107848 + FM_SetException(p_LnxWrpFmDev->h_Dev, e_FM_EX_DMA_BUS_ERROR,FALSE);
107849 + FM_SetException(p_LnxWrpFmDev->h_Dev,e_FM_EX_DMA_READ_ECC,FALSE);
107850 + FM_SetException(p_LnxWrpFmDev->h_Dev,e_FM_EX_DMA_SYSTEM_WRITE_ECC,FALSE);
107851 + FM_SetException(p_LnxWrpFmDev->h_Dev,e_FM_EX_DMA_FM_WRITE_ECC,FALSE);
107852 + FM_SetException(p_LnxWrpFmDev->h_Dev,e_FM_EX_DMA_SINGLE_PORT_ECC, FALSE);
107853 + FM_SetException(p_LnxWrpFmDev->h_Dev,e_FM_EX_FPM_STALL_ON_TASKS , FALSE);
107854 + FM_SetException(p_LnxWrpFmDev->h_Dev,e_FM_EX_FPM_SINGLE_ECC, FALSE);
107855 + FM_SetException(p_LnxWrpFmDev->h_Dev,e_FM_EX_FPM_DOUBLE_ECC,FALSE);
107856 + FM_SetException(p_LnxWrpFmDev->h_Dev,e_FM_EX_QMI_SINGLE_ECC, FALSE);
107857 + FM_SetException(p_LnxWrpFmDev->h_Dev,e_FM_EX_QMI_DOUBLE_ECC,FALSE);
107858 + FM_SetException(p_LnxWrpFmDev->h_Dev,e_FM_EX_QMI_DEQ_FROM_UNKNOWN_PORTID,FALSE);
107859 + FM_SetException(p_LnxWrpFmDev->h_Dev,e_FM_EX_BMI_LIST_RAM_ECC,FALSE);
107860 + FM_SetException(p_LnxWrpFmDev->h_Dev,e_FM_EX_BMI_STORAGE_PROFILE_ECC, FALSE);
107861 + FM_SetException(p_LnxWrpFmDev->h_Dev,e_FM_EX_BMI_STATISTICS_RAM_ECC, FALSE);
107862 + FM_SetException(p_LnxWrpFmDev->h_Dev,e_FM_EX_BMI_DISPATCH_RAM_ECC, FALSE);
107863 + FM_SetException(p_LnxWrpFmDev->h_Dev,e_FM_EX_IRAM_ECC,FALSE);
107864 + /* TODO: FmDisableRamsEcc assert for ramsEccOwners.
107865 + * FM_SetException(p_LnxWrpFmDev->h_Dev,e_FM_EX_MURAM_ECC,FALSE);*/
107866 + }
107867 +
107868 + if (p_LnxWrpFmDev->fmRtcBaseAddr)
107869 + {
107870 + t_FmRtcParams fmRtcParam;
107871 +
107872 + memset(&fmRtcParam, 0, sizeof(fmRtcParam));
107873 + fmRtcParam.h_App = p_LnxWrpFmDev;
107874 + fmRtcParam.h_Fm = p_LnxWrpFmDev->h_Dev;
107875 + fmRtcParam.baseAddress = p_LnxWrpFmDev->fmRtcBaseAddr;
107876 +
107877 + if(!(p_LnxWrpFmDev->h_RtcDev = FM_RTC_Config(&fmRtcParam)))
107878 + RETURN_ERROR(MAJOR, E_INVALID_HANDLE, ("FM-RTC"));
107879 +
107880 + if (FM_RTC_ConfigPeriod(p_LnxWrpFmDev->h_RtcDev, DPA_PTP_NOMINAL_FREQ_PERIOD_NS) != E_OK)
107881 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("FM-RTC"));
107882 +
107883 + if (FM_RTC_Init(p_LnxWrpFmDev->h_RtcDev) != E_OK)
107884 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("FM-RTC"));
107885 + }
107886 +
107887 + return E_OK;
107888 +}
107889 +
107890 +/* TODO: to be moved back here */
107891 +extern void FreeFmPcdDev(t_LnxWrpFmDev *p_LnxWrpFmDev);
107892 +
107893 +static void FreeFmDev(t_LnxWrpFmDev *p_LnxWrpFmDev)
107894 +{
107895 + if (!p_LnxWrpFmDev->active)
107896 + return;
107897 +
107898 + FreeFmPcdDev(p_LnxWrpFmDev);
107899 +
107900 + if (p_LnxWrpFmDev->h_RtcDev)
107901 + FM_RTC_Free(p_LnxWrpFmDev->h_RtcDev);
107902 +
107903 + if (p_LnxWrpFmDev->h_Dev)
107904 + FM_Free(p_LnxWrpFmDev->h_Dev);
107905 +
107906 + if (p_LnxWrpFmDev->h_MuramDev)
107907 + FM_MURAM_Free(p_LnxWrpFmDev->h_MuramDev);
107908 +
107909 + if (p_LnxWrpFmDev->fmRtcBaseAddr)
107910 + {
107911 + SYS_UnregisterIoMap(p_LnxWrpFmDev->fmRtcBaseAddr);
107912 + devm_iounmap(p_LnxWrpFmDev->dev, UINT_TO_PTR(p_LnxWrpFmDev->fmRtcBaseAddr));
107913 + __devm_release_region(p_LnxWrpFmDev->dev, p_LnxWrpFmDev->res, p_LnxWrpFmDev->fmRtcPhysBaseAddr, p_LnxWrpFmDev->fmRtcMemSize);
107914 + }
107915 + SYS_UnregisterIoMap(p_LnxWrpFmDev->fmMuramBaseAddr);
107916 + devm_iounmap(p_LnxWrpFmDev->dev, UINT_TO_PTR(p_LnxWrpFmDev->fmMuramBaseAddr));
107917 + __devm_release_region(p_LnxWrpFmDev->dev, p_LnxWrpFmDev->res, p_LnxWrpFmDev->fmMuramPhysBaseAddr, p_LnxWrpFmDev->fmMuramMemSize);
107918 + SYS_UnregisterIoMap(p_LnxWrpFmDev->fmBaseAddr);
107919 + devm_iounmap(p_LnxWrpFmDev->dev, UINT_TO_PTR(p_LnxWrpFmDev->fmBaseAddr));
107920 + devm_release_mem_region(p_LnxWrpFmDev->dev, p_LnxWrpFmDev->fmPhysBaseAddr, p_LnxWrpFmDev->fmMemSize);
107921 + if (p_LnxWrpFmDev->err_irq != 0) {
107922 + devm_free_irq(p_LnxWrpFmDev->dev, p_LnxWrpFmDev->err_irq, p_LnxWrpFmDev);
107923 + }
107924 +
107925 + devm_free_irq(p_LnxWrpFmDev->dev, p_LnxWrpFmDev->irq, p_LnxWrpFmDev);
107926 +}
107927 +
107928 +/* FMan character device file operations */
107929 +extern struct file_operations fm_fops;
107930 +
107931 +static int /*__devinit*/ fm_probe(struct platform_device *of_dev)
107932 +{
107933 + t_LnxWrpFmDev *p_LnxWrpFmDev;
107934 +
107935 + if ((p_LnxWrpFmDev = ReadFmDevTreeNode(of_dev)) == NULL)
107936 + return -EIO;
107937 + if (ConfigureFmDev(p_LnxWrpFmDev) != E_OK)
107938 + return -EIO;
107939 + if (InitFmDev(p_LnxWrpFmDev) != E_OK)
107940 + return -EIO;
107941 +
107942 + /* IOCTL ABI checking */
107943 + LnxWrpPCDIOCTLEnumChecking();
107944 + LnxWrpPCDIOCTLTypeChecking();
107945 +
107946 + Sprint (p_LnxWrpFmDev->name, "%s%d", DEV_FM_NAME, p_LnxWrpFmDev->id);
107947 +
107948 + /* Register to the /dev for IOCTL API */
107949 + /* Register dynamically a new major number for the character device: */
107950 + if ((p_LnxWrpFmDev->major = register_chrdev(0, p_LnxWrpFmDev->name, &fm_fops)) <= 0) {
107951 + REPORT_ERROR(MAJOR, E_INVALID_STATE, ("Failed to allocate a major number for device \"%s\"", p_LnxWrpFmDev->name));
107952 + return -EIO;
107953 + }
107954 +
107955 + /* Creating classes for FM */
107956 + DBG(TRACE ,("class_create fm_class"));
107957 + p_LnxWrpFmDev->fm_class = class_create(THIS_MODULE, p_LnxWrpFmDev->name);
107958 + if (IS_ERR(p_LnxWrpFmDev->fm_class)) {
107959 + unregister_chrdev(p_LnxWrpFmDev->major, p_LnxWrpFmDev->name);
107960 + REPORT_ERROR(MAJOR, E_INVALID_STATE, ("class_create error fm_class"));
107961 + return -EIO;
107962 + }
107963 +
107964 + device_create(p_LnxWrpFmDev->fm_class, NULL, MKDEV(p_LnxWrpFmDev->major, DEV_FM_MINOR_BASE), NULL,
107965 + "fm%d", p_LnxWrpFmDev->id);
107966 + device_create(p_LnxWrpFmDev->fm_class, NULL, MKDEV(p_LnxWrpFmDev->major, DEV_FM_PCD_MINOR_BASE), NULL,
107967 + "fm%d-pcd", p_LnxWrpFmDev->id);
107968 + dev_set_drvdata(p_LnxWrpFmDev->dev, p_LnxWrpFmDev);
107969 +
107970 + /* create sysfs entries for stats and regs */
107971 + if ( fm_sysfs_create(p_LnxWrpFmDev->dev) !=0 )
107972 + {
107973 + FreeFmDev(p_LnxWrpFmDev);
107974 + REPORT_ERROR(MAJOR, E_INVALID_STATE, ("Unable to create sysfs entry - fm!!!"));
107975 + return -EIO;
107976 + }
107977 +
107978 +#ifdef CONFIG_PM
107979 + device_set_wakeup_capable(p_LnxWrpFmDev->dev, true);
107980 +#endif
107981 +
107982 + DBG(TRACE, ("FM%d probed", p_LnxWrpFmDev->id));
107983 +
107984 + return 0;
107985 +}
107986 +
107987 +static int fm_remove(struct platform_device *of_dev)
107988 +{
107989 + t_LnxWrpFmDev *p_LnxWrpFmDev;
107990 + struct device *dev;
107991 +
107992 + dev = &of_dev->dev;
107993 + p_LnxWrpFmDev = dev_get_drvdata(dev);
107994 +
107995 + fm_sysfs_destroy(dev);
107996 +
107997 + DBG(TRACE, ("destroy fm_class"));
107998 + device_destroy(p_LnxWrpFmDev->fm_class, MKDEV(p_LnxWrpFmDev->major, DEV_FM_MINOR_BASE));
107999 + device_destroy(p_LnxWrpFmDev->fm_class, MKDEV(p_LnxWrpFmDev->major, DEV_FM_PCD_MINOR_BASE));
108000 + class_destroy(p_LnxWrpFmDev->fm_class);
108001 +
108002 + /* Destroy chardev */
108003 + unregister_chrdev(p_LnxWrpFmDev->major, p_LnxWrpFmDev->name);
108004 +
108005 + FreeFmDev(p_LnxWrpFmDev);
108006 +
108007 + DestroyFmDev(p_LnxWrpFmDev);
108008 +
108009 + dev_set_drvdata(dev, NULL);
108010 +
108011 + return 0;
108012 +}
108013 +
108014 +static const struct of_device_id fm_match[] = {
108015 + {
108016 + .compatible = "fsl,fman"
108017 + },
108018 + {}
108019 +};
108020 +#ifndef MODULE
108021 +MODULE_DEVICE_TABLE(of, fm_match);
108022 +#endif /* !MODULE */
108023 +
108024 +#ifdef CONFIG_PM
108025 +
108026 +#define SCFG_FMCLKDPSLPCR_ADDR 0xFFE0FC00C
108027 +#define SCFG_FMCLKDPSLPCR_DS_VAL 0x48402000
108028 +#define SCFG_FMCLKDPSLPCR_NORMAL_VAL 0x00402000
108029 +
108030 +struct device *g_fm_dev;
108031 +
108032 +static int fm_soc_suspend(struct device *dev)
108033 +{
108034 + int err = 0;
108035 + uint32_t *fmclk;
108036 + t_LnxWrpFmDev *p_LnxWrpFmDev = dev_get_drvdata(get_device(dev));
108037 + g_fm_dev = dev;
108038 + fmclk = ioremap(SCFG_FMCLKDPSLPCR_ADDR, 4);
108039 + WRITE_UINT32(*fmclk, SCFG_FMCLKDPSLPCR_DS_VAL);
108040 + if (p_LnxWrpFmDev->h_DsarRxPort)
108041 + {
108042 +#ifdef CONFIG_FSL_QORIQ_PM
108043 + device_set_wakeup_enable(p_LnxWrpFmDev->dev, 1);
108044 +#endif
108045 + err = FM_PORT_EnterDsarFinal(p_LnxWrpFmDev->h_DsarRxPort,
108046 + p_LnxWrpFmDev->h_DsarTxPort);
108047 + }
108048 + return err;
108049 +}
108050 +
108051 +static int fm_soc_resume(struct device *dev)
108052 +{
108053 + t_LnxWrpFmDev *p_LnxWrpFmDev = dev_get_drvdata(get_device(dev));
108054 + uint32_t *fmclk;
108055 + fmclk = ioremap(SCFG_FMCLKDPSLPCR_ADDR, 4);
108056 + WRITE_UINT32(*fmclk, SCFG_FMCLKDPSLPCR_NORMAL_VAL);
108057 + if (p_LnxWrpFmDev->h_DsarRxPort)
108058 + {
108059 +#ifdef CONFIG_FSL_QORIQ_PM
108060 + device_set_wakeup_enable(p_LnxWrpFmDev->dev, 0);
108061 +#endif
108062 + FM_PORT_ExitDsar(p_LnxWrpFmDev->h_DsarRxPort,
108063 + p_LnxWrpFmDev->h_DsarTxPort);
108064 + p_LnxWrpFmDev->h_DsarRxPort = 0;
108065 + p_LnxWrpFmDev->h_DsarTxPort = 0;
108066 + }
108067 + return 0;
108068 +}
108069 +
108070 +static const struct dev_pm_ops fm_pm_ops = {
108071 + .suspend = fm_soc_suspend,
108072 + .resume = fm_soc_resume,
108073 +};
108074 +
108075 +#define FM_PM_OPS (&fm_pm_ops)
108076 +
108077 +#else /* CONFIG_PM */
108078 +
108079 +#define FM_PM_OPS NULL
108080 +
108081 +#endif /* CONFIG_PM */
108082 +
108083 +static struct platform_driver fm_driver = {
108084 + .driver = {
108085 + .name = "fsl-fman",
108086 + .of_match_table = fm_match,
108087 + .owner = THIS_MODULE,
108088 + .pm = FM_PM_OPS,
108089 + },
108090 + .probe = fm_probe,
108091 + .remove = fm_remove
108092 +};
108093 +
108094 +t_Handle LNXWRP_FM_Init(void)
108095 +{
108096 + memset(&lnxWrpFm, 0, sizeof(lnxWrpFm));
108097 + mutex_init(&lnxwrp_mutex);
108098 +
108099 + /* Register to the DTB for basic FM API */
108100 + platform_driver_register(&fm_driver);
108101 +
108102 + return &lnxWrpFm;
108103 +}
108104 +
108105 +t_Error LNXWRP_FM_Free(t_Handle h_LnxWrpFm)
108106 +{
108107 + platform_driver_unregister(&fm_driver);
108108 + mutex_destroy(&lnxwrp_mutex);
108109 +
108110 + return E_OK;
108111 +}
108112 +
108113 +
108114 +struct fm * fm_bind(struct device *fm_dev)
108115 +{
108116 + return (struct fm *)(dev_get_drvdata(get_device(fm_dev)));
108117 +}
108118 +EXPORT_SYMBOL(fm_bind);
108119 +
108120 +void fm_unbind(struct fm *fm)
108121 +{
108122 + t_LnxWrpFmDev *p_LnxWrpFmDev = (t_LnxWrpFmDev*)fm;
108123 +
108124 + put_device(p_LnxWrpFmDev->dev);
108125 +}
108126 +EXPORT_SYMBOL(fm_unbind);
108127 +
108128 +struct resource * fm_get_mem_region(struct fm *fm)
108129 +{
108130 + t_LnxWrpFmDev *p_LnxWrpFmDev = (t_LnxWrpFmDev*)fm;
108131 +
108132 + return p_LnxWrpFmDev->res;
108133 +}
108134 +EXPORT_SYMBOL(fm_get_mem_region);
108135 +
108136 +void * fm_get_handle(struct fm *fm)
108137 +{
108138 + t_LnxWrpFmDev *p_LnxWrpFmDev = (t_LnxWrpFmDev*)fm;
108139 +
108140 + return (void *)p_LnxWrpFmDev->h_Dev;
108141 +}
108142 +EXPORT_SYMBOL(fm_get_handle);
108143 +
108144 +void * fm_get_rtc_handle(struct fm *fm)
108145 +{
108146 + t_LnxWrpFmDev *p_LnxWrpFmDev = (t_LnxWrpFmDev*)fm;
108147 +
108148 + return (void *)p_LnxWrpFmDev->h_RtcDev;
108149 +}
108150 +EXPORT_SYMBOL(fm_get_rtc_handle);
108151 +
108152 +struct fm_port * fm_port_bind (struct device *fm_port_dev)
108153 +{
108154 + return (struct fm_port *)(dev_get_drvdata(get_device(fm_port_dev)));
108155 +}
108156 +EXPORT_SYMBOL(fm_port_bind);
108157 +
108158 +void fm_port_unbind(struct fm_port *port)
108159 +{
108160 + t_LnxWrpFmPortDev *p_LnxWrpFmPortDev = (t_LnxWrpFmPortDev*)port;
108161 +
108162 + put_device(p_LnxWrpFmPortDev->dev);
108163 +}
108164 +EXPORT_SYMBOL(fm_port_unbind);
108165 +
108166 +void *fm_port_get_handle(const struct fm_port *port)
108167 +{
108168 + t_LnxWrpFmPortDev *p_LnxWrpFmPortDev = (t_LnxWrpFmPortDev*)port;
108169 +
108170 + return (void *)p_LnxWrpFmPortDev->h_Dev;
108171 +}
108172 +EXPORT_SYMBOL(fm_port_get_handle);
108173 +
108174 +u64 *fm_port_get_buffer_time_stamp(const struct fm_port *port,
108175 + const void *data)
108176 +{
108177 + return FM_PORT_GetBufferTimeStamp(fm_port_get_handle(port),
108178 + (void *)data);
108179 +}
108180 +EXPORT_SYMBOL(fm_port_get_buffer_time_stamp);
108181 +
108182 +void fm_port_get_base_addr(const struct fm_port *port, uint64_t *base_addr)
108183 +{
108184 + t_LnxWrpFmPortDev *p_LnxWrpFmPortDev = (t_LnxWrpFmPortDev *)port;
108185 +
108186 + *base_addr = p_LnxWrpFmPortDev->settings.param.baseAddr;
108187 +}
108188 +EXPORT_SYMBOL(fm_port_get_base_addr);
108189 +
108190 +void fm_port_pcd_bind (struct fm_port *port, struct fm_port_pcd_param *params)
108191 +{
108192 + t_LnxWrpFmPortDev *p_LnxWrpFmPortDev = (t_LnxWrpFmPortDev*)port;
108193 +
108194 + p_LnxWrpFmPortDev->pcd_owner_params.cba = params->cba;
108195 + p_LnxWrpFmPortDev->pcd_owner_params.cbf = params->cbf;
108196 + p_LnxWrpFmPortDev->pcd_owner_params.dev = params->dev;
108197 +}
108198 +EXPORT_SYMBOL(fm_port_pcd_bind);
108199 +
108200 +void fm_port_get_buff_layout_ext_params(struct fm_port *port, struct fm_port_params *params)
108201 +{
108202 + t_LnxWrpFmPortDev *p_LnxWrpFmPortDev = (t_LnxWrpFmPortDev *)port;
108203 + struct device_node *fm_node, *port_node;
108204 + const uint32_t *uint32_prop;
108205 + int lenp;
108206 +
108207 + params->data_align = 0;
108208 + params->manip_extra_space = 0;
108209 +
108210 + fm_node = GetFmAdvArgsDevTreeNode(((t_LnxWrpFmDev *) p_LnxWrpFmPortDev->h_LnxWrpFmDev)->id);
108211 + if (!fm_node) /* no advance parameters for FMan */
108212 + return;
108213 +
108214 + port_node = GetFmPortAdvArgsDevTreeNode(fm_node,
108215 + p_LnxWrpFmPortDev->settings.param.portType,
108216 + p_LnxWrpFmPortDev->settings.param.portId);
108217 + if (!port_node) /* no advance parameters for FMan-Port */
108218 + return;
108219 +
108220 + uint32_prop = (uint32_t *)of_get_property(port_node, "buffer-layout", &lenp);
108221 + if (uint32_prop) {
108222 + if (WARN_ON(lenp != sizeof(uint32_t)*2))
108223 + return;
108224 +
108225 + params->manip_extra_space = (uint8_t)be32_to_cpu(uint32_prop[0]);
108226 + params->data_align = (uint16_t)be32_to_cpu(uint32_prop[1]);
108227 + }
108228 +
108229 + of_node_put(port_node);
108230 + of_node_put(fm_node);
108231 +}
108232 +EXPORT_SYMBOL(fm_port_get_buff_layout_ext_params);
108233 +
108234 +uint16_t fm_get_tx_port_channel(struct fm_port *port)
108235 +{
108236 + t_LnxWrpFmPortDev *p_LnxWrpFmPortDev = (t_LnxWrpFmPortDev*)port;
108237 +
108238 + return p_LnxWrpFmPortDev->txCh;
108239 +}
108240 +EXPORT_SYMBOL(fm_get_tx_port_channel);
108241 +
108242 +int fm_port_enable (struct fm_port *port)
108243 +{
108244 + t_LnxWrpFmPortDev *p_LnxWrpFmPortDev = (t_LnxWrpFmPortDev*)port;
108245 + t_Error err = FM_PORT_Enable(p_LnxWrpFmPortDev->h_Dev);
108246 +
108247 + return GET_ERROR_TYPE(err);
108248 +}
108249 +EXPORT_SYMBOL(fm_port_enable);
108250 +
108251 +int fm_port_disable(struct fm_port *port)
108252 +{
108253 + t_LnxWrpFmPortDev *p_LnxWrpFmPortDev = (t_LnxWrpFmPortDev*)port;
108254 + t_Error err = FM_PORT_Disable(p_LnxWrpFmPortDev->h_Dev);
108255 +
108256 + return GET_ERROR_TYPE(err);
108257 +}
108258 +EXPORT_SYMBOL(fm_port_disable);
108259 +
108260 +int fm_port_set_rate_limit(struct fm_port *port,
108261 + uint16_t max_burst_size,
108262 + uint32_t rate_limit)
108263 +{
108264 + t_FmPortRateLimit param;
108265 + t_LnxWrpFmPortDev *p_LnxWrpFmPortDev = (t_LnxWrpFmPortDev *)port;
108266 + int err = 0;
108267 +
108268 + param.maxBurstSize = max_burst_size;
108269 + param.rateLimit = rate_limit;
108270 + param.rateLimitDivider = 0;
108271 +
108272 + err = FM_PORT_SetRateLimit(p_LnxWrpFmPortDev->h_Dev, &param);
108273 + return err;
108274 +}
108275 +EXPORT_SYMBOL(fm_port_set_rate_limit);
108276 +
108277 +int fm_port_del_rate_limit(struct fm_port *port)
108278 +{
108279 + t_LnxWrpFmPortDev *p_LnxWrpFmPortDev = (t_LnxWrpFmPortDev *)port;
108280 +
108281 + FM_PORT_DeleteRateLimit(p_LnxWrpFmPortDev->h_Dev);
108282 + return 0;
108283 +}
108284 +EXPORT_SYMBOL(fm_port_del_rate_limit);
108285 +
108286 +void FM_PORT_Dsar_DumpRegs(void);
108287 +int ar_showmem(struct file *file, const char __user *buffer,
108288 + unsigned long count, void *data)
108289 +{
108290 + FM_PORT_Dsar_DumpRegs();
108291 + return 2;
108292 +}
108293 +
108294 +struct auto_res_tables_sizes *fm_port_get_autores_maxsize(
108295 + struct fm_port *port)
108296 +{
108297 + t_LnxWrpFmPortDev *p_LnxWrpFmPortDev = (t_LnxWrpFmPortDev *)port;
108298 + return &p_LnxWrpFmPortDev->dsar_table_sizes;
108299 +}
108300 +EXPORT_SYMBOL(fm_port_get_autores_maxsize);
108301 +
108302 +int fm_port_enter_autores_for_deepsleep(struct fm_port *port,
108303 + struct auto_res_port_params *params)
108304 +{
108305 + t_LnxWrpFmPortDev *p_LnxWrpFmPortDev = (t_LnxWrpFmPortDev *)port;
108306 + t_LnxWrpFmDev* p_LnxWrpFmDev = (t_LnxWrpFmDev*)p_LnxWrpFmPortDev->h_LnxWrpFmDev;
108307 + p_LnxWrpFmDev->h_DsarRxPort = p_LnxWrpFmPortDev->h_Dev;
108308 + p_LnxWrpFmDev->h_DsarTxPort = params->h_FmPortTx;
108309 +
108310 + /*Register other under /proc/autoresponse */
108311 + if (WARN_ON(sizeof(t_FmPortDsarParams) != sizeof(struct auto_res_port_params)))
108312 + return -EFAULT;
108313 +
108314 + FM_PORT_EnterDsar(p_LnxWrpFmPortDev->h_Dev, (t_FmPortDsarParams*)params);
108315 + return 0;
108316 +}
108317 +EXPORT_SYMBOL(fm_port_enter_autores_for_deepsleep);
108318 +
108319 +void fm_port_exit_auto_res_for_deep_sleep(struct fm_port *port_rx,
108320 + struct fm_port *port_tx)
108321 +{
108322 +}
108323 +EXPORT_SYMBOL(fm_port_exit_auto_res_for_deep_sleep);
108324 +
108325 +int fm_port_get_autores_stats(struct fm_port *port,
108326 + struct auto_res_port_stats *stats)
108327 +{
108328 + t_LnxWrpFmPortDev *p_LnxWrpFmPortDev = (t_LnxWrpFmPortDev *)port;
108329 + if (WARN_ON(sizeof(t_FmPortDsarStats) != sizeof(struct auto_res_port_stats)))
108330 + return -EFAULT;
108331 + return FM_PORT_GetDsarStats(p_LnxWrpFmPortDev->h_Dev, (t_FmPortDsarStats*)stats);
108332 +}
108333 +EXPORT_SYMBOL(fm_port_get_autores_stats);
108334 +
108335 +int fm_port_suspend(struct fm_port *port)
108336 +{
108337 + t_LnxWrpFmPortDev *p_LnxWrpFmPortDev = (t_LnxWrpFmPortDev *)port;
108338 + if (!FM_PORT_IsInDsar(p_LnxWrpFmPortDev->h_Dev))
108339 + return FM_PORT_Disable(p_LnxWrpFmPortDev->h_Dev);
108340 + else
108341 + return 0;
108342 +}
108343 +EXPORT_SYMBOL(fm_port_suspend);
108344 +
108345 +int fm_port_resume(struct fm_port *port)
108346 +{
108347 + t_LnxWrpFmPortDev *p_LnxWrpFmPortDev = (t_LnxWrpFmPortDev *)port;
108348 + if (!FM_PORT_IsInDsar(p_LnxWrpFmPortDev->h_Dev))
108349 + return FM_PORT_Enable(p_LnxWrpFmPortDev->h_Dev);
108350 + else
108351 + return 0;
108352 +}
108353 +EXPORT_SYMBOL(fm_port_resume);
108354 +
108355 +bool fm_port_is_in_auto_res_mode(struct fm_port *port)
108356 +{
108357 + return FM_PORT_IsInDsar(port);
108358 +}
108359 +EXPORT_SYMBOL(fm_port_is_in_auto_res_mode);
108360 +
108361 +#ifdef CONFIG_FMAN_PFC
108362 +int fm_port_set_pfc_priorities_mapping_to_qman_wq(struct fm_port *port,
108363 + uint8_t prio, uint8_t wq)
108364 +{
108365 + t_LnxWrpFmPortDev *p_LnxWrpFmPortDev = (t_LnxWrpFmPortDev *)port;
108366 + int err;
108367 + int _errno;
108368 +
108369 + err = FM_PORT_SetPfcPrioritiesMappingToQmanWQ(p_LnxWrpFmPortDev->h_Dev,
108370 + prio, wq);
108371 + _errno = -GET_ERROR_TYPE(err);
108372 + if (unlikely(_errno < 0))
108373 + pr_err("FM_PORT_SetPfcPrioritiesMappingToQmanWQ() = 0x%08x\n", err);
108374 +
108375 + return _errno;
108376 +}
108377 +EXPORT_SYMBOL(fm_port_set_pfc_priorities_mapping_to_qman_wq);
108378 +#endif
108379 +
108380 +int fm_mac_set_exception(struct fm_mac_dev *fm_mac_dev,
108381 + e_FmMacExceptions exception, bool enable)
108382 +{
108383 + int err;
108384 + int _errno;
108385 +
108386 + err = FM_MAC_SetException(fm_mac_dev, exception, enable);
108387 +
108388 + _errno = -GET_ERROR_TYPE(err);
108389 + if (unlikely(_errno < 0))
108390 + pr_err("FM_MAC_SetException() = 0x%08x\n", err);
108391 +
108392 + return _errno;
108393 +}
108394 +EXPORT_SYMBOL(fm_mac_set_exception);
108395 +
108396 +int fm_mac_free(struct fm_mac_dev *fm_mac_dev)
108397 +{
108398 + int err;
108399 + int _error;
108400 +
108401 + err = FM_MAC_Free(fm_mac_dev);
108402 + _error = -GET_ERROR_TYPE(err);
108403 +
108404 + if (unlikely(_error < 0))
108405 + pr_err("FM_MAC_Free() = 0x%08x\n", err);
108406 +
108407 + return _error;
108408 +}
108409 +EXPORT_SYMBOL(fm_mac_free);
108410 +
108411 +struct fm_mac_dev *fm_mac_config(t_FmMacParams *params)
108412 +{
108413 + struct fm_mac_dev *fm_mac_dev;
108414 +
108415 + fm_mac_dev = FM_MAC_Config(params);
108416 + if (unlikely(fm_mac_dev == NULL))
108417 + pr_err("FM_MAC_Config() failed\n");
108418 +
108419 + return fm_mac_dev;
108420 +}
108421 +EXPORT_SYMBOL(fm_mac_config);
108422 +
108423 +int fm_mac_config_max_frame_length(struct fm_mac_dev *fm_mac_dev,
108424 + int len)
108425 +{
108426 + int err;
108427 + int _errno;
108428 +
108429 + err = FM_MAC_ConfigMaxFrameLength(fm_mac_dev, len);
108430 + _errno = -GET_ERROR_TYPE(err);
108431 + if (unlikely(_errno < 0))
108432 + pr_err("FM_MAC_ConfigMaxFrameLength() = 0x%08x\n", err);
108433 +
108434 + return _errno;
108435 +}
108436 +EXPORT_SYMBOL(fm_mac_config_max_frame_length);
108437 +
108438 +int fm_mac_config_pad_and_crc(struct fm_mac_dev *fm_mac_dev, bool enable)
108439 +{
108440 + int err;
108441 + int _errno;
108442 +
108443 + err = FM_MAC_ConfigPadAndCrc(fm_mac_dev, enable);
108444 + _errno = -GET_ERROR_TYPE(err);
108445 + if (unlikely(_errno < 0))
108446 + pr_err("FM_MAC_ConfigPadAndCrc() = 0x%08x\n", err);
108447 +
108448 + return _errno;
108449 +}
108450 +EXPORT_SYMBOL(fm_mac_config_pad_and_crc);
108451 +
108452 +int fm_mac_config_half_duplex(struct fm_mac_dev *fm_mac_dev, bool enable)
108453 +{
108454 + int err;
108455 + int _errno;
108456 +
108457 + err = FM_MAC_ConfigHalfDuplex(fm_mac_dev, enable);
108458 + _errno = -GET_ERROR_TYPE(err);
108459 + if (unlikely(_errno < 0))
108460 + pr_err("FM_MAC_ConfigHalfDuplex() = 0x%08x\n", err);
108461 +
108462 + return _errno;
108463 +}
108464 +EXPORT_SYMBOL(fm_mac_config_half_duplex);
108465 +
108466 +int fm_mac_config_reset_on_init(struct fm_mac_dev *fm_mac_dev, bool enable)
108467 +{
108468 + int err;
108469 + int _errno;
108470 +
108471 + err = FM_MAC_ConfigResetOnInit(fm_mac_dev, enable);
108472 + _errno = -GET_ERROR_TYPE(err);
108473 + if (unlikely(_errno < 0))
108474 + pr_err("FM_MAC_ConfigResetOnInit() = 0x%08x\n", err);
108475 +
108476 + return _errno;
108477 +}
108478 +EXPORT_SYMBOL(fm_mac_config_reset_on_init);
108479 +
108480 +int fm_mac_init(struct fm_mac_dev *fm_mac_dev)
108481 +{
108482 + int err;
108483 + int _errno;
108484 +
108485 + err = FM_MAC_Init(fm_mac_dev);
108486 + _errno = -GET_ERROR_TYPE(err);
108487 + if (unlikely(_errno < 0))
108488 + pr_err("FM_MAC_Init() = 0x%08x\n", err);
108489 +
108490 + return _errno;
108491 +}
108492 +EXPORT_SYMBOL(fm_mac_init);
108493 +
108494 +int fm_mac_get_version(struct fm_mac_dev *fm_mac_dev, uint32_t *version)
108495 +{
108496 + int err;
108497 + int _errno;
108498 +
108499 + err = FM_MAC_GetVesrion(fm_mac_dev, version);
108500 + _errno = -GET_ERROR_TYPE(err);
108501 + if (unlikely(_errno < 0))
108502 + pr_err("FM_MAC_GetVesrion() = 0x%08x\n", err);
108503 +
108504 + return _errno;
108505 +}
108506 +EXPORT_SYMBOL(fm_mac_get_version);
108507 +
108508 +int fm_mac_enable(struct fm_mac_dev *fm_mac_dev)
108509 +{
108510 + int _errno;
108511 + t_Error err;
108512 +
108513 + err = FM_MAC_Enable(fm_mac_dev, e_COMM_MODE_RX_AND_TX);
108514 + _errno = -GET_ERROR_TYPE(err);
108515 + if (unlikely(_errno < 0))
108516 + pr_err("FM_MAC_Enable() = 0x%08x\n", err);
108517 +
108518 + return _errno;
108519 +}
108520 +EXPORT_SYMBOL(fm_mac_enable);
108521 +
108522 +int fm_mac_disable(struct fm_mac_dev *fm_mac_dev)
108523 +{
108524 + int _errno;
108525 + t_Error err;
108526 +
108527 + err = FM_MAC_Disable(fm_mac_dev, e_COMM_MODE_RX_AND_TX);
108528 + _errno = -GET_ERROR_TYPE(err);
108529 + if (unlikely(_errno < 0))
108530 + pr_err("FM_MAC_Disable() = 0x%08x\n", err);
108531 +
108532 + return _errno;
108533 +}
108534 +EXPORT_SYMBOL(fm_mac_disable);
108535 +
108536 +int fm_mac_resume(struct fm_mac_dev *fm_mac_dev)
108537 +{
108538 + int _errno;
108539 + t_Error err;
108540 +
108541 + err = FM_MAC_Resume(fm_mac_dev);
108542 + _errno = -GET_ERROR_TYPE(err);
108543 + if (unlikely(_errno < 0))
108544 + pr_err("FM_MAC_Resume() = 0x%08x\n", err);
108545 +
108546 + return _errno;
108547 +}
108548 +EXPORT_SYMBOL(fm_mac_resume);
108549 +
108550 +int fm_mac_set_promiscuous(struct fm_mac_dev *fm_mac_dev,
108551 + bool enable)
108552 +{
108553 + int _errno;
108554 + t_Error err;
108555 +
108556 + err = FM_MAC_SetPromiscuous(fm_mac_dev, enable);
108557 + _errno = -GET_ERROR_TYPE(err);
108558 + if (unlikely(_errno < 0))
108559 + pr_err("FM_MAC_SetPromiscuous() = 0x%08x\n", err);
108560 +
108561 + return _errno;
108562 +}
108563 +EXPORT_SYMBOL(fm_mac_set_promiscuous);
108564 +
108565 +int fm_mac_remove_hash_mac_addr(struct fm_mac_dev *fm_mac_dev,
108566 + t_EnetAddr *mac_addr)
108567 +{
108568 + int _errno;
108569 + t_Error err;
108570 +
108571 + err = FM_MAC_RemoveHashMacAddr(fm_mac_dev, mac_addr);
108572 + _errno = -GET_ERROR_TYPE(err);
108573 + if (_errno < 0) {
108574 + pr_err("FM_MAC_RemoveHashMacAddr() = 0x%08x\n", err);
108575 + return _errno;
108576 + }
108577 +
108578 + return 0;
108579 +}
108580 +EXPORT_SYMBOL(fm_mac_remove_hash_mac_addr);
108581 +
108582 +int fm_mac_add_hash_mac_addr(struct fm_mac_dev *fm_mac_dev,
108583 + t_EnetAddr *mac_addr)
108584 +{
108585 + int _errno;
108586 + t_Error err;
108587 +
108588 + err = FM_MAC_AddHashMacAddr(fm_mac_dev, mac_addr);
108589 + _errno = -GET_ERROR_TYPE(err);
108590 + if (_errno < 0) {
108591 + pr_err("FM_MAC_AddHashMacAddr() = 0x%08x\n", err);
108592 + return _errno;
108593 + }
108594 +
108595 + return 0;
108596 +}
108597 +EXPORT_SYMBOL(fm_mac_add_hash_mac_addr);
108598 +
108599 +int fm_mac_modify_mac_addr(struct fm_mac_dev *fm_mac_dev,
108600 + uint8_t *addr)
108601 +{
108602 + int _errno;
108603 + t_Error err;
108604 +
108605 + err = FM_MAC_ModifyMacAddr(fm_mac_dev, (t_EnetAddr *)addr);
108606 + _errno = -GET_ERROR_TYPE(err);
108607 + if (_errno < 0)
108608 + pr_err("FM_MAC_ModifyMacAddr() = 0x%08x\n", err);
108609 +
108610 + return _errno;
108611 +}
108612 +EXPORT_SYMBOL(fm_mac_modify_mac_addr);
108613 +
108614 +int fm_mac_adjust_link(struct fm_mac_dev *fm_mac_dev,
108615 + bool link, int speed, bool duplex)
108616 +{
108617 + int _errno;
108618 + t_Error err;
108619 +
108620 + if (!link) {
108621 +#if (DPAA_VERSION < 11)
108622 + FM_MAC_RestartAutoneg(fm_mac_dev);
108623 +#endif
108624 + return 0;
108625 + }
108626 +
108627 + err = FM_MAC_AdjustLink(fm_mac_dev, speed, duplex);
108628 + _errno = -GET_ERROR_TYPE(err);
108629 + if (unlikely(_errno < 0))
108630 + pr_err("FM_MAC_AdjustLink() = 0x%08x\n", err);
108631 +
108632 + return _errno;
108633 +}
108634 +EXPORT_SYMBOL(fm_mac_adjust_link);
108635 +
108636 +int fm_mac_enable_1588_time_stamp(struct fm_mac_dev *fm_mac_dev)
108637 +{
108638 + int _errno;
108639 + t_Error err;
108640 +
108641 + err = FM_MAC_Enable1588TimeStamp(fm_mac_dev);
108642 + _errno = -GET_ERROR_TYPE(err);
108643 + if (unlikely(_errno < 0))
108644 + pr_err("FM_MAC_Enable1588TimeStamp() = 0x%08x\n", err);
108645 + return _errno;
108646 +}
108647 +EXPORT_SYMBOL(fm_mac_enable_1588_time_stamp);
108648 +
108649 +int fm_mac_disable_1588_time_stamp(struct fm_mac_dev *fm_mac_dev)
108650 +{
108651 + int _errno;
108652 + t_Error err;
108653 +
108654 + err = FM_MAC_Disable1588TimeStamp(fm_mac_dev);
108655 + _errno = -GET_ERROR_TYPE(err);
108656 + if (unlikely(_errno < 0))
108657 + pr_err("FM_MAC_Disable1588TimeStamp() = 0x%08x\n", err);
108658 + return _errno;
108659 +}
108660 +EXPORT_SYMBOL(fm_mac_disable_1588_time_stamp);
108661 +
108662 +int fm_mac_set_rx_pause_frames(
108663 + struct fm_mac_dev *fm_mac_dev, bool en)
108664 +{
108665 + int _errno;
108666 + t_Error err;
108667 +
108668 + /* if rx pause is enabled, do NOT ignore pause frames */
108669 + err = FM_MAC_SetRxIgnorePauseFrames(fm_mac_dev, !en);
108670 +
108671 + _errno = -GET_ERROR_TYPE(err);
108672 + if (_errno < 0)
108673 + pr_err("FM_MAC_SetRxIgnorePauseFrames() = 0x%08x\n", err);
108674 +
108675 + return _errno;
108676 +}
108677 +EXPORT_SYMBOL(fm_mac_set_rx_pause_frames);
108678 +
108679 +#ifdef CONFIG_FMAN_PFC
108680 +int fm_mac_set_tx_pause_frames(struct fm_mac_dev *fm_mac_dev,
108681 + bool en)
108682 +{
108683 + int _errno, i;
108684 + t_Error err;
108685 +
108686 + if (en)
108687 + for (i = 0; i < CONFIG_FMAN_PFC_COS_COUNT; i++) {
108688 + err = FM_MAC_SetTxPauseFrames(fm_mac_dev,
108689 + i, fsl_fm_pfc_quanta[i],
108690 + FSL_FM_PAUSE_THRESH_DEFAULT);
108691 + _errno = -GET_ERROR_TYPE(err);
108692 + if (_errno < 0) {
108693 + pr_err("FM_MAC_SetTxPauseFrames() = 0x%08x\n", err);
108694 + return _errno;
108695 + }
108696 + }
108697 + else
108698 + for (i = 0; i < CONFIG_FMAN_PFC_COS_COUNT; i++) {
108699 + err = FM_MAC_SetTxPauseFrames(fm_mac_dev,
108700 + i, FSL_FM_PAUSE_TIME_DISABLE,
108701 + FSL_FM_PAUSE_THRESH_DEFAULT);
108702 + _errno = -GET_ERROR_TYPE(err);
108703 + if (_errno < 0) {
108704 + pr_err("FM_MAC_SetTxPauseFrames() = 0x%08x\n", err);
108705 + return _errno;
108706 + }
108707 + }
108708 +
108709 + return _errno;
108710 +}
108711 +#else
108712 +int fm_mac_set_tx_pause_frames(struct fm_mac_dev *fm_mac_dev,
108713 + bool en)
108714 +{
108715 + int _errno;
108716 + t_Error err;
108717 +
108718 + if (en)
108719 + err = FM_MAC_SetTxAutoPauseFrames(fm_mac_dev,
108720 + FSL_FM_PAUSE_TIME_ENABLE);
108721 + else
108722 + err = FM_MAC_SetTxAutoPauseFrames(fm_mac_dev,
108723 + FSL_FM_PAUSE_TIME_DISABLE);
108724 +
108725 + _errno = -GET_ERROR_TYPE(err);
108726 + if (_errno < 0)
108727 + pr_err("FM_MAC_SetTxAutoPauseFrames() = 0x%08x\n", err);
108728 +
108729 + return _errno;
108730 +}
108731 +#endif
108732 +EXPORT_SYMBOL(fm_mac_set_tx_pause_frames);
108733 +
108734 +int fm_rtc_enable(struct fm *fm_dev)
108735 +{
108736 + int _errno;
108737 + t_Error err;
108738 +
108739 + err = FM_RTC_Enable(fm_get_rtc_handle(fm_dev), 0);
108740 + _errno = -GET_ERROR_TYPE(err);
108741 + if (unlikely(_errno < 0))
108742 + pr_err("FM_RTC_Enable = 0x%08x\n", err);
108743 +
108744 + return _errno;
108745 +}
108746 +EXPORT_SYMBOL(fm_rtc_enable);
108747 +
108748 +int fm_rtc_disable(struct fm *fm_dev)
108749 +{
108750 + int _errno;
108751 + t_Error err;
108752 +
108753 + err = FM_RTC_Disable(fm_get_rtc_handle(fm_dev));
108754 + _errno = -GET_ERROR_TYPE(err);
108755 + if (unlikely(_errno < 0))
108756 + pr_err("FM_RTC_Disable = 0x%08x\n", err);
108757 +
108758 + return _errno;
108759 +}
108760 +EXPORT_SYMBOL(fm_rtc_disable);
108761 +
108762 +int fm_rtc_get_cnt(struct fm *fm_dev, uint64_t *ts)
108763 +{
108764 + int _errno;
108765 + t_Error err;
108766 +
108767 + err = FM_RTC_GetCurrentTime(fm_get_rtc_handle(fm_dev), ts);
108768 + _errno = -GET_ERROR_TYPE(err);
108769 + if (unlikely(_errno < 0))
108770 + pr_err("FM_RTC_GetCurrentTime = 0x%08x\n", err);
108771 +
108772 + return _errno;
108773 +}
108774 +EXPORT_SYMBOL(fm_rtc_get_cnt);
108775 +
108776 +int fm_rtc_set_cnt(struct fm *fm_dev, uint64_t ts)
108777 +{
108778 + int _errno;
108779 + t_Error err;
108780 +
108781 + err = FM_RTC_SetCurrentTime(fm_get_rtc_handle(fm_dev), ts);
108782 + _errno = -GET_ERROR_TYPE(err);
108783 + if (unlikely(_errno < 0))
108784 + pr_err("FM_RTC_SetCurrentTime = 0x%08x\n", err);
108785 +
108786 + return _errno;
108787 +}
108788 +EXPORT_SYMBOL(fm_rtc_set_cnt);
108789 +
108790 +int fm_rtc_get_drift(struct fm *fm_dev, uint32_t *drift)
108791 +{
108792 + int _errno;
108793 + t_Error err;
108794 +
108795 + err = FM_RTC_GetFreqCompensation(fm_get_rtc_handle(fm_dev),
108796 + drift);
108797 + _errno = -GET_ERROR_TYPE(err);
108798 + if (unlikely(_errno < 0))
108799 + pr_err("FM_RTC_GetFreqCompensation = 0x%08x\n", err);
108800 +
108801 + return _errno;
108802 +}
108803 +EXPORT_SYMBOL(fm_rtc_get_drift);
108804 +
108805 +int fm_rtc_set_drift(struct fm *fm_dev, uint32_t drift)
108806 +{
108807 + int _errno;
108808 + t_Error err;
108809 +
108810 + err = FM_RTC_SetFreqCompensation(fm_get_rtc_handle(fm_dev),
108811 + drift);
108812 + _errno = -GET_ERROR_TYPE(err);
108813 + if (unlikely(_errno < 0))
108814 + pr_err("FM_RTC_SetFreqCompensation = 0x%08x\n", err);
108815 +
108816 + return _errno;
108817 +}
108818 +EXPORT_SYMBOL(fm_rtc_set_drift);
108819 +
108820 +int fm_rtc_set_alarm(struct fm *fm_dev, uint32_t id,
108821 + uint64_t time)
108822 +{
108823 + t_FmRtcAlarmParams alarm;
108824 + int _errno;
108825 + t_Error err;
108826 +
108827 + alarm.alarmId = id;
108828 + alarm.alarmTime = time;
108829 + alarm.f_AlarmCallback = NULL;
108830 + err = FM_RTC_SetAlarm(fm_get_rtc_handle(fm_dev),
108831 + &alarm);
108832 + _errno = -GET_ERROR_TYPE(err);
108833 + if (unlikely(_errno < 0))
108834 + pr_err("FM_RTC_SetAlarm = 0x%08x\n", err);
108835 +
108836 + return _errno;
108837 +}
108838 +EXPORT_SYMBOL(fm_rtc_set_alarm);
108839 +
108840 +int fm_rtc_set_fiper(struct fm *fm_dev, uint32_t id,
108841 + uint64_t fiper)
108842 +{
108843 + t_FmRtcPeriodicPulseParams pp;
108844 + int _errno;
108845 + t_Error err;
108846 +
108847 + pp.periodicPulseId = id;
108848 + pp.periodicPulsePeriod = fiper;
108849 + pp.f_PeriodicPulseCallback = NULL;
108850 + err = FM_RTC_SetPeriodicPulse(fm_get_rtc_handle(fm_dev), &pp);
108851 + _errno = -GET_ERROR_TYPE(err);
108852 + if (unlikely(_errno < 0))
108853 + pr_err("FM_RTC_SetPeriodicPulse = 0x%08x\n", err);
108854 +
108855 + return _errno;
108856 +}
108857 +EXPORT_SYMBOL(fm_rtc_set_fiper);
108858 +
108859 +#ifdef CONFIG_PTP_1588_CLOCK_DPAA
108860 +int fm_rtc_enable_interrupt(struct fm *fm_dev, uint32_t events)
108861 +{
108862 + int _errno;
108863 + t_Error err;
108864 +
108865 + err = FM_RTC_EnableInterrupt(fm_get_rtc_handle(fm_dev),
108866 + events);
108867 + _errno = -GET_ERROR_TYPE(err);
108868 + if (unlikely(_errno < 0))
108869 + pr_err("FM_RTC_EnableInterrupt = 0x%08x\n", err);
108870 +
108871 + return _errno;
108872 +}
108873 +EXPORT_SYMBOL(fm_rtc_enable_interrupt);
108874 +
108875 +int fm_rtc_disable_interrupt(struct fm *fm_dev, uint32_t events)
108876 +{
108877 + int _errno;
108878 + t_Error err;
108879 +
108880 + err = FM_RTC_DisableInterrupt(fm_get_rtc_handle(fm_dev),
108881 + events);
108882 + _errno = -GET_ERROR_TYPE(err);
108883 + if (unlikely(_errno < 0))
108884 + pr_err("FM_RTC_DisableInterrupt = 0x%08x\n", err);
108885 +
108886 + return _errno;
108887 +}
108888 +EXPORT_SYMBOL(fm_rtc_disable_interrupt);
108889 +#endif
108890 +
108891 +int fm_mac_set_wol(struct fm_port *port, struct fm_mac_dev *fm_mac_dev, bool en)
108892 +{
108893 + int _errno;
108894 + t_Error err;
108895 + t_LnxWrpFmPortDev *p_LnxWrpFmPortDev = (t_LnxWrpFmPortDev *)port;
108896 +
108897 + /* Do not set WoL on AR ports */
108898 + if (FM_PORT_IsInDsar(p_LnxWrpFmPortDev->h_Dev)) {
108899 + printk(KERN_WARNING "Port is AutoResponse enabled! WoL will not be set on this port!\n");
108900 + return 0;
108901 + }
108902 +
108903 + err = FM_MAC_SetWakeOnLan(fm_mac_dev, en);
108904 +
108905 + _errno = -GET_ERROR_TYPE(err);
108906 + if (_errno < 0)
108907 + pr_err("FM_MAC_SetWakeOnLan() = 0x%08x\n", err);
108908 +
108909 + return _errno;
108910 +}
108911 +EXPORT_SYMBOL(fm_mac_set_wol);
108912 +
108913 +void fm_mutex_lock(void)
108914 +{
108915 + mutex_lock(&lnxwrp_mutex);
108916 +}
108917 +EXPORT_SYMBOL(fm_mutex_lock);
108918 +
108919 +void fm_mutex_unlock(void)
108920 +{
108921 + mutex_unlock(&lnxwrp_mutex);
108922 +}
108923 +EXPORT_SYMBOL(fm_mutex_unlock);
108924 +
108925 +/*Macsec wrapper functions*/
108926 +struct fm_macsec_dev *fm_macsec_config(struct fm_macsec_params *fm_params)
108927 +{
108928 + struct fm_macsec_dev *fm_macsec_dev;
108929 +
108930 + fm_macsec_dev = FM_MACSEC_Config((t_FmMacsecParams *)fm_params);
108931 + if (unlikely(fm_macsec_dev == NULL))
108932 + pr_err("FM_MACSEC_Config() failed\n");
108933 +
108934 + return fm_macsec_dev;
108935 +}
108936 +EXPORT_SYMBOL(fm_macsec_config);
108937 +
108938 +int fm_macsec_init(struct fm_macsec_dev *fm_macsec_dev)
108939 +{
108940 + int err;
108941 + int _errno;
108942 +
108943 + err = FM_MACSEC_Init(fm_macsec_dev);
108944 + _errno = -GET_ERROR_TYPE(err);
108945 + if (unlikely(_errno < 0))
108946 + pr_err("FM_MACSEC_Init() = 0x%08x\n", err);
108947 +
108948 + return _errno;
108949 +}
108950 +EXPORT_SYMBOL(fm_macsec_init);
108951 +
108952 +int fm_macsec_free(struct fm_macsec_dev *fm_macsec_dev)
108953 +{
108954 + int err;
108955 + int _error;
108956 +
108957 + err = FM_MACSEC_Free(fm_macsec_dev);
108958 + _error = -GET_ERROR_TYPE(err);
108959 +
108960 + if (unlikely(_error < 0))
108961 + pr_err("FM_MACSEC_Free() = 0x%08x\n", err);
108962 +
108963 + return _error;
108964 +}
108965 +EXPORT_SYMBOL(fm_macsec_free);
108966 +
108967 +int fm_macsec_config_unknown_sci_frame_treatment(struct fm_macsec_dev
108968 + *fm_macsec_dev,
108969 + fm_macsec_unknown_sci_frame_treatment treat_mode)
108970 +{
108971 + int err;
108972 + int _errno;
108973 +
108974 + err = FM_MACSEC_ConfigUnknownSciFrameTreatment(fm_macsec_dev,
108975 + treat_mode);
108976 + _errno = -GET_ERROR_TYPE(err);
108977 + if (unlikely(_errno < 0))
108978 + pr_err("FM_MACSEC_ConfigUnknownSciFrameTreatmen() = 0x%08x\n", err);
108979 +
108980 + return _errno;
108981 +}
108982 +EXPORT_SYMBOL(fm_macsec_config_unknown_sci_frame_treatment);
108983 +
108984 +int fm_macsec_config_invalid_tags_frame_treatment(struct fm_macsec_dev *fm_macsec_dev,
108985 + bool deliver_uncontrolled)
108986 +{
108987 + int err;
108988 + int _errno;
108989 +
108990 + err = FM_MACSEC_ConfigInvalidTagsFrameTreatment(fm_macsec_dev,
108991 + deliver_uncontrolled);
108992 + _errno = -GET_ERROR_TYPE(err);
108993 + if (unlikely(_errno < 0))
108994 + pr_err("FM_MAC_ConfigMaxFrameLength() = 0x%08x\n", err);
108995 +
108996 + return _errno;
108997 +}
108998 +EXPORT_SYMBOL(fm_macsec_config_invalid_tags_frame_treatment);
108999 +
109000 +int fm_macsec_config_kay_frame_treatment(struct fm_macsec_dev *fm_macsec_dev,
109001 + bool discard_uncontrolled)
109002 +{
109003 + int err;
109004 + int _errno;
109005 +
109006 + err = FM_MACSEC_ConfigEncryptWithNoChangedTextFrameTreatment(fm_macsec_dev,
109007 + discard_uncontrolled);
109008 + _errno = -GET_ERROR_TYPE(err);
109009 + if (unlikely(_errno < 0))
109010 + pr_err("FM_MACSEC_ConfigEncryptWithNoChangedTextFrameTreatmen() = 0x%08x\n", err);
109011 +
109012 + return _errno;
109013 +}
109014 +EXPORT_SYMBOL(fm_macsec_config_kay_frame_treatment);
109015 +
109016 +int fm_macsec_config_untag_frame_treatment(struct fm_macsec_dev *fm_macsec_dev,
109017 + fm_macsec_untag_frame_treatment treat_mode)
109018 +{
109019 + int err;
109020 + int _errno;
109021 +
109022 + err = FM_MACSEC_ConfigUntagFrameTreatment(fm_macsec_dev, treat_mode);
109023 + _errno = -GET_ERROR_TYPE(err);
109024 + if (unlikely(_errno < 0))
109025 + pr_err("FM_MACSEC_ConfigUntagFrameTreatment() = 0x%08x\n", err);
109026 +
109027 + return _errno;
109028 +}
109029 +EXPORT_SYMBOL(fm_macsec_config_untag_frame_treatment);
109030 +
109031 +int fm_macsec_config_pn_exhaustion_threshold(struct fm_macsec_dev *fm_macsec_dev,
109032 + uint32_t pn_exh_thr)
109033 +{
109034 + int err;
109035 + int _errno;
109036 +
109037 + err = FM_MACSEC_ConfigPnExhaustionThreshold(fm_macsec_dev, pn_exh_thr);
109038 + _errno = -GET_ERROR_TYPE(err);
109039 + if (unlikely(_errno < 0))
109040 + pr_err("FM_MACSEC_ConfigPnExhaustionThreshold() = 0x%08x\n", err);
109041 +
109042 + return _errno;
109043 +}
109044 +EXPORT_SYMBOL(fm_macsec_config_pn_exhaustion_threshold);
109045 +
109046 +int fm_macsec_config_keys_unreadable(struct fm_macsec_dev *fm_macsec_dev)
109047 +{
109048 + int err;
109049 + int _errno;
109050 +
109051 + err = FM_MACSEC_ConfigKeysUnreadable(fm_macsec_dev);
109052 + _errno = -GET_ERROR_TYPE(err);
109053 + if (unlikely(_errno < 0))
109054 + pr_err("FM_MACSEC_ConfigKeysUnreadable() = 0x%08x\n", err);
109055 +
109056 + return _errno;
109057 +}
109058 +EXPORT_SYMBOL(fm_macsec_config_keys_unreadable);
109059 +
109060 +int fm_macsec_config_sectag_without_sci(struct fm_macsec_dev *fm_macsec_dev)
109061 +{
109062 + int err;
109063 + int _errno;
109064 +
109065 + err = FM_MACSEC_ConfigSectagWithoutSCI(fm_macsec_dev);
109066 + _errno = -GET_ERROR_TYPE(err);
109067 + if (unlikely(_errno < 0))
109068 + pr_err("FM_MACSEC_ConfigSectagWithoutSCI() = 0x%08x\n", err);
109069 +
109070 + return _errno;
109071 +}
109072 +EXPORT_SYMBOL(fm_macsec_config_sectag_without_sci);
109073 +
109074 +int fm_macsec_config_exception(struct fm_macsec_dev *fm_macsec_dev,
109075 + fm_macsec_exception exception, bool enable)
109076 +{
109077 + int err;
109078 + int _errno;
109079 +
109080 + err = FM_MACSEC_ConfigException(fm_macsec_dev, exception, enable);
109081 + _errno = -GET_ERROR_TYPE(err);
109082 + if (unlikely(_errno < 0))
109083 + pr_err("FM_MACSEC_ConfigException() = 0x%08x\n", err);
109084 +
109085 + return _errno;
109086 +}
109087 +EXPORT_SYMBOL(fm_macsec_config_exception);
109088 +
109089 +int fm_macsec_get_revision(struct fm_macsec_dev *fm_macsec_dev,
109090 + int *macsec_revision)
109091 +{
109092 + int err;
109093 + int _errno;
109094 +
109095 + err = FM_MACSEC_GetRevision(fm_macsec_dev, macsec_revision);
109096 + _errno = -GET_ERROR_TYPE(err);
109097 + if (unlikely(_errno < 0))
109098 + pr_err("FM_MACSEC_GetRevision() = 0x%08x\n", err);
109099 +
109100 + return _errno;
109101 +}
109102 +EXPORT_SYMBOL(fm_macsec_get_revision);
109103 +
109104 +int fm_macsec_enable(struct fm_macsec_dev *fm_macsec_dev)
109105 +{
109106 + int err;
109107 + int _errno;
109108 +
109109 + err = FM_MACSEC_Enable(fm_macsec_dev);
109110 + _errno = -GET_ERROR_TYPE(err);
109111 + if (unlikely(_errno < 0))
109112 + pr_err("FM_MACSEC_Enable() = 0x%08x\n", err);
109113 +
109114 + return _errno;
109115 +}
109116 +EXPORT_SYMBOL(fm_macsec_enable);
109117 +
109118 +int fm_macsec_disable(struct fm_macsec_dev *fm_macsec_dev)
109119 +{
109120 + int err;
109121 + int _errno;
109122 +
109123 + err = FM_MACSEC_Disable(fm_macsec_dev);
109124 + _errno = -GET_ERROR_TYPE(err);
109125 + if (unlikely(_errno < 0))
109126 + pr_err("FM_MACSEC_Disable() = 0x%08x\n", err);
109127 +
109128 + return _errno;
109129 +}
109130 +EXPORT_SYMBOL(fm_macsec_disable);
109131 +
109132 +int fm_macsec_set_exception(struct fm_macsec_dev *fm_macsec_dev,
109133 + fm_macsec_exception exception, bool enable)
109134 +{
109135 + int err;
109136 + int _errno;
109137 +
109138 + err = FM_MACSEC_SetException(fm_macsec_dev, exception, enable);
109139 + _errno = -GET_ERROR_TYPE(err);
109140 + if (unlikely(_errno < 0))
109141 + pr_err("FM_MACSEC_SetException() = 0x%08x\n", err);
109142 +
109143 + return _errno;
109144 +}
109145 +EXPORT_SYMBOL(fm_macsec_set_exception);
109146 +
109147 +/* Macsec SECY wrapper API */
109148 +struct fm_macsec_secy_dev *fm_macsec_secy_config(struct fm_macsec_secy_params *secy_params)
109149 +{
109150 + struct fm_macsec_secy_dev *fm_macsec_secy;
109151 +
109152 + fm_macsec_secy = FM_MACSEC_SECY_Config((t_FmMacsecSecYParams *)secy_params);
109153 + if (unlikely(fm_macsec_secy < 0))
109154 + pr_err("FM_MACSEC_SECY_Config() failed\n");
109155 +
109156 + return fm_macsec_secy;
109157 +}
109158 +EXPORT_SYMBOL(fm_macsec_secy_config);
109159 +
109160 +int fm_macsec_secy_init(struct fm_macsec_secy_dev *fm_macsec_secy_dev)
109161 +{
109162 + int err;
109163 + int _errno;
109164 +
109165 + err = FM_MACSEC_SECY_Init(fm_macsec_secy_dev);
109166 + _errno = -GET_ERROR_TYPE(err);
109167 + if (unlikely(_errno < 0))
109168 + pr_err("FM_MACSEC_SECY_Init() = 0x%08x\n", err);
109169 +
109170 + return _errno;
109171 +}
109172 +EXPORT_SYMBOL(fm_macsec_secy_init);
109173 +
109174 +int fm_macsec_secy_free(struct fm_macsec_secy_dev *fm_macsec_secy_dev)
109175 +{
109176 + int err;
109177 + int _errno;
109178 +
109179 + err = FM_MACSEC_SECY_Free(fm_macsec_secy_dev);
109180 + _errno = -GET_ERROR_TYPE(err);
109181 + if (unlikely(_errno < 0))
109182 + pr_err("FM_MACSEC_SECY_Free() = 0x%08x\n", err);
109183 +
109184 + return _errno;
109185 +}
109186 +EXPORT_SYMBOL(fm_macsec_secy_free);
109187 +
109188 +int fm_macsec_secy_config_sci_insertion_mode(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
109189 + fm_macsec_sci_insertion_mode sci_insertion_mode)
109190 +{
109191 + int err;
109192 + int _errno;
109193 +
109194 + err = FM_MACSEC_SECY_ConfigSciInsertionMode(fm_macsec_secy_dev,
109195 + sci_insertion_mode);
109196 + _errno = -GET_ERROR_TYPE(err);
109197 + if (unlikely(_errno < 0))
109198 + pr_err("FM_MACSEC_SECY_ConfigSciInsertionMode() = 0x%08x\n", err);
109199 +
109200 + return _errno;
109201 +}
109202 +EXPORT_SYMBOL(fm_macsec_secy_config_sci_insertion_mode);
109203 +
109204 +int fm_macsec_secy_config_protect_frames(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
109205 + bool protect_frames)
109206 +{
109207 + int err;
109208 + int _errno;
109209 +
109210 + err = FM_MACSEC_SECY_ConfigProtectFrames(fm_macsec_secy_dev,
109211 + protect_frames);
109212 + _errno = -GET_ERROR_TYPE(err);
109213 + if (unlikely(_errno < 0))
109214 + pr_err("FM_MACSEC_SECY_ConfigProtectFrames() = 0x%08x\n", err);
109215 +
109216 + return _errno;
109217 +}
109218 +EXPORT_SYMBOL(fm_macsec_secy_config_protect_frames);
109219 +
109220 +int fm_macsec_secy_config_replay_window(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
109221 + bool replay_protect, uint32_t replay_window)
109222 +{
109223 + int err;
109224 + int _errno;
109225 +
109226 + err = FM_MACSEC_SECY_ConfigReplayWindow(fm_macsec_secy_dev,
109227 + replay_protect, replay_window);
109228 + _errno = -GET_ERROR_TYPE(err);
109229 + if (unlikely(_errno < 0))
109230 + pr_err("FM_MACSEC_SECY_ConfigReplayWindow() = 0x%08x\n", err);
109231 +
109232 + return _errno;
109233 +}
109234 +EXPORT_SYMBOL(fm_macsec_secy_config_replay_window);
109235 +
109236 +int fm_macsec_secy_config_validation_mode(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
109237 + fm_macsec_valid_frame_behavior validate_frames)
109238 +{
109239 + int err;
109240 + int _errno;
109241 +
109242 + err = FM_MACSEC_SECY_ConfigValidationMode(fm_macsec_secy_dev,
109243 + validate_frames);
109244 + _errno = -GET_ERROR_TYPE(err);
109245 + if (unlikely(_errno < 0))
109246 + pr_err("FM_MACSEC_SECY_ConfigValidationMode() = 0x%08x\n", err);
109247 +
109248 + return _errno;
109249 +}
109250 +EXPORT_SYMBOL(fm_macsec_secy_config_validation_mode);
109251 +
109252 +int fm_macsec_secy_config_confidentiality(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
109253 + bool confidentiality_enable,
109254 + uint32_t confidentiality_offset)
109255 +{
109256 + int err;
109257 + int _errno;
109258 +
109259 + err = FM_MACSEC_SECY_ConfigConfidentiality(fm_macsec_secy_dev,
109260 + confidentiality_enable,
109261 + confidentiality_offset);
109262 + _errno = -GET_ERROR_TYPE(err);
109263 + if (unlikely(_errno < 0))
109264 + pr_err("FM_MACSEC_SECY_ConfigConfidentiality() = 0x%08x\n",
109265 + err);
109266 +
109267 + return _errno;
109268 +}
109269 +EXPORT_SYMBOL(fm_macsec_secy_config_confidentiality);
109270 +
109271 +int fm_macsec_secy_config_point_to_point(struct fm_macsec_secy_dev *fm_macsec_secy_dev)
109272 +{
109273 + int err;
109274 + int _errno;
109275 +
109276 + err = FM_MACSEC_SECY_ConfigPointToPoint(fm_macsec_secy_dev);
109277 + _errno = -GET_ERROR_TYPE(err);
109278 + if (unlikely(_errno < 0))
109279 + pr_err("FM_MACSEC_SECY_ConfigPointToPoint() = 0x%08x\n",
109280 + err);
109281 +
109282 + return _errno;
109283 +}
109284 +EXPORT_SYMBOL(fm_macsec_secy_config_point_to_point);
109285 +
109286 +int fm_macsec_secy_config_exception(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
109287 + fm_macsec_secy_exception exception,
109288 + bool enable)
109289 +{
109290 + int err;
109291 + int _errno;
109292 +
109293 + err = FM_MACSEC_SECY_ConfigException(fm_macsec_secy_dev, exception,
109294 + enable);
109295 + _errno = -GET_ERROR_TYPE(err);
109296 + if (unlikely(_errno < 0))
109297 + pr_err("FM_MACSEC_SECY_ConfigException() = 0x%08x\n",
109298 + err);
109299 +
109300 + return _errno;
109301 +}
109302 +EXPORT_SYMBOL(fm_macsec_secy_config_exception);
109303 +
109304 +int fm_macsec_secy_config_event(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
109305 + fm_macsec_secy_event event,
109306 + bool enable)
109307 +{
109308 + int err;
109309 + int _errno;
109310 +
109311 + err = FM_MACSEC_SECY_ConfigEvent(fm_macsec_secy_dev, event, enable);
109312 + _errno = -GET_ERROR_TYPE(err);
109313 + if (unlikely(_errno < 0))
109314 + pr_err("FM_MACSEC_SECY_ConfigEvent() = 0x%08x\n",
109315 + err);
109316 +
109317 + return _errno;
109318 +}
109319 +EXPORT_SYMBOL(fm_macsec_secy_config_event);
109320 +
109321 +struct rx_sc_dev *fm_macsec_secy_create_rxsc(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
109322 + struct fm_macsec_secy_sc_params *params)
109323 +{
109324 + struct rx_sc_dev *rx_sc_dev;
109325 +
109326 + rx_sc_dev = FM_MACSEC_SECY_CreateRxSc(fm_macsec_secy_dev, (t_FmMacsecSecYSCParams *)params);
109327 + if (unlikely(rx_sc_dev == NULL))
109328 + pr_err("FM_MACSEC_SECY_CreateRxSc() failed\n");
109329 +
109330 + return rx_sc_dev;
109331 +}
109332 +EXPORT_SYMBOL(fm_macsec_secy_create_rxsc);
109333 +
109334 +int fm_macsec_secy_delete_rxsc(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
109335 + struct rx_sc_dev *sc)
109336 +{
109337 + int err;
109338 + int _errno;
109339 +
109340 + err = FM_MACSEC_SECY_DeleteRxSc(fm_macsec_secy_dev, sc);
109341 + _errno = -GET_ERROR_TYPE(err);
109342 + if (unlikely(_errno < 0))
109343 + pr_err("FM_MACSEC_SECY_DeleteRxSc() = 0x%08x\n",
109344 + err);
109345 +
109346 + return _errno;
109347 +}
109348 +EXPORT_SYMBOL(fm_macsec_secy_delete_rxsc);
109349 +
109350 +int fm_macsec_secy_create_rx_sa(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
109351 + struct rx_sc_dev *sc, macsec_an_t an,
109352 + uint32_t lowest_pn, macsec_sa_key_t key)
109353 +{
109354 + int err;
109355 + int _errno;
109356 +
109357 + err = FM_MACSEC_SECY_CreateRxSa(fm_macsec_secy_dev, sc, an,
109358 + lowest_pn, key);
109359 + _errno = -GET_ERROR_TYPE(err);
109360 + if (unlikely(_errno < 0))
109361 + pr_err("FM_MACSEC_SECY_CreateRxSa() = 0x%08x\n",
109362 + err);
109363 +
109364 + return _errno;
109365 +}
109366 +EXPORT_SYMBOL(fm_macsec_secy_create_rx_sa);
109367 +
109368 +int fm_macsec_secy_delete_rx_sa(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
109369 + struct rx_sc_dev *sc, macsec_an_t an)
109370 +{
109371 + int err;
109372 + int _errno;
109373 +
109374 + err = FM_MACSEC_SECY_DeleteRxSa(fm_macsec_secy_dev, sc, an);
109375 + _errno = -GET_ERROR_TYPE(err);
109376 + if (unlikely(_errno < 0))
109377 + pr_err("FM_MACSEC_SECY_DeleteRxSa() = 0x%08x\n",
109378 + err);
109379 +
109380 + return _errno;
109381 +}
109382 +EXPORT_SYMBOL(fm_macsec_secy_delete_rx_sa);
109383 +
109384 +int fm_macsec_secy_rxsa_enable_receive(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
109385 + struct rx_sc_dev *sc,
109386 + macsec_an_t an)
109387 +{
109388 + int err;
109389 + int _errno;
109390 +
109391 + err = FM_MACSEC_SECY_RxSaEnableReceive(fm_macsec_secy_dev, sc, an);
109392 + _errno = -GET_ERROR_TYPE(err);
109393 + if (unlikely(_errno < 0))
109394 + pr_err("FM_MACSEC_SECY_RxSaEnableReceive() = 0x%08x\n",
109395 + err);
109396 +
109397 + return _errno;
109398 +}
109399 +EXPORT_SYMBOL(fm_macsec_secy_rxsa_enable_receive);
109400 +
109401 +int fm_macsec_secy_rxsa_disable_receive(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
109402 + struct rx_sc_dev *sc,
109403 + macsec_an_t an)
109404 +{
109405 + int err;
109406 + int _errno;
109407 +
109408 + err = FM_MACSEC_SECY_RxSaDisableReceive(fm_macsec_secy_dev, sc, an);
109409 + _errno = -GET_ERROR_TYPE(err);
109410 + if (unlikely(_errno < 0))
109411 + pr_err("FM_MACSEC_SECY_RxSaDisableReceive() = 0x%08x\n",
109412 + err);
109413 +
109414 + return _errno;
109415 +}
109416 +EXPORT_SYMBOL(fm_macsec_secy_rxsa_disable_receive);
109417 +
109418 +int fm_macsec_secy_rxsa_update_next_pn(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
109419 + struct rx_sc_dev *sc,
109420 + macsec_an_t an, uint32_t updt_next_pn)
109421 +{
109422 + int err;
109423 + int _errno;
109424 +
109425 + err = FM_MACSEC_SECY_RxSaUpdateNextPn(fm_macsec_secy_dev, sc, an,
109426 + updt_next_pn);
109427 + _errno = -GET_ERROR_TYPE(err);
109428 + if (unlikely(_errno < 0))
109429 + pr_err("FM_MACSEC_SECY_RxSaUpdateNextPn() = 0x%08x\n", err);
109430 +
109431 + return _errno;
109432 +}
109433 +EXPORT_SYMBOL(fm_macsec_secy_rxsa_update_next_pn);
109434 +
109435 +int fm_macsec_secy_rxsa_update_lowest_pn(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
109436 + struct rx_sc_dev *sc,
109437 + macsec_an_t an, uint32_t updt_lowest_pn)
109438 +{
109439 + int err;
109440 + int _errno;
109441 +
109442 + err = FM_MACSEC_SECY_RxSaUpdateLowestPn(fm_macsec_secy_dev, sc, an,
109443 + updt_lowest_pn);
109444 + _errno = -GET_ERROR_TYPE(err);
109445 + if (unlikely(_errno < 0))
109446 + pr_err("FM_MACSEC_SECY_RxSaUpdateLowestPn() = 0x%08x\n",
109447 + err);
109448 +
109449 + return _errno;
109450 +}
109451 +EXPORT_SYMBOL(fm_macsec_secy_rxsa_update_lowest_pn);
109452 +
109453 +int fm_macsec_secy_rxsa_modify_key(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
109454 + struct rx_sc_dev *sc,
109455 + macsec_an_t an, macsec_sa_key_t key)
109456 +{
109457 + int err;
109458 + int _errno;
109459 +
109460 + err = FM_MACSEC_SECY_RxSaModifyKey(fm_macsec_secy_dev, sc, an, key);
109461 + _errno = -GET_ERROR_TYPE(err);
109462 + if (unlikely(_errno < 0))
109463 + pr_err("FM_MACSEC_SECY_RxSaModifyKey() = 0x%08x\n",
109464 + err);
109465 +
109466 + return _errno;
109467 +}
109468 +EXPORT_SYMBOL(fm_macsec_secy_rxsa_modify_key);
109469 +
109470 +int fm_macsec_secy_create_tx_sa(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
109471 + macsec_an_t an, macsec_sa_key_t key)
109472 +{
109473 + int err;
109474 + int _errno;
109475 +
109476 + err = FM_MACSEC_SECY_CreateTxSa(fm_macsec_secy_dev, an, key);
109477 + _errno = -GET_ERROR_TYPE(err);
109478 + if (unlikely(_errno < 0))
109479 + pr_err("FM_MACSEC_SECY_CreateTxSa() = 0x%08x\n",
109480 + err);
109481 +
109482 + return _errno;
109483 +}
109484 +EXPORT_SYMBOL(fm_macsec_secy_create_tx_sa);
109485 +
109486 +int fm_macsec_secy_delete_tx_sa(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
109487 + macsec_an_t an)
109488 +{
109489 + int err;
109490 + int _errno;
109491 +
109492 + err = FM_MACSEC_SECY_DeleteTxSa(fm_macsec_secy_dev, an);
109493 + _errno = -GET_ERROR_TYPE(err);
109494 + if (unlikely(_errno < 0))
109495 + pr_err("FM_MACSEC_SECY_DeleteTxSa() = 0x%08x\n",
109496 + err);
109497 +
109498 + return _errno;
109499 +}
109500 +EXPORT_SYMBOL(fm_macsec_secy_delete_tx_sa);
109501 +
109502 +int fm_macsec_secy_txsa_modify_key(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
109503 + macsec_an_t next_active_an,
109504 + macsec_sa_key_t key)
109505 +{
109506 + int err;
109507 + int _errno;
109508 +
109509 + err = FM_MACSEC_SECY_TxSaModifyKey(fm_macsec_secy_dev, next_active_an,
109510 + key);
109511 + _errno = -GET_ERROR_TYPE(err);
109512 + if (unlikely(_errno < 0))
109513 + pr_err("FM_MACSEC_SECY_TxSaModifyKey() = 0x%08x\n",
109514 + err);
109515 +
109516 + return _errno;
109517 +}
109518 +EXPORT_SYMBOL(fm_macsec_secy_txsa_modify_key);
109519 +
109520 +int fm_macsec_secy_txsa_set_active(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
109521 + macsec_an_t an)
109522 +{
109523 + int err;
109524 + int _errno;
109525 +
109526 + err = FM_MACSEC_SECY_TxSaSetActive(fm_macsec_secy_dev, an);
109527 + _errno = -GET_ERROR_TYPE(err);
109528 + if (unlikely(_errno < 0))
109529 + pr_err("FM_MACSEC_SECY_TxSaSetActive() = 0x%08x\n",
109530 + err);
109531 +
109532 + return _errno;
109533 +}
109534 +EXPORT_SYMBOL(fm_macsec_secy_txsa_set_active);
109535 +
109536 +int fm_macsec_secy_txsa_get_active(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
109537 + macsec_an_t *p_an)
109538 +{
109539 + int err;
109540 + int _errno;
109541 +
109542 + err = FM_MACSEC_SECY_TxSaGetActive(fm_macsec_secy_dev, p_an);
109543 + _errno = -GET_ERROR_TYPE(err);
109544 + if (unlikely(_errno < 0))
109545 + pr_err("FM_MACSEC_SECY_TxSaGetActive() = 0x%08x\n",
109546 + err);
109547 +
109548 + return _errno;
109549 +}
109550 +EXPORT_SYMBOL(fm_macsec_secy_txsa_get_active);
109551 +
109552 +int fm_macsec_secy_get_rxsc_phys_id(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
109553 + struct rx_sc_dev *sc, uint32_t *sc_phys_id)
109554 +{
109555 + int err;
109556 + int _errno;
109557 +
109558 + err = FM_MACSEC_SECY_GetRxScPhysId(fm_macsec_secy_dev, sc, sc_phys_id);
109559 + _errno = -GET_ERROR_TYPE(err);
109560 + if (unlikely(_errno < 0))
109561 + pr_err("FM_MACSEC_SECY_GetRxScPhysId() = 0x%08x\n",
109562 + err);
109563 +
109564 + return _errno;
109565 +}
109566 +EXPORT_SYMBOL(fm_macsec_secy_get_rxsc_phys_id);
109567 +
109568 +int fm_macsec_secy_get_txsc_phys_id(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
109569 + uint32_t *sc_phys_id)
109570 +{
109571 + int err;
109572 + int _errno;
109573 +
109574 + err = FM_MACSEC_SECY_GetTxScPhysId(fm_macsec_secy_dev, sc_phys_id);
109575 + _errno = -GET_ERROR_TYPE(err);
109576 + if (unlikely(_errno < 0))
109577 + pr_err("FM_MACSEC_SECY_GetTxScPhysId() = 0x%08x\n",
109578 + err);
109579 +
109580 + return _errno;
109581 +}
109582 +EXPORT_SYMBOL(fm_macsec_secy_get_txsc_phys_id);
109583 +
109584 +static t_Handle h_FmLnxWrp;
109585 +
109586 +static int __init __cold fm_load (void)
109587 +{
109588 + if ((h_FmLnxWrp = LNXWRP_FM_Init()) == NULL)
109589 + {
109590 + printk("Failed to init FM wrapper!\n");
109591 + return -ENODEV;
109592 + }
109593 +
109594 + printk(KERN_CRIT "Freescale FM module," \
109595 + " FMD API version %d.%d.%d\n",
109596 + FMD_API_VERSION_MAJOR,
109597 + FMD_API_VERSION_MINOR,
109598 + FMD_API_VERSION_RESPIN);
109599 + return 0;
109600 +}
109601 +
109602 +static void __exit __cold fm_unload (void)
109603 +{
109604 + if (h_FmLnxWrp)
109605 + LNXWRP_FM_Free(h_FmLnxWrp);
109606 +}
109607 +
109608 +module_init (fm_load);
109609 +module_exit (fm_unload);
109610 --- /dev/null
109611 +++ b/drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_fm.h
109612 @@ -0,0 +1,294 @@
109613 +/*
109614 + * Copyright 2008-2012 Freescale Semiconductor Inc.
109615 + *
109616 + * Redistribution and use in source and binary forms, with or without
109617 + * modification, are permitted provided that the following conditions are met:
109618 + * * Redistributions of source code must retain the above copyright
109619 + * notice, this list of conditions and the following disclaimer.
109620 + * * Redistributions in binary form must reproduce the above copyright
109621 + * notice, this list of conditions and the following disclaimer in the
109622 + * documentation and/or other materials provided with the distribution.
109623 + * * Neither the name of Freescale Semiconductor nor the
109624 + * names of its contributors may be used to endorse or promote products
109625 + * derived from this software without specific prior written permission.
109626 + *
109627 + *
109628 + * ALTERNATIVELY, this software may be distributed under the terms of the
109629 + * GNU General Public License ("GPL") as published by the Free Software
109630 + * Foundation, either version 2 of that License or (at your option) any
109631 + * later version.
109632 + *
109633 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
109634 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
109635 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
109636 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
109637 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
109638 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
109639 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
109640 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
109641 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
109642 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
109643 + */
109644 +
109645 +/*
109646 + @File lnxwrp_fm.h
109647 +
109648 + @Author Shlomi Gridish
109649 +
109650 + @Description FM Linux wrapper functions.
109651 +
109652 +*/
109653 +
109654 +#ifndef __LNXWRP_FM_H__
109655 +#define __LNXWRP_FM_H__
109656 +
109657 +#include <linux/fsl_qman.h> /* struct qman_fq */
109658 +
109659 +#include "std_ext.h"
109660 +#include "error_ext.h"
109661 +#include "list_ext.h"
109662 +
109663 +#include "lnxwrp_fm_ext.h"
109664 +
109665 +#define FM_MAX_NUM_OF_ADV_SETTINGS 10
109666 +
109667 +#define LNXWRP_FM_NUM_OF_SHARED_PROFILES 16
109668 +
109669 +#if defined(CONFIG_FMAN_DISABLE_OH_TO_REUSE_RESOURCES)
109670 +#define FM_10G_OPENDMA_MIN_TRESHOLD 8 /* 10g minimum treshold if only HC is enabled and no OH port enabled */
109671 +#define FM_OPENDMA_RX_TX_RAPORT 2 /* RX = 2*TX */
109672 +#else
109673 +#define FM_10G_OPENDMA_MIN_TRESHOLD 7 /* 10g minimum treshold if 7 OH ports are enabled */
109674 +#define FM_OPENDMA_RX_TX_RAPORT 1 /* RX = TX */
109675 +#endif
109676 +#define FM_DEFAULT_TX10G_OPENDMA 8 /* default TX 10g open dmas */
109677 +#define FM_DEFAULT_RX10G_OPENDMA 8 /* default RX 10g open dmas */
109678 +
109679 +#define FRAG_MANIP_SPACE 128
109680 +#define FRAG_DATA_ALIGN 64
109681 +
109682 +#ifndef CONFIG_FSL_FM_MAX_FRAME_SIZE
109683 +#define CONFIG_FSL_FM_MAX_FRAME_SIZE 0
109684 +#endif
109685 +
109686 +#ifndef CONFIG_FSL_FM_RX_EXTRA_HEADROOM
109687 +#define CONFIG_FSL_FM_RX_EXTRA_HEADROOM 16
109688 +#endif
109689 +
109690 +typedef enum {
109691 + e_NO_PCD = 0,
109692 + e_FM_PCD_3_TUPLE
109693 +} e_LnxWrpFmPortPcdDefUseCase;
109694 +
109695 +
109696 +typedef struct t_FmTestFq {
109697 + struct qman_fq fq_base;
109698 + t_Handle h_Arg;
109699 +} t_FmTestFq;
109700 +
109701 +typedef struct {
109702 + uint8_t id; /* sw port id, see SW_PORT_ID_TO_HW_PORT_ID() in fm_common.h */
109703 + int minor;
109704 + char name[20];
109705 + bool active;
109706 + uint64_t phys_baseAddr;
109707 + uint64_t baseAddr; /* Port's *virtual* address */
109708 + uint32_t memSize;
109709 + t_WrpFmPortDevSettings settings;
109710 + t_FmExtPools opExtPools;
109711 + uint8_t totalNumOfSchemes;
109712 + uint8_t schemesBase;
109713 + uint8_t numOfSchemesUsed;
109714 + uint32_t pcdBaseQ;
109715 + uint16_t pcdNumOfQs;
109716 + struct fm_port_pcd_param pcd_owner_params;
109717 + e_LnxWrpFmPortPcdDefUseCase defPcd;
109718 + t_Handle h_DefNetEnv;
109719 + t_Handle h_Schemes[FM_PCD_KG_NUM_OF_SCHEMES];
109720 + t_FmBufferPrefixContent buffPrefixContent;
109721 + t_Handle h_Dev;
109722 + t_Handle h_DfltVsp;
109723 + t_Handle h_LnxWrpFmDev;
109724 + uint16_t txCh;
109725 + struct device *dev;
109726 + struct device_attribute *dev_attr_stats;
109727 + struct device_attribute *dev_attr_regs;
109728 + struct device_attribute *dev_attr_bmi_regs;
109729 + struct device_attribute *dev_attr_qmi_regs;
109730 +#if (DPAA_VERSION >= 11)
109731 + struct device_attribute *dev_attr_ipv4_opt;
109732 +#endif
109733 + struct device_attribute *dev_attr_dsar_regs;
109734 + struct device_attribute *dev_attr_dsar_mem;
109735 + struct auto_res_tables_sizes dsar_table_sizes;
109736 +} t_LnxWrpFmPortDev;
109737 +
109738 +typedef struct {
109739 + uint8_t id;
109740 + bool active;
109741 + uint64_t baseAddr;
109742 + uint32_t memSize;
109743 + t_WrpFmMacDevSettings settings;
109744 + t_Handle h_Dev;
109745 + t_Handle h_LnxWrpFmDev;
109746 +} t_LnxWrpFmMacDev;
109747 +
109748 +/* information about all active ports for an FMan.
109749 + * !Some ports may be disabled by u-boot, thus will not be available */
109750 +struct fm_active_ports {
109751 + uint32_t num_oh_ports;
109752 + uint32_t num_tx_ports;
109753 + uint32_t num_rx_ports;
109754 + uint32_t num_tx25_ports;
109755 + uint32_t num_rx25_ports;
109756 + uint32_t num_tx10_ports;
109757 + uint32_t num_rx10_ports;
109758 +};
109759 +
109760 +/* FMan resources precalculated at fm probe based
109761 + * on available FMan port. */
109762 +struct fm_resource_settings {
109763 + /* buffers - fifo sizes */
109764 + uint32_t tx1g_num_buffers;
109765 + uint32_t rx1g_num_buffers;
109766 + uint32_t tx2g5_num_buffers; /* Not supported yet by LLD */
109767 + uint32_t rx2g5_num_buffers; /* Not supported yet by LLD */
109768 + uint32_t tx10g_num_buffers;
109769 + uint32_t rx10g_num_buffers;
109770 + uint32_t oh_num_buffers;
109771 + uint32_t shared_ext_buffers;
109772 +
109773 + /* open DMAs */
109774 + uint32_t tx_1g_dmas;
109775 + uint32_t rx_1g_dmas;
109776 + uint32_t tx_2g5_dmas; /* Not supported yet by LLD */
109777 + uint32_t rx_2g5_dmas; /* Not supported yet by LLD */
109778 + uint32_t tx_10g_dmas;
109779 + uint32_t rx_10g_dmas;
109780 + uint32_t oh_dmas;
109781 + uint32_t shared_ext_open_dma;
109782 +
109783 + /* Tnums */
109784 + uint32_t tx_1g_tnums;
109785 + uint32_t rx_1g_tnums;
109786 + uint32_t tx_2g5_tnums; /* Not supported yet by LLD */
109787 + uint32_t rx_2g5_tnums; /* Not supported yet by LLD */
109788 + uint32_t tx_10g_tnums;
109789 + uint32_t rx_10g_tnums;
109790 + uint32_t oh_tnums;
109791 + uint32_t shared_ext_tnums;
109792 +};
109793 +
109794 +typedef struct {
109795 + uint8_t id;
109796 + char name[10];
109797 + bool active;
109798 + bool pcdActive;
109799 + bool prsActive;
109800 + bool kgActive;
109801 + bool ccActive;
109802 + bool plcrActive;
109803 + e_LnxWrpFmPortPcdDefUseCase defPcd;
109804 + uint32_t usedSchemes;
109805 + uint8_t totalNumOfSharedSchemes;
109806 + uint8_t sharedSchemesBase;
109807 + uint8_t numOfSchemesUsed;
109808 + uint8_t defNetEnvId;
109809 + uint64_t fmPhysBaseAddr;
109810 + uint64_t fmBaseAddr;
109811 + uint32_t fmMemSize;
109812 + uint64_t fmMuramPhysBaseAddr;
109813 + uint64_t fmMuramBaseAddr;
109814 + uint32_t fmMuramMemSize;
109815 + uint64_t fmRtcPhysBaseAddr;
109816 + uint64_t fmRtcBaseAddr;
109817 + uint32_t fmRtcMemSize;
109818 + uint64_t fmVspPhysBaseAddr;
109819 + uint64_t fmVspBaseAddr;
109820 + uint32_t fmVspMemSize;
109821 + int irq;
109822 + int err_irq;
109823 + t_WrpFmDevSettings fmDevSettings;
109824 + t_WrpFmPcdDevSettings fmPcdDevSettings;
109825 + t_Handle h_Dev;
109826 + uint16_t hcCh;
109827 +
109828 + t_Handle h_MuramDev;
109829 + t_Handle h_PcdDev;
109830 + t_Handle h_RtcDev;
109831 +
109832 + t_Handle h_DsarRxPort;
109833 + t_Handle h_DsarTxPort;
109834 +
109835 + t_LnxWrpFmPortDev hcPort;
109836 + t_LnxWrpFmPortDev opPorts[FM_MAX_NUM_OF_OH_PORTS-1];
109837 + t_LnxWrpFmPortDev rxPorts[FM_MAX_NUM_OF_RX_PORTS];
109838 + t_LnxWrpFmPortDev txPorts[FM_MAX_NUM_OF_TX_PORTS];
109839 + t_LnxWrpFmMacDev macs[FM_MAX_NUM_OF_MACS];
109840 + struct fm_active_ports fm_active_ports_info;
109841 + struct fm_resource_settings fm_resource_settings_info;
109842 +
109843 + struct device *dev;
109844 + struct resource *res;
109845 + int major;
109846 + struct class *fm_class;
109847 + struct device_attribute *dev_attr_stats;
109848 + struct device_attribute *dev_attr_regs;
109849 + struct device_attribute *dev_attr_risc_load;
109850 +
109851 + struct device_attribute *dev_pcd_attr_stats;
109852 + struct device_attribute *dev_plcr_attr_regs;
109853 + struct device_attribute *dev_prs_attr_regs;
109854 + struct device_attribute *dev_fm_fpm_attr_regs;
109855 + struct device_attribute *dev_fm_kg_attr_regs;
109856 + struct device_attribute *dev_fm_kg_pe_attr_regs;
109857 + struct device_attribute *dev_attr_muram_free_size;
109858 + struct device_attribute *dev_attr_fm_ctrl_code_ver;
109859 +
109860 +
109861 + struct qman_fq *hc_tx_conf_fq, *hc_tx_err_fq, *hc_tx_fq;
109862 +} t_LnxWrpFmDev;
109863 +
109864 +typedef struct {
109865 + t_LnxWrpFmDev *p_FmDevs[INTG_MAX_NUM_OF_FM];
109866 +} t_LnxWrpFm;
109867 +#define LNXWRP_FM_OBJECT(ptr) LIST_OBJECT(ptr, t_LnxWrpFm, fms[((t_LnxWrpFmDev *)ptr)->id])
109868 +
109869 +
109870 +t_Error LnxwrpFmIOCTL(t_LnxWrpFmDev *p_LnxWrpFmDev, unsigned int cmd, unsigned long arg, bool compat);
109871 +t_Error LnxwrpFmPortIOCTL(t_LnxWrpFmPortDev *p_LnxWrpFmPortDev, unsigned int cmd, unsigned long arg, bool compat);
109872 +
109873 +
109874 +#if 0
109875 +static __inline__ t_Error AllocSchemesForPort(t_LnxWrpFmDev *p_LnxWrpFmDev, uint8_t numSchemes, uint8_t *p_BaseSchemeNum)
109876 +{
109877 + uint32_t schemeMask;
109878 + uint8_t i;
109879 +
109880 + if (!numSchemes)
109881 + RETURN_ERROR(MINOR, E_INVALID_VALUE, NO_MSG);
109882 +
109883 + schemeMask = 0x80000000;
109884 + *p_BaseSchemeNum = 0xff;
109885 +
109886 + for (i=0; schemeMask && numSchemes; schemeMask>>=1, i++)
109887 + if ((p_LnxWrpFmDev->usedSchemes & schemeMask) == 0)
109888 + {
109889 + p_LnxWrpFmDev->usedSchemes |= schemeMask;
109890 + numSchemes--;
109891 + if (*p_BaseSchemeNum==0xff)
109892 + *p_BaseSchemeNum = i;
109893 + }
109894 + else if (*p_BaseSchemeNum!=0xff)
109895 + RETURN_ERROR(MINOR, E_INVALID_STATE, ("Fragmentation on schemes array!!!"));
109896 +
109897 + if (numSchemes)
109898 + RETURN_ERROR(MINOR, E_FULL, ("schemes!!!"));
109899 + return E_OK;
109900 +}
109901 +#endif
109902 +
109903 +void LnxWrpPCDIOCTLTypeChecking(void);
109904 +void LnxWrpPCDIOCTLEnumChecking(void);
109905 +
109906 +#endif /* __LNXWRP_FM_H__ */
109907 --- /dev/null
109908 +++ b/drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_fm_port.c
109909 @@ -0,0 +1,1480 @@
109910 +/*
109911 + * Copyright 2008-2012 Freescale Semiconductor Inc.
109912 + *
109913 + * Redistribution and use in source and binary forms, with or without
109914 + * modification, are permitted provided that the following conditions are met:
109915 + * * Redistributions of source code must retain the above copyright
109916 + * notice, this list of conditions and the following disclaimer.
109917 + * * Redistributions in binary form must reproduce the above copyright
109918 + * notice, this list of conditions and the following disclaimer in the
109919 + * documentation and/or other materials provided with the distribution.
109920 + * * Neither the name of Freescale Semiconductor nor the
109921 + * names of its contributors may be used to endorse or promote products
109922 + * derived from this software without specific prior written permission.
109923 + *
109924 + *
109925 + * ALTERNATIVELY, this software may be distributed under the terms of the
109926 + * GNU General Public License ("GPL") as published by the Free Software
109927 + * Foundation, either version 2 of that License or (at your option) any
109928 + * later version.
109929 + *
109930 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
109931 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
109932 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
109933 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
109934 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
109935 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
109936 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
109937 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
109938 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
109939 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
109940 + */
109941 +
109942 +/*
109943 + @File lnxwrp_fm_port.c
109944 +
109945 + @Description FMD wrapper - FMan port functions.
109946 +
109947 +*/
109948 +
109949 +#include <linux/version.h>
109950 +#if defined(CONFIG_MODVERSIONS) && !defined(MODVERSIONS)
109951 +#define MODVERSIONS
109952 +#endif
109953 +#ifdef MODVERSIONS
109954 +#include <config/modversions.h>
109955 +#endif /* MODVERSIONS */
109956 +#include <linux/kernel.h>
109957 +#include <linux/module.h>
109958 +#include <linux/of_platform.h>
109959 +#include <linux/of_address.h>
109960 +#include <linux/cdev.h>
109961 +#include <linux/slab.h>
109962 +#include <linux/spinlock.h>
109963 +#ifndef CONFIG_FMAN_ARM
109964 +#include <linux/fsl/svr.h>
109965 +#endif
109966 +#include <linux/io.h>
109967 +
109968 +#include "sprint_ext.h"
109969 +#include "fm_common.h"
109970 +#include "lnxwrp_fsl_fman.h"
109971 +#include "fm_port_ext.h"
109972 +#if (DPAA_VERSION >= 11)
109973 +#include "fm_vsp_ext.h"
109974 +#endif /* DPAA_VERSION >= 11 */
109975 +#include "fm_ioctls.h"
109976 +#include "lnxwrp_resources.h"
109977 +#include "lnxwrp_sysfs_fm_port.h"
109978 +
109979 +#define __ERR_MODULE__ MODULE_FM
109980 +
109981 +extern struct device_node *GetFmAdvArgsDevTreeNode (uint8_t fmIndx);
109982 +
109983 +/* TODO: duplicated, see lnxwrp_fm.c */
109984 +#define ADD_ADV_CONFIG_NO_RET(_func, _param)\
109985 +do {\
109986 + if (i < max) {\
109987 + p_Entry = &p_Entrys[i];\
109988 + p_Entry->p_Function = _func;\
109989 + _param\
109990 + i++;\
109991 + } else {\
109992 + REPORT_ERROR(MAJOR, E_INVALID_VALUE,\
109993 + ("Number of advanced-configuration entries exceeded"));\
109994 + } \
109995 +} while (0)
109996 +
109997 +#ifndef CONFIG_FMAN_ARM
109998 +#define IS_T1023_T1024 (SVR_SOC_VER(mfspr(SPRN_SVR)) == SVR_T1024 || \
109999 + SVR_SOC_VER(mfspr(SPRN_SVR)) == SVR_T1023)
110000 +#endif
110001 +
110002 +static volatile int hcFrmRcv/* = 0 */;
110003 +static spinlock_t lock;
110004 +
110005 +static enum qman_cb_dqrr_result qm_tx_conf_dqrr_cb(struct qman_portal *portal,
110006 + struct qman_fq *fq,
110007 + const struct qm_dqrr_entry
110008 + *dq)
110009 +{
110010 + t_LnxWrpFmDev *p_LnxWrpFmDev = ((t_FmTestFq *) fq)->h_Arg;
110011 + unsigned long flags;
110012 +
110013 +#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
110014 +{
110015 + /* extract the HC frame address */
110016 + uint32_t *hcf_va = XX_PhysToVirt(qm_fd_addr((struct qm_fd *)&dq->fd));
110017 + int hcf_l = ((struct qm_fd *)&dq->fd)->length20;
110018 + int i;
110019 +
110020 + /* 32b byteswap of all data in the HC Frame */
110021 + for(i = 0; i < hcf_l / 4; ++i)
110022 + hcf_va[i] =
110023 + ___constant_swab32(hcf_va[i]);
110024 +}
110025 +#endif
110026 + FM_PCD_HcTxConf(p_LnxWrpFmDev->h_PcdDev, (t_DpaaFD *)&dq->fd);
110027 + spin_lock_irqsave(&lock, flags);
110028 + hcFrmRcv--;
110029 + spin_unlock_irqrestore(&lock, flags);
110030 +
110031 + return qman_cb_dqrr_consume;
110032 +}
110033 +
110034 +static enum qman_cb_dqrr_result qm_tx_dqrr_cb(struct qman_portal *portal,
110035 + struct qman_fq *fq,
110036 + const struct qm_dqrr_entry *dq)
110037 +{
110038 + WARN(1, "FMD: failure at %s:%d/%s()!\n", __FILE__, __LINE__,
110039 + __func__);
110040 + return qman_cb_dqrr_consume;
110041 +}
110042 +
110043 +static void qm_err_cb(struct qman_portal *portal,
110044 + struct qman_fq *fq, const struct qm_mr_entry *msg)
110045 +{
110046 + WARN(1, "FMD: failure at %s:%d/%s()!\n", __FILE__, __LINE__,
110047 + __func__);
110048 +}
110049 +
110050 +static struct qman_fq *FqAlloc(t_LnxWrpFmDev * p_LnxWrpFmDev,
110051 + uint32_t fqid,
110052 + uint32_t flags, uint16_t channel, uint8_t wq)
110053 +{
110054 + int _errno;
110055 + struct qman_fq *fq = NULL;
110056 + t_FmTestFq *p_FmtFq;
110057 + struct qm_mcc_initfq initfq;
110058 +
110059 + p_FmtFq = (t_FmTestFq *) XX_Malloc(sizeof(t_FmTestFq));
110060 + if (!p_FmtFq) {
110061 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FQ obj!!!"));
110062 + return NULL;
110063 + }
110064 +
110065 + p_FmtFq->fq_base.cb.dqrr = ((flags & QMAN_FQ_FLAG_NO_ENQUEUE)
110066 + ? qm_tx_conf_dqrr_cb
110067 + : qm_tx_dqrr_cb);
110068 + p_FmtFq->fq_base.cb.ern = qm_err_cb;
110069 + /* p_FmtFq->fq_base.cb.fqs = qm_err_cb; */
110070 + /* qm_err_cb wrongly called when the FQ is parked */
110071 + p_FmtFq->fq_base.cb.fqs = NULL;
110072 + p_FmtFq->h_Arg = (t_Handle) p_LnxWrpFmDev;
110073 + if (fqid == 0) {
110074 + flags |= QMAN_FQ_FLAG_DYNAMIC_FQID;
110075 + flags &= ~QMAN_FQ_FLAG_NO_MODIFY;
110076 + } else {
110077 + flags &= ~QMAN_FQ_FLAG_DYNAMIC_FQID;
110078 + }
110079 +
110080 + if (qman_create_fq(fqid, flags, &p_FmtFq->fq_base)) {
110081 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FQ obj - qman_new_fq!!!"));
110082 + XX_Free(p_FmtFq);
110083 + return NULL;
110084 + }
110085 + fq = &p_FmtFq->fq_base;
110086 +
110087 + if (!(flags & QMAN_FQ_FLAG_NO_MODIFY)) {
110088 + initfq.we_mask = QM_INITFQ_WE_DESTWQ;
110089 + initfq.fqd.dest.channel = channel;
110090 + initfq.fqd.dest.wq = wq;
110091 +
110092 + _errno = qman_init_fq(fq, QMAN_INITFQ_FLAG_SCHED, &initfq);
110093 + if (unlikely(_errno < 0)) {
110094 + REPORT_ERROR(MAJOR, E_NO_MEMORY,
110095 + ("FQ obj - qman_init_fq!!!"));
110096 + qman_destroy_fq(fq, 0);
110097 + XX_Free(p_FmtFq);
110098 + return NULL;
110099 + }
110100 + }
110101 +
110102 + DBG(TRACE,
110103 + ("fqid %d, flags 0x%08x, channel %d, wq %d", qman_fq_fqid(fq),
110104 + flags, channel, wq));
110105 +
110106 + return fq;
110107 +}
110108 +
110109 +static void FqFree(struct qman_fq *fq)
110110 +{
110111 + int _errno;
110112 +
110113 + _errno = qman_retire_fq(fq, NULL);
110114 + if (unlikely(_errno < 0))
110115 + printk(KERN_WARNING "qman_retire_fq(%u) = %d\n", qman_fq_fqid(fq), _errno);
110116 +
110117 + _errno = qman_oos_fq(fq);
110118 + if (unlikely(_errno < 0))
110119 + printk(KERN_WARNING "qman_oos_fq(%u) = %d\n", qman_fq_fqid(fq), _errno);
110120 +
110121 + qman_destroy_fq(fq, 0);
110122 + XX_Free((t_FmTestFq *) fq);
110123 +}
110124 +
110125 +static t_Error QmEnqueueCB(t_Handle h_Arg, void *p_Fd)
110126 +{
110127 + t_LnxWrpFmDev *p_LnxWrpFmDev = (t_LnxWrpFmDev *) h_Arg;
110128 + int _errno, timeout = 1000000;
110129 + unsigned long flags;
110130 +
110131 + ASSERT_COND(p_LnxWrpFmDev);
110132 +
110133 + spin_lock_irqsave(&lock, flags);
110134 + hcFrmRcv++;
110135 + spin_unlock_irqrestore(&lock, flags);
110136 +
110137 +#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
110138 +{
110139 + /* extract the HC frame address */
110140 + uint32_t *hcf_va = XX_PhysToVirt(qm_fd_addr((struct qm_fd *) p_Fd));
110141 + int hcf_l = ((struct qm_fd *)p_Fd)->length20;
110142 + int i;
110143 +
110144 + /* 32b byteswap of all data in the HC Frame */
110145 + for(i = 0; i < hcf_l / 4; ++i)
110146 + hcf_va[i] =
110147 + ___constant_swab32(hcf_va[i]);
110148 +}
110149 +#endif
110150 +
110151 + _errno = qman_enqueue(p_LnxWrpFmDev->hc_tx_fq, (struct qm_fd *) p_Fd,
110152 + 0);
110153 + if (_errno)
110154 + RETURN_ERROR(MINOR, E_INVALID_STATE,
110155 + ("qman_enqueue() failed"));
110156 +
110157 + while (hcFrmRcv && --timeout) {
110158 + udelay(1);
110159 + cpu_relax();
110160 + }
110161 + if (timeout == 0) {
110162 + dump_stack();
110163 + RETURN_ERROR(MINOR, E_WRITE_FAILED,
110164 + ("timeout waiting for Tx confirmation"));
110165 + return E_WRITE_FAILED;
110166 + }
110167 +
110168 + return E_OK;
110169 +}
110170 +
110171 +static t_LnxWrpFmPortDev *ReadFmPortDevTreeNode(struct platform_device
110172 + *of_dev)
110173 +{
110174 + t_LnxWrpFmDev *p_LnxWrpFmDev;
110175 + t_LnxWrpFmPortDev *p_LnxWrpFmPortDev;
110176 + struct device_node *fm_node, *port_node;
110177 + struct resource res;
110178 + const uint32_t *uint32_prop;
110179 + int _errno = 0, lenp;
110180 + uint32_t tmp_prop;
110181 +
110182 +#ifdef CONFIG_FMAN_P1023
110183 + static unsigned char have_oh_port/* = 0 */;
110184 +#endif
110185 +
110186 + port_node = of_node_get(of_dev->dev.of_node);
110187 +
110188 + /* Get the FM node */
110189 + fm_node = of_get_parent(port_node);
110190 + if (unlikely(fm_node == NULL)) {
110191 + REPORT_ERROR(MAJOR, E_NO_DEVICE,
110192 + ("of_get_parent() = %d", _errno));
110193 + return NULL;
110194 + }
110195 +
110196 + p_LnxWrpFmDev =
110197 + dev_get_drvdata(&of_find_device_by_node(fm_node)->dev);
110198 + of_node_put(fm_node);
110199 +
110200 + /* if fm_probe() failed, no point in going further with port probing */
110201 + if (p_LnxWrpFmDev == NULL)
110202 + return NULL;
110203 +
110204 + uint32_prop =
110205 + (uint32_t *) of_get_property(port_node, "cell-index", &lenp);
110206 + if (unlikely(uint32_prop == NULL)) {
110207 + REPORT_ERROR(MAJOR, E_INVALID_VALUE,
110208 + ("of_get_property(%s, cell-index) failed",
110209 + port_node->full_name));
110210 + return NULL;
110211 + }
110212 + tmp_prop = be32_to_cpu(*uint32_prop);
110213 + if (WARN_ON(lenp != sizeof(uint32_t)))
110214 + return NULL;
110215 + if (of_device_is_compatible(port_node, "fsl,fman-port-oh")) {
110216 + if (unlikely(tmp_prop >= FM_MAX_NUM_OF_OH_PORTS)) {
110217 + REPORT_ERROR(MAJOR, E_INVALID_VALUE,
110218 + ("of_get_property(%s, cell-index) failed",
110219 + port_node->full_name));
110220 + return NULL;
110221 + }
110222 +
110223 +#ifdef CONFIG_FMAN_P1023
110224 + /* Beware, this can be done when there is only
110225 + one FMan to be initialized */
110226 + if (!have_oh_port) {
110227 + have_oh_port = 1; /* first OP/HC port
110228 + is used for host command */
110229 +#else
110230 + /* Here it is hardcoded the use of the OH port 1
110231 + (with cell-index 0) */
110232 + if (tmp_prop == 0) {
110233 +#endif
110234 + p_LnxWrpFmPortDev = &p_LnxWrpFmDev->hcPort;
110235 + p_LnxWrpFmPortDev->id = 0;
110236 + /*
110237 + p_LnxWrpFmPortDev->id = *uint32_prop-1;
110238 + p_LnxWrpFmPortDev->id = *uint32_prop;
110239 + */
110240 + p_LnxWrpFmPortDev->settings.param.portType =
110241 + e_FM_PORT_TYPE_OH_HOST_COMMAND;
110242 + } else {
110243 + p_LnxWrpFmPortDev =
110244 + &p_LnxWrpFmDev->opPorts[tmp_prop - 1];
110245 + p_LnxWrpFmPortDev->id = tmp_prop- 1;
110246 + p_LnxWrpFmPortDev->settings.param.portType =
110247 + e_FM_PORT_TYPE_OH_OFFLINE_PARSING;
110248 + }
110249 + p_LnxWrpFmPortDev->settings.param.portId = tmp_prop;
110250 +
110251 + uint32_prop =
110252 + (uint32_t *) of_get_property(port_node,
110253 + "fsl,qman-channel-id",
110254 + &lenp);
110255 + if (uint32_prop == NULL) {
110256 + /*
110257 + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("missing fsl,qman-channel-id"));
110258 + */
110259 + XX_Print("FM warning: missing fsl,qman-channel-id"
110260 + " for OH port.\n");
110261 + return NULL;
110262 + }
110263 + tmp_prop = be32_to_cpu(*uint32_prop);
110264 + if (WARN_ON(lenp != sizeof(uint32_t)))
110265 + return NULL;
110266 + p_LnxWrpFmPortDev->txCh = tmp_prop;
110267 +
110268 + p_LnxWrpFmPortDev->settings.param.specificParams.nonRxParams.
110269 + qmChannel = p_LnxWrpFmPortDev->txCh;
110270 + } else if (of_device_is_compatible(port_node, "fsl,fman-port-1g-tx")) {
110271 + tmp_prop -= 0x28;
110272 + if (unlikely(tmp_prop >= FM_MAX_NUM_OF_1G_TX_PORTS)) {
110273 + REPORT_ERROR(MAJOR, E_INVALID_VALUE,
110274 + ("of_get_property(%s, cell-index) failed",
110275 + port_node->full_name));
110276 + return NULL;
110277 + }
110278 + p_LnxWrpFmPortDev = &p_LnxWrpFmDev->txPorts[tmp_prop];
110279 +
110280 + p_LnxWrpFmPortDev->id = tmp_prop;
110281 + p_LnxWrpFmPortDev->settings.param.portId =
110282 + p_LnxWrpFmPortDev->id;
110283 + p_LnxWrpFmPortDev->settings.param.portType = e_FM_PORT_TYPE_TX;
110284 +
110285 + uint32_prop = (uint32_t *) of_get_property(port_node,
110286 + "fsl,qman-channel-id", &lenp);
110287 + if (uint32_prop == NULL) {
110288 + REPORT_ERROR(MAJOR, E_INVALID_VALUE,
110289 + ("missing fsl,qman-channel-id"));
110290 + return NULL;
110291 + }
110292 + tmp_prop = be32_to_cpu(*uint32_prop);
110293 + if (WARN_ON(lenp != sizeof(uint32_t)))
110294 + return NULL;
110295 + p_LnxWrpFmPortDev->txCh = tmp_prop;
110296 + p_LnxWrpFmPortDev->
110297 + settings.param.specificParams.nonRxParams.qmChannel =
110298 + p_LnxWrpFmPortDev->txCh;
110299 + } else if (of_device_is_compatible(port_node, "fsl,fman-port-10g-tx")) {
110300 + tmp_prop -= 0x30;
110301 + if (unlikely(tmp_prop>= FM_MAX_NUM_OF_10G_TX_PORTS)) {
110302 + REPORT_ERROR(MAJOR, E_INVALID_VALUE,
110303 + ("of_get_property(%s, cell-index) failed",
110304 + port_node->full_name));
110305 + return NULL;
110306 + }
110307 + p_LnxWrpFmPortDev = &p_LnxWrpFmDev->txPorts[tmp_prop +
110308 + FM_MAX_NUM_OF_1G_TX_PORTS];
110309 +#ifndef CONFIG_FMAN_ARM
110310 + if (IS_T1023_T1024)
110311 + p_LnxWrpFmPortDev = &p_LnxWrpFmDev->txPorts[*uint32_prop];
110312 +#endif
110313 +
110314 + p_LnxWrpFmPortDev->id = tmp_prop;
110315 + p_LnxWrpFmPortDev->settings.param.portId =
110316 + p_LnxWrpFmPortDev->id;
110317 + p_LnxWrpFmPortDev->settings.param.portType =
110318 + e_FM_PORT_TYPE_TX_10G;
110319 + uint32_prop = (uint32_t *) of_get_property(port_node,
110320 + "fsl,qman-channel-id", &lenp);
110321 + if (uint32_prop == NULL) {
110322 + REPORT_ERROR(MAJOR, E_INVALID_VALUE,
110323 + ("missing fsl,qman-channel-id"));
110324 + return NULL;
110325 + }
110326 + tmp_prop = be32_to_cpu(*uint32_prop);
110327 + if (WARN_ON(lenp != sizeof(uint32_t)))
110328 + return NULL;
110329 + p_LnxWrpFmPortDev->txCh = tmp_prop;
110330 + p_LnxWrpFmPortDev->settings.param.specificParams.nonRxParams.
110331 + qmChannel = p_LnxWrpFmPortDev->txCh;
110332 + } else if (of_device_is_compatible(port_node, "fsl,fman-port-1g-rx")) {
110333 + tmp_prop -= 0x08;
110334 + if (unlikely(tmp_prop >= FM_MAX_NUM_OF_1G_RX_PORTS)) {
110335 + REPORT_ERROR(MAJOR, E_INVALID_VALUE,
110336 + ("of_get_property(%s, cell-index) failed",
110337 + port_node->full_name));
110338 + return NULL;
110339 + }
110340 + p_LnxWrpFmPortDev = &p_LnxWrpFmDev->rxPorts[tmp_prop];
110341 +
110342 + p_LnxWrpFmPortDev->id = tmp_prop;
110343 + p_LnxWrpFmPortDev->settings.param.portId =
110344 + p_LnxWrpFmPortDev->id;
110345 + p_LnxWrpFmPortDev->settings.param.portType = e_FM_PORT_TYPE_RX;
110346 + if (p_LnxWrpFmDev->pcdActive)
110347 + p_LnxWrpFmPortDev->defPcd = p_LnxWrpFmDev->defPcd;
110348 + } else if (of_device_is_compatible(port_node, "fsl,fman-port-10g-rx")) {
110349 + tmp_prop -= 0x10;
110350 + if (unlikely(tmp_prop >= FM_MAX_NUM_OF_10G_RX_PORTS)) {
110351 + REPORT_ERROR(MAJOR, E_INVALID_VALUE,
110352 + ("of_get_property(%s, cell-index) failed",
110353 + port_node->full_name));
110354 + return NULL;
110355 + }
110356 + p_LnxWrpFmPortDev = &p_LnxWrpFmDev->rxPorts[tmp_prop +
110357 + FM_MAX_NUM_OF_1G_RX_PORTS];
110358 +
110359 +#ifndef CONFIG_FMAN_ARM
110360 + if (IS_T1023_T1024)
110361 + p_LnxWrpFmPortDev = &p_LnxWrpFmDev->rxPorts[*uint32_prop];
110362 +#endif
110363 +
110364 + p_LnxWrpFmPortDev->id = tmp_prop;
110365 + p_LnxWrpFmPortDev->settings.param.portId =
110366 + p_LnxWrpFmPortDev->id;
110367 + p_LnxWrpFmPortDev->settings.param.portType =
110368 + e_FM_PORT_TYPE_RX_10G;
110369 + if (p_LnxWrpFmDev->pcdActive)
110370 + p_LnxWrpFmPortDev->defPcd = p_LnxWrpFmDev->defPcd;
110371 + } else {
110372 + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("Illegal port type"));
110373 + return NULL;
110374 + }
110375 +
110376 + _errno = of_address_to_resource(port_node, 0, &res);
110377 + if (unlikely(_errno < 0)) {
110378 + REPORT_ERROR(MAJOR, E_INVALID_VALUE,
110379 + ("of_address_to_resource() = %d", _errno));
110380 + return NULL;
110381 + }
110382 +
110383 + p_LnxWrpFmPortDev->dev = &of_dev->dev;
110384 + p_LnxWrpFmPortDev->baseAddr = 0;
110385 + p_LnxWrpFmPortDev->phys_baseAddr = res.start;
110386 + p_LnxWrpFmPortDev->memSize = res.end + 1 - res.start;
110387 + p_LnxWrpFmPortDev->settings.param.h_Fm = p_LnxWrpFmDev->h_Dev;
110388 + p_LnxWrpFmPortDev->h_LnxWrpFmDev = (t_Handle) p_LnxWrpFmDev;
110389 +
110390 + of_node_put(port_node);
110391 +
110392 + p_LnxWrpFmPortDev->active = TRUE;
110393 +
110394 +#if defined(CONFIG_FMAN_DISABLE_OH_TO_REUSE_RESOURCES)
110395 + /* for performance mode no OH port available. */
110396 + if (p_LnxWrpFmPortDev->settings.param.portType ==
110397 + e_FM_PORT_TYPE_OH_OFFLINE_PARSING)
110398 + p_LnxWrpFmPortDev->active = FALSE;
110399 +#endif
110400 +
110401 + return p_LnxWrpFmPortDev;
110402 +}
110403 +
110404 +struct device_node * GetFmPortAdvArgsDevTreeNode (struct device_node *fm_node,
110405 + e_FmPortType portType,
110406 + uint8_t portId)
110407 +{
110408 + struct device_node *port_node;
110409 + const uint32_t *uint32_prop;
110410 + int lenp;
110411 + char *portTypeString;
110412 + uint32_t tmp_prop;
110413 +
110414 + switch(portType) {
110415 + case e_FM_PORT_TYPE_OH_OFFLINE_PARSING:
110416 + portTypeString = "fsl,fman-port-op-extended-args";
110417 + break;
110418 + case e_FM_PORT_TYPE_TX:
110419 + portTypeString = "fsl,fman-port-1g-tx-extended-args";
110420 + break;
110421 + case e_FM_PORT_TYPE_TX_10G:
110422 + portTypeString = "fsl,fman-port-10g-tx-extended-args";
110423 + break;
110424 + case e_FM_PORT_TYPE_RX:
110425 + portTypeString = "fsl,fman-port-1g-rx-extended-args";
110426 + break;
110427 + case e_FM_PORT_TYPE_RX_10G:
110428 + portTypeString = "fsl,fman-port-10g-rx-extended-args";
110429 + break;
110430 + default:
110431 + return NULL;
110432 + }
110433 +
110434 + for_each_child_of_node(fm_node, port_node) {
110435 + uint32_prop = (uint32_t *)of_get_property(port_node, "cell-index", &lenp);
110436 + if (unlikely(uint32_prop == NULL)) {
110437 + REPORT_ERROR(MAJOR, E_INVALID_VALUE,
110438 + ("of_get_property(%s, cell-index) failed",
110439 + port_node->full_name));
110440 + return NULL;
110441 + }
110442 + tmp_prop = be32_to_cpu(*uint32_prop);
110443 + if (WARN_ON(lenp != sizeof(uint32_t)))
110444 + return NULL;
110445 + if ((portId == tmp_prop) &&
110446 + (of_device_is_compatible(port_node, portTypeString))) {
110447 + return port_node;
110448 + }
110449 + }
110450 +
110451 + return NULL;
110452 +}
110453 +
110454 +static t_Error CheckNConfigFmPortAdvArgs (t_LnxWrpFmPortDev *p_LnxWrpFmPortDev)
110455 +{
110456 + struct device_node *fm_node, *port_node;
110457 + t_Error err;
110458 + t_FmPortRsrc portRsrc;
110459 + const uint32_t *uint32_prop;
110460 + /*const char *str_prop;*/
110461 + int lenp;
110462 +#ifdef CONFIG_FMAN_PFC
110463 + uint8_t i, id, num_pools;
110464 + t_FmBufPoolDepletion poolDepletion;
110465 +
110466 + if (p_LnxWrpFmPortDev->settings.param.portType == e_FM_PORT_TYPE_RX ||
110467 + p_LnxWrpFmPortDev->settings.param.portType == e_FM_PORT_TYPE_RX_10G) {
110468 + memset(&poolDepletion, 0, sizeof(t_FmBufPoolDepletion));
110469 + poolDepletion.singlePoolModeEnable = true;
110470 + num_pools = p_LnxWrpFmPortDev->settings.param.specificParams.rxParams.
110471 + extBufPools.numOfPoolsUsed;
110472 + for (i = 0; i < num_pools; i++) {
110473 + id = p_LnxWrpFmPortDev->settings.param.specificParams.rxParams.
110474 + extBufPools.extBufPool[i].id;
110475 + poolDepletion.poolsToConsiderForSingleMode[id] = true;
110476 + }
110477 +
110478 + for (i = 0; i < CONFIG_FMAN_PFC_COS_COUNT; i++)
110479 + poolDepletion.pfcPrioritiesEn[i] = true;
110480 +
110481 + err = FM_PORT_ConfigPoolDepletion(p_LnxWrpFmPortDev->h_Dev,
110482 + &poolDepletion);
110483 + if (err != E_OK)
110484 + RETURN_ERROR(MAJOR, err, ("FM_PORT_ConfigPoolDepletion() failed"));
110485 + }
110486 +#endif
110487 +
110488 + fm_node = GetFmAdvArgsDevTreeNode(((t_LnxWrpFmDev *) p_LnxWrpFmPortDev->h_LnxWrpFmDev)->id);
110489 + if (!fm_node) /* no advance parameters for FMan */
110490 + return E_OK;
110491 +
110492 + port_node = GetFmPortAdvArgsDevTreeNode(fm_node,
110493 + p_LnxWrpFmPortDev->settings.param.portType,
110494 + p_LnxWrpFmPortDev->settings.param.portId);
110495 + if (!port_node) /* no advance parameters for FMan-Port */
110496 + return E_OK;
110497 +
110498 + uint32_prop = (uint32_t *)of_get_property(port_node, "num-tnums", &lenp);
110499 + if (uint32_prop) {
110500 + if (WARN_ON(lenp != sizeof(uint32_t)*2))
110501 + RETURN_ERROR(MINOR, E_INVALID_VALUE, NO_MSG);
110502 +
110503 + portRsrc.num = be32_to_cpu(uint32_prop[0]);
110504 + portRsrc.extra = be32_to_cpu(uint32_prop[1]);
110505 +
110506 + if ((err = FM_PORT_ConfigNumOfTasks(p_LnxWrpFmPortDev->h_Dev,
110507 + &portRsrc)) != E_OK)
110508 + RETURN_ERROR(MINOR, err, NO_MSG);
110509 + }
110510 +
110511 + uint32_prop = (uint32_t *)of_get_property(port_node, "num-dmas", &lenp);
110512 + if (uint32_prop) {
110513 + if (WARN_ON(lenp != sizeof(uint32_t)*2))
110514 + RETURN_ERROR(MINOR, E_INVALID_VALUE, NO_MSG);
110515 +
110516 + portRsrc.num = be32_to_cpu(uint32_prop[0]);
110517 + portRsrc.extra = be32_to_cpu(uint32_prop[1]);
110518 +
110519 + if ((err = FM_PORT_ConfigNumOfOpenDmas(p_LnxWrpFmPortDev->h_Dev,
110520 + &portRsrc)) != E_OK)
110521 + RETURN_ERROR(MINOR, err, NO_MSG);
110522 + }
110523 +
110524 + uint32_prop = (uint32_t *)of_get_property(port_node, "fifo-size", &lenp);
110525 + if (uint32_prop) {
110526 + if (WARN_ON(lenp != sizeof(uint32_t)*2))
110527 + RETURN_ERROR(MINOR, E_INVALID_VALUE, NO_MSG);
110528 +
110529 + portRsrc.num = be32_to_cpu(uint32_prop[0]);
110530 + portRsrc.extra = be32_to_cpu(uint32_prop[1]);
110531 +
110532 + if ((err = FM_PORT_ConfigSizeOfFifo(p_LnxWrpFmPortDev->h_Dev,
110533 + &portRsrc)) != E_OK)
110534 + RETURN_ERROR(MINOR, err, NO_MSG);
110535 + }
110536 +
110537 + uint32_prop = (uint32_t *)of_get_property(port_node, "errors-to-discard", &lenp);
110538 + if (uint32_prop) {
110539 + if (WARN_ON(lenp != sizeof(uint32_t)))
110540 + RETURN_ERROR(MINOR, E_INVALID_VALUE, NO_MSG);
110541 + if ((err = FM_PORT_ConfigErrorsToDiscard(p_LnxWrpFmPortDev->h_Dev,
110542 + be32_to_cpu(uint32_prop[0]))) != E_OK)
110543 + RETURN_ERROR(MINOR, err, NO_MSG);
110544 + }
110545 +
110546 + uint32_prop = (uint32_t *)of_get_property(port_node, "ar-tables-sizes",
110547 + &lenp);
110548 + if (uint32_prop) {
110549 +
110550 + if (WARN_ON(lenp != sizeof(uint32_t)*8))
110551 + RETURN_ERROR(MINOR, E_INVALID_VALUE, NO_MSG);
110552 + if (WARN_ON(p_LnxWrpFmPortDev->settings.param.portType !=
110553 + e_FM_PORT_TYPE_RX) &&
110554 + (p_LnxWrpFmPortDev->settings.param.portType !=
110555 + e_FM_PORT_TYPE_RX_10G))
110556 + RETURN_ERROR(MINOR, E_INVALID_VALUE,
110557 + ("Auto Response is an Rx port atribute."));
110558 +
110559 + memset(&p_LnxWrpFmPortDev->dsar_table_sizes, 0, sizeof(struct auto_res_tables_sizes));
110560 +
110561 + p_LnxWrpFmPortDev->dsar_table_sizes.max_num_of_arp_entries =
110562 + (uint16_t)be32_to_cpu(uint32_prop[0]);
110563 + p_LnxWrpFmPortDev->dsar_table_sizes.max_num_of_echo_ipv4_entries =
110564 + (uint16_t)be32_to_cpu(uint32_prop[1]);
110565 + p_LnxWrpFmPortDev->dsar_table_sizes.max_num_of_ndp_entries =
110566 + (uint16_t)be32_to_cpu(uint32_prop[2]);
110567 + p_LnxWrpFmPortDev->dsar_table_sizes.max_num_of_echo_ipv6_entries =
110568 + (uint16_t)be32_to_cpu(uint32_prop[3]);
110569 + p_LnxWrpFmPortDev->dsar_table_sizes.max_num_of_snmp_ipv4_entries =
110570 + (uint16_t)be32_to_cpu(uint32_prop[4]);
110571 + p_LnxWrpFmPortDev->dsar_table_sizes.max_num_of_snmp_ipv6_entries =
110572 + (uint16_t)be32_to_cpu(uint32_prop[5]);
110573 + p_LnxWrpFmPortDev->dsar_table_sizes.max_num_of_snmp_oid_entries =
110574 + (uint16_t)be32_to_cpu(uint32_prop[6]);
110575 + p_LnxWrpFmPortDev->dsar_table_sizes.max_num_of_snmp_char =
110576 + (uint16_t)be32_to_cpu(uint32_prop[7]);
110577 +
110578 + uint32_prop = (uint32_t *)of_get_property(port_node,
110579 + "ar-filters-sizes", &lenp);
110580 + if (uint32_prop) {
110581 + if (WARN_ON(lenp != sizeof(uint32_t)*3))
110582 + RETURN_ERROR(MINOR, E_INVALID_VALUE, NO_MSG);
110583 +
110584 + p_LnxWrpFmPortDev->dsar_table_sizes.max_num_of_ip_prot_filtering =
110585 + (uint16_t)be32_to_cpu(uint32_prop[0]);
110586 + p_LnxWrpFmPortDev->dsar_table_sizes.max_num_of_tcp_port_filtering =
110587 + (uint16_t)be32_to_cpu(uint32_prop[1]);
110588 + p_LnxWrpFmPortDev->dsar_table_sizes.max_num_of_udp_port_filtering =
110589 + (uint16_t)be32_to_cpu(uint32_prop[2]);
110590 + }
110591 +
110592 + if ((err = FM_PORT_ConfigDsarSupport(p_LnxWrpFmPortDev->h_Dev,
110593 + (t_FmPortDsarTablesSizes*)&p_LnxWrpFmPortDev->dsar_table_sizes)) != E_OK)
110594 + RETURN_ERROR(MINOR, err, NO_MSG);
110595 + }
110596 +
110597 + of_node_put(port_node);
110598 + of_node_put(fm_node);
110599 +
110600 + return E_OK;
110601 +}
110602 +
110603 +static t_Error CheckNSetFmPortAdvArgs (t_LnxWrpFmPortDev *p_LnxWrpFmPortDev)
110604 +{
110605 + struct device_node *fm_node, *port_node;
110606 + t_Error err;
110607 + const uint32_t *uint32_prop;
110608 + /*const char *str_prop;*/
110609 + int lenp;
110610 +
110611 + fm_node = GetFmAdvArgsDevTreeNode(((t_LnxWrpFmDev *) p_LnxWrpFmPortDev->h_LnxWrpFmDev)->id);
110612 + if (!fm_node) /* no advance parameters for FMan */
110613 + return E_OK;
110614 +
110615 + port_node = GetFmPortAdvArgsDevTreeNode(fm_node,
110616 + p_LnxWrpFmPortDev->settings.param.portType,
110617 + p_LnxWrpFmPortDev->settings.param.portId);
110618 + if (!port_node) /* no advance parameters for FMan-Port */
110619 + return E_OK;
110620 +
110621 +#if (DPAA_VERSION >= 11)
110622 + uint32_prop = (uint32_t *)of_get_property(port_node, "vsp-window", &lenp);
110623 + if (uint32_prop) {
110624 + t_FmPortVSPAllocParams portVSPAllocParams;
110625 + t_FmVspParams fmVspParams;
110626 + t_LnxWrpFmDev *p_LnxWrpFmDev;
110627 + uint8_t portId;
110628 +
110629 + p_LnxWrpFmDev = ((t_LnxWrpFmDev *)p_LnxWrpFmPortDev->h_LnxWrpFmDev);
110630 +
110631 + if (WARN_ON(lenp != sizeof(uint32_t)*2))
110632 + RETURN_ERROR(MINOR, E_INVALID_VALUE, NO_MSG);
110633 +
110634 + if ((p_LnxWrpFmPortDev->settings.param.portType == e_FM_PORT_TYPE_TX) ||
110635 + (p_LnxWrpFmPortDev->settings.param.portType == e_FM_PORT_TYPE_TX_10G) ||
110636 + ((p_LnxWrpFmPortDev->settings.param.portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING) &&
110637 + p_LnxWrpFmPortDev->settings.frag_enabled))
110638 + return E_OK;
110639 +
110640 + memset(&portVSPAllocParams, 0, sizeof(portVSPAllocParams));
110641 + memset(&fmVspParams, 0, sizeof(fmVspParams));
110642 +
110643 + portVSPAllocParams.numOfProfiles = (uint8_t)be32_to_cpu(uint32_prop[0]);
110644 + portVSPAllocParams.dfltRelativeId = (uint8_t)be32_to_cpu(uint32_prop[1]);
110645 + fmVspParams.h_Fm = p_LnxWrpFmDev->h_Dev;
110646 +
110647 + fmVspParams.portParams.portType = p_LnxWrpFmPortDev->settings.param.portType;
110648 + fmVspParams.portParams.portId = p_LnxWrpFmPortDev->settings.param.portId;
110649 + fmVspParams.relativeProfileId = portVSPAllocParams.dfltRelativeId;
110650 +
110651 + if (p_LnxWrpFmPortDev->settings.param.portType != e_FM_PORT_TYPE_OH_OFFLINE_PARSING)
110652 + {
110653 + portId = fmVspParams.portParams.portId;
110654 + if (p_LnxWrpFmPortDev->settings.param.portType == e_FM_PORT_TYPE_RX_10G){
110655 +#ifndef CONFIG_FMAN_ARM
110656 + if (!(IS_T1023_T1024))
110657 +#endif
110658 + portId += FM_MAX_NUM_OF_1G_RX_PORTS;
110659 + }
110660 + portVSPAllocParams.h_FmTxPort =
110661 + p_LnxWrpFmDev->txPorts[portId].h_Dev;
110662 + fmVspParams.liodnOffset =
110663 + p_LnxWrpFmDev->rxPorts[portId].settings.param.specificParams.rxParams.liodnOffset;
110664 + memcpy(&fmVspParams.extBufPools,
110665 + &p_LnxWrpFmPortDev->settings.param.specificParams.rxParams.extBufPools,
110666 + sizeof(t_FmExtPools));
110667 + }
110668 + else
110669 + {
110670 + memcpy(&fmVspParams.extBufPools,
110671 + &p_LnxWrpFmPortDev->opExtPools,
110672 + sizeof(t_FmExtPools));
110673 + }
110674 +
110675 + if ((err = FM_PORT_VSPAlloc(p_LnxWrpFmPortDev->h_Dev,
110676 + &portVSPAllocParams)) != E_OK)
110677 + RETURN_ERROR(MINOR, err, NO_MSG);
110678 +
110679 + /* We're initializing only the default VSP that are being used by the Linux-Ethernet-driver */
110680 + if ((p_LnxWrpFmPortDev->settings.param.portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING) &&
110681 + !p_LnxWrpFmPortDev->opExtPools.numOfPoolsUsed)
110682 + return E_OK;
110683 +
110684 + p_LnxWrpFmPortDev->h_DfltVsp = FM_VSP_Config(&fmVspParams);
110685 + if (!p_LnxWrpFmPortDev->h_DfltVsp)
110686 + RETURN_ERROR(MAJOR, E_INVALID_HANDLE, ("default-VSP for port!"));
110687 +
110688 + if ((err = FM_VSP_ConfigBufferPrefixContent(p_LnxWrpFmPortDev->h_DfltVsp,
110689 + &p_LnxWrpFmPortDev->buffPrefixContent)) != E_OK)
110690 + RETURN_ERROR(MINOR, err, NO_MSG);
110691 +
110692 + if ((err = FM_VSP_Init(p_LnxWrpFmPortDev->h_DfltVsp)) != E_OK)
110693 + RETURN_ERROR(MINOR, err, NO_MSG);
110694 + }
110695 +#else
110696 +UNUSED(err); UNUSED(uint32_prop); UNUSED(lenp);
110697 +#endif /* (DPAA_VERSION >= 11) */
110698 +
110699 + of_node_put(port_node);
110700 + of_node_put(fm_node);
110701 +
110702 + return E_OK;
110703 +}
110704 +
110705 +static t_Error ConfigureFmPortDev(t_LnxWrpFmPortDev *p_LnxWrpFmPortDev)
110706 +{
110707 + t_LnxWrpFmDev *p_LnxWrpFmDev =
110708 + (t_LnxWrpFmDev *) p_LnxWrpFmPortDev->h_LnxWrpFmDev;
110709 + struct resource *dev_res;
110710 +
110711 + if (!p_LnxWrpFmPortDev->active)
110712 + RETURN_ERROR(MAJOR, E_INVALID_STATE,
110713 + ("FM port not configured!!!"));
110714 +
110715 + dev_res =
110716 + __devm_request_region(p_LnxWrpFmDev->dev, p_LnxWrpFmDev->res,
110717 + p_LnxWrpFmPortDev->phys_baseAddr,
110718 + p_LnxWrpFmPortDev->memSize,
110719 + "fman-port-hc");
110720 + if (unlikely(dev_res == NULL))
110721 + RETURN_ERROR(MAJOR, E_INVALID_STATE,
110722 + ("__devm_request_region() failed"));
110723 + p_LnxWrpFmPortDev->baseAddr =
110724 + PTR_TO_UINT(devm_ioremap
110725 + (p_LnxWrpFmDev->dev,
110726 + p_LnxWrpFmPortDev->phys_baseAddr,
110727 + p_LnxWrpFmPortDev->memSize));
110728 + if (unlikely(p_LnxWrpFmPortDev->baseAddr == 0))
110729 + REPORT_ERROR(MAJOR, E_INVALID_STATE,
110730 + ("devm_ioremap() failed"));
110731 +
110732 + p_LnxWrpFmPortDev->settings.param.baseAddr =
110733 + p_LnxWrpFmPortDev->baseAddr;
110734 +
110735 + return E_OK;
110736 +}
110737 +
110738 +static t_Error InitFmPortDev(t_LnxWrpFmPortDev *p_LnxWrpFmPortDev)
110739 +{
110740 +#define MY_ADV_CONFIG_CHECK_END \
110741 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION,\
110742 + ("Advanced configuration routine"));\
110743 + if (errCode != E_OK)\
110744 + RETURN_ERROR(MAJOR, errCode, NO_MSG);\
110745 + }
110746 +
110747 + int i = 0;
110748 +
110749 + if (!p_LnxWrpFmPortDev->active || p_LnxWrpFmPortDev->h_Dev)
110750 + return E_INVALID_STATE;
110751 +
110752 + p_LnxWrpFmPortDev->h_Dev =
110753 + FM_PORT_Config(&p_LnxWrpFmPortDev->settings.param);
110754 + if (p_LnxWrpFmPortDev->h_Dev == NULL)
110755 + RETURN_ERROR(MAJOR, E_INVALID_HANDLE, ("FM-port"));
110756 +
110757 +#ifndef FM_QMI_NO_DEQ_OPTIONS_SUPPORT
110758 + if ((p_LnxWrpFmPortDev->settings.param.portType ==
110759 + e_FM_PORT_TYPE_TX_10G)
110760 + || (p_LnxWrpFmPortDev->settings.param.portType ==
110761 + e_FM_PORT_TYPE_TX)) {
110762 + t_Error errCode = E_OK;
110763 + errCode =
110764 + FM_PORT_ConfigDeqHighPriority(p_LnxWrpFmPortDev->h_Dev,
110765 + TRUE);
110766 + if (errCode != E_OK)
110767 + RETURN_ERROR(MAJOR, errCode, NO_MSG);
110768 + errCode =
110769 + FM_PORT_ConfigDeqPrefetchOption(p_LnxWrpFmPortDev->h_Dev,
110770 + e_FM_PORT_DEQ_FULL_PREFETCH);
110771 + if (errCode
110772 + != E_OK)
110773 + RETURN_ERROR(MAJOR, errCode, NO_MSG);
110774 + }
110775 +#endif /* !FM_QMI_NO_DEQ_OPTIONS_SUPPORT */
110776 +
110777 +#ifndef CONFIG_FMAN_ARM
110778 +#ifdef FM_BCB_ERRATA_BMI_SW001
110779 +/* Configure BCB workaround on Rx ports, only for B4860 rev1 */
110780 +#define SVR_SECURITY_MASK 0x00080000
110781 +#define SVR_PERSONALITY_MASK 0x0000FF00
110782 +#define SVR_VER_IGNORE_MASK (SVR_SECURITY_MASK | SVR_PERSONALITY_MASK)
110783 +#define SVR_B4860_REV1_VALUE 0x86800010
110784 +
110785 + if ((p_LnxWrpFmPortDev->settings.param.portType ==
110786 + e_FM_PORT_TYPE_RX_10G) ||
110787 + (p_LnxWrpFmPortDev->settings.param.portType ==
110788 + e_FM_PORT_TYPE_RX)) {
110789 + unsigned int svr;
110790 +
110791 + svr = mfspr(SPRN_SVR);
110792 +
110793 + if ((svr & ~SVR_VER_IGNORE_MASK) == SVR_B4860_REV1_VALUE)
110794 + FM_PORT_ConfigBCBWorkaround(p_LnxWrpFmPortDev->h_Dev);
110795 + }
110796 +#endif /* FM_BCB_ERRATA_BMI_SW001 */
110797 +#endif /* CONFIG_FMAN_ARM */
110798 +/* Call the driver's advanced configuration routines, if requested:
110799 + Compare the function pointer of each entry to the available routines,
110800 + and invoke the matching routine with proper casting of arguments. */
110801 + while (p_LnxWrpFmPortDev->settings.advConfig[i].p_Function
110802 + && (i < FM_MAX_NUM_OF_ADV_SETTINGS)) {
110803 +
110804 +/* TODO: Change this MACRO */
110805 + ADV_CONFIG_CHECK_START(
110806 + &(p_LnxWrpFmPortDev->settings.advConfig[i]))
110807 +
110808 + ADV_CONFIG_CHECK(p_LnxWrpFmPortDev->h_Dev,
110809 + FM_PORT_ConfigBufferPrefixContent,
110810 + NCSW_PARAMS(1,
110811 + (t_FmBufferPrefixContent *)))
110812 +
110813 + if ((p_LnxWrpFmPortDev->settings.param.portType ==
110814 + e_FM_PORT_TYPE_OH_OFFLINE_PARSING) &&
110815 + (p_LnxWrpFmPortDev->settings.frag_enabled == TRUE)) {
110816 +
110817 + ADV_CONFIG_CHECK(p_LnxWrpFmPortDev->h_Dev,
110818 + FM_PORT_ConfigExtBufPools,
110819 + NCSW_PARAMS(1, (t_FmExtPools *)))
110820 +
110821 + /* this define contains an else */
110822 + MY_ADV_CONFIG_CHECK_END
110823 + }
110824 +
110825 + /* Advance to next advanced configuration entry */
110826 + i++;
110827 + }
110828 +
110829 +
110830 + if ((p_LnxWrpFmPortDev->settings.param.portType != e_FM_PORT_TYPE_TX) &&
110831 + (p_LnxWrpFmPortDev->settings.param.portType != e_FM_PORT_TYPE_TX_10G)) {
110832 + if (FM_PORT_ConfigErrorsToDiscard(p_LnxWrpFmPortDev->h_Dev, (FM_PORT_FRM_ERR_IPRE |
110833 + FM_PORT_FRM_ERR_IPR_NCSP |
110834 + FM_PORT_FRM_ERR_CLS_DISCARD)) !=E_OK)
110835 + RETURN_ERROR(MAJOR, E_INVALID_STATE, NO_MSG);
110836 + }
110837 +
110838 + if (CheckNConfigFmPortAdvArgs(p_LnxWrpFmPortDev) != E_OK)
110839 + RETURN_ERROR(MAJOR, E_INVALID_STATE, NO_MSG);
110840 +
110841 + if (FM_PORT_Init(p_LnxWrpFmPortDev->h_Dev) != E_OK)
110842 + RETURN_ERROR(MAJOR, E_INVALID_STATE, NO_MSG);
110843 +
110844 + if (CheckNSetFmPortAdvArgs(p_LnxWrpFmPortDev) != E_OK)
110845 + RETURN_ERROR(MAJOR, E_INVALID_STATE, NO_MSG);
110846 +
110847 +/* FMan Fifo sizes behind the scene":
110848 + * Using the following formulae (*), under a set of simplifying assumptions (.):
110849 + * . all ports are configured in Normal Mode (rather than Independent Mode)
110850 + * . the DPAA Eth driver allocates buffers of size:
110851 + * . MAXFRM + NET_IP_ALIGN + DPA_PRIV_DATA_SIZE + DPA_PARSE_RESULTS_SIZE
110852 + * + DPA_HASH_RESULTS_SIZE, i.e.:
110853 + * MAXFRM + 2 + 16 + sizeof(t_FmPrsResult) + 16, i.e.:
110854 + * MAXFRM + 66
110855 + * . excessive buffer pools not accounted for
110856 + *
110857 + * * for Rx ports on P4080:
110858 + * . IFSZ = ceil(max(FMBM_EBMPI[PBS]) / 256) * 256 + 7 * 256
110859 + * . no internal frame offset (FMBM_RIM[FOF] == 0) - otherwise,
110860 + * add up to 256 to the above
110861 + *
110862 + * * for Rx ports on P1023:
110863 + * . IFSZ = ceil(second_largest(FMBM_EBMPI[PBS] / 256)) * 256 + 7 * 256,
110864 + * if at least 2 bpools are configured
110865 + * . IFSZ = 8 * 256, if only a single bpool is configured
110866 + *
110867 + * * for Tx ports:
110868 + * . IFSZ = ceil(frame_size / 256) * 256 + 3 * 256
110869 + * + FMBM_TFP[DPDE] * 256, i.e.:
110870 + * IFSZ = ceil(MAXFRM / 256) * 256 + 3 x 256 + FMBM_TFP[DPDE] * 256
110871 + *
110872 + * * for OH ports on P4080:
110873 + * . IFSZ = ceil(frame_size / 256) * 256 + 1 * 256 + FMBM_PP[MXT] * 256
110874 + * * for OH ports on P1023:
110875 + * . IFSZ = ceil(frame_size / 256) * 256 + 3 * 256 + FMBM_TFP[DPDE] * 256
110876 + * * for both P4080 and P1023:
110877 + * . (conservative decisions, assuming that BMI must bring the entire
110878 + * frame, not only the frame header)
110879 + * . no internal frame offset (FMBM_OIM[FOF] == 0) - otherwise,
110880 + * add up to 256 to the above
110881 + *
110882 + * . for P4080/P5020/P3041/P2040, DPDE is:
110883 + * > 0 or 1, for 1Gb ports, HW default: 0
110884 + * > 2..7 (recommended: 3..7) for 10Gb ports, HW default: 3
110885 + * . for P1023, DPDE should be 1
110886 + *
110887 + * . for P1023, MXT is in range (0..31)
110888 + * . for P4080, MXT is in range (0..63)
110889 + *
110890 + */
110891 +#if 0
110892 + if ((p_LnxWrpFmPortDev->defPcd != e_NO_PCD) &&
110893 + (InitFmPort3TupleDefPcd(p_LnxWrpFmPortDev) != E_OK))
110894 + RETURN_ERROR(MAJOR, E_INVALID_STATE, NO_MSG);
110895 +#endif
110896 + return E_OK;
110897 +}
110898 +
110899 +void fm_set_rx_port_params(struct fm_port *port,
110900 + struct fm_port_params *params)
110901 +{
110902 + t_LnxWrpFmPortDev *p_LnxWrpFmPortDev = (t_LnxWrpFmPortDev *) port;
110903 + int i;
110904 +
110905 + p_LnxWrpFmPortDev->settings.param.specificParams.rxParams.errFqid =
110906 + params->errq;
110907 + p_LnxWrpFmPortDev->settings.param.specificParams.rxParams.dfltFqid =
110908 + params->defq;
110909 + p_LnxWrpFmPortDev->settings.param.specificParams.rxParams.extBufPools.
110910 + numOfPoolsUsed = params->num_pools;
110911 + for (i = 0; i < params->num_pools; i++) {
110912 + p_LnxWrpFmPortDev->settings.param.specificParams.rxParams.
110913 + extBufPools.extBufPool[i].id =
110914 + params->pool_param[i].id;
110915 + p_LnxWrpFmPortDev->settings.param.specificParams.rxParams.
110916 + extBufPools.extBufPool[i].size =
110917 + params->pool_param[i].size;
110918 + }
110919 +
110920 + p_LnxWrpFmPortDev->buffPrefixContent.privDataSize =
110921 + params->priv_data_size;
110922 + p_LnxWrpFmPortDev->buffPrefixContent.passPrsResult =
110923 + params->parse_results;
110924 + p_LnxWrpFmPortDev->buffPrefixContent.passHashResult =
110925 + params->hash_results;
110926 + p_LnxWrpFmPortDev->buffPrefixContent.passTimeStamp =
110927 + params->time_stamp;
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 + ADD_ADV_CONFIG_END InitFmPortDev(p_LnxWrpFmPortDev);
110942 +}
110943 +EXPORT_SYMBOL(fm_set_rx_port_params);
110944 +
110945 +/* this function is called from oh_probe as well, thus it contains oh port
110946 + * specific parameters (make sure everything is checked) */
110947 +void fm_set_tx_port_params(struct fm_port *port,
110948 + struct fm_port_params *params)
110949 +{
110950 + t_LnxWrpFmPortDev *p_LnxWrpFmPortDev = (t_LnxWrpFmPortDev *) port;
110951 +
110952 + p_LnxWrpFmPortDev->settings.param.specificParams.nonRxParams.errFqid =
110953 + params->errq;
110954 + p_LnxWrpFmPortDev->settings.param.specificParams.nonRxParams.
110955 + dfltFqid = params->defq;
110956 +
110957 + p_LnxWrpFmPortDev->buffPrefixContent.privDataSize =
110958 + params->priv_data_size;
110959 + p_LnxWrpFmPortDev->buffPrefixContent.passPrsResult =
110960 + params->parse_results;
110961 + p_LnxWrpFmPortDev->buffPrefixContent.passHashResult =
110962 + params->hash_results;
110963 + p_LnxWrpFmPortDev->buffPrefixContent.passTimeStamp =
110964 + params->time_stamp;
110965 + p_LnxWrpFmPortDev->settings.frag_enabled =
110966 + params->frag_enable;
110967 + p_LnxWrpFmPortDev->buffPrefixContent.dataAlign =
110968 + params->data_align;
110969 + p_LnxWrpFmPortDev->buffPrefixContent.manipExtraSpace =
110970 + params->manip_extra_space;
110971 +
110972 + ADD_ADV_CONFIG_START(p_LnxWrpFmPortDev->settings.advConfig,
110973 + FM_MAX_NUM_OF_ADV_SETTINGS)
110974 +
110975 + ADD_ADV_CONFIG_NO_RET(FM_PORT_ConfigBufferPrefixContent,
110976 + ARGS(1,
110977 + (&p_LnxWrpFmPortDev->
110978 + buffPrefixContent)));
110979 +
110980 + /* oh port specific parameter (for fragmentation only) */
110981 + if ((p_LnxWrpFmPortDev->settings.param.portType ==
110982 + e_FM_PORT_TYPE_OH_OFFLINE_PARSING) &&
110983 + params->num_pools) {
110984 + int i;
110985 +
110986 + p_LnxWrpFmPortDev->opExtPools.numOfPoolsUsed = params->num_pools;
110987 + for (i = 0; i < params->num_pools; i++) {
110988 + p_LnxWrpFmPortDev->opExtPools.extBufPool[i].id = params->pool_param[i].id;
110989 + p_LnxWrpFmPortDev->opExtPools.extBufPool[i].size = params->pool_param[i].size;
110990 + }
110991 +
110992 + if (p_LnxWrpFmPortDev->settings.frag_enabled)
110993 + ADD_ADV_CONFIG_NO_RET(FM_PORT_ConfigExtBufPools,
110994 + ARGS(1, (&p_LnxWrpFmPortDev->opExtPools)));
110995 + }
110996 +
110997 + ADD_ADV_CONFIG_END InitFmPortDev(p_LnxWrpFmPortDev);
110998 +}
110999 +EXPORT_SYMBOL(fm_set_tx_port_params);
111000 +
111001 +void fm_mac_set_handle(t_Handle h_lnx_wrp_fm_dev,
111002 + t_Handle h_fm_mac,
111003 + int mac_id)
111004 +{
111005 + t_LnxWrpFmDev *p_lnx_wrp_fm_dev = (t_LnxWrpFmDev *)h_lnx_wrp_fm_dev;
111006 +
111007 + p_lnx_wrp_fm_dev->macs[mac_id].h_Dev = h_fm_mac;
111008 + p_lnx_wrp_fm_dev->macs[mac_id].h_LnxWrpFmDev = h_lnx_wrp_fm_dev;
111009 +}
111010 +EXPORT_SYMBOL(fm_mac_set_handle);
111011 +
111012 +static void LnxwrpFmPcdDevExceptionsCb(t_Handle h_App,
111013 + e_FmPcdExceptions exception)
111014 +{
111015 + t_LnxWrpFmDev *p_LnxWrpFmDev = (t_LnxWrpFmDev *) h_App;
111016 +
111017 + ASSERT_COND(p_LnxWrpFmDev);
111018 +
111019 + DBG(INFO, ("got fm-pcd exception %d", exception));
111020 +
111021 + /* do nothing */
111022 + UNUSED(exception);
111023 +}
111024 +
111025 +static void LnxwrpFmPcdDevIndexedExceptionsCb(t_Handle h_App,
111026 + e_FmPcdExceptions exception,
111027 + uint16_t index)
111028 +{
111029 + t_LnxWrpFmDev *p_LnxWrpFmDev = (t_LnxWrpFmDev *) h_App;
111030 +
111031 + ASSERT_COND(p_LnxWrpFmDev);
111032 +
111033 + DBG(INFO,
111034 + ("got fm-pcd-indexed exception %d, indx %d", exception, index));
111035 +
111036 + /* do nothing */
111037 + UNUSED(exception);
111038 + UNUSED(index);
111039 +}
111040 +
111041 +static t_Error InitFmPcdDev(t_LnxWrpFmDev *p_LnxWrpFmDev)
111042 +{
111043 + spin_lock_init(&lock);
111044 +
111045 + if (p_LnxWrpFmDev->pcdActive) {
111046 + t_LnxWrpFmPortDev *p_LnxWrpFmPortDev = &p_LnxWrpFmDev->hcPort;
111047 + t_FmPcdParams fmPcdParams;
111048 + t_Error err;
111049 +
111050 + memset(&fmPcdParams, 0, sizeof(fmPcdParams));
111051 + fmPcdParams.h_Fm = p_LnxWrpFmDev->h_Dev;
111052 + fmPcdParams.prsSupport = p_LnxWrpFmDev->prsActive;
111053 + fmPcdParams.kgSupport = p_LnxWrpFmDev->kgActive;
111054 + fmPcdParams.plcrSupport = p_LnxWrpFmDev->plcrActive;
111055 + fmPcdParams.ccSupport = p_LnxWrpFmDev->ccActive;
111056 + fmPcdParams.numOfSchemes = FM_PCD_KG_NUM_OF_SCHEMES;
111057 +
111058 +#ifndef CONFIG_GUEST_PARTITION
111059 + fmPcdParams.f_Exception = LnxwrpFmPcdDevExceptionsCb;
111060 + if (fmPcdParams.kgSupport)
111061 + fmPcdParams.f_ExceptionId =
111062 + LnxwrpFmPcdDevIndexedExceptionsCb;
111063 + fmPcdParams.h_App = p_LnxWrpFmDev;
111064 +#endif /* !CONFIG_GUEST_PARTITION */
111065 +
111066 +#ifdef CONFIG_MULTI_PARTITION_SUPPORT
111067 + fmPcdParams.numOfSchemes = 0;
111068 + fmPcdParams.numOfClsPlanEntries = 0;
111069 + fmPcdParams.partitionId = 0;
111070 +#endif /* CONFIG_MULTI_PARTITION_SUPPORT */
111071 + fmPcdParams.useHostCommand = TRUE;
111072 +
111073 + p_LnxWrpFmDev->hc_tx_fq =
111074 + FqAlloc(p_LnxWrpFmDev,
111075 + 0,
111076 + QMAN_FQ_FLAG_TO_DCPORTAL,
111077 + p_LnxWrpFmPortDev->txCh, 0);
111078 + if (!p_LnxWrpFmDev->hc_tx_fq)
111079 + RETURN_ERROR(MAJOR, E_NULL_POINTER,
111080 + ("Frame queue allocation failed..."));
111081 +
111082 + p_LnxWrpFmDev->hc_tx_conf_fq =
111083 + FqAlloc(p_LnxWrpFmDev,
111084 + 0,
111085 + QMAN_FQ_FLAG_NO_ENQUEUE,
111086 + p_LnxWrpFmDev->hcCh, 1);
111087 + if (!p_LnxWrpFmDev->hc_tx_conf_fq)
111088 + RETURN_ERROR(MAJOR, E_NULL_POINTER,
111089 + ("Frame queue allocation failed..."));
111090 +
111091 + p_LnxWrpFmDev->hc_tx_err_fq =
111092 + FqAlloc(p_LnxWrpFmDev,
111093 + 0,
111094 + QMAN_FQ_FLAG_NO_ENQUEUE,
111095 + p_LnxWrpFmDev->hcCh, 2);
111096 + if (!p_LnxWrpFmDev->hc_tx_err_fq)
111097 + RETURN_ERROR(MAJOR, E_NULL_POINTER,
111098 + ("Frame queue allocation failed..."));
111099 +
111100 + fmPcdParams.hc.portBaseAddr = p_LnxWrpFmPortDev->baseAddr;
111101 + fmPcdParams.hc.portId =
111102 + p_LnxWrpFmPortDev->settings.param.portId;
111103 + fmPcdParams.hc.liodnBase =
111104 + p_LnxWrpFmPortDev->settings.param.liodnBase;
111105 + fmPcdParams.hc.errFqid =
111106 + qman_fq_fqid(p_LnxWrpFmDev->hc_tx_err_fq);
111107 + fmPcdParams.hc.confFqid =
111108 + qman_fq_fqid(p_LnxWrpFmDev->hc_tx_conf_fq);
111109 + fmPcdParams.hc.qmChannel = p_LnxWrpFmPortDev->txCh;
111110 + fmPcdParams.hc.f_QmEnqueue = QmEnqueueCB;
111111 + fmPcdParams.hc.h_QmArg = (t_Handle) p_LnxWrpFmDev;
111112 +
111113 + p_LnxWrpFmDev->h_PcdDev = FM_PCD_Config(&fmPcdParams);
111114 + if (!p_LnxWrpFmDev->h_PcdDev)
111115 + RETURN_ERROR(MAJOR, E_INVALID_HANDLE, ("FM PCD!"));
111116 +
111117 + err =
111118 + FM_PCD_ConfigPlcrNumOfSharedProfiles(p_LnxWrpFmDev->h_PcdDev,
111119 + LNXWRP_FM_NUM_OF_SHARED_PROFILES);
111120 + if (err != E_OK)
111121 + RETURN_ERROR(MAJOR, err, NO_MSG);
111122 +
111123 + err = FM_PCD_Init(p_LnxWrpFmDev->h_PcdDev);
111124 + if (err != E_OK)
111125 + RETURN_ERROR(MAJOR, err, NO_MSG);
111126 +
111127 + if (p_LnxWrpFmDev->err_irq == 0) {
111128 + FM_PCD_SetException(p_LnxWrpFmDev->h_PcdDev,
111129 + e_FM_PCD_KG_EXCEPTION_DOUBLE_ECC,
111130 + FALSE);
111131 + FM_PCD_SetException(p_LnxWrpFmDev->h_PcdDev,
111132 + e_FM_PCD_KG_EXCEPTION_KEYSIZE_OVERFLOW,
111133 + FALSE);
111134 + FM_PCD_SetException(p_LnxWrpFmDev->h_PcdDev,
111135 + e_FM_PCD_PLCR_EXCEPTION_INIT_ENTRY_ERROR,
111136 + FALSE);
111137 + FM_PCD_SetException(p_LnxWrpFmDev->h_PcdDev,
111138 + e_FM_PCD_PLCR_EXCEPTION_DOUBLE_ECC,
111139 + FALSE);
111140 + FM_PCD_SetException(p_LnxWrpFmDev->h_PcdDev,
111141 + e_FM_PCD_PRS_EXCEPTION_DOUBLE_ECC,
111142 + FALSE);
111143 + FM_PCD_SetException(p_LnxWrpFmDev->h_PcdDev,
111144 + e_FM_PCD_PLCR_EXCEPTION_PRAM_SELF_INIT_COMPLETE,
111145 + FALSE);
111146 + FM_PCD_SetException(p_LnxWrpFmDev->h_PcdDev,
111147 + e_FM_PCD_PLCR_EXCEPTION_ATOMIC_ACTION_COMPLETE,
111148 + FALSE);
111149 + FM_PCD_SetException(p_LnxWrpFmDev->h_PcdDev,
111150 + e_FM_PCD_PRS_EXCEPTION_SINGLE_ECC,
111151 + FALSE);
111152 + }
111153 + }
111154 +
111155 + return E_OK;
111156 +}
111157 +
111158 +void FreeFmPcdDev(t_LnxWrpFmDev *p_LnxWrpFmDev)
111159 +{
111160 +
111161 + if (p_LnxWrpFmDev->h_PcdDev)
111162 + FM_PCD_Free(p_LnxWrpFmDev->h_PcdDev);
111163 +
111164 + if (p_LnxWrpFmDev->hc_tx_err_fq)
111165 + FqFree(p_LnxWrpFmDev->hc_tx_err_fq);
111166 +
111167 + if (p_LnxWrpFmDev->hc_tx_conf_fq)
111168 + FqFree(p_LnxWrpFmDev->hc_tx_conf_fq);
111169 +
111170 + if (p_LnxWrpFmDev->hc_tx_fq)
111171 + FqFree(p_LnxWrpFmDev->hc_tx_fq);
111172 +}
111173 +
111174 +static void FreeFmPortDev(t_LnxWrpFmPortDev *p_LnxWrpFmPortDev)
111175 +{
111176 + t_LnxWrpFmDev *p_LnxWrpFmDev =
111177 + (t_LnxWrpFmDev *) p_LnxWrpFmPortDev->h_LnxWrpFmDev;
111178 +
111179 + if (!p_LnxWrpFmPortDev->active)
111180 + return;
111181 +
111182 + if (p_LnxWrpFmPortDev->h_Dev)
111183 + FM_PORT_Free(p_LnxWrpFmPortDev->h_Dev);
111184 +
111185 + devm_iounmap(p_LnxWrpFmDev->dev,
111186 + UINT_TO_PTR(p_LnxWrpFmPortDev->baseAddr));
111187 + __devm_release_region(p_LnxWrpFmDev->dev, p_LnxWrpFmDev->res,
111188 + p_LnxWrpFmPortDev->phys_baseAddr,
111189 + p_LnxWrpFmPortDev->memSize);
111190 +}
111191 +
111192 +static int /*__devinit*/ fm_port_probe(struct platform_device *of_dev)
111193 +{
111194 + t_LnxWrpFmPortDev *p_LnxWrpFmPortDev;
111195 + t_LnxWrpFmDev *p_LnxWrpFmDev;
111196 + struct device *dev;
111197 +
111198 + dev = &of_dev->dev;
111199 +
111200 + p_LnxWrpFmPortDev = ReadFmPortDevTreeNode(of_dev);
111201 + if (p_LnxWrpFmPortDev == NULL)
111202 + return -EIO;
111203 + /* Port can be inactive, thus will not be probed:
111204 + - in performance mode, OH ports are disabled
111205 + ...
111206 + */
111207 + if (!p_LnxWrpFmPortDev->active)
111208 + return 0;
111209 +
111210 + if (ConfigureFmPortDev(p_LnxWrpFmPortDev) != E_OK)
111211 + return -EIO;
111212 +
111213 + dev_set_drvdata(dev, p_LnxWrpFmPortDev);
111214 +
111215 + if (p_LnxWrpFmPortDev->settings.param.portType ==
111216 + e_FM_PORT_TYPE_OH_HOST_COMMAND)
111217 + InitFmPcdDev((t_LnxWrpFmDev *) p_LnxWrpFmPortDev->h_LnxWrpFmDev);
111218 +
111219 + p_LnxWrpFmDev = (t_LnxWrpFmDev *) p_LnxWrpFmPortDev->h_LnxWrpFmDev;
111220 +
111221 + if (p_LnxWrpFmPortDev->settings.param.portType == e_FM_PORT_TYPE_RX) {
111222 + Sprint(p_LnxWrpFmPortDev->name, "%s-port-rx%d",
111223 + p_LnxWrpFmDev->name, p_LnxWrpFmPortDev->id);
111224 + p_LnxWrpFmPortDev->minor =
111225 + p_LnxWrpFmPortDev->id + DEV_FM_RX_PORTS_MINOR_BASE;
111226 + } else if (p_LnxWrpFmPortDev->settings.param.portType ==
111227 + e_FM_PORT_TYPE_RX_10G) {
111228 + Sprint(p_LnxWrpFmPortDev->name, "%s-port-rx%d",
111229 + p_LnxWrpFmDev->name,
111230 + p_LnxWrpFmPortDev->id + FM_MAX_NUM_OF_1G_RX_PORTS);
111231 + p_LnxWrpFmPortDev->minor =
111232 + p_LnxWrpFmPortDev->id + FM_MAX_NUM_OF_1G_RX_PORTS +
111233 + DEV_FM_RX_PORTS_MINOR_BASE;
111234 +#ifndef CONFIG_FMAN_ARM
111235 + if (IS_T1023_T1024) {
111236 + Sprint(p_LnxWrpFmPortDev->name, "%s-port-rx%d",
111237 + p_LnxWrpFmDev->name,
111238 + p_LnxWrpFmPortDev->id);
111239 + p_LnxWrpFmPortDev->minor =
111240 + p_LnxWrpFmPortDev->id +
111241 + DEV_FM_RX_PORTS_MINOR_BASE;
111242 + }
111243 +#endif
111244 + } else if (p_LnxWrpFmPortDev->settings.param.portType ==
111245 + e_FM_PORT_TYPE_TX) {
111246 + Sprint(p_LnxWrpFmPortDev->name, "%s-port-tx%d",
111247 + p_LnxWrpFmDev->name, p_LnxWrpFmPortDev->id);
111248 + p_LnxWrpFmPortDev->minor =
111249 + p_LnxWrpFmPortDev->id + DEV_FM_TX_PORTS_MINOR_BASE;
111250 + } else if (p_LnxWrpFmPortDev->settings.param.portType ==
111251 + e_FM_PORT_TYPE_TX_10G) {
111252 + Sprint(p_LnxWrpFmPortDev->name, "%s-port-tx%d",
111253 + p_LnxWrpFmDev->name,
111254 + p_LnxWrpFmPortDev->id + FM_MAX_NUM_OF_1G_TX_PORTS);
111255 + p_LnxWrpFmPortDev->minor =
111256 + p_LnxWrpFmPortDev->id + FM_MAX_NUM_OF_1G_TX_PORTS +
111257 + DEV_FM_TX_PORTS_MINOR_BASE;
111258 +#ifndef CONFIG_FMAN_ARM
111259 + if (IS_T1023_T1024) {
111260 + Sprint(p_LnxWrpFmPortDev->name, "%s-port-tx%d",
111261 + p_LnxWrpFmDev->name,
111262 + p_LnxWrpFmPortDev->id);
111263 + p_LnxWrpFmPortDev->minor =
111264 + p_LnxWrpFmPortDev->id +
111265 + DEV_FM_TX_PORTS_MINOR_BASE;
111266 + }
111267 +#endif
111268 + } else if (p_LnxWrpFmPortDev->settings.param.portType ==
111269 + e_FM_PORT_TYPE_OH_HOST_COMMAND) {
111270 + Sprint(p_LnxWrpFmPortDev->name, "%s-port-oh%d",
111271 + p_LnxWrpFmDev->name, p_LnxWrpFmPortDev->id);
111272 + p_LnxWrpFmPortDev->minor =
111273 + p_LnxWrpFmPortDev->id + DEV_FM_OH_PORTS_MINOR_BASE;
111274 + } else if (p_LnxWrpFmPortDev->settings.param.portType ==
111275 + e_FM_PORT_TYPE_OH_OFFLINE_PARSING) {
111276 + Sprint(p_LnxWrpFmPortDev->name, "%s-port-oh%d",
111277 + p_LnxWrpFmDev->name, p_LnxWrpFmPortDev->id + 1);
111278 + p_LnxWrpFmPortDev->minor =
111279 + p_LnxWrpFmPortDev->id + 1 +
111280 + DEV_FM_OH_PORTS_MINOR_BASE;
111281 + }
111282 +
111283 + device_create(p_LnxWrpFmDev->fm_class, NULL,
111284 + MKDEV(p_LnxWrpFmDev->major, p_LnxWrpFmPortDev->minor),
111285 + NULL, p_LnxWrpFmPortDev->name);
111286 +
111287 + /* create sysfs entries for stats and regs */
111288 +
111289 + if (fm_port_sysfs_create(dev) != 0) {
111290 + FreeFmPortDev(p_LnxWrpFmPortDev);
111291 + REPORT_ERROR(MAJOR, E_INVALID_STATE,
111292 + ("Unable to create sys entry - fm port!!!"));
111293 + return -EIO;
111294 + }
111295 +
111296 +#ifdef FM_TX_INVALID_ECC_ERRATA_10GMAC_A009
111297 + FM_DisableRamsEcc(p_LnxWrpFmDev->h_Dev);
111298 +#endif /* FM_TX_INVALID_ECC_ERRATA_10GMAC_A009 */
111299 +
111300 + DBG(TRACE, ("%s probed", p_LnxWrpFmPortDev->name));
111301 +
111302 + return 0;
111303 +}
111304 +
111305 +static int fm_port_remove(struct platform_device *of_dev)
111306 +{
111307 + t_LnxWrpFmPortDev *p_LnxWrpFmPortDev;
111308 + t_LnxWrpFmDev *p_LnxWrpFmDev;
111309 + struct device *dev;
111310 +
111311 + dev = &of_dev->dev;
111312 + p_LnxWrpFmPortDev = dev_get_drvdata(dev);
111313 +
111314 + fm_port_sysfs_destroy(dev);
111315 +
111316 + p_LnxWrpFmDev = (t_LnxWrpFmDev *) p_LnxWrpFmPortDev->h_LnxWrpFmDev;
111317 + device_destroy(p_LnxWrpFmDev->fm_class,
111318 + MKDEV(p_LnxWrpFmDev->major, p_LnxWrpFmPortDev->minor));
111319 +
111320 + FreeFmPortDev(p_LnxWrpFmPortDev);
111321 +
111322 + dev_set_drvdata(dev, NULL);
111323 +
111324 + return 0;
111325 +}
111326 +
111327 +static const struct of_device_id fm_port_match[] = {
111328 + {
111329 + .compatible = "fsl,fman-port-oh"},
111330 + {
111331 + .compatible = "fsl,fman-port-1g-rx"},
111332 + {
111333 + .compatible = "fsl,fman-port-10g-rx"},
111334 + {
111335 + .compatible = "fsl,fman-port-1g-tx"},
111336 + {
111337 + .compatible = "fsl,fman-port-10g-tx"},
111338 + {}
111339 +};
111340 +
111341 +#ifndef MODULE
111342 +MODULE_DEVICE_TABLE(of, fm_port_match);
111343 +#endif /* !MODULE */
111344 +
111345 +static struct platform_driver fm_port_driver = {
111346 +
111347 + .driver = {
111348 + .name = "fsl-fman-port",
111349 + .of_match_table = fm_port_match,
111350 + .owner = THIS_MODULE,
111351 + },
111352 + .probe = fm_port_probe,
111353 + .remove = fm_port_remove
111354 +};
111355 +
111356 +
111357 +t_Error LNXWRP_FM_Port_Init(void)
111358 +{
111359 + /* Register to the DTB for basic FM port API */
111360 + if (platform_driver_register(&fm_port_driver))
111361 + return E_NO_DEVICE;
111362 +
111363 + return E_OK;
111364 +}
111365 +
111366 +void LNXWRP_FM_Port_Free(void)
111367 +{
111368 + platform_driver_unregister(&fm_port_driver);
111369 +}
111370 +
111371 +static int __init __cold fm_port_load(void)
111372 +{
111373 + if (LNXWRP_FM_Port_Init() != E_OK) {
111374 + printk(KERN_CRIT "Failed to init FM Ports wrapper!\n");
111375 + return -ENODEV;
111376 + }
111377 +
111378 + printk(KERN_CRIT "Freescale FM Ports module\n");
111379 +
111380 + return 0;
111381 +}
111382 +
111383 +static void __exit __cold fm_port_unload(void)
111384 +{
111385 + LNXWRP_FM_Port_Free();
111386 +}
111387 +
111388 +module_init(fm_port_load);
111389 +module_exit(fm_port_unload);
111390 --- /dev/null
111391 +++ b/drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_ioctls_fm.c
111392 @@ -0,0 +1,4854 @@
111393 +/*
111394 + * Copyright 2008-2012 Freescale Semiconductor Inc.
111395 + *
111396 + * Redistribution and use in source and binary forms, with or without
111397 + * modification, are permitted provided that the following conditions are met:
111398 + * * Redistributions of source code must retain the above copyright
111399 + * notice, this list of conditions and the following disclaimer.
111400 + * * Redistributions in binary form must reproduce the above copyright
111401 + * notice, this list of conditions and the following disclaimer in the
111402 + * documentation and/or other materials provided with the distribution.
111403 + * * Neither the name of Freescale Semiconductor nor the
111404 + * names of its contributors may be used to endorse or promote products
111405 + * derived from this software without specific prior written permission.
111406 + *
111407 + *
111408 + * ALTERNATIVELY, this software may be distributed under the terms of the
111409 + * GNU General Public License ("GPL") as published by the Free Software
111410 + * Foundation, either version 2 of that License or (at your option) any
111411 + * later version.
111412 + *
111413 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
111414 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
111415 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
111416 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
111417 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
111418 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
111419 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
111420 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
111421 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
111422 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
111423 + */
111424 +
111425 +/*
111426 + @File lnxwrp_ioctls_fm.c
111427 + @Author Shlomi Gridish
111428 + @Description FM Linux wrapper functions.
111429 +*/
111430 +
111431 +/* Linux Headers ------------------- */
111432 +#include <linux/version.h>
111433 +
111434 +#if defined(CONFIG_MODVERSIONS) && !defined(MODVERSIONS)
111435 +#define MODVERSIONS
111436 +#endif
111437 +#ifdef MODVERSIONS
111438 +#include <config/modversions.h>
111439 +#endif /* MODVERSIONS */
111440 +
111441 +#include <linux/kernel.h>
111442 +#include <linux/module.h>
111443 +#include <linux/slab.h>
111444 +#include <linux/fs.h>
111445 +#include <linux/cdev.h>
111446 +#include <linux/device.h>
111447 +#include <linux/irq.h>
111448 +#include <linux/interrupt.h>
111449 +#include <linux/io.h>
111450 +#include <linux/ioport.h>
111451 +#include <linux/of_platform.h>
111452 +#include <linux/uaccess.h>
111453 +#include <asm/errno.h>
111454 +#ifndef CONFIG_FMAN_ARM
111455 +#include <sysdev/fsl_soc.h>
111456 +#include <linux/fsl/svr.h>
111457 +#endif
111458 +
111459 +#if defined(CONFIG_COMPAT)
111460 +#include <linux/compat.h>
111461 +#endif
111462 +
111463 +#include "part_ext.h"
111464 +#include "fm_ioctls.h"
111465 +#include "fm_pcd_ioctls.h"
111466 +#include "fm_port_ioctls.h"
111467 +#include "fm_vsp_ext.h"
111468 +
111469 +#ifndef CONFIG_FMAN_ARM
111470 +#define IS_T1023_T1024 (SVR_SOC_VER(mfspr(SPRN_SVR)) == SVR_T1024 || \
111471 + SVR_SOC_VER(mfspr(SPRN_SVR)) == SVR_T1023)
111472 +#endif
111473 +
111474 +#define __ERR_MODULE__ MODULE_FM
111475 +
111476 +#if defined(CONFIG_COMPAT)
111477 +#include "lnxwrp_ioctls_fm_compat.h"
111478 +#endif
111479 +
111480 +#include "lnxwrp_fm.h"
111481 +
111482 +#define CMP_IOC_DEFINE(def) (IOC_##def != def)
111483 +
111484 +/* fm_pcd_ioctls.h === fm_pcd_ext.h assertions */
111485 +#if CMP_IOC_DEFINE(FM_PCD_MAX_NUM_OF_PRIVATE_HDRS)
111486 +#error Error: please synchronize IOC_ defines!
111487 +#endif
111488 +
111489 +#if CMP_IOC_DEFINE(FM_PCD_PRS_NUM_OF_HDRS)
111490 +#error Error: please synchronize IOC_ defines!
111491 +#endif
111492 +
111493 +#if CMP_IOC_DEFINE(FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS)
111494 +#error Error: please synchronize IOC_ defines!
111495 +#endif
111496 +
111497 +#if CMP_IOC_DEFINE(FM_PCD_MAX_NUM_OF_INTERCHANGEABLE_HDRS)
111498 +#error Error: please synchronize IOC_ defines!
111499 +#endif
111500 +
111501 +#if CMP_IOC_DEFINE(FM_PCD_KG_NUM_OF_GENERIC_REGS)
111502 +#error Error: please synchronize IOC_ defines!
111503 +#endif
111504 +
111505 +#if CMP_IOC_DEFINE(FM_PCD_KG_MAX_NUM_OF_EXTRACTS_PER_KEY)
111506 +#error Error: please synchronize IOC_ defines!
111507 +#endif
111508 +
111509 +#if CMP_IOC_DEFINE(FM_PCD_KG_NUM_OF_EXTRACT_MASKS)
111510 +#error Error: please synchronize IOC_ defines!
111511 +#endif
111512 +
111513 +#if CMP_IOC_DEFINE(FM_PCD_KG_NUM_OF_DEFAULT_GROUPS)
111514 +#error Error: please synchronize IOC_ defines!
111515 +#endif
111516 +
111517 +#if CMP_IOC_DEFINE(FM_PCD_PRS_NUM_OF_LABELS)
111518 +#error Error: please synchronize IOC_ defines!
111519 +#endif
111520 +
111521 +#if CMP_IOC_DEFINE(FM_PCD_SW_PRS_SIZE)
111522 +#error Error: please synchronize IOC_ defines!
111523 +#endif
111524 +
111525 +#if CMP_IOC_DEFINE(FM_PCD_MAX_MANIP_INSRT_TEMPLATE_SIZE)
111526 +#error Error: please synchronize IOC_ defines!
111527 +#endif
111528 +
111529 +#if DPAA_VERSION >= 11
111530 +#if CMP_IOC_DEFINE(FM_PCD_FRM_REPLIC_MAX_NUM_OF_ENTRIES)
111531 +#error Error: please synchronize IOC_ defines!
111532 +#endif
111533 +#endif
111534 +
111535 +#if CMP_IOC_DEFINE(FM_PCD_MAX_NUM_OF_CC_TREES)
111536 +#error Error: please synchronize IOC_ defines!
111537 +#endif
111538 +
111539 +#if CMP_IOC_DEFINE(FM_PCD_MAX_NUM_OF_CC_GROUPS)
111540 +#error Error: please synchronize IOC_ defines!
111541 +#endif
111542 +
111543 +#if CMP_IOC_DEFINE(FM_PCD_MAX_NUM_OF_CC_UNITS)
111544 +#error Error: please synchronize IOC_ defines!
111545 +#endif
111546 +
111547 +#if CMP_IOC_DEFINE(FM_PCD_MAX_NUM_OF_KEYS)
111548 +#error Error: please synchronize IOC_ defines!
111549 +#endif
111550 +
111551 +#if CMP_IOC_DEFINE(FM_PCD_MAX_SIZE_OF_KEY)
111552 +#error Error: please synchronize IOC_ defines!
111553 +#endif
111554 +
111555 +#if CMP_IOC_DEFINE(FM_PCD_MAX_NUM_OF_CC_ENTRIES_IN_GRP)
111556 +#error Error: please synchronize IOC_ defines!
111557 +#endif
111558 +
111559 +#if CMP_IOC_DEFINE(FM_PCD_LAST_KEY_INDEX)
111560 +#error Error: please synchronize IOC_ defines!
111561 +#endif
111562 +
111563 +/* net_ioctls.h === net_ext.h assertions */
111564 +#if CMP_IOC_DEFINE(NET_HEADER_FIELD_PPP_PID)
111565 +#error Error: please synchronize IOC_ defines!
111566 +#endif
111567 +
111568 +#if CMP_IOC_DEFINE(NET_HEADER_FIELD_PPP_COMPRESSED)
111569 +#error Error: please synchronize IOC_ defines!
111570 +#endif
111571 +
111572 +#if CMP_IOC_DEFINE(NET_HEADER_FIELD_PPP_ALL_FIELDS)
111573 +#error Error: please synchronize IOC_ defines!
111574 +#endif
111575 +
111576 +#if CMP_IOC_DEFINE(NET_HEADER_FIELD_PPPoE_ALL_FIELDS)
111577 +#error Error: please synchronize IOC_ defines!
111578 +#endif
111579 +
111580 +#if CMP_IOC_DEFINE(NET_HEADER_FIELD_PPPMUX_ALL_FIELDS)
111581 +#error Error: please synchronize IOC_ defines!
111582 +#endif
111583 +
111584 +#if CMP_IOC_DEFINE(NET_HEADER_FIELD_PPPMUX_SUBFRAME_ALL_FIELDS)
111585 +#error Error: please synchronize IOC_ defines!
111586 +#endif
111587 +
111588 +#if CMP_IOC_DEFINE(NET_HEADER_FIELD_ETH_ALL_FIELDS)
111589 +#error Error: please synchronize IOC_ defines!
111590 +#endif
111591 +
111592 +#if CMP_IOC_DEFINE(NET_HEADER_FIELD_IPv4_ALL_FIELDS)
111593 +#error Error: please synchronize IOC_ defines!
111594 +#endif
111595 +
111596 +#if CMP_IOC_DEFINE(NET_HEADER_FIELD_IPv6_ALL_FIELDS)
111597 +#error Error: please synchronize IOC_ defines!
111598 +#endif
111599 +
111600 +#if CMP_IOC_DEFINE(NET_HEADER_FIELD_ICMP_ALL_FIELDS)
111601 +#error Error: please synchronize IOC_ defines!
111602 +#endif
111603 +
111604 +#if CMP_IOC_DEFINE(NET_HEADER_FIELD_IGMP_ALL_FIELDS)
111605 +#error Error: please synchronize IOC_ defines!
111606 +#endif
111607 +
111608 +#if CMP_IOC_DEFINE(NET_HEADER_FIELD_TCP_ALL_FIELDS)
111609 +#error Error: please synchronize IOC_ defines!
111610 +#endif
111611 +
111612 +#if CMP_IOC_DEFINE(NET_HEADER_FIELD_SCTP_ALL_FIELDS)
111613 +#error Error: please synchronize IOC_ defines!
111614 +#endif
111615 +
111616 +#if CMP_IOC_DEFINE(NET_HEADER_FIELD_DCCP_ALL_FIELDS)
111617 +#error Error: please synchronize IOC_ defines!
111618 +#endif
111619 +
111620 +#if CMP_IOC_DEFINE(NET_HEADER_FIELD_UDP_ALL_FIELDS)
111621 +#error Error: please synchronize IOC_ defines!
111622 +#endif
111623 +
111624 +#if CMP_IOC_DEFINE(NET_HEADER_FIELD_UDP_ENCAP_ESP_ALL_FIELDS)
111625 +#error Error: please synchronize IOC_ defines!
111626 +#endif
111627 +
111628 +#if CMP_IOC_DEFINE(NET_HEADER_FIELD_IPHC_ALL_FIELDS)
111629 +#error Error: please synchronize IOC_ defines!
111630 +#endif
111631 +
111632 +#if CMP_IOC_DEFINE(NET_HEADER_FIELD_SCTP_CHUNK_DATA_ALL_FIELDS)
111633 +#error Error: please synchronize IOC_ defines!
111634 +#endif
111635 +
111636 +#if CMP_IOC_DEFINE(NET_HEADER_FIELD_L2TPv2_ALL_FIELDS)
111637 +#error Error: please synchronize IOC_ defines!
111638 +#endif
111639 +
111640 +#if CMP_IOC_DEFINE(NET_HEADER_FIELD_L2TPv3_CTRL_ALL_FIELDS)
111641 +#error Error: please synchronize IOC_ defines!
111642 +#endif
111643 +
111644 +#if CMP_IOC_DEFINE(NET_HEADER_FIELD_L2TPv3_SESS_ALL_FIELDS)
111645 +#error Error: please synchronize IOC_ defines!
111646 +#endif
111647 +
111648 +#if CMP_IOC_DEFINE(NET_HEADER_FIELD_VLAN_ALL_FIELDS)
111649 +#error Error: please synchronize IOC_ defines!
111650 +#endif
111651 +
111652 +#if CMP_IOC_DEFINE(NET_HEADER_FIELD_LLC_ALL_FIELDS)
111653 +#error Error: please synchronize IOC_ defines!
111654 +#endif
111655 +
111656 +#if CMP_IOC_DEFINE(NET_HEADER_FIELD_NLPID_ALL_FIELDS)
111657 +#error Error: please synchronize IOC_ defines!
111658 +#endif
111659 +
111660 +#if CMP_IOC_DEFINE(NET_HEADER_FIELD_SNAP_ALL_FIELDS)
111661 +#error Error: please synchronize IOC_ defines!
111662 +#endif
111663 +
111664 +#if CMP_IOC_DEFINE(NET_HEADER_FIELD_LLC_SNAP_ALL_FIELDS)
111665 +#warning Error: please synchronize IOC_ defines!
111666 +#endif
111667 +
111668 +#if CMP_IOC_DEFINE(NET_HEADER_FIELD_ARP_ALL_FIELDS)
111669 +#error Error: please synchronize IOC_ defines!
111670 +#endif
111671 +
111672 +#if CMP_IOC_DEFINE(NET_HEADER_FIELD_RFC2684_ALL_FIELDS)
111673 +#error Error: please synchronize IOC_ defines!
111674 +#endif
111675 +
111676 +#if CMP_IOC_DEFINE(NET_HEADER_FIELD_USER_DEFINED_ALL_FIELDS)
111677 +#error Error: please synchronize IOC_ defines!
111678 +#endif
111679 +
111680 +#if CMP_IOC_DEFINE(NET_HEADER_FIELD_PAYLOAD_ALL_FIELDS)
111681 +#error Error: please synchronize IOC_ defines!
111682 +#endif
111683 +
111684 +#if CMP_IOC_DEFINE(NET_HEADER_FIELD_GRE_ALL_FIELDS)
111685 +#error Error: please synchronize IOC_ defines!
111686 +#endif
111687 +
111688 +#if CMP_IOC_DEFINE(NET_HEADER_FIELD_MINENCAP_ALL_FIELDS)
111689 +#error Error: please synchronize IOC_ defines!
111690 +#endif
111691 +
111692 +#if CMP_IOC_DEFINE(NET_HEADER_FIELD_IPSEC_AH_ALL_FIELDS)
111693 +#error Error: please synchronize IOC_ defines!
111694 +#endif
111695 +
111696 +#if CMP_IOC_DEFINE(NET_HEADER_FIELD_IPSEC_ESP_ALL_FIELDS)
111697 +#error Error: please synchronize IOC_ defines!
111698 +#endif
111699 +
111700 +#if CMP_IOC_DEFINE(NET_HEADER_FIELD_MPLS_LABEL_STACK_ALL_FIELDS)
111701 +#error Error: please synchronize IOC_ defines!
111702 +#endif
111703 +
111704 +#if CMP_IOC_DEFINE(NET_HEADER_FIELD_MACSEC_ALL_FIELDS)
111705 +#error Error: please synchronize IOC_ defines!
111706 +#endif
111707 +
111708 +/* fm_ioctls.h === fm_ext.h assertions */
111709 +#if CMP_IOC_DEFINE(FM_MAX_NUM_OF_VALID_PORTS)
111710 +#error Error: please synchronize IOC_ defines!
111711 +#endif
111712 +
111713 +void LnxWrpPCDIOCTLTypeChecking(void)
111714 +{
111715 + /* fm_ext.h == fm_ioctls.h */
111716 + ASSERT_COND(sizeof(ioc_fm_port_bandwidth_params) == sizeof(t_FmPortsBandwidthParams));
111717 + ASSERT_COND(sizeof(ioc_fm_revision_info_t) == sizeof(t_FmRevisionInfo));
111718 +
111719 + /* fm_pcd_ext.h == fm_pcd_ioctls.h */
111720 + /*ioc_fm_pcd_counters_params_t : NOT USED */
111721 + /*ioc_fm_pcd_exception_params_t : private */
111722 +#if (DPAA_VERSION >= 11)
111723 + ASSERT_COND(sizeof(ioc_fm_pcd_manip_frag_capwap_params_t) == sizeof(t_FmPcdManipFragCapwapParams));
111724 + ASSERT_COND(sizeof(ioc_fm_pcd_manip_reassem_capwap_params_t) == sizeof(t_FmPcdManipReassemCapwapParams));
111725 + ASSERT_COND(sizeof(ioc_fm_pcd_manip_hdr_insrt_by_hdr_params_t) == sizeof(t_FmPcdManipHdrInsrtByHdrParams));
111726 + ASSERT_COND(sizeof(ioc_fm_pcd_manip_hdr_insrt_ip_params_t) == sizeof(t_FmPcdManipHdrInsrtIpParams));
111727 + ASSERT_COND(sizeof(ioc_fm_pcd_manip_hdr_insrt_t) == sizeof(t_FmPcdManipHdrInsrt));
111728 + ASSERT_COND(sizeof(ioc_fm_manip_hdr_info_t) == sizeof(t_FmManipHdrInfo));
111729 + ASSERT_COND(sizeof(ioc_fm_pcd_manip_hdr_rmv_by_hdr_params_t) == sizeof(t_FmPcdManipHdrRmvByHdrParams));
111730 + ASSERT_COND(sizeof(ioc_fm_pcd_manip_special_offload_capwap_params_t) == sizeof(t_FmPcdManipSpecialOffloadCapwapParams));
111731 + ASSERT_COND(sizeof(ioc_fm_pcd_manip_frag_capwap_stats_t) == sizeof(t_FmPcdManipFragCapwapStats));
111732 + ASSERT_COND(sizeof(ioc_fm_pcd_manip_reassem_capwap_stats_t) == sizeof(t_FmPcdManipReassemCapwapStats));
111733 + ASSERT_COND(sizeof(ioc_fm_pcd_manip_frag_params_t) == sizeof(t_FmPcdManipFragParams));
111734 +#endif /* (DPAA_VERSION >= 11) */
111735 +
111736 + ASSERT_COND(sizeof(ioc_fm_pcd_prs_label_params_t) == sizeof(t_FmPcdPrsLabelParams));
111737 + ASSERT_COND(sizeof(ioc_fm_pcd_prs_sw_params_t) == sizeof(t_FmPcdPrsSwParams));
111738 + /*ioc_fm_pcd_kg_dflt_value_params_t : private */
111739 + ASSERT_COND(sizeof(ioc_fm_pcd_hdr_protocol_opt_u) == sizeof(u_FmPcdHdrProtocolOpt));
111740 + ASSERT_COND(sizeof(ioc_fm_pcd_fields_u) == sizeof(t_FmPcdFields));
111741 + ASSERT_COND(sizeof(ioc_fm_pcd_from_hdr_t) == sizeof(t_FmPcdFromHdr));
111742 + ASSERT_COND(sizeof(ioc_fm_pcd_from_field_t) == sizeof(t_FmPcdFromField));
111743 + ASSERT_COND(sizeof(ioc_fm_pcd_distinction_unit_t) == sizeof(t_FmPcdDistinctionUnit));
111744 +
111745 +#if defined(CONFIG_ARM64)
111746 + /* different alignment */
111747 + ASSERT_COND(sizeof(ioc_fm_pcd_net_env_params_t) == sizeof(t_FmPcdNetEnvParams) + sizeof(void *) + 4);
111748 +#else
111749 +#if !defined(CONFIG_COMPAT)
111750 + /* different alignment */
111751 + ASSERT_COND(sizeof(ioc_fm_pcd_net_env_params_t) == sizeof(t_FmPcdNetEnvParams) + sizeof(void *));
111752 +#endif
111753 +#endif
111754 + ASSERT_COND(sizeof(ioc_fm_pcd_extract_entry_t) == sizeof(t_FmPcdExtractEntry));
111755 + ASSERT_COND(sizeof(ioc_fm_pcd_kg_extract_mask_t) == sizeof(t_FmPcdKgExtractMask));
111756 + ASSERT_COND(sizeof(ioc_fm_pcd_kg_extract_dflt_t) == sizeof(t_FmPcdKgExtractDflt));
111757 + ASSERT_COND(sizeof(ioc_fm_pcd_kg_key_extract_and_hash_params_t) == sizeof(t_FmPcdKgKeyExtractAndHashParams));
111758 + ASSERT_COND(sizeof(ioc_fm_pcd_kg_extracted_or_params_t) == sizeof(t_FmPcdKgExtractedOrParams));
111759 + ASSERT_COND(sizeof(ioc_fm_pcd_kg_scheme_counter_t) == sizeof(t_FmPcdKgSchemeCounter));
111760 + ASSERT_COND(sizeof(ioc_fm_pcd_kg_plcr_profile_t) == sizeof(t_FmPcdKgPlcrProfile));
111761 +#if (DPAA_VERSION >= 11)
111762 + ASSERT_COND(sizeof(ioc_fm_pcd_kg_storage_profile_t) == sizeof(t_FmPcdKgStorageProfile));
111763 +#endif
111764 + ASSERT_COND(sizeof(ioc_fm_pcd_kg_cc_t) == sizeof(t_FmPcdKgCc));
111765 +#if !defined(CONFIG_COMPAT)
111766 + /* different alignment */
111767 + ASSERT_COND(sizeof(ioc_fm_pcd_kg_scheme_params_t) == sizeof(t_FmPcdKgSchemeParams) + sizeof(void *));
111768 +#endif
111769 + ASSERT_COND(sizeof(ioc_fm_pcd_cc_next_cc_params_t) == sizeof(t_FmPcdCcNextCcParams));
111770 + ASSERT_COND(sizeof(ioc_fm_pcd_cc_next_plcr_params_t) == sizeof(t_FmPcdCcNextPlcrParams));
111771 + ASSERT_COND(sizeof(ioc_fm_pcd_cc_next_enqueue_params_t) == sizeof(t_FmPcdCcNextEnqueueParams));
111772 + ASSERT_COND(sizeof(ioc_fm_pcd_cc_next_kg_params_t) == sizeof(t_FmPcdCcNextKgParams));
111773 + ASSERT_COND(sizeof(ioc_fm_pcd_cc_next_engine_params_t) == sizeof(t_FmPcdCcNextEngineParams));
111774 + ASSERT_COND(sizeof(ioc_fm_pcd_cc_key_params_t) == sizeof(t_FmPcdCcKeyParams));
111775 + ASSERT_COND(sizeof(ioc_keys_params_t) == sizeof(t_KeysParams));
111776 +#if !defined(CONFIG_COMPAT)
111777 + /* different alignment */
111778 + ASSERT_COND(sizeof(ioc_fm_pcd_cc_node_params_t) == sizeof(t_FmPcdCcNodeParams) + sizeof(void *));
111779 + ASSERT_COND(sizeof(ioc_fm_pcd_hash_table_params_t) == sizeof(t_FmPcdHashTableParams) + sizeof(void *));
111780 +#endif
111781 + ASSERT_COND(sizeof(ioc_fm_pcd_cc_grp_params_t) == sizeof(t_FmPcdCcGrpParams));
111782 +#if !defined(CONFIG_COMPAT)
111783 + /* different alignment */
111784 + ASSERT_COND(sizeof(ioc_fm_pcd_cc_tree_params_t) == sizeof(t_FmPcdCcTreeParams) + sizeof(void *));
111785 +#endif
111786 + ASSERT_COND(sizeof(ioc_fm_pcd_plcr_byte_rate_mode_param_t) == sizeof(t_FmPcdPlcrByteRateModeParams));
111787 + ASSERT_COND(sizeof(ioc_fm_pcd_plcr_non_passthrough_alg_param_t) == sizeof(t_FmPcdPlcrNonPassthroughAlgParams));
111788 + ASSERT_COND(sizeof(ioc_fm_pcd_plcr_next_engine_params_u) == sizeof(u_FmPcdPlcrNextEngineParams));
111789 + /*ioc_fm_pcd_port_params_t : private */
111790 + ASSERT_COND(sizeof(ioc_fm_pcd_plcr_profile_params_t) == sizeof(t_FmPcdPlcrProfileParams) + sizeof(void *));
111791 + /*ioc_fm_pcd_cc_tree_modify_next_engine_params_t : private */
111792 +
111793 +#ifdef FM_CAPWAP_SUPPORT
111794 +#error TODO: unsupported feature
111795 +/*
111796 + ASSERT_COND(sizeof(TODO) == sizeof(t_FmPcdManipHdrInsrtByTemplateParams));
111797 + ASSERT_COND(sizeof(TODO) == sizeof(t_CapwapFragmentationParams));
111798 + ASSERT_COND(sizeof(TODO) == sizeof(t_CapwapReassemblyParams));
111799 +*/
111800 +#endif
111801 +
111802 + /*ioc_fm_pcd_cc_node_modify_next_engine_params_t : private */
111803 + /*ioc_fm_pcd_cc_node_remove_key_params_t : private */
111804 + /*ioc_fm_pcd_cc_node_modify_key_and_next_engine_params_t : private */
111805 + /*ioc_fm_pcd_cc_node_modify_key_params_t : private */
111806 + /*ioc_fm_manip_hdr_info_t : private */
111807 + /*ioc_fm_pcd_hash_table_set_t : private */
111808 +
111809 + ASSERT_COND(sizeof(ioc_fm_pcd_manip_frag_ip_params_t) == sizeof(t_FmPcdManipFragIpParams));
111810 + ASSERT_COND(sizeof(ioc_fm_pcd_manip_reassem_ip_params_t) == sizeof(t_FmPcdManipReassemIpParams));
111811 + ASSERT_COND(sizeof(ioc_fm_pcd_manip_special_offload_ipsec_params_t) == sizeof(t_FmPcdManipSpecialOffloadIPSecParams));
111812 + ASSERT_COND(sizeof(ioc_fm_pcd_manip_special_offload_params_t) == sizeof(t_FmPcdManipSpecialOffloadParams));
111813 + ASSERT_COND(sizeof(ioc_fm_pcd_manip_hdr_rmv_generic_params_t) == sizeof(t_FmPcdManipHdrRmvGenericParams));
111814 + ASSERT_COND(sizeof(ioc_fm_pcd_manip_hdr_insrt_generic_params_t) == sizeof(t_FmPcdManipHdrInsrtGenericParams));
111815 + ASSERT_COND(sizeof(ioc_fm_pcd_manip_hdr_insrt_params_t) == sizeof(t_FmPcdManipHdrInsrtParams));
111816 + ASSERT_COND(sizeof(ioc_fm_pcd_manip_hdr_rmv_params_t) == sizeof(t_FmPcdManipHdrRmvParams));
111817 + ASSERT_COND(sizeof(ioc_fm_pcd_manip_hdr_params_t) == sizeof(t_FmPcdManipHdrParams));
111818 + ASSERT_COND(sizeof(ioc_fm_pcd_manip_frag_params_t) == sizeof(t_FmPcdManipFragParams));
111819 + ASSERT_COND(sizeof(ioc_fm_pcd_manip_reassem_params_t) == sizeof(t_FmPcdManipReassemParams));
111820 +#if !defined(CONFIG_COMPAT)
111821 + /* different alignment */
111822 + ASSERT_COND(sizeof(ioc_fm_pcd_manip_params_t) == sizeof(t_FmPcdManipParams) + sizeof(void *));
111823 +#endif
111824 + ASSERT_COND(sizeof(ioc_fm_pcd_manip_reassem_ip_stats_t) == sizeof(t_FmPcdManipReassemIpStats));
111825 + ASSERT_COND(sizeof(ioc_fm_pcd_manip_frag_ip_stats_t) == sizeof(t_FmPcdManipFragIpStats));
111826 + ASSERT_COND(sizeof(ioc_fm_pcd_manip_reassem_stats_t) == sizeof(t_FmPcdManipReassemStats));
111827 + ASSERT_COND(sizeof(ioc_fm_pcd_manip_frag_stats_t) == sizeof(t_FmPcdManipFragStats));
111828 + ASSERT_COND(sizeof(ioc_fm_pcd_manip_stats_t) == sizeof(t_FmPcdManipStats));
111829 +#if DPAA_VERSION >= 11
111830 + ASSERT_COND(sizeof(ioc_fm_pcd_frm_replic_group_params_t) == sizeof(t_FmPcdFrmReplicGroupParams) + sizeof(void *));
111831 +#endif
111832 +
111833 + /* fm_port_ext.h == fm_port_ioctls.h */
111834 + ASSERT_COND(sizeof(ioc_fm_port_rate_limit_t) == sizeof(t_FmPortRateLimit));
111835 + ASSERT_COND(sizeof(ioc_fm_port_pcd_params_t) == sizeof(t_FmPortPcdParams));
111836 + ASSERT_COND(sizeof(ioc_fm_pcd_kg_scheme_select_t) == sizeof(t_FmPcdKgSchemeSelect));
111837 + ASSERT_COND(sizeof(ioc_fm_pcd_port_schemes_params_t) == sizeof(t_FmPcdPortSchemesParams));
111838 + ASSERT_COND(sizeof(ioc_fm_pcd_prs_start_t) == sizeof(t_FmPcdPrsStart));
111839 +
111840 + return;
111841 +}
111842 +
111843 +#define ASSERT_IOC_NET_ENUM(def) ASSERT_COND((unsigned long)e_IOC_NET_##def == (unsigned long)def)
111844 +
111845 +void LnxWrpPCDIOCTLEnumChecking(void)
111846 +{
111847 + /* net_ext.h == net_ioctls.h : sampling checks */
111848 + ASSERT_IOC_NET_ENUM(HEADER_TYPE_MACSEC);
111849 + ASSERT_IOC_NET_ENUM(HEADER_TYPE_PPP);
111850 + ASSERT_IOC_NET_ENUM(MAX_HEADER_TYPE_COUNT);
111851 +
111852 + /* fm_ext.h == fm_ioctls.h */
111853 + ASSERT_COND((unsigned long)e_IOC_FM_PORT_TYPE_DUMMY == (unsigned long)e_FM_PORT_TYPE_DUMMY);
111854 + ASSERT_COND((unsigned long)e_IOC_EX_MURAM_ECC == (unsigned long)e_FM_EX_MURAM_ECC);
111855 + ASSERT_COND((unsigned long)e_IOC_FM_COUNTERS_DEQ_CONFIRM == (unsigned long)e_FM_COUNTERS_DEQ_CONFIRM);
111856 +
111857 + /* fm_pcd_ext.h == fm_pcd_ioctls.h */
111858 + 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);
111859 + ASSERT_COND((unsigned long)e_IOC_FM_PCD_PRS_EXCEPTION_SINGLE_ECC == (unsigned long)e_FM_PCD_PRS_EXCEPTION_SINGLE_ECC);
111860 + ASSERT_COND((unsigned long)e_IOC_FM_PCD_PRS == (unsigned long)e_FM_PCD_PRS);
111861 + ASSERT_COND((unsigned long)e_IOC_FM_PCD_EXTRACT_FULL_FIELD == (unsigned long)e_FM_PCD_EXTRACT_FULL_FIELD);
111862 + ASSERT_COND((unsigned long)e_IOC_FM_PCD_EXTRACT_FROM_FLOW_ID == (unsigned long)e_FM_PCD_EXTRACT_FROM_FLOW_ID);
111863 + ASSERT_COND((unsigned long)e_IOC_FM_PCD_KG_EXTRACT_PORT_PRIVATE_INFO == (unsigned long)e_FM_PCD_KG_EXTRACT_PORT_PRIVATE_INFO);
111864 + ASSERT_COND((unsigned long)e_IOC_FM_PCD_KG_DFLT_ILLEGAL == (unsigned long)e_FM_PCD_KG_DFLT_ILLEGAL);
111865 + ASSERT_COND((unsigned long)e_IOC_FM_PCD_KG_GENERIC_NOT_FROM_DATA == (unsigned long)e_FM_PCD_KG_GENERIC_NOT_FROM_DATA);
111866 + ASSERT_COND((unsigned long)e_IOC_FM_PCD_HDR_INDEX_LAST == (unsigned long)e_FM_PCD_HDR_INDEX_LAST);
111867 + ASSERT_COND((unsigned long)e_IOC_FM_PCD_PLCR_SHARED == (unsigned long)e_FM_PCD_PLCR_SHARED);
111868 + ASSERT_COND((unsigned long)e_IOC_FM_PCD_PLCR_RFC_4115 == (unsigned long)e_FM_PCD_PLCR_RFC_4115);
111869 + ASSERT_COND((unsigned long)e_IOC_FM_PCD_PLCR_COLOR_AWARE == (unsigned long)e_FM_PCD_PLCR_COLOR_AWARE);
111870 + ASSERT_COND((unsigned long)e_IOC_FM_PCD_PLCR_OVERRIDE == (unsigned long)e_FM_PCD_PLCR_OVERRIDE);
111871 + ASSERT_COND((unsigned long)e_IOC_FM_PCD_PLCR_FULL_FRM_LEN == (unsigned long)e_FM_PCD_PLCR_FULL_FRM_LEN);
111872 + ASSERT_COND((unsigned long)e_IOC_FM_PCD_PLCR_ROLLBACK_FULL_FRM_LEN == (unsigned long)e_FM_PCD_PLCR_ROLLBACK_FULL_FRM_LEN);
111873 + ASSERT_COND((unsigned long)e_IOC_FM_PCD_PLCR_PACKET_MODE == (unsigned long)e_FM_PCD_PLCR_PACKET_MODE);
111874 + ASSERT_COND((unsigned long)e_IOC_FM_PCD_DROP_FRAME == (unsigned long)e_FM_PCD_DROP_FRAME);
111875 + 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);
111876 + ASSERT_COND((unsigned long)e_IOC_FM_PCD_ACTION_INDEXED_LOOKUP == (unsigned long)e_FM_PCD_ACTION_INDEXED_LOOKUP);
111877 + 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);
111878 +#if !defined(FM_CAPWAP_SUPPORT)
111879 + ASSERT_COND((unsigned long)e_IOC_FM_PCD_MANIP_INSRT_GENERIC == (unsigned long)e_FM_PCD_MANIP_INSRT_GENERIC);
111880 + ASSERT_COND((unsigned long)e_IOC_FM_PCD_MANIP_RMV_GENERIC == (unsigned long)e_FM_PCD_MANIP_RMV_GENERIC);
111881 +#else
111882 + ASSERT_COND((unsigned long)e_IOC_FM_PCD_MANIP_INSRT_BY_TEMPLATE == (unsigned long)e_FM_PCD_MANIP_INSRT_BY_TEMPLATE);
111883 + ASSERT_COND((unsigned long)e_IOC_FM_PCD_MANIP_RMV_BY_HDR == (unsigned long)e_FM_PCD_MANIP_RMV_BY_HDR);
111884 + 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);
111885 +#endif
111886 + ASSERT_COND((unsigned long)e_IOC_FM_PCD_MANIP_TIME_OUT_BETWEEN_FRAG == (unsigned long)e_FM_PCD_MANIP_TIME_OUT_BETWEEN_FRAG);
111887 + ASSERT_COND((unsigned long)e_IOC_FM_PCD_MANIP_EIGHT_WAYS_HASH == (unsigned long)e_FM_PCD_MANIP_EIGHT_WAYS_HASH);
111888 +
111889 +#ifdef FM_CAPWAP_SUPPORT
111890 + ASSERT_COND((unsigned long)e_IOC_FM_PCD_STATS_PER_FLOWID == (unsigned long)e_FM_PCD_STATS_PER_FLOWID);
111891 +#endif
111892 + ASSERT_COND((unsigned long)e_IOC_FM_PCD_MANIP_SPECIAL_OFFLOAD == (unsigned long)e_FM_PCD_MANIP_SPECIAL_OFFLOAD);
111893 + ASSERT_COND((unsigned long)e_IOC_FM_PCD_CC_STATS_MODE_FRAME == (unsigned long)e_FM_PCD_CC_STATS_MODE_FRAME);
111894 + ASSERT_COND((unsigned long)e_IOC_FM_PCD_MANIP_CONTINUE_WITHOUT_FRAG == (unsigned long)e_FM_PCD_MANIP_CONTINUE_WITHOUT_FRAG);
111895 + ASSERT_COND((unsigned long)e_IOC_FM_PCD_MANIP_SPECIAL_OFFLOAD_IPSEC == (unsigned long)e_FM_PCD_MANIP_SPECIAL_OFFLOAD_IPSEC);
111896 +
111897 + /* fm_port_ext.h == fm_port_ioctls.h */
111898 +#if !defined(FM_CAPWAP_SUPPORT)
111899 + 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);
111900 +#else
111901 + 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);
111902 +#endif
111903 + ASSERT_COND((unsigned long)e_IOC_FM_PORT_COUNTERS_DEQ_CONFIRM == (unsigned long)e_FM_PORT_COUNTERS_DEQ_CONFIRM);
111904 + 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);
111905 +
111906 + return;
111907 +}
111908 +
111909 +static t_Error LnxwrpFmPcdIOCTL(t_LnxWrpFmDev *p_LnxWrpFmDev, unsigned int cmd, unsigned long arg, bool compat)
111910 +{
111911 + t_Error err = E_OK;
111912 +
111913 +/*
111914 +Status: PCD API to fmlib (file: drivers/net/dpa/NetCommSw/inc/Peripherals/fm_pcd_ext.h):
111915 +
111916 + FM_PCD_PrsLoadSw
111917 + FM_PCD_SetAdvancedOffloadSupport
111918 + FM_PCD_Enable
111919 + FM_PCD_Disable
111920 + FM_PCD_ForceIntr
111921 + FM_PCD_SetException
111922 + FM_PCD_KgSetAdditionalDataAfterParsing
111923 + FM_PCD_KgSetDfltValue
111924 + FM_PCD_NetEnvCharacteristicsSet
111925 + FM_PCD_NetEnvCharacteristicsDelete
111926 + FM_PCD_KgSchemeSet
111927 + FM_PCD_KgSchemeDelete
111928 + FM_PCD_MatchTableSet
111929 + FM_PCD_MatchTableDelete
111930 + FM_PCD_CcRootBuild
111931 + FM_PCD_CcRootDelete
111932 + FM_PCD_PlcrProfileSet
111933 + FM_PCD_PlcrProfileDelete
111934 + FM_PCD_CcRootModifyNextEngine
111935 + FM_PCD_MatchTableModifyNextEngine
111936 + FM_PCD_MatchTableModifyMissNextEngine
111937 + FM_PCD_MatchTableRemoveKey
111938 + FM_PCD_MatchTableAddKey
111939 + FM_PCD_MatchTableModifyKeyAndNextEngine
111940 + FM_PCD_HashTableSet
111941 + FM_PCD_HashTableDelete
111942 + FM_PCD_HashTableAddKey
111943 + FM_PCD_HashTableRemoveKey
111944 + FM_PCD_MatchTableModifyKey
111945 + FM_PCD_ManipNodeReplace
111946 + FM_PCD_ManipNodeSet
111947 + FM_PCD_ManipNodeDelete
111948 +
111949 +Status: not exported, should be thru sysfs
111950 + FM_PCD_KgSchemeGetCounter
111951 + FM_PCD_KgSchemeSetCounter
111952 + FM_PCD_PlcrProfileGetCounter
111953 + FM_PCD_PlcrProfileSetCounter
111954 +
111955 +Status: not exported
111956 + FM_PCD_MatchTableFindNRemoveKey
111957 + FM_PCD_MatchTableFindNModifyNextEngine
111958 + FM_PCD_MatchTableFindNModifyKeyAndNextEngine
111959 + FM_PCD_MatchTableFindNModifyKey
111960 + FM_PCD_MatchTableGetIndexedHashBucket
111961 + FM_PCD_MatchTableGetNextEngine
111962 + FM_PCD_MatchTableGetKeyCounter
111963 +
111964 +Status: not exported, would be nice to have
111965 + FM_PCD_HashTableModifyNextEngine
111966 + FM_PCD_HashTableModifyMissNextEngine
111967 + FM_PCD_HashTableGetMissNextEngine
111968 + FM_PCD_ManipGetStatistics
111969 +
111970 +Status: not exported
111971 +#if DPAA_VERSION >= 11
111972 +
111973 + FM_VSP_GetStatistics -- it's not available yet
111974 +#endif
111975 +
111976 +Status: feature not supported
111977 +#ifdef FM_CAPWAP_SUPPORT
111978 +#error unsupported feature
111979 + FM_PCD_StatisticsSetNode
111980 +#endif
111981 +
111982 + */
111983 + _fm_ioctl_dbg("cmd:0x%08x(type:0x%02x, nr:%u).\n",
111984 + cmd, _IOC_TYPE(cmd), _IOC_NR(cmd) - 20);
111985 +
111986 + switch (cmd)
111987 + {
111988 +#if defined(CONFIG_COMPAT)
111989 + case FM_PCD_IOC_PRS_LOAD_SW_COMPAT:
111990 +#endif
111991 + case FM_PCD_IOC_PRS_LOAD_SW:
111992 + {
111993 + ioc_fm_pcd_prs_sw_params_t *param;
111994 + uint8_t *p_code;
111995 +
111996 + param = (ioc_fm_pcd_prs_sw_params_t *) XX_Malloc(sizeof(ioc_fm_pcd_prs_sw_params_t));
111997 + if (!param)
111998 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
111999 +
112000 + memset(param, 0, sizeof(ioc_fm_pcd_prs_sw_params_t));
112001 +
112002 +#if defined(CONFIG_COMPAT)
112003 + if (compat)
112004 + {
112005 + ioc_compat_fm_pcd_prs_sw_params_t *compat_param;
112006 +
112007 + compat_param = (ioc_compat_fm_pcd_prs_sw_params_t *) XX_Malloc(
112008 + sizeof(ioc_compat_fm_pcd_prs_sw_params_t));
112009 + if (!compat_param)
112010 + {
112011 + XX_Free(param);
112012 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
112013 + }
112014 +
112015 + memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_prs_sw_params_t));
112016 + if (copy_from_user(compat_param,
112017 + (ioc_compat_fm_pcd_prs_sw_params_t *) compat_ptr(arg),
112018 + sizeof(ioc_compat_fm_pcd_prs_sw_params_t)))
112019 + {
112020 + XX_Free(compat_param);
112021 + XX_Free(param);
112022 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
112023 + }
112024 +
112025 + compat_fm_pcd_prs_sw(compat_param, param, COMPAT_US_TO_K);
112026 +
112027 + XX_Free(compat_param);
112028 + }
112029 + else
112030 +#endif
112031 + {
112032 + if (copy_from_user(param, (ioc_fm_pcd_prs_sw_params_t *)arg,
112033 + sizeof(ioc_fm_pcd_prs_sw_params_t)))
112034 + {
112035 + XX_Free(param);
112036 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
112037 + }
112038 + }
112039 +
112040 + if (!param->p_code || !param->size)
112041 + {
112042 + XX_Free(param);
112043 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
112044 + }
112045 +
112046 + p_code = (uint8_t *) XX_Malloc(param->size);
112047 + if (!p_code)
112048 + {
112049 + XX_Free(param);
112050 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
112051 + }
112052 +
112053 + memset(p_code, 0, param->size);
112054 + if (copy_from_user(p_code, param->p_code, param->size))
112055 + {
112056 + XX_Free(p_code);
112057 + XX_Free(param);
112058 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
112059 + }
112060 +
112061 + param->p_code = p_code;
112062 +
112063 + err = FM_PCD_PrsLoadSw(p_LnxWrpFmDev->h_PcdDev, (t_FmPcdPrsSwParams*)param);
112064 +
112065 + XX_Free(p_code);
112066 + XX_Free(param);
112067 + break;
112068 + }
112069 +
112070 + case FM_PCD_IOC_SET_ADVANCED_OFFLOAD_SUPPORT:
112071 + err = FM_PCD_SetAdvancedOffloadSupport(p_LnxWrpFmDev->h_PcdDev);
112072 + break;
112073 +
112074 + case FM_PCD_IOC_ENABLE:
112075 + err = FM_PCD_Enable(p_LnxWrpFmDev->h_PcdDev);
112076 + break;
112077 +
112078 + case FM_PCD_IOC_DISABLE:
112079 + err = FM_PCD_Disable(p_LnxWrpFmDev->h_PcdDev);
112080 + break;
112081 +
112082 + case FM_PCD_IOC_FORCE_INTR:
112083 + {
112084 + int exception;
112085 +
112086 +#if defined(CONFIG_COMPAT)
112087 + if (compat)
112088 + {
112089 + if (get_user(exception, (int *) compat_ptr(arg)))
112090 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
112091 + }
112092 + else
112093 +#endif
112094 + {
112095 + if (get_user(exception, (int *)arg))
112096 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
112097 + }
112098 +
112099 + err = FM_PCD_ForceIntr(p_LnxWrpFmDev->h_PcdDev, (e_FmPcdExceptions)exception);
112100 + break;
112101 + }
112102 +
112103 + case FM_PCD_IOC_SET_EXCEPTION:
112104 + {
112105 + ioc_fm_pcd_exception_params_t *param;
112106 +
112107 + param = (ioc_fm_pcd_exception_params_t *) XX_Malloc(
112108 + sizeof(ioc_fm_pcd_exception_params_t));
112109 + if (!param)
112110 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
112111 +
112112 + memset(param, 0, sizeof(ioc_fm_pcd_exception_params_t));
112113 +
112114 +#if defined(CONFIG_COMPAT)
112115 + if (compat)
112116 + {
112117 + if (copy_from_user(param, (ioc_fm_pcd_exception_params_t *)compat_ptr(arg),
112118 + sizeof(ioc_fm_pcd_exception_params_t)))
112119 + {
112120 + XX_Free(param);
112121 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
112122 + }
112123 + }
112124 + else
112125 +#endif
112126 + {
112127 + if (copy_from_user(param, (ioc_fm_pcd_exception_params_t *)arg,
112128 + sizeof(ioc_fm_pcd_exception_params_t)))
112129 + {
112130 + XX_Free(param);
112131 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
112132 + }
112133 + }
112134 +
112135 + err = FM_PCD_SetException(p_LnxWrpFmDev->h_PcdDev, param->exception, param->enable);
112136 +
112137 + XX_Free(param);
112138 + break;
112139 + }
112140 +
112141 + case FM_PCD_IOC_KG_SET_ADDITIONAL_DATA_AFTER_PARSING:
112142 + {
112143 + uint8_t payloadOffset;
112144 +
112145 +#if defined(CONFIG_COMPAT)
112146 + if (compat)
112147 + {
112148 + if (get_user(payloadOffset, (uint8_t*) compat_ptr(arg)))
112149 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
112150 + }
112151 + else
112152 +#endif
112153 + {
112154 + if (get_user(payloadOffset, (uint8_t*) arg))
112155 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
112156 + }
112157 +
112158 + err = FM_PCD_KgSetAdditionalDataAfterParsing(p_LnxWrpFmDev->h_PcdDev, payloadOffset);
112159 + break;
112160 + }
112161 +
112162 + case FM_PCD_IOC_KG_SET_DFLT_VALUE:
112163 + {
112164 + ioc_fm_pcd_kg_dflt_value_params_t *param;
112165 +
112166 + param = (ioc_fm_pcd_kg_dflt_value_params_t *) XX_Malloc(
112167 + sizeof(ioc_fm_pcd_kg_dflt_value_params_t));
112168 + if (!param)
112169 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
112170 +
112171 + memset(param, 0, sizeof(ioc_fm_pcd_kg_dflt_value_params_t));
112172 +
112173 +#if defined(CONFIG_COMPAT)
112174 + if (compat)
112175 + {
112176 + if (copy_from_user(param, (ioc_fm_pcd_kg_dflt_value_params_t *)compat_ptr(arg),
112177 + sizeof(ioc_fm_pcd_kg_dflt_value_params_t)))
112178 + {
112179 + XX_Free(param);
112180 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
112181 + }
112182 + }
112183 + else
112184 +#endif
112185 + {
112186 + if (copy_from_user(param, (ioc_fm_pcd_kg_dflt_value_params_t *)arg,
112187 + sizeof(ioc_fm_pcd_kg_dflt_value_params_t)))
112188 + {
112189 + XX_Free(param);
112190 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
112191 + }
112192 + }
112193 +
112194 + err = FM_PCD_KgSetDfltValue(p_LnxWrpFmDev->h_PcdDev, param->valueId, param->value);
112195 +
112196 + XX_Free(param);
112197 + break;
112198 + }
112199 +
112200 +#if defined(CONFIG_COMPAT)
112201 + case FM_PCD_IOC_NET_ENV_CHARACTERISTICS_SET_COMPAT:
112202 +#endif
112203 + case FM_PCD_IOC_NET_ENV_CHARACTERISTICS_SET:
112204 + {
112205 + ioc_fm_pcd_net_env_params_t *param;
112206 +
112207 + param = (ioc_fm_pcd_net_env_params_t *) XX_Malloc(sizeof(ioc_fm_pcd_net_env_params_t));
112208 + if (!param)
112209 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
112210 +
112211 + memset(param, 0, sizeof(ioc_fm_pcd_net_env_params_t));
112212 +
112213 +#if defined(CONFIG_COMPAT)
112214 + if (compat)
112215 + {
112216 + ioc_compat_fm_pcd_net_env_params_t *compat_param;
112217 +
112218 + compat_param = (ioc_compat_fm_pcd_net_env_params_t *) XX_Malloc(
112219 + sizeof(ioc_compat_fm_pcd_net_env_params_t));
112220 + if (!compat_param)
112221 + {
112222 + XX_Free(param);
112223 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
112224 + }
112225 +
112226 + memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_net_env_params_t));
112227 + if (copy_from_user(compat_param, (ioc_compat_fm_pcd_net_env_params_t *) compat_ptr(arg),
112228 + sizeof(ioc_compat_fm_pcd_net_env_params_t)))
112229 + {
112230 + XX_Free(compat_param);
112231 + XX_Free(param);
112232 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
112233 + }
112234 +
112235 + compat_copy_fm_pcd_net_env(compat_param, param, COMPAT_US_TO_K);
112236 + XX_Free(compat_param);
112237 + }
112238 + else
112239 +#endif
112240 + {
112241 + if (copy_from_user(param, (ioc_fm_pcd_net_env_params_t *) arg,
112242 + sizeof(ioc_fm_pcd_net_env_params_t)))
112243 + {
112244 + XX_Free(param);
112245 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
112246 + }
112247 + }
112248 +
112249 + param->id = FM_PCD_NetEnvCharacteristicsSet(p_LnxWrpFmDev->h_PcdDev, (t_FmPcdNetEnvParams*)param);
112250 +
112251 + if (!param->id)
112252 + {
112253 + XX_Free(param);
112254 + err = E_INVALID_VALUE;
112255 + /* Since the LLD has no errno-style error reporting,
112256 + we're left here with no other option than to report
112257 + a generic E_INVALID_VALUE */
112258 + break;
112259 + }
112260 +
112261 +#if defined(CONFIG_COMPAT)
112262 + if (compat)
112263 + {
112264 + ioc_compat_fm_pcd_net_env_params_t *compat_param;
112265 +
112266 + compat_param = (ioc_compat_fm_pcd_net_env_params_t *) XX_Malloc(
112267 + sizeof(ioc_compat_fm_pcd_net_env_params_t));
112268 + if (!compat_param)
112269 + {
112270 + XX_Free(param);
112271 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
112272 + }
112273 +
112274 + memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_net_env_params_t));
112275 + compat_copy_fm_pcd_net_env(compat_param, param, COMPAT_K_TO_US);
112276 +
112277 + if (copy_to_user((ioc_compat_fm_pcd_net_env_params_t *) compat_ptr(arg),
112278 + compat_param,
112279 + sizeof(ioc_compat_fm_pcd_net_env_params_t)))
112280 + err = E_READ_FAILED;
112281 +
112282 + XX_Free(compat_param);
112283 + }
112284 + else
112285 +#endif
112286 + {
112287 + if (copy_to_user((ioc_fm_pcd_net_env_params_t *)arg,
112288 + param,
112289 + sizeof(ioc_fm_pcd_net_env_params_t)))
112290 + err = E_READ_FAILED;
112291 + }
112292 +
112293 + XX_Free(param);
112294 + break;
112295 + }
112296 +
112297 +#if defined(CONFIG_COMPAT)
112298 + case FM_PCD_IOC_NET_ENV_CHARACTERISTICS_DELETE_COMPAT:
112299 +#endif
112300 + case FM_PCD_IOC_NET_ENV_CHARACTERISTICS_DELETE:
112301 + {
112302 + ioc_fm_obj_t id;
112303 +
112304 + memset(&id, 0 , sizeof(ioc_fm_obj_t));
112305 +
112306 +#if defined(CONFIG_COMPAT)
112307 + if (compat)
112308 + {
112309 + ioc_compat_fm_obj_t compat_id;
112310 +
112311 + if (copy_from_user(&compat_id, (ioc_compat_fm_obj_t *) compat_ptr(arg), sizeof(ioc_compat_fm_obj_t)))
112312 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
112313 +
112314 + compat_obj_delete(&compat_id, &id);
112315 + }
112316 + else
112317 +#endif
112318 + {
112319 + if (copy_from_user(&id, (ioc_fm_obj_t *) arg, sizeof(ioc_fm_obj_t)))
112320 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
112321 + }
112322 +
112323 + err = FM_PCD_NetEnvCharacteristicsDelete(id.obj);
112324 + break;
112325 + }
112326 +
112327 +#if defined(CONFIG_COMPAT)
112328 + case FM_PCD_IOC_KG_SCHEME_SET_COMPAT:
112329 +#endif
112330 + case FM_PCD_IOC_KG_SCHEME_SET:
112331 + {
112332 + ioc_fm_pcd_kg_scheme_params_t *param;
112333 +
112334 + param = (ioc_fm_pcd_kg_scheme_params_t *) XX_Malloc(sizeof(ioc_fm_pcd_kg_scheme_params_t));
112335 + if (!param)
112336 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
112337 +
112338 + memset(param, 0, sizeof(ioc_fm_pcd_kg_scheme_params_t));
112339 +
112340 +#if defined(CONFIG_COMPAT)
112341 + if (compat)
112342 + {
112343 + ioc_compat_fm_pcd_kg_scheme_params_t *compat_param = NULL;
112344 +
112345 + compat_param = (ioc_compat_fm_pcd_kg_scheme_params_t *) XX_Malloc(
112346 + sizeof(ioc_compat_fm_pcd_kg_scheme_params_t));
112347 + if (!compat_param)
112348 + {
112349 + XX_Free(param);
112350 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
112351 + }
112352 +
112353 + memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_kg_scheme_params_t));
112354 +
112355 + if (copy_from_user(compat_param, (ioc_compat_fm_pcd_kg_scheme_params_t *) compat_ptr(arg),
112356 + sizeof(ioc_compat_fm_pcd_kg_scheme_params_t)))
112357 + {
112358 + XX_Free(compat_param);
112359 + XX_Free(param);
112360 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
112361 + }
112362 +
112363 + compat_copy_fm_pcd_kg_scheme(compat_param, param, COMPAT_US_TO_K);
112364 +
112365 + XX_Free(compat_param);
112366 + }
112367 + else
112368 +#endif
112369 + {
112370 + if (copy_from_user(param, (ioc_fm_pcd_kg_scheme_params_t *)arg,
112371 + sizeof(ioc_fm_pcd_kg_scheme_params_t)))
112372 + {
112373 + XX_Free(param);
112374 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
112375 + }
112376 + }
112377 +
112378 + param->id = FM_PCD_KgSchemeSet(p_LnxWrpFmDev->h_PcdDev, (t_FmPcdKgSchemeParams*)param);
112379 +
112380 + if (!param->id)
112381 + {
112382 + XX_Free(param);
112383 + err = E_INVALID_VALUE;
112384 + /* Since the LLD has no errno-style error reporting,
112385 + we're left here with no other option than to report
112386 + a generic E_INVALID_VALUE */
112387 + break;
112388 + }
112389 +
112390 +#if defined(CONFIG_COMPAT)
112391 + if (compat)
112392 + {
112393 + ioc_compat_fm_pcd_kg_scheme_params_t *compat_param;
112394 +
112395 + compat_param = (ioc_compat_fm_pcd_kg_scheme_params_t *) XX_Malloc(
112396 + sizeof(ioc_compat_fm_pcd_kg_scheme_params_t));
112397 + if (!compat_param)
112398 + {
112399 + XX_Free(param);
112400 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
112401 + }
112402 +
112403 + memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_kg_scheme_params_t));
112404 + compat_copy_fm_pcd_kg_scheme(compat_param, param, COMPAT_K_TO_US);
112405 + if (copy_to_user((ioc_compat_fm_pcd_kg_scheme_params_t *)compat_ptr(arg),
112406 + compat_param,
112407 + sizeof(ioc_compat_fm_pcd_kg_scheme_params_t)))
112408 + err = E_READ_FAILED;
112409 +
112410 + XX_Free(compat_param);
112411 + }
112412 + else
112413 +#endif
112414 + {
112415 + if (copy_to_user((ioc_fm_pcd_kg_scheme_params_t *)arg,
112416 + param,
112417 + sizeof(ioc_fm_pcd_kg_scheme_params_t)))
112418 + err = E_READ_FAILED;
112419 + }
112420 +
112421 + XX_Free(param);
112422 + break;
112423 + }
112424 +
112425 +#if defined(CONFIG_COMPAT)
112426 + case FM_PCD_IOC_KG_SCHEME_GET_CNTR_COMPAT:
112427 +#endif
112428 + case FM_PCD_IOC_KG_SCHEME_GET_CNTR:
112429 + {
112430 + ioc_fm_pcd_kg_scheme_spc_t *param;
112431 +
112432 + param = (ioc_fm_pcd_kg_scheme_spc_t *) XX_Malloc(sizeof(ioc_fm_pcd_kg_scheme_spc_t));
112433 + if (!param)
112434 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
112435 +
112436 + memset(param, 0, sizeof(ioc_fm_pcd_kg_scheme_spc_t));
112437 +
112438 +#if defined(CONFIG_COMPAT)
112439 + if (compat)
112440 + {
112441 + ioc_compat_fm_pcd_kg_scheme_spc_t *compat_param = NULL;
112442 +
112443 + compat_param = (ioc_compat_fm_pcd_kg_scheme_spc_t *) XX_Malloc(
112444 + sizeof(ioc_compat_fm_pcd_kg_scheme_spc_t));
112445 + if (!compat_param)
112446 + {
112447 + XX_Free(param);
112448 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
112449 + }
112450 +
112451 + memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_kg_scheme_spc_t));
112452 +
112453 + if (copy_from_user(compat_param, (ioc_compat_fm_pcd_kg_scheme_spc_t *) compat_ptr(arg),
112454 + sizeof(ioc_compat_fm_pcd_kg_scheme_spc_t)))
112455 + {
112456 + XX_Free(compat_param);
112457 + XX_Free(param);
112458 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
112459 + }
112460 +
112461 + compat_copy_fm_pcd_kg_scheme_spc(compat_param, param, COMPAT_US_TO_K);
112462 +
112463 + XX_Free(compat_param);
112464 + }
112465 + else
112466 +#endif
112467 + {
112468 + if (copy_from_user(param, (ioc_fm_pcd_kg_scheme_spc_t *)arg,
112469 + sizeof(ioc_fm_pcd_kg_scheme_spc_t)))
112470 + {
112471 + XX_Free(param);
112472 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
112473 + }
112474 + }
112475 +
112476 + param->val = FM_PCD_KgSchemeGetCounter((t_Handle)param->id);
112477 +
112478 +#if defined(CONFIG_COMPAT)
112479 + if (compat)
112480 + {
112481 + ioc_compat_fm_pcd_kg_scheme_spc_t *compat_param;
112482 +
112483 + compat_param = (ioc_compat_fm_pcd_kg_scheme_spc_t *) XX_Malloc(
112484 + sizeof(ioc_compat_fm_pcd_kg_scheme_spc_t));
112485 + if (!compat_param)
112486 + {
112487 + XX_Free(param);
112488 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
112489 + }
112490 +
112491 + memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_kg_scheme_spc_t));
112492 + compat_copy_fm_pcd_kg_scheme_spc(compat_param, param, COMPAT_K_TO_US);
112493 + if (copy_to_user((ioc_compat_fm_pcd_kg_scheme_spc_t *)compat_ptr(arg),
112494 + compat_param,
112495 + sizeof(ioc_compat_fm_pcd_kg_scheme_spc_t)))
112496 + err = E_READ_FAILED;
112497 +
112498 + XX_Free(compat_param);
112499 + }
112500 + else
112501 +#endif
112502 + {
112503 + if (copy_to_user((ioc_fm_pcd_kg_scheme_spc_t *)arg,
112504 + param,
112505 + sizeof(ioc_fm_pcd_kg_scheme_spc_t)))
112506 + err = E_READ_FAILED;
112507 + }
112508 +
112509 + XX_Free(param);
112510 + break;
112511 + }
112512 +
112513 +#if defined(CONFIG_COMPAT)
112514 + case FM_PCD_IOC_KG_SCHEME_DELETE_COMPAT:
112515 +#endif
112516 + case FM_PCD_IOC_KG_SCHEME_DELETE:
112517 + {
112518 + ioc_fm_obj_t id;
112519 +
112520 + memset(&id, 0 , sizeof(ioc_fm_obj_t));
112521 +
112522 +#if defined(CONFIG_COMPAT)
112523 + if (compat)
112524 + {
112525 + ioc_compat_fm_obj_t compat_id;
112526 +
112527 + if (copy_from_user(&compat_id, (ioc_compat_fm_obj_t *) compat_ptr(arg), sizeof(ioc_compat_fm_obj_t)))
112528 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
112529 +
112530 + compat_obj_delete(&compat_id, &id);
112531 + }
112532 + else
112533 +#endif
112534 + {
112535 + if (copy_from_user(&id, (ioc_fm_obj_t *) arg, sizeof(ioc_fm_obj_t)))
112536 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
112537 + }
112538 +
112539 + err = FM_PCD_KgSchemeDelete(id.obj);
112540 + break;
112541 + }
112542 +
112543 +#if defined(CONFIG_COMPAT)
112544 + case FM_PCD_IOC_MATCH_TABLE_SET_COMPAT:
112545 +#endif
112546 + case FM_PCD_IOC_MATCH_TABLE_SET:
112547 + {
112548 + ioc_fm_pcd_cc_node_params_t *param;
112549 + uint8_t *keys;
112550 + uint8_t *masks;
112551 + int i,k;
112552 +
112553 + param = (ioc_fm_pcd_cc_node_params_t *) XX_Malloc(
112554 + sizeof(ioc_fm_pcd_cc_node_params_t) +
112555 + 2 * IOC_FM_PCD_MAX_NUM_OF_KEYS * IOC_FM_PCD_MAX_SIZE_OF_KEY);
112556 + if (!param)
112557 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
112558 +
112559 + memset(param, 0, sizeof(ioc_fm_pcd_cc_node_params_t) +
112560 + 2 * IOC_FM_PCD_MAX_NUM_OF_KEYS * IOC_FM_PCD_MAX_SIZE_OF_KEY);
112561 +
112562 + keys = (uint8_t *) (param + 1);
112563 + masks = keys + IOC_FM_PCD_MAX_NUM_OF_KEYS * IOC_FM_PCD_MAX_SIZE_OF_KEY;
112564 +
112565 +#if defined(CONFIG_COMPAT)
112566 + if (compat)
112567 + {
112568 + ioc_compat_fm_pcd_cc_node_params_t *compat_param;
112569 +
112570 + compat_param = (ioc_compat_fm_pcd_cc_node_params_t *) XX_Malloc(
112571 + sizeof(ioc_compat_fm_pcd_cc_node_params_t) +
112572 + 2 * IOC_FM_PCD_MAX_NUM_OF_KEYS * IOC_FM_PCD_MAX_SIZE_OF_KEY);
112573 + if (!compat_param)
112574 + {
112575 + XX_Free(param);
112576 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
112577 + }
112578 +
112579 + memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_cc_node_params_t) +
112580 + 2 * IOC_FM_PCD_MAX_NUM_OF_KEYS * IOC_FM_PCD_MAX_SIZE_OF_KEY);
112581 +
112582 + if (copy_from_user(compat_param,
112583 + (ioc_compat_fm_pcd_cc_node_params_t *)compat_ptr(arg),
112584 + sizeof(ioc_compat_fm_pcd_cc_node_params_t)))
112585 + {
112586 + XX_Free(compat_param);
112587 + XX_Free(param);
112588 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
112589 + }
112590 +
112591 + compat_copy_fm_pcd_cc_node(compat_param, param, COMPAT_US_TO_K);
112592 +
112593 + XX_Free(compat_param);
112594 + }
112595 + else
112596 +#endif
112597 + {
112598 + if (copy_from_user(param, (ioc_fm_pcd_cc_node_params_t *)arg, sizeof(ioc_fm_pcd_cc_node_params_t)))
112599 + {
112600 + XX_Free(param);
112601 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
112602 + }
112603 + }
112604 +
112605 + ASSERT_COND(param->keys_params.num_of_keys <= IOC_FM_PCD_MAX_NUM_OF_KEYS);
112606 + ASSERT_COND(param->keys_params.key_size <= IOC_FM_PCD_MAX_SIZE_OF_KEY);
112607 +
112608 + /* support for indexed lookup */
112609 + if( !(param->extract_cc_params.type == e_IOC_FM_PCD_EXTRACT_NON_HDR &&
112610 + param->extract_cc_params.extract_params.extract_non_hdr.src == e_IOC_FM_PCD_EXTRACT_FROM_HASH &&
112611 + param->extract_cc_params.extract_params.extract_non_hdr.action == e_IOC_FM_PCD_ACTION_INDEXED_LOOKUP))
112612 + {
112613 + for (i=0, k=0;
112614 + i < param->keys_params.num_of_keys;
112615 + i++, k += IOC_FM_PCD_MAX_SIZE_OF_KEY)
112616 + {
112617 + if (param->keys_params.key_params[i].p_key &&
112618 + param->keys_params.key_size)
112619 + {
112620 + if (copy_from_user(&keys[k],
112621 + param->keys_params.key_params[i].p_key,
112622 + param->keys_params.key_size))
112623 + {
112624 + XX_Free(param);
112625 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
112626 + }
112627 +
112628 + param->keys_params.key_params[i].p_key = &keys[k];
112629 + }
112630 +
112631 + if (param->keys_params.key_params[i].p_mask)
112632 + {
112633 + if (copy_from_user(&masks[k],
112634 + param->keys_params.key_params[i].p_mask,
112635 + param->keys_params.key_size))
112636 + {
112637 + XX_Free(param);
112638 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
112639 + }
112640 +
112641 + param->keys_params.key_params[i].p_mask = &masks[k];
112642 + }
112643 + }
112644 + }
112645 +
112646 + param->id = FM_PCD_MatchTableSet(p_LnxWrpFmDev->h_PcdDev, (t_FmPcdCcNodeParams*)param);
112647 +
112648 + if (!param->id) {
112649 + XX_Free(param);
112650 + err = E_INVALID_VALUE;
112651 + /* Since the LLD has no errno-style error reporting,
112652 + we're left here with no other option than to report
112653 + a generic E_INVALID_VALUE */
112654 + break;
112655 + }
112656 +
112657 +#if defined(CONFIG_COMPAT)
112658 + if (compat)
112659 + {
112660 + ioc_compat_fm_pcd_cc_node_params_t *compat_param;
112661 + compat_param = (ioc_compat_fm_pcd_cc_node_params_t *) XX_Malloc(
112662 + sizeof(ioc_compat_fm_pcd_cc_node_params_t) +
112663 + 2 * IOC_FM_PCD_MAX_NUM_OF_KEYS * IOC_FM_PCD_MAX_SIZE_OF_KEY);
112664 + if (!compat_param)
112665 + {
112666 + XX_Free(param);
112667 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
112668 + }
112669 +
112670 + memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_cc_node_params_t) +
112671 + 2 * IOC_FM_PCD_MAX_NUM_OF_KEYS * IOC_FM_PCD_MAX_SIZE_OF_KEY);
112672 + compat_copy_fm_pcd_cc_node(compat_param, param, COMPAT_K_TO_US);
112673 +
112674 + if (copy_to_user((ioc_compat_fm_pcd_cc_node_params_t *)compat_ptr(arg),
112675 + compat_param,
112676 + sizeof(ioc_compat_fm_pcd_cc_node_params_t)))
112677 + err = E_READ_FAILED;
112678 +
112679 + XX_Free(compat_param);
112680 + }
112681 + else
112682 +#endif
112683 + {
112684 + if (copy_to_user((ioc_fm_pcd_cc_node_params_t *)arg,
112685 + param,
112686 + sizeof(ioc_fm_pcd_cc_node_params_t)))
112687 + err = E_READ_FAILED;
112688 + }
112689 +
112690 + XX_Free(param);
112691 + break;
112692 + }
112693 +
112694 +#if defined(CONFIG_COMPAT)
112695 + case FM_PCD_IOC_MATCH_TABLE_DELETE_COMPAT:
112696 +#endif
112697 + case FM_PCD_IOC_MATCH_TABLE_DELETE:
112698 + {
112699 + ioc_fm_obj_t id;
112700 +
112701 + memset(&id, 0 , sizeof(ioc_fm_obj_t));
112702 +
112703 +#if defined(CONFIG_COMPAT)
112704 + if (compat)
112705 + {
112706 + ioc_compat_fm_obj_t compat_id;
112707 +
112708 + if (copy_from_user(&compat_id, (ioc_compat_fm_obj_t *) compat_ptr(arg), sizeof(ioc_compat_fm_obj_t)))
112709 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
112710 +
112711 + compat_obj_delete(&compat_id, &id);
112712 + }
112713 + else
112714 +#endif
112715 + {
112716 + if (copy_from_user(&id, (ioc_fm_obj_t *) arg, sizeof(ioc_fm_obj_t)))
112717 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
112718 + }
112719 +
112720 + err = FM_PCD_MatchTableDelete(id.obj);
112721 + break;
112722 + }
112723 +
112724 +#if defined(CONFIG_COMPAT)
112725 + case FM_PCD_IOC_CC_ROOT_BUILD_COMPAT:
112726 +#endif
112727 + case FM_PCD_IOC_CC_ROOT_BUILD:
112728 + {
112729 + ioc_fm_pcd_cc_tree_params_t *param;
112730 +
112731 + param = (ioc_fm_pcd_cc_tree_params_t *) XX_Malloc(sizeof(ioc_fm_pcd_cc_tree_params_t));
112732 + if (!param)
112733 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
112734 +
112735 + memset(param, 0, sizeof(ioc_fm_pcd_cc_tree_params_t));
112736 +
112737 +#if defined(CONFIG_COMPAT)
112738 + if (compat)
112739 + {
112740 + ioc_compat_fm_pcd_cc_tree_params_t *compat_param;
112741 +
112742 + compat_param = (ioc_compat_fm_pcd_cc_tree_params_t *) XX_Malloc(
112743 + sizeof(ioc_compat_fm_pcd_cc_tree_params_t));
112744 + if (!compat_param)
112745 + {
112746 + XX_Free(param);
112747 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
112748 + }
112749 +
112750 + memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_cc_tree_params_t));
112751 + if (copy_from_user(compat_param,
112752 + (ioc_compat_fm_pcd_cc_tree_params_t *)compat_ptr(arg),
112753 + sizeof(ioc_compat_fm_pcd_cc_tree_params_t)))
112754 + {
112755 + XX_Free(compat_param);
112756 + XX_Free(param);
112757 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
112758 + }
112759 +
112760 + compat_copy_fm_pcd_cc_tree(compat_param, param, COMPAT_US_TO_K);
112761 +
112762 + XX_Free(compat_param);
112763 + }
112764 + else
112765 +#endif
112766 + {
112767 + if (copy_from_user(param, (ioc_fm_pcd_cc_tree_params_t *)arg,
112768 + sizeof(ioc_fm_pcd_cc_tree_params_t)))
112769 + {
112770 + XX_Free(param);
112771 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
112772 + }
112773 + }
112774 +
112775 + param->id = FM_PCD_CcRootBuild(p_LnxWrpFmDev->h_PcdDev, (t_FmPcdCcTreeParams*)param);
112776 +
112777 + if (!param->id) {
112778 + XX_Free(param);
112779 + err = E_INVALID_VALUE;
112780 + /* Since the LLD has no errno-style error reporting,
112781 + we're left here with no other option than to report
112782 + a generic E_INVALID_VALUE */
112783 + break;
112784 + }
112785 +
112786 +#if defined(CONFIG_COMPAT)
112787 + if (compat)
112788 + {
112789 + ioc_compat_fm_pcd_cc_tree_params_t *compat_param;
112790 +
112791 + compat_param = (ioc_compat_fm_pcd_cc_tree_params_t *) XX_Malloc(sizeof(ioc_compat_fm_pcd_cc_tree_params_t));
112792 + if (!compat_param)
112793 + {
112794 + XX_Free(param);
112795 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
112796 + }
112797 +
112798 + memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_cc_tree_params_t));
112799 +
112800 + compat_copy_fm_pcd_cc_tree(compat_param, param, COMPAT_K_TO_US);
112801 +
112802 + if (copy_to_user((ioc_compat_fm_pcd_cc_tree_params_t *)compat_ptr(arg),
112803 + compat_param,
112804 + sizeof(ioc_compat_fm_pcd_cc_tree_params_t)))
112805 + err = E_READ_FAILED;
112806 +
112807 + XX_Free(compat_param);
112808 + }
112809 + else
112810 +#endif
112811 + {
112812 + if (copy_to_user((ioc_fm_pcd_cc_tree_params_t *)arg,
112813 + param,
112814 + sizeof(ioc_fm_pcd_cc_tree_params_t)))
112815 + err = E_READ_FAILED;
112816 + }
112817 +
112818 + XX_Free(param);
112819 + break;
112820 + }
112821 +
112822 +#if defined(CONFIG_COMPAT)
112823 + case FM_PCD_IOC_CC_ROOT_DELETE_COMPAT:
112824 +#endif
112825 + case FM_PCD_IOC_CC_ROOT_DELETE:
112826 + {
112827 + ioc_fm_obj_t id;
112828 +
112829 + memset(&id, 0 , sizeof(ioc_fm_obj_t));
112830 +
112831 +#if defined(CONFIG_COMPAT)
112832 + if (compat)
112833 + {
112834 + ioc_compat_fm_obj_t compat_id;
112835 +
112836 + if (copy_from_user(&compat_id, (ioc_compat_fm_obj_t *) compat_ptr(arg), sizeof(ioc_compat_fm_obj_t)))
112837 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
112838 +
112839 + compat_obj_delete(&compat_id, &id);
112840 + }
112841 + else
112842 +#endif
112843 + {
112844 + if (copy_from_user(&id, (ioc_fm_obj_t *) arg, sizeof(ioc_fm_obj_t)))
112845 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
112846 + }
112847 +
112848 + err = FM_PCD_CcRootDelete(id.obj);
112849 + break;
112850 + }
112851 +
112852 +#if defined(CONFIG_COMPAT)
112853 + case FM_PCD_IOC_PLCR_PROFILE_SET_COMPAT:
112854 +#endif
112855 + case FM_PCD_IOC_PLCR_PROFILE_SET:
112856 + {
112857 + ioc_fm_pcd_plcr_profile_params_t *param;
112858 +
112859 + param = (ioc_fm_pcd_plcr_profile_params_t *) XX_Malloc(
112860 + sizeof(ioc_fm_pcd_plcr_profile_params_t));
112861 + if (!param)
112862 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
112863 +
112864 + memset(param, 0, sizeof(ioc_fm_pcd_plcr_profile_params_t));
112865 +
112866 +#if defined(CONFIG_COMPAT)
112867 + if (compat)
112868 + {
112869 + ioc_compat_fm_pcd_plcr_profile_params_t *compat_param;
112870 +
112871 + compat_param = (ioc_compat_fm_pcd_plcr_profile_params_t *) XX_Malloc(
112872 + sizeof(ioc_compat_fm_pcd_plcr_profile_params_t));
112873 + if (!compat_param)
112874 + {
112875 + XX_Free(param);
112876 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
112877 + }
112878 +
112879 + memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_plcr_profile_params_t));
112880 + if (copy_from_user(compat_param, (
112881 + ioc_compat_fm_pcd_plcr_profile_params_t *)compat_ptr(arg),
112882 + sizeof(ioc_compat_fm_pcd_plcr_profile_params_t)))
112883 + {
112884 + XX_Free(compat_param);
112885 + XX_Free(param);
112886 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
112887 + }
112888 +
112889 + compat_copy_fm_pcd_plcr_profile(compat_param, param, COMPAT_US_TO_K);
112890 +
112891 + XX_Free(compat_param);
112892 + }
112893 + else
112894 +#endif
112895 + {
112896 + if (copy_from_user(param, (ioc_fm_pcd_plcr_profile_params_t *)arg,
112897 + sizeof(ioc_fm_pcd_plcr_profile_params_t)))
112898 + {
112899 + XX_Free(param);
112900 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
112901 + }
112902 + }
112903 +
112904 + if (!param->modify &&
112905 + (((t_FmPcdPlcrProfileParams*)param)->id.newParams.profileType != e_FM_PCD_PLCR_SHARED))
112906 + {
112907 + t_Handle h_Port;
112908 + ioc_fm_pcd_port_params_t *port_params;
112909 +
112910 + port_params = (ioc_fm_pcd_port_params_t*) XX_Malloc(sizeof(ioc_fm_pcd_port_params_t));
112911 + if (!port_params)
112912 + {
112913 + XX_Free(param);
112914 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
112915 + }
112916 +
112917 + memset(port_params, 0, sizeof(ioc_fm_pcd_port_params_t));
112918 + if (copy_from_user(port_params, (ioc_fm_pcd_port_params_t*)((t_FmPcdPlcrProfileParams*)param)->id.newParams.h_FmPort,
112919 + sizeof(ioc_fm_pcd_port_params_t)))
112920 + {
112921 + XX_Free(port_params);
112922 + XX_Free(param);
112923 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
112924 + }
112925 +
112926 + switch(port_params->port_type)
112927 + {
112928 + case (e_IOC_FM_PORT_TYPE_RX):
112929 + if (port_params->port_id < FM_MAX_NUM_OF_1G_RX_PORTS) {
112930 + h_Port = p_LnxWrpFmDev->rxPorts[port_params->port_id].h_Dev;
112931 + break;
112932 + }
112933 + goto invalid_port_id;
112934 +
112935 + case (e_IOC_FM_PORT_TYPE_RX_10G):
112936 + if (port_params->port_id < FM_MAX_NUM_OF_10G_RX_PORTS) {
112937 +#ifndef CONFIG_FMAN_ARM
112938 + if (IS_T1023_T1024) {
112939 + h_Port = p_LnxWrpFmDev->rxPorts[port_params->port_id].h_Dev;
112940 + } else {
112941 +#else
112942 + {
112943 +#endif
112944 + h_Port = p_LnxWrpFmDev->rxPorts[port_params->port_id + FM_MAX_NUM_OF_1G_RX_PORTS].h_Dev;
112945 + }
112946 + break;
112947 + }
112948 + goto invalid_port_id;
112949 +
112950 + case (e_IOC_FM_PORT_TYPE_OH_OFFLINE_PARSING):
112951 + if (port_params->port_id && port_params->port_id < FM_MAX_NUM_OF_OH_PORTS) {
112952 + h_Port = p_LnxWrpFmDev->opPorts[port_params->port_id - 1].h_Dev;
112953 + break;
112954 + }
112955 + goto invalid_port_id;
112956 +
112957 + default:
112958 +invalid_port_id:
112959 + XX_Free(port_params);
112960 + XX_Free(param);
112961 + RETURN_ERROR(MINOR, E_INVALID_SELECTION, NO_MSG);
112962 + }
112963 +
112964 + ((t_FmPcdPlcrProfileParams*)param)->id.newParams.h_FmPort = h_Port;
112965 + XX_Free(port_params);
112966 + }
112967 +
112968 + param->id = FM_PCD_PlcrProfileSet(p_LnxWrpFmDev->h_PcdDev, (t_FmPcdPlcrProfileParams*)param);
112969 +
112970 + if (!param->id) {
112971 + XX_Free(param);
112972 + err = E_INVALID_VALUE;
112973 + /* Since the LLD has no errno-style error reporting,
112974 + we're left here with no other option than to report
112975 + a generic E_INVALID_VALUE */
112976 + break;
112977 + }
112978 +
112979 +#if defined(CONFIG_COMPAT)
112980 + if (compat)
112981 + {
112982 + ioc_compat_fm_pcd_plcr_profile_params_t *compat_param;
112983 +
112984 + compat_param = (ioc_compat_fm_pcd_plcr_profile_params_t *) XX_Malloc(
112985 + sizeof(ioc_compat_fm_pcd_plcr_profile_params_t));
112986 + if (!compat_param)
112987 + {
112988 + XX_Free(param);
112989 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
112990 + }
112991 +
112992 + memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_plcr_profile_params_t));
112993 + compat_copy_fm_pcd_plcr_profile(compat_param, param, COMPAT_K_TO_US);
112994 + if (copy_to_user((ioc_compat_fm_pcd_plcr_profile_params_t *) compat_ptr(arg),
112995 + compat_param,
112996 + sizeof(ioc_compat_fm_pcd_plcr_profile_params_t)))
112997 + err = E_READ_FAILED;
112998 +
112999 + XX_Free(compat_param);
113000 + }
113001 + else
113002 +#endif
113003 + {
113004 + if (copy_to_user((ioc_fm_pcd_plcr_profile_params_t *)arg,
113005 + param,
113006 + sizeof(ioc_fm_pcd_plcr_profile_params_t)))
113007 + err = E_READ_FAILED;
113008 + }
113009 +
113010 + XX_Free(param);
113011 + break;
113012 + }
113013 +
113014 +#if defined(CONFIG_COMPAT)
113015 + case FM_PCD_IOC_PLCR_PROFILE_DELETE_COMPAT:
113016 +#endif
113017 + case FM_PCD_IOC_PLCR_PROFILE_DELETE:
113018 + {
113019 + ioc_fm_obj_t id;
113020 +
113021 + memset(&id, 0 , sizeof(ioc_fm_obj_t));
113022 +
113023 +#if defined(CONFIG_COMPAT)
113024 + if (compat)
113025 + {
113026 + ioc_compat_fm_obj_t compat_id;
113027 +
113028 + if (copy_from_user(&compat_id, (ioc_compat_fm_obj_t *) compat_ptr(arg), sizeof(ioc_compat_fm_obj_t)))
113029 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
113030 +
113031 + compat_obj_delete(&compat_id, &id);
113032 + }
113033 + else
113034 +#endif
113035 + {
113036 + if (copy_from_user(&id, (ioc_fm_obj_t *) arg, sizeof(ioc_fm_obj_t)))
113037 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
113038 + }
113039 +
113040 + err = FM_PCD_PlcrProfileDelete(id.obj);
113041 + break;
113042 + }
113043 +
113044 +#if defined(CONFIG_COMPAT)
113045 + case FM_PCD_IOC_CC_ROOT_MODIFY_NEXT_ENGINE_COMPAT:
113046 +#endif
113047 + case FM_PCD_IOC_CC_ROOT_MODIFY_NEXT_ENGINE:
113048 + {
113049 + ioc_fm_pcd_cc_tree_modify_next_engine_params_t *param;
113050 +
113051 + param = (ioc_fm_pcd_cc_tree_modify_next_engine_params_t *) XX_Malloc(
113052 + sizeof(ioc_fm_pcd_cc_tree_modify_next_engine_params_t));
113053 + if (!param)
113054 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
113055 +
113056 + memset(param, 0, sizeof(ioc_fm_pcd_cc_tree_modify_next_engine_params_t));
113057 +
113058 +#if defined(CONFIG_COMPAT)
113059 + if (compat)
113060 + {
113061 + ioc_compat_fm_pcd_cc_tree_modify_next_engine_params_t *compat_param;
113062 +
113063 + compat_param = (ioc_compat_fm_pcd_cc_tree_modify_next_engine_params_t *) XX_Malloc(
113064 + sizeof(ioc_compat_fm_pcd_cc_tree_modify_next_engine_params_t));
113065 + if (!compat_param)
113066 + {
113067 + XX_Free(param);
113068 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
113069 + }
113070 +
113071 + memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_cc_tree_modify_next_engine_params_t));
113072 + if (copy_from_user(compat_param, (ioc_compat_fm_pcd_cc_tree_modify_next_engine_params_t *) compat_ptr(arg),
113073 + sizeof(ioc_compat_fm_pcd_cc_tree_modify_next_engine_params_t)))
113074 + {
113075 + XX_Free(compat_param);
113076 + XX_Free(param);
113077 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
113078 + }
113079 +
113080 + compat_fm_pcd_cc_tree_modify_next_engine(compat_param, param, COMPAT_US_TO_K);
113081 +
113082 + XX_Free(compat_param);
113083 + }
113084 + else
113085 +#endif
113086 + {
113087 + if (copy_from_user(param, (ioc_fm_pcd_cc_tree_modify_next_engine_params_t *)arg,
113088 + sizeof(ioc_fm_pcd_cc_tree_modify_next_engine_params_t)))
113089 + {
113090 + XX_Free(param);
113091 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
113092 + }
113093 + }
113094 +
113095 + err = FM_PCD_CcRootModifyNextEngine(param->id,
113096 + param->grp_indx,
113097 + param->indx,
113098 + (t_FmPcdCcNextEngineParams*)(&param->cc_next_engine_params));
113099 +
113100 + XX_Free(param);
113101 + break;
113102 + }
113103 +
113104 +#if defined(CONFIG_COMPAT)
113105 + case FM_PCD_IOC_MATCH_TABLE_MODIFY_NEXT_ENGINE_COMPAT:
113106 +#endif
113107 + case FM_PCD_IOC_MATCH_TABLE_MODIFY_NEXT_ENGINE:
113108 + {
113109 + ioc_fm_pcd_cc_node_modify_next_engine_params_t *param;
113110 +
113111 + param = (ioc_fm_pcd_cc_node_modify_next_engine_params_t *) XX_Malloc(
113112 + sizeof(ioc_fm_pcd_cc_node_modify_next_engine_params_t));
113113 + if (!param)
113114 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
113115 +
113116 + memset(param, 0, sizeof(ioc_fm_pcd_cc_node_modify_next_engine_params_t));
113117 +
113118 +#if defined(CONFIG_COMPAT)
113119 + if (compat)
113120 + {
113121 + ioc_compat_fm_pcd_cc_node_modify_next_engine_params_t *compat_param;
113122 +
113123 + compat_param = (ioc_compat_fm_pcd_cc_node_modify_next_engine_params_t *) XX_Malloc(
113124 + sizeof(ioc_compat_fm_pcd_cc_node_modify_next_engine_params_t));
113125 + if (!compat_param)
113126 + {
113127 + XX_Free(param);
113128 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
113129 + }
113130 +
113131 + memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_cc_node_modify_next_engine_params_t));
113132 + if (copy_from_user(compat_param, (ioc_compat_fm_pcd_cc_node_modify_next_engine_params_t *) compat_ptr(arg),
113133 + sizeof(ioc_compat_fm_pcd_cc_node_modify_next_engine_params_t)))
113134 + {
113135 + XX_Free(compat_param);
113136 + XX_Free(param);
113137 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
113138 + }
113139 +
113140 + compat_copy_fm_pcd_cc_node_modify_next_engine(compat_param, param, COMPAT_US_TO_K);
113141 +
113142 + XX_Free(compat_param);
113143 + }
113144 + else
113145 +#endif
113146 + {
113147 + if (copy_from_user(param, (ioc_fm_pcd_cc_node_modify_next_engine_params_t *)arg,
113148 + sizeof(ioc_fm_pcd_cc_node_modify_next_engine_params_t)))
113149 + {
113150 + XX_Free(param);
113151 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
113152 + }
113153 + }
113154 +
113155 + err = FM_PCD_MatchTableModifyNextEngine(param->id,
113156 + param->key_indx,
113157 + (t_FmPcdCcNextEngineParams*)(&param->cc_next_engine_params));
113158 +
113159 + XX_Free(param);
113160 + break;
113161 + }
113162 +
113163 +#if defined(CONFIG_COMPAT)
113164 + case FM_PCD_IOC_MATCH_TABLE_MODIFY_MISS_NEXT_ENGINE_COMPAT:
113165 +#endif
113166 + case FM_PCD_IOC_MATCH_TABLE_MODIFY_MISS_NEXT_ENGINE:
113167 + {
113168 + ioc_fm_pcd_cc_node_modify_next_engine_params_t *param;
113169 +
113170 + param = (ioc_fm_pcd_cc_node_modify_next_engine_params_t *) XX_Malloc(
113171 + sizeof(ioc_fm_pcd_cc_node_modify_next_engine_params_t));
113172 + if (!param)
113173 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
113174 +
113175 + memset(param, 0, sizeof(ioc_fm_pcd_cc_node_modify_next_engine_params_t));
113176 +
113177 +#if defined(CONFIG_COMPAT)
113178 + if (compat)
113179 + {
113180 + ioc_compat_fm_pcd_cc_node_modify_next_engine_params_t *compat_param;
113181 +
113182 + compat_param = (ioc_compat_fm_pcd_cc_node_modify_next_engine_params_t *) XX_Malloc(
113183 + sizeof(ioc_compat_fm_pcd_cc_node_modify_next_engine_params_t));
113184 + if (!compat_param)
113185 + {
113186 + XX_Free(param);
113187 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
113188 + }
113189 +
113190 + memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_cc_node_modify_next_engine_params_t));
113191 + if (copy_from_user(compat_param, (ioc_compat_fm_pcd_cc_node_modify_next_engine_params_t *) compat_ptr(arg),
113192 + sizeof(ioc_compat_fm_pcd_cc_node_modify_next_engine_params_t)))
113193 + {
113194 + XX_Free(compat_param);
113195 + XX_Free(param);
113196 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
113197 + }
113198 +
113199 + compat_copy_fm_pcd_cc_node_modify_next_engine(compat_param, param, COMPAT_US_TO_K);
113200 +
113201 + XX_Free(compat_param);
113202 + }
113203 + else
113204 +#endif
113205 + {
113206 + if (copy_from_user(param, (ioc_fm_pcd_cc_node_modify_next_engine_params_t *) arg,
113207 + sizeof(ioc_fm_pcd_cc_node_modify_next_engine_params_t)))
113208 + {
113209 + XX_Free(param);
113210 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
113211 + }
113212 + }
113213 +
113214 + err = FM_PCD_MatchTableModifyMissNextEngine(param->id,
113215 + (t_FmPcdCcNextEngineParams*)(&param->cc_next_engine_params));
113216 +
113217 + XX_Free(param);
113218 + break;
113219 + }
113220 +
113221 +#if defined(CONFIG_COMPAT)
113222 + case FM_PCD_IOC_MATCH_TABLE_REMOVE_KEY_COMPAT:
113223 +#endif
113224 + case FM_PCD_IOC_MATCH_TABLE_REMOVE_KEY:
113225 + {
113226 + ioc_fm_pcd_cc_node_remove_key_params_t *param;
113227 +
113228 + param = (ioc_fm_pcd_cc_node_remove_key_params_t *) XX_Malloc(
113229 + sizeof(ioc_fm_pcd_cc_node_remove_key_params_t));
113230 + if (!param)
113231 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
113232 +
113233 + memset(param, 0, sizeof(ioc_fm_pcd_cc_node_remove_key_params_t));
113234 +
113235 +#if defined(CONFIG_COMPAT)
113236 + if (compat)
113237 + {
113238 + ioc_compat_fm_pcd_cc_node_remove_key_params_t *compat_param;
113239 +
113240 + compat_param = (ioc_compat_fm_pcd_cc_node_remove_key_params_t *) XX_Malloc(
113241 + sizeof(ioc_compat_fm_pcd_cc_node_remove_key_params_t));
113242 + if (!compat_param)
113243 + {
113244 + XX_Free(param);
113245 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
113246 + }
113247 +
113248 + memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_cc_node_remove_key_params_t));
113249 + if (copy_from_user(compat_param,
113250 + (ioc_compat_fm_pcd_cc_node_remove_key_params_t *)compat_ptr(arg),
113251 + sizeof(ioc_compat_fm_pcd_cc_node_remove_key_params_t)))
113252 + {
113253 + XX_Free(compat_param);
113254 + XX_Free(param);
113255 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
113256 + }
113257 +
113258 + param->id = compat_ptr(compat_param->id);
113259 + param->key_indx = compat_param->key_indx;
113260 +
113261 + XX_Free(compat_param);
113262 + }
113263 + else
113264 +#endif
113265 + {
113266 + if (copy_from_user(param, (ioc_fm_pcd_cc_node_remove_key_params_t *) arg,
113267 + sizeof(ioc_fm_pcd_cc_node_remove_key_params_t)))
113268 + {
113269 + XX_Free(param);
113270 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
113271 + }
113272 + }
113273 +
113274 + err = FM_PCD_MatchTableRemoveKey(param->id, param->key_indx);
113275 +
113276 + XX_Free(param);
113277 + break;
113278 + }
113279 +#if defined(CONFIG_COMPAT)
113280 + case FM_PCD_IOC_MATCH_TABLE_ADD_KEY_COMPAT:
113281 +#endif
113282 + case FM_PCD_IOC_MATCH_TABLE_ADD_KEY:
113283 + {
113284 + ioc_fm_pcd_cc_node_modify_key_and_next_engine_params_t *param;
113285 +
113286 + param = (ioc_fm_pcd_cc_node_modify_key_and_next_engine_params_t *) XX_Malloc(
113287 + sizeof(ioc_fm_pcd_cc_node_modify_key_and_next_engine_params_t));
113288 + if (!param)
113289 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
113290 +
113291 + memset(param, 0, sizeof(ioc_fm_pcd_cc_node_modify_key_and_next_engine_params_t));
113292 +
113293 +#if defined(CONFIG_COMPAT)
113294 + if (compat)
113295 + {
113296 + ioc_compat_fm_pcd_cc_node_modify_key_and_next_engine_params_t *compat_param;
113297 +
113298 + compat_param = (ioc_compat_fm_pcd_cc_node_modify_key_and_next_engine_params_t *) XX_Malloc(
113299 + sizeof(ioc_compat_fm_pcd_cc_node_modify_key_and_next_engine_params_t));
113300 + if (!compat_param)
113301 + {
113302 + XX_Free(param);
113303 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
113304 + }
113305 +
113306 + memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_cc_node_modify_key_and_next_engine_params_t));
113307 + if (copy_from_user(compat_param,
113308 + (ioc_compat_fm_pcd_cc_node_modify_key_and_next_engine_params_t *)compat_ptr(arg),
113309 + sizeof(ioc_compat_fm_pcd_cc_node_modify_key_and_next_engine_params_t)))
113310 + {
113311 + XX_Free(compat_param);
113312 + XX_Free(param);
113313 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
113314 + }
113315 +
113316 + compat_copy_fm_pcd_cc_node_modify_key_and_next_engine(compat_param, param, COMPAT_US_TO_K);
113317 +
113318 + XX_Free(compat_param);
113319 + }
113320 + else
113321 +#endif
113322 + {
113323 + if (copy_from_user(param, (ioc_fm_pcd_cc_node_modify_key_and_next_engine_params_t *)arg,
113324 + sizeof(ioc_fm_pcd_cc_node_modify_key_and_next_engine_params_t)))
113325 + {
113326 + XX_Free(param);
113327 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
113328 + }
113329 + }
113330 +
113331 + if (param->key_size)
113332 + {
113333 + int size = 0;
113334 +
113335 + if (param->key_params.p_key) size += param->key_size;
113336 + if (param->key_params.p_mask) size += param->key_size;
113337 +
113338 + if (size)
113339 + {
113340 + uint8_t *p_tmp;
113341 +
113342 + p_tmp = (uint8_t*) XX_Malloc(size);
113343 + if (!p_tmp)
113344 + {
113345 + XX_Free(param);
113346 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD key/mask"));
113347 + }
113348 +
113349 + if (param->key_params.p_key)
113350 + {
113351 + if (copy_from_user(p_tmp, param->key_params.p_key, param->key_size))
113352 + {
113353 + XX_Free(p_tmp);
113354 + XX_Free(param);
113355 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
113356 + }
113357 +
113358 + param->key_params.p_key = p_tmp;
113359 + }
113360 +
113361 + if (param->key_params.p_mask)
113362 + {
113363 + p_tmp += param->key_size;
113364 + if (copy_from_user(p_tmp, param->key_params.p_mask, param->key_size))
113365 + {
113366 + XX_Free(p_tmp - param->key_size);
113367 + XX_Free(param);
113368 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
113369 + }
113370 +
113371 + param->key_params.p_mask = p_tmp;
113372 + }
113373 + }
113374 + }
113375 +
113376 + err = FM_PCD_MatchTableAddKey(
113377 + param->id,
113378 + param->key_indx,
113379 + param->key_size,
113380 + (t_FmPcdCcKeyParams*)&param->key_params);
113381 +
113382 + if (param->key_params.p_key)
113383 + XX_Free(param->key_params.p_key);
113384 + XX_Free(param);
113385 + break;
113386 + }
113387 +
113388 +#if defined(CONFIG_COMPAT)
113389 + case FM_PCD_IOC_MATCH_TABLE_MODIFY_KEY_AND_NEXT_ENGINE_COMPAT:
113390 +#endif
113391 + case FM_PCD_IOC_MATCH_TABLE_MODIFY_KEY_AND_NEXT_ENGINE:
113392 + {
113393 + ioc_fm_pcd_cc_node_modify_key_and_next_engine_params_t *param;
113394 +
113395 + param = (ioc_fm_pcd_cc_node_modify_key_and_next_engine_params_t *) XX_Malloc(
113396 + sizeof(ioc_fm_pcd_cc_node_modify_key_and_next_engine_params_t));
113397 + if (!param)
113398 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
113399 +
113400 + memset(param, 0, sizeof(ioc_fm_pcd_cc_node_modify_key_and_next_engine_params_t));
113401 +
113402 +#if defined(CONFIG_COMPAT)
113403 + if (compat)
113404 + {
113405 + ioc_compat_fm_pcd_cc_node_modify_key_and_next_engine_params_t *compat_param;
113406 +
113407 + compat_param = (ioc_compat_fm_pcd_cc_node_modify_key_and_next_engine_params_t *) XX_Malloc(
113408 + sizeof(ioc_compat_fm_pcd_cc_node_modify_key_and_next_engine_params_t));
113409 + if (!compat_param)
113410 + {
113411 + XX_Free(param);
113412 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
113413 + }
113414 +
113415 + memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_cc_node_modify_key_and_next_engine_params_t));
113416 + if (copy_from_user(compat_param,
113417 + (ioc_compat_fm_pcd_cc_node_modify_key_and_next_engine_params_t *)compat_ptr(arg),
113418 + sizeof(ioc_compat_fm_pcd_cc_node_modify_key_and_next_engine_params_t)))
113419 + {
113420 + XX_Free(compat_param);
113421 + XX_Free(param);
113422 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
113423 + }
113424 +
113425 + compat_copy_fm_pcd_cc_node_modify_key_and_next_engine(compat_param, param, COMPAT_US_TO_K);
113426 +
113427 + XX_Free(compat_param);
113428 + }
113429 + else
113430 +#endif
113431 + {
113432 + if (copy_from_user(param, (ioc_fm_pcd_cc_node_modify_key_and_next_engine_params_t *)arg,
113433 + sizeof(ioc_fm_pcd_cc_node_modify_key_and_next_engine_params_t)))
113434 + {
113435 + XX_Free(param);
113436 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
113437 + }
113438 + }
113439 +
113440 + err = FM_PCD_MatchTableModifyKeyAndNextEngine(param->id,
113441 + param->key_indx,
113442 + param->key_size,
113443 + (t_FmPcdCcKeyParams*)(&param->key_params));
113444 +
113445 + XX_Free(param);
113446 + break;
113447 + }
113448 +
113449 +
113450 +#if defined(CONFIG_COMPAT)
113451 + case FM_PCD_IOC_MATCH_TABLE_GET_KEY_STAT_COMPAT:
113452 +#endif
113453 + case FM_PCD_IOC_MATCH_TABLE_GET_KEY_STAT:
113454 + {
113455 + ioc_fm_pcd_cc_tbl_get_stats_t param;
113456 +
113457 +#if defined(CONFIG_COMPAT)
113458 + if (compat)
113459 + {
113460 + ioc_compat_fm_pcd_cc_tbl_get_stats_t *compat_param;
113461 +
113462 + compat_param = (ioc_compat_fm_pcd_cc_tbl_get_stats_t *) XX_Malloc(
113463 + sizeof(ioc_compat_fm_pcd_cc_tbl_get_stats_t));
113464 + if (!compat_param)
113465 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
113466 +
113467 + memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_cc_tbl_get_stats_t));
113468 + if (copy_from_user(compat_param,
113469 + (ioc_compat_fm_pcd_cc_tbl_get_stats_t *)compat_ptr(arg),
113470 + sizeof(ioc_compat_fm_pcd_cc_tbl_get_stats_t)))
113471 + {
113472 + XX_Free(compat_param);
113473 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
113474 + }
113475 +
113476 + compat_copy_fm_pcd_cc_tbl_get_stats(compat_param, &param, COMPAT_US_TO_K);
113477 +
113478 + XX_Free(compat_param);
113479 + }
113480 + else
113481 +#endif
113482 + {
113483 + if (copy_from_user(&param, (ioc_fm_pcd_cc_tbl_get_stats_t *)arg,
113484 + sizeof(ioc_fm_pcd_cc_tbl_get_stats_t)))
113485 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
113486 + }
113487 +
113488 +
113489 + err = FM_PCD_MatchTableGetKeyStatistics((t_Handle) param.id,
113490 + param.key_index,
113491 + (t_FmPcdCcKeyStatistics *) &param.statistics);
113492 +
113493 +#if defined(CONFIG_COMPAT)
113494 + if (compat)
113495 + {
113496 + ioc_compat_fm_pcd_cc_tbl_get_stats_t *compat_param;
113497 +
113498 + compat_param = (ioc_compat_fm_pcd_cc_tbl_get_stats_t*) XX_Malloc(
113499 + sizeof(ioc_compat_fm_pcd_cc_tbl_get_stats_t));
113500 + if (!compat_param)
113501 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
113502 +
113503 + memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_cc_tbl_get_stats_t));
113504 + compat_copy_fm_pcd_cc_tbl_get_stats(compat_param, &param, COMPAT_K_TO_US);
113505 + if (copy_to_user((ioc_compat_fm_pcd_cc_tbl_get_stats_t*) compat_ptr(arg),
113506 + compat_param,
113507 + sizeof(ioc_compat_fm_pcd_cc_tbl_get_stats_t))){
113508 + XX_Free(compat_param);
113509 + RETURN_ERROR(MINOR, E_READ_FAILED, NO_MSG);
113510 + }
113511 + XX_Free(compat_param);
113512 + }
113513 + else
113514 +#endif
113515 + {
113516 + if (copy_to_user((ioc_fm_pcd_cc_tbl_get_stats_t *)arg,
113517 + &param,
113518 + sizeof(ioc_fm_pcd_cc_tbl_get_stats_t)))
113519 + RETURN_ERROR(MINOR, E_READ_FAILED, NO_MSG);
113520 + }
113521 +
113522 + break;
113523 + }
113524 +
113525 +
113526 +#if defined(CONFIG_COMPAT)
113527 + case FM_PCD_IOC_MATCH_TABLE_GET_MISS_STAT_COMPAT:
113528 +#endif
113529 + case FM_PCD_IOC_MATCH_TABLE_GET_MISS_STAT:
113530 + {
113531 + ioc_fm_pcd_cc_tbl_get_stats_t param;
113532 +
113533 +#if defined(CONFIG_COMPAT)
113534 + if (compat)
113535 + {
113536 + ioc_compat_fm_pcd_cc_tbl_get_stats_t *compat_param;
113537 +
113538 + compat_param = (ioc_compat_fm_pcd_cc_tbl_get_stats_t *) XX_Malloc(
113539 + sizeof(ioc_compat_fm_pcd_cc_tbl_get_stats_t));
113540 + if (!compat_param)
113541 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
113542 +
113543 + memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_cc_tbl_get_stats_t));
113544 + if (copy_from_user(compat_param,
113545 + (ioc_compat_fm_pcd_cc_tbl_get_stats_t *)compat_ptr(arg),
113546 + sizeof(ioc_compat_fm_pcd_cc_tbl_get_stats_t)))
113547 + {
113548 + XX_Free(compat_param);
113549 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
113550 + }
113551 +
113552 + compat_copy_fm_pcd_cc_tbl_get_stats(compat_param, &param, COMPAT_US_TO_K);
113553 +
113554 + XX_Free(compat_param);
113555 + }
113556 + else
113557 +#endif
113558 + {
113559 + if (copy_from_user(&param, (ioc_fm_pcd_cc_tbl_get_stats_t *)arg,
113560 + sizeof(ioc_fm_pcd_cc_tbl_get_stats_t)))
113561 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
113562 + }
113563 +
113564 +
113565 + err = FM_PCD_MatchTableGetMissStatistics((t_Handle) param.id,
113566 + (t_FmPcdCcKeyStatistics *) &param.statistics);
113567 +
113568 +#if defined(CONFIG_COMPAT)
113569 + if (compat)
113570 + {
113571 + ioc_compat_fm_pcd_cc_tbl_get_stats_t *compat_param;
113572 +
113573 + compat_param = (ioc_compat_fm_pcd_cc_tbl_get_stats_t*) XX_Malloc(
113574 + sizeof(ioc_compat_fm_pcd_cc_tbl_get_stats_t));
113575 + if (!compat_param)
113576 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
113577 +
113578 + memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_cc_tbl_get_stats_t));
113579 + compat_copy_fm_pcd_cc_tbl_get_stats(compat_param, &param, COMPAT_K_TO_US);
113580 + if (copy_to_user((ioc_compat_fm_pcd_cc_tbl_get_stats_t*) compat_ptr(arg),
113581 + compat_param,
113582 + sizeof(ioc_compat_fm_pcd_cc_tbl_get_stats_t))){
113583 + XX_Free(compat_param);
113584 + RETURN_ERROR(MINOR, E_READ_FAILED, NO_MSG);
113585 + }
113586 + XX_Free(compat_param);
113587 + }
113588 + else
113589 +#endif
113590 + {
113591 + if (copy_to_user((ioc_fm_pcd_cc_tbl_get_stats_t *)arg,
113592 + &param,
113593 + sizeof(ioc_fm_pcd_cc_tbl_get_stats_t)))
113594 + RETURN_ERROR(MINOR, E_READ_FAILED, NO_MSG);
113595 + }
113596 +
113597 + break;
113598 + }
113599 +
113600 +
113601 +#if defined(CONFIG_COMPAT)
113602 + case FM_PCD_IOC_HASH_TABLE_GET_MISS_STAT_COMPAT:
113603 +#endif
113604 + case FM_PCD_IOC_HASH_TABLE_GET_MISS_STAT:
113605 + {
113606 + ioc_fm_pcd_cc_tbl_get_stats_t param;
113607 +
113608 +#if defined(CONFIG_COMPAT)
113609 + if (compat)
113610 + {
113611 + ioc_compat_fm_pcd_cc_tbl_get_stats_t *compat_param;
113612 +
113613 + compat_param = (ioc_compat_fm_pcd_cc_tbl_get_stats_t *) XX_Malloc(
113614 + sizeof(ioc_compat_fm_pcd_cc_tbl_get_stats_t));
113615 + if (!compat_param)
113616 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
113617 +
113618 + memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_cc_tbl_get_stats_t));
113619 + if (copy_from_user(compat_param,
113620 + (ioc_compat_fm_pcd_cc_tbl_get_stats_t *)compat_ptr(arg),
113621 + sizeof(ioc_compat_fm_pcd_cc_tbl_get_stats_t)))
113622 + {
113623 + XX_Free(compat_param);
113624 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
113625 + }
113626 +
113627 + compat_copy_fm_pcd_cc_tbl_get_stats(compat_param, &param, COMPAT_US_TO_K);
113628 +
113629 + XX_Free(compat_param);
113630 + }
113631 + else
113632 +#endif
113633 + {
113634 + if (copy_from_user(&param, (ioc_fm_pcd_cc_tbl_get_stats_t *)arg,
113635 + sizeof(ioc_fm_pcd_cc_tbl_get_stats_t)))
113636 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
113637 + }
113638 +
113639 +
113640 + err = FM_PCD_HashTableGetMissStatistics((t_Handle) param.id,
113641 + (t_FmPcdCcKeyStatistics *) &param.statistics);
113642 +
113643 +#if defined(CONFIG_COMPAT)
113644 + if (compat)
113645 + {
113646 + ioc_compat_fm_pcd_cc_tbl_get_stats_t *compat_param;
113647 +
113648 + compat_param = (ioc_compat_fm_pcd_cc_tbl_get_stats_t*) XX_Malloc(
113649 + sizeof(ioc_compat_fm_pcd_cc_tbl_get_stats_t));
113650 + if (!compat_param)
113651 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
113652 +
113653 + memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_cc_tbl_get_stats_t));
113654 + compat_copy_fm_pcd_cc_tbl_get_stats(compat_param, &param, COMPAT_K_TO_US);
113655 + if (copy_to_user((ioc_compat_fm_pcd_cc_tbl_get_stats_t*) compat_ptr(arg),
113656 + compat_param,
113657 + sizeof(ioc_compat_fm_pcd_cc_tbl_get_stats_t))){
113658 + XX_Free(compat_param);
113659 + RETURN_ERROR(MINOR, E_READ_FAILED, NO_MSG);
113660 + }
113661 + XX_Free(compat_param);
113662 + }
113663 + else
113664 +#endif
113665 + {
113666 + if (copy_to_user((ioc_fm_pcd_cc_tbl_get_stats_t *)arg,
113667 + &param,
113668 + sizeof(ioc_fm_pcd_cc_tbl_get_stats_t)))
113669 + RETURN_ERROR(MINOR, E_READ_FAILED, NO_MSG);
113670 + }
113671 +
113672 + break;
113673 + }
113674 +
113675 +#if defined(CONFIG_COMPAT)
113676 + case FM_PCD_IOC_HASH_TABLE_SET_COMPAT:
113677 +#endif
113678 + case FM_PCD_IOC_HASH_TABLE_SET:
113679 + {
113680 + ioc_fm_pcd_hash_table_params_t *param;
113681 +
113682 + param = (ioc_fm_pcd_hash_table_params_t*) XX_Malloc(
113683 + sizeof(ioc_fm_pcd_hash_table_params_t));
113684 + if (!param)
113685 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
113686 +
113687 + memset(param, 0, sizeof(ioc_fm_pcd_hash_table_params_t));
113688 +
113689 +#if defined(CONFIG_COMPAT)
113690 + if (compat)
113691 + {
113692 + ioc_compat_fm_pcd_hash_table_params_t *compat_param;
113693 +
113694 + compat_param = (ioc_compat_fm_pcd_hash_table_params_t*) XX_Malloc(
113695 + sizeof(ioc_compat_fm_pcd_hash_table_params_t));
113696 + if (!compat_param)
113697 + {
113698 + XX_Free(param);
113699 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
113700 + }
113701 +
113702 + memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_hash_table_params_t));
113703 + if (copy_from_user(compat_param,
113704 + (ioc_compat_fm_pcd_hash_table_params_t*)compat_ptr(arg),
113705 + sizeof(ioc_compat_fm_pcd_hash_table_params_t)))
113706 + {
113707 + XX_Free(compat_param);
113708 + XX_Free(param);
113709 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
113710 + }
113711 +
113712 + compat_copy_fm_pcd_hash_table(compat_param, param, COMPAT_US_TO_K);
113713 +
113714 + XX_Free(compat_param);
113715 + }
113716 + else
113717 +#endif
113718 + {
113719 + if (copy_from_user(param, (ioc_fm_pcd_hash_table_params_t *)arg,
113720 + sizeof(ioc_fm_pcd_hash_table_params_t)))
113721 + {
113722 + XX_Free(param);
113723 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
113724 + }
113725 + }
113726 +
113727 + param->id = FM_PCD_HashTableSet(p_LnxWrpFmDev->h_PcdDev, (t_FmPcdHashTableParams *) param);
113728 +
113729 + if (!param->id)
113730 + {
113731 + XX_Free(param);
113732 + err = E_INVALID_VALUE;
113733 + /* Since the LLD has no errno-style error reporting,
113734 + we're left here with no other option than to report
113735 + a generic E_INVALID_VALUE */
113736 + break;
113737 + }
113738 +
113739 +#if defined(CONFIG_COMPAT)
113740 + if (compat)
113741 + {
113742 + ioc_compat_fm_pcd_hash_table_params_t *compat_param;
113743 +
113744 + compat_param = (ioc_compat_fm_pcd_hash_table_params_t*) XX_Malloc(
113745 + sizeof(ioc_compat_fm_pcd_hash_table_params_t));
113746 + if (!compat_param)
113747 + {
113748 + XX_Free(param);
113749 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
113750 + }
113751 +
113752 + memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_hash_table_params_t));
113753 + compat_copy_fm_pcd_hash_table(compat_param, param, COMPAT_K_TO_US);
113754 + if (copy_to_user((ioc_compat_fm_pcd_hash_table_params_t*) compat_ptr(arg),
113755 + compat_param,
113756 + sizeof(ioc_compat_fm_pcd_hash_table_params_t)))
113757 + err = E_READ_FAILED;
113758 +
113759 + XX_Free(compat_param);
113760 + }
113761 + else
113762 +#endif
113763 + {
113764 + if (copy_to_user((ioc_fm_pcd_hash_table_params_t *)arg,
113765 + param,
113766 + sizeof(ioc_fm_pcd_hash_table_params_t)))
113767 + err = E_READ_FAILED;
113768 + }
113769 +
113770 + XX_Free(param);
113771 + break;
113772 + }
113773 +
113774 +#if defined(CONFIG_COMPAT)
113775 + case FM_PCD_IOC_HASH_TABLE_DELETE_COMPAT:
113776 +#endif
113777 + case FM_PCD_IOC_HASH_TABLE_DELETE:
113778 + {
113779 + ioc_fm_obj_t id;
113780 +
113781 + memset(&id, 0, sizeof(ioc_fm_obj_t));
113782 +
113783 +#if defined(CONFIG_COMPAT)
113784 + if (compat)
113785 + {
113786 + ioc_compat_fm_obj_t compat_id;
113787 +
113788 + if (copy_from_user(&compat_id, (ioc_compat_fm_obj_t *) compat_ptr(arg), sizeof(ioc_compat_fm_obj_t)))
113789 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
113790 +
113791 + id.obj = compat_pcd_id2ptr(compat_id.obj);
113792 + }
113793 + else
113794 +#endif
113795 + {
113796 + if (copy_from_user(&id, (ioc_fm_obj_t *) arg, sizeof(ioc_fm_obj_t)))
113797 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
113798 + }
113799 +
113800 + err = FM_PCD_HashTableDelete(id.obj);
113801 + break;
113802 + }
113803 +
113804 +#if defined(CONFIG_COMPAT)
113805 + case FM_PCD_IOC_HASH_TABLE_ADD_KEY_COMPAT:
113806 +#endif
113807 + case FM_PCD_IOC_HASH_TABLE_ADD_KEY:
113808 + {
113809 + ioc_fm_pcd_hash_table_add_key_params_t *param = NULL;
113810 +
113811 + param = (ioc_fm_pcd_hash_table_add_key_params_t*) XX_Malloc(
113812 + sizeof(ioc_fm_pcd_hash_table_add_key_params_t));
113813 + if (!param)
113814 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
113815 +
113816 + memset(param, 0, sizeof(ioc_fm_pcd_hash_table_add_key_params_t));
113817 +
113818 +#if defined(CONFIG_COMPAT)
113819 + if (compat)
113820 + {
113821 + ioc_compat_fm_pcd_hash_table_add_key_params_t *compat_param;
113822 +
113823 + compat_param = (ioc_compat_fm_pcd_hash_table_add_key_params_t*) XX_Malloc(
113824 + sizeof(ioc_compat_fm_pcd_hash_table_add_key_params_t));
113825 + if (!compat_param)
113826 + {
113827 + XX_Free(param);
113828 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
113829 + }
113830 +
113831 + memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_hash_table_add_key_params_t));
113832 + if (copy_from_user(compat_param,
113833 + (ioc_compat_fm_pcd_hash_table_add_key_params_t*) compat_ptr(arg),
113834 + sizeof(ioc_compat_fm_pcd_hash_table_add_key_params_t)))
113835 + {
113836 + XX_Free(compat_param);
113837 + XX_Free(param);
113838 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
113839 + }
113840 +
113841 + if (compat_param->key_size)
113842 + {
113843 + param->p_hash_tbl = compat_pcd_id2ptr(compat_param->p_hash_tbl);
113844 + param->key_size = compat_param->key_size;
113845 +
113846 + compat_copy_fm_pcd_cc_key(&compat_param->key_params, &param->key_params, COMPAT_US_TO_K);
113847 + }
113848 + else
113849 + {
113850 + XX_Free(compat_param);
113851 + XX_Free(param);
113852 + err = E_INVALID_VALUE;
113853 + break;
113854 + }
113855 +
113856 + XX_Free(compat_param);
113857 + }
113858 + else
113859 +#endif
113860 + {
113861 + if (copy_from_user(param, (ioc_fm_pcd_hash_table_add_key_params_t*) arg,
113862 + sizeof(ioc_fm_pcd_hash_table_add_key_params_t)))
113863 + {
113864 + XX_Free(param);
113865 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
113866 + }
113867 + }
113868 +
113869 + if (param->key_size)
113870 + {
113871 + int size = 0;
113872 +
113873 + if (param->key_params.p_key) size += param->key_size;
113874 + if (param->key_params.p_mask) size += param->key_size;
113875 +
113876 + if (size)
113877 + {
113878 + uint8_t *p_tmp;
113879 +
113880 + p_tmp = (uint8_t*) XX_Malloc(size);
113881 + if (!p_tmp)
113882 + {
113883 + XX_Free(param);
113884 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD key/mask"));
113885 + }
113886 +
113887 + if (param->key_params.p_key)
113888 + {
113889 + if (copy_from_user(p_tmp, param->key_params.p_key, param->key_size))
113890 + {
113891 + XX_Free(p_tmp);
113892 + XX_Free(param);
113893 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
113894 + }
113895 +
113896 + param->key_params.p_key = p_tmp;
113897 + }
113898 +
113899 + if (param->key_params.p_mask)
113900 + {
113901 + p_tmp += param->key_size;
113902 + if (copy_from_user(p_tmp, param->key_params.p_mask, param->key_size))
113903 + {
113904 + XX_Free(p_tmp - param->key_size);
113905 + XX_Free(param);
113906 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
113907 + }
113908 +
113909 + param->key_params.p_mask = p_tmp;
113910 + }
113911 + }
113912 + }
113913 +
113914 + err = FM_PCD_HashTableAddKey(
113915 + param->p_hash_tbl,
113916 + param->key_size,
113917 + (t_FmPcdCcKeyParams*)&param->key_params);
113918 +
113919 + if (param->key_params.p_key)
113920 + XX_Free(param->key_params.p_key);
113921 + XX_Free(param);
113922 + break;
113923 + }
113924 +
113925 +#if defined(CONFIG_COMPAT)
113926 + case FM_PCD_IOC_HASH_TABLE_REMOVE_KEY_COMPAT:
113927 +#endif
113928 + case FM_PCD_IOC_HASH_TABLE_REMOVE_KEY:
113929 + {
113930 + ioc_fm_pcd_hash_table_remove_key_params_t *param = NULL;
113931 +
113932 + param = (ioc_fm_pcd_hash_table_remove_key_params_t*) XX_Malloc(
113933 + sizeof(ioc_fm_pcd_hash_table_remove_key_params_t));
113934 + if (!param)
113935 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
113936 +
113937 + memset(param, 0, sizeof(ioc_fm_pcd_hash_table_remove_key_params_t));
113938 +
113939 +#if defined(CONFIG_COMPAT)
113940 + if (compat)
113941 + {
113942 + ioc_compat_fm_pcd_hash_table_remove_key_params_t *compat_param;
113943 +
113944 + compat_param = (ioc_compat_fm_pcd_hash_table_remove_key_params_t*) XX_Malloc(
113945 + sizeof(ioc_compat_fm_pcd_hash_table_remove_key_params_t));
113946 + if (!compat_param)
113947 + {
113948 + XX_Free(param);
113949 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
113950 + }
113951 +
113952 + memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_hash_table_remove_key_params_t));
113953 + if (copy_from_user(compat_param,
113954 + (ioc_compat_fm_pcd_hash_table_remove_key_params_t*) compat_ptr(arg),
113955 + sizeof(ioc_compat_fm_pcd_hash_table_remove_key_params_t)))
113956 + {
113957 + XX_Free(compat_param);
113958 + XX_Free(param);
113959 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
113960 + }
113961 +
113962 + param->p_hash_tbl = compat_pcd_id2ptr(compat_param->p_hash_tbl);
113963 + param->key_size = compat_param->key_size;
113964 +
113965 + XX_Free(compat_param);
113966 + }
113967 + else
113968 +#endif
113969 + {
113970 + if (copy_from_user(param, (ioc_fm_pcd_hash_table_remove_key_params_t*)arg,
113971 + sizeof(ioc_fm_pcd_hash_table_remove_key_params_t)))
113972 + {
113973 + XX_Free(param);
113974 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
113975 + }
113976 + }
113977 +
113978 + if (param->key_size)
113979 + {
113980 + uint8_t *p_key;
113981 +
113982 + p_key = (uint8_t*) XX_Malloc(param->key_size);
113983 + if (!p_key)
113984 + {
113985 + XX_Free(param);
113986 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
113987 + }
113988 +
113989 + if (param->p_key && copy_from_user(p_key, param->p_key, param->key_size))
113990 + {
113991 + XX_Free(p_key);
113992 + XX_Free(param);
113993 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
113994 + }
113995 + param->p_key = p_key;
113996 + }
113997 +
113998 + err = FM_PCD_HashTableRemoveKey(
113999 + param->p_hash_tbl,
114000 + param->key_size,
114001 + param->p_key);
114002 +
114003 + if (param->p_key)
114004 + XX_Free(param->p_key);
114005 + XX_Free(param);
114006 + break;
114007 + }
114008 +
114009 +#if defined(CONFIG_COMPAT)
114010 + case FM_PCD_IOC_MATCH_TABLE_MODIFY_KEY_COMPAT:
114011 +#endif
114012 + case FM_PCD_IOC_MATCH_TABLE_MODIFY_KEY:
114013 + {
114014 + ioc_fm_pcd_cc_node_modify_key_params_t *param;
114015 +
114016 + param = (ioc_fm_pcd_cc_node_modify_key_params_t *) XX_Malloc(
114017 + sizeof(ioc_fm_pcd_cc_node_modify_key_params_t));
114018 + if (!param)
114019 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
114020 +
114021 + memset(param, 0, sizeof(ioc_fm_pcd_cc_node_modify_key_params_t));
114022 +
114023 +#if defined(CONFIG_COMPAT)
114024 + if (compat)
114025 + {
114026 + ioc_compat_fm_pcd_cc_node_modify_key_params_t *compat_param;
114027 +
114028 + compat_param = (ioc_compat_fm_pcd_cc_node_modify_key_params_t *) XX_Malloc(
114029 + sizeof(ioc_compat_fm_pcd_cc_node_modify_key_params_t));
114030 + if (!compat_param)
114031 + {
114032 + XX_Free(param);
114033 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
114034 + }
114035 +
114036 + memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_cc_node_modify_key_params_t));
114037 + if (copy_from_user(compat_param, (ioc_compat_fm_pcd_cc_node_modify_key_params_t *)compat_ptr(arg),
114038 + sizeof(ioc_compat_fm_pcd_cc_node_modify_key_params_t)))
114039 + {
114040 + XX_Free(compat_param);
114041 + XX_Free(param);
114042 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
114043 + }
114044 +
114045 + compat_copy_fm_pcd_cc_node_modify_key(compat_param, param, COMPAT_US_TO_K);
114046 +
114047 + XX_Free(compat_param);
114048 + }
114049 + else
114050 +#endif
114051 + {
114052 + if (copy_from_user(param, (ioc_fm_pcd_cc_node_modify_key_params_t *)arg,
114053 + sizeof(ioc_fm_pcd_cc_node_modify_key_params_t)))
114054 + {
114055 + XX_Free(param);
114056 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
114057 + }
114058 + }
114059 +
114060 + if (param->key_size)
114061 + {
114062 + int size = 0;
114063 +
114064 + if (param->p_key) size += param->key_size;
114065 + if (param->p_mask) size += param->key_size;
114066 +
114067 + if (size)
114068 + {
114069 + uint8_t *p_tmp;
114070 +
114071 + p_tmp = (uint8_t*) XX_Malloc(size);
114072 + if (!p_tmp)
114073 + {
114074 + XX_Free(param);
114075 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD key/mask"));
114076 + }
114077 +
114078 + if (param->p_key)
114079 + {
114080 + if (copy_from_user(p_tmp, param->p_key, param->key_size))
114081 + {
114082 + XX_Free(p_tmp);
114083 + XX_Free(param);
114084 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
114085 + }
114086 +
114087 + param->p_key = p_tmp;
114088 + }
114089 +
114090 + if (param->p_mask)
114091 + {
114092 + p_tmp += param->key_size;
114093 + if (copy_from_user(p_tmp, param->p_mask, param->key_size))
114094 + {
114095 + XX_Free(p_tmp - param->key_size);
114096 + XX_Free(param);
114097 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
114098 + }
114099 +
114100 + param->p_mask = p_tmp;
114101 + }
114102 + }
114103 + }
114104 +
114105 + err = FM_PCD_MatchTableModifyKey(param->id,
114106 + param->key_indx,
114107 + param->key_size,
114108 + param->p_key,
114109 + param->p_mask);
114110 +
114111 + if (param->p_key)
114112 + XX_Free(param->p_key);
114113 + else if (param->p_mask)
114114 + XX_Free(param->p_mask);
114115 + XX_Free(param);
114116 + break;
114117 + }
114118 +
114119 +#if defined(CONFIG_COMPAT)
114120 + case FM_PCD_IOC_MANIP_NODE_SET_COMPAT:
114121 +#endif
114122 + case FM_PCD_IOC_MANIP_NODE_SET:
114123 + {
114124 + ioc_fm_pcd_manip_params_t *param;
114125 + uint8_t *p_data = NULL;
114126 + uint8_t size;
114127 +
114128 + param = (ioc_fm_pcd_manip_params_t *) XX_Malloc(
114129 + sizeof(ioc_fm_pcd_manip_params_t));
114130 +
114131 + if (!param)
114132 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
114133 +
114134 + memset(param, 0, sizeof(ioc_fm_pcd_manip_params_t));
114135 +
114136 +#if defined(CONFIG_COMPAT)
114137 + if (compat)
114138 + {
114139 + ioc_compat_fm_pcd_manip_params_t *compat_param;
114140 +
114141 + compat_param = (ioc_compat_fm_pcd_manip_params_t *) XX_Malloc(
114142 + sizeof(ioc_compat_fm_pcd_manip_params_t));
114143 + if (!compat_param)
114144 + {
114145 + XX_Free(param);
114146 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
114147 + }
114148 +
114149 + memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_manip_params_t));
114150 + if (copy_from_user(compat_param,
114151 + (ioc_compat_fm_pcd_manip_params_t *) compat_ptr(arg),
114152 + sizeof(ioc_compat_fm_pcd_manip_params_t)))
114153 + {
114154 + XX_Free(compat_param);
114155 + XX_Free(param);
114156 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
114157 + }
114158 +
114159 + compat_fm_pcd_manip_set_node(compat_param, param, COMPAT_US_TO_K);
114160 +
114161 + XX_Free(compat_param);
114162 + }
114163 + else
114164 +#endif
114165 + {
114166 + if (copy_from_user(param, (ioc_fm_pcd_manip_params_t *)arg,
114167 + sizeof(ioc_fm_pcd_manip_params_t)))
114168 + {
114169 + XX_Free(param);
114170 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
114171 + }
114172 + }
114173 +
114174 + if (param->type == e_IOC_FM_PCD_MANIP_HDR)
114175 + {
114176 + size = param->u.hdr.insrt_params.u.generic.size;
114177 + p_data = (uint8_t *) XX_Malloc(size);
114178 + if (!p_data )
114179 + {
114180 + XX_Free(param);
114181 + RETURN_ERROR(MINOR, E_NO_MEMORY, NO_MSG);
114182 + }
114183 +
114184 + if (param->u.hdr.insrt_params.u.generic.p_data &&
114185 + copy_from_user(p_data,
114186 + param->u.hdr.insrt_params.u.generic.p_data, size))
114187 + {
114188 + XX_Free(p_data);
114189 + XX_Free(param);
114190 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
114191 + }
114192 +
114193 + param->u.hdr.insrt_params.u.generic.p_data = p_data;
114194 + }
114195 +
114196 + if (param->id)
114197 + {
114198 + /* Security Hole: the user can pass any piece of garbage
114199 + in 'param->id', and that will go straight through to the LLD,
114200 + no checks being done by the wrapper! */
114201 + err = FM_PCD_ManipNodeReplace(
114202 + (t_Handle) param->id,
114203 + (t_FmPcdManipParams*) param);
114204 + if (err)
114205 + {
114206 + if (p_data)
114207 + XX_Free(p_data);
114208 + XX_Free(param);
114209 + break;
114210 + }
114211 + }
114212 + else
114213 + {
114214 + param->id = FM_PCD_ManipNodeSet(
114215 + p_LnxWrpFmDev->h_PcdDev,
114216 + (t_FmPcdManipParams*) param);
114217 + if (!param->id)
114218 + {
114219 + if (p_data)
114220 + XX_Free(p_data);
114221 + XX_Free(param);
114222 + err = E_INVALID_VALUE;
114223 + /* Since the LLD has no errno-style error reporting,
114224 + we're left here with no other option than to report
114225 + a generic E_INVALID_VALUE */
114226 + break;
114227 + }
114228 + }
114229 +
114230 +#if defined(CONFIG_COMPAT)
114231 + if (compat)
114232 + {
114233 + ioc_compat_fm_pcd_manip_params_t *compat_param;
114234 +
114235 + compat_param = (ioc_compat_fm_pcd_manip_params_t *) XX_Malloc(
114236 + sizeof(ioc_compat_fm_pcd_manip_params_t));
114237 + if (!compat_param)
114238 + {
114239 + if (p_data)
114240 + XX_Free(p_data);
114241 + XX_Free(param);
114242 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
114243 + }
114244 +
114245 + memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_manip_params_t));
114246 +
114247 + compat_fm_pcd_manip_set_node(compat_param, param, COMPAT_K_TO_US);
114248 +
114249 + if (copy_to_user((ioc_compat_fm_pcd_manip_params_t *) compat_ptr(arg),
114250 + compat_param,
114251 + sizeof(ioc_compat_fm_pcd_manip_params_t)))
114252 + err = E_READ_FAILED;
114253 +
114254 + XX_Free(compat_param);
114255 + }
114256 + else
114257 +#endif
114258 + {
114259 + if (copy_to_user((ioc_fm_pcd_manip_params_t *)arg,
114260 + param, sizeof(ioc_fm_pcd_manip_params_t)))
114261 + err = E_READ_FAILED;
114262 + }
114263 +
114264 + if (p_data)
114265 + XX_Free(p_data);
114266 + XX_Free(param);
114267 + break;
114268 + }
114269 +
114270 +#if defined(CONFIG_COMPAT)
114271 + case FM_PCD_IOC_MANIP_NODE_DELETE_COMPAT:
114272 +#endif
114273 + case FM_PCD_IOC_MANIP_NODE_DELETE:
114274 + {
114275 + ioc_fm_obj_t id;
114276 +
114277 + memset(&id, 0, sizeof(ioc_fm_obj_t));
114278 +#if defined(CONFIG_COMPAT)
114279 + if (compat)
114280 + {
114281 + ioc_compat_fm_obj_t compat_id;
114282 +
114283 + if (copy_from_user(&compat_id, (ioc_compat_fm_obj_t *) compat_ptr(arg), sizeof(ioc_compat_fm_obj_t)))
114284 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
114285 +
114286 + compat_obj_delete(&compat_id, &id);
114287 + }
114288 + else
114289 +#endif
114290 + {
114291 + if (copy_from_user(&id, (ioc_fm_obj_t *) arg, sizeof(ioc_fm_obj_t)))
114292 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
114293 + }
114294 +
114295 + err = FM_PCD_ManipNodeDelete(id.obj);
114296 + break;
114297 + }
114298 +
114299 +#if defined(CONFIG_COMPAT)
114300 + case FM_PCD_IOC_MANIP_GET_STATS_COMPAT:
114301 +#endif
114302 + case FM_PCD_IOC_MANIP_GET_STATS:
114303 + {
114304 + ioc_fm_pcd_manip_get_stats_t param;
114305 +
114306 +#if defined(CONFIG_COMPAT)
114307 + if (compat)
114308 + {
114309 + ioc_compat_fm_pcd_manip_get_stats_t *compat_param;
114310 +
114311 + compat_param = (ioc_compat_fm_pcd_manip_get_stats_t *) XX_Malloc(
114312 + sizeof(ioc_compat_fm_pcd_manip_get_stats_t));
114313 + if (!compat_param)
114314 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
114315 +
114316 + memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_manip_get_stats_t));
114317 + if (copy_from_user(compat_param,
114318 + (ioc_compat_fm_pcd_manip_get_stats_t *)compat_ptr(arg),
114319 + sizeof(ioc_compat_fm_pcd_manip_get_stats_t)))
114320 + {
114321 + XX_Free(compat_param);
114322 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
114323 + }
114324 +
114325 + compat_copy_fm_pcd_manip_get_stats(compat_param, &param, COMPAT_US_TO_K);
114326 +
114327 + XX_Free(compat_param);
114328 + }
114329 + else
114330 +#endif
114331 + {
114332 + if (copy_from_user(&param, (ioc_fm_pcd_manip_get_stats_t *)arg,
114333 + sizeof(ioc_fm_pcd_manip_get_stats_t)))
114334 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
114335 + }
114336 +
114337 + err = FM_PCD_ManipGetStatistics((t_Handle) param.id,
114338 + (t_FmPcdManipStats*) &param.stats);
114339 +
114340 +#if defined(CONFIG_COMPAT)
114341 + if (compat)
114342 + {
114343 + ioc_compat_fm_pcd_manip_get_stats_t *compat_param;
114344 +
114345 + compat_param = (ioc_compat_fm_pcd_manip_get_stats_t*) XX_Malloc(
114346 + sizeof(ioc_compat_fm_pcd_manip_get_stats_t));
114347 + if (!compat_param)
114348 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
114349 +
114350 + memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_manip_get_stats_t));
114351 + compat_copy_fm_pcd_manip_get_stats(compat_param, &param, COMPAT_K_TO_US);
114352 + if (copy_to_user((ioc_compat_fm_pcd_manip_get_stats_t*) compat_ptr(arg),
114353 + compat_param,
114354 + sizeof(ioc_compat_fm_pcd_manip_get_stats_t))){
114355 + XX_Free(compat_param);
114356 + RETURN_ERROR(MINOR, E_READ_FAILED, NO_MSG);
114357 + }
114358 + XX_Free(compat_param);
114359 + }
114360 + else
114361 +#endif
114362 + if (copy_to_user((ioc_fm_pcd_manip_get_stats_t *)arg,
114363 + &param,
114364 + sizeof(ioc_fm_pcd_manip_get_stats_t)))
114365 + RETURN_ERROR(MINOR, E_READ_FAILED, NO_MSG);
114366 +
114367 + break;
114368 + }
114369 +
114370 +#if (DPAA_VERSION >= 11)
114371 +#if defined(CONFIG_COMPAT)
114372 + case FM_PCD_IOC_FRM_REPLIC_GROUP_SET_COMPAT:
114373 +#endif
114374 + case FM_PCD_IOC_FRM_REPLIC_GROUP_SET:
114375 + {
114376 + ioc_fm_pcd_frm_replic_group_params_t *param;
114377 +
114378 + param = (ioc_fm_pcd_frm_replic_group_params_t *) XX_Malloc(
114379 + sizeof(ioc_fm_pcd_frm_replic_group_params_t));
114380 + if (!param)
114381 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
114382 +
114383 + memset(param, 0, sizeof(ioc_fm_pcd_frm_replic_group_params_t));
114384 +
114385 +#if defined(CONFIG_COMPAT)
114386 + if (compat)
114387 + {
114388 + ioc_compat_fm_pcd_frm_replic_group_params_t
114389 + *compat_param;
114390 +
114391 + compat_param =
114392 + (ioc_compat_fm_pcd_frm_replic_group_params_t *)
114393 + XX_Malloc(sizeof(ioc_compat_fm_pcd_frm_replic_group_params_t));
114394 + if (!compat_param)
114395 + {
114396 + XX_Free(param);
114397 + RETURN_ERROR(MINOR, E_NO_MEMORY,
114398 + ("IOCTL FM PCD"));
114399 + }
114400 +
114401 + memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_frm_replic_group_params_t));
114402 + if (copy_from_user(compat_param,
114403 + (ioc_compat_fm_pcd_frm_replic_group_params_t *)
114404 + compat_ptr(arg),
114405 + sizeof(ioc_compat_fm_pcd_frm_replic_group_params_t))) {
114406 + XX_Free(compat_param);
114407 + XX_Free(param);
114408 + RETURN_ERROR(MINOR, E_READ_FAILED, NO_MSG);
114409 + }
114410 +
114411 + compat_copy_fm_pcd_frm_replic_group_params(compat_param,
114412 + param, COMPAT_US_TO_K);
114413 +
114414 + XX_Free(compat_param);
114415 + }
114416 + else
114417 +#endif
114418 + {
114419 + if (copy_from_user(param,
114420 + (ioc_fm_pcd_frm_replic_group_params_t *)arg,
114421 + sizeof(ioc_fm_pcd_frm_replic_group_params_t)))
114422 + {
114423 + XX_Free(param);
114424 + RETURN_ERROR(MINOR, E_READ_FAILED, NO_MSG);
114425 + }
114426 + }
114427 +
114428 + param->id = FM_PCD_FrmReplicSetGroup(p_LnxWrpFmDev->h_PcdDev,
114429 + (t_FmPcdFrmReplicGroupParams*)param);
114430 +
114431 + if (!param->id) {
114432 + XX_Free(param);
114433 + err = E_INVALID_VALUE;
114434 + /*
114435 + * Since the LLD has no errno-style error reporting,
114436 + * we're left here with no other option than to report
114437 + * a generic E_INVALID_VALUE
114438 + */
114439 + break;
114440 + }
114441 +
114442 +#if defined(CONFIG_COMPAT)
114443 + if (compat)
114444 + {
114445 + ioc_compat_fm_pcd_frm_replic_group_params_t
114446 + *compat_param;
114447 +
114448 + compat_param =
114449 + (ioc_compat_fm_pcd_frm_replic_group_params_t *)
114450 + XX_Malloc(sizeof(ioc_compat_fm_pcd_frm_replic_group_params_t));
114451 + if (!compat_param)
114452 + {
114453 + XX_Free(param);
114454 + RETURN_ERROR(MINOR, E_NO_MEMORY,
114455 + ("IOCTL FM PCD"));
114456 + }
114457 +
114458 + memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_frm_replic_group_params_t));
114459 + compat_copy_fm_pcd_frm_replic_group_params(compat_param,
114460 + param, COMPAT_K_TO_US);
114461 + if (copy_to_user(
114462 + (ioc_compat_fm_pcd_frm_replic_group_params_t *)
114463 + compat_ptr(arg),
114464 + compat_param,
114465 + sizeof(ioc_compat_fm_pcd_frm_replic_group_params_t)))
114466 + err = E_WRITE_FAILED;
114467 +
114468 + XX_Free(compat_param);
114469 + }
114470 + else
114471 +#endif
114472 + {
114473 + if (copy_to_user(
114474 + (ioc_fm_pcd_frm_replic_group_params_t *)arg,
114475 + param,
114476 + sizeof(ioc_fm_pcd_frm_replic_group_params_t)))
114477 + err = E_WRITE_FAILED;
114478 + }
114479 +
114480 + XX_Free(param);
114481 + break;
114482 + }
114483 + break;
114484 +
114485 +#if defined(CONFIG_COMPAT)
114486 + case FM_PCD_IOC_FRM_REPLIC_GROUP_DELETE_COMPAT:
114487 +#endif
114488 + case FM_PCD_IOC_FRM_REPLIC_GROUP_DELETE:
114489 + {
114490 + ioc_fm_obj_t id;
114491 +
114492 + memset(&id, 0, sizeof(ioc_fm_obj_t));
114493 +#if defined(CONFIG_COMPAT)
114494 + if (compat)
114495 + {
114496 + ioc_compat_fm_obj_t compat_id;
114497 +
114498 + if (copy_from_user(&compat_id,
114499 + (ioc_compat_fm_obj_t *) compat_ptr(arg),
114500 + sizeof(ioc_compat_fm_obj_t)))
114501 + break;
114502 + compat_obj_delete(&compat_id, &id);
114503 + }
114504 + else
114505 +#endif
114506 + {
114507 + if (copy_from_user(&id, (ioc_fm_obj_t *) arg,
114508 + sizeof(ioc_fm_obj_t)))
114509 + break;
114510 + }
114511 +
114512 + return FM_PCD_FrmReplicDeleteGroup(id.obj);
114513 + }
114514 + break;
114515 +
114516 +#if defined(CONFIG_COMPAT)
114517 + case FM_PCD_IOC_FRM_REPLIC_MEMBER_ADD_COMPAT:
114518 +#endif
114519 + case FM_PCD_IOC_FRM_REPLIC_MEMBER_ADD:
114520 + {
114521 + ioc_fm_pcd_frm_replic_member_params_t param;
114522 +
114523 +#if defined(CONFIG_COMPAT)
114524 + if (compat)
114525 + {
114526 + ioc_compat_fm_pcd_frm_replic_member_params_t compat_param;
114527 +
114528 + if (copy_from_user(&compat_param, compat_ptr(arg), sizeof(compat_param)))
114529 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
114530 +
114531 + compat_copy_fm_pcd_frm_replic_member_params(&compat_param, &param, COMPAT_US_TO_K);
114532 + }
114533 + else
114534 +#endif
114535 + if (copy_from_user(&param, (void *)arg, sizeof(param)))
114536 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
114537 +
114538 + return FM_PCD_FrmReplicAddMember(param.member.h_replic_group,
114539 + param.member.member_index,
114540 + (t_FmPcdCcNextEngineParams*)&param.next_engine_params);
114541 + }
114542 + break;
114543 +
114544 +#if defined(CONFIG_COMPAT)
114545 + case FM_PCD_IOC_FRM_REPLIC_MEMBER_REMOVE_COMPAT:
114546 +#endif
114547 + case FM_PCD_IOC_FRM_REPLIC_MEMBER_REMOVE:
114548 + {
114549 + ioc_fm_pcd_frm_replic_member_t param;
114550 +
114551 +#if defined(CONFIG_COMPAT)
114552 + if (compat)
114553 + {
114554 + ioc_compat_fm_pcd_frm_replic_member_t compat_param;
114555 +
114556 + if (copy_from_user(&compat_param, compat_ptr(arg), sizeof(compat_param)))
114557 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
114558 +
114559 + compat_copy_fm_pcd_frm_replic_member(&compat_param, &param, COMPAT_US_TO_K);
114560 + }
114561 + else
114562 +#endif
114563 + if (copy_from_user(&param, (void *)arg, sizeof(param)))
114564 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
114565 +
114566 + return FM_PCD_FrmReplicRemoveMember(param.h_replic_group, param.member_index);
114567 + }
114568 + break;
114569 +
114570 +#if defined(CONFIG_COMPAT)
114571 + case FM_IOC_VSP_CONFIG_COMPAT:
114572 +#endif
114573 + case FM_IOC_VSP_CONFIG:
114574 + {
114575 + ioc_fm_vsp_params_t param;
114576 +
114577 +#if defined(CONFIG_COMPAT)
114578 + if (compat)
114579 + {
114580 + ioc_compat_fm_vsp_params_t compat_param;
114581 +
114582 + if (copy_from_user(&compat_param, compat_ptr(arg), sizeof(compat_param)))
114583 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
114584 +
114585 + compat_copy_fm_vsp_params(&compat_param, &param, COMPAT_US_TO_K);
114586 + }
114587 + else
114588 +#endif
114589 + if (copy_from_user(&param, (void *)arg, sizeof(param)))
114590 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
114591 + {
114592 + uint8_t portId = param.port_params.port_id;
114593 + param.liodn_offset =
114594 + p_LnxWrpFmDev->rxPorts[portId].settings.param.specificParams.rxParams.liodnOffset;
114595 + }
114596 + param.p_fm = p_LnxWrpFmDev->h_Dev;
114597 + param.id = FM_VSP_Config((t_FmVspParams *)&param);
114598 +
114599 +#if defined(CONFIG_COMPAT)
114600 + if (compat)
114601 + {
114602 + ioc_compat_fm_vsp_params_t compat_param;
114603 +
114604 + memset(&compat_param, 0, sizeof(compat_param));
114605 + compat_copy_fm_vsp_params(&compat_param, &param, COMPAT_K_TO_US);
114606 +
114607 + if (copy_to_user(compat_ptr(arg), &compat_param, sizeof(compat_param)))
114608 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
114609 + }
114610 + else
114611 +#endif
114612 + if (copy_to_user((void *)arg, &param, sizeof(param)))
114613 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
114614 + break;
114615 + }
114616 +
114617 +#if defined(CONFIG_COMPAT)
114618 + case FM_IOC_VSP_INIT_COMPAT:
114619 +#endif
114620 + case FM_IOC_VSP_INIT:
114621 + {
114622 + ioc_fm_obj_t id;
114623 +
114624 + memset(&id, 0, sizeof(ioc_fm_obj_t));
114625 +#if defined(CONFIG_COMPAT)
114626 + if (compat)
114627 + {
114628 + ioc_compat_fm_obj_t compat_id;
114629 +
114630 + if (copy_from_user(&compat_id,
114631 + (ioc_compat_fm_obj_t *) compat_ptr(arg),
114632 + sizeof(ioc_compat_fm_obj_t)))
114633 + break;
114634 + id.obj = compat_pcd_id2ptr(compat_id.obj);
114635 + }
114636 + else
114637 +#endif
114638 + {
114639 + if (copy_from_user(&id, (ioc_fm_obj_t *) arg,
114640 + sizeof(ioc_fm_obj_t)))
114641 + break;
114642 + }
114643 +
114644 + return FM_VSP_Init(id.obj);
114645 + }
114646 +
114647 +#if defined(CONFIG_COMPAT)
114648 + case FM_IOC_VSP_FREE_COMPAT:
114649 +#endif
114650 + case FM_IOC_VSP_FREE:
114651 + {
114652 + ioc_fm_obj_t id;
114653 +
114654 + memset(&id, 0, sizeof(ioc_fm_obj_t));
114655 +#if defined(CONFIG_COMPAT)
114656 + if (compat)
114657 + {
114658 + ioc_compat_fm_obj_t compat_id;
114659 +
114660 + if (copy_from_user(&compat_id,
114661 + (ioc_compat_fm_obj_t *) compat_ptr(arg),
114662 + sizeof(ioc_compat_fm_obj_t)))
114663 + break;
114664 + compat_obj_delete(&compat_id, &id);
114665 + }
114666 + else
114667 +#endif
114668 + {
114669 + if (copy_from_user(&id, (ioc_fm_obj_t *) arg,
114670 + sizeof(ioc_fm_obj_t)))
114671 + break;
114672 + }
114673 +
114674 + return FM_VSP_Free(id.obj);
114675 + }
114676 +
114677 +#if defined(CONFIG_COMPAT)
114678 + case FM_IOC_VSP_CONFIG_POOL_DEPLETION_COMPAT:
114679 +#endif
114680 + case FM_IOC_VSP_CONFIG_POOL_DEPLETION:
114681 + {
114682 + ioc_fm_buf_pool_depletion_params_t param;
114683 +
114684 +#if defined(CONFIG_COMPAT)
114685 + if (compat)
114686 + {
114687 + ioc_compat_fm_buf_pool_depletion_params_t compat_param;
114688 +
114689 + if (copy_from_user(&compat_param, compat_ptr(arg), sizeof(compat_param)))
114690 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
114691 +
114692 + compat_copy_fm_buf_pool_depletion_params(&compat_param, &param, COMPAT_US_TO_K);
114693 + }
114694 + else
114695 +#endif
114696 + if (copy_from_user(&param, (void *)arg, sizeof(param)))
114697 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
114698 +
114699 + if (FM_VSP_ConfigPoolDepletion(param.p_fm_vsp,
114700 + (t_FmBufPoolDepletion *)&param.fm_buf_pool_depletion))
114701 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
114702 +
114703 + break;
114704 + }
114705 +
114706 +
114707 +#if defined(CONFIG_COMPAT)
114708 + case FM_IOC_VSP_CONFIG_BUFFER_PREFIX_CONTENT_COMPAT:
114709 +#endif
114710 + case FM_IOC_VSP_CONFIG_BUFFER_PREFIX_CONTENT:
114711 + {
114712 + ioc_fm_buffer_prefix_content_params_t param;
114713 +
114714 +#if defined(CONFIG_COMPAT)
114715 + if (compat)
114716 + {
114717 + ioc_compat_fm_buffer_prefix_content_params_t compat_param;
114718 +
114719 + if (copy_from_user(&compat_param, compat_ptr(arg), sizeof(compat_param)))
114720 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
114721 +
114722 + compat_copy_fm_buffer_prefix_content_params(&compat_param, &param, COMPAT_US_TO_K);
114723 + }
114724 + else
114725 +#endif
114726 + if (copy_from_user(&param, (void *)arg, sizeof(param)))
114727 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
114728 +
114729 + if (FM_VSP_ConfigBufferPrefixContent(param.p_fm_vsp,
114730 + (t_FmBufferPrefixContent *)&param.fm_buffer_prefix_content))
114731 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
114732 +
114733 + break;
114734 + }
114735 +
114736 +#if defined(CONFIG_COMPAT)
114737 + case FM_IOC_VSP_CONFIG_NO_SG_COMPAT:
114738 +#endif
114739 + case FM_IOC_VSP_CONFIG_NO_SG:
114740 + {
114741 + ioc_fm_vsp_config_no_sg_params_t param;
114742 +
114743 +#if defined(CONFIG_COMPAT)
114744 + if (compat)
114745 + {
114746 + ioc_compat_fm_vsp_config_no_sg_params_t compat_param;
114747 +
114748 + if (copy_from_user(&compat_param, compat_ptr(arg), sizeof(compat_param)))
114749 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
114750 +
114751 + compat_copy_fm_vsp_config_no_sg_params(&compat_param, &param, COMPAT_US_TO_K);
114752 + }
114753 + else
114754 +#endif
114755 + if (copy_from_user(&param, (void *)arg, sizeof(param)))
114756 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
114757 +
114758 + if (FM_VSP_ConfigNoScatherGather(param.p_fm_vsp, param.no_sg))
114759 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
114760 +
114761 + break;
114762 + }
114763 +
114764 +#if defined(CONFIG_COMPAT)
114765 + case FM_IOC_VSP_GET_BUFFER_PRS_RESULT_COMPAT:
114766 +#endif
114767 + case FM_IOC_VSP_GET_BUFFER_PRS_RESULT:
114768 + {
114769 + ioc_fm_vsp_prs_result_params_t param;
114770 +
114771 +#if defined(CONFIG_COMPAT)
114772 + if (compat)
114773 + {
114774 + ioc_compat_fm_vsp_prs_result_params_t compat_param;
114775 +
114776 + if (copy_from_user(&compat_param, compat_ptr(arg), sizeof(compat_param)))
114777 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
114778 +
114779 + compat_copy_fm_vsp_prs_result_params(&compat_param, &param, COMPAT_US_TO_K);
114780 + }
114781 + else
114782 +#endif
114783 + if (copy_from_user(&param, (void *)arg, sizeof(param)))
114784 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
114785 +
114786 + /* this call just adds the parse results offset to p_data */
114787 + param.p_data = FM_VSP_GetBufferPrsResult(param.p_fm_vsp, param.p_data);
114788 +
114789 + if (!param.p_data)
114790 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
114791 +
114792 +#if defined(CONFIG_COMPAT)
114793 + if (compat)
114794 + {
114795 + ioc_compat_fm_vsp_prs_result_params_t compat_param;
114796 +
114797 + memset(&compat_param, 0, sizeof(compat_param));
114798 + compat_copy_fm_vsp_prs_result_params(&compat_param, &param, COMPAT_K_TO_US);
114799 +
114800 + if (copy_to_user(compat_ptr(arg), &compat_param, sizeof(compat_param)))
114801 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
114802 + }
114803 + else
114804 +#endif
114805 + if (copy_to_user((void *)arg, &param, sizeof(param)))
114806 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
114807 +
114808 + break;
114809 + }
114810 +#endif /* (DPAA_VERSION >= 11) */
114811 +
114812 +#ifdef FM_CAPWAP_SUPPORT
114813 +#warning "feature not supported!"
114814 +#if defined(CONFIG_COMPAT)
114815 + case FM_PCD_IOC_STATISTICS_SET_NODE_COMPAT:
114816 +#endif
114817 + case FM_PCD_IOC_STATISTICS_SET_NODE:
114818 + {
114819 +/* ioc_fm_pcd_stats_params_t param;
114820 + ...
114821 + param->id = FM_PCD_StatisticsSetNode(p_LnxWrpFmDev->h_PcdDev,
114822 + (t_FmPcdStatsParams *)&param);
114823 +*/
114824 + err = E_NOT_SUPPORTED;
114825 + break;
114826 + }
114827 +#endif /* FM_CAPWAP_SUPPORT */
114828 +
114829 + default:
114830 + RETURN_ERROR(MINOR, E_INVALID_SELECTION,
114831 + ("invalid ioctl: cmd:0x%08x(type:0x%02x, nr: %d.\n",
114832 + cmd, _IOC_TYPE(cmd), _IOC_NR(cmd)));
114833 + }
114834 +
114835 + if (err)
114836 + RETURN_ERROR(MINOR, err, ("IOCTL FM PCD"));
114837 +
114838 + return E_OK;
114839 +}
114840 +
114841 +void FM_Get_Api_Version(ioc_fm_api_version_t *p_version)
114842 +{
114843 + p_version->version.major = FMD_API_VERSION_MAJOR;
114844 + p_version->version.minor = FMD_API_VERSION_MINOR;
114845 + p_version->version.respin = FMD_API_VERSION_RESPIN;
114846 + p_version->version.reserved = 0;
114847 +}
114848 +
114849 +t_Error LnxwrpFmIOCTL(t_LnxWrpFmDev *p_LnxWrpFmDev, unsigned int cmd, unsigned long arg, bool compat)
114850 +{
114851 + t_Error err = E_OK;
114852 +
114853 + switch (cmd)
114854 + {
114855 + case FM_IOC_SET_PORTS_BANDWIDTH:
114856 + {
114857 + ioc_fm_port_bandwidth_params *param;
114858 +
114859 + param = (ioc_fm_port_bandwidth_params*) XX_Malloc(sizeof(ioc_fm_port_bandwidth_params));
114860 + if (!param)
114861 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
114862 +
114863 + memset(param, 0, sizeof(ioc_fm_port_bandwidth_params));
114864 +
114865 +#if defined(CONFIG_COMPAT)
114866 + if (compat)
114867 + {
114868 + if (copy_from_user(param, (ioc_fm_port_bandwidth_params*)compat_ptr(arg), sizeof(ioc_fm_port_bandwidth_params)))
114869 + {
114870 + XX_Free(param);
114871 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
114872 + }
114873 + }
114874 + else
114875 +#endif
114876 + {
114877 + if (copy_from_user(param, (ioc_fm_port_bandwidth_params*)arg, sizeof(ioc_fm_port_bandwidth_params)))
114878 + {
114879 + XX_Free(param);
114880 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
114881 + }
114882 + }
114883 +
114884 + err = FM_SetPortsBandwidth(p_LnxWrpFmDev->h_Dev, (t_FmPortsBandwidthParams*) param);
114885 +
114886 + XX_Free(param);
114887 + break;
114888 + }
114889 +
114890 + case FM_IOC_GET_REVISION:
114891 + {
114892 + ioc_fm_revision_info_t *param;
114893 +
114894 + param = (ioc_fm_revision_info_t *) XX_Malloc(sizeof(ioc_fm_revision_info_t));
114895 + if (!param)
114896 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
114897 +
114898 + FM_GetRevision(p_LnxWrpFmDev->h_Dev, (t_FmRevisionInfo*)param);
114899 + /* This one never returns anything other than E_OK */
114900 +
114901 +#if defined(CONFIG_COMPAT)
114902 + if (compat)
114903 + {
114904 + if (copy_to_user((ioc_fm_revision_info_t *)compat_ptr(arg),
114905 + param,
114906 + sizeof(ioc_fm_revision_info_t))){
114907 + XX_Free(param);
114908 + RETURN_ERROR(MINOR, E_READ_FAILED, NO_MSG);
114909 + }
114910 + }
114911 + else
114912 +#endif
114913 + {
114914 + if (copy_to_user((ioc_fm_revision_info_t *)arg,
114915 + param,
114916 + sizeof(ioc_fm_revision_info_t))){
114917 + XX_Free(param);
114918 + RETURN_ERROR(MINOR, E_READ_FAILED, NO_MSG);
114919 + }
114920 + }
114921 + XX_Free(param);
114922 + break;
114923 + }
114924 +
114925 + case FM_IOC_SET_COUNTER:
114926 + {
114927 + ioc_fm_counters_params_t *param;
114928 +
114929 + param = (ioc_fm_counters_params_t *) XX_Malloc(sizeof(ioc_fm_counters_params_t));
114930 + if (!param)
114931 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
114932 +
114933 + memset(param, 0, sizeof(ioc_fm_counters_params_t));
114934 +
114935 +#if defined(CONFIG_COMPAT)
114936 + if (compat)
114937 + {
114938 + if (copy_from_user(param, (ioc_fm_counters_params_t *)compat_ptr(arg), sizeof(ioc_fm_counters_params_t)))
114939 + {
114940 + XX_Free(param);
114941 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
114942 + }
114943 + }
114944 + else
114945 +#endif
114946 + {
114947 + if (copy_from_user(param, (ioc_fm_counters_params_t *)arg, sizeof(ioc_fm_counters_params_t)))
114948 + {
114949 + XX_Free(param);
114950 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
114951 + }
114952 + }
114953 +
114954 + err = FM_ModifyCounter(p_LnxWrpFmDev->h_Dev, param->cnt, param->val);
114955 +
114956 + XX_Free(param);
114957 + break;
114958 + }
114959 +
114960 + case FM_IOC_GET_COUNTER:
114961 + {
114962 + ioc_fm_counters_params_t *param;
114963 +
114964 + param = (ioc_fm_counters_params_t *) XX_Malloc(sizeof(ioc_fm_counters_params_t));
114965 + if (!param)
114966 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
114967 +
114968 + memset(param, 0, sizeof(ioc_fm_counters_params_t));
114969 +
114970 +#if defined(CONFIG_COMPAT)
114971 + if (compat)
114972 + {
114973 + if (copy_from_user(param, (ioc_fm_counters_params_t *)compat_ptr(arg), sizeof(ioc_fm_counters_params_t)))
114974 + {
114975 + XX_Free(param);
114976 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
114977 + }
114978 + }
114979 + else
114980 +#endif
114981 + {
114982 + if (copy_from_user(param, (ioc_fm_counters_params_t *)arg, sizeof(ioc_fm_counters_params_t)))
114983 + {
114984 + XX_Free(param);
114985 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
114986 + }
114987 + }
114988 +
114989 + param->val = FM_GetCounter(p_LnxWrpFmDev->h_Dev, param->cnt);
114990 +
114991 +#if defined(CONFIG_COMPAT)
114992 + if (compat)
114993 + {
114994 + if (copy_to_user((ioc_fm_counters_params_t *)compat_ptr(arg), param, sizeof(ioc_fm_counters_params_t)))
114995 + err = E_READ_FAILED;
114996 + }
114997 + else
114998 +#endif
114999 + {
115000 + if (copy_to_user((ioc_fm_counters_params_t *)arg, param, sizeof(ioc_fm_counters_params_t)))
115001 + err = E_READ_FAILED;
115002 + }
115003 +
115004 + XX_Free(param);
115005 + break;
115006 + }
115007 +
115008 + case FM_IOC_FORCE_INTR:
115009 + {
115010 + ioc_fm_exceptions param;
115011 +
115012 +#if defined(CONFIG_COMPAT)
115013 + if (compat)
115014 + {
115015 + if (get_user(param, (ioc_fm_exceptions*) compat_ptr(arg)))
115016 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
115017 + }
115018 + else
115019 +#endif
115020 + {
115021 + if (get_user(param, (ioc_fm_exceptions*)arg))
115022 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
115023 + }
115024 +
115025 + err = FM_ForceIntr(p_LnxWrpFmDev->h_Dev, (e_FmExceptions)param);
115026 + break;
115027 + }
115028 +
115029 + case FM_IOC_GET_API_VERSION:
115030 + {
115031 + ioc_fm_api_version_t version;
115032 +
115033 + FM_Get_Api_Version(&version);
115034 +
115035 +#if defined(CONFIG_COMPAT)
115036 + if (compat)
115037 + {
115038 + if (copy_to_user(
115039 + (ioc_fm_api_version_t *)compat_ptr(arg),
115040 + &version, sizeof(version)))
115041 + err = E_READ_FAILED;
115042 + }
115043 + else
115044 +#endif
115045 + {
115046 + if (copy_to_user((ioc_fm_api_version_t *)arg,
115047 + &version, sizeof(version)))
115048 + err = E_READ_FAILED;
115049 + }
115050 + }
115051 + break;
115052 +
115053 + case FM_IOC_CTRL_MON_START:
115054 + {
115055 + FM_CtrlMonStart(p_LnxWrpFmDev->h_Dev);
115056 + }
115057 + break;
115058 +
115059 + case FM_IOC_CTRL_MON_STOP:
115060 + {
115061 + FM_CtrlMonStop(p_LnxWrpFmDev->h_Dev);
115062 + }
115063 + break;
115064 +
115065 +#if defined(CONFIG_COMPAT)
115066 + case FM_IOC_CTRL_MON_GET_COUNTERS_COMPAT:
115067 +#endif
115068 + case FM_IOC_CTRL_MON_GET_COUNTERS:
115069 + {
115070 + ioc_fm_ctrl_mon_counters_params_t param;
115071 + t_FmCtrlMon mon;
115072 +
115073 +#if defined(CONFIG_COMPAT)
115074 + ioc_compat_fm_ctrl_mon_counters_params_t compat_param;
115075 +
115076 + if (compat)
115077 + {
115078 + if (copy_from_user(&compat_param, (void *)compat_ptr(arg),
115079 + sizeof(compat_param)))
115080 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
115081 +
115082 + param.fm_ctrl_index = compat_param.fm_ctrl_index;
115083 + param.p_mon = (fm_ctrl_mon_t *)compat_ptr(compat_param.p_mon);
115084 + }
115085 + else
115086 +#endif
115087 + {
115088 + if (copy_from_user(&param, (void *)arg, sizeof(ioc_fm_ctrl_mon_counters_params_t)))
115089 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
115090 + }
115091 +
115092 + if (FM_CtrlMonGetCounters(p_LnxWrpFmDev->h_Dev, param.fm_ctrl_index, &mon))
115093 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
115094 +
115095 + if (copy_to_user(param.p_mon, &mon, sizeof(t_FmCtrlMon)))
115096 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
115097 + }
115098 + break;
115099 +
115100 + default:
115101 + return LnxwrpFmPcdIOCTL(p_LnxWrpFmDev, cmd, arg, compat);
115102 + }
115103 +
115104 + if (err)
115105 + RETURN_ERROR(MINOR, E_INVALID_OPERATION, ("IOCTL FM"));
115106 +
115107 + return E_OK;
115108 +}
115109 +
115110 +t_Error LnxwrpFmPortIOCTL(t_LnxWrpFmPortDev *p_LnxWrpFmPortDev, unsigned int cmd, unsigned long arg, bool compat)
115111 +{
115112 + t_Error err = E_OK;
115113 +
115114 + _fm_ioctl_dbg("cmd:0x%08x(type:0x%02x, nr:%u).\n",
115115 + cmd, _IOC_TYPE(cmd), _IOC_NR(cmd) - 70);
115116 +
115117 + switch (cmd)
115118 + {
115119 + case FM_PORT_IOC_DISABLE:
115120 + FM_PORT_Disable(p_LnxWrpFmPortDev->h_Dev);
115121 + /* deliberately ignoring error codes here */
115122 + return E_OK;
115123 +
115124 + case FM_PORT_IOC_ENABLE:
115125 + FM_PORT_Enable(p_LnxWrpFmPortDev->h_Dev);
115126 + /* deliberately ignoring error codes here */
115127 + return E_OK;
115128 +
115129 + case FM_PORT_IOC_SET_ERRORS_ROUTE:
115130 + {
115131 + ioc_fm_port_frame_err_select_t errs;
115132 +
115133 +#if defined(CONFIG_COMPAT)
115134 + if (compat)
115135 + {
115136 + if (get_user(errs, (ioc_fm_port_frame_err_select_t*)compat_ptr(arg)))
115137 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
115138 + }
115139 + else
115140 +#endif
115141 + {
115142 + if (get_user(errs, (ioc_fm_port_frame_err_select_t*)arg))
115143 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
115144 + }
115145 +
115146 + err = FM_PORT_SetErrorsRoute(p_LnxWrpFmPortDev->h_Dev, (fmPortFrameErrSelect_t)errs);
115147 + break;
115148 + }
115149 +
115150 + case FM_PORT_IOC_SET_RATE_LIMIT:
115151 + {
115152 + ioc_fm_port_rate_limit_t *param;
115153 +
115154 + param = (ioc_fm_port_rate_limit_t *) XX_Malloc(sizeof(ioc_fm_port_rate_limit_t));
115155 + if (!param)
115156 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PORT"));
115157 +
115158 + memset(param, 0, sizeof(ioc_fm_port_rate_limit_t));
115159 +
115160 +#if defined(CONFIG_COMPAT)
115161 + if (compat)
115162 + {
115163 + if (copy_from_user(param, (ioc_fm_port_rate_limit_t *)compat_ptr(arg), sizeof(ioc_fm_port_rate_limit_t)))
115164 + {
115165 + XX_Free(param);
115166 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
115167 + }
115168 + }
115169 + else
115170 +#endif
115171 + {
115172 + if (copy_from_user(param, (ioc_fm_port_rate_limit_t *)arg, sizeof(ioc_fm_port_rate_limit_t)))
115173 + {
115174 + XX_Free(param);
115175 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
115176 + }
115177 + }
115178 +
115179 + err = FM_PORT_SetRateLimit(p_LnxWrpFmPortDev->h_Dev, (t_FmPortRateLimit *)param);
115180 +
115181 + XX_Free(param);
115182 + break;
115183 + }
115184 +
115185 + case FM_PORT_IOC_REMOVE_RATE_LIMIT:
115186 + FM_PORT_DeleteRateLimit(p_LnxWrpFmPortDev->h_Dev);
115187 + /* deliberately ignoring error codes here */
115188 + return E_OK;
115189 +
115190 + case FM_PORT_IOC_ALLOC_PCD_FQIDS:
115191 + {
115192 + ioc_fm_port_pcd_fqids_params_t *param;
115193 +
115194 + if (!p_LnxWrpFmPortDev->pcd_owner_params.cba)
115195 + RETURN_ERROR(MINOR, E_INVALID_STATE, ("No one to listen on this PCD!!!"));
115196 +
115197 + param = (ioc_fm_port_pcd_fqids_params_t *) XX_Malloc(sizeof(ioc_fm_port_pcd_fqids_params_t));
115198 + if (!param)
115199 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PORT"));
115200 +
115201 + memset(param, 0, sizeof(ioc_fm_port_pcd_fqids_params_t));
115202 +
115203 +#if defined(CONFIG_COMPAT)
115204 + if (compat)
115205 + {
115206 + if (copy_from_user(param, (ioc_fm_port_pcd_fqids_params_t *)compat_ptr(arg),
115207 + sizeof(ioc_fm_port_pcd_fqids_params_t)))
115208 + {
115209 + XX_Free(param);
115210 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
115211 + }
115212 + }
115213 + else
115214 +#endif
115215 + {
115216 + if (copy_from_user(param, (ioc_fm_port_pcd_fqids_params_t *)arg,
115217 + sizeof(ioc_fm_port_pcd_fqids_params_t)))
115218 + {
115219 + XX_Free(param);
115220 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
115221 + }
115222 + }
115223 +
115224 + if (p_LnxWrpFmPortDev->pcd_owner_params.cba(p_LnxWrpFmPortDev->pcd_owner_params.dev,
115225 + param->num_fqids,
115226 + param->alignment,
115227 + &param->base_fqid))
115228 + {
115229 + XX_Free(param);
115230 + RETURN_ERROR(MINOR, E_INVALID_STATE, ("can't allocate fqids for PCD!!!"));
115231 + }
115232 +
115233 +#if defined(CONFIG_COMPAT)
115234 + if (compat)
115235 + {
115236 + if (copy_to_user((ioc_fm_port_pcd_fqids_params_t *)compat_ptr(arg),
115237 + param, sizeof(ioc_fm_port_pcd_fqids_params_t)))
115238 + err = E_READ_FAILED;
115239 + }
115240 + else
115241 +#endif
115242 + {
115243 + if (copy_to_user((ioc_fm_port_pcd_fqids_params_t *)arg,
115244 + param, sizeof(ioc_fm_port_pcd_fqids_params_t)))
115245 + err = E_READ_FAILED;
115246 + }
115247 +
115248 + XX_Free(param);
115249 + break;
115250 + }
115251 +
115252 + case FM_PORT_IOC_FREE_PCD_FQIDS:
115253 + {
115254 + uint32_t base_fqid;
115255 +
115256 + if (!p_LnxWrpFmPortDev->pcd_owner_params.cbf)
115257 + RETURN_ERROR(MINOR, E_INVALID_STATE, ("No one to listen on this PCD!!!"));
115258 +
115259 +#if defined(CONFIG_COMPAT)
115260 + if (compat)
115261 + {
115262 + if (get_user(base_fqid, (uint32_t*) compat_ptr(arg)))
115263 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
115264 + }
115265 + else
115266 +#endif
115267 + {
115268 + if (get_user(base_fqid, (uint32_t*)arg))
115269 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
115270 + }
115271 +
115272 + if (p_LnxWrpFmPortDev->pcd_owner_params.cbf(p_LnxWrpFmPortDev->pcd_owner_params.dev, base_fqid))
115273 + err = E_WRITE_FAILED;
115274 +
115275 + break;
115276 + }
115277 +
115278 +#if defined(CONFIG_COMPAT)
115279 + case FM_PORT_IOC_SET_PCD_COMPAT:
115280 +#endif
115281 + case FM_PORT_IOC_SET_PCD:
115282 + {
115283 + ioc_fm_port_pcd_params_t *port_pcd_params;
115284 + ioc_fm_port_pcd_prs_params_t *port_pcd_prs_params;
115285 + ioc_fm_port_pcd_cc_params_t *port_pcd_cc_params;
115286 + ioc_fm_port_pcd_kg_params_t *port_pcd_kg_params;
115287 + ioc_fm_port_pcd_plcr_params_t *port_pcd_plcr_params;
115288 +
115289 + port_pcd_params = (ioc_fm_port_pcd_params_t *) XX_Malloc(
115290 + sizeof(ioc_fm_port_pcd_params_t) +
115291 + sizeof(ioc_fm_port_pcd_prs_params_t) +
115292 + sizeof(ioc_fm_port_pcd_cc_params_t) +
115293 + sizeof(ioc_fm_port_pcd_kg_params_t) +
115294 + sizeof(ioc_fm_port_pcd_plcr_params_t));
115295 + if (!port_pcd_params)
115296 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PORT"));
115297 +
115298 + memset(port_pcd_params, 0,
115299 + sizeof(ioc_fm_port_pcd_params_t) +
115300 + sizeof(ioc_fm_port_pcd_prs_params_t) +
115301 + sizeof(ioc_fm_port_pcd_cc_params_t) +
115302 + sizeof(ioc_fm_port_pcd_kg_params_t) +
115303 + sizeof(ioc_fm_port_pcd_plcr_params_t));
115304 +
115305 + port_pcd_prs_params = (ioc_fm_port_pcd_prs_params_t *) (port_pcd_params + 1);
115306 + port_pcd_cc_params = (ioc_fm_port_pcd_cc_params_t *) (port_pcd_prs_params + 1);
115307 + port_pcd_kg_params = (ioc_fm_port_pcd_kg_params_t *) (port_pcd_cc_params + 1);
115308 + port_pcd_plcr_params = (ioc_fm_port_pcd_plcr_params_t *) (port_pcd_kg_params + 1);
115309 +
115310 +#if defined(CONFIG_COMPAT)
115311 + if (compat)
115312 + {
115313 + ioc_compat_fm_port_pcd_params_t *compat_port_pcd_params;
115314 + ioc_fm_port_pcd_prs_params_t *same_port_pcd_prs_params;
115315 + ioc_compat_fm_port_pcd_cc_params_t *compat_port_pcd_cc_params;
115316 + ioc_compat_fm_port_pcd_kg_params_t *compat_port_pcd_kg_params;
115317 + ioc_compat_fm_port_pcd_plcr_params_t *compat_port_pcd_plcr_params;
115318 +
115319 + compat_port_pcd_params = (ioc_compat_fm_port_pcd_params_t *) XX_Malloc(
115320 + sizeof(ioc_compat_fm_port_pcd_params_t) +
115321 + sizeof(ioc_fm_port_pcd_prs_params_t) +
115322 + sizeof(ioc_compat_fm_port_pcd_cc_params_t) +
115323 + sizeof(ioc_compat_fm_port_pcd_kg_params_t) +
115324 + sizeof(ioc_compat_fm_port_pcd_plcr_params_t));
115325 + if (!compat_port_pcd_params)
115326 + {
115327 + XX_Free(port_pcd_params);
115328 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PORT"));
115329 + }
115330 +
115331 + memset(compat_port_pcd_params, 0,
115332 + sizeof(ioc_compat_fm_port_pcd_params_t) +
115333 + sizeof(ioc_fm_port_pcd_prs_params_t) +
115334 + sizeof(ioc_compat_fm_port_pcd_cc_params_t) +
115335 + sizeof(ioc_compat_fm_port_pcd_kg_params_t) +
115336 + sizeof(ioc_compat_fm_port_pcd_plcr_params_t));
115337 + same_port_pcd_prs_params = (ioc_fm_port_pcd_prs_params_t *) (compat_port_pcd_params + 1);
115338 + compat_port_pcd_cc_params = (ioc_compat_fm_port_pcd_cc_params_t *) (same_port_pcd_prs_params + 1);
115339 + compat_port_pcd_kg_params = (ioc_compat_fm_port_pcd_kg_params_t *) (compat_port_pcd_cc_params + 1);
115340 + compat_port_pcd_plcr_params = (ioc_compat_fm_port_pcd_plcr_params_t *) (compat_port_pcd_kg_params + 1);
115341 +
115342 + if (copy_from_user(compat_port_pcd_params,
115343 + (ioc_compat_fm_port_pcd_params_t*) compat_ptr(arg),
115344 + sizeof(ioc_compat_fm_port_pcd_params_t)))
115345 + err = E_WRITE_FAILED;
115346 +
115347 + while (!err) /* pseudo-while */
115348 + {
115349 + /* set pointers from where to copy from: */
115350 + port_pcd_params->p_prs_params = compat_ptr(compat_port_pcd_params->p_prs_params); /* same structure */
115351 + port_pcd_params->p_cc_params = compat_ptr(compat_port_pcd_params->p_cc_params);
115352 + port_pcd_params->p_kg_params = compat_ptr(compat_port_pcd_params->p_kg_params);
115353 + port_pcd_params->p_plcr_params = compat_ptr(compat_port_pcd_params->p_plcr_params);
115354 + port_pcd_params->p_ip_reassembly_manip = compat_ptr(compat_port_pcd_params->p_ip_reassembly_manip);
115355 +#if (DPAA_VERSION >= 11)
115356 + port_pcd_params->p_capwap_reassembly_manip = compat_ptr(compat_port_pcd_params->p_capwap_reassembly_manip);
115357 +#endif
115358 + /* the prs member is the same, no compat structure...memcpy only */
115359 + if (port_pcd_params->p_prs_params)
115360 + {
115361 + if (copy_from_user(same_port_pcd_prs_params,
115362 + port_pcd_params->p_prs_params,
115363 + sizeof(ioc_fm_port_pcd_prs_params_t)))
115364 + {
115365 + err = E_WRITE_FAILED;
115366 + break; /* from pseudo-while */
115367 + }
115368 +
115369 + memcpy(port_pcd_prs_params, same_port_pcd_prs_params, sizeof(ioc_fm_port_pcd_prs_params_t));
115370 + port_pcd_params->p_prs_params = port_pcd_prs_params;
115371 + }
115372 +
115373 + if (port_pcd_params->p_cc_params)
115374 + {
115375 + if (copy_from_user(compat_port_pcd_cc_params,
115376 + port_pcd_params->p_cc_params,
115377 + sizeof(ioc_compat_fm_port_pcd_cc_params_t)))
115378 + {
115379 + err = E_WRITE_FAILED;
115380 + break; /* from pseudo-while */
115381 + }
115382 +
115383 + port_pcd_params->p_cc_params = port_pcd_cc_params;
115384 + }
115385 +
115386 + if (port_pcd_params->p_kg_params)
115387 + {
115388 + if (copy_from_user(compat_port_pcd_kg_params,
115389 + port_pcd_params->p_kg_params,
115390 + sizeof(ioc_compat_fm_port_pcd_kg_params_t)))
115391 + {
115392 + err = E_WRITE_FAILED;
115393 + break; /* from pseudo-while */
115394 + }
115395 +
115396 + port_pcd_params->p_kg_params = port_pcd_kg_params;
115397 + }
115398 +
115399 + if (port_pcd_params->p_plcr_params)
115400 + {
115401 + if (copy_from_user(compat_port_pcd_plcr_params,
115402 + port_pcd_params->p_plcr_params,
115403 + sizeof(ioc_compat_fm_port_pcd_plcr_params_t)))
115404 + {
115405 + err = E_WRITE_FAILED;
115406 + break; /* from pseudo-while */
115407 + }
115408 +
115409 + port_pcd_params->p_plcr_params = port_pcd_plcr_params;
115410 + }
115411 +
115412 + break; /* pseudo-while: always run once! */
115413 + }
115414 +
115415 + if (!err)
115416 + compat_copy_fm_port_pcd(compat_port_pcd_params, port_pcd_params, COMPAT_US_TO_K);
115417 +
115418 + XX_Free(compat_port_pcd_params);
115419 + }
115420 + else
115421 +#endif
115422 + {
115423 + if (copy_from_user(port_pcd_params,
115424 + (ioc_fm_port_pcd_params_t*) arg,
115425 + sizeof(ioc_fm_port_pcd_params_t)))
115426 + err = E_WRITE_FAILED;
115427 +
115428 + while (!err) /* pseudo-while */
115429 + {
115430 + if (port_pcd_params->p_prs_params)
115431 + {
115432 + if (copy_from_user(port_pcd_prs_params,
115433 + port_pcd_params->p_prs_params,
115434 + sizeof(ioc_fm_port_pcd_prs_params_t)))
115435 + {
115436 + err = E_WRITE_FAILED;
115437 + break; /* from pseudo-while */
115438 + }
115439 +
115440 + port_pcd_params->p_prs_params = port_pcd_prs_params;
115441 + }
115442 +
115443 + if (port_pcd_params->p_cc_params)
115444 + {
115445 + if (copy_from_user(port_pcd_cc_params,
115446 + port_pcd_params->p_cc_params,
115447 + sizeof(ioc_fm_port_pcd_cc_params_t)))
115448 + {
115449 + err = E_WRITE_FAILED;
115450 + break; /* from pseudo-while */
115451 + }
115452 +
115453 + port_pcd_params->p_cc_params = port_pcd_cc_params;
115454 + }
115455 +
115456 + if (port_pcd_params->p_kg_params)
115457 + {
115458 + if (copy_from_user(port_pcd_kg_params,
115459 + port_pcd_params->p_kg_params,
115460 + sizeof(ioc_fm_port_pcd_kg_params_t)))
115461 + {
115462 + err = E_WRITE_FAILED;
115463 + break; /* from pseudo-while */
115464 + }
115465 +
115466 + port_pcd_params->p_kg_params = port_pcd_kg_params;
115467 + }
115468 +
115469 + if (port_pcd_params->p_plcr_params)
115470 + {
115471 + if (copy_from_user(port_pcd_plcr_params,
115472 + port_pcd_params->p_plcr_params,
115473 + sizeof(ioc_fm_port_pcd_plcr_params_t)))
115474 + {
115475 + err = E_WRITE_FAILED;
115476 + break; /* from pseudo-while */
115477 + }
115478 +
115479 + port_pcd_params->p_plcr_params = port_pcd_plcr_params;
115480 + }
115481 +
115482 + break; /* pseudo-while: always run once! */
115483 + }
115484 + }
115485 +
115486 + if (!err)
115487 + err = FM_PORT_SetPCD(p_LnxWrpFmPortDev->h_Dev, (t_FmPortPcdParams*) port_pcd_params);
115488 +
115489 + XX_Free(port_pcd_params);
115490 + break;
115491 + }
115492 +
115493 + case FM_PORT_IOC_DELETE_PCD:
115494 + err = FM_PORT_DeletePCD(p_LnxWrpFmPortDev->h_Dev);
115495 + break;
115496 +
115497 +#if defined(CONFIG_COMPAT)
115498 + case FM_PORT_IOC_PCD_KG_MODIFY_INITIAL_SCHEME_COMPAT:
115499 +#endif
115500 + case FM_PORT_IOC_PCD_KG_MODIFY_INITIAL_SCHEME:
115501 + {
115502 + ioc_fm_pcd_kg_scheme_select_t *param;
115503 +
115504 + param = (ioc_fm_pcd_kg_scheme_select_t *) XX_Malloc(
115505 + sizeof(ioc_fm_pcd_kg_scheme_select_t));
115506 + if (!param)
115507 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PORT"));
115508 +
115509 + memset(param, 0, sizeof(ioc_fm_pcd_kg_scheme_select_t));
115510 +
115511 +#if defined(CONFIG_COMPAT)
115512 + if (compat)
115513 + {
115514 + ioc_compat_fm_pcd_kg_scheme_select_t *compat_param;
115515 +
115516 + compat_param = (ioc_compat_fm_pcd_kg_scheme_select_t *) XX_Malloc(
115517 + sizeof(ioc_compat_fm_pcd_kg_scheme_select_t));
115518 + if (!compat_param)
115519 + {
115520 + XX_Free(param);
115521 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PORT"));
115522 + }
115523 +
115524 + memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_kg_scheme_select_t));
115525 + if (copy_from_user(compat_param,
115526 + (ioc_compat_fm_pcd_kg_scheme_select_t *) compat_ptr(arg),
115527 + sizeof(ioc_compat_fm_pcd_kg_scheme_select_t)))
115528 + {
115529 + XX_Free(compat_param);
115530 + XX_Free(param);
115531 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
115532 + }
115533 +
115534 + compat_copy_fm_pcd_kg_scheme_select(compat_param, param, COMPAT_US_TO_K);
115535 +
115536 + XX_Free(compat_param);
115537 + }
115538 + else
115539 +#endif
115540 + {
115541 + if (copy_from_user(param, (ioc_fm_pcd_kg_scheme_select_t *)arg,
115542 + sizeof(ioc_fm_pcd_kg_scheme_select_t)))
115543 + {
115544 + XX_Free(param);
115545 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
115546 + }
115547 + }
115548 +
115549 + err = FM_PORT_PcdKgModifyInitialScheme(p_LnxWrpFmPortDev->h_Dev, (t_FmPcdKgSchemeSelect *)param);
115550 +
115551 + XX_Free(param);
115552 + break;
115553 + }
115554 +
115555 +#if defined(CONFIG_COMPAT)
115556 + case FM_PORT_IOC_PCD_PLCR_MODIFY_INITIAL_PROFILE_COMPAT:
115557 +#endif
115558 + case FM_PORT_IOC_PCD_PLCR_MODIFY_INITIAL_PROFILE:
115559 + {
115560 + ioc_fm_obj_t id;
115561 +
115562 + memset(&id, 0 , sizeof(ioc_fm_obj_t));
115563 +
115564 +#if defined(CONFIG_COMPAT)
115565 + if (compat)
115566 + {
115567 + ioc_compat_fm_obj_t compat_id;
115568 +
115569 + if (copy_from_user(&compat_id, (ioc_compat_fm_obj_t *) compat_ptr(arg), sizeof(ioc_compat_fm_obj_t)))
115570 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
115571 +
115572 + id.obj = compat_ptr(compat_id.obj);
115573 + }
115574 + else
115575 +#endif
115576 + {
115577 + if (copy_from_user(&id, (ioc_fm_obj_t *) arg, sizeof(ioc_fm_obj_t)))
115578 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
115579 + }
115580 +
115581 + err = FM_PORT_PcdPlcrModifyInitialProfile(p_LnxWrpFmPortDev->h_Dev, id.obj);
115582 + break;
115583 + }
115584 +
115585 +#if defined(CONFIG_COMPAT)
115586 + case FM_PORT_IOC_PCD_KG_BIND_SCHEMES_COMPAT:
115587 +#endif
115588 + case FM_PORT_IOC_PCD_KG_BIND_SCHEMES:
115589 + {
115590 + ioc_fm_pcd_port_schemes_params_t *param;
115591 +
115592 + param = (ioc_fm_pcd_port_schemes_params_t *) XX_Malloc(
115593 + sizeof(ioc_fm_pcd_port_schemes_params_t));
115594 + if (!param)
115595 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PORT"));
115596 +
115597 + memset(param, 0 , sizeof(ioc_fm_pcd_port_schemes_params_t));
115598 +
115599 +#if defined(CONFIG_COMPAT)
115600 + if (compat)
115601 + {
115602 + ioc_compat_fm_pcd_port_schemes_params_t compat_param;
115603 +
115604 + if (copy_from_user(&compat_param,
115605 + (ioc_compat_fm_pcd_port_schemes_params_t *) compat_ptr(arg),
115606 + sizeof(ioc_compat_fm_pcd_port_schemes_params_t)))
115607 + {
115608 + XX_Free(param);
115609 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
115610 + }
115611 +
115612 + compat_copy_fm_pcd_kg_schemes_params(&compat_param, param, COMPAT_US_TO_K);
115613 + }
115614 + else
115615 +#endif
115616 + {
115617 + if (copy_from_user(param, (ioc_fm_pcd_port_schemes_params_t *) arg,
115618 + sizeof(ioc_fm_pcd_port_schemes_params_t)))
115619 + {
115620 + XX_Free(param);
115621 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
115622 + }
115623 + }
115624 +
115625 + err = FM_PORT_PcdKgBindSchemes(p_LnxWrpFmPortDev->h_Dev, (t_FmPcdPortSchemesParams *)param);
115626 +
115627 + XX_Free(param);
115628 + break;
115629 + }
115630 +
115631 +#if defined(CONFIG_COMPAT)
115632 + case FM_PORT_IOC_PCD_KG_UNBIND_SCHEMES_COMPAT:
115633 +#endif
115634 + case FM_PORT_IOC_PCD_KG_UNBIND_SCHEMES:
115635 + {
115636 + ioc_fm_pcd_port_schemes_params_t *param;
115637 +
115638 + param = (ioc_fm_pcd_port_schemes_params_t *) XX_Malloc(
115639 + sizeof(ioc_fm_pcd_port_schemes_params_t));
115640 + if (!param)
115641 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PORT"));
115642 +
115643 + memset(param, 0 , sizeof(ioc_fm_pcd_port_schemes_params_t));
115644 +
115645 +#if defined(CONFIG_COMPAT)
115646 + if (compat)
115647 + {
115648 + ioc_compat_fm_pcd_port_schemes_params_t compat_param;
115649 +
115650 + if (copy_from_user(&compat_param,
115651 + (ioc_compat_fm_pcd_port_schemes_params_t *) compat_ptr(arg),
115652 + sizeof(ioc_compat_fm_pcd_port_schemes_params_t)))
115653 + {
115654 + XX_Free(param);
115655 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
115656 + }
115657 +
115658 + compat_copy_fm_pcd_kg_schemes_params(&compat_param, param, COMPAT_US_TO_K);
115659 + }
115660 + else
115661 +#endif
115662 + {
115663 + if (copy_from_user(param, (ioc_fm_pcd_port_schemes_params_t *) arg,
115664 + sizeof(ioc_fm_pcd_port_schemes_params_t)))
115665 + {
115666 + XX_Free(param);
115667 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
115668 + }
115669 + }
115670 +
115671 + err = FM_PORT_PcdKgUnbindSchemes(p_LnxWrpFmPortDev->h_Dev, (t_FmPcdPortSchemesParams *)param);
115672 +
115673 + XX_Free(param);
115674 + break;
115675 + }
115676 +
115677 + case FM_PORT_IOC_PCD_PLCR_ALLOC_PROFILES:
115678 + {
115679 + uint16_t num;
115680 + if (get_user(num, (uint16_t*) arg))
115681 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
115682 +
115683 + err = FM_PORT_PcdPlcrAllocProfiles(p_LnxWrpFmPortDev->h_Dev, num);
115684 + break;
115685 + }
115686 +
115687 + case FM_PORT_IOC_PCD_PLCR_FREE_PROFILES:
115688 + err = FM_PORT_PcdPlcrFreeProfiles(p_LnxWrpFmPortDev->h_Dev);
115689 + break;
115690 +
115691 + case FM_PORT_IOC_DETACH_PCD:
115692 + err = FM_PORT_DetachPCD(p_LnxWrpFmPortDev->h_Dev);
115693 + break;
115694 +
115695 + case FM_PORT_IOC_ATTACH_PCD:
115696 + err = FM_PORT_AttachPCD(p_LnxWrpFmPortDev->h_Dev);
115697 + break;
115698 +
115699 +#if defined(CONFIG_COMPAT)
115700 + case FM_PORT_IOC_PCD_CC_MODIFY_TREE_COMPAT:
115701 +#endif
115702 + case FM_PORT_IOC_PCD_CC_MODIFY_TREE:
115703 + {
115704 + ioc_fm_obj_t id;
115705 +
115706 + memset(&id, 0 , sizeof(ioc_fm_obj_t));
115707 +
115708 +#if defined(CONFIG_COMPAT)
115709 + if (compat)
115710 + {
115711 + ioc_compat_fm_obj_t compat_id;
115712 +
115713 + if (copy_from_user(&compat_id, (ioc_compat_fm_obj_t *) compat_ptr(arg), sizeof(ioc_compat_fm_obj_t)))
115714 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
115715 +
115716 + compat_copy_fm_port_pcd_modify_tree(&compat_id, &id, COMPAT_US_TO_K);
115717 + }
115718 + else
115719 +#endif
115720 + {
115721 + if (copy_from_user(&id, (ioc_fm_obj_t *) arg, sizeof(ioc_fm_obj_t)))
115722 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
115723 + }
115724 +
115725 + err = FM_PORT_PcdCcModifyTree(p_LnxWrpFmPortDev->h_Dev, id.obj);
115726 + break;
115727 + }
115728 +
115729 + case FM_PORT_IOC_ADD_CONGESTION_GRPS:
115730 + case FM_PORT_IOC_REMOVE_CONGESTION_GRPS:
115731 + {
115732 + ioc_fm_port_congestion_groups_t *param;
115733 +
115734 + param = (ioc_fm_port_congestion_groups_t*) XX_Malloc(sizeof(ioc_fm_port_congestion_groups_t));
115735 + if (!param)
115736 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PORT"));
115737 +
115738 + memset(param, 0, sizeof(ioc_fm_port_congestion_groups_t));
115739 +
115740 +#if defined(CONFIG_COMPAT)
115741 + if (compat)
115742 + {
115743 + if (copy_from_user(param, (t_FmPortCongestionGrps*) compat_ptr(arg),
115744 + sizeof(t_FmPortCongestionGrps)))
115745 + {
115746 + XX_Free(param);
115747 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
115748 + }
115749 + }
115750 + else
115751 +#endif /* CONFIG_COMPAT */
115752 + {
115753 + if (copy_from_user(param, (t_FmPortCongestionGrps*) arg,
115754 + sizeof(t_FmPortCongestionGrps)))
115755 + {
115756 + XX_Free(param);
115757 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
115758 + }
115759 + }
115760 +
115761 + err = (cmd == FM_PORT_IOC_ADD_CONGESTION_GRPS)
115762 + ? FM_PORT_AddCongestionGrps(p_LnxWrpFmPortDev->h_Dev, (t_FmPortCongestionGrps*) param)
115763 + : FM_PORT_RemoveCongestionGrps(p_LnxWrpFmPortDev->h_Dev, (t_FmPortCongestionGrps*) param)
115764 + ;
115765 +
115766 + XX_Free(param);
115767 + break;
115768 + }
115769 +
115770 + case FM_PORT_IOC_ADD_RX_HASH_MAC_ADDR:
115771 + case FM_PORT_IOC_REMOVE_RX_HASH_MAC_ADDR:
115772 + {
115773 + ioc_fm_port_mac_addr_params_t *param;
115774 +
115775 + param = (ioc_fm_port_mac_addr_params_t*) XX_Malloc(
115776 + sizeof(ioc_fm_port_mac_addr_params_t));
115777 + if (!param)
115778 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PORT"));
115779 +
115780 + memset(param, 0, sizeof(ioc_fm_port_mac_addr_params_t));
115781 +
115782 +#if defined(CONFIG_COMPAT)
115783 + if (compat)
115784 + {
115785 + if (copy_from_user(param, (ioc_fm_port_mac_addr_params_t*) compat_ptr(arg),
115786 + sizeof(ioc_fm_port_mac_addr_params_t)))
115787 + {
115788 + XX_Free(param);
115789 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
115790 + }
115791 + }
115792 + else
115793 +#endif /* CONFIG_COMPAT */
115794 + {
115795 + if (copy_from_user(param, (ioc_fm_port_mac_addr_params_t*) arg,
115796 + sizeof(ioc_fm_port_mac_addr_params_t)))
115797 + {
115798 + XX_Free(param);
115799 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
115800 + }
115801 + }
115802 +
115803 + if (p_LnxWrpFmPortDev->pcd_owner_params.dev)
115804 + {
115805 + int id = -1;
115806 +
115807 + switch(p_LnxWrpFmPortDev->settings.param.portType)
115808 + {
115809 + case e_FM_PORT_TYPE_RX:
115810 + case e_FM_PORT_TYPE_TX:
115811 + id = p_LnxWrpFmPortDev->id;
115812 + break;
115813 + case e_FM_PORT_TYPE_RX_10G:
115814 + case e_FM_PORT_TYPE_TX_10G:
115815 + id = p_LnxWrpFmPortDev->id + FM_MAX_NUM_OF_1G_MACS;
115816 + break;
115817 + default:
115818 + err = E_NOT_AVAILABLE;
115819 + REPORT_ERROR(MINOR, err, ("Attempt to add/remove hash MAC addr. to/from MAC-less port!"));
115820 + }
115821 + if (id >= 0)
115822 + {
115823 + t_LnxWrpFmDev *fm = (t_LnxWrpFmDev *)p_LnxWrpFmPortDev->h_LnxWrpFmDev;
115824 + t_Handle mac_handle = fm->macs[id].h_Dev;
115825 +
115826 + err = (cmd == FM_PORT_IOC_ADD_RX_HASH_MAC_ADDR)
115827 + ? FM_MAC_AddHashMacAddr(mac_handle, (t_EnetAddr*) param)
115828 + : FM_MAC_RemoveHashMacAddr(mac_handle, (t_EnetAddr*) param);
115829 + }
115830 + }
115831 + else
115832 + {
115833 + err = E_NOT_AVAILABLE;
115834 + REPORT_ERROR(MINOR, err, ("Port not initialized or other error!?!?"));
115835 + }
115836 +
115837 + XX_Free(param);
115838 + break;
115839 + }
115840 +
115841 + case FM_PORT_IOC_SET_TX_PAUSE_FRAMES:
115842 + {
115843 + t_LnxWrpFmDev *p_LnxWrpFmDev =
115844 + (t_LnxWrpFmDev *)p_LnxWrpFmPortDev->h_LnxWrpFmDev;
115845 + ioc_fm_port_tx_pause_frames_params_t param;
115846 + int mac_id = p_LnxWrpFmPortDev->id;
115847 +
115848 + if(&p_LnxWrpFmDev->txPorts[mac_id] != p_LnxWrpFmPortDev)
115849 + mac_id += FM_MAX_NUM_OF_1G_MACS; /* 10G port */
115850 +
115851 + if (copy_from_user(&param, (ioc_fm_port_tx_pause_frames_params_t *)arg,
115852 + sizeof(ioc_fm_port_tx_pause_frames_params_t)))
115853 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
115854 +
115855 + if (p_LnxWrpFmDev && p_LnxWrpFmDev->macs[mac_id].h_Dev)
115856 + {
115857 + FM_MAC_SetTxPauseFrames(p_LnxWrpFmDev->macs[mac_id].h_Dev,
115858 + param.priority,
115859 + param.pause_time,
115860 + param.thresh_time);
115861 + }
115862 + else
115863 + {
115864 + err = E_NOT_AVAILABLE;
115865 + REPORT_ERROR(MINOR, err, ("Port not initialized or other error!"));
115866 + }
115867 +
115868 + break;
115869 + }
115870 +
115871 + case FM_PORT_IOC_CONFIG_BUFFER_PREFIX_CONTENT:
115872 + {
115873 + ioc_fm_buffer_prefix_content_t *param;
115874 +
115875 + param = (ioc_fm_buffer_prefix_content_t*) XX_Malloc(sizeof(ioc_fm_buffer_prefix_content_t));
115876 + if (!param)
115877 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PORT"));
115878 +
115879 + memset(param, 0, sizeof(ioc_fm_buffer_prefix_content_t));
115880 +
115881 + if (copy_from_user(param, (ioc_fm_buffer_prefix_content_t*) arg,
115882 + sizeof(ioc_fm_buffer_prefix_content_t)))
115883 + {
115884 + XX_Free(param);
115885 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
115886 + }
115887 +
115888 + if (FM_PORT_ConfigBufferPrefixContent(p_LnxWrpFmPortDev->h_Dev,
115889 + (t_FmBufferPrefixContent *)param))
115890 + {
115891 + XX_Free(param);
115892 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
115893 + }
115894 +
115895 + XX_Free(param);
115896 + break;
115897 + }
115898 +
115899 +#if (DPAA_VERSION >= 11)
115900 +#if defined(CONFIG_COMPAT)
115901 + case FM_PORT_IOC_VSP_ALLOC_COMPAT:
115902 +#endif
115903 + case FM_PORT_IOC_VSP_ALLOC:
115904 + {
115905 + ioc_fm_port_vsp_alloc_params_t *param;
115906 + t_LnxWrpFmDev *p_LnxWrpFmDev;
115907 + t_LnxWrpFmPortDev *p_LnxWrpFmTxPortDev;
115908 +
115909 + param = (ioc_fm_port_vsp_alloc_params_t *) XX_Malloc(
115910 + sizeof(ioc_fm_port_vsp_alloc_params_t));
115911 + if (!param)
115912 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PORT"));
115913 +
115914 + memset(param, 0, sizeof(ioc_fm_port_vsp_alloc_params_t));
115915 +
115916 +#if defined(CONFIG_COMPAT)
115917 + if (compat)
115918 + {
115919 + ioc_compat_fm_port_vsp_alloc_params_t *compat_param;
115920 +
115921 + compat_param = (ioc_compat_fm_port_vsp_alloc_params_t *) XX_Malloc(
115922 + sizeof(ioc_compat_fm_port_vsp_alloc_params_t));
115923 + if (!compat_param)
115924 + {
115925 + XX_Free(param);
115926 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PORT"));
115927 + }
115928 +
115929 + memset(compat_param, 0, sizeof(ioc_compat_fm_port_vsp_alloc_params_t));
115930 + if (copy_from_user(compat_param,
115931 + (ioc_compat_fm_port_vsp_alloc_params_t *) compat_ptr(arg),
115932 + sizeof(ioc_compat_fm_port_vsp_alloc_params_t)))
115933 + {
115934 + XX_Free(compat_param);
115935 + XX_Free(param);
115936 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
115937 + }
115938 +
115939 + compat_copy_fm_port_vsp_alloc_params(compat_param, param, COMPAT_US_TO_K);
115940 +
115941 + XX_Free(compat_param);
115942 + }
115943 + else
115944 +#endif
115945 + {
115946 + if (copy_from_user(param, (ioc_fm_port_vsp_alloc_params_t *)arg,
115947 + sizeof(ioc_fm_port_vsp_alloc_params_t)))
115948 + {
115949 + XX_Free(param);
115950 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
115951 + }
115952 + }
115953 +
115954 + /* Userspace may not have the Tx port t_handle when issuing the IOCTL */
115955 + if (p_LnxWrpFmPortDev->settings.param.portType == e_FM_PORT_TYPE_RX ||
115956 + p_LnxWrpFmPortDev->settings.param.portType == e_FM_PORT_TYPE_RX_10G)
115957 + {
115958 + /* Determine the Tx port t_Handle from the Rx port id */
115959 + p_LnxWrpFmDev = p_LnxWrpFmPortDev->h_LnxWrpFmDev;
115960 + p_LnxWrpFmTxPortDev = &p_LnxWrpFmDev->txPorts[p_LnxWrpFmPortDev->id];
115961 + param->p_fm_tx_port = p_LnxWrpFmTxPortDev->h_Dev;
115962 + }
115963 +
115964 + if (FM_PORT_VSPAlloc(p_LnxWrpFmPortDev->h_Dev, (t_FmPortVSPAllocParams *)param))
115965 + {
115966 + XX_Free(param);
115967 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
115968 + }
115969 +
115970 + XX_Free(param);
115971 + break;
115972 + }
115973 +#endif /* (DPAA_VERSION >= 11) */
115974 +
115975 + case FM_PORT_IOC_GET_MAC_STATISTICS:
115976 + {
115977 + t_LnxWrpFmDev *p_LnxWrpFmDev =
115978 + (t_LnxWrpFmDev *)p_LnxWrpFmPortDev->h_LnxWrpFmDev;
115979 + ioc_fm_port_mac_statistics_t param;
115980 + int mac_id = p_LnxWrpFmPortDev->id;
115981 +
115982 + if (!p_LnxWrpFmDev)
115983 + RETURN_ERROR(MINOR, E_NOT_AVAILABLE, ("Port not initialized or other error!"));
115984 +
115985 + if (&p_LnxWrpFmDev->txPorts[mac_id] != p_LnxWrpFmPortDev &&
115986 + &p_LnxWrpFmDev->rxPorts[mac_id] != p_LnxWrpFmPortDev)
115987 + mac_id += FM_MAX_NUM_OF_1G_MACS; /* 10G port */
115988 +
115989 + if (!p_LnxWrpFmDev->macs[mac_id].h_Dev)
115990 + RETURN_ERROR(MINOR, E_NOT_AVAILABLE, ("Port not initialized or other error!"));
115991 +
115992 + if (FM_MAC_GetStatistics(p_LnxWrpFmDev->macs[mac_id].h_Dev,
115993 + (t_FmMacStatistics *)&param))
115994 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
115995 +
115996 + if (copy_to_user((ioc_fm_port_mac_statistics_t *)arg, &param,
115997 + sizeof(ioc_fm_port_mac_statistics_t)))
115998 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
115999 +
116000 + break;
116001 + }
116002 +
116003 + case FM_PORT_IOC_GET_MAC_FRAME_SIZE_COUNTERS:
116004 + {
116005 + t_LnxWrpFmDev *p_LnxWrpFmDev =
116006 + (t_LnxWrpFmDev *)p_LnxWrpFmPortDev->h_LnxWrpFmDev;
116007 + ioc_fm_port_mac_frame_size_counters_t param;
116008 + t_FmMacFrameSizeCounters frameSizeCounters;
116009 + int mac_id = p_LnxWrpFmPortDev->id;
116010 +
116011 + if (!p_LnxWrpFmDev)
116012 + RETURN_ERROR(MINOR, E_NOT_AVAILABLE, ("Port not initialized or other error!"));
116013 +
116014 + if (&p_LnxWrpFmDev->txPorts[mac_id] != p_LnxWrpFmPortDev &&
116015 + &p_LnxWrpFmDev->rxPorts[mac_id] != p_LnxWrpFmPortDev)
116016 + mac_id += FM_MAX_NUM_OF_1G_MACS; /* 10G port */
116017 +
116018 + if (!p_LnxWrpFmDev->macs[mac_id].h_Dev)
116019 + RETURN_ERROR(MINOR, E_NOT_AVAILABLE, ("Port not initialized or other error!"));
116020 +
116021 + if (copy_from_user(&param, (ioc_fm_port_mac_frame_size_counters_t *)arg,
116022 + sizeof(ioc_fm_port_mac_frame_size_counters_t)))
116023 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
116024 +
116025 + if (FM_MAC_GetFrameSizeCounters(p_LnxWrpFmDev->macs[mac_id].h_Dev,
116026 + &frameSizeCounters, param.type))
116027 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
116028 +
116029 + param.count_pkts_64 = frameSizeCounters.count_pkts_64;
116030 + param.count_pkts_65_to_127 = frameSizeCounters.count_pkts_65_to_127;
116031 + param.count_pkts_128_to_255 = frameSizeCounters.count_pkts_128_to_255;
116032 + param.count_pkts_256_to_511 = frameSizeCounters.count_pkts_256_to_511;
116033 + param.count_pkts_512_to_1023 = frameSizeCounters.count_pkts_512_to_1023;
116034 + param.count_pkts_1024_to_1518 = frameSizeCounters.count_pkts_1024_to_1518;
116035 + param.count_pkts_1519_to_1522 = frameSizeCounters.count_pkts_1519_to_1522;
116036 +
116037 + if (copy_to_user((ioc_fm_port_mac_frame_size_counters_t *)arg, &param,
116038 + sizeof(ioc_fm_port_mac_frame_size_counters_t)))
116039 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
116040 +
116041 + break;
116042 + }
116043 +
116044 + case FM_PORT_IOC_GET_BMI_COUNTERS:
116045 + {
116046 + t_LnxWrpFmDev *p_LnxWrpFmDev =
116047 + (t_LnxWrpFmDev *)p_LnxWrpFmPortDev->h_LnxWrpFmDev;
116048 + ioc_fm_port_bmi_stats_t param;
116049 +
116050 + if (!p_LnxWrpFmDev)
116051 + RETURN_ERROR(MINOR, E_NOT_AVAILABLE, ("Port not initialized or other error!"));
116052 +
116053 + if (FM_PORT_GetBmiCounters(p_LnxWrpFmPortDev->h_Dev,
116054 + (t_FmPortBmiStats *)&param))
116055 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
116056 +
116057 + if (copy_to_user((ioc_fm_port_bmi_stats_t *)arg, &param,
116058 + sizeof(ioc_fm_port_bmi_stats_t)))
116059 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
116060 +
116061 + break;
116062 + }
116063 +
116064 + default:
116065 + RETURN_ERROR(MINOR, E_INVALID_SELECTION,
116066 + ("invalid ioctl: cmd:0x%08x(type:0x%02x, nr:0x%02x.\n",
116067 + cmd, _IOC_TYPE(cmd), _IOC_NR(cmd)));
116068 + }
116069 +
116070 + if (err)
116071 + RETURN_ERROR(MINOR, E_INVALID_OPERATION, ("IOCTL FM PORT"));
116072 +
116073 + return E_OK;
116074 +}
116075 +
116076 +/*****************************************************************************/
116077 +/* API routines for the FM Linux Device */
116078 +/*****************************************************************************/
116079 +
116080 +static int fm_open(struct inode *inode, struct file *file)
116081 +{
116082 + t_LnxWrpFmDev *p_LnxWrpFmDev = NULL;
116083 + t_LnxWrpFmPortDev *p_LnxWrpFmPortDev = NULL;
116084 + unsigned int major = imajor(inode);
116085 + unsigned int minor = iminor(inode);
116086 + struct device_node *fm_node;
116087 + static struct of_device_id fm_node_of_match[] = {
116088 + { .compatible = "fsl,fman", },
116089 + { /* end of list */ },
116090 + };
116091 +
116092 + DBG(TRACE, ("Opening minor - %d - ", minor));
116093 +
116094 + if (file->private_data != NULL)
116095 + return 0;
116096 +
116097 + /* Get all the FM nodes */
116098 + for_each_matching_node(fm_node, fm_node_of_match) {
116099 + struct platform_device *of_dev;
116100 +
116101 + of_dev = of_find_device_by_node(fm_node);
116102 + if (unlikely(of_dev == NULL)) {
116103 + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("fm id!"));
116104 + return -ENXIO;
116105 + }
116106 +
116107 + p_LnxWrpFmDev = (t_LnxWrpFmDev *)fm_bind(&of_dev->dev);
116108 + if (p_LnxWrpFmDev->major == major)
116109 + break;
116110 + fm_unbind((struct fm *)p_LnxWrpFmDev);
116111 + p_LnxWrpFmDev = NULL;
116112 + }
116113 +
116114 + if (!p_LnxWrpFmDev)
116115 + return -ENODEV;
116116 +
116117 + if (minor == DEV_FM_MINOR_BASE)
116118 + file->private_data = p_LnxWrpFmDev;
116119 + else if (minor == DEV_FM_PCD_MINOR_BASE)
116120 + file->private_data = p_LnxWrpFmDev;
116121 + else {
116122 + if (minor == DEV_FM_OH_PORTS_MINOR_BASE)
116123 + p_LnxWrpFmPortDev = &p_LnxWrpFmDev->hcPort;
116124 + else if ((minor > DEV_FM_OH_PORTS_MINOR_BASE) && (minor < DEV_FM_RX_PORTS_MINOR_BASE))
116125 + p_LnxWrpFmPortDev = &p_LnxWrpFmDev->opPorts[minor-DEV_FM_OH_PORTS_MINOR_BASE-1];
116126 + else if ((minor >= DEV_FM_RX_PORTS_MINOR_BASE) && (minor < DEV_FM_TX_PORTS_MINOR_BASE))
116127 + p_LnxWrpFmPortDev = &p_LnxWrpFmDev->rxPorts[minor-DEV_FM_RX_PORTS_MINOR_BASE];
116128 + else if ((minor >= DEV_FM_TX_PORTS_MINOR_BASE) && (minor < DEV_FM_MAX_MINORS))
116129 + p_LnxWrpFmPortDev = &p_LnxWrpFmDev->txPorts[minor-DEV_FM_TX_PORTS_MINOR_BASE];
116130 + else
116131 + return -EINVAL;
116132 +
116133 + /* if trying to open port, check if it initialized */
116134 + if (!p_LnxWrpFmPortDev->h_Dev)
116135 + return -ENODEV;
116136 +
116137 + p_LnxWrpFmPortDev = (t_LnxWrpFmPortDev *)fm_port_bind(p_LnxWrpFmPortDev->dev);
116138 + file->private_data = p_LnxWrpFmPortDev;
116139 + fm_unbind((struct fm *)p_LnxWrpFmDev);
116140 + }
116141 +
116142 + if (file->private_data == NULL)
116143 + return -ENXIO;
116144 +
116145 + return 0;
116146 +}
116147 +
116148 +static int fm_close(struct inode *inode, struct file *file)
116149 +{
116150 + t_LnxWrpFmDev *p_LnxWrpFmDev;
116151 + t_LnxWrpFmPortDev *p_LnxWrpFmPortDev;
116152 + unsigned int minor = iminor(inode);
116153 + int err = 0;
116154 +
116155 + DBG(TRACE, ("Closing minor - %d - ", minor));
116156 +
116157 + if ((minor == DEV_FM_MINOR_BASE) ||
116158 + (minor == DEV_FM_PCD_MINOR_BASE))
116159 + {
116160 + p_LnxWrpFmDev = (t_LnxWrpFmDev*)file->private_data;
116161 + if (!p_LnxWrpFmDev)
116162 + return -ENODEV;
116163 + fm_unbind((struct fm *)p_LnxWrpFmDev);
116164 + }
116165 + else if (((minor >= DEV_FM_OH_PORTS_MINOR_BASE) && (minor < DEV_FM_RX_PORTS_MINOR_BASE)) ||
116166 + ((minor >= DEV_FM_RX_PORTS_MINOR_BASE) && (minor < DEV_FM_TX_PORTS_MINOR_BASE)) ||
116167 + ((minor >= DEV_FM_TX_PORTS_MINOR_BASE) && (minor < DEV_FM_MAX_MINORS)))
116168 + {
116169 + p_LnxWrpFmPortDev = (t_LnxWrpFmPortDev*)file->private_data;
116170 + if (!p_LnxWrpFmPortDev)
116171 + return -ENODEV;
116172 + fm_port_unbind((struct fm_port *)p_LnxWrpFmPortDev);
116173 + }
116174 +
116175 + return err;
116176 +}
116177 +
116178 +static int fm_ioctls(unsigned int minor, struct file *file, unsigned int cmd, unsigned long arg, bool compat)
116179 +{
116180 + DBG(TRACE, ("IOCTL minor - %u, cmd - 0x%08x, arg - 0x%08lx \n", minor, cmd, arg));
116181 +
116182 + if ((minor == DEV_FM_MINOR_BASE) ||
116183 + (minor == DEV_FM_PCD_MINOR_BASE))
116184 + {
116185 + t_LnxWrpFmDev *p_LnxWrpFmDev = ((t_LnxWrpFmDev*)file->private_data);
116186 + if (!p_LnxWrpFmDev)
116187 + return -ENODEV;
116188 + if (LnxwrpFmIOCTL(p_LnxWrpFmDev, cmd, arg, compat))
116189 + return -EFAULT;
116190 + }
116191 + else if (((minor >= DEV_FM_OH_PORTS_MINOR_BASE) && (minor < DEV_FM_RX_PORTS_MINOR_BASE)) ||
116192 + ((minor >= DEV_FM_RX_PORTS_MINOR_BASE) && (minor < DEV_FM_TX_PORTS_MINOR_BASE)) ||
116193 + ((minor >= DEV_FM_TX_PORTS_MINOR_BASE) && (minor < DEV_FM_MAX_MINORS)))
116194 + {
116195 + t_LnxWrpFmPortDev *p_LnxWrpFmPortDev = ((t_LnxWrpFmPortDev*)file->private_data);
116196 + if (!p_LnxWrpFmPortDev)
116197 + return -ENODEV;
116198 + if (LnxwrpFmPortIOCTL(p_LnxWrpFmPortDev, cmd, arg, compat))
116199 + return -EFAULT;
116200 + }
116201 + else
116202 + {
116203 + REPORT_ERROR(MINOR, E_INVALID_VALUE, ("minor"));
116204 + return -ENODEV;
116205 + }
116206 +
116207 + return 0;
116208 +}
116209 +
116210 +#ifdef CONFIG_COMPAT
116211 +static long fm_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
116212 +{
116213 + unsigned int minor = iminor(file->f_path.dentry->d_inode);
116214 + long res;
116215 +
116216 + fm_mutex_lock();
116217 + res = fm_ioctls(minor, file, cmd, arg, true);
116218 + fm_mutex_unlock();
116219 +
116220 + return res;
116221 +}
116222 +#endif
116223 +
116224 +static long fm_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
116225 +{
116226 + unsigned int minor = iminor(file->f_path.dentry->d_inode);
116227 + long res;
116228 +
116229 + fm_mutex_lock();
116230 + res = fm_ioctls(minor, file, cmd, arg, false);
116231 + fm_mutex_unlock();
116232 +
116233 + return res;
116234 +}
116235 +
116236 +/* Globals for FM character device */
116237 +struct file_operations fm_fops =
116238 +{
116239 + .owner = THIS_MODULE,
116240 + .unlocked_ioctl = fm_ioctl,
116241 +#ifdef CONFIG_COMPAT
116242 + .compat_ioctl = fm_compat_ioctl,
116243 +#endif
116244 + .open = fm_open,
116245 + .release = fm_close,
116246 +};
116247 --- /dev/null
116248 +++ b/drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_ioctls_fm_compat.c
116249 @@ -0,0 +1,1297 @@
116250 +/*
116251 + * Copyright 2008-2012 Freescale Semiconductor Inc.
116252 + *
116253 + * Redistribution and use in source and binary forms, with or without
116254 + * modification, are permitted provided that the following conditions are met:
116255 + * * Redistributions of source code must retain the above copyright
116256 + * notice, this list of conditions and the following disclaimer.
116257 + * * Redistributions in binary form must reproduce the above copyright
116258 + * notice, this list of conditions and the following disclaimer in the
116259 + * documentation and/or other materials provided with the distribution.
116260 + * * Neither the name of Freescale Semiconductor nor the
116261 + * names of its contributors may be used to endorse or promote products
116262 + * derived from this software without specific prior written permission.
116263 + *
116264 + *
116265 + * ALTERNATIVELY, this software may be distributed under the terms of the
116266 + * GNU General Public License ("GPL") as published by the Free Software
116267 + * Foundation, either version 2 of that License or (at your option) any
116268 + * later version.
116269 + *
116270 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
116271 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
116272 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
116273 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
116274 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
116275 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
116276 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
116277 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
116278 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
116279 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
116280 + */
116281 +
116282 +/*
116283 + @File lnxwrp_fm_compat_ioctls.c
116284 +
116285 + @Description FM PCD compat functions
116286 +
116287 +*/
116288 +
116289 +#if !defined(CONFIG_COMPAT)
116290 +#error "missing COMPAT layer..."
116291 +#endif
116292 +
116293 +
116294 +#include <linux/kernel.h>
116295 +#include <linux/module.h>
116296 +#include <linux/fs.h>
116297 +#include <linux/cdev.h>
116298 +#include <linux/device.h>
116299 +#include <linux/irq.h>
116300 +#include <linux/interrupt.h>
116301 +#include <linux/io.h>
116302 +#include <linux/ioport.h>
116303 +#include <asm/uaccess.h>
116304 +#include <asm/errno.h>
116305 +#ifndef CONFIG_FMAN_ARM
116306 +#include <sysdev/fsl_soc.h>
116307 +#endif
116308 +
116309 +#include "part_ext.h"
116310 +#include "fm_ioctls.h"
116311 +#include "fm_pcd_ioctls.h"
116312 +#include "fm_port_ioctls.h"
116313 +#include "lnxwrp_ioctls_fm_compat.h"
116314 +
116315 +#if defined(FM_COMPAT_DBG)
116316 +static void hex_dump(void * p_addr, unsigned int size)
116317 +{
116318 + int i;
116319 +
116320 + for(i=0; i<size; i+=16)
116321 + {
116322 + printk("%p: 0x%08x 0x%08x 0x%08x 0x%08x\n", p_addr + i,
116323 + *(unsigned int *)(p_addr + i),
116324 + *(unsigned int *)(p_addr + i + 4),
116325 + *(unsigned int *)(p_addr + i + 8),
116326 + *(unsigned int *)(p_addr + i +12)
116327 + );
116328 + }
116329 +}
116330 +#endif
116331 +
116332 +/* maping kernel pointers w/ UserSpace id's { */
116333 +struct map_node {
116334 + void *ptr;
116335 + u8 node_type;
116336 +};
116337 +
116338 +static struct map_node compat_ptr2id_array[COMPAT_PTR2ID_ARRAY_MAX] = {{NULL},{FM_MAP_TYPE_UNSPEC}};
116339 +
116340 +void compat_del_ptr2id(void *p, enum fm_map_node_type node_type)
116341 +{
116342 + compat_uptr_t k;
116343 +
116344 + _fm_cpt_dbg(COMPAT_GENERIC, "delete (%p)\n", p);
116345 +
116346 + for(k=1; k < COMPAT_PTR2ID_ARRAY_MAX; k++)
116347 + if(compat_ptr2id_array[k].ptr == p){
116348 + compat_ptr2id_array[k].ptr = NULL;
116349 + compat_ptr2id_array[k].node_type = FM_MAP_TYPE_UNSPEC;
116350 + }
116351 +}
116352 +EXPORT_SYMBOL(compat_del_ptr2id);
116353 +
116354 +compat_uptr_t compat_add_ptr2id(void *p, enum fm_map_node_type node_type)
116355 +{
116356 + compat_uptr_t k;
116357 +
116358 + _fm_cpt_dbg(COMPAT_GENERIC, " (%p) do ->\n", p);
116359 +
116360 + if(!p)
116361 + return 0;
116362 +
116363 + for(k=1; k < COMPAT_PTR2ID_ARRAY_MAX; k++)
116364 + if(compat_ptr2id_array[k].ptr == NULL)
116365 + {
116366 + compat_ptr2id_array[k].ptr = p;
116367 + compat_ptr2id_array[k].node_type = node_type;
116368 + _fm_cpt_dbg(COMPAT_GENERIC, "0x%08x \n", k | COMPAT_PTR2ID_WATERMARK);
116369 + return k | COMPAT_PTR2ID_WATERMARK;
116370 + }
116371 +
116372 + printk(KERN_WARNING "FMan map list full! No more PCD space on kernel!\n");
116373 + return 0;
116374 +}
116375 +EXPORT_SYMBOL(compat_add_ptr2id);
116376 +
116377 +compat_uptr_t compat_get_ptr2id(void *p, enum fm_map_node_type node_type)
116378 +{
116379 + compat_uptr_t k;
116380 +
116381 + _fm_cpt_dbg(COMPAT_GENERIC, " (%p) get -> \n", p);
116382 +
116383 + for(k=1; k < COMPAT_PTR2ID_ARRAY_MAX; k++)
116384 + if(compat_ptr2id_array[k].ptr == p &&
116385 + compat_ptr2id_array[k].node_type == node_type) {
116386 +
116387 + _fm_cpt_dbg(COMPAT_GENERIC, "0x%08x\n", k | COMPAT_PTR2ID_WATERMARK);
116388 + return k | COMPAT_PTR2ID_WATERMARK;
116389 + }
116390 +
116391 + return 0;
116392 +}
116393 +EXPORT_SYMBOL(compat_get_ptr2id);
116394 +
116395 +void *compat_get_id2ptr(compat_uptr_t comp, enum fm_map_node_type node_type)
116396 +{
116397 +
116398 + _fm_cpt_dbg(COMPAT_GENERIC, " (0x%08x) get -> \n", comp);
116399 +
116400 + if((COMPAT_PTR2ID_WM_MASK & comp) != COMPAT_PTR2ID_WATERMARK) {
116401 + _fm_cpt_dbg(COMPAT_GENERIC, "Error, invalid watermark (0x%08x)!\n\n", comp);
116402 + dump_stack();
116403 + return compat_ptr(comp);
116404 + }
116405 +
116406 + comp &= ~COMPAT_PTR2ID_WM_MASK;
116407 +
116408 + if(((0 < comp) && (comp < COMPAT_PTR2ID_ARRAY_MAX) && (compat_ptr2id_array[comp].ptr != NULL)
116409 + && compat_ptr2id_array[comp].node_type == node_type)) {
116410 + _fm_cpt_dbg(COMPAT_GENERIC, "%p\n", compat_ptr2id_array[comp].ptr);
116411 + return compat_ptr2id_array[comp].ptr;
116412 + }
116413 + return NULL;
116414 +}
116415 +EXPORT_SYMBOL(compat_get_id2ptr);
116416 +/* } maping kernel pointers w/ UserSpace id's */
116417 +
116418 +void compat_obj_delete(
116419 + ioc_compat_fm_obj_t *compat_id,
116420 + ioc_fm_obj_t *id)
116421 +{
116422 + id->obj = compat_pcd_id2ptr(compat_id->obj);
116423 + compat_del_ptr2id(id->obj, FM_MAP_TYPE_PCD_NODE);
116424 +}
116425 +
116426 +static inline void compat_copy_fm_pcd_plcr_next_engine(
116427 + ioc_compat_fm_pcd_plcr_next_engine_params_u *compat_param,
116428 + ioc_fm_pcd_plcr_next_engine_params_u *param,
116429 + ioc_fm_pcd_engine next_engine,
116430 + uint8_t compat)
116431 +{
116432 + _fm_cpt_dbg (compat, " {->...\n");
116433 +
116434 + switch (next_engine)
116435 + {
116436 + case e_IOC_FM_PCD_PLCR:
116437 + if (compat == COMPAT_US_TO_K)
116438 + param->p_profile = compat_pcd_id2ptr(compat_param->p_profile);
116439 + else
116440 + compat_param->p_profile = compat_pcd_ptr2id(param->p_profile);
116441 + break;
116442 + case e_IOC_FM_PCD_KG:
116443 + if (compat == COMPAT_US_TO_K)
116444 + param->p_direct_scheme = compat_pcd_id2ptr(compat_param->p_direct_scheme);
116445 + else
116446 + compat_param->p_direct_scheme = compat_pcd_ptr2id(param->p_direct_scheme);
116447 + break;
116448 + default:
116449 + if (compat == COMPAT_US_TO_K)
116450 + param->action = compat_param->action;
116451 + else
116452 + compat_param->action = param->action;
116453 + break;
116454 + }
116455 +
116456 + _fm_cpt_dbg (compat, " ...->}\n");
116457 +}
116458 +
116459 +void compat_copy_fm_pcd_plcr_profile(
116460 + ioc_compat_fm_pcd_plcr_profile_params_t *compat_param,
116461 + ioc_fm_pcd_plcr_profile_params_t *param,
116462 + uint8_t compat)
116463 +{
116464 + _fm_cpt_dbg (compat, " {->...\n");
116465 +
116466 + if (compat == COMPAT_US_TO_K)
116467 + {
116468 + param->modify = compat_param->modify;
116469 +
116470 + /* profile_select */
116471 + if (!compat_param->modify)
116472 + {
116473 + param->profile_select.new_params.profile_type =
116474 + compat_param->profile_select.new_params.profile_type;
116475 + param->profile_select.new_params.p_fm_port =
116476 + compat_ptr(compat_param->profile_select.new_params.p_fm_port);
116477 + param->profile_select.new_params.relative_profile_id =
116478 + compat_param->profile_select.new_params.relative_profile_id;
116479 + }
116480 + else
116481 + param->profile_select.p_profile =
116482 + compat_pcd_id2ptr(compat_param->profile_select.p_profile);
116483 +
116484 + param->alg_selection = compat_param->alg_selection;
116485 + param->color_mode = compat_param->color_mode;
116486 +
116487 + /* both parameters in the union has the same size, so memcpy works */
116488 + memcpy(&param->color, &compat_param->color, sizeof(param->color));
116489 +
116490 + memcpy(&param->non_passthrough_alg_param,
116491 + &compat_param->non_passthrough_alg_param,
116492 + sizeof(ioc_fm_pcd_plcr_non_passthrough_alg_param_t));
116493 +
116494 + param->next_engine_on_green = compat_param->next_engine_on_green;
116495 + param->next_engine_on_yellow = compat_param->next_engine_on_yellow;
116496 + param->next_engine_on_red = compat_param->next_engine_on_red;
116497 +
116498 + param->trap_profile_on_flow_A = compat_param->trap_profile_on_flow_A;
116499 + param->trap_profile_on_flow_B = compat_param->trap_profile_on_flow_B;
116500 + param->trap_profile_on_flow_C = compat_param->trap_profile_on_flow_C;
116501 + }
116502 + else
116503 + {
116504 + compat_param->modify = param->modify;
116505 +
116506 + /* profile_select */
116507 + if (!param->modify)
116508 + {
116509 + compat_param->profile_select.new_params.profile_type =
116510 + param->profile_select.new_params.profile_type;
116511 + compat_param->profile_select.new_params.p_fm_port =
116512 + ptr_to_compat(param->profile_select.new_params.p_fm_port);
116513 + compat_param->profile_select.new_params.relative_profile_id =
116514 + param->profile_select.new_params.relative_profile_id;
116515 + }
116516 + else
116517 + compat_param->profile_select.p_profile =
116518 + compat_pcd_ptr2id(param->profile_select.p_profile);
116519 +
116520 + compat_param->alg_selection = param->alg_selection;
116521 + compat_param->color_mode = param->color_mode;
116522 +
116523 + /* both parameters in the union has the same size, so memcpy works */
116524 + memcpy(&compat_param->color, &param->color, sizeof(compat_param->color));
116525 +
116526 + memcpy(&compat_param->non_passthrough_alg_param,
116527 + &param->non_passthrough_alg_param,
116528 + sizeof(ioc_fm_pcd_plcr_non_passthrough_alg_param_t));
116529 +
116530 + compat_param->next_engine_on_green = param->next_engine_on_green;
116531 + compat_param->next_engine_on_yellow = param->next_engine_on_yellow;
116532 + compat_param->next_engine_on_red = param->next_engine_on_red;
116533 +
116534 + compat_param->trap_profile_on_flow_A = param->trap_profile_on_flow_A;
116535 + compat_param->trap_profile_on_flow_B = param->trap_profile_on_flow_B;
116536 + compat_param->trap_profile_on_flow_C = param->trap_profile_on_flow_C;
116537 +
116538 + compat_param->id = compat_add_ptr2id(param->id, FM_MAP_TYPE_PCD_NODE);
116539 + }
116540 +
116541 + compat_copy_fm_pcd_plcr_next_engine(&compat_param->params_on_green,
116542 + &param->params_on_green, param->next_engine_on_green, compat);
116543 +
116544 + compat_copy_fm_pcd_plcr_next_engine(&compat_param->params_on_yellow,
116545 + &param->params_on_yellow, param->next_engine_on_yellow, compat);
116546 +
116547 + compat_copy_fm_pcd_plcr_next_engine(&compat_param->params_on_red,
116548 + &param->params_on_red, param->next_engine_on_red, compat);
116549 +
116550 + _fm_cpt_dbg (compat, " ...->}\n");
116551 +}
116552 +
116553 +static inline void compat_copy_fm_pcd_cc_next_kg(
116554 + ioc_compat_fm_pcd_cc_next_kg_params_t *compat_param,
116555 + ioc_fm_pcd_cc_next_kg_params_t *param,
116556 + uint8_t compat)
116557 +{
116558 + _fm_cpt_dbg (compat, " {->...\n");
116559 +
116560 + if (compat == COMPAT_US_TO_K)
116561 + {
116562 + param->new_fqid = compat_param->new_fqid;
116563 + param->override_fqid = compat_param->override_fqid;
116564 +#if DPAA_VERSION >= 11
116565 + param->new_relative_storage_profile_id = compat_param->new_relative_storage_profile_id;
116566 +#endif
116567 + param->p_direct_scheme = compat_pcd_id2ptr(compat_param->p_direct_scheme);
116568 + }
116569 + else
116570 + {
116571 + compat_param->new_fqid = param->new_fqid;
116572 + compat_param->override_fqid = param->override_fqid;
116573 +#if DPAA_VERSION >= 11
116574 + compat_param->new_relative_storage_profile_id = param->new_relative_storage_profile_id;
116575 +#endif
116576 + compat_param->p_direct_scheme = compat_pcd_ptr2id(param->p_direct_scheme);
116577 + }
116578 +
116579 + _fm_cpt_dbg (compat, " ...->}\n");
116580 +}
116581 +
116582 +static inline void compat_copy_fm_pcd_cc_next_cc(
116583 + ioc_compat_fm_pcd_cc_next_cc_params_t *compat_param,
116584 + ioc_fm_pcd_cc_next_cc_params_t *param,
116585 + uint8_t compat)
116586 +{
116587 + _fm_cpt_dbg (compat, " {->...\n");
116588 +
116589 + if (compat == COMPAT_US_TO_K)
116590 + param->cc_node_id = compat_pcd_id2ptr(compat_param->cc_node_id);
116591 + else
116592 + compat_param->cc_node_id = compat_pcd_ptr2id(param->cc_node_id);
116593 +
116594 + _fm_cpt_dbg (compat, " ...->}\n");
116595 +}
116596 +
116597 +static inline void compat_copy_fm_pcd_cc_next_engine(
116598 + ioc_compat_fm_pcd_cc_next_engine_params_t *compat_param,
116599 + ioc_fm_pcd_cc_next_engine_params_t *param,
116600 + uint8_t compat)
116601 +{
116602 + _fm_cpt_dbg (compat, " {->...\n");
116603 +
116604 + if (compat == COMPAT_US_TO_K)
116605 + {
116606 + param->next_engine = compat_param->next_engine;
116607 + if (param->next_engine != e_IOC_FM_PCD_INVALID )
116608 + _fm_cpt_dbg(compat, " param->next_engine = %i \n", param->next_engine);
116609 +
116610 + switch (param->next_engine)
116611 + {
116612 +#if DPAA_VERSION >= 11
116613 + case e_IOC_FM_PCD_FR:
116614 + param->params.fr_params.frm_replic_id = compat_pcd_id2ptr(compat_param->params.fr_params.frm_replic_id);
116615 + break;
116616 +#endif /* DPAA_VERSION >= 11 */
116617 + case e_IOC_FM_PCD_CC:
116618 + param->manip_id = compat_pcd_id2ptr(compat_param->manip_id);
116619 + compat_copy_fm_pcd_cc_next_cc(&compat_param->params.cc_params, &param->params.cc_params, compat);
116620 + break;
116621 + case e_IOC_FM_PCD_KG:
116622 + param->manip_id = compat_pcd_id2ptr(compat_param->manip_id);
116623 + compat_copy_fm_pcd_cc_next_kg(&compat_param->params.kg_params, &param->params.kg_params, compat);
116624 + break;
116625 + case e_IOC_FM_PCD_DONE:
116626 + case e_IOC_FM_PCD_PLCR:
116627 + param->manip_id = compat_pcd_id2ptr(compat_param->manip_id);
116628 + default:
116629 + memcpy(&param->params, &compat_param->params, sizeof(param->params));
116630 + }
116631 + param->statistics_en = compat_param->statistics_en;
116632 + }
116633 + else
116634 + {
116635 + compat_param->next_engine = param->next_engine;
116636 +
116637 + switch (compat_param->next_engine)
116638 + {
116639 +#if DPAA_VERSION >= 11
116640 + case e_IOC_FM_PCD_FR:
116641 + compat_param->params.fr_params.frm_replic_id = compat_pcd_ptr2id(param->params.fr_params.frm_replic_id);
116642 + break;
116643 +#endif /* DPAA_VERSION >= 11 */
116644 + case e_IOC_FM_PCD_CC:
116645 + compat_param->manip_id = compat_pcd_ptr2id(param->manip_id);
116646 + compat_copy_fm_pcd_cc_next_cc(&compat_param->params.cc_params, &param->params.cc_params, compat);
116647 + break;
116648 + case e_IOC_FM_PCD_KG:
116649 + compat_param->manip_id = compat_pcd_ptr2id(param->manip_id);
116650 + compat_copy_fm_pcd_cc_next_kg(&compat_param->params.kg_params, &param->params.kg_params, compat);
116651 + break;
116652 + case e_IOC_FM_PCD_DONE:
116653 + case e_IOC_FM_PCD_PLCR:
116654 + compat_param->manip_id = compat_pcd_ptr2id(param->manip_id);
116655 + default:
116656 + memcpy(&compat_param->params, &param->params, sizeof(compat_param->params));
116657 + }
116658 + compat_param->statistics_en = param->statistics_en;
116659 + }
116660 +
116661 + _fm_cpt_dbg (compat, " ...->}\n");
116662 +}
116663 +
116664 +void compat_copy_fm_pcd_cc_key(
116665 + ioc_compat_fm_pcd_cc_key_params_t *compat_param,
116666 + ioc_fm_pcd_cc_key_params_t *param,
116667 + uint8_t compat)
116668 +{
116669 + if (compat == COMPAT_US_TO_K)
116670 + {
116671 + param->p_key = compat_ptr(compat_param->p_key);
116672 + param->p_mask = compat_ptr(compat_param->p_mask);
116673 + }
116674 + else
116675 + {
116676 + compat_param->p_key = ptr_to_compat(param->p_key);
116677 + compat_param->p_mask = ptr_to_compat(param->p_mask);
116678 + }
116679 +
116680 + compat_copy_fm_pcd_cc_next_engine(
116681 + &compat_param->cc_next_engine_params,
116682 + &param->cc_next_engine_params,
116683 + compat);
116684 +}
116685 +
116686 +void compat_copy_fm_pcd_cc_node_modify_key_and_next_engine(
116687 + ioc_compat_fm_pcd_cc_node_modify_key_and_next_engine_params_t *compat_param,
116688 + ioc_fm_pcd_cc_node_modify_key_and_next_engine_params_t *param,
116689 + uint8_t compat)
116690 +{
116691 + if (compat == COMPAT_US_TO_K)
116692 + {
116693 + param->id = compat_pcd_id2ptr(compat_param->id);
116694 + param->key_indx = compat_param->key_indx;
116695 + param->key_size = compat_param->key_size;
116696 + compat_copy_fm_pcd_cc_key(
116697 + &compat_param->key_params,
116698 + &param->key_params,
116699 + compat);
116700 + }
116701 + else
116702 + {
116703 + compat_param->id = compat_pcd_ptr2id(param->id);
116704 + compat_param->key_indx = param->key_indx;
116705 + compat_param->key_size = param->key_size;
116706 + compat_copy_fm_pcd_cc_key(
116707 + &compat_param->key_params,
116708 + &param->key_params,
116709 + compat);
116710 + }
116711 +}
116712 +
116713 +void compat_copy_fm_pcd_cc_node_modify_next_engine(
116714 + ioc_compat_fm_pcd_cc_node_modify_next_engine_params_t *compat_param,
116715 + ioc_fm_pcd_cc_node_modify_next_engine_params_t *param,
116716 + uint8_t compat)
116717 +{
116718 + if (compat == COMPAT_US_TO_K)
116719 + {
116720 + param->id = compat_pcd_id2ptr(compat_param->id);
116721 + param->key_indx = compat_param->key_indx;
116722 + param->key_size = compat_param->key_size;
116723 + }
116724 + else
116725 + {
116726 + compat_param->id = compat_pcd_ptr2id(param->id);
116727 + compat_param->key_indx = param->key_indx;
116728 + compat_param->key_size = param->key_size;
116729 + }
116730 +
116731 + compat_copy_fm_pcd_cc_next_engine(
116732 + &compat_param->cc_next_engine_params,
116733 + &param->cc_next_engine_params,
116734 + compat);
116735 +}
116736 +
116737 +void compat_fm_pcd_cc_tree_modify_next_engine(
116738 + ioc_compat_fm_pcd_cc_tree_modify_next_engine_params_t *compat_param,
116739 + ioc_fm_pcd_cc_tree_modify_next_engine_params_t *param,
116740 + uint8_t compat)
116741 +{
116742 + if (compat == COMPAT_US_TO_K)
116743 + {
116744 + param->id = compat_pcd_id2ptr(compat_param->id);
116745 + param->grp_indx = compat_param->grp_indx;
116746 + param->indx = compat_param->indx;
116747 + }
116748 + else
116749 + {
116750 + compat_param->id = compat_pcd_ptr2id(param->id);
116751 + compat_param->grp_indx = param->grp_indx;
116752 + compat_param->indx = param->indx;
116753 + }
116754 +
116755 + compat_copy_fm_pcd_cc_next_engine(
116756 + &compat_param->cc_next_engine_params,
116757 + &param->cc_next_engine_params,
116758 + compat);
116759 +}
116760 +
116761 +void compat_copy_fm_pcd_hash_table(
116762 + ioc_compat_fm_pcd_hash_table_params_t *compat_param,
116763 + ioc_fm_pcd_hash_table_params_t *param,
116764 + uint8_t compat)
116765 +{
116766 + if (compat == COMPAT_US_TO_K)
116767 + {
116768 + param->max_num_of_keys = compat_param->max_num_of_keys;
116769 + param->statistics_mode = compat_param->statistics_mode;
116770 + param->kg_hash_shift = compat_param->kg_hash_shift;
116771 + param->hash_res_mask = compat_param->hash_res_mask;
116772 + param->hash_shift = compat_param->hash_shift;
116773 + param->match_key_size = compat_param->match_key_size;
116774 + param->id = compat_pcd_id2ptr(compat_param->id);
116775 + }
116776 + else
116777 + {
116778 + compat_param->max_num_of_keys = param->max_num_of_keys;
116779 + compat_param->statistics_mode = param->statistics_mode;
116780 + compat_param->kg_hash_shift = param->kg_hash_shift;
116781 + compat_param->hash_res_mask = param->hash_res_mask;
116782 + compat_param->hash_shift = param->hash_shift;
116783 + compat_param->match_key_size = param->match_key_size;
116784 +
116785 + compat_param->id = compat_add_ptr2id(param->id, FM_MAP_TYPE_PCD_NODE);
116786 + }
116787 +
116788 + compat_copy_fm_pcd_cc_next_engine(
116789 + &compat_param->cc_next_engine_params_for_miss,
116790 + &param->cc_next_engine_params_for_miss,
116791 + compat);
116792 +}
116793 +
116794 +void compat_copy_fm_pcd_cc_grp(
116795 + ioc_compat_fm_pcd_cc_grp_params_t *compat_param,
116796 + ioc_fm_pcd_cc_grp_params_t *param,
116797 + uint8_t compat)
116798 +{
116799 + int k;
116800 +
116801 + _fm_cpt_dbg (compat, " {->...\n");
116802 +
116803 + if (compat == COMPAT_US_TO_K)
116804 + {
116805 + param->num_of_distinction_units = compat_param->num_of_distinction_units;
116806 + memcpy(param->unit_ids, compat_param->unit_ids, IOC_FM_PCD_MAX_NUM_OF_CC_UNITS);
116807 + }
116808 + else
116809 + {
116810 + compat_param->num_of_distinction_units = param->num_of_distinction_units;
116811 + memcpy(compat_param->unit_ids, param->unit_ids, IOC_FM_PCD_MAX_NUM_OF_CC_UNITS);
116812 + }
116813 +
116814 + for (k=0; k < IOC_FM_PCD_MAX_NUM_OF_CC_ENTRIES_IN_GRP; k++)
116815 + compat_copy_fm_pcd_cc_next_engine(
116816 + &compat_param->next_engine_per_entries_in_grp[k],
116817 + &param->next_engine_per_entries_in_grp[k],
116818 + compat);
116819 +
116820 + _fm_cpt_dbg (compat, " ...->}\n");
116821 +}
116822 +
116823 +void compat_copy_fm_pcd_cc_tree(
116824 + ioc_compat_fm_pcd_cc_tree_params_t *compat_param,
116825 + ioc_fm_pcd_cc_tree_params_t *param,
116826 + uint8_t compat)
116827 +{
116828 + int k;
116829 + _fm_cpt_dbg (compat, " {->...\n");
116830 +
116831 + if (compat == COMPAT_US_TO_K)
116832 + {
116833 + param->net_env_id = compat_pcd_id2ptr(compat_param->net_env_id);
116834 + param->num_of_groups = compat_param->num_of_groups;
116835 + }
116836 + else
116837 + {
116838 + compat_param->net_env_id = compat_pcd_ptr2id(param->net_env_id);
116839 + compat_param->num_of_groups = param->num_of_groups;
116840 +
116841 + compat_param->id = compat_add_ptr2id(param->id, FM_MAP_TYPE_PCD_NODE);
116842 + }
116843 +
116844 + for (k=0; k < IOC_FM_PCD_MAX_NUM_OF_CC_GROUPS; k++)
116845 + compat_copy_fm_pcd_cc_grp(
116846 + &compat_param->fm_pcd_cc_group_params[k],
116847 + &param->fm_pcd_cc_group_params[k],
116848 + compat);
116849 +
116850 + _fm_cpt_dbg (compat, " ...->}\n");
116851 +}
116852 +
116853 +void compat_fm_pcd_prs_sw(
116854 + ioc_compat_fm_pcd_prs_sw_params_t *compat_param,
116855 + ioc_fm_pcd_prs_sw_params_t *param,
116856 + uint8_t compat)
116857 +{
116858 + if (compat == COMPAT_US_TO_K)
116859 + {
116860 + param->override = compat_param->override;
116861 + param->size = compat_param->size;
116862 + param->base = compat_param->base;
116863 + param->p_code = compat_ptr(compat_param->p_code);
116864 + memcpy(param->sw_prs_data_params,compat_param->sw_prs_data_params,IOC_FM_PCD_PRS_NUM_OF_HDRS*sizeof(uint32_t));
116865 + param->num_of_labels = compat_param->num_of_labels;
116866 + memcpy(param->labels_table,compat_param->labels_table,IOC_FM_PCD_PRS_NUM_OF_LABELS*sizeof(ioc_fm_pcd_prs_label_params_t));
116867 + }
116868 +}
116869 +
116870 +void compat_copy_fm_pcd_kg_scheme(
116871 + ioc_compat_fm_pcd_kg_scheme_params_t *compat_param,
116872 + ioc_fm_pcd_kg_scheme_params_t *param,
116873 + uint8_t compat)
116874 +{
116875 + _fm_cpt_dbg(compat," {->...\n");
116876 +
116877 + if (compat == COMPAT_US_TO_K)
116878 + {
116879 + param->modify = compat_param->modify;
116880 +
116881 + /* scm_id */
116882 + if (compat_param->modify)
116883 + {
116884 + param->scm_id.scheme_id = compat_pcd_id2ptr(compat_param->scm_id.scheme_id);
116885 + _fm_cpt_dbg(compat," param->scm_id.scheme_id = %p \n", param->scm_id.scheme_id);
116886 + }
116887 + else
116888 + param->scm_id.relative_scheme_id = compat_param->scm_id.relative_scheme_id;
116889 +
116890 + param->always_direct = compat_param->always_direct;
116891 + /* net_env_params */
116892 + param->net_env_params.net_env_id = compat_pcd_id2ptr(compat_param->net_env_params.net_env_id);
116893 + param->net_env_params.num_of_distinction_units = compat_param->net_env_params.num_of_distinction_units;
116894 + memcpy(param->net_env_params.unit_ids,
116895 + compat_param->net_env_params.unit_ids,
116896 + IOC_FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS);
116897 +
116898 + param->use_hash = compat_param->use_hash;
116899 + memcpy(&param->key_extract_and_hash_params,
116900 + &compat_param->key_extract_and_hash_params,
116901 + sizeof(ioc_fm_pcd_kg_key_extract_and_hash_params_t));
116902 + param->bypass_fqid_generation = compat_param->bypass_fqid_generation;
116903 + param->base_fqid = compat_param->base_fqid;
116904 +#if DPAA_VERSION >= 11
116905 + param->override_storage_profile =
116906 + compat_param->override_storage_profile;
116907 + param->storage_profile = compat_param->storage_profile;
116908 +#endif
116909 + param->num_of_used_extracted_ors = compat_param->num_of_used_extracted_ors;
116910 + memcpy(param->extracted_ors,
116911 + compat_param->extracted_ors,
116912 + IOC_FM_PCD_KG_NUM_OF_GENERIC_REGS * sizeof(ioc_fm_pcd_kg_extracted_or_params_t));
116913 + param->next_engine = compat_param->next_engine;
116914 +
116915 + /* kg_next_engine_params */
116916 + if (param->next_engine == e_IOC_FM_PCD_CC)
116917 + {
116918 + param->kg_next_engine_params.cc.tree_id = compat_pcd_id2ptr(compat_param->kg_next_engine_params.cc.tree_id);
116919 + param->kg_next_engine_params.cc.grp_id = compat_param->kg_next_engine_params.cc.grp_id;
116920 + param->kg_next_engine_params.cc.plcr_next = compat_param->kg_next_engine_params.cc.plcr_next;
116921 + param->kg_next_engine_params.cc.bypass_plcr_profile_generation
116922 + = compat_param->kg_next_engine_params.cc.bypass_plcr_profile_generation;
116923 + memcpy(&param->kg_next_engine_params.cc.plcr_profile,
116924 + &compat_param->kg_next_engine_params.cc.plcr_profile,
116925 + sizeof(ioc_fm_pcd_kg_plcr_profile_t));
116926 + }
116927 + else
116928 + memcpy(&param->kg_next_engine_params,
116929 + &compat_param->kg_next_engine_params,
116930 + sizeof(param->kg_next_engine_params));
116931 +
116932 + memcpy(&param->scheme_counter,
116933 + &compat_param->scheme_counter,
116934 + sizeof(ioc_fm_pcd_kg_scheme_counter_t));
116935 + }
116936 + else
116937 + {
116938 + compat_param->modify = param->modify;
116939 +
116940 + /* scm_id */
116941 + if (param->modify)
116942 + compat_param->scm_id.scheme_id = compat_pcd_ptr2id(param->scm_id.scheme_id);
116943 + else
116944 + compat_param->scm_id.relative_scheme_id = param->scm_id.relative_scheme_id;
116945 +
116946 + compat_param->always_direct = param->always_direct;
116947 +
116948 + /* net_env_params */
116949 + compat_param->net_env_params.net_env_id = compat_pcd_ptr2id(param->net_env_params.net_env_id);
116950 + compat_param->net_env_params.num_of_distinction_units = param->net_env_params.num_of_distinction_units;
116951 + memcpy(compat_param->net_env_params.unit_ids, param->net_env_params.unit_ids, IOC_FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS);
116952 +
116953 + compat_param->use_hash = param->use_hash;
116954 + 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));
116955 + compat_param->bypass_fqid_generation = param->bypass_fqid_generation;
116956 + compat_param->base_fqid = param->base_fqid;
116957 +#if DPAA_VERSION >= 11
116958 + compat_param->override_storage_profile =
116959 + param->override_storage_profile;
116960 + compat_param->storage_profile = param->storage_profile;
116961 +#endif
116962 + compat_param->num_of_used_extracted_ors = param->num_of_used_extracted_ors;
116963 + 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));
116964 + compat_param->next_engine = param->next_engine;
116965 +
116966 + /* kg_next_engine_params */
116967 + if (compat_param->next_engine == e_IOC_FM_PCD_CC)
116968 + {
116969 + compat_param->kg_next_engine_params.cc.tree_id = compat_pcd_ptr2id(param->kg_next_engine_params.cc.tree_id);
116970 + compat_param->kg_next_engine_params.cc.grp_id = param->kg_next_engine_params.cc.grp_id;
116971 + compat_param->kg_next_engine_params.cc.plcr_next = param->kg_next_engine_params.cc.plcr_next;
116972 + compat_param->kg_next_engine_params.cc.bypass_plcr_profile_generation
116973 + = param->kg_next_engine_params.cc.bypass_plcr_profile_generation;
116974 + memcpy(&compat_param->kg_next_engine_params.cc.plcr_profile,
116975 + &param->kg_next_engine_params.cc.plcr_profile,
116976 + sizeof(ioc_fm_pcd_kg_plcr_profile_t));
116977 + }
116978 + else
116979 + memcpy(&param->kg_next_engine_params, &compat_param->kg_next_engine_params, sizeof(compat_param->kg_next_engine_params));
116980 +
116981 + memcpy(&compat_param->scheme_counter, &param->scheme_counter, sizeof(ioc_fm_pcd_kg_scheme_counter_t));
116982 +
116983 + compat_param->id = compat_add_ptr2id(param->id, FM_MAP_TYPE_PCD_NODE);
116984 + }
116985 +
116986 + _fm_cpt_dbg(compat," ...->}\n");
116987 +}
116988 +
116989 +void compat_copy_fm_pcd_kg_scheme_spc(
116990 + ioc_compat_fm_pcd_kg_scheme_spc_t *compat_param,
116991 + ioc_fm_pcd_kg_scheme_spc_t *param,
116992 + uint8_t compat)
116993 +{
116994 + if (compat == COMPAT_US_TO_K)
116995 + {
116996 + param->id = compat_pcd_id2ptr(compat_param->id);
116997 + param->val = compat_param->val;
116998 + } else {
116999 + compat_param->id = compat_pcd_ptr2id(param->id);
117000 + compat_param->val = param->val;
117001 + }
117002 +}
117003 +
117004 +
117005 +void compat_copy_fm_pcd_kg_scheme_select(
117006 + ioc_compat_fm_pcd_kg_scheme_select_t *compat_param,
117007 + ioc_fm_pcd_kg_scheme_select_t *param,
117008 + uint8_t compat)
117009 +{
117010 + if (compat == COMPAT_US_TO_K)
117011 + {
117012 + param->direct = compat_param->direct;
117013 + if (param->direct)
117014 + param->scheme_id = compat_pcd_id2ptr(compat_param->scheme_id);
117015 + }
117016 +}
117017 +
117018 +void compat_copy_fm_pcd_kg_schemes_params(
117019 + ioc_compat_fm_pcd_port_schemes_params_t *compat_param,
117020 + ioc_fm_pcd_port_schemes_params_t *param,
117021 + uint8_t compat)
117022 +{
117023 + int k;
117024 +
117025 + if (compat == COMPAT_US_TO_K) {
117026 + param->num_of_schemes = compat_param->num_of_schemes;
117027 + for(k=0; k < compat_param->num_of_schemes; k++)
117028 + param->scheme_ids[k] = compat_pcd_id2ptr(compat_param->scheme_ids[k]);
117029 + }
117030 +}
117031 +
117032 +void compat_copy_fm_port_pcd_cc(
117033 + ioc_compat_fm_port_pcd_cc_params_t *compat_cc_params ,
117034 + ioc_fm_port_pcd_cc_params_t *p_cc_params,
117035 + uint8_t compat)
117036 +{
117037 + if (compat == COMPAT_US_TO_K){
117038 + p_cc_params->cc_tree_id = compat_pcd_id2ptr(compat_cc_params->cc_tree_id);
117039 + }
117040 +}
117041 +
117042 +void compat_copy_fm_port_pcd_kg(
117043 + ioc_compat_fm_port_pcd_kg_params_t *compat_param,
117044 + ioc_fm_port_pcd_kg_params_t *param,
117045 + uint8_t compat)
117046 +{
117047 + if (compat == COMPAT_US_TO_K){
117048 + uint8_t k;
117049 +
117050 + param->num_of_schemes = compat_param->num_of_schemes;
117051 + for(k=0; k<compat_param->num_of_schemes; k++)
117052 + param->scheme_ids[k] = compat_pcd_id2ptr(compat_param->scheme_ids[k]);
117053 +
117054 + param->direct_scheme = compat_param->direct_scheme;
117055 + if (param->direct_scheme)
117056 + param->direct_scheme_id = compat_pcd_id2ptr(compat_param->direct_scheme_id);
117057 + }
117058 +}
117059 +
117060 +void compat_copy_fm_port_pcd(
117061 + ioc_compat_fm_port_pcd_params_t *compat_param,
117062 + ioc_fm_port_pcd_params_t *param,
117063 + uint8_t compat)
117064 +{
117065 + if (compat == COMPAT_US_TO_K)
117066 + {
117067 + ioc_fm_port_pcd_prs_params_t *same_port_pcd_prs_params;
117068 + ioc_compat_fm_port_pcd_cc_params_t *compat_port_pcd_cc_params;
117069 + ioc_compat_fm_port_pcd_kg_params_t *compat_port_pcd_kg_params;
117070 + ioc_compat_fm_port_pcd_plcr_params_t *compat_port_pcd_plcr_params;
117071 +
117072 + same_port_pcd_prs_params = (ioc_fm_port_pcd_prs_params_t *) (compat_param + 1);
117073 + compat_port_pcd_cc_params = (ioc_compat_fm_port_pcd_cc_params_t *) (same_port_pcd_prs_params + 1);
117074 + compat_port_pcd_kg_params = (ioc_compat_fm_port_pcd_kg_params_t *) (compat_port_pcd_cc_params + 1);
117075 + compat_port_pcd_plcr_params = (ioc_compat_fm_port_pcd_plcr_params_t *) (compat_port_pcd_kg_params + 1);
117076 +
117077 + _fm_cpt_dbg(compat,"\n param->p_prs_params=%p \n", param->p_prs_params);
117078 + _fm_cpt_dbg(compat," param->p_cc_params=%p \n", param->p_cc_params);
117079 + _fm_cpt_dbg(compat," param->p_kg_params=%p \n", param->p_kg_params);
117080 + _fm_cpt_dbg(compat," param->p_plcr_params=%p \n", param->p_plcr_params);
117081 + _fm_cpt_dbg(compat," param->p_ip_reassembly_manip=%p \n", param->p_ip_reassembly_manip);
117082 +#if (DPAA_VERSION >= 11)
117083 + _fm_cpt_dbg(compat," param->p_capwap_reassembly_manip=%p \n", param->p_capwap_reassembly_manip);
117084 +#endif
117085 + param->pcd_support = compat_param->pcd_support;
117086 + param->net_env_id = compat_pcd_id2ptr(compat_param->net_env_id);
117087 +
117088 + if (param->p_cc_params)
117089 + compat_copy_fm_port_pcd_cc(compat_port_pcd_cc_params, param->p_cc_params, COMPAT_US_TO_K);
117090 + if (param->p_kg_params)
117091 + compat_copy_fm_port_pcd_kg(compat_port_pcd_kg_params, param->p_kg_params, COMPAT_US_TO_K);
117092 + if (param->p_plcr_params)
117093 + param->p_plcr_params->plcr_profile_id = compat_pcd_id2ptr(compat_port_pcd_plcr_params->plcr_profile_id);
117094 + param->p_ip_reassembly_manip = compat_pcd_id2ptr(compat_param->p_ip_reassembly_manip);
117095 +#if (DPAA_VERSION >= 11)
117096 + param->p_capwap_reassembly_manip = compat_pcd_id2ptr(compat_param->p_capwap_reassembly_manip);
117097 +#endif
117098 + }
117099 +}
117100 +
117101 +void compat_copy_fm_port_pcd_modify_tree(
117102 + ioc_compat_fm_obj_t *compat_id,
117103 + ioc_fm_obj_t *id,
117104 + uint8_t compat)
117105 +{
117106 + if (compat == COMPAT_US_TO_K)
117107 + id->obj = compat_pcd_id2ptr(compat_id->obj);
117108 +}
117109 +
117110 +#if (DPAA_VERSION >= 11)
117111 +void compat_copy_fm_port_vsp_alloc_params(
117112 + ioc_compat_fm_port_vsp_alloc_params_t *compat_param,
117113 + ioc_fm_port_vsp_alloc_params_t *param,
117114 + uint8_t compat)
117115 +{
117116 + if (compat == COMPAT_US_TO_K)
117117 + {
117118 + _fm_cpt_dbg(compat," param->p_fm_tx_port=%p \n", param->p_fm_tx_port);
117119 +
117120 + param->dflt_relative_id = compat_param->dflt_relative_id;
117121 + param->num_of_profiles = compat_param->num_of_profiles;
117122 + param->p_fm_tx_port = compat_pcd_id2ptr(compat_param->p_fm_tx_port);
117123 + }
117124 +}
117125 +#endif /* (DPAA_VERSION >= 11) */
117126 +
117127 +void compat_copy_fm_pcd_cc_tbl_get_stats(
117128 + ioc_compat_fm_pcd_cc_tbl_get_stats_t *compat_param,
117129 + ioc_fm_pcd_cc_tbl_get_stats_t *param,
117130 + uint8_t compat)
117131 +{
117132 + if (compat == COMPAT_US_TO_K)
117133 + {
117134 + param->id = compat_pcd_id2ptr(compat_param->id);
117135 + param->key_index = compat_param->key_index;
117136 + memcpy(&param->statistics, &compat_param->statistics, sizeof(ioc_fm_pcd_cc_key_statistics_t));
117137 + } else {
117138 + compat_param->id = compat_add_ptr2id(param->id, FM_MAP_TYPE_PCD_NODE);
117139 + compat_param->key_index = param->key_index;
117140 + memcpy(&compat_param->statistics, &param->statistics, sizeof(ioc_fm_pcd_cc_key_statistics_t));
117141 + }
117142 +}
117143 +
117144 +
117145 +void compat_copy_fm_pcd_net_env(
117146 + ioc_compat_fm_pcd_net_env_params_t *compat_param,
117147 + ioc_fm_pcd_net_env_params_t *param,
117148 + uint8_t compat)
117149 +{
117150 + if (compat == COMPAT_US_TO_K)
117151 + {
117152 + param->num_of_distinction_units = compat_param->num_of_distinction_units;
117153 + memcpy(param->units, compat_param->units, sizeof(ioc_fm_pcd_distinction_unit_t)*IOC_FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS);
117154 + param->id = NULL; /* to avoid passing garbage to the kernel */
117155 + }
117156 + else
117157 + {
117158 + compat_param->num_of_distinction_units = param->num_of_distinction_units;
117159 + memcpy(compat_param->units, param->units, sizeof(ioc_fm_pcd_distinction_unit_t)*IOC_FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS);
117160 +
117161 + compat_param->id = compat_add_ptr2id(param->id, FM_MAP_TYPE_PCD_NODE);
117162 + }
117163 +}
117164 +
117165 +void compat_copy_fm_pcd_cc_node_modify_key(
117166 + ioc_compat_fm_pcd_cc_node_modify_key_params_t *compat_param,
117167 + ioc_fm_pcd_cc_node_modify_key_params_t *param,
117168 + uint8_t compat)
117169 +{
117170 + if (compat == COMPAT_US_TO_K)
117171 + {
117172 + param->key_indx = compat_param->key_indx;
117173 + param->key_size = compat_param->key_size;
117174 + param->p_key = (uint8_t *)compat_ptr(compat_param->p_key);
117175 + _fm_cpt_dbg(compat," param->p_key = %p \n", param->p_key);
117176 + param->p_mask = (uint8_t *)compat_ptr(compat_param->p_mask);
117177 + _fm_cpt_dbg(compat," param->p_mask = %p\n", param->p_mask);
117178 + param->id = compat_pcd_id2ptr(compat_param->id);
117179 + _fm_cpt_dbg(compat," param->id = %p \n", param->id);
117180 + }
117181 + else
117182 + {
117183 + compat_param->key_indx = param->key_indx;
117184 + compat_param->key_size = param->key_size;
117185 + compat_param->p_key = ptr_to_compat((void *)param->p_key);
117186 + compat_param->p_mask = ptr_to_compat((void *)param->p_mask);
117187 +
117188 + compat_param->id = compat_add_ptr2id(param->id, FM_MAP_TYPE_PCD_NODE);
117189 + }
117190 +}
117191 +
117192 +void compat_copy_keys(
117193 + ioc_compat_keys_params_t *compat_param,
117194 + ioc_keys_params_t *param,
117195 + uint8_t compat)
117196 +{
117197 + int k = 0;
117198 +
117199 + _fm_cpt_dbg(compat," {->...\n");
117200 +
117201 + if (compat == COMPAT_US_TO_K) {
117202 + param->max_num_of_keys = compat_param->max_num_of_keys;
117203 + param->mask_support = compat_param->mask_support;
117204 + param->statistics_mode = compat_param->statistics_mode;
117205 + param->num_of_keys = compat_param->num_of_keys;
117206 + param->key_size = compat_param->key_size;
117207 +#if (DPAA_VERSION >= 11)
117208 + memcpy(&param->frame_length_ranges,
117209 + &compat_param->frame_length_ranges,
117210 + sizeof(param->frame_length_ranges[0]) *
117211 + IOC_FM_PCD_CC_STATS_MAX_NUM_OF_FLR);
117212 +#endif /* (DPAA_VERSION >= 11) */
117213 + }
117214 + else {
117215 + compat_param->max_num_of_keys = param->max_num_of_keys;
117216 + compat_param->mask_support = param->mask_support;
117217 + compat_param->statistics_mode = param->statistics_mode;
117218 + compat_param->num_of_keys = param->num_of_keys;
117219 + compat_param->key_size = param->key_size;
117220 +#if (DPAA_VERSION >= 11)
117221 + memcpy(&compat_param->frame_length_ranges,
117222 + &param->frame_length_ranges,
117223 + sizeof(compat_param->frame_length_ranges[0]) *
117224 + IOC_FM_PCD_CC_STATS_MAX_NUM_OF_FLR);
117225 +#endif /* (DPAA_VERSION >= 11) */
117226 + }
117227 +
117228 + for (k=0; k < IOC_FM_PCD_MAX_NUM_OF_KEYS; k++)
117229 + compat_copy_fm_pcd_cc_key(
117230 + &compat_param->key_params[k],
117231 + &param->key_params[k],
117232 + compat);
117233 +
117234 + compat_copy_fm_pcd_cc_next_engine(
117235 + &compat_param->cc_next_engine_params_for_miss,
117236 + &param->cc_next_engine_params_for_miss,
117237 + compat);
117238 +
117239 + _fm_cpt_dbg(compat," ...->}\n");
117240 +}
117241 +
117242 +void compat_copy_fm_pcd_cc_node(
117243 + ioc_compat_fm_pcd_cc_node_params_t *compat_param,
117244 + ioc_fm_pcd_cc_node_params_t *param,
117245 + uint8_t compat)
117246 +{
117247 + _fm_cpt_dbg(compat," {->...\n");
117248 +
117249 + if (compat == COMPAT_US_TO_K)
117250 + memcpy(&param->extract_cc_params, &compat_param->extract_cc_params, sizeof(ioc_fm_pcd_extract_entry_t));
117251 +
117252 + else
117253 + {
117254 + compat_copy_keys(&compat_param->keys_params, &param->keys_params, compat);
117255 +
117256 + compat_param->id = compat_add_ptr2id(param->id, FM_MAP_TYPE_PCD_NODE);
117257 + _fm_cpt_dbg(compat," param->id = %p \n", param->id);
117258 + }
117259 +
117260 + compat_copy_keys(&compat_param->keys_params, &param->keys_params, compat);
117261 +
117262 + _fm_cpt_dbg(compat," ...->}\n");
117263 +}
117264 +
117265 +void compat_fm_pcd_manip_set_node(
117266 + ioc_compat_fm_pcd_manip_params_t *compat_param,
117267 + ioc_fm_pcd_manip_params_t *param,
117268 + uint8_t compat)
117269 +{
117270 + if (compat == COMPAT_US_TO_K) {
117271 + param->type = compat_param->type;
117272 + switch (param->type) {
117273 + case e_IOC_FM_PCD_MANIP_HDR:
117274 + param->u.hdr.rmv = compat_param->u.hdr.rmv;
117275 + memcpy(&param->u.hdr.rmv_params,
117276 + &compat_param->u.hdr.rmv_params,
117277 + sizeof(param->u.hdr.rmv_params));
117278 +
117279 + param->u.hdr.insrt = compat_param->u.hdr.insrt;
117280 + param->u.hdr.insrt_params.type =
117281 + compat_param->u.hdr.insrt_params.type;
117282 + switch (compat_param->u.hdr.insrt_params.type)
117283 + {
117284 + case e_IOC_FM_PCD_MANIP_INSRT_GENERIC:
117285 + param->u.hdr.insrt_params.u.generic.offset =
117286 + compat_param->u.hdr.insrt_params.u.generic.offset;
117287 + param->u.hdr.insrt_params.u.generic.size =
117288 + compat_param->u.hdr.insrt_params.u.generic.size;
117289 + param->u.hdr.insrt_params.u.generic.replace =
117290 + compat_param->u.hdr.insrt_params.u.generic.replace;
117291 + param->u.hdr.insrt_params.u.generic.p_data =
117292 + compat_ptr(compat_param->u.hdr.insrt_params.u.generic.p_data);
117293 + break;
117294 + case e_IOC_FM_PCD_MANIP_INSRT_BY_HDR:
117295 + param->u.hdr.insrt_params.u.by_hdr.type =
117296 + compat_param->u.hdr.insrt_params.u.by_hdr.type;
117297 + param->u.hdr.insrt_params.u.by_hdr.u.specific_l2_params.specific_l2 =
117298 + compat_param->u.hdr.insrt_params.u.by_hdr.u.specific_l2_params.specific_l2;
117299 + param->u.hdr.insrt_params.u.by_hdr.u.specific_l2_params.update =
117300 + compat_param->u.hdr.insrt_params.u.by_hdr.u.specific_l2_params.update;
117301 + param->u.hdr.insrt_params.u.by_hdr.u.specific_l2_params.size =
117302 + compat_param->u.hdr.insrt_params.u.by_hdr.u.specific_l2_params.size;
117303 + param->u.hdr.insrt_params.u.by_hdr.u.specific_l2_params.p_data =
117304 + compat_ptr(compat_param->u.hdr.insrt_params.u.by_hdr.u.specific_l2_params.p_data);
117305 + break;
117306 + default:
117307 + _fm_cpt_err("Unsupported type: %d", compat_param->u.hdr.insrt_params.type);
117308 + }
117309 +
117310 + param->u.hdr.field_update = compat_param->u.hdr.field_update;
117311 + memcpy(&param->u.hdr.field_update_params,
117312 + &compat_param->u.hdr.field_update_params,
117313 + sizeof(param->u.hdr.field_update_params));
117314 +
117315 + param->u.hdr.custom = compat_param->u.hdr.custom;
117316 + memcpy(&param->u.hdr.custom_params,
117317 + &compat_param->u.hdr.custom_params,
117318 + sizeof(param->u.hdr.custom_params));
117319 +
117320 + param->u.hdr.dont_parse_after_manip =
117321 + compat_param->u.hdr.dont_parse_after_manip;
117322 + break;
117323 + case e_IOC_FM_PCD_MANIP_REASSEM:
117324 + memcpy(&param->u.reassem, &compat_param->u.reassem, sizeof(param->u.reassem));
117325 + break;
117326 + case e_IOC_FM_PCD_MANIP_FRAG:
117327 + memcpy(&param->u.frag, &compat_param->u.frag, sizeof(param->u.frag));
117328 + break;
117329 + case e_IOC_FM_PCD_MANIP_SPECIAL_OFFLOAD:
117330 + memcpy(&param->u.special_offload,
117331 + &compat_param->u.special_offload,
117332 + sizeof(param->u.special_offload));
117333 + break;
117334 + }
117335 +
117336 + param->p_next_manip = compat_pcd_id2ptr(compat_param->p_next_manip);
117337 + param->id = compat_pcd_id2ptr(compat_param->id);
117338 + }
117339 + else {
117340 + compat_param->type = param->type;
117341 + memcpy(&compat_param->u, &param->u, sizeof(compat_param->u));
117342 +
117343 + if (param->type == e_IOC_FM_PCD_MANIP_HDR &&
117344 + param->u.hdr.insrt_params.type == e_IOC_FM_PCD_MANIP_INSRT_GENERIC)
117345 + compat_param->u.hdr.insrt_params.u.generic.p_data =
117346 + ptr_to_compat(param->u.hdr.insrt_params.u.generic.p_data);
117347 +
117348 + compat_param->p_next_manip = compat_pcd_ptr2id(param->id);
117349 + /* ... should be one that was added previously by the very call to
117350 + compat_add_ptr2id() below: */
117351 + compat_param->id = compat_add_ptr2id(param->id, FM_MAP_TYPE_PCD_NODE);
117352 + }
117353 +}
117354 +
117355 +void compat_copy_fm_pcd_manip_get_stats(
117356 + ioc_compat_fm_pcd_manip_get_stats_t *compat_param,
117357 + ioc_fm_pcd_manip_get_stats_t *param,
117358 + uint8_t compat)
117359 +{
117360 + _fm_cpt_dbg (compat, " {->...\n");
117361 +
117362 + if (compat == COMPAT_US_TO_K)
117363 + {
117364 + param->id = compat_pcd_id2ptr(compat_param->id);
117365 + memcpy(&param->stats, &compat_param->stats,
117366 + sizeof(ioc_fm_pcd_manip_stats_t));
117367 + }
117368 + else
117369 + {
117370 + compat_param->id = compat_add_ptr2id(param->id,
117371 + FM_MAP_TYPE_PCD_NODE);
117372 + memcpy(&compat_param->stats, &param->stats,
117373 + sizeof(ioc_fm_pcd_manip_stats_t));
117374 + }
117375 +
117376 + _fm_cpt_dbg (compat, " ...->}\n");
117377 +}
117378 +
117379 +#if (DPAA_VERSION >= 11)
117380 +void compat_copy_fm_pcd_frm_replic_group_params(
117381 + ioc_compat_fm_pcd_frm_replic_group_params_t *compat_param,
117382 + ioc_fm_pcd_frm_replic_group_params_t *param,
117383 + uint8_t compat)
117384 +{
117385 + int k;
117386 +
117387 + _fm_cpt_dbg (compat, " {->...\n");
117388 +
117389 + if (compat == COMPAT_US_TO_K)
117390 + {
117391 + param->max_num_of_entries = compat_param->max_num_of_entries;
117392 + param->num_of_entries = compat_param->num_of_entries;
117393 + param->id = compat_pcd_id2ptr(compat_param->id);
117394 + }
117395 + else
117396 + {
117397 + compat_param->max_num_of_entries = param->max_num_of_entries;
117398 + compat_param->num_of_entries = param->num_of_entries;
117399 + compat_param->id = compat_add_ptr2id(param->id,
117400 + FM_MAP_TYPE_PCD_NODE);
117401 + }
117402 +
117403 + for (k=0; k < IOC_FM_PCD_FRM_REPLIC_MAX_NUM_OF_ENTRIES; k++)
117404 + compat_copy_fm_pcd_cc_next_engine(
117405 + &compat_param->next_engine_params[k],
117406 + &param->next_engine_params[k],
117407 + compat);
117408 +
117409 + _fm_cpt_dbg (compat, " ...->}\n");
117410 +}
117411 +
117412 +void compat_copy_fm_pcd_frm_replic_member(
117413 + ioc_compat_fm_pcd_frm_replic_member_t *compat_param,
117414 + ioc_fm_pcd_frm_replic_member_t *param,
117415 + uint8_t compat)
117416 +{
117417 + _fm_cpt_dbg (compat, " {->...\n");
117418 +
117419 + if (compat == COMPAT_US_TO_K)
117420 + {
117421 + param->h_replic_group = compat_pcd_id2ptr(compat_param->h_replic_group);
117422 + param->member_index = compat_param->member_index;
117423 + }
117424 +
117425 + _fm_cpt_dbg (compat, " ...->}\n");
117426 +}
117427 +
117428 +void compat_copy_fm_pcd_frm_replic_member_params(
117429 + ioc_compat_fm_pcd_frm_replic_member_params_t *compat_param,
117430 + ioc_fm_pcd_frm_replic_member_params_t *param,
117431 + uint8_t compat)
117432 +{
117433 + _fm_cpt_dbg (compat, " {->...\n");
117434 +
117435 + compat_copy_fm_pcd_frm_replic_member(&compat_param->member,
117436 + &param->member, compat);
117437 +
117438 + compat_copy_fm_pcd_cc_next_engine(&compat_param->next_engine_params,
117439 + &param->next_engine_params, compat);
117440 +
117441 + _fm_cpt_dbg (compat, " ...->}\n");
117442 +}
117443 +
117444 +void compat_copy_fm_vsp_params(
117445 + ioc_compat_fm_vsp_params_t *compat_param,
117446 + ioc_fm_vsp_params_t *param,
117447 + uint8_t compat)
117448 +{
117449 + _fm_cpt_dbg (compat, " {->...\n");
117450 +
117451 + if (compat == COMPAT_US_TO_K)
117452 + {
117453 + memcpy(&param->ext_buf_pools, &compat_param->ext_buf_pools, sizeof(ioc_fm_ext_pools));
117454 + param->liodn_offset = compat_param->liodn_offset;
117455 + param->port_params.port_id = compat_param->port_params.port_id;
117456 + param->port_params.port_type = compat_param->port_params.port_type;
117457 + param->relative_profile_id = compat_param->relative_profile_id;
117458 + }
117459 + else
117460 + {
117461 + memcpy(&compat_param->ext_buf_pools, &param->ext_buf_pools, sizeof(ioc_fm_ext_pools));
117462 + compat_param->liodn_offset = param->liodn_offset;
117463 + compat_param->port_params.port_id = param->port_params.port_id;
117464 + compat_param->port_params.port_type = param->port_params.port_type;
117465 + compat_param->relative_profile_id = param->relative_profile_id;
117466 + compat_param->id = compat_add_ptr2id(param->id, FM_MAP_TYPE_PCD_NODE);
117467 + }
117468 +
117469 + _fm_cpt_dbg (compat, " ...->}\n");
117470 +}
117471 +
117472 +void compat_copy_fm_buf_pool_depletion_params(
117473 + ioc_compat_fm_buf_pool_depletion_params_t *compat_param,
117474 + ioc_fm_buf_pool_depletion_params_t *param,
117475 + uint8_t compat)
117476 +{
117477 + _fm_cpt_dbg (compat, " {->...\n");
117478 +
117479 + if (compat == COMPAT_US_TO_K)
117480 + {
117481 + param->p_fm_vsp = compat_pcd_id2ptr(compat_param->p_fm_vsp);
117482 + memcpy(&param->fm_buf_pool_depletion,
117483 + &compat_param->fm_buf_pool_depletion,
117484 + sizeof(ioc_fm_buf_pool_depletion_t));
117485 + }
117486 +
117487 + _fm_cpt_dbg (compat, " ...->}\n");
117488 +}
117489 +
117490 +void compat_copy_fm_buffer_prefix_content_params(
117491 + ioc_compat_fm_buffer_prefix_content_params_t *compat_param,
117492 + ioc_fm_buffer_prefix_content_params_t *param,
117493 + uint8_t compat)
117494 +{
117495 + _fm_cpt_dbg (compat, " {->...\n");
117496 +
117497 + if (compat == COMPAT_US_TO_K)
117498 + {
117499 + param->p_fm_vsp = compat_pcd_id2ptr(compat_param->p_fm_vsp);
117500 + memcpy(&param->fm_buffer_prefix_content,
117501 + &compat_param->fm_buffer_prefix_content,
117502 + sizeof(ioc_fm_buffer_prefix_content_t));
117503 + }
117504 +
117505 + _fm_cpt_dbg (compat, " ...->}\n");
117506 +}
117507 +
117508 +void compat_copy_fm_vsp_config_no_sg_params(
117509 + ioc_compat_fm_vsp_config_no_sg_params_t *compat_param,
117510 + ioc_fm_vsp_config_no_sg_params_t *param,
117511 + uint8_t compat)
117512 +{
117513 + _fm_cpt_dbg (compat, " {->...\n");
117514 +
117515 + if (compat == COMPAT_US_TO_K)
117516 + {
117517 + param->p_fm_vsp = compat_pcd_id2ptr(compat_param->p_fm_vsp);
117518 + param->no_sg = compat_param->no_sg;
117519 + }
117520 +
117521 + _fm_cpt_dbg (compat, " ...->}\n");
117522 +}
117523 +
117524 +void compat_copy_fm_vsp_prs_result_params(
117525 + ioc_compat_fm_vsp_prs_result_params_t *compat_param,
117526 + ioc_fm_vsp_prs_result_params_t *param,
117527 + uint8_t compat)
117528 +{
117529 + _fm_cpt_dbg (compat, " {->...\n");
117530 +
117531 + if (compat == COMPAT_US_TO_K)
117532 + {
117533 + param->p_fm_vsp = compat_pcd_id2ptr(compat_param->p_fm_vsp);
117534 + /* p_data is an user-space pointer that needs to remain unmodified */
117535 + param->p_data = (void *)(unsigned long long)compat_param->p_data;
117536 + }
117537 + else
117538 + {
117539 + compat_param->p_fm_vsp = compat_pcd_ptr2id(param->p_fm_vsp);
117540 + /* p_data is an user-space pointer that needs to remain unmodified */
117541 + compat_param->p_data = (compat_uptr_t)((unsigned long long)param->p_data & 0xFFFFFFFF);
117542 + }
117543 +
117544 + _fm_cpt_dbg (compat, " ...->}\n");
117545 +}
117546 +#endif /* (DPAA_VERSION >= 11) */
117547 --- /dev/null
117548 +++ b/drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_ioctls_fm_compat.h
117549 @@ -0,0 +1,755 @@
117550 +/*
117551 + * Copyright 2008-2012 Freescale Semiconductor Inc.
117552 + *
117553 + * Redistribution and use in source and binary forms, with or without
117554 + * modification, are permitted provided that the following conditions are met:
117555 + * * Redistributions of source code must retain the above copyright
117556 + * notice, this list of conditions and the following disclaimer.
117557 + * * Redistributions in binary form must reproduce the above copyright
117558 + * notice, this list of conditions and the following disclaimer in the
117559 + * documentation and/or other materials provided with the distribution.
117560 + * * Neither the name of Freescale Semiconductor nor the
117561 + * names of its contributors may be used to endorse or promote products
117562 + * derived from this software without specific prior written permission.
117563 + *
117564 + *
117565 + * ALTERNATIVELY, this software may be distributed under the terms of the
117566 + * GNU General Public License ("GPL") as published by the Free Software
117567 + * Foundation, either version 2 of that License or (at your option) any
117568 + * later version.
117569 + *
117570 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
117571 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
117572 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
117573 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
117574 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
117575 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
117576 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
117577 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
117578 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
117579 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
117580 + */
117581 +
117582 +/*
117583 + @File lnxwrp_ioctls_fm_compat.h
117584 +
117585 + @Description FM PCD compat structures definition.
117586 +
117587 +*/
117588 +
117589 +#ifndef __FM_COMPAT_IOCTLS_H
117590 +#define __FM_COMPAT_IOCTLS_H
117591 +
117592 +#include <linux/compat.h>
117593 +
117594 +#define COMPAT_K_TO_US 0 /* copy from Kernel to User */
117595 +#define COMPAT_US_TO_K 1 /* copy from User to Kernel */
117596 +#define COMPAT_GENERIC 2
117597 +
117598 +#define COMPAT_COPY_K2US(dest, src, type) compat_copy_##type(src, dest, 0)
117599 +#define COMPAT_COPY_US2K(dest, src, type) compat_copy_##type(dest, src, 1)
117600 +
117601 +/* mapping kernel pointers w/ UserSpace id's { */
117602 +/* Because compat_ptr(ptr_to_compat(X)) != X, this way we cannot exchange pointers
117603 + back and forth (US - KS). compat_ptr is a cast and pointers are broken. */
117604 +#define COMPAT_PTR2ID_ARRAY_MAX (512+1) /* first location is not used */
117605 +#define COMPAT_PTR2ID_WATERMARK 0xface0000
117606 +#define COMPAT_PTR2ID_WM_MASK 0xffff0000
117607 +
117608 +/* define it for debug trace */
117609 +/*#define FM_COMPAT_DBG*/
117610 +
117611 +#define _fm_cpt_prk(stage, format, arg...) \
117612 + printk(stage "fm_cpt (cpu:%u): " format, raw_smp_processor_id(), ##arg)
117613 +
117614 +#define _fm_cpt_inf(format, arg...) _fm_cpt_prk(KERN_INFO, format, ##arg)
117615 +#define _fm_cpt_wrn(format, arg...) _fm_cpt_prk(KERN_WARNING, format, ##arg)
117616 +#define _fm_cpt_err(format, arg...) _fm_cpt_prk(KERN_ERR, format, ##arg)
117617 +
117618 +/* used for compat IOCTL debugging */
117619 +#if defined(FM_COMPAT_DBG)
117620 + #define _fm_cpt_dbg(from, format, arg...) \
117621 + do{ \
117622 + if (from == COMPAT_US_TO_K) \
117623 + printk("fm_cpt to KS [%s:%u](cpu:%u) - " format, \
117624 + __func__, __LINE__, raw_smp_processor_id(), ##arg); \
117625 + else if (from == COMPAT_K_TO_US) \
117626 + printk("fm_cpt to US [%s:%u](cpu:%u) - " format, \
117627 + __func__, __LINE__, raw_smp_processor_id(), ##arg); \
117628 + else \
117629 + printk("fm_cpt [%s:%u](cpu:%u) - " format, \
117630 + __func__, __LINE__, raw_smp_processor_id(), ##arg); \
117631 + }while(0)
117632 +#else
117633 +# define _fm_cpt_dbg(arg...)
117634 +#endif
117635 +
117636 +/*TODO: per FMan module:
117637 + *
117638 + * Parser: FM_MAP_TYPE_PARSER_NODE,
117639 + * Kg: FM_MAP_TYPE_KG_NODE,
117640 + * Policer: FM_MAP_TYPE_POLICER_NODE
117641 + * Manip: FM_MAP_TYPE_MANIP_NODE
117642 + **/
117643 +enum fm_map_node_type {
117644 + FM_MAP_TYPE_UNSPEC = 0,
117645 + FM_MAP_TYPE_PCD_NODE,
117646 +
117647 + /* add types here, update the policy */
117648 +
117649 + __FM_MAP_TYPE_AFTER_LAST,
117650 + FM_MAP_TYPE_MAX = __FM_MAP_TYPE_AFTER_LAST - 1
117651 +};
117652 +
117653 +void compat_del_ptr2id(void *p, enum fm_map_node_type);
117654 +compat_uptr_t compat_add_ptr2id(void *p, enum fm_map_node_type);
117655 +compat_uptr_t compat_get_ptr2id(void *p, enum fm_map_node_type);
117656 +void *compat_get_id2ptr(compat_uptr_t comp, enum fm_map_node_type);
117657 +
117658 +static inline compat_uptr_t compat_pcd_ptr2id(void *ptr) {
117659 + return (ptr)? compat_get_ptr2id(ptr, FM_MAP_TYPE_PCD_NODE)
117660 + : (compat_uptr_t) 0;
117661 +}
117662 +
117663 +static inline void *compat_pcd_id2ptr(compat_uptr_t id) {
117664 + return (id) ? compat_get_id2ptr(id, FM_MAP_TYPE_PCD_NODE)
117665 + : NULL;
117666 +}
117667 +
117668 +/* other similar inlines may be added as new nodes are added
117669 + to enum fm_map_node_type above... */
117670 +/* } mapping kernel pointers w/ UserSpace id's */
117671 +
117672 +/* pcd compat structures { */
117673 +typedef struct ioc_compat_fm_pcd_cc_node_remove_key_params_t {
117674 + compat_uptr_t id;
117675 + uint16_t key_indx;
117676 +} ioc_compat_fm_pcd_cc_node_remove_key_params_t;
117677 +
117678 +typedef union ioc_compat_fm_pcd_plcr_next_engine_params_u {
117679 + ioc_fm_pcd_done_action action;
117680 + compat_uptr_t p_profile;
117681 + compat_uptr_t p_direct_scheme;
117682 +} ioc_compat_fm_pcd_plcr_next_engine_params_u;
117683 +
117684 +typedef struct ioc_compat_fm_pcd_plcr_profile_params_t {
117685 + bool modify;
117686 + union {
117687 + struct {
117688 + ioc_fm_pcd_profile_type_selection profile_type;
117689 + compat_uptr_t p_fm_port;
117690 + uint16_t relative_profile_id;
117691 + } new_params;
117692 + compat_uptr_t p_profile;
117693 + } profile_select;
117694 + ioc_fm_pcd_plcr_algorithm_selection alg_selection;
117695 + ioc_fm_pcd_plcr_color_mode color_mode;
117696 +
117697 + union {
117698 + ioc_fm_pcd_plcr_color dflt_color;
117699 + ioc_fm_pcd_plcr_color override;
117700 + } color;
117701 +
117702 + ioc_fm_pcd_plcr_non_passthrough_alg_param_t non_passthrough_alg_param;
117703 +
117704 + ioc_fm_pcd_engine next_engine_on_green;
117705 + ioc_compat_fm_pcd_plcr_next_engine_params_u params_on_green;
117706 +
117707 + ioc_fm_pcd_engine next_engine_on_yellow;
117708 + ioc_compat_fm_pcd_plcr_next_engine_params_u params_on_yellow;
117709 +
117710 + ioc_fm_pcd_engine next_engine_on_red;
117711 + ioc_compat_fm_pcd_plcr_next_engine_params_u params_on_red;
117712 +
117713 + bool trap_profile_on_flow_A;
117714 + bool trap_profile_on_flow_B;
117715 + bool trap_profile_on_flow_C;
117716 + compat_uptr_t id;
117717 +} ioc_compat_fm_pcd_plcr_profile_params_t;
117718 +
117719 +typedef struct ioc_compat_fm_obj_t {
117720 + compat_uptr_t obj;
117721 +} ioc_compat_fm_obj_t;
117722 +
117723 +typedef struct ioc_compat_fm_pcd_kg_scheme_select_t {
117724 + bool direct;
117725 + compat_uptr_t scheme_id;
117726 +} ioc_compat_fm_pcd_kg_scheme_select_t;
117727 +
117728 +typedef struct ioc_compat_fm_pcd_port_schemes_params_t {
117729 + uint8_t num_of_schemes;
117730 + compat_uptr_t scheme_ids[FM_PCD_KG_NUM_OF_SCHEMES];
117731 +} ioc_compat_fm_pcd_port_schemes_params_t;
117732 +
117733 +#if (DPAA_VERSION >= 11)
117734 +typedef struct ioc_compat_fm_port_vsp_alloc_params_t {
117735 + uint8_t num_of_profiles; /**< Number of Virtual Storage Profiles */
117736 + uint8_t dflt_relative_id; /**< The default Virtual-Storage-Profile-id dedicated to Rx/OP port
117737 + The same default Virtual-Storage-Profile-id will be for coupled Tx port
117738 + if relevant function called for Rx port */
117739 + compat_uptr_t p_fm_tx_port; /**< Handle to coupled Tx Port; not relevant for OP port. */
117740 +}ioc_compat_fm_port_vsp_alloc_params_t;
117741 +#endif /* (DPAA_VERSION >= 11) */
117742 +
117743 +typedef struct ioc_compat_fm_pcd_net_env_params_t {
117744 + uint8_t num_of_distinction_units;
117745 + ioc_fm_pcd_distinction_unit_t units[IOC_FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS]; /* same structure*/
117746 + compat_uptr_t id;
117747 +} ioc_compat_fm_pcd_net_env_params_t;
117748 +
117749 +typedef struct ioc_compat_fm_pcd_prs_sw_params_t {
117750 + bool override;
117751 + uint32_t size;
117752 + uint16_t base;
117753 + compat_uptr_t p_code;
117754 + uint32_t sw_prs_data_params[IOC_FM_PCD_PRS_NUM_OF_HDRS];
117755 + uint8_t num_of_labels;
117756 + ioc_fm_pcd_prs_label_params_t labels_table[IOC_FM_PCD_PRS_NUM_OF_LABELS];
117757 +} ioc_compat_fm_pcd_prs_sw_params_t;
117758 +
117759 +typedef struct ioc_compat_fm_pcd_cc_next_kg_params_t {
117760 + bool override_fqid;
117761 + uint32_t new_fqid;
117762 +#if DPAA_VERSION >= 11
117763 + uint8_t new_relative_storage_profile_id;
117764 +#endif
117765 + compat_uptr_t p_direct_scheme;
117766 +} ioc_compat_fm_pcd_cc_next_kg_params_t;
117767 +
117768 +typedef struct ioc_compat_fm_pcd_cc_next_cc_params_t {
117769 + compat_uptr_t cc_node_id;
117770 +} ioc_compat_fm_pcd_cc_next_cc_params_t;
117771 +
117772 +#if DPAA_VERSION >= 11
117773 +typedef struct ioc_compat_fm_pcd_cc_next_fr_params_t {
117774 + compat_uptr_t frm_replic_id;
117775 +} ioc_compat_fm_pcd_cc_next_fr_params_t;
117776 +#endif /* DPAA_VERSION >= 11 */
117777 +
117778 +typedef struct ioc_compat_fm_pcd_cc_next_engine_params_t {
117779 + ioc_fm_pcd_engine next_engine;
117780 + union {
117781 + ioc_compat_fm_pcd_cc_next_cc_params_t cc_params; /**< compat structure*/
117782 + ioc_fm_pcd_cc_next_plcr_params_t plcr_params; /**< same structure*/
117783 + ioc_fm_pcd_cc_next_enqueue_params_t enqueue_params; /**< same structure*/
117784 + ioc_compat_fm_pcd_cc_next_kg_params_t kg_params; /**< compat structure*/
117785 +#if DPAA_VERSION >= 11
117786 + ioc_compat_fm_pcd_cc_next_fr_params_t fr_params; /**< compat structure*/
117787 +#endif /* DPAA_VERSION >= 11 */
117788 + } params;
117789 + compat_uptr_t manip_id;
117790 + bool statistics_en;
117791 +} ioc_compat_fm_pcd_cc_next_engine_params_t;
117792 +
117793 +typedef struct ioc_compat_fm_pcd_cc_grp_params_t {
117794 + uint8_t num_of_distinction_units;
117795 + uint8_t unit_ids [IOC_FM_PCD_MAX_NUM_OF_CC_UNITS];
117796 + 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];
117797 +} ioc_compat_fm_pcd_cc_grp_params_t;
117798 +
117799 +typedef struct ioc_compat_fm_pcd_cc_tree_params_t {
117800 + compat_uptr_t net_env_id;
117801 + uint8_t num_of_groups;
117802 + ioc_compat_fm_pcd_cc_grp_params_t fm_pcd_cc_group_params [IOC_FM_PCD_MAX_NUM_OF_CC_GROUPS];
117803 + compat_uptr_t id;
117804 +} ioc_compat_fm_pcd_cc_tree_params_t;
117805 +
117806 +typedef struct ioc_compat_fm_pcd_cc_tree_modify_next_engine_params_t {
117807 + compat_uptr_t id;
117808 + uint8_t grp_indx;
117809 + uint8_t indx;
117810 + ioc_compat_fm_pcd_cc_next_engine_params_t cc_next_engine_params;
117811 +} ioc_compat_fm_pcd_cc_tree_modify_next_engine_params_t;
117812 +
117813 +typedef struct ioc_compat_fm_pcd_cc_key_params_t {
117814 + compat_uptr_t p_key;
117815 + compat_uptr_t p_mask;
117816 + ioc_compat_fm_pcd_cc_next_engine_params_t cc_next_engine_params; /**< compat structure*/
117817 +} ioc_compat_fm_pcd_cc_key_params_t;
117818 +
117819 +typedef struct ioc_compat_keys_params_t {
117820 + uint16_t max_num_of_keys;
117821 + bool mask_support;
117822 + ioc_fm_pcd_cc_stats_mode statistics_mode;
117823 +#if (DPAA_VERSION >= 11)
117824 + uint16_t frame_length_ranges[IOC_FM_PCD_CC_STATS_MAX_NUM_OF_FLR];
117825 +#endif /* (DPAA_VERSION >= 11) */
117826 + uint16_t num_of_keys;
117827 + uint8_t key_size;
117828 + ioc_compat_fm_pcd_cc_key_params_t key_params[IOC_FM_PCD_MAX_NUM_OF_KEYS]; /**< compat structure*/
117829 + ioc_compat_fm_pcd_cc_next_engine_params_t cc_next_engine_params_for_miss; /**< compat structure*/
117830 +} ioc_compat_keys_params_t;
117831 +
117832 +typedef struct ioc_compat_fm_pcd_cc_node_params_t {
117833 + ioc_fm_pcd_extract_entry_t extract_cc_params; /**< same structure*/
117834 + ioc_compat_keys_params_t keys_params; /**< compat structure*/
117835 + compat_uptr_t id;
117836 +} ioc_compat_fm_pcd_cc_node_params_t;
117837 +
117838 +/**************************************************************************//**
117839 + @Description Parameters for defining a hash table
117840 +*//***************************************************************************/
117841 +typedef struct ioc_compat_fm_pcd_hash_table_params_t {
117842 + uint16_t max_num_of_keys;
117843 + ioc_fm_pcd_cc_stats_mode statistics_mode;
117844 + uint8_t kg_hash_shift;
117845 + uint16_t hash_res_mask;
117846 + uint8_t hash_shift;
117847 + uint8_t match_key_size;
117848 + ioc_compat_fm_pcd_cc_next_engine_params_t cc_next_engine_params_for_miss;
117849 + compat_uptr_t id;
117850 +} ioc_compat_fm_pcd_hash_table_params_t;
117851 +
117852 +typedef struct ioc_compat_fm_pcd_hash_table_add_key_params_t {
117853 + compat_uptr_t p_hash_tbl;
117854 + uint8_t key_size;
117855 + ioc_compat_fm_pcd_cc_key_params_t key_params;
117856 +} ioc_compat_fm_pcd_hash_table_add_key_params_t;
117857 +
117858 +typedef struct ioc_compat_fm_pcd_cc_node_modify_key_params_t {
117859 + compat_uptr_t id;
117860 + uint16_t key_indx;
117861 + uint8_t key_size;
117862 + compat_uptr_t p_key;
117863 + compat_uptr_t p_mask;
117864 +} ioc_compat_fm_pcd_cc_node_modify_key_params_t;
117865 +
117866 +typedef struct ioc_compat_fm_pcd_hash_table_remove_key_params_t {
117867 + compat_uptr_t p_hash_tbl;
117868 + uint8_t key_size;
117869 + compat_uptr_t p_key;
117870 +} ioc_compat_fm_pcd_hash_table_remove_key_params_t;
117871 +
117872 +typedef struct ioc_compat_fm_pcd_cc_node_modify_key_and_next_engine_params_t {
117873 + compat_uptr_t id;
117874 + uint16_t key_indx;
117875 + uint8_t key_size;
117876 + ioc_compat_fm_pcd_cc_key_params_t key_params;
117877 +} ioc_compat_fm_pcd_cc_node_modify_key_and_next_engine_params_t;
117878 +
117879 +typedef struct ioc_compat_fm_port_pcd_plcr_params_t {
117880 + compat_uptr_t plcr_profile_id;
117881 +} ioc_compat_fm_port_pcd_plcr_params_t;
117882 +
117883 +typedef struct ioc_compat_fm_port_pcd_cc_params_t {
117884 + compat_uptr_t cc_tree_id;
117885 +} ioc_compat_fm_port_pcd_cc_params_t;
117886 +
117887 +typedef struct ioc_compat_fm_port_pcd_kg_params_t {
117888 + uint8_t num_of_schemes;
117889 + compat_uptr_t scheme_ids[FM_PCD_KG_NUM_OF_SCHEMES];
117890 + bool direct_scheme;
117891 + compat_uptr_t direct_scheme_id;
117892 +} ioc_compat_fm_port_pcd_kg_params_t;
117893 +
117894 +typedef struct ioc_compat_fm_port_pcd_params_t {
117895 + ioc_fm_port_pcd_support pcd_support;
117896 + compat_uptr_t net_env_id;
117897 + compat_uptr_t p_prs_params;
117898 + compat_uptr_t p_cc_params;
117899 + compat_uptr_t p_kg_params;
117900 + compat_uptr_t p_plcr_params;
117901 + compat_uptr_t p_ip_reassembly_manip;
117902 +#if DPAA_VERSION >= 11
117903 + compat_uptr_t p_capwap_reassembly_manip;
117904 +#endif
117905 +} ioc_compat_fm_port_pcd_params_t;
117906 +
117907 +typedef struct ioc_compat_fm_pcd_kg_cc_t {
117908 + compat_uptr_t tree_id;
117909 + uint8_t grp_id;
117910 + bool plcr_next;
117911 + bool bypass_plcr_profile_generation;
117912 + ioc_fm_pcd_kg_plcr_profile_t plcr_profile;
117913 +} ioc_compat_fm_pcd_kg_cc_t;
117914 +
117915 +typedef struct ioc_compat_fm_pcd_kg_scheme_params_t {
117916 + bool modify;
117917 + union {
117918 + uint8_t relative_scheme_id;
117919 + compat_uptr_t scheme_id;
117920 + } scm_id;
117921 + bool always_direct;
117922 + struct {
117923 + compat_uptr_t net_env_id;
117924 + uint8_t num_of_distinction_units;
117925 + uint8_t unit_ids[IOC_FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS];
117926 + } net_env_params;
117927 + bool use_hash;
117928 + ioc_fm_pcd_kg_key_extract_and_hash_params_t key_extract_and_hash_params;
117929 + bool bypass_fqid_generation;
117930 + uint32_t base_fqid;
117931 + uint8_t num_of_used_extracted_ors;
117932 + ioc_fm_pcd_kg_extracted_or_params_t extracted_ors[IOC_FM_PCD_KG_NUM_OF_GENERIC_REGS];
117933 +#if DPAA_VERSION >= 11
117934 + bool override_storage_profile;
117935 + ioc_fm_pcd_kg_storage_profile_t storage_profile;
117936 +#endif /* DPAA_VERSION >= 11 */
117937 + ioc_fm_pcd_engine next_engine;
117938 + union{
117939 + ioc_fm_pcd_done_action done_action;
117940 + ioc_fm_pcd_kg_plcr_profile_t plcr_profile;
117941 + ioc_compat_fm_pcd_kg_cc_t cc;
117942 + } kg_next_engine_params;
117943 + ioc_fm_pcd_kg_scheme_counter_t scheme_counter;
117944 + compat_uptr_t id;
117945 +} ioc_compat_fm_pcd_kg_scheme_params_t;
117946 +
117947 +typedef struct ioc_compat_fm_pcd_cc_node_modify_next_engine_params_t {
117948 + compat_uptr_t id;
117949 + uint16_t key_indx;
117950 + uint8_t key_size;
117951 + ioc_compat_fm_pcd_cc_next_engine_params_t cc_next_engine_params;
117952 +} ioc_compat_fm_pcd_cc_node_modify_next_engine_params_t;
117953 +
117954 +typedef struct ioc_compat_fm_pcd_manip_hdr_insrt_generic_params_t {
117955 + uint8_t offset;
117956 + uint8_t size;
117957 + bool replace;
117958 + compat_uptr_t p_data;
117959 +} ioc_compat_fm_pcd_manip_hdr_insrt_generic_params_t;
117960 +
117961 +typedef struct ioc_compat_fm_pcd_manip_hdr_insrt_specific_l2_params_t {
117962 + ioc_fm_pcd_manip_hdr_insrt_specific_l2 specific_l2;
117963 + bool update;
117964 + uint8_t size;
117965 + compat_uptr_t p_data;
117966 +} ioc_compat_fm_pcd_manip_hdr_insrt_specific_l2_params_t;
117967 +
117968 +typedef struct ioc_compat_fm_pcd_manip_hdr_insrt_t {
117969 + uint8_t size; /**< size of inserted section */
117970 + compat_uptr_t p_data; /**< data to be inserted */
117971 +} ioc_compat_fm_pcd_manip_hdr_insrt_t;
117972 +
117973 +#if (DPAA_VERSION >= 11)
117974 +typedef struct ioc_compat_fm_pcd_manip_hdr_insrt_ip_params_t {
117975 + bool calc_l4_checksum; /**< Calculate L4 checksum. */
117976 + ioc_fm_pcd_manip_hdr_qos_mapping_mode mapping_mode; /**< TODO */
117977 + uint8_t last_pid_offset; /**< the offset of the last Protocol within
117978 + the inserted header */
117979 + uint16_t id; /**< 16 bit New IP ID */
117980 + bool dont_frag_overwrite;
117981 + /**< IPv4 only. DF is overwritten with the hash-result next-to-last byte.
117982 + * This byte is configured to be overwritten when RPD is set. */
117983 + uint8_t last_dst_offset;
117984 + /**< IPv6 only. if routing extension exist, user should set the offset of the destination address
117985 + * in order to calculate UDP checksum pseudo header;
117986 + * Otherwise set it to '0'. */
117987 + ioc_compat_fm_pcd_manip_hdr_insrt_t insrt; /**< size and data to be inserted. */
117988 +} ioc_compat_fm_pcd_manip_hdr_insrt_ip_params_t;
117989 +#endif /* (DPAA_VERSION >= 11) */
117990 +
117991 +typedef struct ioc_compat_fm_pcd_manip_hdr_insrt_by_hdr_params_t {
117992 + ioc_fm_pcd_manip_hdr_insrt_by_hdr_type type;
117993 + union {
117994 + ioc_compat_fm_pcd_manip_hdr_insrt_specific_l2_params_t specific_l2_params;
117995 +#if (DPAA_VERSION >= 11)
117996 + ioc_compat_fm_pcd_manip_hdr_insrt_ip_params_t ip_params;
117997 + ioc_compat_fm_pcd_manip_hdr_insrt_t insrt;
117998 +#endif /* (DPAA_VERSION >= 11) */
117999 + } u;
118000 +} ioc_compat_fm_pcd_manip_hdr_insrt_by_hdr_params_t;
118001 +
118002 +typedef struct ioc_compat_fm_pcd_manip_hdr_insrt_params_t {
118003 + ioc_fm_pcd_manip_hdr_insrt_type type;
118004 + union {
118005 + ioc_compat_fm_pcd_manip_hdr_insrt_by_hdr_params_t by_hdr;
118006 + ioc_compat_fm_pcd_manip_hdr_insrt_generic_params_t generic;
118007 +#if (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10))
118008 +#error "FM_CAPWAP_SUPPORT feature not supported!"
118009 + ioc_fm_pcd_manip_hdr_insrt_by_template_params_t by_template;
118010 +#endif /* FM_CAPWAP_SUPPORT */
118011 + } u;
118012 +} ioc_compat_fm_pcd_manip_hdr_insrt_params_t;
118013 +
118014 +typedef struct ioc_compat_fm_pcd_manip_hdr_params_t {
118015 + bool rmv;
118016 + ioc_fm_pcd_manip_hdr_rmv_params_t rmv_params;
118017 + bool insrt;
118018 + ioc_compat_fm_pcd_manip_hdr_insrt_params_t insrt_params;
118019 + bool field_update;
118020 + ioc_fm_pcd_manip_hdr_field_update_params_t field_update_params;
118021 + bool custom;
118022 + ioc_fm_pcd_manip_hdr_custom_params_t custom_params;
118023 + bool dont_parse_after_manip;
118024 +} ioc_compat_fm_pcd_manip_hdr_params_t;
118025 +
118026 +typedef struct ioc_compat_fm_pcd_manip_special_offload_params_t {
118027 + bool decryption;
118028 + bool ecn_copy;
118029 + bool dscp_copy;
118030 + bool variable_ip_hdr_len;
118031 + bool variable_ip_version;
118032 + uint8_t outer_ip_hdr_len;
118033 + uint16_t arw_size;
118034 + compat_uptr_t arw_addr;
118035 +} ioc_compat_fm_pcd_manip_special_offload_params_t;
118036 +
118037 +typedef struct ioc_compat_fm_pcd_manip_params_t {
118038 + ioc_fm_pcd_manip_type type;
118039 + union {
118040 + ioc_compat_fm_pcd_manip_hdr_params_t hdr;
118041 + ioc_fm_pcd_manip_reassem_params_t reassem;
118042 + ioc_fm_pcd_manip_frag_params_t frag;
118043 + ioc_compat_fm_pcd_manip_special_offload_params_t special_offload;
118044 + } u;
118045 + compat_uptr_t p_next_manip;
118046 +#if (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10))
118047 +#error "FM_CAPWAP_SUPPORT feature not supported!"
118048 + bool frag_or_reasm;
118049 + ioc_fm_pcd_manip_frag_or_reasm_params_t frag_or_reasm_params;
118050 +#endif /* FM_CAPWAP_SUPPORT */
118051 + compat_uptr_t id;
118052 +} ioc_compat_fm_pcd_manip_params_t;
118053 +
118054 +typedef struct ioc_compat_fm_pcd_manip_get_stats_t {
118055 + compat_uptr_t id;
118056 + ioc_fm_pcd_manip_stats_t stats;
118057 +} ioc_compat_fm_pcd_manip_get_stats_t;
118058 +
118059 +#if (DPAA_VERSION >= 11)
118060 +typedef struct ioc_compat_fm_pcd_frm_replic_group_params_t {
118061 + uint8_t max_num_of_entries;
118062 + uint8_t num_of_entries;
118063 + ioc_compat_fm_pcd_cc_next_engine_params_t
118064 + next_engine_params[IOC_FM_PCD_FRM_REPLIC_MAX_NUM_OF_ENTRIES];
118065 + compat_uptr_t id;
118066 +} ioc_compat_fm_pcd_frm_replic_group_params_t;
118067 +
118068 +typedef struct ioc_compat_fm_pcd_frm_replic_member_t {
118069 + compat_uptr_t h_replic_group;
118070 + uint16_t member_index;
118071 +} ioc_compat_fm_pcd_frm_replic_member_t;
118072 +
118073 +typedef struct ioc_compat_fm_pcd_frm_replic_member_params_t {
118074 + ioc_compat_fm_pcd_frm_replic_member_t member;
118075 + ioc_compat_fm_pcd_cc_next_engine_params_t next_engine_params;
118076 +} ioc_compat_fm_pcd_frm_replic_member_params_t;
118077 +
118078 +typedef struct ioc_compat_fm_vsp_params_t {
118079 + compat_uptr_t p_fm; /**< A handle to the FM object this VSP related to */
118080 + ioc_fm_ext_pools ext_buf_pools; /**< Which external buffer pools are used
118081 + (up to FM_PORT_MAX_NUM_OF_EXT_POOLS), and their sizes.
118082 + parameter associated with Rx / OP port */
118083 + uint16_t liodn_offset; /**< VSP's LIODN offset */
118084 + struct {
118085 + ioc_fm_port_type port_type; /**< Port type */
118086 + uint8_t port_id; /**< Port Id - relative to type */
118087 + } port_params;
118088 + uint8_t relative_profile_id; /**< VSP Id - relative to VSP's range
118089 + defined in relevant FM object */
118090 + compat_uptr_t id; /**< return value */
118091 +} ioc_compat_fm_vsp_params_t;
118092 +
118093 +typedef struct ioc_compat_fm_buf_pool_depletion_params_t {
118094 + compat_uptr_t p_fm_vsp;
118095 + ioc_fm_buf_pool_depletion_t fm_buf_pool_depletion;
118096 +} ioc_compat_fm_buf_pool_depletion_params_t;
118097 +
118098 +typedef struct ioc_compat_fm_buffer_prefix_content_params_t {
118099 + compat_uptr_t p_fm_vsp;
118100 + ioc_fm_buffer_prefix_content_t fm_buffer_prefix_content;
118101 +} ioc_compat_fm_buffer_prefix_content_params_t;
118102 +
118103 +typedef struct ioc_compat_fm_vsp_config_no_sg_params_t {
118104 + compat_uptr_t p_fm_vsp;
118105 + bool no_sg;
118106 +} ioc_compat_fm_vsp_config_no_sg_params_t;
118107 +
118108 +typedef struct ioc_compat_fm_vsp_prs_result_params_t {
118109 + compat_uptr_t p_fm_vsp;
118110 + compat_uptr_t p_data;
118111 +} ioc_compat_fm_vsp_prs_result_params_t;
118112 +
118113 +#endif /* (DPAA_VERSION >= 11) */
118114 +typedef struct ioc_compat_fm_pcd_kg_scheme_spc_t {
118115 + uint32_t val;
118116 + compat_uptr_t id;
118117 +} ioc_compat_fm_pcd_kg_scheme_spc_t;
118118 +
118119 +typedef struct ioc_compat_fm_ctrl_mon_counters_params_t {
118120 + uint8_t fm_ctrl_index;
118121 + compat_uptr_t p_mon;
118122 +} ioc_compat_fm_ctrl_mon_counters_params_t;
118123 +
118124 +typedef struct ioc_compat_fm_pcd_cc_tbl_get_stats_t {
118125 + compat_uptr_t id;
118126 + uint16_t key_index;
118127 + ioc_fm_pcd_cc_key_statistics_t statistics;
118128 +} ioc_compat_fm_pcd_cc_tbl_get_stats_t;
118129 +
118130 +
118131 +/* } pcd compat structures */
118132 +
118133 +void compat_obj_delete(
118134 + ioc_compat_fm_obj_t *compat_id,
118135 + ioc_fm_obj_t *id);
118136 +
118137 +/* pcd compat functions { */
118138 +void compat_copy_fm_pcd_plcr_profile(
118139 + ioc_compat_fm_pcd_plcr_profile_params_t *compat_param,
118140 + ioc_fm_pcd_plcr_profile_params_t *param,
118141 + uint8_t compat);
118142 +
118143 +void compat_copy_fm_pcd_cc_key(
118144 + ioc_compat_fm_pcd_cc_key_params_t *compat_param,
118145 + ioc_fm_pcd_cc_key_params_t *param,
118146 + uint8_t compat);
118147 +
118148 +void compat_copy_fm_pcd_cc_node_modify_key_and_next_engine(
118149 + ioc_compat_fm_pcd_cc_node_modify_key_and_next_engine_params_t *compat_param,
118150 + ioc_fm_pcd_cc_node_modify_key_and_next_engine_params_t *param,
118151 + uint8_t compat);
118152 +
118153 +void compat_copy_fm_pcd_cc_node_modify_next_engine(
118154 + ioc_compat_fm_pcd_cc_node_modify_next_engine_params_t *compat_param,
118155 + ioc_fm_pcd_cc_node_modify_next_engine_params_t *param,
118156 + uint8_t compat);
118157 +
118158 +void compat_fm_pcd_cc_tree_modify_next_engine(
118159 + ioc_compat_fm_pcd_cc_tree_modify_next_engine_params_t *compat_param,
118160 + ioc_fm_pcd_cc_tree_modify_next_engine_params_t *param,
118161 + uint8_t compat);
118162 +
118163 +void compat_copy_fm_pcd_hash_table(
118164 + ioc_compat_fm_pcd_hash_table_params_t *compat_param,
118165 + ioc_fm_pcd_hash_table_params_t *param,
118166 + uint8_t compat);
118167 +
118168 +void compat_copy_fm_pcd_cc_grp(
118169 + ioc_compat_fm_pcd_cc_grp_params_t *compat_param,
118170 + ioc_fm_pcd_cc_grp_params_t *param,
118171 + uint8_t compat);
118172 +
118173 +void compat_copy_fm_pcd_cc_tree(
118174 + ioc_compat_fm_pcd_cc_tree_params_t *compat_param,
118175 + ioc_fm_pcd_cc_tree_params_t *param,
118176 + uint8_t compat);
118177 +
118178 +void compat_copy_fm_pcd_cc_tbl_get_stats(
118179 + ioc_compat_fm_pcd_cc_tbl_get_stats_t *compat_param,
118180 + ioc_fm_pcd_cc_tbl_get_stats_t *param,
118181 + uint8_t compat);
118182 +
118183 +void compat_fm_pcd_prs_sw(
118184 + ioc_compat_fm_pcd_prs_sw_params_t *compat_param,
118185 + ioc_fm_pcd_prs_sw_params_t *param,
118186 + uint8_t compat);
118187 +
118188 +void compat_copy_fm_pcd_kg_scheme(
118189 + ioc_compat_fm_pcd_kg_scheme_params_t *compat_param,
118190 + ioc_fm_pcd_kg_scheme_params_t *param,
118191 + uint8_t compat);
118192 +
118193 +void compat_copy_fm_pcd_kg_scheme_select(
118194 + ioc_compat_fm_pcd_kg_scheme_select_t *compat_param,
118195 + ioc_fm_pcd_kg_scheme_select_t *param,
118196 + uint8_t compat);
118197 +
118198 +void compat_copy_fm_pcd_kg_schemes_params(
118199 + ioc_compat_fm_pcd_port_schemes_params_t *compat_param,
118200 + ioc_fm_pcd_port_schemes_params_t *param,
118201 + uint8_t compat);
118202 +
118203 +void compat_copy_fm_port_pcd_kg(
118204 + ioc_compat_fm_port_pcd_kg_params_t *compat_param,
118205 + ioc_fm_port_pcd_kg_params_t *param,
118206 + uint8_t compat);
118207 +
118208 +void compat_copy_fm_port_pcd(
118209 + ioc_compat_fm_port_pcd_params_t *compat_param,
118210 + ioc_fm_port_pcd_params_t *param,
118211 + uint8_t compat);
118212 +
118213 +#if (DPAA_VERSION >= 11)
118214 +void compat_copy_fm_port_vsp_alloc_params(
118215 + ioc_compat_fm_port_vsp_alloc_params_t *compat_param,
118216 + ioc_fm_port_vsp_alloc_params_t *param,
118217 + uint8_t compat);
118218 +#endif /* (DPAA_VERSION >= 11) */
118219 +
118220 +void compat_copy_fm_pcd_net_env(
118221 + ioc_compat_fm_pcd_net_env_params_t *compat_param,
118222 + ioc_fm_pcd_net_env_params_t *param,
118223 + uint8_t compat);
118224 +
118225 +void compat_copy_fm_pcd_cc_node_modify_key(
118226 + ioc_compat_fm_pcd_cc_node_modify_key_params_t *compat_param,
118227 + ioc_fm_pcd_cc_node_modify_key_params_t *param,
118228 + uint8_t compat);
118229 +
118230 +void compat_copy_keys(
118231 + ioc_compat_keys_params_t *compat_param,
118232 + ioc_keys_params_t *param,
118233 + uint8_t compat);
118234 +
118235 +void compat_copy_fm_pcd_cc_node(
118236 + ioc_compat_fm_pcd_cc_node_params_t *compat_param,
118237 + ioc_fm_pcd_cc_node_params_t *param,
118238 + uint8_t compat);
118239 +
118240 +void compat_fm_pcd_manip_set_node(
118241 + ioc_compat_fm_pcd_manip_params_t *compat_param,
118242 + ioc_fm_pcd_manip_params_t *param,
118243 + uint8_t compat);
118244 +
118245 +void compat_copy_fm_pcd_manip_get_stats(
118246 + ioc_compat_fm_pcd_manip_get_stats_t *compat_param,
118247 + ioc_fm_pcd_manip_get_stats_t *param,
118248 + uint8_t compat);
118249 +
118250 +void compat_copy_fm_port_pcd_modify_tree(
118251 + ioc_compat_fm_obj_t *compat_id,
118252 + ioc_fm_obj_t *id,
118253 + uint8_t compat);
118254 +
118255 +#if (DPAA_VERSION >= 11)
118256 +void compat_copy_fm_pcd_frm_replic_group_params(
118257 + ioc_compat_fm_pcd_frm_replic_group_params_t *compat_param,
118258 + ioc_fm_pcd_frm_replic_group_params_t *param,
118259 + uint8_t compat);
118260 +
118261 +void compat_copy_fm_pcd_frm_replic_member(
118262 + ioc_compat_fm_pcd_frm_replic_member_t *compat_param,
118263 + ioc_fm_pcd_frm_replic_member_t *param,
118264 + uint8_t compat);
118265 +
118266 +void compat_copy_fm_pcd_frm_replic_member_params(
118267 + ioc_compat_fm_pcd_frm_replic_member_params_t *compat_param,
118268 + ioc_fm_pcd_frm_replic_member_params_t *param,
118269 + uint8_t compat);
118270 +
118271 +void compat_copy_fm_vsp_params(
118272 + ioc_compat_fm_vsp_params_t *compat_param,
118273 + ioc_fm_vsp_params_t *param,
118274 + uint8_t compat);
118275 +
118276 +void compat_copy_fm_buf_pool_depletion_params(
118277 + ioc_compat_fm_buf_pool_depletion_params_t *compat_param,
118278 + ioc_fm_buf_pool_depletion_params_t *param,
118279 + uint8_t compat);
118280 +
118281 +void compat_copy_fm_buffer_prefix_content_params(
118282 + ioc_compat_fm_buffer_prefix_content_params_t *compat_param,
118283 + ioc_fm_buffer_prefix_content_params_t *param,
118284 + uint8_t compat);
118285 +
118286 +void compat_copy_fm_vsp_config_no_sg_params(
118287 + ioc_compat_fm_vsp_config_no_sg_params_t *compat_param,
118288 + ioc_fm_vsp_config_no_sg_params_t *param,
118289 + uint8_t compat);
118290 +
118291 +void compat_copy_fm_vsp_prs_result_params(
118292 + ioc_compat_fm_vsp_prs_result_params_t *compat_param,
118293 + ioc_fm_vsp_prs_result_params_t *param,
118294 + uint8_t compat);
118295 +
118296 +#endif /* (DPAA_VERSION >= 11) */
118297 +
118298 +void compat_copy_fm_pcd_kg_scheme_spc(
118299 + ioc_compat_fm_pcd_kg_scheme_spc_t *compat_param,
118300 + ioc_fm_pcd_kg_scheme_spc_t *param,
118301 + uint8_t compat);
118302 +
118303 +/* } pcd compat functions */
118304 +#endif
118305 --- /dev/null
118306 +++ b/drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_resources.h
118307 @@ -0,0 +1,121 @@
118308 +/*
118309 + * Copyright 2008-2012 Freescale Semiconductor Inc.
118310 + *
118311 + * Redistribution and use in source and binary forms, with or without
118312 + * modification, are permitted provided that the following conditions are met:
118313 + * * Redistributions of source code must retain the above copyright
118314 + * notice, this list of conditions and the following disclaimer.
118315 + * * Redistributions in binary form must reproduce the above copyright
118316 + * notice, this list of conditions and the following disclaimer in the
118317 + * documentation and/or other materials provided with the distribution.
118318 + * * Neither the name of Freescale Semiconductor nor the
118319 + * names of its contributors may be used to endorse or promote products
118320 + * derived from this software without specific prior written permission.
118321 + *
118322 + *
118323 + * ALTERNATIVELY, this software may be distributed under the terms of the
118324 + * GNU General Public License ("GPL") as published by the Free Software
118325 + * Foundation, either version 2 of that License or (at your option) any
118326 + * later version.
118327 + *
118328 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
118329 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
118330 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
118331 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
118332 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
118333 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
118334 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
118335 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
118336 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
118337 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
118338 + */
118339 +
118340 +/*
118341 + @File lnxwrp_resources.h
118342 +
118343 + @Description FMD wrapper resource allocation functions.
118344 +
118345 +*/
118346 +
118347 +#ifndef LNXWRP_RESOURCES_H_
118348 +#define LNXWRP_RESOURCES_H_
118349 +
118350 +#if !defined(FMAN_RESOURCES_UNIT_TEST)
118351 +#include "lnxwrp_fm.h"
118352 +#else
118353 +#include "lnxwrp_resources_ut.h"
118354 +#endif
118355 +
118356 +#define ROUND(X) ((2*(X)+1)/2)
118357 +#define CEIL(X) ((X)+1)
118358 +/* #define ROUND_DIV(X, Y) (((X)+(Y)/2)/(Y)) */
118359 +#define ROUND_DIV(X, Y) ((2*(X)+(Y))/(2*(Y)))
118360 +#define CEIL_DIV(X, Y) (((X)+(Y)-1)/(Y))
118361 +
118362 +/* used for resource calculus */
118363 +#define DPDE_1G 2 /* DQDP 1g - from LLD:
118364 + DEFAULT_PORT_txFifoDeqPipelineDepth_1G */
118365 +#define DPDE_10G 8 /* DQDP 10g - from LLD:
118366 + DEFAULT_PORT_txFifoDeqPipelineDepth_10G */
118367 +
118368 +int fm_set_active_fman_ports(struct platform_device *of_dev,
118369 + t_LnxWrpFmDev *p_LnxWrpFmDev);
118370 +
118371 +/* Calculate the fifosize based on MURAM allocation, number of ports, dpde
118372 + * value and s/g software support (! Kernel does not suport s/g).
118373 + *
118374 + * Algorithm summary:
118375 + * - Calculate the the minimum fifosize required for every type of port
118376 + * (TX,RX for 1G, 2.5G and 10G).
118377 + * - Set TX the minimum fifosize required.
118378 + * - Distribute the remaining buffers (after all TX were set) to RX ports
118379 + * based on:
118380 + * 1G RX = Remaining_buffers * 1/(1+2.5+10)
118381 + * 2.5G RX = Remaining_buffers * 2.5/(1+2.5+10)
118382 + * 10G RX = Remaining_buffers * 10/(1+2.5+10)
118383 + * - if the RX is smaller than the minimum required, then set the minimum
118384 + * required
118385 + * - In the end distribuite the leftovers if there are any (due to
118386 + * unprecise calculus) or if over allocation cat some buffers from all RX
118387 + * ports w/o pass over minimum required treshold, but if there must be
118388 + * pass the treshold in order to cat the over allocation ,then this
118389 + * configuration can not be set - KERN_ALERT.
118390 +*/
118391 +int fm_precalculate_fifosizes(t_LnxWrpFmDev *p_LnxWrpFmDev,
118392 + int muram_fifo_size);
118393 +
118394 +#if !defined(FMAN_RESOURCES_UNIT_TEST)
118395 +int fm_config_precalculate_fifosize(t_LnxWrpFmPortDev *p_LnxWrpFmPortDev);
118396 +#endif
118397 +
118398 +/* Compute FMan open DMA based on total number of open DMAs and
118399 + * number of available fman ports.
118400 + *
118401 + * By default 10g ports are set to input parameters. The other ports
118402 + * tries to keep the proportion rx=2tx open dmas or tresholds.
118403 + *
118404 + * If leftovers, then those will be set as shared.
118405 + *
118406 + * If after computing overflow appears, then it decrements open dma
118407 + * for all ports w/o cross the tresholds. If the tresholds are meet
118408 + * and is still overflow, then it returns error.
118409 +*/
118410 +int fm_precalculate_open_dma(t_LnxWrpFmDev *p_LnxWrpFmDev,
118411 + int max_fm_open_dma,
118412 + int default_tx_10g_dmas,
118413 + int default_rx_10g_dmas,
118414 + int min_tx_10g_treshold, int min_rx_10g_treshold);
118415 +
118416 +#if !defined(FMAN_RESOURCES_UNIT_TEST)
118417 +int fm_config_precalculate_open_dma(t_LnxWrpFmPortDev *p_LnxWrpFmPortDev);
118418 +#endif
118419 +
118420 +/* Compute FMan tnums based on available tnums and number of ports.
118421 + * Set defaults (minim tresholds) and then distribute leftovers.*/
118422 +int fm_precalculate_tnums(t_LnxWrpFmDev *p_LnxWrpFmDev, int max_fm_tnums);
118423 +
118424 +#if !defined(FMAN_RESOURCES_UNIT_TEST)
118425 +int fm_config_precalculate_tnums(t_LnxWrpFmPortDev *p_LnxWrpFmPortDev);
118426 +#endif
118427 +
118428 +#endif /* LNXWRP_RESOURCES_H_ */
118429 --- /dev/null
118430 +++ b/drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_resources_ut.c
118431 @@ -0,0 +1,191 @@
118432 +/* Copyright (c) 2012 Freescale Semiconductor, Inc.
118433 + * All rights reserved.
118434 + *
118435 + * Redistribution and use in source and binary forms, with or without
118436 + * modification, are permitted provided that the following conditions are met:
118437 + * * Redistributions of source code must retain the above copyright
118438 + * notice, this list of conditions and the following disclaimer.
118439 + * * Redistributions in binary form must reproduce the above copyright
118440 + * notice, this list of conditions and the following disclaimer in the
118441 + * documentation and/or other materials provided with the distribution.
118442 + * * Neither the name of Freescale Semiconductor nor the
118443 + * names of its contributors may be used to endorse or promote products
118444 + * derived from this software without specific prior written permission.
118445 + *
118446 + *
118447 + * ALTERNATIVELY, this software may be distributed under the terms of the
118448 + * GNU General Public License ("GPL") as published by the Free Software
118449 + * Foundation, either version 2 of that License or (at your option) any
118450 + * later version.
118451 + *
118452 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
118453 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
118454 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
118455 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
118456 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
118457 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
118458 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
118459 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
118460 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
118461 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
118462 + */
118463 +
118464 +#include "lnxwrp_resources.h"
118465 +#include "lnxwrp_resources_ut.h"
118466 +
118467 +#define KILOBYTE 0x400 /* 1024 */
118468 +
118469 +typedef enum e_board_type {
118470 + e_p3041,
118471 + e_p4080,
118472 + e_p5020,
118473 + e_p1023
118474 +} e_board_type;
118475 +
118476 +uint8_t board_type;
118477 +uint32_t muram_size = 0;
118478 +uint32_t dmas_num = 0;
118479 +uint32_t task_num = 0;
118480 +uint32_t frame_size = 0;
118481 +uint32_t oh_num = 0;
118482 +uint32_t num_ports_1g = 0;
118483 +uint32_t num_ports_10g = 0;
118484 +uint32_t num_ports_2g5 = 0;
118485 +uint32_t fsl_fman_phy_maxfrm = 0;
118486 +uint32_t dpa_rx_extra_headroom = 0;
118487 +
118488 +void show_help(void){
118489 + printf(" help: \n");
118490 + printf(" -b <board_type> -f <max_fram_size(mtu)> -o <num_oh_ports> -g1"
118491 + " <num_1g_ports> -g10 <num_10g_ports> -g25 <num_2g5_ports>\n");
118492 + printf(" Maxim num of DMAS availbale: P3/P4/P5:32 , P1023:16 \n");
118493 + printf(" Maxim num of TNUMs availbale: P3/P4/P5:128, P1023:32 \n");
118494 + printf(" Muram size: P3/P4/P5:160K, P1023:64K \n");
118495 + printf(" Number of ports:\n");
118496 + printf(" P3/P5: 5p 1g, 1p 10g, 7p oh \n");
118497 + printf(" P4 : 4p 1g, 1p 10g, 7p oh \n");
118498 + printf(" P1 : 2p 1g, 0p 10g, 4p oh \n");
118499 + printf(" MTU: Default:1522, Jumbo:9600 \n");
118500 +}
118501 +
118502 +int fm_set_param(t_LnxWrpFmDev *p_LnxWrpFmDev) {
118503 + struct fm_active_ports *fm_active_ports_info = NULL;
118504 + fm_active_ports_info = &p_LnxWrpFmDev->fm_active_ports_info;
118505 +
118506 + switch(board_type){
118507 + case e_p3041:
118508 + case e_p5020:
118509 + muram_size = 160*KILOBYTE;
118510 + dmas_num = 32;
118511 + task_num = 128;
118512 + if ((num_ports_1g+num_ports_2g5) > 5 || num_ports_10g > 1 || oh_num > 7)
118513 + goto err_fm_set_param;
118514 + break;
118515 + case e_p4080:
118516 + muram_size = 160*KILOBYTE;
118517 + dmas_num = 32;
118518 + task_num = 128;
118519 + if ((num_ports_1g+num_ports_2g5) > 4 || num_ports_10g > 1 || oh_num > 7)
118520 + goto err_fm_set_param;
118521 + break;
118522 + case e_p1023:
118523 + muram_size = 64*KILOBYTE;
118524 + dmas_num = 16;
118525 + task_num = 128;
118526 + if ((num_ports_1g+num_ports_2g5) > 2 || oh_num > 4)
118527 + goto err_fm_set_param;
118528 + break;
118529 + default:
118530 + goto err_fm_set_param;
118531 + break;
118532 + }
118533 +
118534 + p_LnxWrpFmDev->id = 0;
118535 + fsl_fman_phy_maxfrm = frame_size;
118536 + dpa_rx_extra_headroom = 0; /* ATTENTION: can be != 0 */
118537 + fm_active_ports_info->num_oh_ports = oh_num;
118538 + fm_active_ports_info->num_tx_ports = num_ports_1g;
118539 + fm_active_ports_info->num_rx_ports = num_ports_1g;
118540 + fm_active_ports_info->num_tx25_ports = num_ports_2g5;
118541 + fm_active_ports_info->num_rx25_ports = num_ports_2g5;
118542 + fm_active_ports_info->num_tx10_ports = num_ports_10g;
118543 + fm_active_ports_info->num_rx10_ports = num_ports_10g;
118544 +
118545 + return 0;
118546 +
118547 +err_fm_set_param:
118548 + printf(" ERR: To many ports!!! \n");
118549 + return -1;
118550 +}
118551 +
118552 +int main (int argc, char *argv[]){
118553 + t_LnxWrpFmDev LnxWrpFmDev;
118554 + t_LnxWrpFmDev *p_LnxWrpFmDev = &LnxWrpFmDev;
118555 + int tokens_cnt = 1;
118556 +
118557 + char *token = NULL;
118558 +
118559 + while(tokens_cnt < argc)
118560 + {
118561 + token = argv[tokens_cnt++];
118562 + if (strcmp(token, "-b") == 0){
118563 + if(strcmp(argv[tokens_cnt],"p3") == 0)
118564 + board_type = e_p3041;
118565 + else if(strcmp(argv[tokens_cnt],"p4") == 0)
118566 + board_type = e_p4080;
118567 + else if(strcmp(argv[tokens_cnt],"p5") == 0)
118568 + board_type = e_p5020;
118569 + else if(strcmp(argv[tokens_cnt],"p1") == 0)
118570 + board_type = e_p1023;
118571 + else
118572 + show_help();
118573 + tokens_cnt++;
118574 + }
118575 + else if(strcmp(token, "-d") == 0){
118576 + dmas_num = atoi(argv[tokens_cnt++]);
118577 + }
118578 + else if(strcmp(token, "-t") == 0)
118579 + task_num = atoi(argv[tokens_cnt++]);
118580 + else if(strcmp(token, "-f") == 0)
118581 + frame_size = atoi(argv[tokens_cnt++]);
118582 + else if(strcmp(token, "-o") == 0)
118583 + oh_num = atoi(argv[tokens_cnt++]);
118584 + else if(strcmp(token, "-g1") == 0)
118585 + num_ports_1g = atoi(argv[tokens_cnt++]);
118586 + else if(strcmp(token, "-g10") == 0)
118587 + num_ports_10g = atoi(argv[tokens_cnt++]);
118588 + else if(strcmp(token, "-g25") == 0)
118589 + num_ports_2g5 = atoi(argv[tokens_cnt++]);
118590 + else {
118591 + show_help();
118592 + return -1;
118593 + }
118594 + }
118595 +
118596 + if(fm_set_param(p_LnxWrpFmDev) < 0){
118597 + show_help();
118598 + return -1;
118599 + }
118600 +
118601 + if(fm_precalculate_fifosizes(
118602 + p_LnxWrpFmDev,
118603 + 128*KILOBYTE)
118604 + != 0)
118605 + return -1;
118606 + if(fm_precalculate_open_dma(
118607 + p_LnxWrpFmDev,
118608 + dmas_num, /* max open dmas:dpaa_integration_ext.h */
118609 + FM_DEFAULT_TX10G_OPENDMA, /* default TX 10g open dmas */
118610 + FM_DEFAULT_RX10G_OPENDMA, /* default RX 10g open dmas */
118611 + FM_10G_OPENDMA_MIN_TRESHOLD,/* TX 10g minimum treshold */
118612 + FM_10G_OPENDMA_MIN_TRESHOLD)/* RX 10g minimum treshold */
118613 + != 0)
118614 + return -1;
118615 + if(fm_precalculate_tnums(
118616 + p_LnxWrpFmDev,
118617 + task_num) /* max TNUMS: dpa integration file. */
118618 + != 0)
118619 + return -1;
118620 +
118621 + return 0;
118622 +}
118623 --- /dev/null
118624 +++ b/drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_resources_ut.h
118625 @@ -0,0 +1,144 @@
118626 +/* Copyright (c) 2012 Freescale Semiconductor, Inc
118627 + * All rights reserved.
118628 + *
118629 + * Redistribution and use in source and binary forms, with or without
118630 + * modification, are permitted provided that the following conditions are met:
118631 + * * Redistributions of source code must retain the above copyright
118632 + * notice, this list of conditions and the following disclaimer.
118633 + * * Redistributions in binary form must reproduce the above copyright
118634 + * notice, this list of conditions and the following disclaimer in the
118635 + * documentation and/or other materials provided with the distribution.
118636 + * * Neither the name of Freescale Semiconductor nor the
118637 + * names of its contributors may be used to endorse or promote products
118638 + * derived from this software without specific prior written permission.
118639 + *
118640 + *
118641 + * ALTERNATIVELY, this software may be distributed under the terms of the
118642 + * GNU General Public License ("GPL") as published by the Free Software
118643 + * Foundation, either version 2 of that License or (at your option) any
118644 + * later version.
118645 + *
118646 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
118647 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
118648 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
118649 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
118650 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
118651 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
118652 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
118653 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
118654 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
118655 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
118656 + */
118657 +
118658 +#ifndef FM_RESS_TEST_H_
118659 +#define FM_RESS_TEST_H_
118660 +
118661 +#include <stdint.h>
118662 +#include <stdbool.h>
118663 +#include <stdio.h>
118664 +#include <assert.h>
118665 +#include <string.h>
118666 +#include <stdlib.h>
118667 +
118668 +#define _Packed
118669 +#define _PackedType __attribute__ ((packed))
118670 +#define MAX(x, y) (((x) > (y)) ? (x) : (y))
118671 +#define MIN(x, y) (((x) < (y)) ? (x) : (y))
118672 +#define KERN_ALERT ""
118673 +#define KERN_INFO ""
118674 +#define ASSERT_COND assert
118675 +#define printk printf
118676 +#define NET_IP_ALIGN 0
118677 +#define FM_FIFO_ALLOCATION_OLD_ALG
118678 +
118679 +#if defined(CONFIG_FMAN_DISABLE_OH_AND_DISTRIBUTE_RESOURCES)
118680 +#define FM_10G_OPENDMA_MIN_TRESHOLD 8 /* 10g minimum treshold if only HC is enabled and no OH port enabled */
118681 +#define FM_OPENDMA_RX_TX_RAPORT 2 /* RX = 2*TX */
118682 +#else
118683 +#define FM_10G_OPENDMA_MIN_TRESHOLD 7 /* 10g minimum treshold if 7 OH ports are enabled */
118684 +#define FM_OPENDMA_RX_TX_RAPORT 1 /* RX = TX */
118685 +#endif
118686 +#define FM_DEFAULT_TX10G_OPENDMA 8 /* default TX 10g open dmas */
118687 +#define FM_DEFAULT_RX10G_OPENDMA 8 /* default RX 10g open dmas */
118688 +
118689 +/* information about all active ports for an FMan.
118690 + * !Some ports may be disabled by u-boot, thus will not be available */
118691 +struct fm_active_ports {
118692 + uint32_t num_oh_ports;
118693 + uint32_t num_tx_ports;
118694 + uint32_t num_rx_ports;
118695 + uint32_t num_tx25_ports;
118696 + uint32_t num_rx25_ports;
118697 + uint32_t num_tx10_ports;
118698 + uint32_t num_rx10_ports;
118699 +};
118700 +
118701 +/* FMan resources precalculated at fm probe based
118702 + * on available FMan port. */
118703 +struct fm_resource_settings {
118704 + /* buffers - fifo sizes */
118705 + uint32_t tx1g_num_buffers;
118706 + uint32_t rx1g_num_buffers;
118707 + uint32_t tx2g5_num_buffers; /* Not supported yet by LLD */
118708 + uint32_t rx2g5_num_buffers; /* Not supported yet by LLD */
118709 + uint32_t tx10g_num_buffers;
118710 + uint32_t rx10g_num_buffers;
118711 + uint32_t oh_num_buffers;
118712 + uint32_t shared_ext_buffers;
118713 +
118714 +
118715 + /* open DMAs */
118716 + uint32_t tx_1g_dmas;
118717 + uint32_t rx_1g_dmas;
118718 + uint32_t tx_2g5_dmas; /* Not supported yet by LLD */
118719 + uint32_t rx_2g5_dmas; /* Not supported yet by LLD */
118720 + uint32_t tx_10g_dmas;
118721 + uint32_t rx_10g_dmas;
118722 + uint32_t oh_dmas;
118723 + uint32_t shared_ext_open_dma;
118724 +
118725 + /* Tnums */
118726 + uint32_t tx_1g_tnums;
118727 + uint32_t rx_1g_tnums;
118728 + uint32_t tx_2g5_tnums; /* Not supported yet by LLD */
118729 + uint32_t rx_2g5_tnums; /* Not supported yet by LLD */
118730 + uint32_t tx_10g_tnums;
118731 + uint32_t rx_10g_tnums;
118732 + uint32_t oh_tnums;
118733 + uint32_t shared_ext_tnums;
118734 +};
118735 +
118736 +typedef struct {
118737 + uint8_t id;
118738 + struct fm_active_ports fm_active_ports_info;
118739 + struct fm_resource_settings fm_resource_settings_info;
118740 +} t_LnxWrpFmDev;
118741 +
118742 +typedef struct {
118743 + uint8_t id;
118744 +} t_LnxWrpFmPortDev;
118745 +
118746 +typedef _Packed struct t_FmPrsResult {
118747 + volatile uint8_t lpid; /**< Logical port id */
118748 + volatile uint8_t shimr; /**< Shim header result */
118749 + volatile uint16_t l2r; /**< Layer 2 result */
118750 + volatile uint16_t l3r; /**< Layer 3 result */
118751 + volatile uint8_t l4r; /**< Layer 4 result */
118752 + volatile uint8_t cplan; /**< Classification plan id */
118753 + volatile uint16_t nxthdr; /**< Next Header */
118754 + volatile uint16_t cksum; /**< Checksum */
118755 + volatile uint32_t lcv; /**< LCV */
118756 + volatile uint8_t shim_off[3]; /**< Shim offset */
118757 + volatile uint8_t eth_off; /**< ETH offset */
118758 + volatile uint8_t llc_snap_off; /**< LLC_SNAP offset */
118759 + volatile uint8_t vlan_off[2]; /**< VLAN offset */
118760 + volatile uint8_t etype_off; /**< ETYPE offset */
118761 + volatile uint8_t pppoe_off; /**< PPP offset */
118762 + volatile uint8_t mpls_off[2]; /**< MPLS offset */
118763 + volatile uint8_t ip_off[2]; /**< IP offset */
118764 + volatile uint8_t gre_off; /**< GRE offset */
118765 + volatile uint8_t l4_off; /**< Layer 4 offset */
118766 + volatile uint8_t nxthdr_off; /**< Parser end point */
118767 +} _PackedType t_FmPrsResult;
118768 +
118769 +#endif
118770 --- /dev/null
118771 +++ b/drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_resources_ut.make
118772 @@ -0,0 +1,28 @@
118773 +CC=gcc
118774 +
118775 +LNXWRP_RESS_UT=lnxwrp_resources_ut
118776 +OBJ=lnxwrp_resources
118777 +
118778 +INC_PATH=
118779 +LIB_PATH=
118780 +
118781 +INC=$(addprefix -I,$(INC_PATH))
118782 +LIB=$(addprefix -L,$(LIB_PATH))
118783 +
118784 +CFLAGS= -gdwarf-2 -g -O0 -Wall
118785 +XFLAGS= -DFMAN_RESOURCES_UNIT_TEST
118786 +
118787 +all: $(LNXWRP_RESS_UT)
118788 +
118789 +$(LNXWRP_RESS_UT):$(addsuffix .o,$(OBJ)) $(LNXWRP_RESS_UT).o
118790 + $(CC) -o $(LNXWRP_RESS_UT) $(LNXWRP_RESS_UT).o $(addsuffix .o,$(OBJ))
118791 +
118792 +%.o: %.c
118793 + @(echo " (CC) $@")
118794 + @($(CC) $(INC) $(CFLAGS) $(XFLAGS) -o $(@) -c $<)
118795 +
118796 +.PHONY: clean
118797 +
118798 +clean:
118799 + rm -f *.o
118800 + rm -f $(LNXWRP_RESS_UT)
118801 --- /dev/null
118802 +++ b/drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_sysfs.c
118803 @@ -0,0 +1,60 @@
118804 +/*
118805 + * Copyright 2008-2012 Freescale Semiconductor Inc.
118806 + *
118807 + * Redistribution and use in source and binary forms, with or without
118808 + * modification, are permitted provided that the following conditions are met:
118809 + * * Redistributions of source code must retain the above copyright
118810 + * notice, this list of conditions and the following disclaimer.
118811 + * * Redistributions in binary form must reproduce the above copyright
118812 + * notice, this list of conditions and the following disclaimer in the
118813 + * documentation and/or other materials provided with the distribution.
118814 + * * Neither the name of Freescale Semiconductor nor the
118815 + * names of its contributors may be used to endorse or promote products
118816 + * derived from this software without specific prior written permission.
118817 + *
118818 + *
118819 + * ALTERNATIVELY, this software may be distributed under the terms of the
118820 + * GNU General Public License ("GPL") as published by the Free Software
118821 + * Foundation, either version 2 of that License or (at your option) any
118822 + * later version.
118823 + *
118824 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
118825 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
118826 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
118827 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
118828 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
118829 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
118830 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
118831 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
118832 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
118833 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
118834 + */
118835 +
118836 +/*
118837 + @File lnxwrp_sysfs.c
118838 +
118839 + @Description FM wrapper sysfs related functions.
118840 +
118841 +*/
118842 +
118843 +#include <linux/types.h>
118844 +#include "lnxwrp_sysfs.h"
118845 +
118846 +uint8_t fm_find_statistic_counter_by_name(const char *attr_name,
118847 + const struct sysfs_stats_t *sysfs_stats,
118848 + uint8_t *offset)
118849 +{
118850 + int i = 0;
118851 +
118852 + while (sysfs_stats[i].stat_name != NULL) {
118853 + if (strcmp(sysfs_stats[i].stat_name, attr_name) == 0) {
118854 + if (offset != NULL)
118855 + *offset = i;
118856 + return sysfs_stats[i].stat_counter;
118857 + }
118858 +
118859 + i++;
118860 + }
118861 + WARN(1, "FMD: Should never get here!");
118862 + return 0;
118863 +}
118864 --- /dev/null
118865 +++ b/drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_sysfs.h
118866 @@ -0,0 +1,60 @@
118867 +/*
118868 + * Copyright 2008-2012 Freescale Semiconductor Inc.
118869 + *
118870 + * Redistribution and use in source and binary forms, with or without
118871 + * modification, are permitted provided that the following conditions are met:
118872 + * * Redistributions of source code must retain the above copyright
118873 + * notice, this list of conditions and the following disclaimer.
118874 + * * Redistributions in binary form must reproduce the above copyright
118875 + * notice, this list of conditions and the following disclaimer in the
118876 + * documentation and/or other materials provided with the distribution.
118877 + * * Neither the name of Freescale Semiconductor nor the
118878 + * names of its contributors may be used to endorse or promote products
118879 + * derived from this software without specific prior written permission.
118880 + *
118881 + *
118882 + * ALTERNATIVELY, this software may be distributed under the terms of the
118883 + * GNU General Public License ("GPL") as published by the Free Software
118884 + * Foundation, either version 2 of that License or (at your option) any
118885 + * later version.
118886 + *
118887 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
118888 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
118889 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
118890 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
118891 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
118892 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
118893 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
118894 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
118895 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
118896 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
118897 + */
118898 +
118899 +#ifndef LNXWRP_SYSFS_H_
118900 +#define LNXWRP_SYSFS_H_
118901 +
118902 +/* Linux Headers ------------------- */
118903 +#include <linux/version.h>
118904 +
118905 +#if defined(CONFIG_MODVERSIONS) && !defined(MODVERSIONS)
118906 +#define MODVERSIONS
118907 +#endif
118908 +#ifdef MODVERSIONS
118909 +#include <config/modversions.h>
118910 +#endif /* MODVERSIONS */
118911 +
118912 +#include <linux/kernel.h>
118913 +#include <linux/module.h>
118914 +#include <linux/device.h>
118915 +#include <linux/sysfs.h>
118916 +
118917 +struct sysfs_stats_t {
118918 + const char *stat_name;
118919 + uint8_t stat_counter;
118920 +};
118921 +
118922 +uint8_t fm_find_statistic_counter_by_name(const char *attr_name,
118923 + const struct sysfs_stats_t *sysfs_stats,
118924 + uint8_t *offset);
118925 +
118926 +#endif /* LNXWRP_SYSFS_H_ */
118927 --- /dev/null
118928 +++ b/drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_sysfs_fm.c
118929 @@ -0,0 +1,1855 @@
118930 +/*
118931 + * Copyright 2008-2012 Freescale Semiconductor Inc.
118932 + *
118933 + * Redistribution and use in source and binary forms, with or without
118934 + * modification, are permitted provided that the following conditions are met:
118935 + * * Redistributions of source code must retain the above copyright
118936 + * notice, this list of conditions and the following disclaimer.
118937 + * * Redistributions in binary form must reproduce the above copyright
118938 + * notice, this list of conditions and the following disclaimer in the
118939 + * documentation and/or other materials provided with the distribution.
118940 + * * Neither the name of Freescale Semiconductor nor the
118941 + * names of its contributors may be used to endorse or promote products
118942 + * derived from this software without specific prior written permission.
118943 + *
118944 + *
118945 + * ALTERNATIVELY, this software may be distributed under the terms of the
118946 + * GNU General Public License ("GPL") as published by the Free Software
118947 + * Foundation, either version 2 of that License or (at your option) any
118948 + * later version.
118949 + *
118950 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
118951 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
118952 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
118953 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
118954 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
118955 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
118956 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
118957 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
118958 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
118959 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
118960 + */
118961 +
118962 +#include "lnxwrp_sysfs.h"
118963 +#include "lnxwrp_sysfs_fm.h"
118964 +#include "lnxwrp_fm.h"
118965 +
118966 +#include "../../sdk_fman/Peripherals/FM/inc/fm_common.h"
118967 +#include "../../sdk_fman/Peripherals/FM/Pcd/fm_pcd.h"
118968 +#include "../../sdk_fman/Peripherals/FM/Pcd/fm_kg.h"
118969 +#include "../../sdk_fman/Peripherals/FM/Pcd/fm_plcr.h"
118970 +
118971 +#if defined(__ERR_MODULE__)
118972 +#undef __ERR_MODULE__
118973 +#endif
118974 +
118975 +#include "../../sdk_fman/Peripherals/FM/fm.h"
118976 +#include <linux/delay.h>
118977 +
118978 +
118979 +static int fm_get_counter(void *h_fm, e_FmCounters cnt_e, uint32_t *cnt_val);
118980 +
118981 +enum fm_dma_match_stats {
118982 + FM_DMA_COUNTERS_CMQ_NOT_EMPTY,
118983 + FM_DMA_COUNTERS_BUS_ERROR,
118984 + FM_DMA_COUNTERS_READ_BUF_ECC_ERROR,
118985 + FM_DMA_COUNTERS_WRITE_BUF_ECC_SYS_ERROR,
118986 + FM_DMA_COUNTERS_WRITE_BUF_ECC_FM_ERROR
118987 +};
118988 +
118989 +static const struct sysfs_stats_t fm_sysfs_stats[] = {
118990 + /* FM statistics */
118991 + {
118992 + .stat_name = "enq_total_frame",
118993 + .stat_counter = e_FM_COUNTERS_ENQ_TOTAL_FRAME,
118994 + },
118995 + {
118996 + .stat_name = "deq_total_frame",
118997 + .stat_counter = e_FM_COUNTERS_DEQ_TOTAL_FRAME,
118998 + },
118999 + {
119000 + .stat_name = "deq_0",
119001 + .stat_counter = e_FM_COUNTERS_DEQ_0,
119002 + },
119003 + {
119004 + .stat_name = "deq_1",
119005 + .stat_counter = e_FM_COUNTERS_DEQ_1,
119006 + },
119007 + {
119008 + .stat_name = "deq_2",
119009 + .stat_counter = e_FM_COUNTERS_DEQ_2,
119010 + },
119011 + {
119012 + .stat_name = "deq_3",
119013 + .stat_counter = e_FM_COUNTERS_DEQ_3,
119014 + },
119015 + {
119016 + .stat_name = "deq_from_default",
119017 + .stat_counter = e_FM_COUNTERS_DEQ_FROM_DEFAULT,
119018 + },
119019 + {
119020 + .stat_name = "deq_from_context",
119021 + .stat_counter = e_FM_COUNTERS_DEQ_FROM_CONTEXT,
119022 + },
119023 + {
119024 + .stat_name = "deq_from_fd",
119025 + .stat_counter = e_FM_COUNTERS_DEQ_FROM_FD,
119026 + },
119027 + {
119028 + .stat_name = "deq_confirm",
119029 + .stat_counter = e_FM_COUNTERS_DEQ_CONFIRM,
119030 + },
119031 + /* FM:DMA statistics */
119032 + {
119033 + .stat_name = "cmq_not_empty",
119034 + .stat_counter = FM_DMA_COUNTERS_CMQ_NOT_EMPTY,
119035 + },
119036 + {
119037 + .stat_name = "bus_error",
119038 + .stat_counter = FM_DMA_COUNTERS_BUS_ERROR,
119039 + },
119040 + {
119041 + .stat_name = "read_buf_ecc_error",
119042 + .stat_counter = FM_DMA_COUNTERS_READ_BUF_ECC_ERROR,
119043 + },
119044 + {
119045 + .stat_name = "write_buf_ecc_sys_error",
119046 + .stat_counter = FM_DMA_COUNTERS_WRITE_BUF_ECC_SYS_ERROR,
119047 + },
119048 + {
119049 + .stat_name = "write_buf_ecc_fm_error",
119050 + .stat_counter = FM_DMA_COUNTERS_WRITE_BUF_ECC_FM_ERROR,
119051 + },
119052 + /* FM:PCD statistics */
119053 + {
119054 + .stat_name = "pcd_kg_total",
119055 + .stat_counter = e_FM_PCD_KG_COUNTERS_TOTAL,
119056 + },
119057 + {
119058 + .stat_name = "pcd_plcr_yellow",
119059 + .stat_counter = e_FM_PCD_PLCR_COUNTERS_YELLOW,
119060 + },
119061 + {
119062 + .stat_name = "pcd_plcr_red",
119063 + .stat_counter = e_FM_PCD_PLCR_COUNTERS_RED,
119064 + },
119065 + {
119066 + .stat_name = "pcd_plcr_recolored_to_red",
119067 + .stat_counter = e_FM_PCD_PLCR_COUNTERS_RECOLORED_TO_RED,
119068 + },
119069 + {
119070 + .stat_name = "pcd_plcr_recolored_to_yellow",
119071 + .stat_counter = e_FM_PCD_PLCR_COUNTERS_RECOLORED_TO_YELLOW,
119072 + },
119073 + {
119074 + .stat_name = "pcd_plcr_total",
119075 + .stat_counter = e_FM_PCD_PLCR_COUNTERS_TOTAL,
119076 + },
119077 + {
119078 + .stat_name = "pcd_plcr_length_mismatch",
119079 + .stat_counter = e_FM_PCD_PLCR_COUNTERS_LENGTH_MISMATCH,
119080 + },
119081 + {
119082 + .stat_name = "pcd_prs_parse_dispatch",
119083 + .stat_counter = e_FM_PCD_PRS_COUNTERS_PARSE_DISPATCH,
119084 + },
119085 + {
119086 + .stat_name = "pcd_prs_l2_parse_result_returned",
119087 + .stat_counter = e_FM_PCD_PRS_COUNTERS_L2_PARSE_RESULT_RETURNED,
119088 + },
119089 + {
119090 + .stat_name = "pcd_prs_l3_parse_result_returned",
119091 + .stat_counter = e_FM_PCD_PRS_COUNTERS_L3_PARSE_RESULT_RETURNED,
119092 + },
119093 + {
119094 + .stat_name = "pcd_prs_l4_parse_result_returned",
119095 + .stat_counter = e_FM_PCD_PRS_COUNTERS_L4_PARSE_RESULT_RETURNED,
119096 + },
119097 + {
119098 + .stat_name = "pcd_prs_shim_parse_result_returned",
119099 + .stat_counter = e_FM_PCD_PRS_COUNTERS_SHIM_PARSE_RESULT_RETURNED,
119100 + },
119101 + {
119102 + .stat_name = "pcd_prs_l2_parse_result_returned_with_err",
119103 + .stat_counter =
119104 + e_FM_PCD_PRS_COUNTERS_L2_PARSE_RESULT_RETURNED_WITH_ERR,
119105 + },
119106 + {
119107 + .stat_name = "pcd_prs_l3_parse_result_returned_with_err",
119108 + .stat_counter =
119109 + e_FM_PCD_PRS_COUNTERS_L3_PARSE_RESULT_RETURNED_WITH_ERR,
119110 + },
119111 + {
119112 + .stat_name = "pcd_prs_l4_parse_result_returned_with_err",
119113 + .stat_counter =
119114 + e_FM_PCD_PRS_COUNTERS_L4_PARSE_RESULT_RETURNED_WITH_ERR,
119115 + },
119116 + {
119117 + .stat_name = "pcd_prs_shim_parse_result_returned_with_err",
119118 + .stat_counter =
119119 + e_FM_PCD_PRS_COUNTERS_SHIM_PARSE_RESULT_RETURNED_WITH_ERR,
119120 + },
119121 + {
119122 + .stat_name = "pcd_prs_soft_prs_cycles",
119123 + .stat_counter = e_FM_PCD_PRS_COUNTERS_SOFT_PRS_CYCLES,
119124 + },
119125 + {
119126 + .stat_name = "pcd_prs_soft_prs_stall_cycles",
119127 + .stat_counter = e_FM_PCD_PRS_COUNTERS_SOFT_PRS_STALL_CYCLES,
119128 + },
119129 + {
119130 + .stat_name = "pcd_prs_hard_prs_cycle_incl_stall_cycles",
119131 + .stat_counter =
119132 + e_FM_PCD_PRS_COUNTERS_HARD_PRS_CYCLE_INCL_STALL_CYCLES,
119133 + },
119134 + {
119135 + .stat_name = "pcd_prs_muram_read_cycles",
119136 + .stat_counter = e_FM_PCD_PRS_COUNTERS_MURAM_READ_CYCLES,
119137 + },
119138 + {
119139 + .stat_name = "pcd_prs_muram_read_stall_cycles",
119140 + .stat_counter = e_FM_PCD_PRS_COUNTERS_MURAM_READ_STALL_CYCLES,
119141 + },
119142 + {
119143 + .stat_name = "pcd_prs_muram_write_cycles",
119144 + .stat_counter = e_FM_PCD_PRS_COUNTERS_MURAM_WRITE_CYCLES,
119145 + },
119146 + {
119147 + .stat_name = "pcd_prs_muram_write_stall_cycles",
119148 + .stat_counter = e_FM_PCD_PRS_COUNTERS_MURAM_WRITE_STALL_CYCLES,
119149 + },
119150 + {
119151 + .stat_name = "pcd_prs_fpm_command_stall_cycles",
119152 + .stat_counter = e_FM_PCD_PRS_COUNTERS_FPM_COMMAND_STALL_CYCLES,
119153 + },
119154 + {}
119155 +};
119156 +
119157 +
119158 +static ssize_t show_fm_risc_load(struct device *dev,
119159 + struct device_attribute *attr, char *buf)
119160 +{
119161 + t_LnxWrpFmDev *p_wrp_fm_dev = NULL;
119162 + unsigned long flags;
119163 + int m =0;
119164 + int err =0;
119165 + unsigned n = 0;
119166 + t_FmCtrlMon util;
119167 + uint8_t i =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 + local_irq_save(flags);
119180 +
119181 + /* Calculate risc load */
119182 + FM_CtrlMonStart(p_wrp_fm_dev->h_Dev);
119183 + msleep(1000);
119184 + FM_CtrlMonStop(p_wrp_fm_dev->h_Dev);
119185 +
119186 + for (i = 0; i < FM_NUM_OF_CTRL; i++) {
119187 + err |= FM_CtrlMonGetCounters(p_wrp_fm_dev->h_Dev, i, &util);
119188 + m = snprintf(&buf[n],PAGE_SIZE,"\tRisc%u: util-%u%%, efficiency-%u%%\n",
119189 + i, util.percentCnt[0], util.percentCnt[1]);
119190 + n=m+n;
119191 + }
119192 +
119193 + local_irq_restore(flags);
119194 +
119195 + return n;
119196 +}
119197 +
119198 +/* Fm stats and regs dumps via sysfs */
119199 +static ssize_t show_fm_dma_stats(struct device *dev,
119200 + struct device_attribute *attr, char *buf)
119201 +{
119202 + t_LnxWrpFmDev *p_wrp_fm_dev = NULL;
119203 + t_FmDmaStatus dma_status;
119204 + unsigned long flags = 0;
119205 + unsigned n = 0;
119206 + uint8_t counter_value = 0, counter = 0;
119207 +
119208 + if (attr == NULL || buf == NULL || dev == NULL)
119209 + return -EINVAL;
119210 +
119211 + p_wrp_fm_dev = (t_LnxWrpFmDev *) dev_get_drvdata(dev);
119212 + if (WARN_ON(p_wrp_fm_dev == NULL))
119213 + return -EINVAL;
119214 +
119215 + if (!p_wrp_fm_dev->active || !p_wrp_fm_dev->h_Dev)
119216 + return -EIO;
119217 +
119218 + counter = fm_find_statistic_counter_by_name(
119219 + attr->attr.name,
119220 + fm_sysfs_stats, NULL);
119221 +
119222 + local_irq_save(flags);
119223 +
119224 + memset(&dma_status, 0, sizeof(dma_status));
119225 + FM_GetDmaStatus(p_wrp_fm_dev->h_Dev, &dma_status);
119226 +
119227 + switch (counter) {
119228 + case FM_DMA_COUNTERS_CMQ_NOT_EMPTY:
119229 + counter_value = dma_status.cmqNotEmpty;
119230 + break;
119231 + case FM_DMA_COUNTERS_BUS_ERROR:
119232 + counter_value = dma_status.busError;
119233 + break;
119234 + case FM_DMA_COUNTERS_READ_BUF_ECC_ERROR:
119235 + counter_value = dma_status.readBufEccError;
119236 + break;
119237 + case FM_DMA_COUNTERS_WRITE_BUF_ECC_SYS_ERROR:
119238 + counter_value = dma_status.writeBufEccSysError;
119239 + break;
119240 + case FM_DMA_COUNTERS_WRITE_BUF_ECC_FM_ERROR:
119241 + counter_value = dma_status.writeBufEccFmError;
119242 + break;
119243 + default:
119244 + WARN(1, "FMD: failure at %s:%d/%s()!\n", __FILE__, __LINE__,
119245 + __func__);
119246 + break;
119247 + };
119248 +
119249 + n = snprintf(buf, PAGE_SIZE, "\tFM %u counter: %c\n",
119250 + p_wrp_fm_dev->id, counter_value ? 'T' : 'F');
119251 +
119252 + local_irq_restore(flags);
119253 +
119254 + return n;
119255 +}
119256 +
119257 +static ssize_t show_fm_stats(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, cnt_e = 0;
119263 + uint32_t cnt_val;
119264 + int err;
119265 +
119266 + if (attr == NULL || buf == NULL || dev == NULL)
119267 + return -EINVAL;
119268 +
119269 + p_wrp_fm_dev = (t_LnxWrpFmDev *) dev_get_drvdata(dev);
119270 + if (WARN_ON(p_wrp_fm_dev == NULL))
119271 + return -EINVAL;
119272 +
119273 + if (!p_wrp_fm_dev->active || !p_wrp_fm_dev->h_Dev)
119274 + return -EIO;
119275 +
119276 + cnt_e = fm_find_statistic_counter_by_name(
119277 + attr->attr.name,
119278 + fm_sysfs_stats, NULL);
119279 +
119280 + err = fm_get_counter(p_wrp_fm_dev->h_Dev,
119281 + (e_FmCounters) cnt_e, &cnt_val);
119282 +
119283 + if (err)
119284 + return err;
119285 +
119286 + local_irq_save(flags);
119287 +
119288 + n = snprintf(buf, PAGE_SIZE, "\tFM %d counter: %d\n",
119289 + p_wrp_fm_dev->id, cnt_val);
119290 +
119291 + local_irq_restore(flags);
119292 +
119293 + return n;
119294 +}
119295 +
119296 +static ssize_t show_fm_muram_free_sz(struct device *dev,
119297 + struct device_attribute *attr, char *buf)
119298 +{
119299 + t_LnxWrpFmDev *p_wrp_fm_dev = NULL;
119300 + unsigned long flags = 0;
119301 + unsigned n = 0;
119302 + uint64_t muram_free_size = 0;
119303 +
119304 + if (attr == NULL || buf == NULL || dev == NULL)
119305 + return -EINVAL;
119306 +
119307 + p_wrp_fm_dev = (t_LnxWrpFmDev *) dev_get_drvdata(dev);
119308 + if (WARN_ON(p_wrp_fm_dev == NULL))
119309 + return -EINVAL;
119310 +
119311 + if (!p_wrp_fm_dev->active || !p_wrp_fm_dev->h_Dev)
119312 + return -EIO;
119313 +
119314 + muram_free_size = FM_MURAM_GetFreeMemSize(p_wrp_fm_dev->h_MuramDev);
119315 +
119316 + local_irq_save(flags);
119317 +
119318 + n = snprintf(buf, PAGE_SIZE, "\tFM %d muram_free_size: %lld\n",
119319 + p_wrp_fm_dev->id, muram_free_size);
119320 +
119321 + local_irq_restore(flags);
119322 +
119323 + return n;
119324 +}
119325 +
119326 +static ssize_t show_fm_ctrl_code_ver(struct device *dev,
119327 + struct device_attribute *attr, char *buf)
119328 +{
119329 + t_LnxWrpFmDev *p_wrp_fm_dev = NULL;
119330 + unsigned long flags = 0;
119331 + unsigned n = 0;
119332 + t_FmCtrlCodeRevisionInfo rv_info;
119333 +
119334 + if (attr == NULL || buf == NULL || dev == NULL)
119335 + return -EINVAL;
119336 +
119337 + p_wrp_fm_dev = (t_LnxWrpFmDev *) dev_get_drvdata(dev);
119338 + if (WARN_ON(p_wrp_fm_dev == NULL))
119339 + return -EINVAL;
119340 +
119341 + if (!p_wrp_fm_dev->active || !p_wrp_fm_dev->h_Dev)
119342 + return -EIO;
119343 +
119344 + FM_GetFmanCtrlCodeRevision((t_Fm *)p_wrp_fm_dev->h_Dev, &rv_info);
119345 +
119346 + local_irq_save(flags);
119347 +
119348 + FM_DMP_LN(buf, n, "- FM %d ctrl code pkg info:\n", p_wrp_fm_dev->id);
119349 + FM_DMP_LN(buf, n, "Package rev: %d\n", rv_info.packageRev);
119350 + FM_DMP_LN(buf, n, "major rev: %d\n", rv_info.majorRev);
119351 + FM_DMP_LN(buf, n, "minor rev: %d\n", rv_info.minorRev);
119352 +
119353 + local_irq_restore(flags);
119354 +
119355 + return n;
119356 +}
119357 +
119358 +static ssize_t show_fm_pcd_stats(struct device *dev,
119359 + struct device_attribute *attr, char *buf)
119360 +{
119361 + t_LnxWrpFmDev *p_wrp_fm_dev = NULL;
119362 + unsigned long flags = 0;
119363 + unsigned n = 0, counter = 0;
119364 +
119365 + if (attr == NULL || buf == NULL || dev == NULL)
119366 + return -EINVAL;
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 + if (!p_wrp_fm_dev->active || !p_wrp_fm_dev->h_Dev ||
119373 + !p_wrp_fm_dev->h_PcdDev)
119374 + return -EIO;
119375 +
119376 + counter = fm_find_statistic_counter_by_name(
119377 + attr->attr.name,
119378 + fm_sysfs_stats, NULL);
119379 +
119380 + local_irq_save(flags);
119381 +
119382 + n = snprintf(buf, PAGE_SIZE, "\tFM %d counter: %d\n",
119383 + p_wrp_fm_dev->id,
119384 + FM_PCD_GetCounter(p_wrp_fm_dev->h_PcdDev,
119385 + (e_FmPcdCounters) counter));
119386 +
119387 + local_irq_restore(flags);
119388 +
119389 + return n;
119390 +}
119391 +
119392 +static ssize_t show_fm_tnum_dbg(struct device *dev,
119393 + struct device_attribute *attr,
119394 + char *buf)
119395 +{
119396 + unsigned long flags;
119397 + unsigned n = 0;
119398 +#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
119399 + t_LnxWrpFmDev *p_wrp_fm_dev = NULL;
119400 +#endif
119401 +
119402 + if (attr == NULL || buf == NULL || dev == NULL)
119403 + return -EINVAL;
119404 +
119405 +#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
119406 +
119407 + p_wrp_fm_dev = (t_LnxWrpFmDev *) dev_get_drvdata(dev);
119408 + if (WARN_ON(p_wrp_fm_dev == NULL))
119409 + return -EINVAL;
119410 +
119411 + local_irq_save(flags);
119412 +
119413 + if (!p_wrp_fm_dev->active)
119414 + return -EIO;
119415 + else {
119416 + int tn_s;
119417 +
119418 + if (!sscanf(attr->attr.name, "tnum_dbg_%d", &tn_s))
119419 + return -EINVAL;
119420 +
119421 + n = fm_dump_tnum_dbg(p_wrp_fm_dev->h_Dev,
119422 + tn_s, tn_s + 15, buf, n);
119423 + }
119424 + local_irq_restore(flags);
119425 +#else
119426 +
119427 + local_irq_save(flags);
119428 + n = snprintf(buf, PAGE_SIZE,
119429 + "Debug level is too low to dump registers!!!\n");
119430 + local_irq_restore(flags);
119431 +#endif /* (defined(DEBUG_ERRORS) && ... */
119432 +
119433 + return n;
119434 +}
119435 +
119436 +static ssize_t show_fm_cls_plan(struct device *dev,
119437 + struct device_attribute *attr,
119438 + char *buf)
119439 +{
119440 + unsigned long flags;
119441 + unsigned n = 0;
119442 +#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
119443 + t_LnxWrpFmDev *p_wrp_fm_dev = NULL;
119444 +#endif
119445 +
119446 + if (attr == NULL || buf == NULL || dev == NULL)
119447 + return -EINVAL;
119448 +
119449 +#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
119450 + p_wrp_fm_dev = (t_LnxWrpFmDev *) dev_get_drvdata(dev);
119451 + if (WARN_ON(p_wrp_fm_dev == NULL))
119452 + return -EINVAL;
119453 +
119454 + local_irq_save(flags);
119455 +
119456 + n = snprintf(buf, PAGE_SIZE, "\n FM-KG classification plan dump.\n");
119457 +
119458 + if (!p_wrp_fm_dev->active || !p_wrp_fm_dev->h_PcdDev)
119459 + return -EIO;
119460 + else {
119461 + int cpn;
119462 +
119463 + if (!sscanf(attr->attr.name, "cls_plan_%d", &cpn))
119464 + return -EINVAL;
119465 +
119466 + n = fm_dump_cls_plan(p_wrp_fm_dev->h_PcdDev, cpn, buf, n);
119467 + }
119468 + local_irq_restore(flags);
119469 +#else
119470 + local_irq_save(flags);
119471 + n = snprintf(buf, PAGE_SIZE,
119472 + "Debug level is too low to dump registers!!!\n");
119473 + local_irq_restore(flags);
119474 +#endif /* (defined(DEBUG_ERRORS) && ... */
119475 +
119476 + return n;
119477 +}
119478 +
119479 +static ssize_t show_fm_profiles(struct device *dev,
119480 + struct device_attribute *attr,
119481 + char *buf)
119482 +{
119483 + unsigned long flags;
119484 + unsigned n = 0;
119485 +#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
119486 + t_LnxWrpFmDev *p_wrp_fm_dev = NULL;
119487 +#endif
119488 +
119489 + if (attr == NULL || buf == NULL || dev == NULL)
119490 + return -EINVAL;
119491 +
119492 +#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
119493 +
119494 + p_wrp_fm_dev = (t_LnxWrpFmDev *) dev_get_drvdata(dev);
119495 + if (WARN_ON(p_wrp_fm_dev == NULL))
119496 + return -EINVAL;
119497 +
119498 + local_irq_save(flags);
119499 +
119500 + n = snprintf(buf, PAGE_SIZE, "FM policer profile dump.\n");
119501 +
119502 + if (!p_wrp_fm_dev->active || !p_wrp_fm_dev->h_PcdDev)
119503 + return -EIO;
119504 + else {
119505 + int pn;
119506 +
119507 + if (!sscanf(attr->attr.name, "profile_%d", &pn))
119508 + return -EINVAL;
119509 +
119510 + n = fm_profile_dump_regs(p_wrp_fm_dev->h_PcdDev, pn, buf, n);
119511 + }
119512 + local_irq_restore(flags);
119513 +#else
119514 + local_irq_save(flags);
119515 + n = snprintf(buf, PAGE_SIZE,
119516 + "Debug level is too low to dump registers!!!\n");
119517 + local_irq_restore(flags);
119518 +#endif /* (defined(DEBUG_ERRORS) && ... */
119519 +
119520 + return n;
119521 +}
119522 +
119523 +static ssize_t show_fm_schemes(struct device *dev,
119524 + struct device_attribute *attr,
119525 + char *buf)
119526 +{
119527 + unsigned long flags;
119528 + unsigned n = 0;
119529 +#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
119530 + t_LnxWrpFmDev *p_wrp_fm_dev = NULL;
119531 +#endif
119532 +
119533 + if (attr == NULL || buf == NULL || dev == NULL)
119534 + return -EINVAL;
119535 +
119536 +#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
119537 +
119538 + p_wrp_fm_dev = (t_LnxWrpFmDev *) dev_get_drvdata(dev);
119539 + if (WARN_ON(p_wrp_fm_dev == NULL))
119540 + return -EINVAL;
119541 +
119542 + local_irq_save(flags);
119543 +
119544 + n = snprintf(buf, PAGE_SIZE, "FM-KG driver schemes dump.\n");
119545 +
119546 + if (!p_wrp_fm_dev->active || !p_wrp_fm_dev->h_PcdDev)
119547 + return -EIO;
119548 + else {
119549 + int sn;
119550 +
119551 + if (!sscanf(attr->attr.name, "scheme_%d", &sn))
119552 + return -EINVAL;
119553 +
119554 + n = fm_dump_scheme(p_wrp_fm_dev->h_PcdDev, sn, buf, n);
119555 + }
119556 + local_irq_restore(flags);
119557 +#else
119558 +
119559 + local_irq_save(flags);
119560 + n = snprintf(buf, PAGE_SIZE,
119561 + "Debug level is too low to dump registers!!!\n");
119562 + local_irq_restore(flags);
119563 +#endif /* (defined(DEBUG_ERRORS) && ... */
119564 +
119565 + return n;
119566 +}
119567 +
119568 +/* FM */
119569 +static DEVICE_ATTR(enq_total_frame, S_IRUGO, show_fm_stats, NULL);
119570 +static DEVICE_ATTR(deq_total_frame, S_IRUGO, show_fm_stats, NULL);
119571 +static DEVICE_ATTR(fm_risc_load_val, S_IRUGO, show_fm_risc_load, NULL);
119572 +static DEVICE_ATTR(deq_0, S_IRUGO, show_fm_stats, NULL);
119573 +static DEVICE_ATTR(deq_1, S_IRUGO, show_fm_stats, NULL);
119574 +static DEVICE_ATTR(deq_2, S_IRUGO, show_fm_stats, NULL);
119575 +static DEVICE_ATTR(deq_3, S_IRUGO, show_fm_stats, NULL);
119576 +static DEVICE_ATTR(deq_from_default, S_IRUGO, show_fm_stats, NULL);
119577 +static DEVICE_ATTR(deq_from_context, S_IRUGO, show_fm_stats, NULL);
119578 +static DEVICE_ATTR(deq_from_fd, S_IRUGO, show_fm_stats, NULL);
119579 +static DEVICE_ATTR(deq_confirm, S_IRUGO, show_fm_stats, NULL);
119580 +/* FM:DMA */
119581 +static DEVICE_ATTR(cmq_not_empty, S_IRUGO, show_fm_dma_stats, NULL);
119582 +static DEVICE_ATTR(bus_error, S_IRUGO, show_fm_dma_stats, NULL);
119583 +static DEVICE_ATTR(read_buf_ecc_error, S_IRUGO, show_fm_dma_stats, NULL);
119584 +static DEVICE_ATTR(write_buf_ecc_sys_error, S_IRUGO, show_fm_dma_stats, NULL);
119585 +static DEVICE_ATTR(write_buf_ecc_fm_error, S_IRUGO, show_fm_dma_stats, NULL);
119586 +/* FM:PCD */
119587 +static DEVICE_ATTR(pcd_kg_total, S_IRUGO, show_fm_pcd_stats, NULL);
119588 +static DEVICE_ATTR(pcd_plcr_yellow, S_IRUGO, show_fm_pcd_stats, NULL);
119589 +static DEVICE_ATTR(pcd_plcr_red, S_IRUGO, show_fm_pcd_stats, NULL);
119590 +static DEVICE_ATTR(pcd_plcr_recolored_to_red, S_IRUGO, show_fm_pcd_stats,
119591 + NULL);
119592 +static DEVICE_ATTR(pcd_plcr_recolored_to_yellow, S_IRUGO, show_fm_pcd_stats,
119593 + NULL);
119594 +static DEVICE_ATTR(pcd_plcr_total, S_IRUGO, show_fm_pcd_stats, NULL);
119595 +static DEVICE_ATTR(pcd_plcr_length_mismatch, S_IRUGO, show_fm_pcd_stats,
119596 + NULL);
119597 +static DEVICE_ATTR(pcd_prs_parse_dispatch, S_IRUGO, show_fm_pcd_stats, NULL);
119598 +static DEVICE_ATTR(pcd_prs_l2_parse_result_returned, S_IRUGO,
119599 + show_fm_pcd_stats, NULL);
119600 +static DEVICE_ATTR(pcd_prs_l3_parse_result_returned, S_IRUGO,
119601 + show_fm_pcd_stats, NULL);
119602 +static DEVICE_ATTR(pcd_prs_l4_parse_result_returned, S_IRUGO,
119603 + show_fm_pcd_stats, NULL);
119604 +static DEVICE_ATTR(pcd_prs_shim_parse_result_returned, S_IRUGO,
119605 + show_fm_pcd_stats, NULL);
119606 +static DEVICE_ATTR(pcd_prs_l2_parse_result_returned_with_err, S_IRUGO,
119607 + show_fm_pcd_stats, NULL);
119608 +static DEVICE_ATTR(pcd_prs_l3_parse_result_returned_with_err, S_IRUGO,
119609 + show_fm_pcd_stats, NULL);
119610 +static DEVICE_ATTR(pcd_prs_l4_parse_result_returned_with_err, S_IRUGO,
119611 + show_fm_pcd_stats, NULL);
119612 +static DEVICE_ATTR(pcd_prs_shim_parse_result_returned_with_err, S_IRUGO,
119613 + show_fm_pcd_stats, NULL);
119614 +static DEVICE_ATTR(pcd_prs_soft_prs_cycles, S_IRUGO, show_fm_pcd_stats, NULL);
119615 +static DEVICE_ATTR(pcd_prs_soft_prs_stall_cycles, S_IRUGO, show_fm_pcd_stats,
119616 + NULL);
119617 +static DEVICE_ATTR(pcd_prs_hard_prs_cycle_incl_stall_cycles, S_IRUGO,
119618 + show_fm_pcd_stats, NULL);
119619 +static DEVICE_ATTR(pcd_prs_muram_read_cycles, S_IRUGO, show_fm_pcd_stats,
119620 + NULL);
119621 +static DEVICE_ATTR(pcd_prs_muram_read_stall_cycles, S_IRUGO,
119622 + show_fm_pcd_stats, NULL);
119623 +static DEVICE_ATTR(pcd_prs_muram_write_cycles, S_IRUGO, show_fm_pcd_stats,
119624 + NULL);
119625 +static DEVICE_ATTR(pcd_prs_muram_write_stall_cycles, S_IRUGO,
119626 + show_fm_pcd_stats, NULL);
119627 +static DEVICE_ATTR(pcd_prs_fpm_command_stall_cycles, S_IRUGO,
119628 + show_fm_pcd_stats, NULL);
119629 +
119630 +static DEVICE_ATTR(tnum_dbg_0, S_IRUGO, show_fm_tnum_dbg, NULL);
119631 +static DEVICE_ATTR(tnum_dbg_16, S_IRUGO, show_fm_tnum_dbg, NULL);
119632 +static DEVICE_ATTR(tnum_dbg_32, S_IRUGO, show_fm_tnum_dbg, NULL);
119633 +static DEVICE_ATTR(tnum_dbg_48, S_IRUGO, show_fm_tnum_dbg, NULL);
119634 +static DEVICE_ATTR(tnum_dbg_64, S_IRUGO, show_fm_tnum_dbg, NULL);
119635 +static DEVICE_ATTR(tnum_dbg_80, S_IRUGO, show_fm_tnum_dbg, NULL);
119636 +static DEVICE_ATTR(tnum_dbg_96, S_IRUGO, show_fm_tnum_dbg, NULL);
119637 +static DEVICE_ATTR(tnum_dbg_112, S_IRUGO, show_fm_tnum_dbg, NULL);
119638 +
119639 +static DEVICE_ATTR(cls_plan_0, S_IRUGO, show_fm_cls_plan, NULL);
119640 +static DEVICE_ATTR(cls_plan_1, S_IRUGO, show_fm_cls_plan, NULL);
119641 +static DEVICE_ATTR(cls_plan_2, S_IRUGO, show_fm_cls_plan, NULL);
119642 +static DEVICE_ATTR(cls_plan_3, S_IRUGO, show_fm_cls_plan, NULL);
119643 +static DEVICE_ATTR(cls_plan_4, S_IRUGO, show_fm_cls_plan, NULL);
119644 +static DEVICE_ATTR(cls_plan_5, S_IRUGO, show_fm_cls_plan, NULL);
119645 +static DEVICE_ATTR(cls_plan_6, S_IRUGO, show_fm_cls_plan, NULL);
119646 +static DEVICE_ATTR(cls_plan_7, S_IRUGO, show_fm_cls_plan, NULL);
119647 +static DEVICE_ATTR(cls_plan_8, S_IRUGO, show_fm_cls_plan, NULL);
119648 +static DEVICE_ATTR(cls_plan_9, S_IRUGO, show_fm_cls_plan, NULL);
119649 +static DEVICE_ATTR(cls_plan_10, S_IRUGO, show_fm_cls_plan, NULL);
119650 +static DEVICE_ATTR(cls_plan_11, S_IRUGO, show_fm_cls_plan, NULL);
119651 +static DEVICE_ATTR(cls_plan_12, S_IRUGO, show_fm_cls_plan, NULL);
119652 +static DEVICE_ATTR(cls_plan_13, S_IRUGO, show_fm_cls_plan, NULL);
119653 +static DEVICE_ATTR(cls_plan_14, S_IRUGO, show_fm_cls_plan, NULL);
119654 +static DEVICE_ATTR(cls_plan_15, S_IRUGO, show_fm_cls_plan, NULL);
119655 +static DEVICE_ATTR(cls_plan_16, S_IRUGO, show_fm_cls_plan, NULL);
119656 +static DEVICE_ATTR(cls_plan_17, S_IRUGO, show_fm_cls_plan, NULL);
119657 +static DEVICE_ATTR(cls_plan_18, S_IRUGO, show_fm_cls_plan, NULL);
119658 +static DEVICE_ATTR(cls_plan_19, S_IRUGO, show_fm_cls_plan, NULL);
119659 +static DEVICE_ATTR(cls_plan_20, S_IRUGO, show_fm_cls_plan, NULL);
119660 +static DEVICE_ATTR(cls_plan_21, S_IRUGO, show_fm_cls_plan, NULL);
119661 +static DEVICE_ATTR(cls_plan_22, S_IRUGO, show_fm_cls_plan, NULL);
119662 +static DEVICE_ATTR(cls_plan_23, S_IRUGO, show_fm_cls_plan, NULL);
119663 +static DEVICE_ATTR(cls_plan_24, S_IRUGO, show_fm_cls_plan, NULL);
119664 +static DEVICE_ATTR(cls_plan_25, S_IRUGO, show_fm_cls_plan, NULL);
119665 +static DEVICE_ATTR(cls_plan_26, S_IRUGO, show_fm_cls_plan, NULL);
119666 +static DEVICE_ATTR(cls_plan_27, S_IRUGO, show_fm_cls_plan, NULL);
119667 +static DEVICE_ATTR(cls_plan_28, S_IRUGO, show_fm_cls_plan, NULL);
119668 +static DEVICE_ATTR(cls_plan_29, S_IRUGO, show_fm_cls_plan, NULL);
119669 +static DEVICE_ATTR(cls_plan_30, S_IRUGO, show_fm_cls_plan, NULL);
119670 +static DEVICE_ATTR(cls_plan_31, S_IRUGO, show_fm_cls_plan, NULL);
119671 +
119672 +static DEVICE_ATTR(profile_0, S_IRUGO, show_fm_profiles, NULL);
119673 +static DEVICE_ATTR(profile_1, S_IRUGO, show_fm_profiles, NULL);
119674 +static DEVICE_ATTR(profile_2, S_IRUGO, show_fm_profiles, NULL);
119675 +static DEVICE_ATTR(profile_3, S_IRUGO, show_fm_profiles, NULL);
119676 +static DEVICE_ATTR(profile_4, S_IRUGO, show_fm_profiles, NULL);
119677 +static DEVICE_ATTR(profile_5, S_IRUGO, show_fm_profiles, NULL);
119678 +static DEVICE_ATTR(profile_6, S_IRUGO, show_fm_profiles, NULL);
119679 +static DEVICE_ATTR(profile_7, S_IRUGO, show_fm_profiles, NULL);
119680 +static DEVICE_ATTR(profile_8, S_IRUGO, show_fm_profiles, NULL);
119681 +static DEVICE_ATTR(profile_9, S_IRUGO, show_fm_profiles, NULL);
119682 +static DEVICE_ATTR(profile_10, S_IRUGO, show_fm_profiles, NULL);
119683 +static DEVICE_ATTR(profile_11, S_IRUGO, show_fm_profiles, NULL);
119684 +static DEVICE_ATTR(profile_12, S_IRUGO, show_fm_profiles, NULL);
119685 +static DEVICE_ATTR(profile_13, S_IRUGO, show_fm_profiles, NULL);
119686 +static DEVICE_ATTR(profile_14, S_IRUGO, show_fm_profiles, NULL);
119687 +static DEVICE_ATTR(profile_15, S_IRUGO, show_fm_profiles, NULL);
119688 +static DEVICE_ATTR(profile_16, S_IRUGO, show_fm_profiles, NULL);
119689 +static DEVICE_ATTR(profile_17, S_IRUGO, show_fm_profiles, NULL);
119690 +static DEVICE_ATTR(profile_18, S_IRUGO, show_fm_profiles, NULL);
119691 +static DEVICE_ATTR(profile_19, S_IRUGO, show_fm_profiles, NULL);
119692 +static DEVICE_ATTR(profile_20, S_IRUGO, show_fm_profiles, NULL);
119693 +static DEVICE_ATTR(profile_21, S_IRUGO, show_fm_profiles, NULL);
119694 +static DEVICE_ATTR(profile_22, S_IRUGO, show_fm_profiles, NULL);
119695 +static DEVICE_ATTR(profile_23, S_IRUGO, show_fm_profiles, NULL);
119696 +static DEVICE_ATTR(profile_24, S_IRUGO, show_fm_profiles, NULL);
119697 +static DEVICE_ATTR(profile_25, S_IRUGO, show_fm_profiles, NULL);
119698 +static DEVICE_ATTR(profile_26, S_IRUGO, show_fm_profiles, NULL);
119699 +static DEVICE_ATTR(profile_27, S_IRUGO, show_fm_profiles, NULL);
119700 +static DEVICE_ATTR(profile_28, S_IRUGO, show_fm_profiles, NULL);
119701 +static DEVICE_ATTR(profile_29, S_IRUGO, show_fm_profiles, NULL);
119702 +static DEVICE_ATTR(profile_30, S_IRUGO, show_fm_profiles, NULL);
119703 +static DEVICE_ATTR(profile_31, S_IRUGO, show_fm_profiles, NULL);
119704 +
119705 +static DEVICE_ATTR(scheme_0, S_IRUGO, show_fm_schemes, NULL);
119706 +static DEVICE_ATTR(scheme_1, S_IRUGO, show_fm_schemes, NULL);
119707 +static DEVICE_ATTR(scheme_2, S_IRUGO, show_fm_schemes, NULL);
119708 +static DEVICE_ATTR(scheme_3, S_IRUGO, show_fm_schemes, NULL);
119709 +static DEVICE_ATTR(scheme_4, S_IRUGO, show_fm_schemes, NULL);
119710 +static DEVICE_ATTR(scheme_5, S_IRUGO, show_fm_schemes, NULL);
119711 +static DEVICE_ATTR(scheme_6, S_IRUGO, show_fm_schemes, NULL);
119712 +static DEVICE_ATTR(scheme_7, S_IRUGO, show_fm_schemes, NULL);
119713 +static DEVICE_ATTR(scheme_8, S_IRUGO, show_fm_schemes, NULL);
119714 +static DEVICE_ATTR(scheme_9, S_IRUGO, show_fm_schemes, NULL);
119715 +static DEVICE_ATTR(scheme_10, S_IRUGO, show_fm_schemes, NULL);
119716 +static DEVICE_ATTR(scheme_11, S_IRUGO, show_fm_schemes, NULL);
119717 +static DEVICE_ATTR(scheme_12, S_IRUGO, show_fm_schemes, NULL);
119718 +static DEVICE_ATTR(scheme_13, S_IRUGO, show_fm_schemes, NULL);
119719 +static DEVICE_ATTR(scheme_14, S_IRUGO, show_fm_schemes, NULL);
119720 +static DEVICE_ATTR(scheme_15, S_IRUGO, show_fm_schemes, NULL);
119721 +static DEVICE_ATTR(scheme_16, S_IRUGO, show_fm_schemes, NULL);
119722 +static DEVICE_ATTR(scheme_17, S_IRUGO, show_fm_schemes, NULL);
119723 +static DEVICE_ATTR(scheme_18, S_IRUGO, show_fm_schemes, NULL);
119724 +static DEVICE_ATTR(scheme_19, S_IRUGO, show_fm_schemes, NULL);
119725 +static DEVICE_ATTR(scheme_20, S_IRUGO, show_fm_schemes, NULL);
119726 +static DEVICE_ATTR(scheme_21, S_IRUGO, show_fm_schemes, NULL);
119727 +static DEVICE_ATTR(scheme_22, S_IRUGO, show_fm_schemes, NULL);
119728 +static DEVICE_ATTR(scheme_23, S_IRUGO, show_fm_schemes, NULL);
119729 +static DEVICE_ATTR(scheme_24, S_IRUGO, show_fm_schemes, NULL);
119730 +static DEVICE_ATTR(scheme_25, S_IRUGO, show_fm_schemes, NULL);
119731 +static DEVICE_ATTR(scheme_26, S_IRUGO, show_fm_schemes, NULL);
119732 +static DEVICE_ATTR(scheme_27, S_IRUGO, show_fm_schemes, NULL);
119733 +static DEVICE_ATTR(scheme_28, S_IRUGO, show_fm_schemes, NULL);
119734 +static DEVICE_ATTR(scheme_29, S_IRUGO, show_fm_schemes, NULL);
119735 +static DEVICE_ATTR(scheme_30, S_IRUGO, show_fm_schemes, NULL);
119736 +static DEVICE_ATTR(scheme_31, S_IRUGO, show_fm_schemes, NULL);
119737 +
119738 +
119739 +static struct attribute *fm_dev_stats_attributes[] = {
119740 + &dev_attr_enq_total_frame.attr,
119741 + &dev_attr_deq_total_frame.attr,
119742 + &dev_attr_deq_0.attr,
119743 + &dev_attr_deq_1.attr,
119744 + &dev_attr_deq_2.attr,
119745 + &dev_attr_deq_3.attr,
119746 + &dev_attr_deq_from_default.attr,
119747 + &dev_attr_deq_from_context.attr,
119748 + &dev_attr_deq_from_fd.attr,
119749 + &dev_attr_deq_confirm.attr,
119750 + &dev_attr_cmq_not_empty.attr,
119751 + &dev_attr_bus_error.attr,
119752 + &dev_attr_read_buf_ecc_error.attr,
119753 + &dev_attr_write_buf_ecc_sys_error.attr,
119754 + &dev_attr_write_buf_ecc_fm_error.attr,
119755 + &dev_attr_pcd_kg_total.attr,
119756 + &dev_attr_pcd_plcr_yellow.attr,
119757 + &dev_attr_pcd_plcr_red.attr,
119758 + &dev_attr_pcd_plcr_recolored_to_red.attr,
119759 + &dev_attr_pcd_plcr_recolored_to_yellow.attr,
119760 + &dev_attr_pcd_plcr_total.attr,
119761 + &dev_attr_pcd_plcr_length_mismatch.attr,
119762 + &dev_attr_pcd_prs_parse_dispatch.attr,
119763 + &dev_attr_pcd_prs_l2_parse_result_returned.attr,
119764 + &dev_attr_pcd_prs_l3_parse_result_returned.attr,
119765 + &dev_attr_pcd_prs_l4_parse_result_returned.attr,
119766 + &dev_attr_pcd_prs_shim_parse_result_returned.attr,
119767 + &dev_attr_pcd_prs_l2_parse_result_returned_with_err.attr,
119768 + &dev_attr_pcd_prs_l3_parse_result_returned_with_err.attr,
119769 + &dev_attr_pcd_prs_l4_parse_result_returned_with_err.attr,
119770 + &dev_attr_pcd_prs_shim_parse_result_returned_with_err.attr,
119771 + &dev_attr_pcd_prs_soft_prs_cycles.attr,
119772 + &dev_attr_pcd_prs_soft_prs_stall_cycles.attr,
119773 + &dev_attr_pcd_prs_hard_prs_cycle_incl_stall_cycles.attr,
119774 + &dev_attr_pcd_prs_muram_read_cycles.attr,
119775 + &dev_attr_pcd_prs_muram_read_stall_cycles.attr,
119776 + &dev_attr_pcd_prs_muram_write_cycles.attr,
119777 + &dev_attr_pcd_prs_muram_write_stall_cycles.attr,
119778 + &dev_attr_pcd_prs_fpm_command_stall_cycles.attr,
119779 + NULL
119780 +};
119781 +
119782 +static struct attribute *fm_dev_tnums_dbg_attributes[] = {
119783 + &dev_attr_tnum_dbg_0.attr,
119784 + &dev_attr_tnum_dbg_16.attr,
119785 + &dev_attr_tnum_dbg_32.attr,
119786 + &dev_attr_tnum_dbg_48.attr,
119787 + &dev_attr_tnum_dbg_64.attr,
119788 + &dev_attr_tnum_dbg_80.attr,
119789 + &dev_attr_tnum_dbg_96.attr,
119790 + &dev_attr_tnum_dbg_112.attr,
119791 + NULL
119792 +};
119793 +
119794 +static struct attribute *fm_dev_cls_plans_attributes[] = {
119795 + &dev_attr_cls_plan_0.attr,
119796 + &dev_attr_cls_plan_1.attr,
119797 + &dev_attr_cls_plan_2.attr,
119798 + &dev_attr_cls_plan_3.attr,
119799 + &dev_attr_cls_plan_4.attr,
119800 + &dev_attr_cls_plan_5.attr,
119801 + &dev_attr_cls_plan_6.attr,
119802 + &dev_attr_cls_plan_7.attr,
119803 + &dev_attr_cls_plan_8.attr,
119804 + &dev_attr_cls_plan_9.attr,
119805 + &dev_attr_cls_plan_10.attr,
119806 + &dev_attr_cls_plan_11.attr,
119807 + &dev_attr_cls_plan_12.attr,
119808 + &dev_attr_cls_plan_13.attr,
119809 + &dev_attr_cls_plan_14.attr,
119810 + &dev_attr_cls_plan_15.attr,
119811 + &dev_attr_cls_plan_16.attr,
119812 + &dev_attr_cls_plan_17.attr,
119813 + &dev_attr_cls_plan_18.attr,
119814 + &dev_attr_cls_plan_19.attr,
119815 + &dev_attr_cls_plan_20.attr,
119816 + &dev_attr_cls_plan_21.attr,
119817 + &dev_attr_cls_plan_22.attr,
119818 + &dev_attr_cls_plan_23.attr,
119819 + &dev_attr_cls_plan_24.attr,
119820 + &dev_attr_cls_plan_25.attr,
119821 + &dev_attr_cls_plan_26.attr,
119822 + &dev_attr_cls_plan_27.attr,
119823 + &dev_attr_cls_plan_28.attr,
119824 + &dev_attr_cls_plan_29.attr,
119825 + &dev_attr_cls_plan_30.attr,
119826 + &dev_attr_cls_plan_31.attr,
119827 + NULL
119828 +};
119829 +
119830 +static struct attribute *fm_dev_profiles_attributes[] = {
119831 + &dev_attr_profile_0.attr,
119832 + &dev_attr_profile_1.attr,
119833 + &dev_attr_profile_2.attr,
119834 + &dev_attr_profile_3.attr,
119835 + &dev_attr_profile_4.attr,
119836 + &dev_attr_profile_5.attr,
119837 + &dev_attr_profile_6.attr,
119838 + &dev_attr_profile_7.attr,
119839 + &dev_attr_profile_8.attr,
119840 + &dev_attr_profile_9.attr,
119841 + &dev_attr_profile_10.attr,
119842 + &dev_attr_profile_11.attr,
119843 + &dev_attr_profile_12.attr,
119844 + &dev_attr_profile_13.attr,
119845 + &dev_attr_profile_14.attr,
119846 + &dev_attr_profile_15.attr,
119847 + &dev_attr_profile_16.attr,
119848 + &dev_attr_profile_17.attr,
119849 + &dev_attr_profile_18.attr,
119850 + &dev_attr_profile_19.attr,
119851 + &dev_attr_profile_20.attr,
119852 + &dev_attr_profile_21.attr,
119853 + &dev_attr_profile_22.attr,
119854 + &dev_attr_profile_23.attr,
119855 + &dev_attr_profile_24.attr,
119856 + &dev_attr_profile_25.attr,
119857 + &dev_attr_profile_26.attr,
119858 + &dev_attr_profile_27.attr,
119859 + &dev_attr_profile_28.attr,
119860 + &dev_attr_profile_29.attr,
119861 + &dev_attr_profile_30.attr,
119862 + &dev_attr_profile_31.attr,
119863 + NULL
119864 +};
119865 +
119866 +static struct attribute *fm_dev_schemes_attributes[] = {
119867 + &dev_attr_scheme_0.attr,
119868 + &dev_attr_scheme_1.attr,
119869 + &dev_attr_scheme_2.attr,
119870 + &dev_attr_scheme_3.attr,
119871 + &dev_attr_scheme_4.attr,
119872 + &dev_attr_scheme_5.attr,
119873 + &dev_attr_scheme_6.attr,
119874 + &dev_attr_scheme_7.attr,
119875 + &dev_attr_scheme_8.attr,
119876 + &dev_attr_scheme_9.attr,
119877 + &dev_attr_scheme_10.attr,
119878 + &dev_attr_scheme_11.attr,
119879 + &dev_attr_scheme_12.attr,
119880 + &dev_attr_scheme_13.attr,
119881 + &dev_attr_scheme_14.attr,
119882 + &dev_attr_scheme_15.attr,
119883 + &dev_attr_scheme_16.attr,
119884 + &dev_attr_scheme_17.attr,
119885 + &dev_attr_scheme_18.attr,
119886 + &dev_attr_scheme_19.attr,
119887 + &dev_attr_scheme_20.attr,
119888 + &dev_attr_scheme_21.attr,
119889 + &dev_attr_scheme_22.attr,
119890 + &dev_attr_scheme_23.attr,
119891 + &dev_attr_scheme_24.attr,
119892 + &dev_attr_scheme_25.attr,
119893 + &dev_attr_scheme_26.attr,
119894 + &dev_attr_scheme_27.attr,
119895 + &dev_attr_scheme_28.attr,
119896 + &dev_attr_scheme_29.attr,
119897 + &dev_attr_scheme_30.attr,
119898 + &dev_attr_scheme_31.attr,
119899 + NULL
119900 +};
119901 +
119902 +static const struct attribute_group fm_dev_stats_attr_grp = {
119903 + .name = "statistics",
119904 + .attrs = fm_dev_stats_attributes
119905 +};
119906 +
119907 +static const struct attribute_group fm_dev_tnums_dbg_attr_grp = {
119908 + .name = "tnums_dbg",
119909 + .attrs = fm_dev_tnums_dbg_attributes
119910 +};
119911 +
119912 +static const struct attribute_group fm_dev_cls_plans_attr_grp = {
119913 + .name = "cls_plans",
119914 + .attrs = fm_dev_cls_plans_attributes
119915 +};
119916 +
119917 +static const struct attribute_group fm_dev_schemes_attr_grp = {
119918 + .name = "schemes",
119919 + .attrs = fm_dev_schemes_attributes
119920 +};
119921 +
119922 +static const struct attribute_group fm_dev_profiles_attr_grp = {
119923 + .name = "profiles",
119924 + .attrs = fm_dev_profiles_attributes
119925 +};
119926 +
119927 +static ssize_t show_fm_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 + if (attr == NULL || buf == NULL || dev == NULL)
119937 + return -EINVAL;
119938 +
119939 +#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
119940 +
119941 + p_wrp_fm_dev = (t_LnxWrpFmDev *) dev_get_drvdata(dev);
119942 + if (WARN_ON(p_wrp_fm_dev == NULL))
119943 + return -EINVAL;
119944 +
119945 + local_irq_save(flags);
119946 +
119947 + n = snprintf(buf, PAGE_SIZE, "FM driver registers dump.\n");
119948 +
119949 + if (!p_wrp_fm_dev->active || !p_wrp_fm_dev->h_Dev)
119950 + return -EIO;
119951 + else
119952 + n = fm_dump_regs(p_wrp_fm_dev->h_Dev, buf, n);
119953 +
119954 + local_irq_restore(flags);
119955 +#else
119956 +
119957 + local_irq_save(flags);
119958 + n = snprintf(buf, PAGE_SIZE,
119959 + "Debug level is too low to dump registers!!!\n");
119960 + local_irq_restore(flags);
119961 +#endif /* (defined(DEBUG_ERRORS) && ... */
119962 +
119963 + return n;
119964 +}
119965 +
119966 +static ssize_t show_fm_kg_pe_regs(struct device *dev,
119967 + struct device_attribute *attr,
119968 + char *buf)
119969 +{
119970 + unsigned long flags;
119971 + unsigned n = 0;
119972 +#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
119973 + t_LnxWrpFmDev *p_wrp_fm_dev = NULL;
119974 +#endif
119975 +
119976 + if (attr == NULL || buf == NULL || dev == NULL)
119977 + return -EINVAL;
119978 +
119979 +#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
119980 +
119981 + p_wrp_fm_dev = (t_LnxWrpFmDev *) dev_get_drvdata(dev);
119982 + if (WARN_ON(p_wrp_fm_dev == NULL))
119983 + return -EINVAL;
119984 +
119985 + local_irq_save(flags);
119986 +
119987 + n = snprintf(buf, PAGE_SIZE,
119988 + "\n FM-KG Port Partition Config registers dump.\n");
119989 +
119990 + if (!p_wrp_fm_dev->active || !p_wrp_fm_dev->h_PcdDev)
119991 + return -EIO;
119992 + else
119993 + n = fm_kg_pe_dump_regs(p_wrp_fm_dev->h_PcdDev, buf, n);
119994 +
119995 + local_irq_restore(flags);
119996 +#else
119997 +
119998 + local_irq_save(flags);
119999 + n = snprintf(buf, PAGE_SIZE,
120000 + "Debug level is too low to dump registers!!!\n");
120001 + local_irq_restore(flags);
120002 +#endif /* (defined(DEBUG_ERRORS) && ... */
120003 +
120004 + return n;
120005 +}
120006 +
120007 +static ssize_t show_fm_kg_regs(struct device *dev,
120008 + struct device_attribute *attr,
120009 + char *buf)
120010 +{
120011 + unsigned long flags;
120012 + unsigned n = 0;
120013 +#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
120014 + t_LnxWrpFmDev *p_wrp_fm_dev = NULL;
120015 +#endif
120016 +
120017 + if (attr == NULL || buf == NULL || dev == NULL)
120018 + return -EINVAL;
120019 +
120020 +#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
120021 +
120022 + p_wrp_fm_dev = (t_LnxWrpFmDev *) dev_get_drvdata(dev);
120023 + if (WARN_ON(p_wrp_fm_dev == NULL))
120024 + return -EINVAL;
120025 +
120026 + local_irq_save(flags);
120027 +
120028 + n = snprintf(buf, PAGE_SIZE, "FM-KG registers dump.\n");
120029 +
120030 + if (!p_wrp_fm_dev->active || !p_wrp_fm_dev->h_PcdDev)
120031 + return -EIO;
120032 + else
120033 + n = fm_kg_dump_regs(p_wrp_fm_dev->h_PcdDev, buf, n);
120034 +
120035 + local_irq_restore(flags);
120036 +#else
120037 +
120038 + local_irq_save(flags);
120039 + n = snprintf(buf, PAGE_SIZE,
120040 + "Debug level is too low to dump registers!!!\n");
120041 + local_irq_restore(flags);
120042 +#endif /* (defined(DEBUG_ERRORS) && ... */
120043 +
120044 + return n;
120045 +}
120046 +
120047 +
120048 +static ssize_t show_fm_fpm_regs(struct device *dev,
120049 + struct device_attribute *attr,
120050 + 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 +
120063 + p_wrp_fm_dev = (t_LnxWrpFmDev *) dev_get_drvdata(dev);
120064 + if (WARN_ON(p_wrp_fm_dev == NULL))
120065 + return -EINVAL;
120066 +
120067 + local_irq_save(flags);
120068 +
120069 + n = snprintf(buf, PAGE_SIZE, "FM-FPM registers dump.\n");
120070 +
120071 + if (!p_wrp_fm_dev->active || !p_wrp_fm_dev->h_Dev)
120072 + return -EIO;
120073 + else
120074 + n = fm_fpm_dump_regs(p_wrp_fm_dev->h_Dev, buf, n);
120075 +
120076 + local_irq_restore(flags);
120077 +#else
120078 +
120079 + local_irq_save(flags);
120080 + n = snprintf(buf, PAGE_SIZE,
120081 + "Debug level is too low to dump registers!!!\n");
120082 + local_irq_restore(flags);
120083 +#endif /* (defined(DEBUG_ERRORS) && ... */
120084 +
120085 + return n;
120086 +}
120087 +
120088 +static ssize_t show_prs_regs(struct device *dev,
120089 + struct device_attribute *attr, 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_prs_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 ssize_t show_plcr_regs(struct device *dev,
120127 + struct device_attribute *attr,
120128 + char *buf)
120129 +{
120130 + unsigned long flags;
120131 + unsigned n = 0;
120132 +#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
120133 + t_LnxWrpFmDev *p_wrp_fm_dev = NULL;
120134 +#endif
120135 +
120136 + if (attr == NULL || buf == NULL || dev == NULL)
120137 + return -EINVAL;
120138 +
120139 +#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
120140 + p_wrp_fm_dev = (t_LnxWrpFmDev *) dev_get_drvdata(dev);
120141 + if (WARN_ON(p_wrp_fm_dev == NULL))
120142 + return -EINVAL;
120143 +
120144 + local_irq_save(flags);
120145 + n = snprintf(buf, PAGE_SIZE, "FM Policer registers dump.\n");
120146 +
120147 + if (!p_wrp_fm_dev->active || !p_wrp_fm_dev->h_PcdDev)
120148 + return -EIO;
120149 + else
120150 + n = fm_plcr_dump_regs(p_wrp_fm_dev->h_PcdDev, buf, n);
120151 +
120152 + local_irq_restore(flags);
120153 +#else
120154 +
120155 + local_irq_save(flags);
120156 + n = snprintf(buf, PAGE_SIZE,
120157 + "Debug level is too low to dump registers!!!\n");
120158 + local_irq_restore(flags);
120159 +
120160 +#endif /* (defined(DEBUG_ERRORS) && ... */
120161 +
120162 + return n;
120163 +}
120164 +
120165 +static DEVICE_ATTR(fm_regs, S_IRUGO, show_fm_regs, NULL);
120166 +static DEVICE_ATTR(fm_fpm_regs, S_IRUGO, show_fm_fpm_regs, NULL);
120167 +static DEVICE_ATTR(fm_kg_regs, S_IRUGO, show_fm_kg_regs, NULL);
120168 +static DEVICE_ATTR(fm_kg_pe_regs, S_IRUGO, show_fm_kg_pe_regs, NULL);
120169 +static DEVICE_ATTR(fm_plcr_regs, S_IRUGO, show_plcr_regs, NULL);
120170 +static DEVICE_ATTR(fm_prs_regs, S_IRUGO, show_prs_regs, NULL);
120171 +static DEVICE_ATTR(fm_muram_free_size, S_IRUGO, show_fm_muram_free_sz, NULL);
120172 +static DEVICE_ATTR(fm_ctrl_code_ver, S_IRUGO, show_fm_ctrl_code_ver, NULL);
120173 +
120174 +int fm_sysfs_create(struct device *dev)
120175 +{
120176 + t_LnxWrpFmDev *p_wrp_fm_dev = NULL;
120177 +
120178 + if (dev == NULL)
120179 + return -EIO;
120180 +
120181 + p_wrp_fm_dev = (t_LnxWrpFmDev *) dev_get_drvdata(dev);
120182 +
120183 + /* store to remove them when module is disabled */
120184 + p_wrp_fm_dev->dev_attr_regs = &dev_attr_fm_regs;
120185 + p_wrp_fm_dev->dev_attr_risc_load = &dev_attr_fm_risc_load_val;
120186 + p_wrp_fm_dev->dev_fm_fpm_attr_regs = &dev_attr_fm_fpm_regs;
120187 + p_wrp_fm_dev->dev_fm_kg_attr_regs = &dev_attr_fm_kg_regs;
120188 + p_wrp_fm_dev->dev_fm_kg_pe_attr_regs = &dev_attr_fm_kg_pe_regs;
120189 + p_wrp_fm_dev->dev_plcr_attr_regs = &dev_attr_fm_plcr_regs;
120190 + p_wrp_fm_dev->dev_prs_attr_regs = &dev_attr_fm_prs_regs;
120191 + p_wrp_fm_dev->dev_attr_muram_free_size = &dev_attr_fm_muram_free_size;
120192 + p_wrp_fm_dev->dev_attr_fm_ctrl_code_ver = &dev_attr_fm_ctrl_code_ver;
120193 +
120194 + /* Create sysfs statistics group for FM module */
120195 + if (sysfs_create_group(&dev->kobj, &fm_dev_stats_attr_grp) != 0)
120196 + return -EIO;
120197 +
120198 + if (sysfs_create_group(&dev->kobj, &fm_dev_schemes_attr_grp) != 0)
120199 + return -EIO;
120200 +
120201 + if (sysfs_create_group(&dev->kobj, &fm_dev_profiles_attr_grp) != 0)
120202 + return -EIO;
120203 +
120204 + if (sysfs_create_group(&dev->kobj, &fm_dev_tnums_dbg_attr_grp) != 0)
120205 + return -EIO;
120206 +
120207 + if (sysfs_create_group(&dev->kobj, &fm_dev_cls_plans_attr_grp) != 0)
120208 + return -EIO;
120209 +
120210 + /* Registers dump entry - in future will be moved to debugfs */
120211 + if (device_create_file(dev, &dev_attr_fm_regs) != 0)
120212 + return -EIO;
120213 +
120214 + if (device_create_file(dev, &dev_attr_fm_risc_load_val) != 0)
120215 + return -EIO;
120216 +
120217 + if (device_create_file(dev, &dev_attr_fm_fpm_regs) != 0)
120218 + return -EIO;
120219 +
120220 + if (device_create_file(dev, &dev_attr_fm_kg_regs) != 0)
120221 + return -EIO;
120222 +
120223 + if (device_create_file(dev, &dev_attr_fm_kg_pe_regs) != 0)
120224 + return -EIO;
120225 +
120226 + if (device_create_file(dev, &dev_attr_fm_plcr_regs) != 0)
120227 + return -EIO;
120228 +
120229 + if (device_create_file(dev, &dev_attr_fm_prs_regs) != 0)
120230 + return -EIO;
120231 +
120232 + /* muram free size */
120233 + if (device_create_file(dev, &dev_attr_fm_muram_free_size) != 0)
120234 + return -EIO;
120235 +
120236 + /* fm ctrl code version */
120237 + if (device_create_file(dev, &dev_attr_fm_ctrl_code_ver) != 0)
120238 + return -EIO;
120239 +
120240 + return 0;
120241 +}
120242 +
120243 +void fm_sysfs_destroy(struct device *dev)
120244 +{
120245 + t_LnxWrpFmDev *p_wrp_fm_dev = NULL;
120246 +
120247 + if (WARN_ON(dev == NULL))
120248 + return;
120249 +
120250 + p_wrp_fm_dev = (t_LnxWrpFmDev *) dev_get_drvdata(dev);
120251 + if (WARN_ON(p_wrp_fm_dev == NULL))
120252 + return;
120253 +
120254 + sysfs_remove_group(&dev->kobj, &fm_dev_stats_attr_grp);
120255 + sysfs_remove_group(&dev->kobj, &fm_dev_schemes_attr_grp);
120256 + sysfs_remove_group(&dev->kobj, &fm_dev_profiles_attr_grp);
120257 + sysfs_remove_group(&dev->kobj, &fm_dev_cls_plans_attr_grp);
120258 + sysfs_remove_group(&dev->kobj, &fm_dev_tnums_dbg_attr_grp);
120259 + device_remove_file(dev, p_wrp_fm_dev->dev_attr_regs);
120260 + device_remove_file(dev, p_wrp_fm_dev->dev_fm_fpm_attr_regs);
120261 + device_remove_file(dev, p_wrp_fm_dev->dev_fm_kg_attr_regs);
120262 + device_remove_file(dev, p_wrp_fm_dev->dev_fm_kg_pe_attr_regs);
120263 + device_remove_file(dev, p_wrp_fm_dev->dev_plcr_attr_regs);
120264 + device_remove_file(dev, p_wrp_fm_dev->dev_prs_attr_regs);
120265 + device_remove_file(dev, p_wrp_fm_dev->dev_attr_muram_free_size);
120266 + device_remove_file(dev, p_wrp_fm_dev->dev_attr_fm_ctrl_code_ver);
120267 +}
120268 +
120269 +int fm_dump_regs(void *h_fm, char *buf, int nn)
120270 +{
120271 + t_Fm *p_Fm = (t_Fm *)h_fm;
120272 + uint8_t i = 0;
120273 + int n = nn;
120274 +
120275 + FM_DMP_SUBTITLE(buf, n, "\n");
120276 +
120277 + FM_DMP_TITLE(buf, n, p_Fm->p_FmDmaRegs, "FM-DMA Regs");
120278 +
120279 + FM_DMP_V32(buf, n, p_Fm->p_FmDmaRegs, fmdmsr);
120280 + FM_DMP_V32(buf, n, p_Fm->p_FmDmaRegs, fmdmemsr);
120281 + FM_DMP_V32(buf, n, p_Fm->p_FmDmaRegs, fmdmmr);
120282 + FM_DMP_V32(buf, n, p_Fm->p_FmDmaRegs, fmdmtr);
120283 + FM_DMP_V32(buf, n, p_Fm->p_FmDmaRegs, fmdmhy);
120284 + FM_DMP_V32(buf, n, p_Fm->p_FmDmaRegs, fmdmsetr);
120285 + FM_DMP_V32(buf, n, p_Fm->p_FmDmaRegs, fmdmtah);
120286 + FM_DMP_V32(buf, n, p_Fm->p_FmDmaRegs, fmdmtal);
120287 + FM_DMP_V32(buf, n, p_Fm->p_FmDmaRegs, fmdmtcid);
120288 + FM_DMP_V32(buf, n, p_Fm->p_FmDmaRegs, fmdmra);
120289 + FM_DMP_V32(buf, n, p_Fm->p_FmDmaRegs, fmdmrd);
120290 + FM_DMP_V32(buf, n, p_Fm->p_FmDmaRegs, fmdmwcr);
120291 + FM_DMP_V32(buf, n, p_Fm->p_FmDmaRegs, fmdmebcr);
120292 + FM_DMP_V32(buf, n, p_Fm->p_FmDmaRegs, fmdmdcr);
120293 +
120294 + FM_DMP_TITLE(buf, n, &p_Fm->p_FmDmaRegs->fmdmplr, "fmdmplr");
120295 +
120296 + for (i = 0; i < FM_MAX_NUM_OF_HW_PORT_IDS / 2 ; ++i)
120297 + FM_DMP_MEM_32(buf, n, &p_Fm->p_FmDmaRegs->fmdmplr[i]);
120298 +
120299 + FM_DMP_TITLE(buf, n, p_Fm->p_FmBmiRegs, "FM-BMI COMMON Regs");
120300 + FM_DMP_V32(buf, n, p_Fm->p_FmBmiRegs, fmbm_init);
120301 + FM_DMP_V32(buf, n, p_Fm->p_FmBmiRegs, fmbm_cfg1);
120302 + FM_DMP_V32(buf, n, p_Fm->p_FmBmiRegs, fmbm_cfg2);
120303 + FM_DMP_V32(buf, n, p_Fm->p_FmBmiRegs, fmbm_ievr);
120304 + FM_DMP_V32(buf, n, p_Fm->p_FmBmiRegs, fmbm_ier);
120305 +
120306 + FM_DMP_TITLE(buf, n, &p_Fm->p_FmBmiRegs->fmbm_arb, "fmbm_arb");
120307 + for (i = 0; i < 8 ; ++i)
120308 + FM_DMP_MEM_32(buf, n, &p_Fm->p_FmBmiRegs->fmbm_arb[i]);
120309 +
120310 + FM_DMP_TITLE(buf, n, p_Fm->p_FmQmiRegs, "FM-QMI COMMON Regs");
120311 + FM_DMP_V32(buf, n, p_Fm->p_FmQmiRegs, fmqm_gc);
120312 + FM_DMP_V32(buf, n, p_Fm->p_FmQmiRegs, fmqm_eie);
120313 + FM_DMP_V32(buf, n, p_Fm->p_FmQmiRegs, fmqm_eien);
120314 + FM_DMP_V32(buf, n, p_Fm->p_FmQmiRegs, fmqm_eif);
120315 + FM_DMP_V32(buf, n, p_Fm->p_FmQmiRegs, fmqm_ie);
120316 + FM_DMP_V32(buf, n, p_Fm->p_FmQmiRegs, fmqm_ien);
120317 + FM_DMP_V32(buf, n, p_Fm->p_FmQmiRegs, fmqm_if);
120318 + FM_DMP_V32(buf, n, p_Fm->p_FmQmiRegs, fmqm_gs);
120319 + FM_DMP_V32(buf, n, p_Fm->p_FmQmiRegs, fmqm_etfc);
120320 +
120321 + return n;
120322 +}
120323 +
120324 +int fm_dump_tnum_dbg(void *h_fm, int tn_s, int tn_e, char *buf, int nn)
120325 +{
120326 + t_Fm *p_Fm = (t_Fm *)h_fm;
120327 + uint8_t i, j = 0;
120328 + int n = nn;
120329 +
120330 + FM_DMP_TITLE(buf, n, NULL, "Tnums and Tnum dbg regs %d - %d",
120331 + tn_s, tn_e);
120332 +
120333 + iowrite32be(tn_s << 24, &p_Fm->p_FmFpmRegs->fmfp_dra);
120334 +
120335 + mb();
120336 +
120337 + for (j = tn_s; j <= tn_e; j++) {
120338 + FM_DMP_LN(buf, n, "> fmfp_ts[%d]\n", j);
120339 + FM_DMP_MEM_32(buf, n, &p_Fm->p_FmFpmRegs->fmfp_ts[j]);
120340 + FM_DMP_V32(buf, n, p_Fm->p_FmFpmRegs, fmfp_dra);
120341 + FM_DMP_LN(buf, n, "> fmfp_drd[0-3]\n");
120342 +
120343 + for (i = 0; i < 4 ; ++i)
120344 + FM_DMP_MEM_32(buf, n, &p_Fm->p_FmFpmRegs->fmfp_drd[i]);
120345 +
120346 + FM_DMP_LN(buf, n, "\n");
120347 +
120348 + }
120349 +
120350 + return n;
120351 +}
120352 +
120353 +int fm_dump_cls_plan(void *h_fm_pcd, int cpn, char *buf, int nn)
120354 +{
120355 + t_FmPcd *p_pcd = (t_FmPcd *)h_fm_pcd;
120356 + int i = 0;
120357 + uint32_t tmp;
120358 + unsigned long i_flg;
120359 + int n = nn;
120360 + u_FmPcdKgIndirectAccessRegs *idac;
120361 + spinlock_t *p_lk;
120362 +
120363 + p_lk = (spinlock_t *)p_pcd->p_FmPcdKg->h_HwSpinlock;
120364 + idac = p_pcd->p_FmPcdKg->p_IndirectAccessRegs;
120365 +
120366 + spin_lock_irqsave(p_lk, i_flg);
120367 +
120368 + /* Read ClsPlan Block Action Regs */
120369 + tmp = (uint32_t)(FM_KG_KGAR_GO |
120370 + FM_KG_KGAR_READ |
120371 + FM_PCD_KG_KGAR_SEL_CLS_PLAN_ENTRY |
120372 + DUMMY_PORT_ID |
120373 + ((uint32_t)cpn << FM_PCD_KG_KGAR_NUM_SHIFT) |
120374 + FM_PCD_KG_KGAR_WSEL_MASK);
120375 +
120376 + if (fman_kg_write_ar_wait(p_pcd->p_FmPcdKg->p_FmPcdKgRegs, tmp)) {
120377 + FM_DMP_LN(buf, nn, "Keygen scheme access violation");
120378 + spin_unlock_irqrestore(p_lk, i_flg);
120379 + return nn;
120380 + }
120381 + FM_DMP_TITLE(buf, n, &idac->clsPlanRegs,
120382 + "ClsPlan %d Indirect Access Regs", cpn);
120383 +
120384 + for (i = 0; i < 8; i++)
120385 + FM_DMP_MEM_32(buf, n, &idac->clsPlanRegs.kgcpe[i]);
120386 +
120387 + spin_unlock_irqrestore(p_lk, i_flg);
120388 +
120389 + return n;
120390 +}
120391 +
120392 +int fm_profile_dump_regs(void *h_fm_pcd, int ppn, char *buf, int nn)
120393 +{
120394 + t_FmPcd *p_pcd = (t_FmPcd *)h_fm_pcd;
120395 + t_FmPcdPlcrProfileRegs *p_prof_regs;
120396 + t_FmPcdPlcrRegs *p_plcr_regs;
120397 + t_FmPcdPlcr *p_plcr;
120398 + uint32_t tmp;
120399 + unsigned long i_flg;
120400 + int n = nn;
120401 + int toc = 10;
120402 + spinlock_t *p_lk;
120403 +
120404 + p_plcr = p_pcd->p_FmPcdPlcr;
120405 + p_prof_regs = &p_pcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->profileRegs;
120406 + p_plcr_regs = p_pcd->p_FmPcdPlcr->p_FmPcdPlcrRegs;
120407 +
120408 + p_lk = (spinlock_t *)((t_FmPcdPlcr *)p_plcr)->h_HwSpinlock;
120409 +
120410 + FM_DMP_SUBTITLE(buf, n, "\n");
120411 + FM_DMP_TITLE(buf, n, p_plcr_regs, "FM-PCD policer-profile regs");
120412 +
120413 + tmp = (uint32_t)(FM_PCD_PLCR_PAR_GO |
120414 + FM_PCD_PLCR_PAR_R |
120415 + ((uint32_t)ppn << FM_PCD_PLCR_PAR_PNUM_SHIFT) |
120416 + FM_PCD_PLCR_PAR_PWSEL_MASK);
120417 +
120418 + spin_lock_irqsave(p_lk, i_flg);
120419 +
120420 + iowrite32be(tmp, &p_plcr_regs->fmpl_par);
120421 +
120422 + mb();
120423 +
120424 + /* wait for the porfile regs to be present */
120425 + do {
120426 + --toc;
120427 + udelay(10);
120428 + if (!toc) {
120429 + /* looks like PLCR_PAR_GO refuses to clear */
120430 + spin_unlock_irqrestore(p_lk, i_flg);
120431 + FM_DMP_LN(buf, n, "Profile regs not accessible -");
120432 + FM_DMP_LN(buf, n, " check profile init process\n");
120433 + return n;
120434 + }
120435 + } while ((ioread32be(&p_plcr_regs->fmpl_par) & FM_PCD_PLCR_PAR_GO));
120436 +
120437 + FM_DMP_TITLE(buf, n, p_prof_regs, "Profile %d regs", ppn);
120438 +
120439 + FM_DMP_V32(buf, n, p_prof_regs, fmpl_pemode);
120440 + FM_DMP_V32(buf, n, p_prof_regs, fmpl_pegnia);
120441 + FM_DMP_V32(buf, n, p_prof_regs, fmpl_peynia);
120442 + FM_DMP_V32(buf, n, p_prof_regs, fmpl_pernia);
120443 + FM_DMP_V32(buf, n, p_prof_regs, fmpl_pecir);
120444 + FM_DMP_V32(buf, n, p_prof_regs, fmpl_pecbs);
120445 + FM_DMP_V32(buf, n, p_prof_regs, fmpl_pepepir_eir);
120446 + FM_DMP_V32(buf, n, p_prof_regs, fmpl_pepbs_ebs);
120447 + FM_DMP_V32(buf, n, p_prof_regs, fmpl_pelts);
120448 + FM_DMP_V32(buf, n, p_prof_regs, fmpl_pects);
120449 + FM_DMP_V32(buf, n, p_prof_regs, fmpl_pepts_ets);
120450 + FM_DMP_V32(buf, n, p_prof_regs, fmpl_pegpc);
120451 + FM_DMP_V32(buf, n, p_prof_regs, fmpl_peypc);
120452 + FM_DMP_V32(buf, n, p_prof_regs, fmpl_perpc);
120453 + FM_DMP_V32(buf, n, p_prof_regs, fmpl_perypc);
120454 + FM_DMP_V32(buf, n, p_prof_regs, fmpl_perrpc);
120455 +
120456 + spin_unlock_irqrestore(p_lk, i_flg);
120457 +
120458 + return n;
120459 +}
120460 +
120461 +int fm_dump_scheme(void *h_fm_pcd, int scnum, char *buf, int nn)
120462 +{
120463 + t_FmPcd *p_pcd = (t_FmPcd *)h_fm_pcd;
120464 + uint32_t tmp_ar;
120465 + unsigned long i_flg;
120466 + int i, n = nn;
120467 + spinlock_t *p_lk;
120468 + u_FmPcdKgIndirectAccessRegs *idac;
120469 +
120470 + idac = p_pcd->p_FmPcdKg->p_IndirectAccessRegs;
120471 + p_lk = (spinlock_t *)p_pcd->p_FmPcdKg->h_HwSpinlock;
120472 +
120473 + spin_lock_irqsave(p_lk, i_flg);
120474 +
120475 + tmp_ar = FmPcdKgBuildReadSchemeActionReg((uint8_t)scnum);
120476 + if (fman_kg_write_ar_wait(p_pcd->p_FmPcdKg->p_FmPcdKgRegs, tmp_ar)) {
120477 + FM_DMP_LN(buf, nn,
120478 + "Keygen scheme access violation or no such scheme");
120479 + spin_unlock_irqrestore(p_lk, i_flg);
120480 + return nn;
120481 + }
120482 +
120483 + FM_DMP_TITLE(buf, n, &idac->schemeRegs,
120484 + "Scheme %d Indirect Access Regs", scnum);
120485 +
120486 + FM_DMP_V32(buf, n, &idac->schemeRegs, kgse_mode);
120487 + FM_DMP_V32(buf, n, &idac->schemeRegs, kgse_ekfc);
120488 + FM_DMP_V32(buf, n, &idac->schemeRegs, kgse_ekdv);
120489 + FM_DMP_V32(buf, n, &idac->schemeRegs, kgse_bmch);
120490 + FM_DMP_V32(buf, n, &idac->schemeRegs, kgse_bmcl);
120491 + FM_DMP_V32(buf, n, &idac->schemeRegs, kgse_fqb);
120492 + FM_DMP_V32(buf, n, &idac->schemeRegs, kgse_hc);
120493 + FM_DMP_V32(buf, n, &idac->schemeRegs, kgse_ppc);
120494 +
120495 + FM_DMP_TITLE(buf, n, &idac->schemeRegs.kgse_gec, "kgse_gec");
120496 +
120497 + for (i = 0; i < FM_KG_NUM_OF_GENERIC_REGS; i++)
120498 + FM_DMP_MEM_32(buf, n, &idac->schemeRegs.kgse_gec[i]);
120499 +
120500 + FM_DMP_V32(buf, n, &idac->schemeRegs, kgse_spc);
120501 + FM_DMP_V32(buf, n, &idac->schemeRegs, kgse_dv0);
120502 + FM_DMP_V32(buf, n, &idac->schemeRegs, kgse_dv1);
120503 + FM_DMP_V32(buf, n, &idac->schemeRegs, kgse_ccbs);
120504 + FM_DMP_V32(buf, n, &idac->schemeRegs, kgse_mv);
120505 +
120506 + FM_DMP_SUBTITLE(buf, n, "\n");
120507 +
120508 + spin_unlock_irqrestore(p_lk, i_flg);
120509 +
120510 + return n;
120511 +}
120512 +
120513 +int fm_kg_pe_dump_regs(void *h_fm_pcd, char *buf, int nn)
120514 +{
120515 + t_FmPcd *p_pcd = (t_FmPcd *)h_fm_pcd;
120516 + int i = 0;
120517 + uint8_t prt_id = 0;
120518 + uint32_t tmp_ar;
120519 + unsigned long i_flg;
120520 + int n = nn;
120521 + u_FmPcdKgIndirectAccessRegs *idac;
120522 + t_FmPcdKg *p_kg;
120523 + spinlock_t *p_lk;
120524 +
120525 + p_kg = p_pcd->p_FmPcdKg;
120526 + idac = p_pcd->p_FmPcdKg->p_IndirectAccessRegs;
120527 + p_lk = (spinlock_t *)p_kg->h_HwSpinlock;
120528 +
120529 + spin_lock_irqsave(p_lk, i_flg);
120530 +
120531 + FM_DMP_SUBTITLE(buf, n, "\n");
120532 +
120533 + for (i = 0; i < FM_MAX_NUM_OF_PORTS; i++) {
120534 + SW_PORT_INDX_TO_HW_PORT_ID(prt_id, i);
120535 +
120536 + tmp_ar = FmPcdKgBuildReadPortSchemeBindActionReg(prt_id);
120537 +
120538 + if (fman_kg_write_ar_wait(p_kg->p_FmPcdKgRegs, tmp_ar)) {
120539 + FM_DMP_LN(buf, nn, "Keygen scheme access violation");
120540 + spin_unlock_irqrestore(p_lk, i_flg);
120541 + return nn;
120542 + }
120543 + FM_DMP_TITLE(buf, n, &idac->portRegs, "Port %d regs", prt_id);
120544 + FM_DMP_V32(buf, n, &idac->portRegs, fmkg_pe_sp);
120545 + FM_DMP_V32(buf, n, &idac->portRegs, fmkg_pe_cpp);
120546 + }
120547 +
120548 + FM_DMP_SUBTITLE(buf, n, "\n");
120549 +
120550 + spin_unlock_irqrestore(p_lk, i_flg);
120551 +
120552 + return n;
120553 +}
120554 +
120555 +int fm_kg_dump_regs(void *h_fm_pcd, char *buf, int nn)
120556 +{
120557 + t_FmPcd *p_pcd = (t_FmPcd *)h_fm_pcd;
120558 + int n = nn;
120559 +
120560 + FM_DMP_SUBTITLE(buf, n, "\n");
120561 + FM_DMP_TITLE(buf, n, p_pcd->p_FmPcdKg->p_FmPcdKgRegs,
120562 + "FmPcdKgRegs Regs");
120563 +
120564 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdKg->p_FmPcdKgRegs, fmkg_gcr);
120565 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdKg->p_FmPcdKgRegs, fmkg_eer);
120566 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdKg->p_FmPcdKgRegs, fmkg_eeer);
120567 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdKg->p_FmPcdKgRegs, fmkg_seer);
120568 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdKg->p_FmPcdKgRegs, fmkg_seeer);
120569 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdKg->p_FmPcdKgRegs, fmkg_gsr);
120570 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdKg->p_FmPcdKgRegs, fmkg_tpc);
120571 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdKg->p_FmPcdKgRegs, fmkg_serc);
120572 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdKg->p_FmPcdKgRegs, fmkg_fdor);
120573 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdKg->p_FmPcdKgRegs, fmkg_gdv0r);
120574 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdKg->p_FmPcdKgRegs, fmkg_gdv1r);
120575 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdKg->p_FmPcdKgRegs, fmkg_feer);
120576 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdKg->p_FmPcdKgRegs, fmkg_ar);
120577 +
120578 + FM_DMP_SUBTITLE(buf, n, "\n");
120579 +
120580 + return n;
120581 +}
120582 +
120583 +
120584 +int fm_fpm_dump_regs(void *h_fm, char *buf, int nn)
120585 +{
120586 + t_Fm *p_fm = (t_Fm *)h_fm;
120587 + uint8_t i;
120588 + int n = nn;
120589 +
120590 + FM_DMP_SUBTITLE(buf, n, "\n");
120591 +
120592 + FM_DMP_TITLE(buf, n, p_fm->p_FmFpmRegs, "FM-FPM Regs");
120593 +
120594 + FM_DMP_V32(buf, n, p_fm->p_FmFpmRegs, fmfp_tnc);
120595 + FM_DMP_V32(buf, n, p_fm->p_FmFpmRegs, fmfp_prc);
120596 + FM_DMP_V32(buf, n, p_fm->p_FmFpmRegs, fmfp_brkc);
120597 + FM_DMP_V32(buf, n, p_fm->p_FmFpmRegs, fmfp_mxd);
120598 + FM_DMP_V32(buf, n, p_fm->p_FmFpmRegs, fmfp_dist1);
120599 + FM_DMP_V32(buf, n, p_fm->p_FmFpmRegs, fmfp_dist2);
120600 + FM_DMP_V32(buf, n, p_fm->p_FmFpmRegs, fm_epi);
120601 + FM_DMP_V32(buf, n, p_fm->p_FmFpmRegs, fm_rie);
120602 +
120603 + FM_DMP_TITLE(buf, n, &p_fm->p_FmFpmRegs->fmfp_fcev, "fmfp_fcev");
120604 + for (i = 0; i < 4; ++i)
120605 + FM_DMP_MEM_32(buf, n, &p_fm->p_FmFpmRegs->fmfp_fcev[i]);
120606 +
120607 + FM_DMP_TITLE(buf, n, &p_fm->p_FmFpmRegs->fmfp_cee, "fmfp_cee");
120608 + for (i = 0; i < 4; ++i)
120609 + FM_DMP_MEM_32(buf, n, &p_fm->p_FmFpmRegs->fmfp_cee[i]);
120610 +
120611 + FM_DMP_SUBTITLE(buf, n, "\n");
120612 + FM_DMP_V32(buf, n, p_fm->p_FmFpmRegs, fmfp_tsc1);
120613 + FM_DMP_V32(buf, n, p_fm->p_FmFpmRegs, fmfp_tsc2);
120614 + FM_DMP_V32(buf, n, p_fm->p_FmFpmRegs, fmfp_tsp);
120615 + FM_DMP_V32(buf, n, p_fm->p_FmFpmRegs, fmfp_tsf);
120616 + FM_DMP_V32(buf, n, p_fm->p_FmFpmRegs, fm_rcr);
120617 + FM_DMP_V32(buf, n, p_fm->p_FmFpmRegs, fmfp_extc);
120618 + FM_DMP_V32(buf, n, p_fm->p_FmFpmRegs, fmfp_ext1);
120619 + FM_DMP_V32(buf, n, p_fm->p_FmFpmRegs, fmfp_ext2);
120620 +
120621 + FM_DMP_SUBTITLE(buf, n, "\n");
120622 + FM_DMP_V32(buf, n, p_fm->p_FmFpmRegs, fm_ip_rev_1);
120623 + FM_DMP_V32(buf, n, p_fm->p_FmFpmRegs, fm_ip_rev_2);
120624 + FM_DMP_V32(buf, n, p_fm->p_FmFpmRegs, fm_rstc);
120625 + FM_DMP_V32(buf, n, p_fm->p_FmFpmRegs, fm_cld);
120626 + FM_DMP_V32(buf, n, p_fm->p_FmFpmRegs, fm_npi);
120627 + FM_DMP_V32(buf, n, p_fm->p_FmFpmRegs, fmfp_ee);
120628 +
120629 + FM_DMP_TITLE(buf, n, &p_fm->p_FmFpmRegs->fmfp_cev, "fmfp_cev");
120630 + for (i = 0; i < 4; ++i)
120631 + FM_DMP_MEM_32(buf, n, &p_fm->p_FmFpmRegs->fmfp_cev[i]);
120632 +
120633 + FM_DMP_TITLE(buf, n, &p_fm->p_FmFpmRegs->fmfp_ps, "fmfp_ps");
120634 + for (i = 0; i < 64; ++i)
120635 + FM_DMP_MEM_32(buf, n, &p_fm->p_FmFpmRegs->fmfp_ps[i]);
120636 +
120637 + return n;
120638 +}
120639 +
120640 +int fm_prs_dump_regs(void *h_fm_pcd, char *buf, int nn)
120641 +{
120642 + t_FmPcd *p_pcd = (t_FmPcd *)h_fm_pcd;
120643 + int n = nn;
120644 +
120645 + FM_DMP_SUBTITLE(buf, n, "\n");
120646 +
120647 + FM_DMP_TITLE(buf, n, p_pcd->p_FmPcdPrs->p_FmPcdPrsRegs,
120648 + "FM-PCD parser regs");
120649 +
120650 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdPrs->p_FmPcdPrsRegs, fmpr_rpclim);
120651 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdPrs->p_FmPcdPrsRegs, fmpr_rpimac);
120652 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdPrs->p_FmPcdPrsRegs, pmeec);
120653 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdPrs->p_FmPcdPrsRegs, fmpr_pevr);
120654 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdPrs->p_FmPcdPrsRegs, fmpr_pever);
120655 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdPrs->p_FmPcdPrsRegs, fmpr_perr);
120656 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdPrs->p_FmPcdPrsRegs, fmpr_perer);
120657 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdPrs->p_FmPcdPrsRegs, fmpr_ppsc);
120658 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdPrs->p_FmPcdPrsRegs, fmpr_pds);
120659 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdPrs->p_FmPcdPrsRegs, fmpr_l2rrs);
120660 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdPrs->p_FmPcdPrsRegs, fmpr_l3rrs);
120661 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdPrs->p_FmPcdPrsRegs, fmpr_l4rrs);
120662 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdPrs->p_FmPcdPrsRegs, fmpr_srrs);
120663 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdPrs->p_FmPcdPrsRegs, fmpr_l2rres);
120664 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdPrs->p_FmPcdPrsRegs, fmpr_l3rres);
120665 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdPrs->p_FmPcdPrsRegs, fmpr_l4rres);
120666 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdPrs->p_FmPcdPrsRegs, fmpr_srres);
120667 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdPrs->p_FmPcdPrsRegs, fmpr_spcs);
120668 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdPrs->p_FmPcdPrsRegs, fmpr_spscs);
120669 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdPrs->p_FmPcdPrsRegs, fmpr_hxscs);
120670 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdPrs->p_FmPcdPrsRegs, fmpr_mrcs);
120671 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdPrs->p_FmPcdPrsRegs, fmpr_mwcs);
120672 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdPrs->p_FmPcdPrsRegs, fmpr_mrscs);
120673 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdPrs->p_FmPcdPrsRegs, fmpr_mwscs);
120674 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdPrs->p_FmPcdPrsRegs, fmpr_fcscs);
120675 +
120676 + return n;
120677 +}
120678 +
120679 +int fm_plcr_dump_regs(void *h_fm_pcd, char *buf, int nn)
120680 +{
120681 + t_FmPcd *p_pcd = (t_FmPcd *)h_fm_pcd;
120682 + int i = 0;
120683 + int n = nn;
120684 +
120685 + FM_DMP_SUBTITLE(buf, n, "\n");
120686 +
120687 + FM_DMP_TITLE(buf, n,
120688 + p_pcd->p_FmPcdPlcr->p_FmPcdPlcrRegs,
120689 + "FM policer regs");
120690 +
120691 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdPlcr->p_FmPcdPlcrRegs, fmpl_gcr);
120692 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdPlcr->p_FmPcdPlcrRegs, fmpl_gsr);
120693 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdPlcr->p_FmPcdPlcrRegs, fmpl_evr);
120694 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdPlcr->p_FmPcdPlcrRegs, fmpl_ier);
120695 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdPlcr->p_FmPcdPlcrRegs, fmpl_ifr);
120696 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdPlcr->p_FmPcdPlcrRegs, fmpl_eevr);
120697 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdPlcr->p_FmPcdPlcrRegs, fmpl_eier);
120698 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdPlcr->p_FmPcdPlcrRegs, fmpl_eifr);
120699 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdPlcr->p_FmPcdPlcrRegs, fmpl_rpcnt);
120700 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdPlcr->p_FmPcdPlcrRegs, fmpl_ypcnt);
120701 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdPlcr->p_FmPcdPlcrRegs, fmpl_rrpcnt);
120702 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdPlcr->p_FmPcdPlcrRegs, fmpl_rypcnt);
120703 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdPlcr->p_FmPcdPlcrRegs, fmpl_tpcnt);
120704 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdPlcr->p_FmPcdPlcrRegs, fmpl_flmcnt);
120705 +
120706 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdPlcr->p_FmPcdPlcrRegs, fmpl_serc);
120707 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdPlcr->p_FmPcdPlcrRegs, fmpl_upcr);
120708 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdPlcr->p_FmPcdPlcrRegs, fmpl_dpmr);
120709 +
120710 + FM_DMP_TITLE(buf, n,
120711 + &p_pcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_pmr,
120712 + "fmpl_pmr");
120713 +
120714 + for (i = 0; i < 63; ++i)
120715 + FM_DMP_MEM_32(buf, n,
120716 + &p_pcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_pmr[i]);
120717 +
120718 + return n;
120719 +}
120720 +
120721 +int fm_get_counter(void *h_fm, e_FmCounters cnt_e, uint32_t *cnt_val)
120722 +{
120723 + t_Fm *p_fm = (t_Fm *)h_fm;
120724 +
120725 + /* When applicable (when there is an "enable counters" bit),
120726 + check that counters are enabled */
120727 +
120728 + switch (cnt_e) {
120729 + case (e_FM_COUNTERS_DEQ_1):
120730 + case (e_FM_COUNTERS_DEQ_2):
120731 + case (e_FM_COUNTERS_DEQ_3):
120732 + if (p_fm->p_FmStateStruct->revInfo.majorRev >= 6)
120733 + return -EINVAL; /* counter not available */
120734 +
120735 + case (e_FM_COUNTERS_ENQ_TOTAL_FRAME):
120736 + case (e_FM_COUNTERS_DEQ_TOTAL_FRAME):
120737 + case (e_FM_COUNTERS_DEQ_0):
120738 + case (e_FM_COUNTERS_DEQ_FROM_DEFAULT):
120739 + case (e_FM_COUNTERS_DEQ_FROM_CONTEXT):
120740 + case (e_FM_COUNTERS_DEQ_FROM_FD):
120741 + case (e_FM_COUNTERS_DEQ_CONFIRM):
120742 + if (!(ioread32be(&p_fm->p_FmQmiRegs->fmqm_gc) &
120743 + QMI_CFG_EN_COUNTERS))
120744 + return -EINVAL; /* Requested counter not available */
120745 + break;
120746 + default:
120747 + break;
120748 + }
120749 +
120750 + switch (cnt_e) {
120751 + case (e_FM_COUNTERS_ENQ_TOTAL_FRAME):
120752 + *cnt_val = ioread32be(&p_fm->p_FmQmiRegs->fmqm_etfc);
120753 + return 0;
120754 + case (e_FM_COUNTERS_DEQ_TOTAL_FRAME):
120755 + *cnt_val = ioread32be(&p_fm->p_FmQmiRegs->fmqm_dtfc);
120756 + return 0;
120757 + case (e_FM_COUNTERS_DEQ_0):
120758 + *cnt_val = ioread32be(&p_fm->p_FmQmiRegs->fmqm_dc0);
120759 + return 0;
120760 + case (e_FM_COUNTERS_DEQ_1):
120761 + *cnt_val = ioread32be(&p_fm->p_FmQmiRegs->fmqm_dc1);
120762 + return 0;
120763 + case (e_FM_COUNTERS_DEQ_2):
120764 + *cnt_val = ioread32be(&p_fm->p_FmQmiRegs->fmqm_dc2);
120765 + return 0;
120766 + case (e_FM_COUNTERS_DEQ_3):
120767 + *cnt_val = ioread32be(&p_fm->p_FmQmiRegs->fmqm_dc3);
120768 + return 0;
120769 + case (e_FM_COUNTERS_DEQ_FROM_DEFAULT):
120770 + *cnt_val = ioread32be(&p_fm->p_FmQmiRegs->fmqm_dfdc);
120771 + return 0;
120772 + case (e_FM_COUNTERS_DEQ_FROM_CONTEXT):
120773 + *cnt_val = ioread32be(&p_fm->p_FmQmiRegs->fmqm_dfcc);
120774 + return 0;
120775 + case (e_FM_COUNTERS_DEQ_FROM_FD):
120776 + *cnt_val = ioread32be(&p_fm->p_FmQmiRegs->fmqm_dffc);
120777 + return 0;
120778 + case (e_FM_COUNTERS_DEQ_CONFIRM):
120779 + *cnt_val = ioread32be(&p_fm->p_FmQmiRegs->fmqm_dcc);
120780 + return 0;
120781 + }
120782 + /* should never get here */
120783 + return -EINVAL; /* counter not available */
120784 +}
120785 --- /dev/null
120786 +++ b/drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_sysfs_fm.h
120787 @@ -0,0 +1,136 @@
120788 +/*
120789 + * Copyright 2008-2012 Freescale Semiconductor Inc.
120790 + *
120791 + * Redistribution and use in source and binary forms, with or without
120792 + * modification, are permitted provided that the following conditions are met:
120793 + * * Redistributions of source code must retain the above copyright
120794 + * notice, this list of conditions and the following disclaimer.
120795 + * * Redistributions in binary form must reproduce the above copyright
120796 + * notice, this list of conditions and the following disclaimer in the
120797 + * documentation and/or other materials provided with the distribution.
120798 + * * Neither the name of Freescale Semiconductor nor the
120799 + * names of its contributors may be used to endorse or promote products
120800 + * derived from this software without specific prior written permission.
120801 + *
120802 + *
120803 + * ALTERNATIVELY, this software may be distributed under the terms of the
120804 + * GNU General Public License ("GPL") as published by the Free Software
120805 + * Foundation, either version 2 of that License or (at your option) any
120806 + * later version.
120807 + *
120808 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
120809 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
120810 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
120811 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
120812 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
120813 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
120814 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
120815 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
120816 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
120817 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
120818 + */
120819 +
120820 +
120821 +#ifndef LNXWRP_SYSFS_FM_H_
120822 +#define LNXWRP_SYSFS_FM_H_
120823 +
120824 +#include "lnxwrp_sysfs.h"
120825 +
120826 +int fm_sysfs_create(struct device *dev);
120827 +void fm_sysfs_destroy(struct device *dev);
120828 +int fm_dump_regs(void *h_dev, char *buf, int nn);
120829 +int fm_fpm_dump_regs(void *h_dev, char *buf, int nn);
120830 +int fm_kg_dump_regs(void *h_pcd, char *buf, int nn);
120831 +int fm_kg_pe_dump_regs(void *h_pcd, char *buf, int nn);
120832 +int fm_dump_scheme(void *h_pcd, int scnum, char *buf, int nn);
120833 +int fm_dump_tnum_dbg(void *h_fm, int tn_s, int tn_e, char *buf, int nn);
120834 +int fm_dump_cls_plan(void *h_pcd, int cpn, char *buf, int nn);
120835 +int fm_plcr_dump_regs(void *h_pcd, char *buf, int nn);
120836 +int fm_prs_dump_regs(void *h_pcd, char *buf, int nn);
120837 +int fm_profile_dump_regs(void *h_pcd, int ppnum, char *buf, int nn);
120838 +
120839 +#define FM_DMP_PGSZ_ERR { \
120840 + snprintf(&buf[PAGE_SIZE - 80], 70, \
120841 + "\n Err: current sysfs buffer reached PAGE_SIZE\n");\
120842 + n = PAGE_SIZE - 2; \
120843 + }
120844 +
120845 +#define FM_DMP_LN(buf, n, ...) \
120846 + do { \
120847 + int k, m = n; \
120848 + m += k = snprintf(&buf[m], PAGE_SIZE - m, __VA_ARGS__); \
120849 + if (k < 0 || m > PAGE_SIZE - 90) \
120850 + FM_DMP_PGSZ_ERR \
120851 + n = m; \
120852 + } while (0)
120853 +
120854 +#define FM_DMP_TITLE(buf, n, addr, ...) \
120855 + do { \
120856 + int k, m = n; \
120857 + m += k = snprintf(&buf[m], PAGE_SIZE - m, "\n"); \
120858 + if (k < 0 || m > PAGE_SIZE - 90) \
120859 + FM_DMP_PGSZ_ERR \
120860 + m += k = snprintf(&buf[m], PAGE_SIZE - m, __VA_ARGS__); \
120861 + if (k < 0 || m > PAGE_SIZE - 90) \
120862 + FM_DMP_PGSZ_ERR \
120863 + if (addr) { \
120864 + phys_addr_t pa; \
120865 + pa = virt_to_phys(addr); \
120866 + m += k = \
120867 + snprintf(&buf[m], PAGE_SIZE - m, " (0x%lX)", \
120868 + (long unsigned int)(pa)); \
120869 + if (k < 0 || m > PAGE_SIZE - 90) \
120870 + FM_DMP_PGSZ_ERR \
120871 + } \
120872 + m += k = snprintf(&buf[m], PAGE_SIZE - m, \
120873 + "\n----------------------------------------\n\n"); \
120874 + if (k < 0 || m > PAGE_SIZE - 90) \
120875 + FM_DMP_PGSZ_ERR \
120876 + n = m; \
120877 + } while (0)
120878 +
120879 +#define FM_DMP_SUBTITLE(buf, n, ...) \
120880 + do { \
120881 + int k, m = n; \
120882 + m += k = snprintf(&buf[m], PAGE_SIZE - m, "------- "); \
120883 + if (k < 0 || m > PAGE_SIZE - 90) \
120884 + FM_DMP_PGSZ_ERR \
120885 + m += k = snprintf(&buf[m], PAGE_SIZE - m, __VA_ARGS__); \
120886 + if (k < 0 || m > PAGE_SIZE - 90) \
120887 + FM_DMP_PGSZ_ERR \
120888 + m += k = snprintf(&buf[m], PAGE_SIZE - m, "\n"); \
120889 + if (k < 0 || m > PAGE_SIZE - 90) \
120890 + FM_DMP_PGSZ_ERR \
120891 + n = m; \
120892 + } while (0)
120893 +
120894 +#define FM_DMP_MEM_32(buf, n, addr) \
120895 + { \
120896 + uint32_t val; \
120897 + phys_addr_t pa; \
120898 + int k, m = n; \
120899 + pa = virt_to_phys(addr); \
120900 + val = ioread32be((addr)); \
120901 + do { \
120902 + m += k = snprintf(&buf[m], \
120903 + PAGE_SIZE - m, "0x%010llX: 0x%08x\n", \
120904 + pa, val); \
120905 + if (k < 0 || m > PAGE_SIZE - 90) \
120906 + FM_DMP_PGSZ_ERR \
120907 + n += k; \
120908 + } while (0) ;\
120909 + }
120910 +
120911 +#define FM_DMP_V32(buf, n, st, phrase) \
120912 + do { \
120913 + int k, m = n; \
120914 + phys_addr_t pa = virt_to_phys(&((st)->phrase)); \
120915 + k = snprintf(&buf[m], PAGE_SIZE - m, \
120916 + "0x%010llX: 0x%08x%8s\t%s\n", (unsigned long long) pa, \
120917 + ioread32be((uint32_t *)&((st)->phrase)), "", #phrase); \
120918 + if (k < 0 || m > PAGE_SIZE - 90) \
120919 + FM_DMP_PGSZ_ERR \
120920 + n += k; \
120921 + } while (0)
120922 +
120923 +#endif /* LNXWRP_SYSFS_FM_H_ */
120924 --- /dev/null
120925 +++ b/drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_sysfs_fm_port.c
120926 @@ -0,0 +1,1268 @@
120927 +/*
120928 + * Copyright 2008-2012 Freescale Semiconductor Inc.
120929 + *
120930 + * Redistribution and use in source and binary forms, with or without
120931 + * modification, are permitted provided that the following conditions are met:
120932 + * * Redistributions of source code must retain the above copyright
120933 + * notice, this list of conditions and the following disclaimer.
120934 + * * Redistributions in binary form must reproduce the above copyright
120935 + * notice, this list of conditions and the following disclaimer in the
120936 + * documentation and/or other materials provided with the distribution.
120937 + * * Neither the name of Freescale Semiconductor nor the
120938 + * names of its contributors may be used to endorse or promote products
120939 + * derived from this software without specific prior written permission.
120940 + *
120941 + *
120942 + * ALTERNATIVELY, this software may be distributed under the terms of the
120943 + * GNU General Public License ("GPL") as published by the Free Software
120944 + * Foundation, either version 2 of that License or (at your option) any
120945 + * later version.
120946 + *
120947 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
120948 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
120949 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
120950 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
120951 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
120952 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
120953 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
120954 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
120955 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
120956 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
120957 + */
120958 +
120959 +#include "lnxwrp_sysfs.h"
120960 +#include "lnxwrp_fm.h"
120961 +#include "debug_ext.h"
120962 +#include "lnxwrp_sysfs_fm_port.h"
120963 +#include "lnxwrp_sysfs_fm.h"
120964 +
120965 +#include "../../sdk_fman/Peripherals/FM/Port/fm_port.h"
120966 +#include "../../sdk_fman/Peripherals/FM/Port/fm_port_dsar.h"
120967 +
120968 +#if defined(__ERR_MODULE__)
120969 +#undef __ERR_MODULE__
120970 +#endif
120971 +
120972 +#include "../../sdk_fman/Peripherals/FM/fm.h"
120973 +
120974 +static const struct sysfs_stats_t portSysfsStats[] = {
120975 + /* RX/TX/OH common statistics */
120976 + {
120977 + .stat_name = "port_frame",
120978 + .stat_counter = e_FM_PORT_COUNTERS_FRAME,
120979 + },
120980 + {
120981 + .stat_name = "port_discard_frame",
120982 + .stat_counter = e_FM_PORT_COUNTERS_DISCARD_FRAME,
120983 + },
120984 + {
120985 + .stat_name = "port_dealloc_buf",
120986 + .stat_counter = e_FM_PORT_COUNTERS_DEALLOC_BUF,
120987 + },
120988 + {
120989 + .stat_name = "port_enq_total",
120990 + .stat_counter = e_FM_PORT_COUNTERS_ENQ_TOTAL,
120991 + },
120992 + /* TX/OH */
120993 + {
120994 + .stat_name = "port_length_err",
120995 + .stat_counter = e_FM_PORT_COUNTERS_LENGTH_ERR,
120996 + },
120997 + {
120998 + .stat_name = "port_unsupprted_format",
120999 + .stat_counter = e_FM_PORT_COUNTERS_UNSUPPRTED_FORMAT,
121000 + },
121001 + {
121002 + .stat_name = "port_deq_total",
121003 + .stat_counter = e_FM_PORT_COUNTERS_DEQ_TOTAL,
121004 + },
121005 + {
121006 + .stat_name = "port_deq_from_default",
121007 + .stat_counter = e_FM_PORT_COUNTERS_DEQ_FROM_DEFAULT,
121008 + },
121009 + {
121010 + .stat_name = "port_deq_confirm",
121011 + .stat_counter = e_FM_PORT_COUNTERS_DEQ_CONFIRM,
121012 + },
121013 + /* RX/OH */
121014 + {
121015 + .stat_name = "port_rx_bad_frame",
121016 + .stat_counter = e_FM_PORT_COUNTERS_RX_BAD_FRAME,
121017 + },
121018 + {
121019 + .stat_name = "port_rx_large_frame",
121020 + .stat_counter = e_FM_PORT_COUNTERS_RX_LARGE_FRAME,
121021 + },
121022 + {
121023 + .stat_name = "port_rx_out_of_buffers_discard",
121024 + .stat_counter = e_FM_PORT_COUNTERS_RX_OUT_OF_BUFFERS_DISCARD,
121025 + },
121026 + {
121027 + .stat_name = "port_rx_filter_frame",
121028 + .stat_counter = e_FM_PORT_COUNTERS_RX_FILTER_FRAME,
121029 + },
121030 + /* TODO: Particular statistics for OH ports */
121031 + {}
121032 +};
121033 +
121034 +static ssize_t show_fm_port_stats(struct device *dev,
121035 + struct device_attribute *attr, char *buf)
121036 +{
121037 + t_LnxWrpFmPortDev *p_LnxWrpFmPortDev;
121038 + t_LnxWrpFmDev *p_LnxWrpFmDev;
121039 + unsigned long flags;
121040 + int n = 0;
121041 + uint8_t counter = 0;
121042 +
121043 + if (attr == NULL || buf == NULL || dev == NULL)
121044 + return -EINVAL;
121045 +
121046 + p_LnxWrpFmPortDev = (t_LnxWrpFmPortDev *) dev_get_drvdata(dev);
121047 + if (WARN_ON(p_LnxWrpFmPortDev == NULL))
121048 + return -EINVAL;
121049 +
121050 + p_LnxWrpFmDev = (t_LnxWrpFmDev *) p_LnxWrpFmPortDev->h_LnxWrpFmDev;
121051 + if (WARN_ON(p_LnxWrpFmDev == NULL))
121052 + return -EINVAL;
121053 +
121054 + if (!p_LnxWrpFmDev->active || !p_LnxWrpFmDev->h_Dev)
121055 + return -EIO;
121056 +
121057 + if (!p_LnxWrpFmPortDev->h_Dev) {
121058 + n = snprintf(buf, PAGE_SIZE, "\tFM Port not configured...\n");
121059 + return n;
121060 + }
121061 +
121062 + counter = fm_find_statistic_counter_by_name(
121063 + attr->attr.name,
121064 + portSysfsStats, NULL);
121065 +
121066 + if (counter == e_FM_PORT_COUNTERS_RX_LIST_DMA_ERR) {
121067 + uint32_t fmRev = 0;
121068 + fmRev = 0xffff &
121069 + ioread32(UINT_TO_PTR(p_LnxWrpFmDev->fmBaseAddr +
121070 + 0x000c30c4));
121071 +
121072 + if (fmRev == 0x0100) {
121073 + local_irq_save(flags);
121074 + n = snprintf(buf, PAGE_SIZE,
121075 + "counter not available for revision 1\n");
121076 + local_irq_restore(flags);
121077 + }
121078 + return n;
121079 + }
121080 +
121081 + local_irq_save(flags);
121082 + n = snprintf(buf, PAGE_SIZE, "\t%s counter: %u\n",
121083 + p_LnxWrpFmPortDev->name,
121084 + FM_PORT_GetCounter(p_LnxWrpFmPortDev->h_Dev,
121085 + (e_FmPortCounters) counter));
121086 + local_irq_restore(flags);
121087 +
121088 + return n;
121089 +}
121090 +
121091 +/* FM PORT RX/TX/OH statistics */
121092 +static DEVICE_ATTR(port_frame, S_IRUGO, show_fm_port_stats, NULL);
121093 +static DEVICE_ATTR(port_discard_frame, S_IRUGO, show_fm_port_stats, NULL);
121094 +static DEVICE_ATTR(port_dealloc_buf, S_IRUGO, show_fm_port_stats, NULL);
121095 +static DEVICE_ATTR(port_enq_total, S_IRUGO, show_fm_port_stats, NULL);
121096 +/* FM PORT TX/OH statistics */
121097 +static DEVICE_ATTR(port_length_err, S_IRUGO, show_fm_port_stats, NULL);
121098 +static DEVICE_ATTR(port_unsupprted_format, S_IRUGO, show_fm_port_stats, NULL);
121099 +static DEVICE_ATTR(port_deq_total, S_IRUGO, show_fm_port_stats, NULL);
121100 +static DEVICE_ATTR(port_deq_from_default, S_IRUGO, show_fm_port_stats, NULL);
121101 +static DEVICE_ATTR(port_deq_confirm, S_IRUGO, show_fm_port_stats, NULL);
121102 +/* FM PORT RX/OH statistics */
121103 +static DEVICE_ATTR(port_rx_bad_frame, S_IRUGO, show_fm_port_stats, NULL);
121104 +static DEVICE_ATTR(port_rx_large_frame, S_IRUGO, show_fm_port_stats, NULL);
121105 +static DEVICE_ATTR(port_rx_out_of_buffers_discard, S_IRUGO,
121106 + show_fm_port_stats, NULL);
121107 +static DEVICE_ATTR(port_rx_filter_frame, S_IRUGO, show_fm_port_stats, NULL);
121108 +
121109 +/* FM PORT TX statistics */
121110 +static struct attribute *fm_tx_port_dev_stats_attributes[] = {
121111 + &dev_attr_port_frame.attr,
121112 + &dev_attr_port_discard_frame.attr,
121113 + &dev_attr_port_dealloc_buf.attr,
121114 + &dev_attr_port_enq_total.attr,
121115 + &dev_attr_port_length_err.attr,
121116 + &dev_attr_port_unsupprted_format.attr,
121117 + &dev_attr_port_deq_total.attr,
121118 + &dev_attr_port_deq_from_default.attr,
121119 + &dev_attr_port_deq_confirm.attr,
121120 + NULL
121121 +};
121122 +
121123 +static const struct attribute_group fm_tx_port_dev_stats_attr_grp = {
121124 + .name = "statistics",
121125 + .attrs = fm_tx_port_dev_stats_attributes
121126 +};
121127 +
121128 +/* FM PORT RX statistics */
121129 +static struct attribute *fm_rx_port_dev_stats_attributes[] = {
121130 + &dev_attr_port_frame.attr,
121131 + &dev_attr_port_discard_frame.attr,
121132 + &dev_attr_port_dealloc_buf.attr,
121133 + &dev_attr_port_enq_total.attr,
121134 + &dev_attr_port_rx_bad_frame.attr,
121135 + &dev_attr_port_rx_large_frame.attr,
121136 + &dev_attr_port_rx_out_of_buffers_discard.attr,
121137 + &dev_attr_port_rx_filter_frame.attr,
121138 + NULL
121139 +};
121140 +
121141 +static const struct attribute_group fm_rx_port_dev_stats_attr_grp = {
121142 + .name = "statistics",
121143 + .attrs = fm_rx_port_dev_stats_attributes
121144 +};
121145 +
121146 +/* TODO: add particular OH ports statistics */
121147 +static struct attribute *fm_oh_port_dev_stats_attributes[] = {
121148 + &dev_attr_port_frame.attr,
121149 + &dev_attr_port_discard_frame.attr,
121150 + &dev_attr_port_dealloc_buf.attr,
121151 + &dev_attr_port_enq_total.attr,
121152 + /*TX*/ &dev_attr_port_length_err.attr,
121153 + &dev_attr_port_unsupprted_format.attr,
121154 + &dev_attr_port_deq_total.attr,
121155 + &dev_attr_port_deq_from_default.attr,
121156 + &dev_attr_port_deq_confirm.attr,
121157 + /* &dev_attr_port_rx_bad_frame.attr, */
121158 + /* &dev_attr_port_rx_large_frame.attr, */
121159 + &dev_attr_port_rx_out_of_buffers_discard.attr,
121160 + /*&dev_attr_port_rx_filter_frame.attr, */
121161 + NULL
121162 +};
121163 +
121164 +static const struct attribute_group fm_oh_port_dev_stats_attr_grp = {
121165 + .name = "statistics",
121166 + .attrs = fm_oh_port_dev_stats_attributes
121167 +};
121168 +
121169 +static ssize_t show_fm_port_regs(struct device *dev,
121170 + struct device_attribute *attr, char *buf)
121171 +{
121172 + unsigned long flags;
121173 + unsigned n = 0;
121174 +#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
121175 + t_LnxWrpFmPortDev *p_LnxWrpFmPortDev;
121176 +#endif
121177 + if (attr == NULL || buf == NULL || dev == NULL)
121178 + return -EINVAL;
121179 +
121180 +#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
121181 + p_LnxWrpFmPortDev =
121182 + (t_LnxWrpFmPortDev *) dev_get_drvdata(dev);
121183 +
121184 +
121185 + local_irq_save(flags);
121186 +
121187 + if (!p_LnxWrpFmPortDev->h_Dev) {
121188 + n = snprintf(buf, PAGE_SIZE, "\tFM Port not configured...\n");
121189 + return n;
121190 + } else {
121191 + n = snprintf(buf, PAGE_SIZE,
121192 + "FM port driver registers dump.\n");
121193 + n = fm_port_dump_regs(p_LnxWrpFmPortDev->h_Dev, buf, n);
121194 + }
121195 +
121196 + local_irq_restore(flags);
121197 +
121198 + return n;
121199 +#else
121200 +
121201 + local_irq_save(flags);
121202 + n = snprintf(buf, PAGE_SIZE,
121203 + "Debug level is too low to dump registers!!!\n");
121204 + local_irq_restore(flags);
121205 +
121206 + return n;
121207 +#endif
121208 +}
121209 +static int fm_port_dsar_dump_mem(void *h_dev, char *buf, int nn)
121210 +{
121211 + t_FmPort *p_FmPort;
121212 + t_Fm *p_Fm;
121213 + uint8_t hardwarePortId;
121214 + uint32_t *param_page;
121215 + t_ArCommonDesc *ArCommonDescPtr;
121216 + uint32_t *mem;
121217 + int i, n = nn;
121218 +
121219 + p_FmPort = (t_FmPort *)h_dev;
121220 + hardwarePortId = p_FmPort->hardwarePortId;
121221 + p_Fm = (t_Fm *)p_FmPort->h_Fm;
121222 +
121223 + if (!FM_PORT_IsInDsar(p_FmPort))
121224 + {
121225 + FM_DMP_LN(buf, n, "port %u is not a DSAR port\n",
121226 + hardwarePortId);
121227 + return n;
121228 + }
121229 + FM_DMP_LN(buf, n, "port %u DSAR mem\n", hardwarePortId);
121230 + FM_DMP_LN(buf, n, "========================\n");
121231 +
121232 + /* do I need request_mem_region here? */
121233 + param_page = ioremap(p_FmPort->fmMuramPhysBaseAddr + ioread32be(&p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rgpr), 4);
121234 + ArCommonDescPtr = (t_ArCommonDesc*)(ioremap(p_FmPort->fmMuramPhysBaseAddr + ioread32be(param_page), 300*4)); /* this should be changed*/
121235 + mem = (uint32_t*)ArCommonDescPtr;
121236 + for (i = 0; i < 300; i+=4)
121237 + FM_DMP_LN(buf, n, "%08x: %08x %08x %08x %08x\n", i*4, mem[i], mem[i + 1], mem[i + 2], mem[i + 3]);
121238 + iounmap(ArCommonDescPtr);
121239 + iounmap(param_page);
121240 + return n;
121241 +}
121242 +
121243 +static int fm_port_dsar_dump_regs(void *h_dev, char *buf, int nn)
121244 +{
121245 + t_FmPort *p_FmPort;
121246 + t_Fm *p_Fm;
121247 + uint8_t hardwarePortId;
121248 + uint32_t *param_page;
121249 + t_ArCommonDesc *ArCommonDescPtr;
121250 + int i, n = nn;
121251 +
121252 + p_FmPort = (t_FmPort *)h_dev;
121253 + hardwarePortId = p_FmPort->hardwarePortId;
121254 + p_Fm = (t_Fm *)p_FmPort->h_Fm;
121255 +
121256 + if (!FM_PORT_IsInDsar(p_FmPort))
121257 + {
121258 + FM_DMP_LN(buf, n, "port %u is not a DSAR port\n",
121259 + hardwarePortId);
121260 + return n;
121261 + }
121262 + FM_DMP_LN(buf, n, "port %u DSAR information\n", hardwarePortId);
121263 + FM_DMP_LN(buf, n, "========================\n");
121264 +
121265 + /* do I need request_mem_region here? */
121266 + param_page = ioremap(p_FmPort->fmMuramPhysBaseAddr + ioread32be(&p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rgpr), 4);
121267 + ArCommonDescPtr = (t_ArCommonDesc*)(ioremap(p_FmPort->fmMuramPhysBaseAddr + ioread32be(param_page), sizeof(t_ArCommonDesc))); /* this should be changed*/
121268 + FM_DMP_LN(buf, n, "Tx port: 0x%x\n", ArCommonDescPtr->arTxPort);
121269 + FM_DMP_LN(buf, n, "Active HPNIA: 0x%08x\n", ArCommonDescPtr->activeHPNIA);
121270 + FM_DMP_LN(buf, n, "Snmp port: 0x%x\n", ArCommonDescPtr->snmpPort);
121271 + FM_DMP_LN(buf, n, "MAC address: %02x:%02x:%02x:%02x:%02x:%02x\n", ArCommonDescPtr->macStationAddr[0],
121272 + ArCommonDescPtr->macStationAddr[1], ArCommonDescPtr->macStationAddr[2],
121273 + ArCommonDescPtr->macStationAddr[3], ArCommonDescPtr->macStationAddr[4],
121274 + ArCommonDescPtr->macStationAddr[5]);
121275 + FM_DMP_LN(buf, n, "filterControl: 0x%02x\n", ArCommonDescPtr->filterControl);
121276 + FM_DMP_LN(buf, n, "tcpControlPass: 0x%04x\n", ArCommonDescPtr->tcpControlPass);
121277 + FM_DMP_LN(buf, n, "ipProtocolTblSize: 0x%x\n", ArCommonDescPtr->ipProtocolTblSize);
121278 + FM_DMP_LN(buf, n, "udpPortTblSize: 0x%x\n", ArCommonDescPtr->udpPortTblSize);
121279 + FM_DMP_LN(buf, n, "tcpPortTblSize: 0x%x\n", ArCommonDescPtr->tcpPortTblSize);
121280 + if (ArCommonDescPtr->p_ArStats)
121281 + {
121282 + t_ArStatistics *arStatistics = (t_ArStatistics*)
121283 + ioremap(ioread32be(&ArCommonDescPtr->p_ArStats) +
121284 + p_FmPort->fmMuramPhysBaseAddr,
121285 + sizeof (t_ArStatistics));
121286 + FM_DMP_LN(buf, n, "\nDSAR statistics\n");
121287 + FM_DMP_LN(buf, n, "DSAR_Discarded: 0x%x\n", arStatistics->dsarDiscarded);
121288 + FM_DMP_LN(buf, n, "DSAR_Err_Discarded: 0x%x\n", arStatistics->dsarErrDiscarded);
121289 + FM_DMP_LN(buf, n, "DSAR_Frag_Discarded: 0x%x\n", arStatistics->dsarFragDiscarded);
121290 + FM_DMP_LN(buf, n, "DSAR_Tunnel_Discarded: 0x%x\n", arStatistics->dsarTunnelDiscarded);
121291 + FM_DMP_LN(buf, n, "DSAR_ARP_Discarded: 0x%x\n", arStatistics->dsarArpDiscarded);
121292 + FM_DMP_LN(buf, n, "DSAR_IP_Discarded: 0x%x\n", arStatistics->dsarIpDiscarded);
121293 + FM_DMP_LN(buf, n, "DSAR_TCP_Discarded: 0x%x\n", arStatistics->dsarTcpDiscarded);
121294 + FM_DMP_LN(buf, n, "DSAR_UDP_Discarded: 0x%x\n", arStatistics->dsarUdpDiscarded);
121295 + FM_DMP_LN(buf, n, "DSAR_ICMPv6_Checksum_Err: 0x%x\n", arStatistics->dsarIcmpV6ChecksumErr);
121296 + FM_DMP_LN(buf, n, "DSAR_ICMPv6_Other_Type: 0x%x\n", arStatistics->dsarIcmpV6OtherType);
121297 + FM_DMP_LN(buf, n, "DSAR_ICMPv4_Other_Type: 0x%x\n", arStatistics->dsarIcmpV4OtherType);
121298 +
121299 + iounmap(arStatistics);
121300 + }
121301 + if (ArCommonDescPtr->p_ArpDescriptor)
121302 + {
121303 + t_DsarArpDescriptor* ArpDescriptor = (t_DsarArpDescriptor*)
121304 + ioremap(ioread32be(&ArCommonDescPtr->p_ArpDescriptor) +
121305 + p_FmPort->fmMuramPhysBaseAddr,
121306 + sizeof (t_DsarArpDescriptor));
121307 + FM_DMP_LN(buf, n, "\nARP\n");
121308 + FM_DMP_LN(buf, n, "===\n");
121309 + FM_DMP_LN(buf, n, "control bits 0x%04x\n", ArpDescriptor->control);
121310 + if (ArpDescriptor->numOfBindings)
121311 + {
121312 + char ip_str[100];
121313 + t_DsarArpBindingEntry* bindings = ioremap(
121314 + ioread32be(&ArpDescriptor->p_Bindings) +
121315 + p_FmPort->fmMuramPhysBaseAddr,
121316 + ArpDescriptor->numOfBindings *
121317 + sizeof(t_DsarArpBindingEntry));
121318 + uint8_t* ip_addr = (uint8_t*)&bindings->ipv4Addr;
121319 + FM_DMP_LN(buf, n, " ip vlan id\n");
121320 + for (i = 0; i < ArpDescriptor->numOfBindings; i++)
121321 + {
121322 + n += snprintf(ip_str, 100, "%d.%d.%d.%d",
121323 + ip_addr[0], ip_addr[1],
121324 + ip_addr[2], ip_addr[3]);
121325 + FM_DMP_LN(buf, n, "%-15s 0x%x\n",
121326 + ip_str, bindings->vlanId);
121327 + }
121328 + iounmap(bindings);
121329 + }
121330 + if (ArpDescriptor->p_Statistics)
121331 + {
121332 + t_DsarArpStatistics* arpStats = ioremap(
121333 + ioread32be(&ArpDescriptor->p_Statistics) +
121334 + p_FmPort->fmMuramPhysBaseAddr,
121335 + sizeof(t_DsarArpStatistics));
121336 + FM_DMP_LN(buf, n, "statistics\n");
121337 + FM_DMP_LN(buf, n, "INVAL_CNT: 0x%x\n", arpStats->invalCnt);
121338 + FM_DMP_LN(buf, n, "ECHO_CNT: 0x%x\n", arpStats->echoCnt);
121339 + FM_DMP_LN(buf, n, "CD_CNT: 0x%x\n", arpStats->cdCnt);
121340 + FM_DMP_LN(buf, n, "AR_CNT: 0x%x\n", arpStats->arCnt);
121341 + FM_DMP_LN(buf, n, "RATM_CNT: 0x%x\n", arpStats->ratmCnt);
121342 + FM_DMP_LN(buf, n, "UKOP_CNT: 0x%x\n", arpStats->ukopCnt);
121343 + FM_DMP_LN(buf, n, "NMTP_CNT: 0x%x\n", arpStats->nmtpCnt);
121344 + FM_DMP_LN(buf, n, "NMVLAN_CNT: 0x%x\n", arpStats->nmVlanCnt);
121345 + iounmap(arpStats);
121346 + }
121347 +
121348 + iounmap(ArpDescriptor);
121349 + }
121350 + if (ArCommonDescPtr->p_IcmpV4Descriptor)
121351 + {
121352 + t_DsarIcmpV4Descriptor* ICMPV4Descriptor =
121353 + (t_DsarIcmpV4Descriptor*)ioremap(ioread32be(
121354 + &ArCommonDescPtr->p_IcmpV4Descriptor) +
121355 + p_FmPort->fmMuramPhysBaseAddr,
121356 + sizeof (t_DsarIcmpV4Descriptor));
121357 + FM_DMP_LN(buf, n, "\nEcho ICMPv4\n");
121358 + FM_DMP_LN(buf, n, "===========\n");
121359 + FM_DMP_LN(buf, n, "control bits 0x%04x\n", ICMPV4Descriptor->control);
121360 + if (ICMPV4Descriptor->numOfBindings)
121361 + {
121362 + char ip_str[100];
121363 + t_DsarArpBindingEntry* bindings = ioremap(
121364 + ioread32be(&ICMPV4Descriptor->p_Bindings) +
121365 + p_FmPort->fmMuramPhysBaseAddr,
121366 + ICMPV4Descriptor->numOfBindings *
121367 + sizeof(t_DsarArpBindingEntry));
121368 + uint8_t* ip_addr = (uint8_t*)&bindings->ipv4Addr;
121369 + FM_DMP_LN(buf, n, " ip vlan id\n");
121370 + for (i = 0; i < ICMPV4Descriptor->numOfBindings; i++)
121371 + {
121372 + n += snprintf(ip_str, 100, "%d.%d.%d.%d",
121373 + ip_addr[0], ip_addr[1],
121374 + ip_addr[2], ip_addr[3]);
121375 + FM_DMP_LN(buf, n, "%-15s 0x%x\n",
121376 + ip_str, bindings->vlanId);
121377 + }
121378 + iounmap(bindings);
121379 + }
121380 + if (ICMPV4Descriptor->p_Statistics)
121381 + {
121382 + t_DsarIcmpV4Statistics* icmpv4Stats = ioremap(
121383 + ioread32be(&ICMPV4Descriptor->p_Statistics) +
121384 + p_FmPort->fmMuramPhysBaseAddr,
121385 + sizeof(t_DsarIcmpV4Statistics));
121386 + FM_DMP_LN(buf, n, "statistics\n");
121387 + FM_DMP_LN(buf, n, "INVAL_CNT: 0x%x\n", icmpv4Stats->invalCnt);
121388 + FM_DMP_LN(buf, n, "NMVLAN_CNT: 0x%x\n", icmpv4Stats->nmVlanCnt);
121389 + FM_DMP_LN(buf, n, "NMIP_CNT: 0x%x\n", icmpv4Stats->nmIpCnt);
121390 + FM_DMP_LN(buf, n, "AR_CNT: 0x%x\n", icmpv4Stats->arCnt);
121391 + FM_DMP_LN(buf, n, "CSERR_CNT: 0x%x\n", icmpv4Stats->cserrCnt);
121392 + iounmap(icmpv4Stats);
121393 + }
121394 + iounmap(ICMPV4Descriptor);
121395 + }
121396 + if (ArCommonDescPtr->p_NdDescriptor)
121397 + {
121398 + t_DsarNdDescriptor *NDDescriptor =
121399 + (t_DsarNdDescriptor*)ioremap(ioread32be(
121400 + &ArCommonDescPtr->p_NdDescriptor) + p_FmPort->
121401 + fmMuramPhysBaseAddr, sizeof (t_DsarNdDescriptor));
121402 + FM_DMP_LN(buf, n, "\nNDP\n");
121403 + FM_DMP_LN(buf, n, "===\n");
121404 + FM_DMP_LN(buf, n, "control bits 0x%04x\n", NDDescriptor->control);
121405 + FM_DMP_LN(buf, n, "solicited address 0x%08x\n", NDDescriptor->solicitedAddr);
121406 + if (NDDescriptor->numOfBindings)
121407 + {
121408 + char ip_str[100];
121409 + t_DsarIcmpV6BindingEntry* bindings = ioremap(
121410 + ioread32be(&NDDescriptor->p_Bindings) +
121411 + p_FmPort->fmMuramPhysBaseAddr,
121412 + NDDescriptor->numOfBindings *
121413 + sizeof(t_DsarIcmpV6BindingEntry));
121414 + uint16_t* ip_addr = (uint16_t*)&bindings->ipv6Addr;
121415 + FM_DMP_LN(buf, n, " ip vlan id\n");
121416 + for (i = 0; i < NDDescriptor->numOfBindings; i++)
121417 + {
121418 + n += snprintf(ip_str, 100,
121419 + "%04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x",
121420 + ip_addr[0], ip_addr[1], ip_addr[2], ip_addr[3],
121421 + ip_addr[4], ip_addr[5], ip_addr[6], ip_addr[7]);
121422 + FM_DMP_LN(buf, n, "%s 0x%x\n", ip_str, bindings->vlanId);
121423 + }
121424 + iounmap(bindings);
121425 + }
121426 + if (NDDescriptor->p_Statistics)
121427 + {
121428 + t_NdStatistics* ndStats = ioremap(
121429 + ioread32be(&NDDescriptor->p_Statistics) +
121430 + p_FmPort->fmMuramPhysBaseAddr,
121431 + sizeof(t_NdStatistics));
121432 + FM_DMP_LN(buf, n, "statistics\n");
121433 + FM_DMP_LN(buf, n, "INVAL_CNT: 0x%x\n", ndStats->invalCnt);
121434 + FM_DMP_LN(buf, n, "NMVLAN_CNT: 0x%x\n", ndStats->nmVlanCnt);
121435 + FM_DMP_LN(buf, n, "NMIP_CNT: 0x%x\n", ndStats->nmIpCnt);
121436 + FM_DMP_LN(buf, n, "AR_CNT: 0x%x\n", ndStats->arCnt);
121437 + FM_DMP_LN(buf, n, "USADVERT_CNT: 0x%x\n", ndStats->usadvertCnt);
121438 + FM_DMP_LN(buf, n, "NMMCAST_CNT: 0x%x\n", ndStats->nmmcastCnt);
121439 + FM_DMP_LN(buf, n, "NSLLA_CNT: 0x%x\n", ndStats->nsllaCnt);
121440 + iounmap(ndStats);
121441 + }
121442 + iounmap(NDDescriptor);
121443 + }
121444 + if (ArCommonDescPtr->p_IcmpV6Descriptor)
121445 + {
121446 + t_DsarIcmpV6Descriptor *ICMPV6Descriptor =
121447 + (t_DsarIcmpV6Descriptor*)ioremap(ioread32be(
121448 + &ArCommonDescPtr->p_IcmpV6Descriptor) + p_FmPort->
121449 + fmMuramPhysBaseAddr, sizeof (t_DsarIcmpV6Descriptor));
121450 + FM_DMP_LN(buf, n, "\nEcho ICMPv6\n");
121451 + FM_DMP_LN(buf, n, "===========\n");
121452 + FM_DMP_LN(buf, n, "control bits 0x%04x\n", ICMPV6Descriptor->control);
121453 + if (ICMPV6Descriptor->numOfBindings)
121454 + {
121455 + char ip_str[100];
121456 + t_DsarIcmpV6BindingEntry* bindings = ioremap(
121457 + ioread32be(&ICMPV6Descriptor->p_Bindings) +
121458 + p_FmPort->fmMuramPhysBaseAddr,
121459 + ICMPV6Descriptor->numOfBindings *
121460 + sizeof(t_DsarIcmpV6BindingEntry));
121461 + uint16_t* ip_addr = (uint16_t*)&bindings->ipv6Addr;
121462 + FM_DMP_LN(buf, n, " ip vlan id\n");
121463 + for (i = 0; i < ICMPV6Descriptor->numOfBindings; i++)
121464 + {
121465 + n += snprintf(ip_str, 100,
121466 + "%04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x",
121467 + ip_addr[0], ip_addr[1], ip_addr[2], ip_addr[3],
121468 + ip_addr[4], ip_addr[5], ip_addr[6], ip_addr[7]);
121469 + FM_DMP_LN(buf, n, "%s 0x%x\n", ip_str, bindings->vlanId);
121470 + }
121471 + iounmap(bindings);
121472 + }
121473 + if (ICMPV6Descriptor->p_Statistics)
121474 + {
121475 + t_DsarIcmpV6Statistics* icmpv6Stats = ioremap(
121476 + ioread32be(&ICMPV6Descriptor->p_Statistics) +
121477 + p_FmPort->fmMuramPhysBaseAddr,
121478 + sizeof(t_DsarIcmpV6Statistics));
121479 + FM_DMP_LN(buf, n, "statistics\n");
121480 + FM_DMP_LN(buf, n, "INVAL_CNT: 0x%x\n", icmpv6Stats->invalCnt);
121481 + FM_DMP_LN(buf, n, "NMVLAN_CNT: 0x%x\n", icmpv6Stats->nmVlanCnt);
121482 + FM_DMP_LN(buf, n, "NMIP_CNT: 0x%x\n", icmpv6Stats->nmIpCnt);
121483 + FM_DMP_LN(buf, n, "AR_CNT: 0x%x\n", icmpv6Stats->arCnt);
121484 + iounmap(icmpv6Stats);
121485 + }
121486 + iounmap(ICMPV6Descriptor);
121487 + }
121488 + if (ArCommonDescPtr->p_SnmpDescriptor)
121489 + {
121490 + t_DsarSnmpDescriptor *SnmpDescriptor =
121491 + (t_DsarSnmpDescriptor*)ioremap(ioread32be(
121492 + &ArCommonDescPtr->p_SnmpDescriptor) + p_FmPort->
121493 + fmMuramPhysBaseAddr, sizeof (t_DsarSnmpDescriptor));
121494 + FM_DMP_LN(buf, n, "\nSNMP\n");
121495 + FM_DMP_LN(buf, n, "===========\n");
121496 + FM_DMP_LN(buf, n, "control bits 0x%04x\n", SnmpDescriptor->control);
121497 + FM_DMP_LN(buf, n, "max message length 0x%04x\n", SnmpDescriptor->maxSnmpMsgLength);
121498 + if (SnmpDescriptor->numOfIpv4Addresses)
121499 + {
121500 + char ip_str[100];
121501 + t_DsarSnmpIpv4AddrTblEntry* addrs = ioremap(
121502 + ioread32be(&SnmpDescriptor->p_Ipv4AddrTbl) +
121503 + p_FmPort->fmMuramPhysBaseAddr,
121504 + SnmpDescriptor->numOfIpv4Addresses *
121505 + sizeof(t_DsarSnmpIpv4AddrTblEntry));
121506 + uint8_t* ip_addr = (uint8_t*)&addrs->ipv4Addr;
121507 + FM_DMP_LN(buf, n, " ip vlan id\n");
121508 + for (i = 0; i < SnmpDescriptor->numOfIpv4Addresses; i++)
121509 + {
121510 + n += snprintf(ip_str, 100, "%d.%d.%d.%d",
121511 + ip_addr[0], ip_addr[1],
121512 + ip_addr[2], ip_addr[3]);
121513 + FM_DMP_LN(buf, n, "%-15s 0x%x\n", ip_str, addrs->vlanId);
121514 + }
121515 + iounmap(addrs);
121516 + }
121517 + if (SnmpDescriptor->p_Statistics)
121518 + {
121519 + t_DsarSnmpStatistics* snmpStats = ioremap(
121520 + ioread32be(&SnmpDescriptor->p_Statistics) +
121521 + p_FmPort->fmMuramPhysBaseAddr,
121522 + sizeof(t_DsarSnmpStatistics));
121523 + FM_DMP_LN(buf, n, "statistics\n");
121524 + FM_DMP_LN(buf, n, "snmpErrCnt: 0x%x\n", snmpStats->snmpErrCnt);
121525 + FM_DMP_LN(buf, n, "snmpCommunityErrCnt: 0x%x\n", snmpStats->snmpCommunityErrCnt);
121526 + FM_DMP_LN(buf, n, "snmpTotalDiscardCnt: 0x%x\n", snmpStats->snmpTotalDiscardCnt);
121527 + FM_DMP_LN(buf, n, "snmpGetReqCnt: 0x%x\n", snmpStats->snmpGetReqCnt);
121528 + FM_DMP_LN(buf, n, "snmpGetNextReqCnt: 0x%x\n", snmpStats->snmpGetNextReqCnt);
121529 + iounmap(snmpStats);
121530 + }
121531 + iounmap(SnmpDescriptor);
121532 + }
121533 + iounmap(ArCommonDescPtr);
121534 + iounmap(param_page);
121535 + return n;
121536 +}
121537 +
121538 +static ssize_t show_fm_port_dsar_mem(struct device *dev,
121539 + struct device_attribute *attr, char *buf)
121540 +{
121541 + unsigned long flags;
121542 + unsigned n = 0;
121543 +#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
121544 + t_LnxWrpFmPortDev *p_LnxWrpFmPortDev;
121545 +#endif
121546 + if (attr == NULL || buf == NULL || dev == NULL)
121547 + return -EINVAL;
121548 +
121549 +#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
121550 + p_LnxWrpFmPortDev =
121551 + (t_LnxWrpFmPortDev *) dev_get_drvdata(dev);
121552 +
121553 + local_irq_save(flags);
121554 +
121555 + if (!p_LnxWrpFmPortDev->h_Dev) {
121556 + n = snprintf(buf, PAGE_SIZE, "\tFM Port not configured...\n");
121557 + return n;
121558 + } else {
121559 + n = snprintf(buf, PAGE_SIZE,
121560 + "FM port driver registers dump.\n");
121561 + n = fm_port_dsar_dump_mem(p_LnxWrpFmPortDev->h_Dev, buf, n);
121562 + }
121563 +
121564 + local_irq_restore(flags);
121565 +
121566 + return n;
121567 +#else
121568 +
121569 + local_irq_save(flags);
121570 + n = snprintf(buf, PAGE_SIZE,
121571 + "Debug level is too low to dump registers!!!\n");
121572 + local_irq_restore(flags);
121573 +
121574 + return n;
121575 +#endif
121576 +}
121577 +
121578 +static ssize_t show_fm_port_dsar_regs(struct device *dev,
121579 + struct device_attribute *attr, char *buf)
121580 +{
121581 + unsigned long flags;
121582 + unsigned n = 0;
121583 +#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
121584 + t_LnxWrpFmPortDev *p_LnxWrpFmPortDev;
121585 +#endif
121586 + if (attr == NULL || buf == NULL || dev == NULL)
121587 + return -EINVAL;
121588 +
121589 +#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
121590 + p_LnxWrpFmPortDev =
121591 + (t_LnxWrpFmPortDev *) dev_get_drvdata(dev);
121592 +
121593 + local_irq_save(flags);
121594 +
121595 + if (!p_LnxWrpFmPortDev->h_Dev) {
121596 + n = snprintf(buf, PAGE_SIZE, "\tFM Port not configured...\n");
121597 + return n;
121598 + } else {
121599 + n = snprintf(buf, PAGE_SIZE,
121600 + "FM port driver registers dump.\n");
121601 + n = fm_port_dsar_dump_regs(p_LnxWrpFmPortDev->h_Dev, buf, n);
121602 + }
121603 +
121604 + local_irq_restore(flags);
121605 +
121606 + return n;
121607 +#else
121608 +
121609 + local_irq_save(flags);
121610 + n = snprintf(buf, PAGE_SIZE,
121611 + "Debug level is too low to dump registers!!!\n");
121612 + local_irq_restore(flags);
121613 +
121614 + return n;
121615 +#endif
121616 +}
121617 +
121618 +#if (DPAA_VERSION >= 11)
121619 +static ssize_t show_fm_port_ipv4_options(struct device *dev,
121620 + struct device_attribute *attr, char *buf)
121621 +{
121622 + unsigned long flags;
121623 + unsigned n = 0;
121624 +#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
121625 + t_LnxWrpFmPortDev *p_LnxWrpFmPortDev;
121626 +#endif
121627 +
121628 + if (attr == NULL || buf == NULL || dev == NULL)
121629 + return -EINVAL;
121630 +
121631 +#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
121632 + p_LnxWrpFmPortDev =
121633 + (t_LnxWrpFmPortDev *) dev_get_drvdata(dev);
121634 +
121635 + local_irq_save(flags);
121636 +
121637 + if (!p_LnxWrpFmPortDev->h_Dev) {
121638 + n = snprintf(buf, PAGE_SIZE, "\tFM Port not configured...\n");
121639 + return n;
121640 + } else if (((t_FmPort *)p_LnxWrpFmPortDev->h_Dev)->p_ParamsPage
121641 + == NULL) {
121642 + n = snprintf(buf, PAGE_SIZE,
121643 + "\tPort: FMan-controller params page not set\n");
121644 + return n;
121645 + } else {
121646 + n = snprintf(buf, PAGE_SIZE,
121647 + "Counter for fragmented pkt with IP header options\n");
121648 + n = fm_port_dump_ipv4_opt(p_LnxWrpFmPortDev->h_Dev, buf, n);
121649 + }
121650 +
121651 + local_irq_restore(flags);
121652 +
121653 + return n;
121654 +#else
121655 +
121656 + local_irq_save(flags);
121657 + n = snprintf(buf, PAGE_SIZE,
121658 + "Debug level is too low to dump registers!!!\n");
121659 + local_irq_restore(flags);
121660 +
121661 + return n;
121662 +#endif
121663 +}
121664 +
121665 +#endif
121666 +
121667 +static ssize_t show_fm_port_bmi_regs(struct device *dev,
121668 + struct device_attribute *attr, char *buf)
121669 +{
121670 + unsigned long flags;
121671 + unsigned n = 0;
121672 +#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
121673 + t_LnxWrpFmPortDev *p_LnxWrpFmPortDev;
121674 +#endif
121675 +
121676 + if (attr == NULL || buf == NULL || dev == NULL)
121677 + return -EINVAL;
121678 +
121679 +#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
121680 + p_LnxWrpFmPortDev =
121681 + (t_LnxWrpFmPortDev *) dev_get_drvdata(dev);
121682 +
121683 + local_irq_save(flags);
121684 +
121685 + if (!p_LnxWrpFmPortDev->h_Dev) {
121686 + n = snprintf(buf, PAGE_SIZE, "\tFM Port not configured...\n");
121687 + return n;
121688 + } else {
121689 + n = snprintf(buf, PAGE_SIZE,
121690 + "FM port driver registers dump.\n");
121691 + n = fm_port_dump_regs_bmi(p_LnxWrpFmPortDev->h_Dev, buf, n);
121692 + }
121693 +
121694 + local_irq_restore(flags);
121695 +
121696 + return n;
121697 +#else
121698 +
121699 + local_irq_save(flags);
121700 + n = snprintf(buf, PAGE_SIZE,
121701 + "Debug level is too low to dump registers!!!\n");
121702 + local_irq_restore(flags);
121703 +
121704 + return n;
121705 +#endif
121706 +}
121707 +
121708 +static ssize_t show_fm_port_qmi_regs(struct device *dev,
121709 + struct device_attribute *attr, char *buf)
121710 +{
121711 + unsigned long flags;
121712 + unsigned n = 0;
121713 +#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
121714 + t_LnxWrpFmPortDev *p_LnxWrpFmPortDev;
121715 +#endif
121716 +
121717 + if (attr == NULL || buf == NULL || dev == NULL)
121718 + return -EINVAL;
121719 +
121720 +#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
121721 + p_LnxWrpFmPortDev =
121722 + (t_LnxWrpFmPortDev *) dev_get_drvdata(dev);
121723 +
121724 + local_irq_save(flags);
121725 +
121726 + if (!p_LnxWrpFmPortDev->h_Dev) {
121727 + n = snprintf(buf, PAGE_SIZE, "\tFM Port not configured...\n");
121728 + return n;
121729 + } else {
121730 + n = snprintf(buf, PAGE_SIZE,
121731 + "FM port driver registers dump.\n");
121732 + n = fm_port_dump_regs_qmi(p_LnxWrpFmPortDev->h_Dev, buf, n);
121733 + }
121734 +
121735 + local_irq_restore(flags);
121736 +
121737 + return n;
121738 +#else
121739 +
121740 + local_irq_save(flags);
121741 + n = snprintf(buf, PAGE_SIZE,
121742 + "Debug level is too low to dump registers!!!\n");
121743 + local_irq_restore(flags);
121744 +
121745 + return n;
121746 +#endif
121747 +}
121748 +
121749 +static DEVICE_ATTR(fm_port_regs, S_IRUGO | S_IRUSR, show_fm_port_regs, NULL);
121750 +static DEVICE_ATTR(fm_port_qmi_regs, S_IRUGO | S_IRUSR, show_fm_port_qmi_regs, NULL);
121751 +static DEVICE_ATTR(fm_port_bmi_regs, S_IRUGO | S_IRUSR, show_fm_port_bmi_regs, NULL);
121752 +#if (DPAA_VERSION >= 11)
121753 +static DEVICE_ATTR(fm_port_ipv4_opt, S_IRUGO | S_IRUSR, show_fm_port_ipv4_options, NULL);
121754 +#endif
121755 +static DEVICE_ATTR(fm_port_dsar_regs, S_IRUGO | S_IRUSR, show_fm_port_dsar_regs, NULL);
121756 +static DEVICE_ATTR(fm_port_dsar_mem, S_IRUGO | S_IRUSR, show_fm_port_dsar_mem, NULL);
121757 +
121758 +int fm_port_sysfs_create(struct device *dev)
121759 +{
121760 + t_LnxWrpFmPortDev *p_LnxWrpFmPortDev;
121761 +
121762 + if (dev == NULL)
121763 + return -EINVAL;
121764 +
121765 + p_LnxWrpFmPortDev = (t_LnxWrpFmPortDev *) dev_get_drvdata(dev);
121766 + if (WARN_ON(p_LnxWrpFmPortDev == NULL))
121767 + return -EINVAL;
121768 +
121769 + /* store to remove them when module is disabled */
121770 + p_LnxWrpFmPortDev->dev_attr_regs = &dev_attr_fm_port_regs;
121771 + p_LnxWrpFmPortDev->dev_attr_qmi_regs = &dev_attr_fm_port_qmi_regs;
121772 + p_LnxWrpFmPortDev->dev_attr_bmi_regs = &dev_attr_fm_port_bmi_regs;
121773 +#if (DPAA_VERSION >= 11)
121774 + p_LnxWrpFmPortDev->dev_attr_ipv4_opt = &dev_attr_fm_port_ipv4_opt;
121775 +#endif
121776 + p_LnxWrpFmPortDev->dev_attr_dsar_regs = &dev_attr_fm_port_dsar_regs;
121777 + p_LnxWrpFmPortDev->dev_attr_dsar_mem = &dev_attr_fm_port_dsar_mem;
121778 + /* Registers dump entry - in future will be moved to debugfs */
121779 + if (device_create_file(dev, &dev_attr_fm_port_regs) != 0)
121780 + return -EIO;
121781 + if (device_create_file(dev, &dev_attr_fm_port_qmi_regs) != 0)
121782 + return -EIO;
121783 + if (device_create_file(dev, &dev_attr_fm_port_bmi_regs) != 0)
121784 + return -EIO;
121785 +#if (DPAA_VERSION >= 11)
121786 + if (device_create_file(dev, &dev_attr_fm_port_ipv4_opt) != 0)
121787 + return -EIO;
121788 +#endif
121789 + if (device_create_file(dev, &dev_attr_fm_port_dsar_regs) != 0)
121790 + return -EIO;
121791 + if (device_create_file(dev, &dev_attr_fm_port_dsar_mem) != 0)
121792 + return -EIO;
121793 +
121794 + /* FM Ports statistics */
121795 + switch (p_LnxWrpFmPortDev->settings.param.portType) {
121796 + case e_FM_PORT_TYPE_TX:
121797 + case e_FM_PORT_TYPE_TX_10G:
121798 + if (sysfs_create_group
121799 + (&dev->kobj, &fm_tx_port_dev_stats_attr_grp) != 0)
121800 + return -EIO;
121801 + break;
121802 + case e_FM_PORT_TYPE_RX:
121803 + case e_FM_PORT_TYPE_RX_10G:
121804 + if (sysfs_create_group
121805 + (&dev->kobj, &fm_rx_port_dev_stats_attr_grp) != 0)
121806 + return -EIO;
121807 + break;
121808 + case e_FM_PORT_TYPE_DUMMY:
121809 + case e_FM_PORT_TYPE_OH_OFFLINE_PARSING:
121810 + if (sysfs_create_group
121811 + (&dev->kobj, &fm_oh_port_dev_stats_attr_grp) != 0)
121812 + return -EIO;
121813 + break;
121814 + default:
121815 + WARN(1, "FMD: failure at %s:%d/%s()!\n", __FILE__, __LINE__,
121816 + __func__);
121817 + return -EINVAL;
121818 + break;
121819 + };
121820 +
121821 + return 0;
121822 +}
121823 +
121824 +void fm_port_sysfs_destroy(struct device *dev)
121825 +{
121826 + t_LnxWrpFmPortDev *p_LnxWrpFmPortDev = NULL;
121827 +
121828 + /* this function has never been tested !!! */
121829 +
121830 + if (WARN_ON(dev == NULL))
121831 + return;
121832 +
121833 + p_LnxWrpFmPortDev = (t_LnxWrpFmPortDev *) dev_get_drvdata(dev);
121834 + if (WARN_ON(p_LnxWrpFmPortDev == NULL))
121835 + return;
121836 +
121837 + /* The name attribute will be freed also by these 2 functions? */
121838 + switch (p_LnxWrpFmPortDev->settings.param.portType) {
121839 + case e_FM_PORT_TYPE_TX:
121840 + case e_FM_PORT_TYPE_TX_10G:
121841 + sysfs_remove_group(&dev->kobj, &fm_tx_port_dev_stats_attr_grp);
121842 + break;
121843 + case e_FM_PORT_TYPE_RX:
121844 + case e_FM_PORT_TYPE_RX_10G:
121845 + sysfs_remove_group(&dev->kobj, &fm_rx_port_dev_stats_attr_grp);
121846 + break;
121847 + case e_FM_PORT_TYPE_DUMMY:
121848 + case e_FM_PORT_TYPE_OH_OFFLINE_PARSING:
121849 + sysfs_remove_group(&dev->kobj, &fm_oh_port_dev_stats_attr_grp);
121850 + break;
121851 + default:
121852 + WARN(1, "FMD: failure at %s:%d/%s()!\n", __FILE__, __LINE__,
121853 + __func__);
121854 + break;
121855 + };
121856 +
121857 + device_remove_file(dev, p_LnxWrpFmPortDev->dev_attr_regs);
121858 + device_remove_file(dev, p_LnxWrpFmPortDev->dev_attr_qmi_regs);
121859 + device_remove_file(dev, p_LnxWrpFmPortDev->dev_attr_bmi_regs);
121860 +#if (DPAA_VERSION >= 11)
121861 + device_remove_file(dev, p_LnxWrpFmPortDev->dev_attr_ipv4_opt);
121862 +#endif
121863 + device_remove_file(dev, p_LnxWrpFmPortDev->dev_attr_dsar_regs);
121864 + device_remove_file(dev, p_LnxWrpFmPortDev->dev_attr_dsar_mem);
121865 +}
121866 +
121867 +
121868 +int fm_port_dump_regs(void *h_dev, char *buf, int nn)
121869 +{
121870 + t_FmPort *p_FmPort;
121871 + t_Fm *p_Fm;
121872 + uint8_t hardwarePortId;
121873 + int n = nn;
121874 +
121875 + p_FmPort = (t_FmPort *)h_dev;
121876 + hardwarePortId = p_FmPort->hardwarePortId;
121877 + p_Fm = (t_Fm *)p_FmPort->h_Fm;
121878 +
121879 + FM_DMP_TITLE(buf, n, &p_Fm->p_FmBmiRegs->fmbm_pp[hardwarePortId - 1],
121880 + "fmbm_pp for port %u", hardwarePortId);
121881 + FM_DMP_MEM_32(buf, n,
121882 + &p_Fm->p_FmBmiRegs->fmbm_pp[hardwarePortId - 1]);
121883 +
121884 + FM_DMP_TITLE(buf, n, &p_Fm->p_FmBmiRegs->fmbm_pfs[hardwarePortId - 1],
121885 + "fmbm_pfs for port %u", hardwarePortId);
121886 + FM_DMP_MEM_32(buf, n,
121887 + &p_Fm->p_FmBmiRegs->fmbm_pfs[hardwarePortId - 1]);
121888 +
121889 + FM_DMP_TITLE(buf, n,
121890 + &p_Fm->p_FmBmiRegs->fmbm_spliodn[hardwarePortId - 1],
121891 + "fmbm_spliodn for port %u", hardwarePortId);
121892 + FM_DMP_MEM_32(buf, n,
121893 + &p_Fm->p_FmBmiRegs->fmbm_spliodn[hardwarePortId - 1]);
121894 +
121895 + FM_DMP_TITLE(buf, n, &p_Fm->p_FmFpmRegs->fmfp_ps[hardwarePortId],
121896 + "fmfp_psfor port %u", hardwarePortId);
121897 + FM_DMP_MEM_32(buf, n, &p_Fm->p_FmFpmRegs->fmfp_ps[hardwarePortId]);
121898 +
121899 + FM_DMP_TITLE(buf, n, &p_Fm->p_FmDmaRegs->fmdmplr[hardwarePortId / 2],
121900 + "fmdmplrfor port %u", hardwarePortId);
121901 + FM_DMP_MEM_32(buf, n,
121902 + &p_Fm->p_FmDmaRegs->fmdmplr[hardwarePortId / 2]);
121903 + return n;
121904 +}
121905 +
121906 +#if (DPAA_VERSION >= 11)
121907 +
121908 +int fm_port_dump_ipv4_opt(void *h_dev, char *buf, int nn)
121909 +{
121910 + t_FmPort *p_FmPort;
121911 + int n = nn;
121912 +
121913 + p_FmPort = (t_FmPort *)h_dev;
121914 +
121915 + FM_DMP_V32(buf, n, p_FmPort->p_ParamsPage, ipfOptionsCounter);
121916 +
121917 + FM_DMP_SUBTITLE(buf, n, "\n");
121918 +
121919 + return n;
121920 +}
121921 +#endif
121922 +
121923 +int fm_port_dump_regs_bmi(void *h_dev, char *buf, int nn)
121924 +{
121925 + t_FmPort *p_FmPort;
121926 + u_FmPortBmiRegs *p_bmi;
121927 +
121928 + char arr[20];
121929 + uint8_t flag;
121930 + int i = 0;
121931 + int n = nn;
121932 +
121933 + p_FmPort = (t_FmPort *)h_dev;
121934 + p_bmi = p_FmPort->p_FmPortBmiRegs;
121935 +
121936 + memset(arr, 0, sizeof(arr));
121937 + switch (p_FmPort->portType) {
121938 + case (e_FM_PORT_TYPE_OH_OFFLINE_PARSING):
121939 + strcpy(arr, "OFFLINE-PARSING");
121940 + flag = 0;
121941 + break;
121942 + case (e_FM_PORT_TYPE_OH_HOST_COMMAND):
121943 + strcpy(arr, "HOST-COMMAND");
121944 + flag = 0;
121945 + break;
121946 + case (e_FM_PORT_TYPE_RX):
121947 + strcpy(arr, "RX");
121948 + flag = 1;
121949 + break;
121950 + case (e_FM_PORT_TYPE_RX_10G):
121951 + strcpy(arr, "RX-10G");
121952 + flag = 1;
121953 + break;
121954 + case (e_FM_PORT_TYPE_TX):
121955 + strcpy(arr, "TX");
121956 + flag = 2;
121957 + break;
121958 + case (e_FM_PORT_TYPE_TX_10G):
121959 + strcpy(arr, "TX-10G");
121960 + flag = 2;
121961 + break;
121962 + default:
121963 + return -EINVAL;
121964 + }
121965 +
121966 + FM_DMP_TITLE(buf, n, NULL,
121967 + "FMan-Port (%s #%d) registers:",
121968 + arr, p_FmPort->portId);
121969 +
121970 + FM_DMP_TITLE(buf, n, p_bmi, "Bmi Port Regs");
121971 +
121972 + switch (flag) {
121973 + case (0):
121974 + FM_DMP_SUBTITLE(buf, n, "\n");
121975 + FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_ocfg);
121976 + FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_ost);
121977 + FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_oda);
121978 + FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_oicp);
121979 + FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_ofdne);
121980 + FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_ofne);
121981 + FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_ofca);
121982 + FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_ofpne);
121983 + FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_opso);
121984 + FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_opp);
121985 + FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_occb);
121986 + FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_oim);
121987 + FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_ofp);
121988 + FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_ofed);
121989 +
121990 + FM_DMP_TITLE(buf, n,
121991 + &(p_bmi->ohPortBmiRegs.fmbm_oprai), "fmbm_oprai");
121992 + for (i = 0; i < FM_PORT_PRS_RESULT_NUM_OF_WORDS; ++i) {
121993 + FM_DMP_MEM_32(buf, n,
121994 + &(p_bmi->ohPortBmiRegs.fmbm_oprai[i]));
121995 + }
121996 + FM_DMP_SUBTITLE(buf, n, "\n");
121997 + FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_ofqid);
121998 + FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_oefqid);
121999 + FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_ofsdm);
122000 + FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_ofsem);
122001 + FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_ofene);
122002 + FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_orlmts);
122003 + FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_orlmt);
122004 + FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_ocmne);
122005 + {
122006 +#ifndef FM_NO_OP_OBSERVED_POOLS
122007 + if (p_FmPort->fmRevInfo.majorRev == 4) {
122008 + FM_DMP_TITLE(buf, n,
122009 + &p_bmi->ohPortBmiRegs.fmbm_oebmpi,
122010 + "fmbm_oebmpi");
122011 +
122012 + for (i = 0; i < FM_PORT_MAX_NUM_OF_OBSERVED_EXT_POOLS; ++i) {
122013 + FM_DMP_MEM_32(buf, n,
122014 + &(p_bmi->ohPortBmiRegs.fmbm_oebmpi[i]));
122015 + }
122016 + FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_ocgm);
122017 + }
122018 +#endif /* !FM_NO_OP_OBSERVED_POOLS */
122019 + }
122020 + FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_ostc);
122021 + FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_ofrc);
122022 + FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_ofdc);
122023 + FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_ofledc);
122024 + FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_ofufdc);
122025 + FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_offc);
122026 + FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_ofwdc);
122027 + FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_ofldec);
122028 + FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_opc);
122029 + FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_opcp);
122030 + FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_occn);
122031 + FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_otuc);
122032 + FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_oduc);
122033 + FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_ofuc);
122034 + FM_DMP_TITLE(buf, n, &(p_bmi->ohPortBmiRegs.fmbm_odcfg),
122035 + "fmbm_odcfg");
122036 + for (i = 0; i < 3; ++i) {
122037 + FM_DMP_MEM_32(buf, n,
122038 + &(p_bmi->ohPortBmiRegs.fmbm_odcfg[i]));
122039 + }
122040 + FM_DMP_SUBTITLE(buf, n, "\n");
122041 +
122042 + FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_ogpr);
122043 + break;
122044 + case (1):
122045 + FM_DMP_SUBTITLE(buf, n, "\n");
122046 + FM_DMP_V32(buf, n, &p_bmi->rxPortBmiRegs, fmbm_rcfg);
122047 + FM_DMP_V32(buf, n, &p_bmi->rxPortBmiRegs, fmbm_rst);
122048 + FM_DMP_V32(buf, n, &p_bmi->rxPortBmiRegs, fmbm_rda);
122049 + FM_DMP_V32(buf, n, &p_bmi->rxPortBmiRegs, fmbm_rfp);
122050 + FM_DMP_V32(buf, n, &p_bmi->rxPortBmiRegs, fmbm_reth);
122051 + FM_DMP_V32(buf, n, &p_bmi->rxPortBmiRegs, fmbm_rfed);
122052 + FM_DMP_V32(buf, n, &p_bmi->rxPortBmiRegs, fmbm_ricp);
122053 + FM_DMP_V32(buf, n, &p_bmi->rxPortBmiRegs, fmbm_rebm);
122054 + FM_DMP_V32(buf, n, &p_bmi->rxPortBmiRegs, fmbm_rfne);
122055 + FM_DMP_V32(buf, n, &p_bmi->rxPortBmiRegs, fmbm_rfca);
122056 + FM_DMP_V32(buf, n, &p_bmi->rxPortBmiRegs, fmbm_rfpne);
122057 + FM_DMP_V32(buf, n, &p_bmi->rxPortBmiRegs, fmbm_rpso);
122058 + FM_DMP_V32(buf, n, &p_bmi->rxPortBmiRegs, fmbm_rpp);
122059 + FM_DMP_TITLE(buf, n, &(p_bmi->rxPortBmiRegs.fmbm_rprai),
122060 + "fmbm_rprai");
122061 + for (i = 0; i < FM_PORT_PRS_RESULT_NUM_OF_WORDS; ++i) {
122062 + FM_DMP_MEM_32(buf, n,
122063 + &(p_bmi->rxPortBmiRegs.fmbm_rprai[i]));
122064 + }
122065 + FM_DMP_SUBTITLE(buf, n, "\n");
122066 + FM_DMP_V32(buf, n, &p_bmi->rxPortBmiRegs, fmbm_rfqid);
122067 + FM_DMP_V32(buf, n, &p_bmi->rxPortBmiRegs, fmbm_refqid);
122068 + FM_DMP_V32(buf, n, &p_bmi->rxPortBmiRegs, fmbm_rfsdm);
122069 + FM_DMP_V32(buf, n, &p_bmi->rxPortBmiRegs, fmbm_rfsem);
122070 + FM_DMP_V32(buf, n, &p_bmi->rxPortBmiRegs, fmbm_rfene);
122071 + FM_DMP_V32(buf, n, &p_bmi->rxPortBmiRegs, fmbm_rcmne);
122072 + FM_DMP_TITLE(buf, n, &p_bmi->rxPortBmiRegs.fmbm_ebmpi,
122073 + "fmbm_ebmpi");
122074 + for (i = 0; i < FM_PORT_MAX_NUM_OF_EXT_POOLS; ++i) {
122075 + FM_DMP_MEM_32(buf, n,
122076 + &(p_bmi->rxPortBmiRegs.fmbm_ebmpi[i]));
122077 + }
122078 + FM_DMP_TITLE(buf, n, &p_bmi->rxPortBmiRegs.fmbm_acnt,
122079 + "fmbm_acnt");
122080 + for (i = 0; i < FM_PORT_MAX_NUM_OF_EXT_POOLS; ++i) {
122081 + FM_DMP_MEM_32(buf, n,
122082 + &(p_bmi->rxPortBmiRegs.fmbm_acnt[i]));
122083 + }
122084 + FM_DMP_TITLE(buf, n, &p_bmi->rxPortBmiRegs.fmbm_rcgm,
122085 + "fmbm_rcgm");
122086 + for (i = 0; i < FM_PORT_NUM_OF_CONGESTION_GRPS / 32; ++i) {
122087 + FM_DMP_MEM_32(buf, n,
122088 + &(p_bmi->rxPortBmiRegs.fmbm_rcgm[i]));
122089 + }
122090 +
122091 + FM_DMP_SUBTITLE(buf, n, "\n");
122092 + FM_DMP_V32(buf, n, &p_bmi->rxPortBmiRegs, fmbm_rmpd);
122093 + FM_DMP_V32(buf, n, &p_bmi->rxPortBmiRegs, fmbm_rstc);
122094 + FM_DMP_V32(buf, n, &p_bmi->rxPortBmiRegs, fmbm_rfrc);
122095 + FM_DMP_V32(buf, n, &p_bmi->rxPortBmiRegs, fmbm_rfbc);
122096 + FM_DMP_V32(buf, n, &p_bmi->rxPortBmiRegs, fmbm_rlfc);
122097 + FM_DMP_V32(buf, n, &p_bmi->rxPortBmiRegs, fmbm_rffc);
122098 + FM_DMP_V32(buf, n, &p_bmi->rxPortBmiRegs, fmbm_rfcd);
122099 + FM_DMP_V32(buf, n, &p_bmi->rxPortBmiRegs, fmbm_rfldec);
122100 + FM_DMP_V32(buf, n, &p_bmi->rxPortBmiRegs, fmbm_rodc);
122101 + FM_DMP_V32(buf, n, &p_bmi->rxPortBmiRegs, fmbm_rpc);
122102 + FM_DMP_V32(buf, n, &p_bmi->rxPortBmiRegs, fmbm_rpcp);
122103 + FM_DMP_V32(buf, n, &p_bmi->rxPortBmiRegs, fmbm_rccn);
122104 + FM_DMP_V32(buf, n, &p_bmi->rxPortBmiRegs, fmbm_rtuc);
122105 + FM_DMP_V32(buf, n, &p_bmi->rxPortBmiRegs, fmbm_rrquc);
122106 + FM_DMP_V32(buf, n, &p_bmi->rxPortBmiRegs, fmbm_rduc);
122107 + FM_DMP_V32(buf, n, &p_bmi->rxPortBmiRegs, fmbm_rfuc);
122108 + FM_DMP_V32(buf, n, &p_bmi->rxPortBmiRegs, fmbm_rpac);
122109 + FM_DMP_TITLE(buf, n, &(p_bmi->rxPortBmiRegs.fmbm_rdcfg),
122110 + "fmbm_rdcfg");
122111 + for (i = 0; i < 3; ++i) {
122112 + FM_DMP_MEM_32(buf, n,
122113 + &(p_bmi->rxPortBmiRegs.fmbm_rdcfg[i]));
122114 + }
122115 + FM_DMP_SUBTITLE(buf, n, "\n");
122116 + FM_DMP_V32(buf, n, &p_bmi->rxPortBmiRegs, fmbm_rgpr);
122117 + break;
122118 + case (2):
122119 + FM_DMP_SUBTITLE(buf, n, "\n");
122120 + FM_DMP_V32(buf, n, &p_bmi->txPortBmiRegs, fmbm_tcfg);
122121 + FM_DMP_V32(buf, n, &p_bmi->txPortBmiRegs, fmbm_tst);
122122 + FM_DMP_V32(buf, n, &p_bmi->txPortBmiRegs, fmbm_tda);
122123 + FM_DMP_V32(buf, n, &p_bmi->txPortBmiRegs, fmbm_tfp);
122124 + FM_DMP_V32(buf, n, &p_bmi->txPortBmiRegs, fmbm_tfed);
122125 + FM_DMP_V32(buf, n, &p_bmi->txPortBmiRegs, fmbm_ticp);
122126 + FM_DMP_V32(buf, n, &p_bmi->txPortBmiRegs, fmbm_tfdne);
122127 + FM_DMP_V32(buf, n, &p_bmi->txPortBmiRegs, fmbm_tfca);
122128 + FM_DMP_V32(buf, n, &p_bmi->txPortBmiRegs, fmbm_tcfqid);
122129 + FM_DMP_V32(buf, n, &p_bmi->txPortBmiRegs, fmbm_tfeqid);
122130 + FM_DMP_V32(buf, n, &p_bmi->txPortBmiRegs, fmbm_tfene);
122131 +#if (DPAA_VERSION >= 11)
122132 + FM_DMP_V32(buf, n, &p_bmi->txPortBmiRegs, fmbm_tfne);
122133 + FM_DMP_V32(buf, n, &p_bmi->txPortBmiRegs, fmbm_tcmne);
122134 +#endif /* (DPAA_VERSION >= 11) */
122135 + FM_DMP_V32(buf, n, &p_bmi->txPortBmiRegs, fmbm_trlmts);
122136 + FM_DMP_V32(buf, n, &p_bmi->txPortBmiRegs, fmbm_trlmt);
122137 + FM_DMP_V32(buf, n, &p_bmi->txPortBmiRegs, fmbm_tstc);
122138 + FM_DMP_V32(buf, n, &p_bmi->txPortBmiRegs, fmbm_tfrc);
122139 + FM_DMP_V32(buf, n, &p_bmi->txPortBmiRegs, fmbm_tfdc);
122140 + FM_DMP_V32(buf, n, &p_bmi->txPortBmiRegs, fmbm_tfledc);
122141 + FM_DMP_V32(buf, n, &p_bmi->txPortBmiRegs, fmbm_tfufdc);
122142 + FM_DMP_V32(buf, n, &p_bmi->txPortBmiRegs, fmbm_tpc);
122143 + FM_DMP_V32(buf, n, &p_bmi->txPortBmiRegs, fmbm_tpcp);
122144 + FM_DMP_V32(buf, n, &p_bmi->txPortBmiRegs, fmbm_tccn);
122145 + FM_DMP_V32(buf, n, &p_bmi->txPortBmiRegs, fmbm_ttuc);
122146 + FM_DMP_V32(buf, n, &p_bmi->txPortBmiRegs, fmbm_ttcquc);
122147 + FM_DMP_V32(buf, n, &p_bmi->txPortBmiRegs, fmbm_tduc);
122148 + FM_DMP_V32(buf, n, &p_bmi->txPortBmiRegs, fmbm_tfuc);
122149 + FM_DMP_TITLE(buf, n, &(p_bmi->txPortBmiRegs.fmbm_tdcfg),
122150 + "fmbm_tdcfg");
122151 + for (i = 0; i < 3 ; ++i) {
122152 + FM_DMP_MEM_32(buf, n,
122153 + &(p_bmi->txPortBmiRegs.fmbm_tdcfg[i]));
122154 + }
122155 + FM_DMP_SUBTITLE(buf, n, "\n");
122156 + FM_DMP_V32(buf, n, &p_bmi->txPortBmiRegs, fmbm_tgpr);
122157 + break;
122158 + }
122159 +
122160 + FM_DMP_SUBTITLE(buf, n, "\n");
122161 +
122162 + return n;
122163 +}
122164 +
122165 +int fm_port_dump_regs_qmi(void *h_dev, char *buf, int nn)
122166 +{
122167 + t_FmPort *p_FmPort;
122168 + int n = nn;
122169 +
122170 + p_FmPort = (t_FmPort *)h_dev;
122171 +
122172 + FM_DMP_TITLE(buf, n, p_FmPort->p_FmPortQmiRegs, "Qmi Port Regs");
122173 +
122174 + FM_DMP_V32(buf, n, p_FmPort->p_FmPortQmiRegs, fmqm_pnc);
122175 + FM_DMP_V32(buf, n, p_FmPort->p_FmPortQmiRegs, fmqm_pns);
122176 + FM_DMP_V32(buf, n, p_FmPort->p_FmPortQmiRegs, fmqm_pnts);
122177 + FM_DMP_V32(buf, n, p_FmPort->p_FmPortQmiRegs, fmqm_pnen);
122178 + FM_DMP_V32(buf, n, p_FmPort->p_FmPortQmiRegs, fmqm_pnetfc);
122179 + FM_DMP_V32(buf, n,
122180 + &p_FmPort->p_FmPortQmiRegs->nonRxQmiRegs, fmqm_pndn);
122181 + FM_DMP_V32(buf, n,
122182 + &p_FmPort->p_FmPortQmiRegs->nonRxQmiRegs, fmqm_pndc);
122183 + FM_DMP_V32(buf, n,
122184 + &p_FmPort->p_FmPortQmiRegs->nonRxQmiRegs, fmqm_pndtfc);
122185 + FM_DMP_V32(buf, n,
122186 + &p_FmPort->p_FmPortQmiRegs->nonRxQmiRegs, fmqm_pndfdc);
122187 + FM_DMP_V32(buf, n,
122188 + &p_FmPort->p_FmPortQmiRegs->nonRxQmiRegs, fmqm_pndcc);
122189 +
122190 + FM_DMP_SUBTITLE(buf, n, "\n");
122191 +
122192 + return n;
122193 +}
122194 +
122195 --- /dev/null
122196 +++ b/drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_sysfs_fm_port.h
122197 @@ -0,0 +1,56 @@
122198 +/*
122199 + * Copyright 2008-2012 Freescale Semiconductor Inc.
122200 + *
122201 + * Redistribution and use in source and binary forms, with or without
122202 + * modification, are permitted provided that the following conditions are met:
122203 + * * Redistributions of source code must retain the above copyright
122204 + * notice, this list of conditions and the following disclaimer.
122205 + * * Redistributions in binary form must reproduce the above copyright
122206 + * notice, this list of conditions and the following disclaimer in the
122207 + * documentation and/or other materials provided with the distribution.
122208 + * * Neither the name of Freescale Semiconductor nor the
122209 + * names of its contributors may be used to endorse or promote products
122210 + * derived from this software without specific prior written permission.
122211 + *
122212 + *
122213 + * ALTERNATIVELY, this software may be distributed under the terms of the
122214 + * GNU General Public License ("GPL") as published by the Free Software
122215 + * Foundation, either version 2 of that License or (at your option) any
122216 + * later version.
122217 + *
122218 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
122219 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
122220 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
122221 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
122222 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
122223 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
122224 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
122225 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
122226 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
122227 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
122228 + */
122229 +
122230 +/*
122231 + @File lnxwrp_sysfs_fm_port.h
122232 +
122233 + @Description FM port sysfs functions.
122234 +
122235 +*/
122236 +
122237 +#ifndef LNXWRP_SYSFS_FM_PORT_H_
122238 +#define LNXWRP_SYSFS_FM_PORT_H_
122239 +
122240 +#include "lnxwrp_sysfs.h"
122241 +
122242 +int fm_port_sysfs_create(struct device *dev);
122243 +void fm_port_sysfs_destroy(struct device *dev);
122244 +
122245 +int fm_port_dump_regs(void *h_dev, char *buf, int n);
122246 +int fm_port_dump_regs_bmi(void *h_dev, char *buf, int n);
122247 +int fm_port_dump_regs_qmi(void *h_dev, char *buf, int n);
122248 +
122249 +#if (DPAA_VERSION >= 11)
122250 +int fm_port_dump_ipv4_opt(void *h_dev, char *buf, int n);
122251 +#endif
122252 +
122253 +#endif /* LNXWRP_SYSFS_FM_PORT_H_ */
122254 --- /dev/null
122255 +++ b/drivers/net/ethernet/freescale/sdk_fman/src/xx/Makefile
122256 @@ -0,0 +1,18 @@
122257 +#
122258 +# Makefile for the Freescale Ethernet controllers
122259 +#
122260 +ccflags-y += -DVERSION=\"\"
122261 +#
122262 +#Include netcomm SW specific definitions
122263 +include $(srctree)/drivers/net/ethernet/freescale/sdk_fman/ncsw_config.mk
122264 +
122265 +obj-y += fsl-ncsw-xx.o
122266 +
122267 +ifneq ($(CONFIG_FMAN_ARM),y)
122268 +fsl-ncsw-xx-objs := xx_linux.o \
122269 + module_strings.o
122270 +else
122271 +fsl-ncsw-xx-objs := xx_arm_linux.o \
122272 + module_strings.o
122273 +endif
122274 +
122275 --- /dev/null
122276 +++ b/drivers/net/ethernet/freescale/sdk_fman/src/xx/module_strings.c
122277 @@ -0,0 +1,46 @@
122278 +/*
122279 + * Copyright 2012 Freescale Semiconductor Inc.
122280 + *
122281 + * Redistribution and use in source and binary forms, with or without
122282 + * modification, are permitted provided that the following conditions are met:
122283 + * * Redistributions of source code must retain the above copyright
122284 + * notice, this list of conditions and the following disclaimer.
122285 + * * Redistributions in binary form must reproduce the above copyright
122286 + * notice, this list of conditions and the following disclaimer in the
122287 + * documentation and/or other materials provided with the distribution.
122288 + * * Neither the name of Freescale Semiconductor nor the
122289 + * names of its contributors may be used to endorse or promote products
122290 + * derived from this software without specific prior written permission.
122291 + *
122292 + *
122293 + * ALTERNATIVELY, this software may be distributed under the terms of the
122294 + * GNU General Public License ("GPL") as published by the Free Software
122295 + * Foundation, either version 2 of that License or (at your option) any
122296 + * later version.
122297 + *
122298 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
122299 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
122300 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
122301 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
122302 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
122303 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
122304 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
122305 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
122306 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
122307 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
122308 + */
122309 +
122310 +/* Module names for debug messages */
122311 +const char *moduleStrings[] =
122312 +{
122313 + "", /* MODULE_UNKNOWN */
122314 + "FM", /* MODULE_FM */
122315 + "FM-MURAM", /* MODULE_FM_MURAM */
122316 + "FM-PCD", /* MODULE_FM_PCD */
122317 + "FM-RTC", /* MODULE_FM_RTC */
122318 + "FM-MAC", /* MODULE_FM_MAC */
122319 + "FM-Port", /* MODULE_FM_PORT */
122320 + "MM", /* MODULE_MM */
122321 + "FM-SP", /* MODULE_FM_SP */
122322 + "FM-MACSEC" /* MODULE_FM_MACSEC */
122323 +};
122324 --- /dev/null
122325 +++ b/drivers/net/ethernet/freescale/sdk_fman/src/xx/xx_arm_linux.c
122326 @@ -0,0 +1,905 @@
122327 +/*
122328 + * Copyright 2008-2012 Freescale Semiconductor Inc.
122329 + *
122330 + * Redistribution and use in source and binary forms, with or without
122331 + * modification, are permitted provided that the following conditions are met:
122332 + * * Redistributions of source code must retain the above copyright
122333 + * notice, this list of conditions and the following disclaimer.
122334 + * * Redistributions in binary form must reproduce the above copyright
122335 + * notice, this list of conditions and the following disclaimer in the
122336 + * documentation and/or other materials provided with the distribution.
122337 + * * Neither the name of Freescale Semiconductor nor the
122338 + * names of its contributors may be used to endorse or promote products
122339 + * derived from this software without specific prior written permission.
122340 + *
122341 + *
122342 + * ALTERNATIVELY, this software may be distributed under the terms of the
122343 + * GNU General Public License ("GPL") as published by the Free Software
122344 + * Foundation, either version 2 of that License or (at your option) any
122345 + * later version.
122346 + *
122347 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
122348 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
122349 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
122350 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
122351 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
122352 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
122353 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
122354 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
122355 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
122356 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
122357 + */
122358 +
122359 +/**************************************************************************//**
122360 + @File xx_arm_linux.c
122361 +
122362 + @Description XX routines implementation for Linux.
122363 +*//***************************************************************************/
122364 +#include <linux/version.h>
122365 +
122366 +#if defined(CONFIG_MODVERSIONS) && !defined(MODVERSIONS)
122367 +#define MODVERSIONS
122368 +#endif
122369 +#ifdef MODVERSIONS
122370 +#include <config/modversions.h>
122371 +#endif /* MODVERSIONS */
122372 +
122373 +#include <linux/module.h>
122374 +#include <linux/kernel.h>
122375 +#include <linux/sched.h>
122376 +#include <linux/string.h>
122377 +#include <linux/ptrace.h>
122378 +#include <linux/errno.h>
122379 +#include <linux/ioport.h>
122380 +#include <linux/slab.h>
122381 +#include <linux/interrupt.h>
122382 +#include <linux/fs.h>
122383 +#include <linux/vmalloc.h>
122384 +#include <linux/init.h>
122385 +#include <linux/timer.h>
122386 +#include <linux/spinlock.h>
122387 +#include <linux/delay.h>
122388 +#include <linux/proc_fs.h>
122389 +#include <linux/smp.h>
122390 +#include <linux/of.h>
122391 +#include <linux/irqdomain.h>
122392 +
122393 +#include <linux/workqueue.h>
122394 +
122395 +#ifdef BIGPHYSAREA_ENABLE
122396 +#include <linux/bigphysarea.h>
122397 +#endif /* BIGPHYSAREA_ENABLE */
122398 +
122399 +//#include <sysdev/fsl_soc.h>
122400 +#include <asm/pgtable.h>
122401 +#include <asm/irq.h>
122402 +#include <asm/bitops.h>
122403 +#include <asm/uaccess.h>
122404 +#include <asm/io.h>
122405 +#include <asm/atomic.h>
122406 +#include <asm/string.h>
122407 +#include <asm/byteorder.h>
122408 +#include <asm/page.h>
122409 +
122410 +#include "error_ext.h"
122411 +#include "std_ext.h"
122412 +#include "list_ext.h"
122413 +#include "mm_ext.h"
122414 +#include "sys_io_ext.h"
122415 +#include "xx.h"
122416 +
122417 +
122418 +#define __ERR_MODULE__ MODULE_UNKNOWN
122419 +
122420 +#ifdef BIGPHYSAREA_ENABLE
122421 +#define MAX_ALLOCATION_SIZE 128 * 1024 /* Maximum size allocated with kmalloc is 128K */
122422 +
122423 +
122424 +/* TODO: large allocations => use big phys area */
122425 +/******************************************************************************
122426 + * routine: get_nr_pages
122427 + *
122428 + * description:
122429 + * calculates the number of memory pages for a given size (in bytes)
122430 + *
122431 + * arguments:
122432 + * size - the number of bytes
122433 + *
122434 + * return code:
122435 + * The number of pages
122436 + *
122437 + *****************************************************************************/
122438 +static __inline__ uint32_t get_nr_pages (uint32_t size)
122439 +{
122440 + return (uint32_t)((size >> PAGE_SHIFT) + (size & PAGE_SHIFT ? 1 : 0));
122441 +}
122442 +
122443 +static bool in_big_phys_area (uint32_t addr)
122444 +{
122445 + uint32_t base, size;
122446 +
122447 + bigphysarea_get_details (&base, &size);
122448 + return ((addr >= base) && (addr < base + size));
122449 +}
122450 +#endif /* BIGPHYSAREA_ENABLE */
122451 +
122452 +void * xx_Malloc(uint32_t n)
122453 +{
122454 + void *a;
122455 + uint32_t flags;
122456 +
122457 + flags = XX_DisableAllIntr();
122458 +#ifdef BIGPHYSAREA_ENABLE
122459 + if (n >= MAX_ALLOCATION_SIZE)
122460 + a = (void*)bigphysarea_alloc_pages(get_nr_pages(n), 0, GFP_ATOMIC);
122461 + else
122462 +#endif /* BIGPHYSAREA_ENABLE */
122463 + a = (void *)kmalloc((uint32_t)n, GFP_ATOMIC);
122464 + if (!a)
122465 + XX_Print("No memory for XX_Malloc\n");
122466 + XX_RestoreAllIntr(flags);
122467 +
122468 + return a;
122469 +}
122470 +
122471 +void xx_Free(void *p)
122472 +{
122473 +#ifdef BIGPHYSAREA_ENABLE
122474 + if (in_big_phys_area ((uint32_t)p))
122475 + bigphysarea_free_pages(p);
122476 + else
122477 +#endif /* BIGPHYSAREA_ENABLE */
122478 + kfree(p);
122479 +}
122480 +
122481 +void XX_Exit(int status)
122482 +{
122483 + WARN(1, "\n\nFMD: fatal error, driver can't go on!!!\n\n");
122484 +}
122485 +
122486 +#define BUF_SIZE 512
122487 +void XX_Print(char *str, ...)
122488 +{
122489 + va_list args;
122490 +#ifdef CONFIG_SMP
122491 + char buf[BUF_SIZE];
122492 +#endif /* CONFIG_SMP */
122493 +
122494 + va_start(args, str);
122495 +#ifdef CONFIG_SMP
122496 + if (vsnprintf (buf, BUF_SIZE, str, args) >= BUF_SIZE)
122497 + printk(KERN_WARNING "Illegal string to print!\n more than %d characters.\n\tString was not printed completelly.\n", BUF_SIZE);
122498 + printk(KERN_CRIT "cpu %d: %s", raw_smp_processor_id(), buf);
122499 +#else
122500 + vprintk(str, args);
122501 +#endif /* CONFIG_SMP */
122502 + va_end(args);
122503 +}
122504 +
122505 +void XX_Fprint(void *file, char *str, ...)
122506 +{
122507 + va_list args;
122508 +#ifdef CONFIG_SMP
122509 + char buf[BUF_SIZE];
122510 +#endif /* CONFIG_SMP */
122511 +
122512 + va_start(args, str);
122513 +#ifdef CONFIG_SMP
122514 + if (vsnprintf (buf, BUF_SIZE, str, args) >= BUF_SIZE)
122515 + printk(KERN_WARNING "Illegal string to print!\n more than %d characters.\n\tString was not printed completelly.\n", BUF_SIZE);
122516 + printk (KERN_CRIT "cpu %d: %s", smp_processor_id(), buf);
122517 +
122518 +#else
122519 + vprintk(str, args);
122520 +#endif /* CONFIG_SMP */
122521 + va_end(args);
122522 +}
122523 +
122524 +#ifdef DEBUG_XX_MALLOC
122525 +typedef void (*t_ffn)(void *);
122526 +typedef struct {
122527 + t_ffn f_free;
122528 + void *mem;
122529 + char *fname;
122530 + int fline;
122531 + uint32_t size;
122532 + t_List node;
122533 +} t_MemDebug;
122534 +#define MEMDBG_OBJECT(p_List) LIST_OBJECT(p_List, t_MemDebug, node)
122535 +
122536 +LIST(memDbgLst);
122537 +
122538 +
122539 +void * XX_MallocDebug(uint32_t size, char *fname, int line)
122540 +{
122541 + void *mem;
122542 + t_MemDebug *p_MemDbg;
122543 +
122544 + p_MemDbg = (t_MemDebug *)xx_Malloc(sizeof(t_MemDebug));
122545 + if (p_MemDbg == NULL)
122546 + return NULL;
122547 +
122548 + mem = xx_Malloc(size);
122549 + if (mem == NULL)
122550 + {
122551 + XX_Free(p_MemDbg);
122552 + return NULL;
122553 + }
122554 +
122555 + INIT_LIST(&p_MemDbg->node);
122556 + p_MemDbg->f_free = xx_Free;
122557 + p_MemDbg->mem = mem;
122558 + p_MemDbg->fname = fname;
122559 + p_MemDbg->fline = line;
122560 + p_MemDbg->size = size+sizeof(t_MemDebug);
122561 + LIST_AddToTail(&p_MemDbg->node, &memDbgLst);
122562 +
122563 + return mem;
122564 +}
122565 +
122566 +void * XX_MallocSmartDebug(uint32_t size,
122567 + int memPartitionId,
122568 + uint32_t align,
122569 + char *fname,
122570 + int line)
122571 +{
122572 + void *mem;
122573 + t_MemDebug *p_MemDbg;
122574 +
122575 + p_MemDbg = (t_MemDebug *)XX_Malloc(sizeof(t_MemDebug));
122576 + if (p_MemDbg == NULL)
122577 + return NULL;
122578 +
122579 + mem = xx_MallocSmart((uint32_t)size, memPartitionId, align);
122580 + if (mem == NULL)
122581 + {
122582 + XX_Free(p_MemDbg);
122583 + return NULL;
122584 + }
122585 +
122586 + INIT_LIST(&p_MemDbg->node);
122587 + p_MemDbg->f_free = xx_FreeSmart;
122588 + p_MemDbg->mem = mem;
122589 + p_MemDbg->fname = fname;
122590 + p_MemDbg->fline = line;
122591 + p_MemDbg->size = size+sizeof(t_MemDebug);
122592 + LIST_AddToTail(&p_MemDbg->node, &memDbgLst);
122593 +
122594 + return mem;
122595 +}
122596 +
122597 +static void debug_free(void *mem)
122598 +{
122599 + t_List *p_MemDbgLh = NULL;
122600 + t_MemDebug *p_MemDbg;
122601 + bool found = FALSE;
122602 +
122603 + if (LIST_IsEmpty(&memDbgLst))
122604 + {
122605 + REPORT_ERROR(MAJOR, E_ALREADY_FREE, ("Unbalanced free (0x%08x)", mem));
122606 + return;
122607 + }
122608 +
122609 + LIST_FOR_EACH(p_MemDbgLh, &memDbgLst)
122610 + {
122611 + p_MemDbg = MEMDBG_OBJECT(p_MemDbgLh);
122612 + if (p_MemDbg->mem == mem)
122613 + {
122614 + found = TRUE;
122615 + break;
122616 + }
122617 + }
122618 +
122619 + if (!found)
122620 + {
122621 + REPORT_ERROR(MAJOR, E_NOT_FOUND,
122622 + ("Attempt to free unallocated address (0x%08x)",mem));
122623 + dump_stack();
122624 + return;
122625 + }
122626 +
122627 + LIST_Del(p_MemDbgLh);
122628 + p_MemDbg->f_free(mem);
122629 + p_MemDbg->f_free(p_MemDbg);
122630 +}
122631 +
122632 +void XX_FreeSmart(void *p)
122633 +{
122634 + debug_free(p);
122635 +}
122636 +
122637 +
122638 +void XX_Free(void *p)
122639 +{
122640 + debug_free(p);
122641 +}
122642 +
122643 +#else /* not DEBUG_XX_MALLOC */
122644 +void * XX_Malloc(uint32_t size)
122645 +{
122646 + return xx_Malloc(size);
122647 +}
122648 +
122649 +void * XX_MallocSmart(uint32_t size, int memPartitionId, uint32_t alignment)
122650 +{
122651 + return xx_MallocSmart(size,memPartitionId, alignment);
122652 +}
122653 +
122654 +void XX_FreeSmart(void *p)
122655 +{
122656 + xx_FreeSmart(p);
122657 +}
122658 +
122659 +
122660 +void XX_Free(void *p)
122661 +{
122662 + xx_Free(p);
122663 +}
122664 +#endif /* not DEBUG_XX_MALLOC */
122665 +
122666 +
122667 +#if (defined(REPORT_EVENTS) && (REPORT_EVENTS > 0))
122668 +void XX_EventById(uint32_t event, t_Handle appId, uint16_t flags, char *msg)
122669 +{
122670 + e_Event eventCode = (e_Event)event;
122671 +
122672 + UNUSED(eventCode);
122673 + UNUSED(appId);
122674 + UNUSED(flags);
122675 + UNUSED(msg);
122676 +}
122677 +#endif /* (defined(REPORT_EVENTS) && ... */
122678 +
122679 +
122680 +uint32_t XX_DisableAllIntr(void)
122681 +{
122682 + unsigned long flags;
122683 +
122684 +#ifdef local_irq_save_nort
122685 + local_irq_save_nort(flags);
122686 +#else
122687 + local_irq_save(flags);
122688 +#endif
122689 +
122690 + return (uint32_t)flags;
122691 +}
122692 +
122693 +void XX_RestoreAllIntr(uint32_t flags)
122694 +{
122695 +#ifdef local_irq_restore_nort
122696 + local_irq_restore_nort((unsigned long)flags);
122697 +#else
122698 + local_irq_restore((unsigned long)flags);
122699 +#endif
122700 +}
122701 +
122702 +t_Error XX_Call( uint32_t qid, t_Error (* f)(t_Handle), t_Handle id, t_Handle appId, uint16_t flags )
122703 +{
122704 + UNUSED(qid);
122705 + UNUSED(appId);
122706 + UNUSED(flags);
122707 +
122708 + return f(id);
122709 +}
122710 +
122711 +int XX_IsICacheEnable(void)
122712 +{
122713 + return TRUE;
122714 +}
122715 +
122716 +int XX_IsDCacheEnable(void)
122717 +{
122718 + return TRUE;
122719 +}
122720 +
122721 +
122722 +typedef struct {
122723 + t_Isr *f_Isr;
122724 + t_Handle handle;
122725 +} t_InterruptHandler;
122726 +
122727 +
122728 +t_Handle interruptHandlers[0x00010000];
122729 +
122730 +static irqreturn_t LinuxInterruptHandler (int irq, void *dev_id)
122731 +{
122732 + t_InterruptHandler *p_IntrHndl = (t_InterruptHandler *)dev_id;
122733 + p_IntrHndl->f_Isr(p_IntrHndl->handle);
122734 + return IRQ_HANDLED;
122735 +}
122736 +
122737 +t_Error XX_SetIntr(int irq, t_Isr *f_Isr, t_Handle handle)
122738 +{
122739 + const char *device;
122740 + t_InterruptHandler *p_IntrHndl;
122741 +
122742 + device = GetDeviceName(irq);
122743 + if (device == NULL)
122744 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Interrupt source - %d", irq));
122745 +
122746 + p_IntrHndl = (t_InterruptHandler *)XX_Malloc(sizeof(t_InterruptHandler));
122747 + if (p_IntrHndl == NULL)
122748 + RETURN_ERROR(MAJOR, E_NO_MEMORY, NO_MSG);
122749 + p_IntrHndl->f_Isr = f_Isr;
122750 + p_IntrHndl->handle = handle;
122751 + interruptHandlers[irq] = p_IntrHndl;
122752 +
122753 + if (request_irq(GetDeviceIrqNum(irq), LinuxInterruptHandler, 0, device, p_IntrHndl) < 0)
122754 + RETURN_ERROR(MAJOR, E_BUSY, ("Can't get IRQ %s\n", device));
122755 + disable_irq(GetDeviceIrqNum(irq));
122756 +
122757 + return E_OK;
122758 +}
122759 +
122760 +t_Error XX_FreeIntr(int irq)
122761 +{
122762 + t_InterruptHandler *p_IntrHndl = interruptHandlers[irq];
122763 + free_irq(GetDeviceIrqNum(irq), p_IntrHndl);
122764 + XX_Free(p_IntrHndl);
122765 + interruptHandlers[irq] = 0;
122766 + return E_OK;
122767 +}
122768 +
122769 +t_Error XX_EnableIntr(int irq)
122770 +{
122771 + enable_irq(GetDeviceIrqNum(irq));
122772 + return E_OK;
122773 +}
122774 +
122775 +t_Error XX_DisableIntr(int irq)
122776 +{
122777 + disable_irq(GetDeviceIrqNum(irq));
122778 + return E_OK;
122779 +}
122780 +
122781 +
122782 +/*****************************************************************************/
122783 +/* Tasklet Service Routines */
122784 +/*****************************************************************************/
122785 +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
122786 +typedef struct
122787 +{
122788 + t_Handle h_Data;
122789 + void (*f_Callback) (void *);
122790 + struct delayed_work dwork;
122791 +} t_Tasklet;
122792 +
122793 +static void GenericTaskletCallback(struct work_struct *p_Work)
122794 +{
122795 + t_Tasklet *p_Task = container_of(p_Work, t_Tasklet, dwork.work);
122796 +
122797 + p_Task->f_Callback(p_Task->h_Data);
122798 +}
122799 +#endif /* LINUX_VERSION_CODE */
122800 +
122801 +
122802 +t_TaskletHandle XX_InitTasklet (void (*routine)(void *), void *data)
122803 +{
122804 +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
122805 + struct work_struct *p_Task;
122806 + p_Task = (struct work_struct *)XX_Malloc(sizeof(struct work_struct));
122807 + INIT_WORK(p_Task, routine, data);
122808 +#else
122809 + t_Tasklet *p_Task = (t_Tasklet *)XX_Malloc(sizeof(t_Tasklet));
122810 + p_Task->h_Data = data;
122811 + p_Task->f_Callback = routine;
122812 + INIT_DELAYED_WORK(&p_Task->dwork, GenericTaskletCallback);
122813 +#endif /* LINUX_VERSION_CODE */
122814 +
122815 + return (t_TaskletHandle)p_Task;
122816 +}
122817 +
122818 +
122819 +void XX_FreeTasklet (t_TaskletHandle h_Tasklet)
122820 +{
122821 + if (h_Tasklet)
122822 + XX_Free(h_Tasklet);
122823 +}
122824 +
122825 +int XX_ScheduleTask(t_TaskletHandle h_Tasklet, int immediate)
122826 +{
122827 + int ans;
122828 +
122829 +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
122830 + if (immediate)
122831 + ans = schedule_work(h_Tasklet);
122832 + else
122833 + ans = schedule_delayed_work(h_Tasklet, 1);
122834 +#else
122835 + if (immediate)
122836 + ans = schedule_delayed_work(&((t_Tasklet *)h_Tasklet)->dwork, 0);
122837 + else
122838 + ans = schedule_delayed_work(&((t_Tasklet *)h_Tasklet)->dwork, HZ);
122839 +#endif /* LINUX_VERSION_CODE */
122840 +
122841 + return ans;
122842 +}
122843 +
122844 +void XX_FlushScheduledTasks(void)
122845 +{
122846 +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
122847 + flush_scheduled_tasks();
122848 +#else
122849 + flush_scheduled_work();
122850 +#endif /* LINUX_VERSION_CODE */
122851 +}
122852 +
122853 +int XX_TaskletIsQueued(t_TaskletHandle h_Tasklet)
122854 +{
122855 +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
122856 + return (int)(((struct work_struct *)h_Tasklet)->pending);
122857 +#else
122858 + return (int)delayed_work_pending(&((t_Tasklet *)h_Tasklet)->dwork);
122859 +#endif /* LINUX_VERSION_CODE */
122860 +}
122861 +
122862 +void XX_SetTaskletData(t_TaskletHandle h_Tasklet, t_Handle data)
122863 +{
122864 +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
122865 + ((struct tq_struct *)h_Tasklet)->data = data;
122866 +#elif LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
122867 + ((struct work_struct *)h_Tasklet)->data = data;
122868 +#else
122869 + ((t_Tasklet *)h_Tasklet)->h_Data = data;
122870 +#endif /* LINUX_VERSION_CODE */
122871 +}
122872 +
122873 +t_Handle XX_GetTaskletData(t_TaskletHandle h_Tasklet)
122874 +{
122875 +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
122876 + return (t_Handle)(((struct work_struct *)h_Tasklet)->data);
122877 +#else
122878 + return ((t_Tasklet *)h_Tasklet)->h_Data;
122879 +#endif /* LINUX_VERSION_CODE */
122880 +}
122881 +
122882 +
122883 +/*****************************************************************************/
122884 +/* Spinlock Service Routines */
122885 +/*****************************************************************************/
122886 +
122887 +t_Handle XX_InitSpinlock(void)
122888 +{
122889 + spinlock_t *p_Spinlock = (spinlock_t *)XX_Malloc(sizeof(spinlock_t));
122890 + if (!p_Spinlock)
122891 + return NULL;
122892 +
122893 + spin_lock_init(p_Spinlock);
122894 +
122895 + return (t_Handle)p_Spinlock;
122896 +}
122897 +
122898 +void XX_FreeSpinlock(t_Handle h_Spinlock)
122899 +{
122900 + if (h_Spinlock)
122901 + XX_Free(h_Spinlock);
122902 +}
122903 +
122904 +void XX_LockSpinlock(t_Handle h_Spinlock)
122905 +{
122906 + spin_lock((spinlock_t *)h_Spinlock);
122907 +}
122908 +
122909 +void XX_UnlockSpinlock(t_Handle h_Spinlock)
122910 +{
122911 + spin_unlock((spinlock_t *)h_Spinlock);
122912 +}
122913 +
122914 +uint32_t XX_LockIntrSpinlock(t_Handle h_Spinlock)
122915 +{
122916 + unsigned long intrFlags;
122917 + spin_lock_irqsave((spinlock_t *)h_Spinlock, intrFlags);
122918 + return intrFlags;
122919 +}
122920 +
122921 +void XX_UnlockIntrSpinlock(t_Handle h_Spinlock, uint32_t intrFlags)
122922 +{
122923 + spin_unlock_irqrestore((spinlock_t *)h_Spinlock, (unsigned long)intrFlags);
122924 +}
122925 +
122926 +
122927 +/*****************************************************************************/
122928 +/* Timers Service Routines */
122929 +/*****************************************************************************/
122930 +/* The time now is in mili sec. resolution */
122931 +uint32_t XX_CurrentTime(void)
122932 +{
122933 + return (jiffies*1000)/HZ;
122934 +}
122935 +
122936 +
122937 +t_Handle XX_CreateTimer(void)
122938 +{
122939 + struct timer_list *p_Timer = (struct timer_list *)XX_Malloc(sizeof(struct timer_list));
122940 + if (p_Timer)
122941 + {
122942 + memset(p_Timer, 0, sizeof(struct timer_list));
122943 + init_timer(p_Timer);
122944 + }
122945 + return (t_Handle)p_Timer;
122946 +}
122947 +
122948 +void XX_FreeTimer(t_Handle h_Timer)
122949 +{
122950 + if (h_Timer)
122951 + XX_Free(h_Timer);
122952 +}
122953 +
122954 +void XX_StartTimer(t_Handle h_Timer,
122955 + uint32_t msecs,
122956 + bool periodic,
122957 + void (*f_TimerExpired)(t_Handle),
122958 + t_Handle h_Arg)
122959 +{
122960 + int tmp_jiffies = (msecs*HZ)/1000;
122961 + struct timer_list *p_Timer = (struct timer_list *)h_Timer;
122962 +
122963 + SANITY_CHECK_RETURN((periodic == FALSE), E_NOT_SUPPORTED);
122964 +
122965 + p_Timer->function = (void (*)(unsigned long))f_TimerExpired;
122966 + p_Timer->data = (unsigned long)h_Arg;
122967 + if ((msecs*HZ)%1000)
122968 + tmp_jiffies++;
122969 + p_Timer->expires = (jiffies + tmp_jiffies);
122970 +
122971 + add_timer((struct timer_list *)h_Timer);
122972 +}
122973 +
122974 +void XX_SetTimerData(t_Handle h_Timer, t_Handle data)
122975 +{
122976 + struct timer_list *p_Timer = (struct timer_list *)h_Timer;
122977 +
122978 + p_Timer->data = (unsigned long)data;
122979 +}
122980 +
122981 +t_Handle XX_GetTimerData(t_Handle h_Timer)
122982 +{
122983 + struct timer_list *p_Timer = (struct timer_list *)h_Timer;
122984 +
122985 + return (t_Handle)p_Timer->data;
122986 +}
122987 +
122988 +uint32_t XX_GetExpirationTime(t_Handle h_Timer)
122989 +{
122990 + struct timer_list *p_Timer = (struct timer_list *)h_Timer;
122991 +
122992 + return (uint32_t)p_Timer->expires;
122993 +}
122994 +
122995 +void XX_StopTimer(t_Handle h_Timer)
122996 +{
122997 + del_timer((struct timer_list *)h_Timer);
122998 +}
122999 +
123000 +void XX_ModTimer(t_Handle h_Timer, uint32_t msecs)
123001 +{
123002 + int tmp_jiffies = (msecs*HZ)/1000;
123003 +
123004 + if ((msecs*HZ)%1000)
123005 + tmp_jiffies++;
123006 + mod_timer((struct timer_list *)h_Timer, jiffies + tmp_jiffies);
123007 +}
123008 +
123009 +int XX_TimerIsActive(t_Handle h_Timer)
123010 +{
123011 + return timer_pending((struct timer_list *)h_Timer);
123012 +}
123013 +
123014 +uint32_t XX_Sleep(uint32_t msecs)
123015 +{
123016 + int tmp_jiffies = (msecs*HZ)/1000;
123017 +
123018 + if ((msecs*HZ)%1000)
123019 + tmp_jiffies++;
123020 + return schedule_timeout(tmp_jiffies);
123021 +}
123022 +
123023 +/*BEWARE!!!!! UDelay routine is BUSY WAITTING!!!!!*/
123024 +void XX_UDelay(uint32_t usecs)
123025 +{
123026 + udelay(usecs);
123027 +}
123028 +
123029 +/* TODO: verify that these are correct */
123030 +#define MSG_BODY_SIZE 512
123031 +typedef t_Error (t_MsgHandler) (t_Handle h_Mod, uint32_t msgId, uint8_t msgBody[MSG_BODY_SIZE]);
123032 +typedef void (t_MsgCompletionCB) (t_Handle h_Arg, uint8_t msgBody[MSG_BODY_SIZE]);
123033 +t_Error XX_SendMessage(char *p_DestAddr,
123034 + uint32_t msgId,
123035 + uint8_t msgBody[MSG_BODY_SIZE],
123036 + t_MsgCompletionCB *f_CompletionCB,
123037 + t_Handle h_CBArg);
123038 +
123039 +typedef struct {
123040 + char *p_Addr;
123041 + t_MsgHandler *f_MsgHandlerCB;
123042 + t_Handle h_Mod;
123043 + t_List node;
123044 +} t_MsgHndlr;
123045 +#define MSG_HNDLR_OBJECT(ptr) LIST_OBJECT(ptr, t_MsgHndlr, node)
123046 +
123047 +LIST(msgHndlrList);
123048 +
123049 +static void EnqueueMsgHndlr(t_MsgHndlr *p_MsgHndlr)
123050 +{
123051 + uint32_t intFlags;
123052 +
123053 + intFlags = XX_DisableAllIntr();
123054 + LIST_AddToTail(&p_MsgHndlr->node, &msgHndlrList);
123055 + XX_RestoreAllIntr(intFlags);
123056 +}
123057 +/* TODO: add this for multi-platform support
123058 +static t_MsgHndlr * DequeueMsgHndlr(void)
123059 +{
123060 + t_MsgHndlr *p_MsgHndlr = NULL;
123061 + uint32_t intFlags;
123062 +
123063 + intFlags = XX_DisableAllIntr();
123064 + if (!LIST_IsEmpty(&msgHndlrList))
123065 + {
123066 + p_MsgHndlr = MSG_HNDLR_OBJECT(msgHndlrList.p_Next);
123067 + LIST_DelAndInit(&p_MsgHndlr->node);
123068 + }
123069 + XX_RestoreAllIntr(intFlags);
123070 +
123071 + return p_MsgHndlr;
123072 +}
123073 +*/
123074 +static t_MsgHndlr * FindMsgHndlr(char *p_Addr)
123075 +{
123076 + t_MsgHndlr *p_MsgHndlr;
123077 + t_List *p_Pos;
123078 +
123079 + LIST_FOR_EACH(p_Pos, &msgHndlrList)
123080 + {
123081 + p_MsgHndlr = MSG_HNDLR_OBJECT(p_Pos);
123082 + if (strstr(p_MsgHndlr->p_Addr, p_Addr))
123083 + return p_MsgHndlr;
123084 + }
123085 +
123086 + return NULL;
123087 +}
123088 +
123089 +t_Error XX_RegisterMessageHandler (char *p_Addr, t_MsgHandler *f_MsgHandlerCB, t_Handle h_Mod)
123090 +{
123091 + t_MsgHndlr *p_MsgHndlr;
123092 + uint32_t len;
123093 +
123094 + p_MsgHndlr = (t_MsgHndlr*)XX_Malloc(sizeof(t_MsgHndlr));
123095 + if (!p_MsgHndlr)
123096 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("message handler object!!!"));
123097 + memset(p_MsgHndlr, 0, sizeof(t_MsgHndlr));
123098 +
123099 + len = strlen(p_Addr);
123100 + p_MsgHndlr->p_Addr = (char*)XX_Malloc(len+1);
123101 + strncpy(p_MsgHndlr->p_Addr,p_Addr, (uint32_t)(len+1));
123102 +
123103 + p_MsgHndlr->f_MsgHandlerCB = f_MsgHandlerCB;
123104 + p_MsgHndlr->h_Mod = h_Mod;
123105 + INIT_LIST(&p_MsgHndlr->node);
123106 + EnqueueMsgHndlr(p_MsgHndlr);
123107 +
123108 + return E_OK;
123109 +}
123110 +
123111 +t_Error XX_UnregisterMessageHandler (char *p_Addr)
123112 +{
123113 + t_MsgHndlr *p_MsgHndlr = FindMsgHndlr(p_Addr);
123114 + if (!p_MsgHndlr)
123115 + RETURN_ERROR(MINOR, E_NO_DEVICE, ("message handler not found in list!!!"));
123116 +
123117 + LIST_Del(&p_MsgHndlr->node);
123118 + XX_Free(p_MsgHndlr->p_Addr);
123119 + XX_Free(p_MsgHndlr);
123120 +
123121 + return E_OK;
123122 +}
123123 +
123124 +t_Error XX_SendMessage(char *p_DestAddr,
123125 + uint32_t msgId,
123126 + uint8_t msgBody[MSG_BODY_SIZE],
123127 + t_MsgCompletionCB *f_CompletionCB,
123128 + t_Handle h_CBArg)
123129 +{
123130 + t_Error ans;
123131 + t_MsgHndlr *p_MsgHndlr = FindMsgHndlr(p_DestAddr);
123132 + if (!p_MsgHndlr)
123133 + RETURN_ERROR(MINOR, E_NO_DEVICE, ("message handler not found in list!!!"));
123134 +
123135 + ans = p_MsgHndlr->f_MsgHandlerCB(p_MsgHndlr->h_Mod, msgId, msgBody);
123136 +
123137 + if (f_CompletionCB)
123138 + f_CompletionCB(h_CBArg, msgBody);
123139 +
123140 + return ans;
123141 +}
123142 +
123143 +t_Error XX_IpcRegisterMsgHandler(char addr[XX_IPC_MAX_ADDR_NAME_LENGTH],
123144 + t_IpcMsgHandler *f_MsgHandler,
123145 + t_Handle h_Module,
123146 + uint32_t replyLength)
123147 +{
123148 + UNUSED(addr);UNUSED(f_MsgHandler);UNUSED(h_Module);UNUSED(replyLength);
123149 + return E_OK;
123150 +}
123151 +
123152 +t_Error XX_IpcUnregisterMsgHandler(char addr[XX_IPC_MAX_ADDR_NAME_LENGTH])
123153 +{
123154 + UNUSED(addr);
123155 + return E_OK;
123156 +}
123157 +
123158 +
123159 +t_Error XX_IpcSendMessage(t_Handle h_Session,
123160 + uint8_t *p_Msg,
123161 + uint32_t msgLength,
123162 + uint8_t *p_Reply,
123163 + uint32_t *p_ReplyLength,
123164 + t_IpcMsgCompletion *f_Completion,
123165 + t_Handle h_Arg)
123166 +{
123167 + UNUSED(h_Session); UNUSED(p_Msg); UNUSED(msgLength); UNUSED(p_Reply);
123168 + UNUSED(p_ReplyLength); UNUSED(f_Completion); UNUSED(h_Arg);
123169 + return E_OK;
123170 +}
123171 +
123172 +t_Handle XX_IpcInitSession(char destAddr[XX_IPC_MAX_ADDR_NAME_LENGTH],
123173 + char srcAddr[XX_IPC_MAX_ADDR_NAME_LENGTH])
123174 +{
123175 + UNUSED(destAddr); UNUSED(srcAddr);
123176 + return E_OK;
123177 +}
123178 +
123179 +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22)
123180 +int GetDeviceIrqNum(int irq)
123181 +{
123182 + struct device_node *iPar;
123183 + struct irq_domain *irqHost;
123184 + uint32_t hwIrq;
123185 +
123186 + /* Get the interrupt controller */
123187 + iPar = of_find_node_by_name(NULL, "mpic");
123188 + hwIrq = 0;
123189 +
123190 + ASSERT_COND(iPar != NULL);
123191 + /* Get the irq host */
123192 + irqHost = irq_find_host(iPar);
123193 + of_node_put(iPar);
123194 +
123195 + /* Create irq mapping */
123196 + return irq_create_mapping(irqHost, hwIrq);
123197 +}
123198 +#else
123199 +#error "kernel not supported!!!"
123200 +#endif /* LINUX_VERSION_CODE */
123201 +
123202 +void * XX_PhysToVirt(physAddress_t addr)
123203 +{
123204 + return UINT_TO_PTR(SYS_PhysToVirt((uint64_t)addr));
123205 +}
123206 +
123207 +physAddress_t XX_VirtToPhys(void * addr)
123208 +{
123209 + return (physAddress_t)SYS_VirtToPhys(PTR_TO_UINT(addr));
123210 +}
123211 +
123212 +void * xx_MallocSmart(uint32_t size, int memPartitionId, uint32_t alignment)
123213 +{
123214 + uintptr_t *returnCode, tmp;
123215 +
123216 + if (alignment < sizeof(uintptr_t))
123217 + alignment = sizeof(uintptr_t);
123218 + size += alignment + sizeof(returnCode);
123219 + tmp = (uintptr_t)xx_Malloc(size);
123220 + if (tmp == 0)
123221 + return NULL;
123222 + returnCode = (uintptr_t*)((tmp + alignment + sizeof(returnCode)) & ~((uintptr_t)alignment - 1));
123223 + *(returnCode - 1) = tmp;
123224 +
123225 + return (void*)returnCode;
123226 +}
123227 +
123228 +void xx_FreeSmart(void *p)
123229 +{
123230 + xx_Free((void*)(*((uintptr_t *)(p) - 1)));
123231 +}
123232 --- /dev/null
123233 +++ b/drivers/net/ethernet/freescale/sdk_fman/src/xx/xx_linux.c
123234 @@ -0,0 +1,918 @@
123235 +/*
123236 + * Copyright 2008-2012 Freescale Semiconductor Inc.
123237 + *
123238 + * Redistribution and use in source and binary forms, with or without
123239 + * modification, are permitted provided that the following conditions are met:
123240 + * * Redistributions of source code must retain the above copyright
123241 + * notice, this list of conditions and the following disclaimer.
123242 + * * Redistributions in binary form must reproduce the above copyright
123243 + * notice, this list of conditions and the following disclaimer in the
123244 + * documentation and/or other materials provided with the distribution.
123245 + * * Neither the name of Freescale Semiconductor nor the
123246 + * names of its contributors may be used to endorse or promote products
123247 + * derived from this software without specific prior written permission.
123248 + *
123249 + *
123250 + * ALTERNATIVELY, this software may be distributed under the terms of the
123251 + * GNU General Public License ("GPL") as published by the Free Software
123252 + * Foundation, either version 2 of that License or (at your option) any
123253 + * later version.
123254 + *
123255 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
123256 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
123257 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
123258 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
123259 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
123260 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
123261 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
123262 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
123263 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
123264 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
123265 + */
123266 +
123267 +/**************************************************************************//**
123268 + @File xx_linux.c
123269 +
123270 + @Description XX routines implementation for Linux.
123271 +*//***************************************************************************/
123272 +#include <linux/version.h>
123273 +
123274 +#if defined(CONFIG_MODVERSIONS) && !defined(MODVERSIONS)
123275 +#define MODVERSIONS
123276 +#endif
123277 +#ifdef MODVERSIONS
123278 +#include <config/modversions.h>
123279 +#endif /* MODVERSIONS */
123280 +
123281 +#include <linux/module.h>
123282 +#include <linux/kernel.h>
123283 +#include <linux/sched.h>
123284 +#include <linux/string.h>
123285 +#include <linux/ptrace.h>
123286 +#include <linux/errno.h>
123287 +#include <linux/ioport.h>
123288 +#include <linux/slab.h>
123289 +#include <linux/interrupt.h>
123290 +#include <linux/fs.h>
123291 +#include <linux/vmalloc.h>
123292 +#include <linux/init.h>
123293 +#include <linux/timer.h>
123294 +#include <linux/spinlock.h>
123295 +#include <linux/delay.h>
123296 +#include <linux/proc_fs.h>
123297 +#include <linux/smp.h>
123298 +#include <linux/of.h>
123299 +#ifdef CONFIG_FMAN_ARM
123300 +#include <linux/irqdomain.h>
123301 +#endif
123302 +
123303 +#include <linux/workqueue.h>
123304 +
123305 +#ifdef BIGPHYSAREA_ENABLE
123306 +#include <linux/bigphysarea.h>
123307 +#endif /* BIGPHYSAREA_ENABLE */
123308 +
123309 +#ifndef CONFIG_FMAN_ARM
123310 +#include <sysdev/fsl_soc.h>
123311 +#endif
123312 +#include <asm/pgtable.h>
123313 +#include <asm/irq.h>
123314 +#include <asm/bitops.h>
123315 +#include <asm/uaccess.h>
123316 +#include <asm/io.h>
123317 +#include <asm/atomic.h>
123318 +#include <asm/string.h>
123319 +#include <asm/byteorder.h>
123320 +#include <asm/page.h>
123321 +
123322 +#include "error_ext.h"
123323 +#include "std_ext.h"
123324 +#include "list_ext.h"
123325 +#include "mm_ext.h"
123326 +#include "sys_io_ext.h"
123327 +#include "xx.h"
123328 +
123329 +
123330 +#define __ERR_MODULE__ MODULE_UNKNOWN
123331 +
123332 +#ifdef BIGPHYSAREA_ENABLE
123333 +#define MAX_ALLOCATION_SIZE 128 * 1024 /* Maximum size allocated with kmalloc is 128K */
123334 +
123335 +
123336 +/* TODO: large allocations => use big phys area */
123337 +/******************************************************************************
123338 + * routine: get_nr_pages
123339 + *
123340 + * description:
123341 + * calculates the number of memory pages for a given size (in bytes)
123342 + *
123343 + * arguments:
123344 + * size - the number of bytes
123345 + *
123346 + * return code:
123347 + * The number of pages
123348 + *
123349 + *****************************************************************************/
123350 +static __inline__ uint32_t get_nr_pages (uint32_t size)
123351 +{
123352 + return (uint32_t)((size >> PAGE_SHIFT) + (size & PAGE_SHIFT ? 1 : 0));
123353 +}
123354 +
123355 +static bool in_big_phys_area (uint32_t addr)
123356 +{
123357 + uint32_t base, size;
123358 +
123359 + bigphysarea_get_details (&base, &size);
123360 + return ((addr >= base) && (addr < base + size));
123361 +}
123362 +#endif /* BIGPHYSAREA_ENABLE */
123363 +
123364 +void * xx_Malloc(uint32_t n)
123365 +{
123366 + void *a;
123367 + uint32_t flags;
123368 +
123369 + flags = XX_DisableAllIntr();
123370 +#ifdef BIGPHYSAREA_ENABLE
123371 + if (n >= MAX_ALLOCATION_SIZE)
123372 + a = (void*)bigphysarea_alloc_pages(get_nr_pages(n), 0, GFP_ATOMIC);
123373 + else
123374 +#endif /* BIGPHYSAREA_ENABLE */
123375 + a = (void *)kmalloc((uint32_t)n, GFP_ATOMIC);
123376 + if (!a)
123377 + XX_Print("No memory for XX_Malloc\n");
123378 + XX_RestoreAllIntr(flags);
123379 +
123380 + return a;
123381 +}
123382 +
123383 +void xx_Free(void *p)
123384 +{
123385 +#ifdef BIGPHYSAREA_ENABLE
123386 + if (in_big_phys_area ((uint32_t)p))
123387 + bigphysarea_free_pages(p);
123388 + else
123389 +#endif /* BIGPHYSAREA_ENABLE */
123390 + kfree(p);
123391 +}
123392 +
123393 +void XX_Exit(int status)
123394 +{
123395 + WARN(1, "\n\nFMD: fatal error, driver can't go on!!!\n\n");
123396 +}
123397 +
123398 +#define BUF_SIZE 512
123399 +void XX_Print(char *str, ...)
123400 +{
123401 + va_list args;
123402 +#ifdef CONFIG_SMP
123403 + char buf[BUF_SIZE];
123404 +#endif /* CONFIG_SMP */
123405 +
123406 + va_start(args, str);
123407 +#ifdef CONFIG_SMP
123408 + if (vsnprintf (buf, BUF_SIZE, str, args) >= BUF_SIZE)
123409 + printk(KERN_WARNING "Illegal string to print!\n more than %d characters.\n\tString was not printed completelly.\n", BUF_SIZE);
123410 + printk(KERN_CRIT "cpu%d/%d: %s", raw_smp_processor_id(), NR_CPUS, buf);
123411 +#else
123412 + vprintk(str, args);
123413 +#endif /* CONFIG_SMP */
123414 + va_end(args);
123415 +}
123416 +
123417 +void XX_Fprint(void *file, char *str, ...)
123418 +{
123419 + va_list args;
123420 +#ifdef CONFIG_SMP
123421 + char buf[BUF_SIZE];
123422 +#endif /* CONFIG_SMP */
123423 +
123424 + va_start(args, str);
123425 +#ifdef CONFIG_SMP
123426 + if (vsnprintf (buf, BUF_SIZE, str, args) >= BUF_SIZE)
123427 + printk(KERN_WARNING "Illegal string to print!\n more than %d characters.\n\tString was not printed completelly.\n", BUF_SIZE);
123428 + printk (KERN_CRIT "cpu%d/%d: %s", raw_smp_processor_id(), NR_CPUS, buf);
123429 +
123430 +#else
123431 + vprintk(str, args);
123432 +#endif /* CONFIG_SMP */
123433 + va_end(args);
123434 +}
123435 +
123436 +#ifdef DEBUG_XX_MALLOC
123437 +typedef void (*t_ffn)(void *);
123438 +typedef struct {
123439 + t_ffn f_free;
123440 + void *mem;
123441 + char *fname;
123442 + int fline;
123443 + uint32_t size;
123444 + t_List node;
123445 +} t_MemDebug;
123446 +#define MEMDBG_OBJECT(p_List) LIST_OBJECT(p_List, t_MemDebug, node)
123447 +
123448 +LIST(memDbgLst);
123449 +
123450 +
123451 +void * XX_MallocDebug(uint32_t size, char *fname, int line)
123452 +{
123453 + void *mem;
123454 + t_MemDebug *p_MemDbg;
123455 +
123456 + p_MemDbg = (t_MemDebug *)xx_Malloc(sizeof(t_MemDebug));
123457 + if (p_MemDbg == NULL)
123458 + return NULL;
123459 +
123460 + mem = xx_Malloc(size);
123461 + if (mem == NULL)
123462 + {
123463 + XX_Free(p_MemDbg);
123464 + return NULL;
123465 + }
123466 +
123467 + INIT_LIST(&p_MemDbg->node);
123468 + p_MemDbg->f_free = xx_Free;
123469 + p_MemDbg->mem = mem;
123470 + p_MemDbg->fname = fname;
123471 + p_MemDbg->fline = line;
123472 + p_MemDbg->size = size+sizeof(t_MemDebug);
123473 + LIST_AddToTail(&p_MemDbg->node, &memDbgLst);
123474 +
123475 + return mem;
123476 +}
123477 +
123478 +void * XX_MallocSmartDebug(uint32_t size,
123479 + int memPartitionId,
123480 + uint32_t align,
123481 + char *fname,
123482 + int line)
123483 +{
123484 + void *mem;
123485 + t_MemDebug *p_MemDbg;
123486 +
123487 + p_MemDbg = (t_MemDebug *)XX_Malloc(sizeof(t_MemDebug));
123488 + if (p_MemDbg == NULL)
123489 + return NULL;
123490 +
123491 + mem = xx_MallocSmart((uint32_t)size, memPartitionId, align);
123492 + if (mem == NULL)
123493 + {
123494 + XX_Free(p_MemDbg);
123495 + return NULL;
123496 + }
123497 +
123498 + INIT_LIST(&p_MemDbg->node);
123499 + p_MemDbg->f_free = xx_FreeSmart;
123500 + p_MemDbg->mem = mem;
123501 + p_MemDbg->fname = fname;
123502 + p_MemDbg->fline = line;
123503 + p_MemDbg->size = size+sizeof(t_MemDebug);
123504 + LIST_AddToTail(&p_MemDbg->node, &memDbgLst);
123505 +
123506 + return mem;
123507 +}
123508 +
123509 +static void debug_free(void *mem)
123510 +{
123511 + t_List *p_MemDbgLh = NULL;
123512 + t_MemDebug *p_MemDbg;
123513 + bool found = FALSE;
123514 +
123515 + if (LIST_IsEmpty(&memDbgLst))
123516 + {
123517 + REPORT_ERROR(MAJOR, E_ALREADY_FREE, ("Unbalanced free (0x%08x)", mem));
123518 + return;
123519 + }
123520 +
123521 + LIST_FOR_EACH(p_MemDbgLh, &memDbgLst)
123522 + {
123523 + p_MemDbg = MEMDBG_OBJECT(p_MemDbgLh);
123524 + if (p_MemDbg->mem == mem)
123525 + {
123526 + found = TRUE;
123527 + break;
123528 + }
123529 + }
123530 +
123531 + if (!found)
123532 + {
123533 + REPORT_ERROR(MAJOR, E_NOT_FOUND,
123534 + ("Attempt to free unallocated address (0x%08x)",mem));
123535 + dump_stack();
123536 + return;
123537 + }
123538 +
123539 + LIST_Del(p_MemDbgLh);
123540 + p_MemDbg->f_free(mem);
123541 + p_MemDbg->f_free(p_MemDbg);
123542 +}
123543 +
123544 +void XX_FreeSmart(void *p)
123545 +{
123546 + debug_free(p);
123547 +}
123548 +
123549 +
123550 +void XX_Free(void *p)
123551 +{
123552 + debug_free(p);
123553 +}
123554 +
123555 +#else /* not DEBUG_XX_MALLOC */
123556 +void * XX_Malloc(uint32_t size)
123557 +{
123558 + return xx_Malloc(size);
123559 +}
123560 +
123561 +void * XX_MallocSmart(uint32_t size, int memPartitionId, uint32_t alignment)
123562 +{
123563 + return xx_MallocSmart(size,memPartitionId, alignment);
123564 +}
123565 +
123566 +void XX_FreeSmart(void *p)
123567 +{
123568 + xx_FreeSmart(p);
123569 +}
123570 +
123571 +
123572 +void XX_Free(void *p)
123573 +{
123574 + xx_Free(p);
123575 +}
123576 +#endif /* not DEBUG_XX_MALLOC */
123577 +
123578 +
123579 +#if (defined(REPORT_EVENTS) && (REPORT_EVENTS > 0))
123580 +void XX_EventById(uint32_t event, t_Handle appId, uint16_t flags, char *msg)
123581 +{
123582 + e_Event eventCode = (e_Event)event;
123583 +
123584 + UNUSED(eventCode);
123585 + UNUSED(appId);
123586 + UNUSED(flags);
123587 + UNUSED(msg);
123588 +}
123589 +#endif /* (defined(REPORT_EVENTS) && ... */
123590 +
123591 +
123592 +uint32_t XX_DisableAllIntr(void)
123593 +{
123594 + unsigned long flags;
123595 +
123596 +#ifdef local_irq_save_nort
123597 + local_irq_save_nort(flags);
123598 +#else
123599 + local_irq_save(flags);
123600 +#endif
123601 +
123602 + return (uint32_t)flags;
123603 +}
123604 +
123605 +void XX_RestoreAllIntr(uint32_t flags)
123606 +{
123607 +#ifdef local_irq_restore_nort
123608 + local_irq_restore_nort((unsigned long)flags);
123609 +#else
123610 + local_irq_restore((unsigned long)flags);
123611 +#endif
123612 +}
123613 +
123614 +t_Error XX_Call( uint32_t qid, t_Error (* f)(t_Handle), t_Handle id, t_Handle appId, uint16_t flags )
123615 +{
123616 + UNUSED(qid);
123617 + UNUSED(appId);
123618 + UNUSED(flags);
123619 +
123620 + return f(id);
123621 +}
123622 +
123623 +int XX_IsICacheEnable(void)
123624 +{
123625 + return TRUE;
123626 +}
123627 +
123628 +int XX_IsDCacheEnable(void)
123629 +{
123630 + return TRUE;
123631 +}
123632 +
123633 +
123634 +typedef struct {
123635 + t_Isr *f_Isr;
123636 + t_Handle handle;
123637 +} t_InterruptHandler;
123638 +
123639 +
123640 +t_Handle interruptHandlers[0x00010000];
123641 +
123642 +#ifdef CONFIG_FMAN_ARM
123643 +static irqreturn_t LinuxInterruptHandler (int irq, void *dev_id)
123644 +{
123645 + t_InterruptHandler *p_IntrHndl = (t_InterruptHandler *)dev_id;
123646 + p_IntrHndl->f_Isr(p_IntrHndl->handle);
123647 + return IRQ_HANDLED;
123648 +}
123649 +#endif
123650 +
123651 +t_Error XX_SetIntr(int irq, t_Isr *f_Isr, t_Handle handle)
123652 +{
123653 +#ifdef CONFIG_FMAN_ARM
123654 + const char *device;
123655 + t_InterruptHandler *p_IntrHndl;
123656 +
123657 + device = GetDeviceName(irq);
123658 + if (device == NULL)
123659 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Interrupt source - %d", irq));
123660 +
123661 + p_IntrHndl = (t_InterruptHandler *)XX_Malloc(sizeof(t_InterruptHandler));
123662 + if (p_IntrHndl == NULL)
123663 + RETURN_ERROR(MAJOR, E_NO_MEMORY, NO_MSG);
123664 + p_IntrHndl->f_Isr = f_Isr;
123665 + p_IntrHndl->handle = handle;
123666 + interruptHandlers[irq] = p_IntrHndl;
123667 +
123668 + if (request_irq(GetDeviceIrqNum(irq), LinuxInterruptHandler, 0, device, p_IntrHndl) < 0)
123669 + RETURN_ERROR(MAJOR, E_BUSY, ("Can't get IRQ %s\n", device));
123670 + disable_irq(GetDeviceIrqNum(irq));
123671 +#endif
123672 + return E_OK;
123673 +}
123674 +
123675 +t_Error XX_FreeIntr(int irq)
123676 +{
123677 + t_InterruptHandler *p_IntrHndl = interruptHandlers[irq];
123678 + free_irq(GetDeviceIrqNum(irq), p_IntrHndl);
123679 + XX_Free(p_IntrHndl);
123680 + interruptHandlers[irq] = 0;
123681 + return E_OK;
123682 +}
123683 +
123684 +t_Error XX_EnableIntr(int irq)
123685 +{
123686 + enable_irq(GetDeviceIrqNum(irq));
123687 + return E_OK;
123688 +}
123689 +
123690 +t_Error XX_DisableIntr(int irq)
123691 +{
123692 + disable_irq(GetDeviceIrqNum(irq));
123693 + return E_OK;
123694 +}
123695 +
123696 +
123697 +/*****************************************************************************/
123698 +/* Tasklet Service Routines */
123699 +/*****************************************************************************/
123700 +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
123701 +typedef struct
123702 +{
123703 + t_Handle h_Data;
123704 + void (*f_Callback) (void *);
123705 + struct delayed_work dwork;
123706 +} t_Tasklet;
123707 +
123708 +static void GenericTaskletCallback(struct work_struct *p_Work)
123709 +{
123710 + t_Tasklet *p_Task = container_of(p_Work, t_Tasklet, dwork.work);
123711 +
123712 + p_Task->f_Callback(p_Task->h_Data);
123713 +}
123714 +#endif /* LINUX_VERSION_CODE */
123715 +
123716 +
123717 +t_TaskletHandle XX_InitTasklet (void (*routine)(void *), void *data)
123718 +{
123719 +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
123720 + struct work_struct *p_Task;
123721 + p_Task = (struct work_struct *)XX_Malloc(sizeof(struct work_struct));
123722 + INIT_WORK(p_Task, routine, data);
123723 +#else
123724 + t_Tasklet *p_Task = (t_Tasklet *)XX_Malloc(sizeof(t_Tasklet));
123725 + p_Task->h_Data = data;
123726 + p_Task->f_Callback = routine;
123727 + INIT_DELAYED_WORK(&p_Task->dwork, GenericTaskletCallback);
123728 +#endif /* LINUX_VERSION_CODE */
123729 +
123730 + return (t_TaskletHandle)p_Task;
123731 +}
123732 +
123733 +
123734 +void XX_FreeTasklet (t_TaskletHandle h_Tasklet)
123735 +{
123736 + if (h_Tasklet)
123737 + XX_Free(h_Tasklet);
123738 +}
123739 +
123740 +int XX_ScheduleTask(t_TaskletHandle h_Tasklet, int immediate)
123741 +{
123742 + int ans;
123743 +
123744 +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
123745 + if (immediate)
123746 + ans = schedule_work(h_Tasklet);
123747 + else
123748 + ans = schedule_delayed_work(h_Tasklet, 1);
123749 +#else
123750 + if (immediate)
123751 + ans = schedule_delayed_work(&((t_Tasklet *)h_Tasklet)->dwork, 0);
123752 + else
123753 + ans = schedule_delayed_work(&((t_Tasklet *)h_Tasklet)->dwork, HZ);
123754 +#endif /* LINUX_VERSION_CODE */
123755 +
123756 + return ans;
123757 +}
123758 +
123759 +void XX_FlushScheduledTasks(void)
123760 +{
123761 +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
123762 + flush_scheduled_tasks();
123763 +#else
123764 + flush_scheduled_work();
123765 +#endif /* LINUX_VERSION_CODE */
123766 +}
123767 +
123768 +int XX_TaskletIsQueued(t_TaskletHandle h_Tasklet)
123769 +{
123770 +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
123771 + return (int)(((struct work_struct *)h_Tasklet)->pending);
123772 +#else
123773 + return (int)delayed_work_pending(&((t_Tasklet *)h_Tasklet)->dwork);
123774 +#endif /* LINUX_VERSION_CODE */
123775 +}
123776 +
123777 +void XX_SetTaskletData(t_TaskletHandle h_Tasklet, t_Handle data)
123778 +{
123779 +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
123780 + ((struct tq_struct *)h_Tasklet)->data = data;
123781 +#elif LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
123782 + ((struct work_struct *)h_Tasklet)->data = data;
123783 +#else
123784 + ((t_Tasklet *)h_Tasklet)->h_Data = data;
123785 +#endif /* LINUX_VERSION_CODE */
123786 +}
123787 +
123788 +t_Handle XX_GetTaskletData(t_TaskletHandle h_Tasklet)
123789 +{
123790 +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
123791 + return (t_Handle)(((struct work_struct *)h_Tasklet)->data);
123792 +#else
123793 + return ((t_Tasklet *)h_Tasklet)->h_Data;
123794 +#endif /* LINUX_VERSION_CODE */
123795 +}
123796 +
123797 +
123798 +/*****************************************************************************/
123799 +/* Spinlock Service Routines */
123800 +/*****************************************************************************/
123801 +
123802 +t_Handle XX_InitSpinlock(void)
123803 +{
123804 + spinlock_t *p_Spinlock = (spinlock_t *)XX_Malloc(sizeof(spinlock_t));
123805 + if (!p_Spinlock)
123806 + return NULL;
123807 +
123808 + spin_lock_init(p_Spinlock);
123809 +
123810 + return (t_Handle)p_Spinlock;
123811 +}
123812 +
123813 +void XX_FreeSpinlock(t_Handle h_Spinlock)
123814 +{
123815 + if (h_Spinlock)
123816 + XX_Free(h_Spinlock);
123817 +}
123818 +
123819 +void XX_LockSpinlock(t_Handle h_Spinlock)
123820 +{
123821 + spin_lock((spinlock_t *)h_Spinlock);
123822 +}
123823 +
123824 +void XX_UnlockSpinlock(t_Handle h_Spinlock)
123825 +{
123826 + spin_unlock((spinlock_t *)h_Spinlock);
123827 +}
123828 +
123829 +uint32_t XX_LockIntrSpinlock(t_Handle h_Spinlock)
123830 +{
123831 + unsigned long intrFlags;
123832 + spin_lock_irqsave((spinlock_t *)h_Spinlock, intrFlags);
123833 + return intrFlags;
123834 +}
123835 +
123836 +void XX_UnlockIntrSpinlock(t_Handle h_Spinlock, uint32_t intrFlags)
123837 +{
123838 + spin_unlock_irqrestore((spinlock_t *)h_Spinlock, (unsigned long)intrFlags);
123839 +}
123840 +
123841 +
123842 +/*****************************************************************************/
123843 +/* Timers Service Routines */
123844 +/*****************************************************************************/
123845 +/* The time now is in mili sec. resolution */
123846 +uint32_t XX_CurrentTime(void)
123847 +{
123848 + return (jiffies*1000)/HZ;
123849 +}
123850 +
123851 +
123852 +t_Handle XX_CreateTimer(void)
123853 +{
123854 + struct timer_list *p_Timer = (struct timer_list *)XX_Malloc(sizeof(struct timer_list));
123855 + if (p_Timer)
123856 + {
123857 + memset(p_Timer, 0, sizeof(struct timer_list));
123858 + init_timer(p_Timer);
123859 + }
123860 + return (t_Handle)p_Timer;
123861 +}
123862 +
123863 +void XX_FreeTimer(t_Handle h_Timer)
123864 +{
123865 + if (h_Timer)
123866 + XX_Free(h_Timer);
123867 +}
123868 +
123869 +void XX_StartTimer(t_Handle h_Timer,
123870 + uint32_t msecs,
123871 + bool periodic,
123872 + void (*f_TimerExpired)(t_Handle),
123873 + t_Handle h_Arg)
123874 +{
123875 + int tmp_jiffies = (msecs*HZ)/1000;
123876 + struct timer_list *p_Timer = (struct timer_list *)h_Timer;
123877 +
123878 + SANITY_CHECK_RETURN((periodic == FALSE), E_NOT_SUPPORTED);
123879 +
123880 + p_Timer->function = (void (*)(unsigned long))f_TimerExpired;
123881 + p_Timer->data = (unsigned long)h_Arg;
123882 + if ((msecs*HZ)%1000)
123883 + tmp_jiffies++;
123884 + p_Timer->expires = (jiffies + tmp_jiffies);
123885 +
123886 + add_timer((struct timer_list *)h_Timer);
123887 +}
123888 +
123889 +void XX_SetTimerData(t_Handle h_Timer, t_Handle data)
123890 +{
123891 + struct timer_list *p_Timer = (struct timer_list *)h_Timer;
123892 +
123893 + p_Timer->data = (unsigned long)data;
123894 +}
123895 +
123896 +t_Handle XX_GetTimerData(t_Handle h_Timer)
123897 +{
123898 + struct timer_list *p_Timer = (struct timer_list *)h_Timer;
123899 +
123900 + return (t_Handle)p_Timer->data;
123901 +}
123902 +
123903 +uint32_t XX_GetExpirationTime(t_Handle h_Timer)
123904 +{
123905 + struct timer_list *p_Timer = (struct timer_list *)h_Timer;
123906 +
123907 + return (uint32_t)p_Timer->expires;
123908 +}
123909 +
123910 +void XX_StopTimer(t_Handle h_Timer)
123911 +{
123912 + del_timer((struct timer_list *)h_Timer);
123913 +}
123914 +
123915 +void XX_ModTimer(t_Handle h_Timer, uint32_t msecs)
123916 +{
123917 + int tmp_jiffies = (msecs*HZ)/1000;
123918 +
123919 + if ((msecs*HZ)%1000)
123920 + tmp_jiffies++;
123921 + mod_timer((struct timer_list *)h_Timer, jiffies + tmp_jiffies);
123922 +}
123923 +
123924 +int XX_TimerIsActive(t_Handle h_Timer)
123925 +{
123926 + return timer_pending((struct timer_list *)h_Timer);
123927 +}
123928 +
123929 +uint32_t XX_Sleep(uint32_t msecs)
123930 +{
123931 + int tmp_jiffies = (msecs*HZ)/1000;
123932 +
123933 + if ((msecs*HZ)%1000)
123934 + tmp_jiffies++;
123935 + return schedule_timeout(tmp_jiffies);
123936 +}
123937 +
123938 +/*BEWARE!!!!! UDelay routine is BUSY WAITTING!!!!!*/
123939 +void XX_UDelay(uint32_t usecs)
123940 +{
123941 + udelay(usecs);
123942 +}
123943 +
123944 +/* TODO: verify that these are correct */
123945 +#define MSG_BODY_SIZE 512
123946 +typedef t_Error (t_MsgHandler) (t_Handle h_Mod, uint32_t msgId, uint8_t msgBody[MSG_BODY_SIZE]);
123947 +typedef void (t_MsgCompletionCB) (t_Handle h_Arg, uint8_t msgBody[MSG_BODY_SIZE]);
123948 +t_Error XX_SendMessage(char *p_DestAddr,
123949 + uint32_t msgId,
123950 + uint8_t msgBody[MSG_BODY_SIZE],
123951 + t_MsgCompletionCB *f_CompletionCB,
123952 + t_Handle h_CBArg);
123953 +
123954 +typedef struct {
123955 + char *p_Addr;
123956 + t_MsgHandler *f_MsgHandlerCB;
123957 + t_Handle h_Mod;
123958 + t_List node;
123959 +} t_MsgHndlr;
123960 +#define MSG_HNDLR_OBJECT(ptr) LIST_OBJECT(ptr, t_MsgHndlr, node)
123961 +
123962 +LIST(msgHndlrList);
123963 +
123964 +static void EnqueueMsgHndlr(t_MsgHndlr *p_MsgHndlr)
123965 +{
123966 + uint32_t intFlags;
123967 +
123968 + intFlags = XX_DisableAllIntr();
123969 + LIST_AddToTail(&p_MsgHndlr->node, &msgHndlrList);
123970 + XX_RestoreAllIntr(intFlags);
123971 +}
123972 +/* TODO: add this for multi-platform support
123973 +static t_MsgHndlr * DequeueMsgHndlr(void)
123974 +{
123975 + t_MsgHndlr *p_MsgHndlr = NULL;
123976 + uint32_t intFlags;
123977 +
123978 + intFlags = XX_DisableAllIntr();
123979 + if (!LIST_IsEmpty(&msgHndlrList))
123980 + {
123981 + p_MsgHndlr = MSG_HNDLR_OBJECT(msgHndlrList.p_Next);
123982 + LIST_DelAndInit(&p_MsgHndlr->node);
123983 + }
123984 + XX_RestoreAllIntr(intFlags);
123985 +
123986 + return p_MsgHndlr;
123987 +}
123988 +*/
123989 +static t_MsgHndlr * FindMsgHndlr(char *p_Addr)
123990 +{
123991 + t_MsgHndlr *p_MsgHndlr;
123992 + t_List *p_Pos;
123993 +
123994 + LIST_FOR_EACH(p_Pos, &msgHndlrList)
123995 + {
123996 + p_MsgHndlr = MSG_HNDLR_OBJECT(p_Pos);
123997 + if (strstr(p_MsgHndlr->p_Addr, p_Addr))
123998 + return p_MsgHndlr;
123999 + }
124000 +
124001 + return NULL;
124002 +}
124003 +
124004 +t_Error XX_RegisterMessageHandler (char *p_Addr, t_MsgHandler *f_MsgHandlerCB, t_Handle h_Mod)
124005 +{
124006 + t_MsgHndlr *p_MsgHndlr;
124007 + uint32_t len;
124008 +
124009 + p_MsgHndlr = (t_MsgHndlr*)XX_Malloc(sizeof(t_MsgHndlr));
124010 + if (!p_MsgHndlr)
124011 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("message handler object!!!"));
124012 + memset(p_MsgHndlr, 0, sizeof(t_MsgHndlr));
124013 +
124014 + len = strlen(p_Addr);
124015 + p_MsgHndlr->p_Addr = (char*)XX_Malloc(len+1);
124016 + strncpy(p_MsgHndlr->p_Addr,p_Addr, (uint32_t)(len+1));
124017 +
124018 + p_MsgHndlr->f_MsgHandlerCB = f_MsgHandlerCB;
124019 + p_MsgHndlr->h_Mod = h_Mod;
124020 + INIT_LIST(&p_MsgHndlr->node);
124021 + EnqueueMsgHndlr(p_MsgHndlr);
124022 +
124023 + return E_OK;
124024 +}
124025 +
124026 +t_Error XX_UnregisterMessageHandler (char *p_Addr)
124027 +{
124028 + t_MsgHndlr *p_MsgHndlr = FindMsgHndlr(p_Addr);
124029 + if (!p_MsgHndlr)
124030 + RETURN_ERROR(MINOR, E_NO_DEVICE, ("message handler not found in list!!!"));
124031 +
124032 + LIST_Del(&p_MsgHndlr->node);
124033 + XX_Free(p_MsgHndlr->p_Addr);
124034 + XX_Free(p_MsgHndlr);
124035 +
124036 + return E_OK;
124037 +}
124038 +
124039 +t_Error XX_SendMessage(char *p_DestAddr,
124040 + uint32_t msgId,
124041 + uint8_t msgBody[MSG_BODY_SIZE],
124042 + t_MsgCompletionCB *f_CompletionCB,
124043 + t_Handle h_CBArg)
124044 +{
124045 + t_Error ans;
124046 + t_MsgHndlr *p_MsgHndlr = FindMsgHndlr(p_DestAddr);
124047 + if (!p_MsgHndlr)
124048 + RETURN_ERROR(MINOR, E_NO_DEVICE, ("message handler not found in list!!!"));
124049 +
124050 + ans = p_MsgHndlr->f_MsgHandlerCB(p_MsgHndlr->h_Mod, msgId, msgBody);
124051 +
124052 + if (f_CompletionCB)
124053 + f_CompletionCB(h_CBArg, msgBody);
124054 +
124055 + return ans;
124056 +}
124057 +
124058 +t_Error XX_IpcRegisterMsgHandler(char addr[XX_IPC_MAX_ADDR_NAME_LENGTH],
124059 + t_IpcMsgHandler *f_MsgHandler,
124060 + t_Handle h_Module,
124061 + uint32_t replyLength)
124062 +{
124063 + UNUSED(addr);UNUSED(f_MsgHandler);UNUSED(h_Module);UNUSED(replyLength);
124064 + return E_OK;
124065 +}
124066 +
124067 +t_Error XX_IpcUnregisterMsgHandler(char addr[XX_IPC_MAX_ADDR_NAME_LENGTH])
124068 +{
124069 + UNUSED(addr);
124070 + return E_OK;
124071 +}
124072 +
124073 +
124074 +t_Error XX_IpcSendMessage(t_Handle h_Session,
124075 + uint8_t *p_Msg,
124076 + uint32_t msgLength,
124077 + uint8_t *p_Reply,
124078 + uint32_t *p_ReplyLength,
124079 + t_IpcMsgCompletion *f_Completion,
124080 + t_Handle h_Arg)
124081 +{
124082 + UNUSED(h_Session); UNUSED(p_Msg); UNUSED(msgLength); UNUSED(p_Reply);
124083 + UNUSED(p_ReplyLength); UNUSED(f_Completion); UNUSED(h_Arg);
124084 + return E_OK;
124085 +}
124086 +
124087 +t_Handle XX_IpcInitSession(char destAddr[XX_IPC_MAX_ADDR_NAME_LENGTH],
124088 + char srcAddr[XX_IPC_MAX_ADDR_NAME_LENGTH])
124089 +{
124090 + UNUSED(destAddr); UNUSED(srcAddr);
124091 + return E_OK;
124092 +}
124093 +
124094 +/*Forced to introduce due to PRINT_FMT_PARAMS define*/
124095 +uint32_t E500_GetId(void)
124096 +{
124097 + return raw_smp_processor_id();
124098 +}
124099 +
124100 +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22)
124101 +int GetDeviceIrqNum(int irq)
124102 +{
124103 + struct device_node *iPar;
124104 + struct irq_domain *irqHost;
124105 + uint32_t hwIrq;
124106 +
124107 + /* Get the interrupt controller */
124108 + iPar = of_find_node_by_name(NULL, "mpic");
124109 + hwIrq = 0;
124110 +
124111 + ASSERT_COND(iPar != NULL);
124112 + /* Get the irq host */
124113 + irqHost = irq_find_host(iPar);
124114 + of_node_put(iPar);
124115 +
124116 + /* Create irq mapping */
124117 + return irq_create_mapping(irqHost, hwIrq);
124118 +}
124119 +#else
124120 +#error "kernel not supported!!!"
124121 +#endif /* LINUX_VERSION_CODE */
124122 +
124123 +void * XX_PhysToVirt(physAddress_t addr)
124124 +{
124125 + return UINT_TO_PTR(SYS_PhysToVirt((uint64_t)addr));
124126 +}
124127 +
124128 +physAddress_t XX_VirtToPhys(void * addr)
124129 +{
124130 + return (physAddress_t)SYS_VirtToPhys(PTR_TO_UINT(addr));
124131 +}
124132 +
124133 +void * xx_MallocSmart(uint32_t size, int memPartitionId, uint32_t alignment)
124134 +{
124135 + uintptr_t *returnCode, tmp;
124136 +
124137 + if (alignment < sizeof(uintptr_t))
124138 + alignment = sizeof(uintptr_t);
124139 + size += alignment + sizeof(returnCode);
124140 + tmp = (uintptr_t)xx_Malloc(size);
124141 + if (tmp == 0)
124142 + return NULL;
124143 + returnCode = (uintptr_t*)((tmp + alignment + sizeof(returnCode)) & ~((uintptr_t)alignment - 1));
124144 + *(returnCode - 1) = tmp;
124145 +
124146 + return (void*)returnCode;
124147 +}
124148 +
124149 +void xx_FreeSmart(void *p)
124150 +{
124151 + xx_Free((void*)(*((uintptr_t *)(p) - 1)));
124152 +}
124153 --- /dev/null
124154 +++ b/drivers/staging/fsl_qbman/Kconfig
124155 @@ -0,0 +1,228 @@
124156 +config FSL_SDK_DPA
124157 + bool "Freescale Datapath Queue and Buffer management"
124158 + depends on !FSL_DPAA
124159 + select FSL_QMAN_FQ_LOOKUP if PPC64
124160 + select FSL_QMAN_FQ_LOOKUP if ARM64
124161 +
124162 +
124163 +menu "Freescale Datapath QMan/BMan options"
124164 + depends on FSL_SDK_DPA
124165 +
124166 +config FSL_DPA_CHECKING
124167 + bool "additional driver checking"
124168 + default n
124169 + ---help---
124170 + Compiles in additional checks to sanity-check the drivers and any
124171 + use of it by other code. Not recommended for performance.
124172 +
124173 +config FSL_DPA_CAN_WAIT
124174 + bool
124175 + default y
124176 +
124177 +config FSL_DPA_CAN_WAIT_SYNC
124178 + bool
124179 + default y
124180 +
124181 +config FSL_DPA_PIRQ_FAST
124182 + bool
124183 + default y
124184 +
124185 +config FSL_DPA_PIRQ_SLOW
124186 + bool
124187 + default y
124188 +
124189 +config FSL_DPA_PORTAL_SHARE
124190 + bool
124191 + default y
124192 +
124193 +config FSL_SDK_BMAN
124194 + bool "Freescale Buffer Manager (BMan) support"
124195 + default y
124196 +
124197 +if FSL_SDK_BMAN
124198 +
124199 +config FSL_BMAN_CONFIG
124200 + bool "BMan device management"
124201 + default y
124202 + ---help---
124203 + If this linux image is running natively, you need this option. If this
124204 + linux image is running as a guest OS under the hypervisor, only one
124205 + guest OS ("the control plane") needs this option.
124206 +
124207 +config FSL_BMAN_TEST
124208 + tristate "BMan self-tests"
124209 + default n
124210 + ---help---
124211 + This option compiles self-test code for BMan.
124212 +
124213 +config FSL_BMAN_TEST_HIGH
124214 + bool "BMan high-level self-test"
124215 + depends on FSL_BMAN_TEST
124216 + default y
124217 + ---help---
124218 + This requires the presence of cpu-affine portals, and performs
124219 + high-level API testing with them (whichever portal(s) are affine to
124220 + the cpu(s) the test executes on).
124221 +
124222 +config FSL_BMAN_TEST_THRESH
124223 + bool "BMan threshold test"
124224 + depends on FSL_BMAN_TEST
124225 + default y
124226 + ---help---
124227 + Multi-threaded (SMP) test of BMan pool depletion. A pool is seeded
124228 + before multiple threads (one per cpu) create pool objects to track
124229 + depletion state changes. The pool is then drained to empty by a
124230 + "drainer" thread, and the other threads that they observe exactly
124231 + the depletion state changes that are expected.
124232 +
124233 +config FSL_BMAN_DEBUGFS
124234 + tristate "BMan debugfs interface"
124235 + depends on DEBUG_FS
124236 + default y
124237 + ---help---
124238 + This option compiles debugfs code for BMan.
124239 +
124240 +endif # FSL_SDK_BMAN
124241 +
124242 +config FSL_SDK_QMAN
124243 + bool "Freescale Queue Manager (QMan) support"
124244 + default y
124245 +
124246 +if FSL_SDK_QMAN
124247 +
124248 +config FSL_QMAN_POLL_LIMIT
124249 + int
124250 + default 32
124251 +
124252 +config FSL_QMAN_CONFIG
124253 + bool "QMan device management"
124254 + default y
124255 + ---help---
124256 + If this linux image is running natively, you need this option. If this
124257 + linux image is running as a guest OS under the hypervisor, only one
124258 + guest OS ("the control plane") needs this option.
124259 +
124260 +config FSL_QMAN_TEST
124261 + tristate "QMan self-tests"
124262 + default n
124263 + ---help---
124264 + This option compiles self-test code for QMan.
124265 +
124266 +config FSL_QMAN_TEST_STASH_POTATO
124267 + bool "QMan 'hot potato' data-stashing self-test"
124268 + depends on FSL_QMAN_TEST
124269 + default y
124270 + ---help---
124271 + This performs a "hot potato" style test enqueuing/dequeuing a frame
124272 + across a series of FQs scheduled to different portals (and cpus), with
124273 + DQRR, data and context stashing always on.
124274 +
124275 +config FSL_QMAN_TEST_HIGH
124276 + bool "QMan high-level self-test"
124277 + depends on FSL_QMAN_TEST
124278 + default y
124279 + ---help---
124280 + This requires the presence of cpu-affine portals, and performs
124281 + high-level API testing with them (whichever portal(s) are affine to
124282 + the cpu(s) the test executes on).
124283 +
124284 +config FSL_QMAN_DEBUGFS
124285 + tristate "QMan debugfs interface"
124286 + depends on DEBUG_FS
124287 + default y
124288 + ---help---
124289 + This option compiles debugfs code for QMan.
124290 +
124291 +# H/w settings that can be hard-coded for now.
124292 +config FSL_QMAN_FQD_SZ
124293 + int "size of Frame Queue Descriptor region"
124294 + default 10
124295 + ---help---
124296 + This is the size of the FQD region defined as: PAGE_SIZE * (2^value)
124297 + ex: 10 => PAGE_SIZE * (2^10)
124298 + Note: Default device-trees now require minimum Kconfig setting of 10.
124299 +
124300 +config FSL_QMAN_PFDR_SZ
124301 + int "size of the PFDR pool"
124302 + default 13
124303 + ---help---
124304 + This is the size of the PFDR pool defined as: PAGE_SIZE * (2^value)
124305 + ex: 13 => PAGE_SIZE * (2^13)
124306 +
124307 +# Corenet initiator settings. Stash request queues are 4-deep to match cores'
124308 +# ability to snart. Stash priority is 3, other priorities are 2.
124309 +config FSL_QMAN_CI_SCHED_CFG_SRCCIV
124310 + int
124311 + depends on FSL_QMAN_CONFIG
124312 + default 4
124313 +config FSL_QMAN_CI_SCHED_CFG_SRQ_W
124314 + int
124315 + depends on FSL_QMAN_CONFIG
124316 + default 3
124317 +config FSL_QMAN_CI_SCHED_CFG_RW_W
124318 + int
124319 + depends on FSL_QMAN_CONFIG
124320 + default 2
124321 +config FSL_QMAN_CI_SCHED_CFG_BMAN_W
124322 + int
124323 + depends on FSL_QMAN_CONFIG
124324 + default 2
124325 +
124326 +# portal interrupt settings
124327 +config FSL_QMAN_PIRQ_DQRR_ITHRESH
124328 + int
124329 + default 12
124330 +config FSL_QMAN_PIRQ_MR_ITHRESH
124331 + int
124332 + default 4
124333 +config FSL_QMAN_PIRQ_IPERIOD
124334 + int
124335 + default 100
124336 +
124337 +# 64 bit kernel support
124338 +config FSL_QMAN_FQ_LOOKUP
124339 + bool
124340 + default n
124341 +
124342 +config QMAN_CEETM_UPDATE_PERIOD
124343 + int "Token update period for shaping, in nanoseconds"
124344 + default 1000
124345 + ---help---
124346 + Traffic shaping works by performing token calculations (using
124347 + credits) on shaper instances periodically. This update period
124348 + sets the granularity for how often those token rate credit
124349 + updates are performed, and thus determines the accuracy and
124350 + range of traffic rates that can be configured by users. The
124351 + reference manual recommends a 1 microsecond period as providing
124352 + a good balance between granularity and range.
124353 +
124354 + Unless you know what you are doing, leave this value at its default.
124355 +
124356 +config FSL_QMAN_INIT_TIMEOUT
124357 + int "timeout for qman init stage, in seconds"
124358 + default 10
124359 + ---help---
124360 + The timeout setting to quit the initialization loop for non-control
124361 + partition in case the control partition fails to boot-up.
124362 +
124363 +endif # FSL_SDK_QMAN
124364 +
124365 +config FSL_USDPAA
124366 + bool "Freescale USDPAA process driver"
124367 + depends on FSL_SDK_DPA
124368 + default y
124369 + ---help---
124370 + This driver provides user-space access to kernel-managed
124371 + resource interfaces for USDPAA applications, on the assumption
124372 + that each process will open this device once. Specifically, this
124373 + device exposes functionality that would be awkward if exposed
124374 + via the portal devices - ie. this device exposes functionality
124375 + that is inherently process-wide rather than portal-specific.
124376 + This device is necessary for obtaining access to DMA memory and
124377 + for allocation of Qman and Bman resources. In short, if you wish
124378 + to use USDPAA applications, you need this.
124379 +
124380 + If unsure, say Y.
124381 +
124382 +
124383 +endmenu
124384 --- /dev/null
124385 +++ b/drivers/staging/fsl_qbman/Makefile
124386 @@ -0,0 +1,28 @@
124387 +subdir-ccflags-y := -Werror
124388 +
124389 +# Common
124390 +obj-$(CONFIG_FSL_SDK_DPA) += dpa_alloc.o
124391 +obj-$(CONFIG_FSL_SDK_DPA) += qbman_driver.o
124392 +
124393 +# Bman
124394 +obj-$(CONFIG_FSL_SDK_BMAN) += bman_high.o
124395 +obj-$(CONFIG_FSL_BMAN_CONFIG) += bman_config.o bman_driver.o
124396 +obj-$(CONFIG_FSL_BMAN_TEST) += bman_tester.o
124397 +obj-$(CONFIG_FSL_BMAN_DEBUGFS) += bman_debugfs_interface.o
124398 +bman_tester-y = bman_test.o
124399 +bman_tester-$(CONFIG_FSL_BMAN_TEST_HIGH) += bman_test_high.o
124400 +bman_tester-$(CONFIG_FSL_BMAN_TEST_THRESH) += bman_test_thresh.o
124401 +bman_debugfs_interface-y = bman_debugfs.o
124402 +
124403 +# Qman
124404 +obj-$(CONFIG_FSL_SDK_QMAN) += qman_high.o qman_utility.o
124405 +obj-$(CONFIG_FSL_QMAN_CONFIG) += qman_config.o qman_driver.o
124406 +obj-$(CONFIG_FSL_QMAN_TEST) += qman_tester.o
124407 +qman_tester-y = qman_test.o
124408 +qman_tester-$(CONFIG_FSL_QMAN_TEST_STASH_POTATO) += qman_test_hotpotato.o
124409 +qman_tester-$(CONFIG_FSL_QMAN_TEST_HIGH) += qman_test_high.o
124410 +obj-$(CONFIG_FSL_QMAN_DEBUGFS) += qman_debugfs_interface.o
124411 +qman_debugfs_interface-y = qman_debugfs.o
124412 +
124413 +# USDPAA
124414 +obj-$(CONFIG_FSL_USDPAA) += fsl_usdpaa.o fsl_usdpaa_irq.o
124415 --- /dev/null
124416 +++ b/drivers/staging/fsl_qbman/bman_config.c
124417 @@ -0,0 +1,720 @@
124418 +/* Copyright (c) 2009-2012 Freescale Semiconductor, Inc.
124419 + *
124420 + * Redistribution and use in source and binary forms, with or without
124421 + * modification, are permitted provided that the following conditions are met:
124422 + * * Redistributions of source code must retain the above copyright
124423 + * notice, this list of conditions and the following disclaimer.
124424 + * * Redistributions in binary form must reproduce the above copyright
124425 + * notice, this list of conditions and the following disclaimer in the
124426 + * documentation and/or other materials provided with the distribution.
124427 + * * Neither the name of Freescale Semiconductor nor the
124428 + * names of its contributors may be used to endorse or promote products
124429 + * derived from this software without specific prior written permission.
124430 + *
124431 + *
124432 + * ALTERNATIVELY, this software may be distributed under the terms of the
124433 + * GNU General Public License ("GPL") as published by the Free Software
124434 + * Foundation, either version 2 of that License or (at your option) any
124435 + * later version.
124436 + *
124437 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
124438 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
124439 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
124440 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
124441 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
124442 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
124443 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
124444 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
124445 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
124446 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
124447 + */
124448 +
124449 +#include <asm/cacheflush.h>
124450 +#include "bman_private.h"
124451 +#include <linux/of_reserved_mem.h>
124452 +
124453 +/* Last updated for v00.79 of the BG */
124454 +
124455 +struct bman;
124456 +
124457 +/* Register offsets */
124458 +#define REG_POOL_SWDET(n) (0x0000 + ((n) * 0x04))
124459 +#define REG_POOL_HWDET(n) (0x0100 + ((n) * 0x04))
124460 +#define REG_POOL_SWDXT(n) (0x0200 + ((n) * 0x04))
124461 +#define REG_POOL_HWDXT(n) (0x0300 + ((n) * 0x04))
124462 +#define REG_POOL_CONTENT(n) (0x0600 + ((n) * 0x04))
124463 +#define REG_FBPR_FPC 0x0800
124464 +#define REG_STATE_IDLE 0x960
124465 +#define REG_STATE_STOP 0x964
124466 +#define REG_ECSR 0x0a00
124467 +#define REG_ECIR 0x0a04
124468 +#define REG_EADR 0x0a08
124469 +#define REG_EDATA(n) (0x0a10 + ((n) * 0x04))
124470 +#define REG_SBEC(n) (0x0a80 + ((n) * 0x04))
124471 +#define REG_IP_REV_1 0x0bf8
124472 +#define REG_IP_REV_2 0x0bfc
124473 +#define REG_FBPR_BARE 0x0c00
124474 +#define REG_FBPR_BAR 0x0c04
124475 +#define REG_FBPR_AR 0x0c10
124476 +#define REG_SRCIDR 0x0d04
124477 +#define REG_LIODNR 0x0d08
124478 +#define REG_ERR_ISR 0x0e00 /* + "enum bm_isr_reg" */
124479 +
124480 +/* Used by all error interrupt registers except 'inhibit' */
124481 +#define BM_EIRQ_IVCI 0x00000010 /* Invalid Command Verb */
124482 +#define BM_EIRQ_FLWI 0x00000008 /* FBPR Low Watermark */
124483 +#define BM_EIRQ_MBEI 0x00000004 /* Multi-bit ECC Error */
124484 +#define BM_EIRQ_SBEI 0x00000002 /* Single-bit ECC Error */
124485 +#define BM_EIRQ_BSCN 0x00000001 /* pool State Change Notification */
124486 +
124487 +/* BMAN_ECIR valid error bit */
124488 +#define PORTAL_ECSR_ERR (BM_EIRQ_IVCI)
124489 +
124490 +union bman_ecir {
124491 + u32 ecir_raw;
124492 + struct {
124493 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
124494 + u32 __reserved1:4;
124495 + u32 portal_num:4;
124496 + u32 __reserved2:12;
124497 + u32 numb:4;
124498 + u32 __reserved3:2;
124499 + u32 pid:6;
124500 +#else
124501 + u32 pid:6;
124502 + u32 __reserved3:2;
124503 + u32 numb:4;
124504 + u32 __reserved2:12;
124505 + u32 portal_num:4;
124506 + u32 __reserved1:4;
124507 +#endif
124508 + } __packed info;
124509 +};
124510 +
124511 +union bman_eadr {
124512 + u32 eadr_raw;
124513 + struct {
124514 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
124515 + u32 __reserved1:5;
124516 + u32 memid:3;
124517 + u32 __reserved2:14;
124518 + u32 eadr:10;
124519 +#else
124520 + u32 eadr:10;
124521 + u32 __reserved2:14;
124522 + u32 memid:3;
124523 + u32 __reserved1:5;
124524 +#endif
124525 + } __packed info;
124526 +};
124527 +
124528 +struct bman_hwerr_txt {
124529 + u32 mask;
124530 + const char *txt;
124531 +};
124532 +
124533 +#define BMAN_HWE_TXT(a, b) { .mask = BM_EIRQ_##a, .txt = b }
124534 +
124535 +static const struct bman_hwerr_txt bman_hwerr_txts[] = {
124536 + BMAN_HWE_TXT(IVCI, "Invalid Command Verb"),
124537 + BMAN_HWE_TXT(FLWI, "FBPR Low Watermark"),
124538 + BMAN_HWE_TXT(MBEI, "Multi-bit ECC Error"),
124539 + BMAN_HWE_TXT(SBEI, "Single-bit ECC Error"),
124540 + BMAN_HWE_TXT(BSCN, "Pool State Change Notification"),
124541 +};
124542 +#define BMAN_HWE_COUNT (sizeof(bman_hwerr_txts)/sizeof(struct bman_hwerr_txt))
124543 +
124544 +struct bman_error_info_mdata {
124545 + u16 addr_mask;
124546 + u16 bits;
124547 + const char *txt;
124548 +};
124549 +
124550 +#define BMAN_ERR_MDATA(a, b, c) { .addr_mask = a, .bits = b, .txt = c}
124551 +static const struct bman_error_info_mdata error_mdata[] = {
124552 + BMAN_ERR_MDATA(0x03FF, 192, "Stockpile memory"),
124553 + BMAN_ERR_MDATA(0x00FF, 256, "SW portal ring memory port 1"),
124554 + BMAN_ERR_MDATA(0x00FF, 256, "SW portal ring memory port 2"),
124555 +};
124556 +#define BMAN_ERR_MDATA_COUNT \
124557 + (sizeof(error_mdata)/sizeof(struct bman_error_info_mdata))
124558 +
124559 +/* Add this in Kconfig */
124560 +#define BMAN_ERRS_TO_UNENABLE (BM_EIRQ_FLWI)
124561 +
124562 +/**
124563 + * bm_err_isr_<reg>_<verb> - Manipulate global interrupt registers
124564 + * @v: for accessors that write values, this is the 32-bit value
124565 + *
124566 + * Manipulates BMAN_ERR_ISR, BMAN_ERR_IER, BMAN_ERR_ISDR, BMAN_ERR_IIR. All
124567 + * manipulations except bm_err_isr_[un]inhibit() use 32-bit masks composed of
124568 + * the BM_EIRQ_*** definitions. Note that "bm_err_isr_enable_write" means
124569 + * "write the enable register" rather than "enable the write register"!
124570 + */
124571 +#define bm_err_isr_status_read(bm) \
124572 + __bm_err_isr_read(bm, bm_isr_status)
124573 +#define bm_err_isr_status_clear(bm, m) \
124574 + __bm_err_isr_write(bm, bm_isr_status, m)
124575 +#define bm_err_isr_enable_read(bm) \
124576 + __bm_err_isr_read(bm, bm_isr_enable)
124577 +#define bm_err_isr_enable_write(bm, v) \
124578 + __bm_err_isr_write(bm, bm_isr_enable, v)
124579 +#define bm_err_isr_disable_read(bm) \
124580 + __bm_err_isr_read(bm, bm_isr_disable)
124581 +#define bm_err_isr_disable_write(bm, v) \
124582 + __bm_err_isr_write(bm, bm_isr_disable, v)
124583 +#define bm_err_isr_inhibit(bm) \
124584 + __bm_err_isr_write(bm, bm_isr_inhibit, 1)
124585 +#define bm_err_isr_uninhibit(bm) \
124586 + __bm_err_isr_write(bm, bm_isr_inhibit, 0)
124587 +
124588 +/*
124589 + * TODO: unimplemented registers
124590 + *
124591 + * BMAN_POOLk_SDCNT, BMAN_POOLk_HDCNT, BMAN_FULT,
124592 + * BMAN_VLDPL, BMAN_EECC, BMAN_SBET, BMAN_EINJ
124593 + */
124594 +
124595 +/* Encapsulate "struct bman *" as a cast of the register space address. */
124596 +
124597 +static struct bman *bm_create(void *regs)
124598 +{
124599 + return (struct bman *)regs;
124600 +}
124601 +
124602 +static inline u32 __bm_in(struct bman *bm, u32 offset)
124603 +{
124604 + return in_be32((void *)bm + offset);
124605 +}
124606 +static inline void __bm_out(struct bman *bm, u32 offset, u32 val)
124607 +{
124608 + out_be32((void *)bm + offset, val);
124609 +}
124610 +#define bm_in(reg) __bm_in(bm, REG_##reg)
124611 +#define bm_out(reg, val) __bm_out(bm, REG_##reg, val)
124612 +
124613 +static u32 __bm_err_isr_read(struct bman *bm, enum bm_isr_reg n)
124614 +{
124615 + return __bm_in(bm, REG_ERR_ISR + (n << 2));
124616 +}
124617 +
124618 +static void __bm_err_isr_write(struct bman *bm, enum bm_isr_reg n, u32 val)
124619 +{
124620 + __bm_out(bm, REG_ERR_ISR + (n << 2), val);
124621 +}
124622 +
124623 +static void bm_get_version(struct bman *bm, u16 *id, u8 *major, u8 *minor)
124624 +{
124625 + u32 v = bm_in(IP_REV_1);
124626 + *id = (v >> 16);
124627 + *major = (v >> 8) & 0xff;
124628 + *minor = v & 0xff;
124629 +}
124630 +
124631 +static u32 __generate_thresh(u32 val, int roundup)
124632 +{
124633 + u32 e = 0; /* co-efficient, exponent */
124634 + int oddbit = 0;
124635 + while (val > 0xff) {
124636 + oddbit = val & 1;
124637 + val >>= 1;
124638 + e++;
124639 + if (roundup && oddbit)
124640 + val++;
124641 + }
124642 + DPA_ASSERT(e < 0x10);
124643 + return val | (e << 8);
124644 +}
124645 +
124646 +static void bm_set_pool(struct bman *bm, u8 pool, u32 swdet, u32 swdxt,
124647 + u32 hwdet, u32 hwdxt)
124648 +{
124649 + DPA_ASSERT(pool < bman_pool_max);
124650 + bm_out(POOL_SWDET(pool), __generate_thresh(swdet, 0));
124651 + bm_out(POOL_SWDXT(pool), __generate_thresh(swdxt, 1));
124652 + bm_out(POOL_HWDET(pool), __generate_thresh(hwdet, 0));
124653 + bm_out(POOL_HWDXT(pool), __generate_thresh(hwdxt, 1));
124654 +}
124655 +
124656 +static void bm_set_memory(struct bman *bm, u64 ba, int prio, u32 size)
124657 +{
124658 + u32 exp = ilog2(size);
124659 + /* choke if size isn't within range */
124660 + DPA_ASSERT((size >= 4096) && (size <= 1073741824) &&
124661 + is_power_of_2(size));
124662 + /* choke if '[e]ba' has lower-alignment than 'size' */
124663 + DPA_ASSERT(!(ba & (size - 1)));
124664 + bm_out(FBPR_BARE, upper_32_bits(ba));
124665 + bm_out(FBPR_BAR, lower_32_bits(ba));
124666 + bm_out(FBPR_AR, (prio ? 0x40000000 : 0) | (exp - 1));
124667 +}
124668 +
124669 +/*****************/
124670 +/* Config driver */
124671 +/*****************/
124672 +
124673 +/* TODO: Kconfig these? */
124674 +#define DEFAULT_FBPR_SZ (PAGE_SIZE << 12)
124675 +
124676 +/* We support only one of these. */
124677 +static struct bman *bm;
124678 +static struct device_node *bm_node;
124679 +
124680 +/* And this state belongs to 'bm'. It is set during fsl_bman_init(), but used
124681 + * during bman_init_ccsr(). */
124682 +static dma_addr_t fbpr_a;
124683 +static size_t fbpr_sz = DEFAULT_FBPR_SZ;
124684 +
124685 +static int bman_fbpr(struct reserved_mem *rmem)
124686 +{
124687 + fbpr_a = rmem->base;
124688 + fbpr_sz = rmem->size;
124689 +
124690 + WARN_ON(!(fbpr_a && fbpr_sz));
124691 +
124692 + return 0;
124693 +}
124694 +RESERVEDMEM_OF_DECLARE(bman_fbpr, "fsl,bman-fbpr", bman_fbpr);
124695 +
124696 +static int __init fsl_bman_init(struct device_node *node)
124697 +{
124698 + struct resource res;
124699 + u32 __iomem *regs;
124700 + const char *s;
124701 + int ret, standby = 0;
124702 + u16 id;
124703 + u8 major, minor;
124704 +
124705 + ret = of_address_to_resource(node, 0, &res);
124706 + if (ret) {
124707 + pr_err("Can't get %s property 'reg'\n",
124708 + node->full_name);
124709 + return ret;
124710 + }
124711 + s = of_get_property(node, "fsl,hv-claimable", &ret);
124712 + if (s && !strcmp(s, "standby"))
124713 + standby = 1;
124714 + /* Global configuration */
124715 + regs = ioremap(res.start, res.end - res.start + 1);
124716 + bm = bm_create(regs);
124717 + BUG_ON(!bm);
124718 + bm_node = node;
124719 + bm_get_version(bm, &id, &major, &minor);
124720 + pr_info("Bman ver:%04x,%02x,%02x\n", id, major, minor);
124721 + if ((major == 1) && (minor == 0)) {
124722 + bman_ip_rev = BMAN_REV10;
124723 + bman_pool_max = 64;
124724 + } else if ((major == 2) && (minor == 0)) {
124725 + bman_ip_rev = BMAN_REV20;
124726 + bman_pool_max = 8;
124727 + } else if ((major == 2) && (minor == 1)) {
124728 + bman_ip_rev = BMAN_REV21;
124729 + bman_pool_max = 64;
124730 + } else {
124731 + pr_warn("unknown Bman version, default to rev1.0\n");
124732 + }
124733 +
124734 + if (standby) {
124735 + pr_info(" -> in standby mode\n");
124736 + return 0;
124737 + }
124738 + return 0;
124739 +}
124740 +
124741 +int bman_have_ccsr(void)
124742 +{
124743 + return bm ? 1 : 0;
124744 +}
124745 +
124746 +int bm_pool_set(u32 bpid, const u32 *thresholds)
124747 +{
124748 + if (!bm)
124749 + return -ENODEV;
124750 + bm_set_pool(bm, bpid, thresholds[0],
124751 + thresholds[1], thresholds[2],
124752 + thresholds[3]);
124753 + return 0;
124754 +}
124755 +EXPORT_SYMBOL(bm_pool_set);
124756 +
124757 +__init int bman_init_early(void)
124758 +{
124759 + struct device_node *dn;
124760 + int ret;
124761 +
124762 + for_each_compatible_node(dn, NULL, "fsl,bman") {
124763 + if (bm)
124764 + pr_err("%s: only one 'fsl,bman' allowed\n",
124765 + dn->full_name);
124766 + else {
124767 + if (!of_device_is_available(dn))
124768 + continue;
124769 +
124770 + ret = fsl_bman_init(dn);
124771 + BUG_ON(ret);
124772 + }
124773 + }
124774 + return 0;
124775 +}
124776 +postcore_initcall_sync(bman_init_early);
124777 +
124778 +
124779 +static void log_edata_bits(u32 bit_count)
124780 +{
124781 + u32 i, j, mask = 0xffffffff;
124782 +
124783 + pr_warn("Bman ErrInt, EDATA:\n");
124784 + i = bit_count/32;
124785 + if (bit_count%32) {
124786 + i++;
124787 + mask = ~(mask << bit_count%32);
124788 + }
124789 + j = 16-i;
124790 + pr_warn(" 0x%08x\n", bm_in(EDATA(j)) & mask);
124791 + j++;
124792 + for (; j < 16; j++)
124793 + pr_warn(" 0x%08x\n", bm_in(EDATA(j)));
124794 +}
124795 +
124796 +static void log_additional_error_info(u32 isr_val, u32 ecsr_val)
124797 +{
124798 + union bman_ecir ecir_val;
124799 + union bman_eadr eadr_val;
124800 +
124801 + ecir_val.ecir_raw = bm_in(ECIR);
124802 + /* Is portal info valid */
124803 + if (ecsr_val & PORTAL_ECSR_ERR) {
124804 + pr_warn("Bman ErrInt: SWP id %d, numb %d, pid %d\n",
124805 + ecir_val.info.portal_num, ecir_val.info.numb,
124806 + ecir_val.info.pid);
124807 + }
124808 + if (ecsr_val & (BM_EIRQ_SBEI|BM_EIRQ_MBEI)) {
124809 + eadr_val.eadr_raw = bm_in(EADR);
124810 + pr_warn("Bman ErrInt: EADR Memory: %s, 0x%x\n",
124811 + error_mdata[eadr_val.info.memid].txt,
124812 + error_mdata[eadr_val.info.memid].addr_mask
124813 + & eadr_val.info.eadr);
124814 + log_edata_bits(error_mdata[eadr_val.info.memid].bits);
124815 + }
124816 +}
124817 +
124818 +/* Bman interrupt handler */
124819 +static irqreturn_t bman_isr(int irq, void *ptr)
124820 +{
124821 + u32 isr_val, ier_val, ecsr_val, isr_mask, i;
124822 +
124823 + ier_val = bm_err_isr_enable_read(bm);
124824 + isr_val = bm_err_isr_status_read(bm);
124825 + ecsr_val = bm_in(ECSR);
124826 + isr_mask = isr_val & ier_val;
124827 +
124828 + if (!isr_mask)
124829 + return IRQ_NONE;
124830 + for (i = 0; i < BMAN_HWE_COUNT; i++) {
124831 + if (bman_hwerr_txts[i].mask & isr_mask) {
124832 + pr_warn("Bman ErrInt: %s\n", bman_hwerr_txts[i].txt);
124833 + if (bman_hwerr_txts[i].mask & ecsr_val) {
124834 + log_additional_error_info(isr_mask, ecsr_val);
124835 + /* Re-arm error capture registers */
124836 + bm_out(ECSR, ecsr_val);
124837 + }
124838 + if (bman_hwerr_txts[i].mask & BMAN_ERRS_TO_UNENABLE) {
124839 + pr_devel("Bman un-enabling error 0x%x\n",
124840 + bman_hwerr_txts[i].mask);
124841 + ier_val &= ~bman_hwerr_txts[i].mask;
124842 + bm_err_isr_enable_write(bm, ier_val);
124843 + }
124844 + }
124845 + }
124846 + bm_err_isr_status_clear(bm, isr_val);
124847 + return IRQ_HANDLED;
124848 +}
124849 +
124850 +static int __bind_irq(void)
124851 +{
124852 + int ret, err_irq;
124853 +
124854 + err_irq = of_irq_to_resource(bm_node, 0, NULL);
124855 + if (err_irq == 0) {
124856 + pr_info("Can't get %s property '%s'\n", bm_node->full_name,
124857 + "interrupts");
124858 + return -ENODEV;
124859 + }
124860 + ret = request_irq(err_irq, bman_isr, IRQF_SHARED, "bman-err", bm_node);
124861 + if (ret) {
124862 + pr_err("request_irq() failed %d for '%s'\n", ret,
124863 + bm_node->full_name);
124864 + return -ENODEV;
124865 + }
124866 + /* Disable Buffer Pool State Change */
124867 + bm_err_isr_disable_write(bm, BM_EIRQ_BSCN);
124868 + /* Write-to-clear any stale bits, (eg. starvation being asserted prior
124869 + * to resource allocation during driver init). */
124870 + bm_err_isr_status_clear(bm, 0xffffffff);
124871 + /* Enable Error Interrupts */
124872 + bm_err_isr_enable_write(bm, 0xffffffff);
124873 + return 0;
124874 +}
124875 +
124876 +int bman_init_ccsr(struct device_node *node)
124877 +{
124878 + int ret;
124879 + if (!bman_have_ccsr())
124880 + return 0;
124881 + if (node != bm_node)
124882 + return -EINVAL;
124883 + /* FBPR memory */
124884 + bm_set_memory(bm, fbpr_a, 0, fbpr_sz);
124885 + pr_info("bman-fbpr addr %pad size 0x%zx\n", &fbpr_a, fbpr_sz);
124886 +
124887 + ret = __bind_irq();
124888 + if (ret)
124889 + return ret;
124890 + return 0;
124891 +}
124892 +
124893 +u32 bm_pool_free_buffers(u32 bpid)
124894 +{
124895 + return bm_in(POOL_CONTENT(bpid));
124896 +}
124897 +
124898 +#ifdef CONFIG_SYSFS
124899 +
124900 +#define DRV_NAME "fsl-bman"
124901 +#define SBEC_MAX_ID 1
124902 +#define SBEC_MIN_ID 0
124903 +
124904 +static ssize_t show_fbpr_fpc(struct device *dev,
124905 + struct device_attribute *dev_attr, char *buf)
124906 +{
124907 + return snprintf(buf, PAGE_SIZE, "%u\n", bm_in(FBPR_FPC));
124908 +};
124909 +
124910 +static ssize_t show_pool_count(struct device *dev,
124911 + struct device_attribute *dev_attr, char *buf)
124912 +{
124913 + u32 data;
124914 + int i;
124915 +
124916 + if (!sscanf(dev_attr->attr.name, "%d", &i) || (i >= bman_pool_max))
124917 + return -EINVAL;
124918 + data = bm_in(POOL_CONTENT(i));
124919 + return snprintf(buf, PAGE_SIZE, "%d\n", data);
124920 +};
124921 +
124922 +static ssize_t show_err_isr(struct device *dev,
124923 + struct device_attribute *dev_attr, char *buf)
124924 +{
124925 + return snprintf(buf, PAGE_SIZE, "0x%08x\n", bm_in(ERR_ISR));
124926 +};
124927 +
124928 +static ssize_t show_sbec(struct device *dev,
124929 + struct device_attribute *dev_attr, char *buf)
124930 +{
124931 + int i;
124932 +
124933 + if (!sscanf(dev_attr->attr.name, "sbec_%d", &i))
124934 + return -EINVAL;
124935 + if (i < SBEC_MIN_ID || i > SBEC_MAX_ID)
124936 + return -EINVAL;
124937 + return snprintf(buf, PAGE_SIZE, "%u\n", bm_in(SBEC(i)));
124938 +};
124939 +
124940 +static DEVICE_ATTR(err_isr, S_IRUSR, show_err_isr, NULL);
124941 +static DEVICE_ATTR(fbpr_fpc, S_IRUSR, show_fbpr_fpc, NULL);
124942 +
124943 +/* Didn't use DEVICE_ATTR as 64 of this would be required.
124944 + * Initialize them when needed. */
124945 +static char *name_attrs_pool_count; /* "xx" + null-terminator */
124946 +static struct device_attribute *dev_attr_buffer_pool_count;
124947 +
124948 +static DEVICE_ATTR(sbec_0, S_IRUSR, show_sbec, NULL);
124949 +static DEVICE_ATTR(sbec_1, S_IRUSR, show_sbec, NULL);
124950 +
124951 +static struct attribute *bman_dev_attributes[] = {
124952 + &dev_attr_fbpr_fpc.attr,
124953 + &dev_attr_err_isr.attr,
124954 + NULL
124955 +};
124956 +
124957 +static struct attribute *bman_dev_ecr_attributes[] = {
124958 + &dev_attr_sbec_0.attr,
124959 + &dev_attr_sbec_1.attr,
124960 + NULL
124961 +};
124962 +
124963 +static struct attribute **bman_dev_pool_count_attributes;
124964 +
124965 +
124966 +/* root level */
124967 +static const struct attribute_group bman_dev_attr_grp = {
124968 + .name = NULL,
124969 + .attrs = bman_dev_attributes
124970 +};
124971 +static const struct attribute_group bman_dev_ecr_grp = {
124972 + .name = "error_capture",
124973 + .attrs = bman_dev_ecr_attributes
124974 +};
124975 +static struct attribute_group bman_dev_pool_countent_grp = {
124976 + .name = "pool_count",
124977 +};
124978 +
124979 +static int of_fsl_bman_remove(struct platform_device *ofdev)
124980 +{
124981 + sysfs_remove_group(&ofdev->dev.kobj, &bman_dev_attr_grp);
124982 + return 0;
124983 +};
124984 +
124985 +static int of_fsl_bman_probe(struct platform_device *ofdev)
124986 +{
124987 + int ret, i;
124988 +
124989 + ret = sysfs_create_group(&ofdev->dev.kobj, &bman_dev_attr_grp);
124990 + if (ret)
124991 + goto done;
124992 + ret = sysfs_create_group(&ofdev->dev.kobj, &bman_dev_ecr_grp);
124993 + if (ret)
124994 + goto del_group_0;
124995 +
124996 + name_attrs_pool_count = kmalloc(sizeof(char) * bman_pool_max * 3,
124997 + GFP_KERNEL);
124998 + if (!name_attrs_pool_count) {
124999 + pr_err("Can't alloc name_attrs_pool_count\n");
125000 + goto del_group_1;
125001 + }
125002 +
125003 + dev_attr_buffer_pool_count = kmalloc(sizeof(struct device_attribute) *
125004 + bman_pool_max, GFP_KERNEL);
125005 + if (!dev_attr_buffer_pool_count) {
125006 + pr_err("Can't alloc dev_attr-buffer_pool_count\n");
125007 + goto del_group_2;
125008 + }
125009 +
125010 + bman_dev_pool_count_attributes = kmalloc(sizeof(struct attribute *) *
125011 + (bman_pool_max + 1), GFP_KERNEL);
125012 + if (!bman_dev_pool_count_attributes) {
125013 + pr_err("can't alloc bman_dev_pool_count_attributes\n");
125014 + goto del_group_3;
125015 + }
125016 +
125017 + for (i = 0; i < bman_pool_max; i++) {
125018 + ret = scnprintf((name_attrs_pool_count + i * 3), 3, "%d", i);
125019 + if (!ret)
125020 + goto del_group_4;
125021 + dev_attr_buffer_pool_count[i].attr.name =
125022 + (name_attrs_pool_count + i * 3);
125023 + dev_attr_buffer_pool_count[i].attr.mode = S_IRUSR;
125024 + dev_attr_buffer_pool_count[i].show = show_pool_count;
125025 + bman_dev_pool_count_attributes[i] =
125026 + &dev_attr_buffer_pool_count[i].attr;
125027 + sysfs_attr_init(bman_dev_pool_count_attributes[i]);
125028 + }
125029 + bman_dev_pool_count_attributes[bman_pool_max] = NULL;
125030 +
125031 + bman_dev_pool_countent_grp.attrs = bman_dev_pool_count_attributes;
125032 +
125033 + ret = sysfs_create_group(&ofdev->dev.kobj, &bman_dev_pool_countent_grp);
125034 + if (ret)
125035 + goto del_group_4;
125036 +
125037 + goto done;
125038 +
125039 +del_group_4:
125040 + kfree(bman_dev_pool_count_attributes);
125041 +del_group_3:
125042 + kfree(dev_attr_buffer_pool_count);
125043 +del_group_2:
125044 + kfree(name_attrs_pool_count);
125045 +del_group_1:
125046 + sysfs_remove_group(&ofdev->dev.kobj, &bman_dev_ecr_grp);
125047 +del_group_0:
125048 + sysfs_remove_group(&ofdev->dev.kobj, &bman_dev_attr_grp);
125049 +done:
125050 + if (ret)
125051 + dev_err(&ofdev->dev,
125052 + "Cannot create dev attributes ret=%d\n", ret);
125053 + return ret;
125054 +};
125055 +
125056 +static struct of_device_id of_fsl_bman_ids[] = {
125057 + {
125058 + .compatible = "fsl,bman",
125059 + },
125060 + {}
125061 +};
125062 +MODULE_DEVICE_TABLE(of, of_fsl_bman_ids);
125063 +
125064 +#ifdef CONFIG_SUSPEND
125065 +static u32 saved_isdr;
125066 +
125067 +static int bman_pm_suspend_noirq(struct device *dev)
125068 +{
125069 + uint32_t idle_state;
125070 +
125071 + suspend_unused_bportal();
125072 + /* save isdr, disable all, clear isr */
125073 + saved_isdr = bm_err_isr_disable_read(bm);
125074 + bm_err_isr_disable_write(bm, 0xffffffff);
125075 + bm_err_isr_status_clear(bm, 0xffffffff);
125076 +
125077 + if (bman_ip_rev < BMAN_REV21) {
125078 +#ifdef CONFIG_PM_DEBUG
125079 + pr_info("Bman version doesn't have STATE_IDLE\n");
125080 +#endif
125081 + return 0;
125082 + }
125083 + idle_state = bm_in(STATE_IDLE);
125084 + if (!(idle_state & 0x1)) {
125085 + pr_err("Bman not idle 0x%x aborting\n", idle_state);
125086 + bm_err_isr_disable_write(bm, saved_isdr);
125087 + resume_unused_bportal();
125088 + return -EBUSY;
125089 + }
125090 +#ifdef CONFIG_PM_DEBUG
125091 + pr_info("Bman suspend code, IDLE_STAT = 0x%x\n", idle_state);
125092 +#endif
125093 + return 0;
125094 +}
125095 +
125096 +static int bman_pm_resume_noirq(struct device *dev)
125097 +{
125098 + /* restore isdr */
125099 + bm_err_isr_disable_write(bm, saved_isdr);
125100 + resume_unused_bportal();
125101 + return 0;
125102 +}
125103 +#else
125104 +#define bman_pm_suspend_noirq NULL
125105 +#define bman_pm_resume_noirq NULL
125106 +#endif
125107 +
125108 +static const struct dev_pm_ops bman_pm_ops = {
125109 + .suspend_noirq = bman_pm_suspend_noirq,
125110 + .resume_noirq = bman_pm_resume_noirq,
125111 +};
125112 +
125113 +static struct platform_driver of_fsl_bman_driver = {
125114 + .driver = {
125115 + .owner = THIS_MODULE,
125116 + .name = DRV_NAME,
125117 + .of_match_table = of_fsl_bman_ids,
125118 + .pm = &bman_pm_ops,
125119 + },
125120 + .probe = of_fsl_bman_probe,
125121 + .remove = of_fsl_bman_remove,
125122 +};
125123 +
125124 +static int bman_ctrl_init(void)
125125 +{
125126 + return platform_driver_register(&of_fsl_bman_driver);
125127 +}
125128 +
125129 +static void bman_ctrl_exit(void)
125130 +{
125131 + platform_driver_unregister(&of_fsl_bman_driver);
125132 +}
125133 +
125134 +module_init(bman_ctrl_init);
125135 +module_exit(bman_ctrl_exit);
125136 +
125137 +#endif /* CONFIG_SYSFS */
125138 --- /dev/null
125139 +++ b/drivers/staging/fsl_qbman/bman_debugfs.c
125140 @@ -0,0 +1,119 @@
125141 +/* Copyright 2010-2011 Freescale Semiconductor, Inc.
125142 + *
125143 + * Redistribution and use in source and binary forms, with or without
125144 + * modification, are permitted provided that the following conditions are met:
125145 + * * Redistributions of source code must retain the above copyright
125146 + * notice, this list of conditions and the following disclaimer.
125147 + * * Redistributions in binary form must reproduce the above copyright
125148 + * notice, this list of conditions and the following disclaimer in the
125149 + * documentation and/or other materials provided with the distribution.
125150 + * * Neither the name of Freescale Semiconductor nor the
125151 + * names of its contributors may be used to endorse or promote products
125152 + * derived from this software without specific prior written permission.
125153 + *
125154 + *
125155 + * ALTERNATIVELY, this software may be distributed under the terms of the
125156 + * GNU General Public License ("GPL") as published by the Free Software
125157 + * Foundation, either version 2 of that License or (at your option) any
125158 + * later version.
125159 + *
125160 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
125161 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
125162 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
125163 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
125164 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
125165 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
125166 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
125167 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
125168 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
125169 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
125170 + */
125171 +#include <linux/module.h>
125172 +#include <linux/fsl_bman.h>
125173 +#include <linux/debugfs.h>
125174 +#include <linux/seq_file.h>
125175 +#include <linux/uaccess.h>
125176 +
125177 +static struct dentry *dfs_root; /* debugfs root directory */
125178 +
125179 +/*******************************************************************************
125180 + * Query Buffer Pool State
125181 + ******************************************************************************/
125182 +static int query_bp_state_show(struct seq_file *file, void *offset)
125183 +{
125184 + int ret;
125185 + struct bm_pool_state state;
125186 + int i, j;
125187 + u32 mask;
125188 +
125189 + memset(&state, 0, sizeof(struct bm_pool_state));
125190 + ret = bman_query_pools(&state);
125191 + if (ret) {
125192 + seq_printf(file, "Error %d\n", ret);
125193 + return 0;
125194 + }
125195 + seq_puts(file, "bp_id free_buffers_avail bp_depleted\n");
125196 + for (i = 0; i < 2; i++) {
125197 + mask = 0x80000000;
125198 + for (j = 0; j < 32; j++) {
125199 + seq_printf(file,
125200 + " %-2u %-3s %-3s\n",
125201 + (i*32)+j,
125202 + (state.as.state.__state[i] & mask) ? "no" : "yes",
125203 + (state.ds.state.__state[i] & mask) ? "yes" : "no");
125204 + mask >>= 1;
125205 + }
125206 + }
125207 + return 0;
125208 +}
125209 +
125210 +static int query_bp_state_open(struct inode *inode, struct file *file)
125211 +{
125212 + return single_open(file, query_bp_state_show, NULL);
125213 +}
125214 +
125215 +static const struct file_operations query_bp_state_fops = {
125216 + .owner = THIS_MODULE,
125217 + .open = query_bp_state_open,
125218 + .read = seq_read,
125219 + .release = single_release,
125220 +};
125221 +
125222 +static int __init bman_debugfs_module_init(void)
125223 +{
125224 + int ret = 0;
125225 + struct dentry *d;
125226 +
125227 + dfs_root = debugfs_create_dir("bman", NULL);
125228 +
125229 + if (dfs_root == NULL) {
125230 + ret = -ENOMEM;
125231 + pr_err("Cannot create bman debugfs dir\n");
125232 + goto _return;
125233 + }
125234 + d = debugfs_create_file("query_bp_state",
125235 + S_IRUGO,
125236 + dfs_root,
125237 + NULL,
125238 + &query_bp_state_fops);
125239 + if (d == NULL) {
125240 + ret = -ENOMEM;
125241 + pr_err("Cannot create query_bp_state\n");
125242 + goto _return;
125243 + }
125244 + return 0;
125245 +
125246 +_return:
125247 + debugfs_remove_recursive(dfs_root);
125248 + return ret;
125249 +}
125250 +
125251 +static void __exit bman_debugfs_module_exit(void)
125252 +{
125253 + debugfs_remove_recursive(dfs_root);
125254 +}
125255 +
125256 +
125257 +module_init(bman_debugfs_module_init);
125258 +module_exit(bman_debugfs_module_exit);
125259 +MODULE_LICENSE("Dual BSD/GPL");
125260 --- /dev/null
125261 +++ b/drivers/staging/fsl_qbman/bman_driver.c
125262 @@ -0,0 +1,575 @@
125263 +/* Copyright 2008-2012 Freescale Semiconductor, Inc.
125264 + *
125265 + * Redistribution and use in source and binary forms, with or without
125266 + * modification, are permitted provided that the following conditions are met:
125267 + * * Redistributions of source code must retain the above copyright
125268 + * notice, this list of conditions and the following disclaimer.
125269 + * * Redistributions in binary form must reproduce the above copyright
125270 + * notice, this list of conditions and the following disclaimer in the
125271 + * documentation and/or other materials provided with the distribution.
125272 + * * Neither the name of Freescale Semiconductor nor the
125273 + * names of its contributors may be used to endorse or promote products
125274 + * derived from this software without specific prior written permission.
125275 + *
125276 + *
125277 + * ALTERNATIVELY, this software may be distributed under the terms of the
125278 + * GNU General Public License ("GPL") as published by the Free Software
125279 + * Foundation, either version 2 of that License or (at your option) any
125280 + * later version.
125281 + *
125282 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
125283 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
125284 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
125285 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
125286 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
125287 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
125288 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
125289 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
125290 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
125291 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
125292 + */
125293 +#include "bman_low.h"
125294 +#ifdef CONFIG_HOTPLUG_CPU
125295 +#include <linux/cpu.h>
125296 +#endif
125297 +/*
125298 + * Global variables of the max portal/pool number this bman version supported
125299 + */
125300 +u16 bman_ip_rev;
125301 +EXPORT_SYMBOL(bman_ip_rev);
125302 +u16 bman_pool_max;
125303 +EXPORT_SYMBOL(bman_pool_max);
125304 +static u16 bman_portal_max;
125305 +
125306 +/* After initialising cpus that own shared portal configs, we cache the
125307 + * resulting portals (ie. not just the configs) in this array. Then we
125308 + * initialise slave cpus that don't have their own portals, redirecting them to
125309 + * portals from this cache in a round-robin assignment. */
125310 +static struct bman_portal *shared_portals[NR_CPUS];
125311 +static int num_shared_portals;
125312 +static int shared_portals_idx;
125313 +static LIST_HEAD(unused_pcfgs);
125314 +static DEFINE_SPINLOCK(unused_pcfgs_lock);
125315 +static void *affine_bportals[NR_CPUS];
125316 +
125317 +static int __init fsl_bpool_init(struct device_node *node)
125318 +{
125319 + int ret;
125320 + u32 *thresh, *bpid = (u32 *)of_get_property(node, "fsl,bpid", &ret);
125321 + if (!bpid || (ret != 4)) {
125322 + pr_err("Can't get %s property 'fsl,bpid'\n", node->full_name);
125323 + return -ENODEV;
125324 + }
125325 + thresh = (u32 *)of_get_property(node, "fsl,bpool-thresholds", &ret);
125326 + if (thresh) {
125327 + if (ret != 16) {
125328 + pr_err("Invalid %s property '%s'\n",
125329 + node->full_name, "fsl,bpool-thresholds");
125330 + return -ENODEV;
125331 + }
125332 + }
125333 + if (thresh) {
125334 +#ifdef CONFIG_FSL_BMAN_CONFIG
125335 + ret = bm_pool_set(be32_to_cpu(*bpid), thresh);
125336 + if (ret)
125337 + pr_err("No CCSR node for %s property '%s'\n",
125338 + node->full_name, "fsl,bpool-thresholds");
125339 + return ret;
125340 +#else
125341 + pr_err("Ignoring %s property '%s', no CCSR support\n",
125342 + node->full_name, "fsl,bpool-thresholds");
125343 +#endif
125344 + }
125345 + return 0;
125346 +}
125347 +
125348 +static int __init fsl_bpid_range_init(struct device_node *node)
125349 +{
125350 + int ret;
125351 + u32 *range = (u32 *)of_get_property(node, "fsl,bpid-range", &ret);
125352 + if (!range) {
125353 + pr_err("No 'fsl,bpid-range' property in node %s\n",
125354 + node->full_name);
125355 + return -EINVAL;
125356 + }
125357 + if (ret != 8) {
125358 + pr_err("'fsl,bpid-range' is not a 2-cell range in node %s\n",
125359 + node->full_name);
125360 + return -EINVAL;
125361 + }
125362 + bman_seed_bpid_range(be32_to_cpu(range[0]), be32_to_cpu(range[1]));
125363 + pr_info("Bman: BPID allocator includes range %d:%d\n",
125364 + be32_to_cpu(range[0]), be32_to_cpu(range[1]));
125365 + return 0;
125366 +}
125367 +
125368 +static struct bm_portal_config * __init parse_pcfg(struct device_node *node)
125369 +{
125370 + struct bm_portal_config *pcfg;
125371 + const u32 *index;
125372 + int irq, ret;
125373 + resource_size_t len;
125374 +
125375 + pcfg = kmalloc(sizeof(*pcfg), GFP_KERNEL);
125376 + if (!pcfg) {
125377 + pr_err("can't allocate portal config");
125378 + return NULL;
125379 + }
125380 +
125381 + if (of_device_is_compatible(node, "fsl,bman-portal-1.0") ||
125382 + of_device_is_compatible(node, "fsl,bman-portal-1.0.0")) {
125383 + bman_ip_rev = BMAN_REV10;
125384 + bman_pool_max = 64;
125385 + bman_portal_max = 10;
125386 + } else if (of_device_is_compatible(node, "fsl,bman-portal-2.0") ||
125387 + of_device_is_compatible(node, "fsl,bman-portal-2.0.8")) {
125388 + bman_ip_rev = BMAN_REV20;
125389 + bman_pool_max = 8;
125390 + bman_portal_max = 3;
125391 + } else if (of_device_is_compatible(node, "fsl,bman-portal-2.1.0")) {
125392 + bman_ip_rev = BMAN_REV21;
125393 + bman_pool_max = 64;
125394 + bman_portal_max = 50;
125395 + } else if (of_device_is_compatible(node, "fsl,bman-portal-2.1.1")) {
125396 + bman_ip_rev = BMAN_REV21;
125397 + bman_pool_max = 64;
125398 + bman_portal_max = 25;
125399 + } else if (of_device_is_compatible(node, "fsl,bman-portal-2.1.2")) {
125400 + bman_ip_rev = BMAN_REV21;
125401 + bman_pool_max = 64;
125402 + bman_portal_max = 18;
125403 + } else if (of_device_is_compatible(node, "fsl,bman-portal-2.1.3")) {
125404 + bman_ip_rev = BMAN_REV21;
125405 + bman_pool_max = 64;
125406 + bman_portal_max = 10;
125407 + } else {
125408 + pr_warn("unknown BMan version in portal node,"
125409 + "default to rev1.0\n");
125410 + bman_ip_rev = BMAN_REV10;
125411 + bman_pool_max = 64;
125412 + bman_portal_max = 10;
125413 + }
125414 +
125415 + ret = of_address_to_resource(node, DPA_PORTAL_CE,
125416 + &pcfg->addr_phys[DPA_PORTAL_CE]);
125417 + if (ret) {
125418 + pr_err("Can't get %s property 'reg::CE'\n", node->full_name);
125419 + goto err;
125420 + }
125421 + ret = of_address_to_resource(node, DPA_PORTAL_CI,
125422 + &pcfg->addr_phys[DPA_PORTAL_CI]);
125423 + if (ret) {
125424 + pr_err("Can't get %s property 'reg::CI'\n", node->full_name);
125425 + goto err;
125426 + }
125427 +
125428 + index = of_get_property(node, "cell-index", &ret);
125429 + if (!index || (ret != 4)) {
125430 + pr_err("Can't get %s property '%s'\n", node->full_name,
125431 + "cell-index");
125432 + goto err;
125433 + }
125434 + if (be32_to_cpu(*index) >= bman_portal_max) {
125435 + pr_err("BMan portal cell index %d out of range, max %d\n",
125436 + be32_to_cpu(*index), bman_portal_max);
125437 + goto err;
125438 + }
125439 +
125440 + pcfg->public_cfg.cpu = -1;
125441 +
125442 + irq = irq_of_parse_and_map(node, 0);
125443 + if (irq == 0) {
125444 + pr_err("Can't get %s property 'interrupts'\n", node->full_name);
125445 + goto err;
125446 + }
125447 + pcfg->public_cfg.irq = irq;
125448 + pcfg->public_cfg.index = be32_to_cpu(*index);
125449 + bman_depletion_fill(&pcfg->public_cfg.mask);
125450 +
125451 + len = resource_size(&pcfg->addr_phys[DPA_PORTAL_CE]);
125452 + if (len != (unsigned long)len)
125453 + goto err;
125454 +
125455 +#if defined(CONFIG_ARM) || defined(CONFIG_ARM64)
125456 + pcfg->addr_virt[DPA_PORTAL_CE] = ioremap_cache_ns(
125457 + pcfg->addr_phys[DPA_PORTAL_CE].start,
125458 + resource_size(&pcfg->addr_phys[DPA_PORTAL_CE]));
125459 + pcfg->addr_virt[DPA_PORTAL_CI] = ioremap(
125460 + pcfg->addr_phys[DPA_PORTAL_CI].start,
125461 + resource_size(&pcfg->addr_phys[DPA_PORTAL_CI]));
125462 +
125463 +#else
125464 + pcfg->addr_virt[DPA_PORTAL_CE] = ioremap_prot(
125465 + pcfg->addr_phys[DPA_PORTAL_CE].start,
125466 + (unsigned long)len,
125467 + 0);
125468 + pcfg->addr_virt[DPA_PORTAL_CI] = ioremap_prot(
125469 + pcfg->addr_phys[DPA_PORTAL_CI].start,
125470 + resource_size(&pcfg->addr_phys[DPA_PORTAL_CI]),
125471 + _PAGE_GUARDED | _PAGE_NO_CACHE);
125472 +#endif
125473 + /* disable bp depletion */
125474 + __raw_writel(0x0, pcfg->addr_virt[DPA_PORTAL_CI] + BM_REG_SCN(0));
125475 + __raw_writel(0x0, pcfg->addr_virt[DPA_PORTAL_CI] + BM_REG_SCN(1));
125476 + return pcfg;
125477 +err:
125478 + kfree(pcfg);
125479 + return NULL;
125480 +}
125481 +
125482 +static struct bm_portal_config *get_pcfg(struct list_head *list)
125483 +{
125484 + struct bm_portal_config *pcfg;
125485 + if (list_empty(list))
125486 + return NULL;
125487 + pcfg = list_entry(list->prev, struct bm_portal_config, list);
125488 + list_del(&pcfg->list);
125489 + return pcfg;
125490 +}
125491 +
125492 +static struct bm_portal_config *get_pcfg_idx(struct list_head *list,
125493 + uint32_t idx)
125494 +{
125495 + struct bm_portal_config *pcfg;
125496 + if (list_empty(list))
125497 + return NULL;
125498 + list_for_each_entry(pcfg, list, list) {
125499 + if (pcfg->public_cfg.index == idx) {
125500 + list_del(&pcfg->list);
125501 + return pcfg;
125502 + }
125503 + }
125504 + return NULL;
125505 +}
125506 +
125507 +struct bm_portal_config *bm_get_unused_portal(void)
125508 +{
125509 + return bm_get_unused_portal_idx(QBMAN_ANY_PORTAL_IDX);
125510 +}
125511 +
125512 +struct bm_portal_config *bm_get_unused_portal_idx(uint32_t idx)
125513 +{
125514 + struct bm_portal_config *ret;
125515 + spin_lock(&unused_pcfgs_lock);
125516 + if (idx == QBMAN_ANY_PORTAL_IDX)
125517 + ret = get_pcfg(&unused_pcfgs);
125518 + else
125519 + ret = get_pcfg_idx(&unused_pcfgs, idx);
125520 + spin_unlock(&unused_pcfgs_lock);
125521 + return ret;
125522 +}
125523 +
125524 +void bm_put_unused_portal(struct bm_portal_config *pcfg)
125525 +{
125526 + spin_lock(&unused_pcfgs_lock);
125527 + list_add(&pcfg->list, &unused_pcfgs);
125528 + spin_unlock(&unused_pcfgs_lock);
125529 +}
125530 +
125531 +static struct bman_portal *init_pcfg(struct bm_portal_config *pcfg)
125532 +{
125533 + struct bman_portal *p;
125534 + p = bman_create_affine_portal(pcfg);
125535 + if (p) {
125536 +#ifdef CONFIG_FSL_DPA_PIRQ_SLOW
125537 + bman_p_irqsource_add(p, BM_PIRQ_RCRI | BM_PIRQ_BSCN);
125538 +#endif
125539 + pr_info("Bman portal %sinitialised, cpu %d\n",
125540 + pcfg->public_cfg.is_shared ? "(shared) " : "",
125541 + pcfg->public_cfg.cpu);
125542 + affine_bportals[pcfg->public_cfg.cpu] = p;
125543 + } else
125544 + pr_crit("Bman portal failure on cpu %d\n",
125545 + pcfg->public_cfg.cpu);
125546 + return p;
125547 +}
125548 +
125549 +static void init_slave(int cpu)
125550 +{
125551 + struct bman_portal *p;
125552 + p = bman_create_affine_slave(shared_portals[shared_portals_idx++], cpu);
125553 + if (!p)
125554 + pr_err("Bman slave portal failure on cpu %d\n", cpu);
125555 + else
125556 + pr_info("Bman portal %sinitialised, cpu %d\n", "(slave) ", cpu);
125557 + if (shared_portals_idx >= num_shared_portals)
125558 + shared_portals_idx = 0;
125559 + affine_bportals[cpu] = p;
125560 +}
125561 +
125562 +/* Bootarg "bportals=[...]" has the same syntax as "qportals=", and so the
125563 + * parsing is in dpa_sys.h. The syntax is a comma-separated list of indexes
125564 + * and/or ranges of indexes, with each being optionally prefixed by "s" to
125565 + * explicitly mark it or them for sharing.
125566 + * Eg;
125567 + * bportals=s0,1-3,s4
125568 + * means that cpus 1,2,3 get "unshared" portals, cpus 0 and 4 get "shared"
125569 + * portals, and any remaining cpus share the portals that are assigned to cpus 0
125570 + * or 4, selected in a round-robin fashion. (In this example, cpu 5 would share
125571 + * cpu 0's portal, cpu 6 would share cpu4's portal, and cpu 7 would share cpu
125572 + * 0's portal.) */
125573 +static struct cpumask want_unshared __initdata; /* cpus requested without "s" */
125574 +static struct cpumask want_shared __initdata; /* cpus requested with "s" */
125575 +
125576 +static int __init parse_bportals(char *str)
125577 +{
125578 + return parse_portals_bootarg(str, &want_shared, &want_unshared,
125579 + "bportals");
125580 +}
125581 +__setup("bportals=", parse_bportals);
125582 +
125583 +static int bman_offline_cpu(unsigned int cpu)
125584 +{
125585 + struct bman_portal *p;
125586 + const struct bm_portal_config *pcfg;
125587 + p = (struct bman_portal *)affine_bportals[cpu];
125588 + if (p) {
125589 + pcfg = bman_get_bm_portal_config(p);
125590 + if (pcfg)
125591 + irq_set_affinity(pcfg->public_cfg.irq, cpumask_of(0));
125592 + }
125593 + return 0;
125594 +}
125595 +
125596 +#ifdef CONFIG_HOTPLUG_CPU
125597 +static int bman_online_cpu(unsigned int cpu)
125598 +{
125599 + struct bman_portal *p;
125600 + const struct bm_portal_config *pcfg;
125601 + p = (struct bman_portal *)affine_bportals[cpu];
125602 + if (p) {
125603 + pcfg = bman_get_bm_portal_config(p);
125604 + if (pcfg)
125605 + irq_set_affinity(pcfg->public_cfg.irq, cpumask_of(cpu));
125606 + }
125607 + return 0;
125608 +}
125609 +static int bman_hotplug_cpu_callback(struct notifier_block *nfb,
125610 + unsigned long action, void *hcpu)
125611 +{
125612 + unsigned int cpu = (unsigned long)hcpu;
125613 +
125614 + switch (action) {
125615 + case CPU_ONLINE:
125616 + case CPU_ONLINE_FROZEN:
125617 + bman_online_cpu(cpu);
125618 + break;
125619 + case CPU_DOWN_PREPARE:
125620 + case CPU_DOWN_PREPARE_FROZEN:
125621 + bman_offline_cpu(cpu);
125622 + default:
125623 + break;
125624 + }
125625 + return NOTIFY_OK;
125626 +}
125627 +
125628 +static struct notifier_block bman_hotplug_cpu_notifier = {
125629 + .notifier_call = bman_hotplug_cpu_callback,
125630 +};
125631 +#endif /* CONFIG_HOTPLUG_CPU */
125632 +
125633 +/* Initialise the Bman driver. The meat of this function deals with portals. The
125634 + * following describes the flow of portal-handling, the code "steps" refer to
125635 + * this description;
125636 + * 1. Portal configs are parsed from the device-tree into 'unused_pcfgs', with
125637 + * ::cpu==-1. Regions and interrupts are mapped (but interrupts are not
125638 + * bound).
125639 + * 2. The "want_shared" and "want_unshared" lists (as filled by the
125640 + * "bportals=[...]" bootarg) are processed, allocating portals and assigning
125641 + * them to cpus, placing them in the relevant list and setting ::cpu as
125642 + * appropriate. If no "bportals" bootarg was present, the defaut is to try to
125643 + * assign portals to all online cpus at the time of driver initialisation.
125644 + * Any failure to allocate portals (when parsing the "want" lists or when
125645 + * using default behaviour) will be silently tolerated (the "fixup" logic in
125646 + * step 3 will determine what happens in this case).
125647 + * 3. Do fixups relative to cpu_online_mask(). If no portals are marked for
125648 + * sharing and sharing is required (because not all cpus have been assigned
125649 + * portals), then one portal will marked for sharing. Conversely if no
125650 + * sharing is required, any portals marked for sharing will not be shared. It
125651 + * may be that sharing occurs when it wasn't expected, if portal allocation
125652 + * failed to honour all the requested assignments (including the default
125653 + * assignments if no bootarg is present).
125654 + * 4. Unshared portals are initialised on their respective cpus.
125655 + * 5. Shared portals are initialised on their respective cpus.
125656 + * 6. Each remaining cpu is initialised to slave to one of the shared portals,
125657 + * which are selected in a round-robin fashion.
125658 + * Any portal configs left unused are available for USDPAA allocation.
125659 + */
125660 +__init int bman_init(void)
125661 +{
125662 + struct cpumask slave_cpus;
125663 + struct cpumask unshared_cpus = *cpu_none_mask;
125664 + struct cpumask shared_cpus = *cpu_none_mask;
125665 + LIST_HEAD(unshared_pcfgs);
125666 + LIST_HEAD(shared_pcfgs);
125667 + struct device_node *dn;
125668 + struct bm_portal_config *pcfg;
125669 + struct bman_portal *p;
125670 + int cpu, ret;
125671 + struct cpumask offline_cpus;
125672 +
125673 + /* Initialise the Bman (CCSR) device */
125674 + for_each_compatible_node(dn, NULL, "fsl,bman") {
125675 + if (!bman_init_ccsr(dn))
125676 + pr_info("Bman err interrupt handler present\n");
125677 + else
125678 + pr_err("Bman CCSR setup failed\n");
125679 + }
125680 + /* Initialise any declared buffer pools */
125681 + for_each_compatible_node(dn, NULL, "fsl,bpool") {
125682 + ret = fsl_bpool_init(dn);
125683 + if (ret)
125684 + return ret;
125685 + }
125686 + /* Step 1. See comments at the beginning of the file. */
125687 + for_each_compatible_node(dn, NULL, "fsl,bman-portal") {
125688 + if (!of_device_is_available(dn))
125689 + continue;
125690 + pcfg = parse_pcfg(dn);
125691 + if (pcfg)
125692 + list_add_tail(&pcfg->list, &unused_pcfgs);
125693 + }
125694 + /* Step 2. */
125695 + for_each_possible_cpu(cpu) {
125696 + if (cpumask_test_cpu(cpu, &want_shared)) {
125697 + pcfg = get_pcfg(&unused_pcfgs);
125698 + if (!pcfg)
125699 + break;
125700 + pcfg->public_cfg.cpu = cpu;
125701 + list_add_tail(&pcfg->list, &shared_pcfgs);
125702 + cpumask_set_cpu(cpu, &shared_cpus);
125703 + }
125704 + if (cpumask_test_cpu(cpu, &want_unshared)) {
125705 + if (cpumask_test_cpu(cpu, &shared_cpus))
125706 + continue;
125707 + pcfg = get_pcfg(&unused_pcfgs);
125708 + if (!pcfg)
125709 + break;
125710 + pcfg->public_cfg.cpu = cpu;
125711 + list_add_tail(&pcfg->list, &unshared_pcfgs);
125712 + cpumask_set_cpu(cpu, &unshared_cpus);
125713 + }
125714 + }
125715 + if (list_empty(&shared_pcfgs) && list_empty(&unshared_pcfgs)) {
125716 + /* Default, give an unshared portal to each online cpu */
125717 + for_each_online_cpu(cpu) {
125718 + pcfg = get_pcfg(&unused_pcfgs);
125719 + if (!pcfg)
125720 + break;
125721 + pcfg->public_cfg.cpu = cpu;
125722 + list_add_tail(&pcfg->list, &unshared_pcfgs);
125723 + cpumask_set_cpu(cpu, &unshared_cpus);
125724 + }
125725 + }
125726 + /* Step 3. */
125727 + cpumask_andnot(&slave_cpus, cpu_possible_mask, &shared_cpus);
125728 + cpumask_andnot(&slave_cpus, &slave_cpus, &unshared_cpus);
125729 + if (cpumask_empty(&slave_cpus)) {
125730 + /* No sharing required */
125731 + if (!list_empty(&shared_pcfgs)) {
125732 + /* Migrate "shared" to "unshared" */
125733 + cpumask_or(&unshared_cpus, &unshared_cpus,
125734 + &shared_cpus);
125735 + cpumask_clear(&shared_cpus);
125736 + list_splice_tail(&shared_pcfgs, &unshared_pcfgs);
125737 + INIT_LIST_HEAD(&shared_pcfgs);
125738 + }
125739 + } else {
125740 + /* Sharing required */
125741 + if (list_empty(&shared_pcfgs)) {
125742 + /* Migrate one "unshared" to "shared" */
125743 + pcfg = get_pcfg(&unshared_pcfgs);
125744 + if (!pcfg) {
125745 + pr_crit("No BMan portals available!\n");
125746 + return 0;
125747 + }
125748 + cpumask_clear_cpu(pcfg->public_cfg.cpu, &unshared_cpus);
125749 + cpumask_set_cpu(pcfg->public_cfg.cpu, &shared_cpus);
125750 + list_add_tail(&pcfg->list, &shared_pcfgs);
125751 + }
125752 + }
125753 + /* Step 4. */
125754 + list_for_each_entry(pcfg, &unshared_pcfgs, list) {
125755 + pcfg->public_cfg.is_shared = 0;
125756 + p = init_pcfg(pcfg);
125757 + if (!p) {
125758 + pr_crit("Unable to initialize bman portal\n");
125759 + return 0;
125760 + }
125761 + }
125762 + /* Step 5. */
125763 + list_for_each_entry(pcfg, &shared_pcfgs, list) {
125764 + pcfg->public_cfg.is_shared = 1;
125765 + p = init_pcfg(pcfg);
125766 + if (p)
125767 + shared_portals[num_shared_portals++] = p;
125768 + }
125769 + /* Step 6. */
125770 + if (!cpumask_empty(&slave_cpus))
125771 + for_each_cpu(cpu, &slave_cpus)
125772 + init_slave(cpu);
125773 + pr_info("Bman portals initialised\n");
125774 + cpumask_andnot(&offline_cpus, cpu_possible_mask, cpu_online_mask);
125775 + for_each_cpu(cpu, &offline_cpus)
125776 + bman_offline_cpu(cpu);
125777 +#ifdef CONFIG_HOTPLUG_CPU
125778 + register_hotcpu_notifier(&bman_hotplug_cpu_notifier);
125779 +#endif
125780 + return 0;
125781 +}
125782 +
125783 +__init int bman_resource_init(void)
125784 +{
125785 + struct device_node *dn;
125786 + int ret;
125787 +
125788 + /* Initialise BPID allocation ranges */
125789 + for_each_compatible_node(dn, NULL, "fsl,bpid-range") {
125790 + ret = fsl_bpid_range_init(dn);
125791 + if (ret)
125792 + return ret;
125793 + }
125794 + return 0;
125795 +}
125796 +
125797 +#ifdef CONFIG_SUSPEND
125798 +void suspend_unused_bportal(void)
125799 +{
125800 + struct bm_portal_config *pcfg;
125801 +
125802 + if (list_empty(&unused_pcfgs))
125803 + return;
125804 +
125805 + list_for_each_entry(pcfg, &unused_pcfgs, list) {
125806 +#ifdef CONFIG_PM_DEBUG
125807 + pr_info("Need to save bportal %d\n", pcfg->public_cfg.index);
125808 +#endif
125809 + /* save isdr, disable all via isdr, clear isr */
125810 + pcfg->saved_isdr =
125811 + __raw_readl(pcfg->addr_virt[DPA_PORTAL_CI] + 0xe08);
125812 + __raw_writel(0xffffffff, pcfg->addr_virt[DPA_PORTAL_CI] +
125813 + 0xe08);
125814 + __raw_writel(0xffffffff, pcfg->addr_virt[DPA_PORTAL_CI] +
125815 + 0xe00);
125816 + }
125817 + return;
125818 +}
125819 +
125820 +void resume_unused_bportal(void)
125821 +{
125822 + struct bm_portal_config *pcfg;
125823 +
125824 + if (list_empty(&unused_pcfgs))
125825 + return;
125826 +
125827 + list_for_each_entry(pcfg, &unused_pcfgs, list) {
125828 +#ifdef CONFIG_PM_DEBUG
125829 + pr_info("Need to resume bportal %d\n", pcfg->public_cfg.index);
125830 +#endif
125831 + /* restore isdr */
125832 + __raw_writel(pcfg->saved_isdr,
125833 + pcfg->addr_virt[DPA_PORTAL_CI] + 0xe08);
125834 + }
125835 + return;
125836 +}
125837 +#endif
125838 --- /dev/null
125839 +++ b/drivers/staging/fsl_qbman/bman_high.c
125840 @@ -0,0 +1,1145 @@
125841 +/* Copyright 2008-2012 Freescale Semiconductor, Inc.
125842 + *
125843 + * Redistribution and use in source and binary forms, with or without
125844 + * modification, are permitted provided that the following conditions are met:
125845 + * * Redistributions of source code must retain the above copyright
125846 + * notice, this list of conditions and the following disclaimer.
125847 + * * Redistributions in binary form must reproduce the above copyright
125848 + * notice, this list of conditions and the following disclaimer in the
125849 + * documentation and/or other materials provided with the distribution.
125850 + * * Neither the name of Freescale Semiconductor nor the
125851 + * names of its contributors may be used to endorse or promote products
125852 + * derived from this software without specific prior written permission.
125853 + *
125854 + *
125855 + * ALTERNATIVELY, this software may be distributed under the terms of the
125856 + * GNU General Public License ("GPL") as published by the Free Software
125857 + * Foundation, either version 2 of that License or (at your option) any
125858 + * later version.
125859 + *
125860 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
125861 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
125862 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
125863 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
125864 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
125865 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
125866 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
125867 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
125868 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
125869 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
125870 + */
125871 +
125872 +#include "bman_low.h"
125873 +
125874 +/* Compilation constants */
125875 +#define RCR_THRESH 2 /* reread h/w CI when running out of space */
125876 +#define IRQNAME "BMan portal %d"
125877 +#define MAX_IRQNAME 16 /* big enough for "BMan portal %d" */
125878 +
125879 +struct bman_portal {
125880 + struct bm_portal p;
125881 + /* 2-element array. pools[0] is mask, pools[1] is snapshot. */
125882 + struct bman_depletion *pools;
125883 + int thresh_set;
125884 + unsigned long irq_sources;
125885 + u32 slowpoll; /* only used when interrupts are off */
125886 +#ifdef CONFIG_FSL_DPA_CAN_WAIT_SYNC
125887 + struct bman_pool *rcri_owned; /* only 1 release WAIT_SYNC at a time */
125888 +#endif
125889 +#ifdef CONFIG_FSL_DPA_PORTAL_SHARE
125890 + raw_spinlock_t sharing_lock; /* only used if is_shared */
125891 + int is_shared;
125892 + struct bman_portal *sharing_redirect;
125893 +#endif
125894 + /* When the cpu-affine portal is activated, this is non-NULL */
125895 + const struct bm_portal_config *config;
125896 + /* This is needed for power management */
125897 + struct platform_device *pdev;
125898 + /* 64-entry hash-table of pool objects that are tracking depletion
125899 + * entry/exit (ie. BMAN_POOL_FLAG_DEPLETION). This isn't fast-path, so
125900 + * we're not fussy about cache-misses and so forth - whereas the above
125901 + * members should all fit in one cacheline.
125902 + * BTW, with 64 entries in the hash table and 64 buffer pools to track,
125903 + * you'll never guess the hash-function ... */
125904 + struct bman_pool *cb[64];
125905 + char irqname[MAX_IRQNAME];
125906 + /* Track if the portal was alloced by the driver */
125907 + u8 alloced;
125908 + /* power management data */
125909 + u32 save_isdr;
125910 +};
125911 +
125912 +/* For an explanation of the locking, redirection, or affine-portal logic,
125913 + * please consult the Qman driver for details. This is the same, only simpler
125914 + * (no fiddly Qman-specific bits.) */
125915 +#ifdef CONFIG_FSL_DPA_PORTAL_SHARE
125916 +#define PORTAL_IRQ_LOCK(p, irqflags) \
125917 + do { \
125918 + if ((p)->is_shared) \
125919 + raw_spin_lock_irqsave(&(p)->sharing_lock, irqflags); \
125920 + else \
125921 + local_irq_save(irqflags); \
125922 + } while (0)
125923 +#define PORTAL_IRQ_UNLOCK(p, irqflags) \
125924 + do { \
125925 + if ((p)->is_shared) \
125926 + raw_spin_unlock_irqrestore(&(p)->sharing_lock, \
125927 + irqflags); \
125928 + else \
125929 + local_irq_restore(irqflags); \
125930 + } while (0)
125931 +#else
125932 +#define PORTAL_IRQ_LOCK(p, irqflags) local_irq_save(irqflags)
125933 +#define PORTAL_IRQ_UNLOCK(p, irqflags) local_irq_restore(irqflags)
125934 +#endif
125935 +
125936 +static cpumask_t affine_mask;
125937 +static DEFINE_SPINLOCK(affine_mask_lock);
125938 +static DEFINE_PER_CPU(struct bman_portal, bman_affine_portal);
125939 +static inline struct bman_portal *get_raw_affine_portal(void)
125940 +{
125941 + return &get_cpu_var(bman_affine_portal);
125942 +}
125943 +#ifdef CONFIG_FSL_DPA_PORTAL_SHARE
125944 +static inline struct bman_portal *get_affine_portal(void)
125945 +{
125946 + struct bman_portal *p = get_raw_affine_portal();
125947 + if (p->sharing_redirect)
125948 + return p->sharing_redirect;
125949 + return p;
125950 +}
125951 +#else
125952 +#define get_affine_portal() get_raw_affine_portal()
125953 +#endif
125954 +static inline void put_affine_portal(void)
125955 +{
125956 + put_cpu_var(bman_affine_portal);
125957 +}
125958 +static inline struct bman_portal *get_poll_portal(void)
125959 +{
125960 + return &get_cpu_var(bman_affine_portal);
125961 +}
125962 +#define put_poll_portal()
125963 +
125964 +/* GOTCHA: this object type refers to a pool, it isn't *the* pool. There may be
125965 + * more than one such object per Bman buffer pool, eg. if different users of the
125966 + * pool are operating via different portals. */
125967 +struct bman_pool {
125968 + struct bman_pool_params params;
125969 + /* Used for hash-table admin when using depletion notifications. */
125970 + struct bman_portal *portal;
125971 + struct bman_pool *next;
125972 + /* stockpile state - NULL unless BMAN_POOL_FLAG_STOCKPILE is set */
125973 + struct bm_buffer *sp;
125974 + unsigned int sp_fill;
125975 +#ifdef CONFIG_FSL_DPA_CHECKING
125976 + atomic_t in_use;
125977 +#endif
125978 +};
125979 +
125980 +/* (De)Registration of depletion notification callbacks */
125981 +static void depletion_link(struct bman_portal *portal, struct bman_pool *pool)
125982 +{
125983 + __maybe_unused unsigned long irqflags;
125984 + pool->portal = portal;
125985 + PORTAL_IRQ_LOCK(portal, irqflags);
125986 + pool->next = portal->cb[pool->params.bpid];
125987 + portal->cb[pool->params.bpid] = pool;
125988 + if (!pool->next)
125989 + /* First object for that bpid on this portal, enable the BSCN
125990 + * mask bit. */
125991 + bm_isr_bscn_mask(&portal->p, pool->params.bpid, 1);
125992 + PORTAL_IRQ_UNLOCK(portal, irqflags);
125993 +}
125994 +static void depletion_unlink(struct bman_pool *pool)
125995 +{
125996 + struct bman_pool *it, *last = NULL;
125997 + struct bman_pool **base = &pool->portal->cb[pool->params.bpid];
125998 + __maybe_unused unsigned long irqflags;
125999 + PORTAL_IRQ_LOCK(pool->portal, irqflags);
126000 + it = *base; /* <-- gotcha, don't do this prior to the irq_save */
126001 + while (it != pool) {
126002 + last = it;
126003 + it = it->next;
126004 + }
126005 + if (!last)
126006 + *base = pool->next;
126007 + else
126008 + last->next = pool->next;
126009 + if (!last && !pool->next) {
126010 + /* Last object for that bpid on this portal, disable the BSCN
126011 + * mask bit. */
126012 + bm_isr_bscn_mask(&pool->portal->p, pool->params.bpid, 0);
126013 + /* And "forget" that we last saw this pool as depleted */
126014 + bman_depletion_unset(&pool->portal->pools[1],
126015 + pool->params.bpid);
126016 + }
126017 + PORTAL_IRQ_UNLOCK(pool->portal, irqflags);
126018 +}
126019 +
126020 +/* In the case that the application's core loop calls qman_poll() and
126021 + * bman_poll(), we ought to balance how often we incur the overheads of the
126022 + * slow-path poll. We'll use two decrementer sources. The idle decrementer
126023 + * constant is used when the last slow-poll detected no work to do, and the busy
126024 + * decrementer constant when the last slow-poll had work to do. */
126025 +#define SLOW_POLL_IDLE 1000
126026 +#define SLOW_POLL_BUSY 10
126027 +static u32 __poll_portal_slow(struct bman_portal *p, u32 is);
126028 +
126029 +/* Portal interrupt handler */
126030 +static irqreturn_t portal_isr(__always_unused int irq, void *ptr)
126031 +{
126032 + struct bman_portal *p = ptr;
126033 + u32 clear = p->irq_sources;
126034 + u32 is = bm_isr_status_read(&p->p) & p->irq_sources;
126035 + clear |= __poll_portal_slow(p, is);
126036 + bm_isr_status_clear(&p->p, clear);
126037 + return IRQ_HANDLED;
126038 +}
126039 +
126040 +#ifdef CONFIG_SUSPEND
126041 +static int _bman_portal_suspend_noirq(struct device *dev)
126042 +{
126043 + struct bman_portal *p = (struct bman_portal *)dev->platform_data;
126044 +#ifdef CONFIG_PM_DEBUG
126045 + struct platform_device *pdev = to_platform_device(dev);
126046 +#endif
126047 + p->save_isdr = bm_isr_disable_read(&p->p);
126048 + bm_isr_disable_write(&p->p, 0xffffffff);
126049 + bm_isr_status_clear(&p->p, 0xffffffff);
126050 +#ifdef CONFIG_PM_DEBUG
126051 + pr_info("Suspend for %s\n", pdev->name);
126052 +#endif
126053 + return 0;
126054 +}
126055 +
126056 +static int _bman_portal_resume_noirq(struct device *dev)
126057 +{
126058 + struct bman_portal *p = (struct bman_portal *)dev->platform_data;
126059 +
126060 + /* restore isdr */
126061 + bm_isr_disable_write(&p->p, p->save_isdr);
126062 + return 0;
126063 +}
126064 +#else
126065 +#define _bman_portal_suspend_noirq NULL
126066 +#define _bman_portal_resume_noirq NULL
126067 +#endif
126068 +
126069 +struct dev_pm_domain bman_portal_device_pm_domain = {
126070 + .ops = {
126071 + USE_PLATFORM_PM_SLEEP_OPS
126072 + .suspend_noirq = _bman_portal_suspend_noirq,
126073 + .resume_noirq = _bman_portal_resume_noirq,
126074 + }
126075 +};
126076 +
126077 +struct bman_portal *bman_create_portal(
126078 + struct bman_portal *portal,
126079 + const struct bm_portal_config *config)
126080 +{
126081 + struct bm_portal *__p;
126082 + const struct bman_depletion *pools = &config->public_cfg.mask;
126083 + int ret;
126084 + u8 bpid = 0;
126085 + char buf[16];
126086 +
126087 + if (!portal) {
126088 + portal = kmalloc(sizeof(*portal), GFP_KERNEL);
126089 + if (!portal)
126090 + return portal;
126091 + portal->alloced = 1;
126092 + } else
126093 + portal->alloced = 0;
126094 +
126095 + __p = &portal->p;
126096 +
126097 + /* prep the low-level portal struct with the mapped addresses from the
126098 + * config, everything that follows depends on it and "config" is more
126099 + * for (de)reference... */
126100 + __p->addr.addr_ce = config->addr_virt[DPA_PORTAL_CE];
126101 + __p->addr.addr_ci = config->addr_virt[DPA_PORTAL_CI];
126102 + if (bm_rcr_init(__p, bm_rcr_pvb, bm_rcr_cce)) {
126103 + pr_err("Bman RCR initialisation failed\n");
126104 + goto fail_rcr;
126105 + }
126106 + if (bm_mc_init(__p)) {
126107 + pr_err("Bman MC initialisation failed\n");
126108 + goto fail_mc;
126109 + }
126110 + if (bm_isr_init(__p)) {
126111 + pr_err("Bman ISR initialisation failed\n");
126112 + goto fail_isr;
126113 + }
126114 + portal->pools = kmalloc(2 * sizeof(*pools), GFP_KERNEL);
126115 + if (!portal->pools)
126116 + goto fail_pools;
126117 + portal->pools[0] = *pools;
126118 + bman_depletion_init(portal->pools + 1);
126119 + while (bpid < bman_pool_max) {
126120 + /* Default to all BPIDs disabled, we enable as required at
126121 + * run-time. */
126122 + bm_isr_bscn_mask(__p, bpid, 0);
126123 + bpid++;
126124 + }
126125 + portal->slowpoll = 0;
126126 +#ifdef CONFIG_FSL_DPA_CAN_WAIT_SYNC
126127 + portal->rcri_owned = NULL;
126128 +#endif
126129 +#ifdef CONFIG_FSL_DPA_PORTAL_SHARE
126130 + raw_spin_lock_init(&portal->sharing_lock);
126131 + portal->is_shared = config->public_cfg.is_shared;
126132 + portal->sharing_redirect = NULL;
126133 +#endif
126134 + sprintf(buf, "bportal-%u", config->public_cfg.index);
126135 + portal->pdev = platform_device_alloc(buf, -1);
126136 + if (!portal->pdev)
126137 + goto fail_devalloc;
126138 + portal->pdev->dev.pm_domain = &bman_portal_device_pm_domain;
126139 + portal->pdev->dev.platform_data = portal;
126140 + ret = platform_device_add(portal->pdev);
126141 + if (ret)
126142 + goto fail_devadd;
126143 + memset(&portal->cb, 0, sizeof(portal->cb));
126144 + /* Write-to-clear any stale interrupt status bits */
126145 + bm_isr_disable_write(__p, 0xffffffff);
126146 + portal->irq_sources = 0;
126147 + bm_isr_enable_write(__p, portal->irq_sources);
126148 + bm_isr_status_clear(__p, 0xffffffff);
126149 + snprintf(portal->irqname, MAX_IRQNAME, IRQNAME, config->public_cfg.cpu);
126150 + if (request_irq(config->public_cfg.irq, portal_isr, 0, portal->irqname,
126151 + portal)) {
126152 + pr_err("request_irq() failed\n");
126153 + goto fail_irq;
126154 + }
126155 + if ((config->public_cfg.cpu != -1) &&
126156 + irq_can_set_affinity(config->public_cfg.irq) &&
126157 + irq_set_affinity(config->public_cfg.irq,
126158 + cpumask_of(config->public_cfg.cpu))) {
126159 + pr_err("irq_set_affinity() failed %s\n", portal->irqname);
126160 + goto fail_affinity;
126161 + }
126162 +
126163 + /* Need RCR to be empty before continuing */
126164 + ret = bm_rcr_get_fill(__p);
126165 + if (ret) {
126166 + pr_err("Bman RCR unclean\n");
126167 + goto fail_rcr_empty;
126168 + }
126169 + /* Success */
126170 + portal->config = config;
126171 +
126172 + bm_isr_disable_write(__p, 0);
126173 + bm_isr_uninhibit(__p);
126174 + return portal;
126175 +fail_rcr_empty:
126176 +fail_affinity:
126177 + free_irq(config->public_cfg.irq, portal);
126178 +fail_irq:
126179 + platform_device_del(portal->pdev);
126180 +fail_devadd:
126181 + platform_device_put(portal->pdev);
126182 +fail_devalloc:
126183 + kfree(portal->pools);
126184 +fail_pools:
126185 + bm_isr_finish(__p);
126186 +fail_isr:
126187 + bm_mc_finish(__p);
126188 +fail_mc:
126189 + bm_rcr_finish(__p);
126190 +fail_rcr:
126191 + if (portal->alloced)
126192 + kfree(portal);
126193 + return NULL;
126194 +}
126195 +
126196 +struct bman_portal *bman_create_affine_portal(
126197 + const struct bm_portal_config *config)
126198 +{
126199 + struct bman_portal *portal;
126200 +
126201 + portal = &per_cpu(bman_affine_portal, config->public_cfg.cpu);
126202 + portal = bman_create_portal(portal, config);
126203 + if (portal) {
126204 + spin_lock(&affine_mask_lock);
126205 + cpumask_set_cpu(config->public_cfg.cpu, &affine_mask);
126206 + spin_unlock(&affine_mask_lock);
126207 + }
126208 + return portal;
126209 +}
126210 +
126211 +
126212 +struct bman_portal *bman_create_affine_slave(struct bman_portal *redirect,
126213 + int cpu)
126214 +{
126215 +#ifdef CONFIG_FSL_DPA_PORTAL_SHARE
126216 + struct bman_portal *p;
126217 + p = &per_cpu(bman_affine_portal, cpu);
126218 + BUG_ON(p->config);
126219 + BUG_ON(p->is_shared);
126220 + BUG_ON(!redirect->config->public_cfg.is_shared);
126221 + p->irq_sources = 0;
126222 + p->sharing_redirect = redirect;
126223 + return p;
126224 +#else
126225 + BUG();
126226 + return NULL;
126227 +#endif
126228 +}
126229 +
126230 +void bman_destroy_portal(struct bman_portal *bm)
126231 +{
126232 + const struct bm_portal_config *pcfg;
126233 + pcfg = bm->config;
126234 + bm_rcr_cce_update(&bm->p);
126235 + bm_rcr_cce_update(&bm->p);
126236 +
126237 + free_irq(pcfg->public_cfg.irq, bm);
126238 +
126239 + kfree(bm->pools);
126240 + bm_isr_finish(&bm->p);
126241 + bm_mc_finish(&bm->p);
126242 + bm_rcr_finish(&bm->p);
126243 + bm->config = NULL;
126244 + if (bm->alloced)
126245 + kfree(bm);
126246 +}
126247 +
126248 +const struct bm_portal_config *bman_destroy_affine_portal(void)
126249 +{
126250 + struct bman_portal *bm = get_raw_affine_portal();
126251 + const struct bm_portal_config *pcfg;
126252 +#ifdef CONFIG_FSL_DPA_PORTAL_SHARE
126253 + if (bm->sharing_redirect) {
126254 + bm->sharing_redirect = NULL;
126255 + put_affine_portal();
126256 + return NULL;
126257 + }
126258 + bm->is_shared = 0;
126259 +#endif
126260 + pcfg = bm->config;
126261 + bman_destroy_portal(bm);
126262 + spin_lock(&affine_mask_lock);
126263 + cpumask_clear_cpu(pcfg->public_cfg.cpu, &affine_mask);
126264 + spin_unlock(&affine_mask_lock);
126265 + put_affine_portal();
126266 + return pcfg;
126267 +}
126268 +
126269 +/* When release logic waits on available RCR space, we need a global waitqueue
126270 + * in the case of "affine" use (as the waits wake on different cpus which means
126271 + * different portals - so we can't wait on any per-portal waitqueue). */
126272 +static DECLARE_WAIT_QUEUE_HEAD(affine_queue);
126273 +
126274 +static u32 __poll_portal_slow(struct bman_portal *p, u32 is)
126275 +{
126276 + struct bman_depletion tmp;
126277 + u32 ret = is;
126278 +
126279 + /* There is a gotcha to be aware of. If we do the query before clearing
126280 + * the status register, we may miss state changes that occur between the
126281 + * two. If we write to clear the status register before the query, the
126282 + * cache-enabled query command may overtake the status register write
126283 + * unless we use a heavyweight sync (which we don't want). Instead, we
126284 + * write-to-clear the status register then *read it back* before doing
126285 + * the query, hence the odd while loop with the 'is' accumulation. */
126286 + if (is & BM_PIRQ_BSCN) {
126287 + struct bm_mc_result *mcr;
126288 + __maybe_unused unsigned long irqflags;
126289 + unsigned int i, j;
126290 + u32 __is;
126291 + bm_isr_status_clear(&p->p, BM_PIRQ_BSCN);
126292 + while ((__is = bm_isr_status_read(&p->p)) & BM_PIRQ_BSCN) {
126293 + is |= __is;
126294 + bm_isr_status_clear(&p->p, BM_PIRQ_BSCN);
126295 + }
126296 + is &= ~BM_PIRQ_BSCN;
126297 + PORTAL_IRQ_LOCK(p, irqflags);
126298 + bm_mc_start(&p->p);
126299 + bm_mc_commit(&p->p, BM_MCC_VERB_CMD_QUERY);
126300 + while (!(mcr = bm_mc_result(&p->p)))
126301 + cpu_relax();
126302 + tmp = mcr->query.ds.state;
126303 + tmp.__state[0] = be32_to_cpu(tmp.__state[0]);
126304 + tmp.__state[1] = be32_to_cpu(tmp.__state[1]);
126305 + PORTAL_IRQ_UNLOCK(p, irqflags);
126306 + for (i = 0; i < 2; i++) {
126307 + int idx = i * 32;
126308 + /* tmp is a mask of currently-depleted pools.
126309 + * pools[0] is mask of those we care about.
126310 + * pools[1] is our previous view (we only want to
126311 + * be told about changes). */
126312 + tmp.__state[i] &= p->pools[0].__state[i];
126313 + if (tmp.__state[i] == p->pools[1].__state[i])
126314 + /* fast-path, nothing to see, move along */
126315 + continue;
126316 + for (j = 0; j <= 31; j++, idx++) {
126317 + struct bman_pool *pool = p->cb[idx];
126318 + int b4 = bman_depletion_get(&p->pools[1], idx);
126319 + int af = bman_depletion_get(&tmp, idx);
126320 + if (b4 == af)
126321 + continue;
126322 + while (pool) {
126323 + pool->params.cb(p, pool,
126324 + pool->params.cb_ctx, af);
126325 + pool = pool->next;
126326 + }
126327 + }
126328 + }
126329 + p->pools[1] = tmp;
126330 + }
126331 +
126332 + if (is & BM_PIRQ_RCRI) {
126333 + __maybe_unused unsigned long irqflags;
126334 + PORTAL_IRQ_LOCK(p, irqflags);
126335 + bm_rcr_cce_update(&p->p);
126336 +#ifdef CONFIG_FSL_DPA_CAN_WAIT_SYNC
126337 + /* If waiting for sync, we only cancel the interrupt threshold
126338 + * when the ring utilisation hits zero. */
126339 + if (p->rcri_owned) {
126340 + if (!bm_rcr_get_fill(&p->p)) {
126341 + p->rcri_owned = NULL;
126342 + bm_rcr_set_ithresh(&p->p, 0);
126343 + }
126344 + } else
126345 +#endif
126346 + bm_rcr_set_ithresh(&p->p, 0);
126347 + PORTAL_IRQ_UNLOCK(p, irqflags);
126348 + wake_up(&affine_queue);
126349 + bm_isr_status_clear(&p->p, BM_PIRQ_RCRI);
126350 + is &= ~BM_PIRQ_RCRI;
126351 + }
126352 +
126353 + /* There should be no status register bits left undefined */
126354 + DPA_ASSERT(!is);
126355 + return ret;
126356 +}
126357 +
126358 +const struct bman_portal_config *bman_get_portal_config(void)
126359 +{
126360 + struct bman_portal *p = get_affine_portal();
126361 + const struct bman_portal_config *ret = &p->config->public_cfg;
126362 + put_affine_portal();
126363 + return ret;
126364 +}
126365 +EXPORT_SYMBOL(bman_get_portal_config);
126366 +
126367 +u32 bman_irqsource_get(void)
126368 +{
126369 + struct bman_portal *p = get_raw_affine_portal();
126370 + u32 ret = p->irq_sources & BM_PIRQ_VISIBLE;
126371 + put_affine_portal();
126372 + return ret;
126373 +}
126374 +EXPORT_SYMBOL(bman_irqsource_get);
126375 +
126376 +int bman_p_irqsource_add(struct bman_portal *p, __maybe_unused u32 bits)
126377 +{
126378 +#ifdef CONFIG_FSL_DPA_PORTAL_SHARE
126379 + if (p->sharing_redirect)
126380 + return -EINVAL;
126381 + else
126382 +#endif
126383 + {
126384 + __maybe_unused unsigned long irqflags;
126385 + PORTAL_IRQ_LOCK(p, irqflags);
126386 + set_bits(bits & BM_PIRQ_VISIBLE, &p->irq_sources);
126387 + bm_isr_enable_write(&p->p, p->irq_sources);
126388 + PORTAL_IRQ_UNLOCK(p, irqflags);
126389 + }
126390 + return 0;
126391 +}
126392 +EXPORT_SYMBOL(bman_p_irqsource_add);
126393 +
126394 +int bman_irqsource_add(__maybe_unused u32 bits)
126395 +{
126396 + struct bman_portal *p = get_raw_affine_portal();
126397 + int ret = 0;
126398 + ret = bman_p_irqsource_add(p, bits);
126399 + put_affine_portal();
126400 + return ret;
126401 +}
126402 +EXPORT_SYMBOL(bman_irqsource_add);
126403 +
126404 +int bman_irqsource_remove(u32 bits)
126405 +{
126406 + struct bman_portal *p = get_raw_affine_portal();
126407 + __maybe_unused unsigned long irqflags;
126408 + u32 ier;
126409 +#ifdef CONFIG_FSL_DPA_PORTAL_SHARE
126410 + if (p->sharing_redirect) {
126411 + put_affine_portal();
126412 + return -EINVAL;
126413 + }
126414 +#endif
126415 + /* Our interrupt handler only processes+clears status register bits that
126416 + * are in p->irq_sources. As we're trimming that mask, if one of them
126417 + * were to assert in the status register just before we remove it from
126418 + * the enable register, there would be an interrupt-storm when we
126419 + * release the IRQ lock. So we wait for the enable register update to
126420 + * take effect in h/w (by reading it back) and then clear all other bits
126421 + * in the status register. Ie. we clear them from ISR once it's certain
126422 + * IER won't allow them to reassert. */
126423 + PORTAL_IRQ_LOCK(p, irqflags);
126424 + bits &= BM_PIRQ_VISIBLE;
126425 + clear_bits(bits, &p->irq_sources);
126426 + bm_isr_enable_write(&p->p, p->irq_sources);
126427 + ier = bm_isr_enable_read(&p->p);
126428 + /* Using "~ier" (rather than "bits" or "~p->irq_sources") creates a
126429 + * data-dependency, ie. to protect against re-ordering. */
126430 + bm_isr_status_clear(&p->p, ~ier);
126431 + PORTAL_IRQ_UNLOCK(p, irqflags);
126432 + put_affine_portal();
126433 + return 0;
126434 +}
126435 +EXPORT_SYMBOL(bman_irqsource_remove);
126436 +
126437 +const cpumask_t *bman_affine_cpus(void)
126438 +{
126439 + return &affine_mask;
126440 +}
126441 +EXPORT_SYMBOL(bman_affine_cpus);
126442 +
126443 +u32 bman_poll_slow(void)
126444 +{
126445 + struct bman_portal *p = get_poll_portal();
126446 + u32 ret;
126447 +#ifdef CONFIG_FSL_DPA_PORTAL_SHARE
126448 + if (unlikely(p->sharing_redirect))
126449 + ret = (u32)-1;
126450 + else
126451 +#endif
126452 + {
126453 + u32 is = bm_isr_status_read(&p->p) & ~p->irq_sources;
126454 + ret = __poll_portal_slow(p, is);
126455 + bm_isr_status_clear(&p->p, ret);
126456 + }
126457 + put_poll_portal();
126458 + return ret;
126459 +}
126460 +EXPORT_SYMBOL(bman_poll_slow);
126461 +
126462 +/* Legacy wrapper */
126463 +void bman_poll(void)
126464 +{
126465 + struct bman_portal *p = get_poll_portal();
126466 +#ifdef CONFIG_FSL_DPA_PORTAL_SHARE
126467 + if (unlikely(p->sharing_redirect))
126468 + goto done;
126469 +#endif
126470 + if (!(p->slowpoll--)) {
126471 + u32 is = bm_isr_status_read(&p->p) & ~p->irq_sources;
126472 + u32 active = __poll_portal_slow(p, is);
126473 + if (active)
126474 + p->slowpoll = SLOW_POLL_BUSY;
126475 + else
126476 + p->slowpoll = SLOW_POLL_IDLE;
126477 + }
126478 +#ifdef CONFIG_FSL_DPA_PORTAL_SHARE
126479 +done:
126480 +#endif
126481 + put_poll_portal();
126482 +}
126483 +EXPORT_SYMBOL(bman_poll);
126484 +
126485 +static const u32 zero_thresholds[4] = {0, 0, 0, 0};
126486 +
126487 +struct bman_pool *bman_new_pool(const struct bman_pool_params *params)
126488 +{
126489 + struct bman_pool *pool = NULL;
126490 + u32 bpid;
126491 +
126492 + if (params->flags & BMAN_POOL_FLAG_DYNAMIC_BPID) {
126493 + int ret = bman_alloc_bpid(&bpid);
126494 + if (ret)
126495 + return NULL;
126496 + } else {
126497 + if (params->bpid >= bman_pool_max)
126498 + return NULL;
126499 + bpid = params->bpid;
126500 + }
126501 +#ifdef CONFIG_FSL_BMAN_CONFIG
126502 + if (params->flags & BMAN_POOL_FLAG_THRESH) {
126503 + int ret = bm_pool_set(bpid, params->thresholds);
126504 + if (ret)
126505 + goto err;
126506 + }
126507 +#else
126508 + if (params->flags & BMAN_POOL_FLAG_THRESH)
126509 + goto err;
126510 +#endif
126511 + pool = kmalloc(sizeof(*pool), GFP_KERNEL);
126512 + if (!pool)
126513 + goto err;
126514 + pool->sp = NULL;
126515 + pool->sp_fill = 0;
126516 + pool->params = *params;
126517 +#ifdef CONFIG_FSL_DPA_CHECKING
126518 + atomic_set(&pool->in_use, 1);
126519 +#endif
126520 + if (params->flags & BMAN_POOL_FLAG_DYNAMIC_BPID)
126521 + pool->params.bpid = bpid;
126522 + if (params->flags & BMAN_POOL_FLAG_STOCKPILE) {
126523 + pool->sp = kmalloc(sizeof(struct bm_buffer) * BMAN_STOCKPILE_SZ,
126524 + GFP_KERNEL);
126525 + if (!pool->sp)
126526 + goto err;
126527 + }
126528 + if (pool->params.flags & BMAN_POOL_FLAG_DEPLETION) {
126529 + struct bman_portal *p = get_affine_portal();
126530 + if (!p->pools || !bman_depletion_get(&p->pools[0], bpid)) {
126531 + pr_err("Depletion events disabled for bpid %d\n", bpid);
126532 + goto err;
126533 + }
126534 + depletion_link(p, pool);
126535 + put_affine_portal();
126536 + }
126537 + return pool;
126538 +err:
126539 +#ifdef CONFIG_FSL_BMAN_CONFIG
126540 + if (params->flags & BMAN_POOL_FLAG_THRESH)
126541 + bm_pool_set(bpid, zero_thresholds);
126542 +#endif
126543 + if (params->flags & BMAN_POOL_FLAG_DYNAMIC_BPID)
126544 + bman_release_bpid(bpid);
126545 + if (pool) {
126546 + kfree(pool->sp);
126547 + kfree(pool);
126548 + }
126549 + return NULL;
126550 +}
126551 +EXPORT_SYMBOL(bman_new_pool);
126552 +
126553 +void bman_free_pool(struct bman_pool *pool)
126554 +{
126555 +#ifdef CONFIG_FSL_BMAN_CONFIG
126556 + if (pool->params.flags & BMAN_POOL_FLAG_THRESH)
126557 + bm_pool_set(pool->params.bpid, zero_thresholds);
126558 +#endif
126559 + if (pool->params.flags & BMAN_POOL_FLAG_DEPLETION)
126560 + depletion_unlink(pool);
126561 + if (pool->params.flags & BMAN_POOL_FLAG_STOCKPILE) {
126562 + if (pool->sp_fill)
126563 + pr_err("Stockpile not flushed, has %u in bpid %u.\n",
126564 + pool->sp_fill, pool->params.bpid);
126565 + kfree(pool->sp);
126566 + pool->sp = NULL;
126567 + pool->params.flags ^= BMAN_POOL_FLAG_STOCKPILE;
126568 + }
126569 + if (pool->params.flags & BMAN_POOL_FLAG_DYNAMIC_BPID)
126570 + bman_release_bpid(pool->params.bpid);
126571 + kfree(pool);
126572 +}
126573 +EXPORT_SYMBOL(bman_free_pool);
126574 +
126575 +const struct bman_pool_params *bman_get_params(const struct bman_pool *pool)
126576 +{
126577 + return &pool->params;
126578 +}
126579 +EXPORT_SYMBOL(bman_get_params);
126580 +
126581 +static noinline void update_rcr_ci(struct bman_portal *p, u8 avail)
126582 +{
126583 + if (avail)
126584 + bm_rcr_cce_prefetch(&p->p);
126585 + else
126586 + bm_rcr_cce_update(&p->p);
126587 +}
126588 +
126589 +int bman_rcr_is_empty(void)
126590 +{
126591 + __maybe_unused unsigned long irqflags;
126592 + struct bman_portal *p = get_affine_portal();
126593 + u8 avail;
126594 +
126595 + PORTAL_IRQ_LOCK(p, irqflags);
126596 + update_rcr_ci(p, 0);
126597 + avail = bm_rcr_get_fill(&p->p);
126598 + PORTAL_IRQ_UNLOCK(p, irqflags);
126599 + put_affine_portal();
126600 + return avail == 0;
126601 +}
126602 +EXPORT_SYMBOL(bman_rcr_is_empty);
126603 +
126604 +static inline struct bm_rcr_entry *try_rel_start(struct bman_portal **p,
126605 +#ifdef CONFIG_FSL_DPA_CAN_WAIT
126606 + __maybe_unused struct bman_pool *pool,
126607 +#endif
126608 + __maybe_unused unsigned long *irqflags,
126609 + __maybe_unused u32 flags)
126610 +{
126611 + struct bm_rcr_entry *r;
126612 + u8 avail;
126613 +
126614 + *p = get_affine_portal();
126615 + PORTAL_IRQ_LOCK(*p, (*irqflags));
126616 +#ifdef CONFIG_FSL_DPA_CAN_WAIT_SYNC
126617 + if (unlikely((flags & BMAN_RELEASE_FLAG_WAIT) &&
126618 + (flags & BMAN_RELEASE_FLAG_WAIT_SYNC))) {
126619 + if ((*p)->rcri_owned) {
126620 + PORTAL_IRQ_UNLOCK(*p, (*irqflags));
126621 + put_affine_portal();
126622 + return NULL;
126623 + }
126624 + (*p)->rcri_owned = pool;
126625 + }
126626 +#endif
126627 + avail = bm_rcr_get_avail(&(*p)->p);
126628 + if (avail < 2)
126629 + update_rcr_ci(*p, avail);
126630 + r = bm_rcr_start(&(*p)->p);
126631 + if (unlikely(!r)) {
126632 +#ifdef CONFIG_FSL_DPA_CAN_WAIT_SYNC
126633 + if (unlikely((flags & BMAN_RELEASE_FLAG_WAIT) &&
126634 + (flags & BMAN_RELEASE_FLAG_WAIT_SYNC)))
126635 + (*p)->rcri_owned = NULL;
126636 +#endif
126637 + PORTAL_IRQ_UNLOCK(*p, (*irqflags));
126638 + put_affine_portal();
126639 + }
126640 + return r;
126641 +}
126642 +
126643 +#ifdef CONFIG_FSL_DPA_CAN_WAIT
126644 +static noinline struct bm_rcr_entry *__wait_rel_start(struct bman_portal **p,
126645 + struct bman_pool *pool,
126646 + __maybe_unused unsigned long *irqflags,
126647 + u32 flags)
126648 +{
126649 + struct bm_rcr_entry *rcr = try_rel_start(p, pool, irqflags, flags);
126650 + if (!rcr)
126651 + bm_rcr_set_ithresh(&(*p)->p, 1);
126652 + return rcr;
126653 +}
126654 +
126655 +static noinline struct bm_rcr_entry *wait_rel_start(struct bman_portal **p,
126656 + struct bman_pool *pool,
126657 + __maybe_unused unsigned long *irqflags,
126658 + u32 flags)
126659 +{
126660 + struct bm_rcr_entry *rcr;
126661 +#ifndef CONFIG_FSL_DPA_CAN_WAIT_SYNC
126662 + pool = NULL;
126663 +#endif
126664 + if (flags & BMAN_RELEASE_FLAG_WAIT_INT)
126665 + /* NB: return NULL if signal occurs before completion. Signal
126666 + * can occur during return. Caller must check for signal */
126667 + wait_event_interruptible(affine_queue,
126668 + (rcr = __wait_rel_start(p, pool, irqflags, flags)));
126669 + else
126670 + wait_event(affine_queue,
126671 + (rcr = __wait_rel_start(p, pool, irqflags, flags)));
126672 + return rcr;
126673 +}
126674 +#endif
126675 +
126676 +static inline int __bman_release(struct bman_pool *pool,
126677 + const struct bm_buffer *bufs, u8 num, u32 flags)
126678 +{
126679 + struct bman_portal *p;
126680 + struct bm_rcr_entry *r;
126681 + __maybe_unused unsigned long irqflags;
126682 + u32 i = num - 1;
126683 +
126684 +#ifdef CONFIG_FSL_DPA_CAN_WAIT
126685 + if (flags & BMAN_RELEASE_FLAG_WAIT)
126686 + r = wait_rel_start(&p, pool, &irqflags, flags);
126687 + else
126688 + r = try_rel_start(&p, pool, &irqflags, flags);
126689 +#else
126690 + r = try_rel_start(&p, &irqflags, flags);
126691 +#endif
126692 + if (!r)
126693 + return -EBUSY;
126694 + /* We can copy all but the first entry, as this can trigger badness
126695 + * with the valid-bit. Use the overlay to mask the verb byte. */
126696 + r->bufs[0].opaque =
126697 + ((cpu_to_be64((bufs[0].opaque |
126698 + ((u64)pool->params.bpid<<48))
126699 + & 0x00ffffffffffffff)));
126700 + if (i) {
126701 + for (i = 1; i < num; i++)
126702 + r->bufs[i].opaque =
126703 + cpu_to_be64(bufs[i].opaque);
126704 + }
126705 +
126706 + bm_rcr_pvb_commit(&p->p, BM_RCR_VERB_CMD_BPID_SINGLE |
126707 + (num & BM_RCR_VERB_BUFCOUNT_MASK));
126708 +#ifdef CONFIG_FSL_DPA_CAN_WAIT_SYNC
126709 + /* if we wish to sync we need to set the threshold after h/w sees the
126710 + * new ring entry. As we're mixing cache-enabled and cache-inhibited
126711 + * accesses, this requires a heavy-weight sync. */
126712 + if (unlikely((flags & BMAN_RELEASE_FLAG_WAIT) &&
126713 + (flags & BMAN_RELEASE_FLAG_WAIT_SYNC))) {
126714 + hwsync();
126715 + bm_rcr_set_ithresh(&p->p, 1);
126716 + }
126717 +#endif
126718 + PORTAL_IRQ_UNLOCK(p, irqflags);
126719 + put_affine_portal();
126720 +#ifdef CONFIG_FSL_DPA_CAN_WAIT_SYNC
126721 + if (unlikely((flags & BMAN_RELEASE_FLAG_WAIT) &&
126722 + (flags & BMAN_RELEASE_FLAG_WAIT_SYNC))) {
126723 + if (flags & BMAN_RELEASE_FLAG_WAIT_INT)
126724 + /* NB: return success even if signal occurs before
126725 + * condition is true. pvb_commit guarantees success */
126726 + wait_event_interruptible(affine_queue,
126727 + (p->rcri_owned != pool));
126728 + else
126729 + wait_event(affine_queue, (p->rcri_owned != pool));
126730 + }
126731 +#endif
126732 + return 0;
126733 +}
126734 +
126735 +int bman_release(struct bman_pool *pool, const struct bm_buffer *bufs, u8 num,
126736 + u32 flags)
126737 +{
126738 + int ret;
126739 +#ifdef CONFIG_FSL_DPA_CHECKING
126740 + if (!num || (num > 8))
126741 + return -EINVAL;
126742 + if (pool->params.flags & BMAN_POOL_FLAG_NO_RELEASE)
126743 + return -EINVAL;
126744 +#endif
126745 + /* Without stockpile, this API is a pass-through to the h/w operation */
126746 + if (!(pool->params.flags & BMAN_POOL_FLAG_STOCKPILE))
126747 + return __bman_release(pool, bufs, num, flags);
126748 +#ifdef CONFIG_FSL_DPA_CHECKING
126749 + if (!atomic_dec_and_test(&pool->in_use)) {
126750 + pr_crit("Parallel attempts to enter bman_released() detected.");
126751 + panic("only one instance of bman_released/acquired allowed");
126752 + }
126753 +#endif
126754 + /* Two movements of buffers are possible, and can occur in either order.
126755 + * A: moving buffers from the caller to the stockpile.
126756 + * B: moving buffers from the stockpile to hardware.
126757 + * Order 1: if there is already enough space in the stockpile for A
126758 + * then we want to do A first, and only do B if we trigger the
126759 + * stockpile-high threshold.
126760 + * Order 2: if there is not enough space in the stockpile for A, then
126761 + * we want to do B first, then do A if B had succeeded. However in this
126762 + * case B is dependent on how many buffers the user needs to release,
126763 + * not the stockpile-high threshold.
126764 + * Due to the different handling of B between the two cases, putting A
126765 + * and B in a while() loop would require quite obscure logic, so handle
126766 + * the different sequences explicitly. */
126767 + if ((pool->sp_fill + num) <= BMAN_STOCKPILE_SZ) {
126768 + /* Order 1: do A */
126769 + copy_words(pool->sp + pool->sp_fill, bufs,
126770 + sizeof(struct bm_buffer) * num);
126771 + pool->sp_fill += num;
126772 + /* do B relative to STOCKPILE_HIGH */
126773 + while (pool->sp_fill >= BMAN_STOCKPILE_HIGH) {
126774 + ret = __bman_release(pool,
126775 + pool->sp + (pool->sp_fill - 8), 8,
126776 + flags);
126777 + if (ret >= 0)
126778 + pool->sp_fill -= 8;
126779 + }
126780 + } else {
126781 + /* Order 2: do B relative to 'num' */
126782 + do {
126783 + ret = __bman_release(pool,
126784 + pool->sp + (pool->sp_fill - 8), 8,
126785 + flags);
126786 + if (ret < 0)
126787 + /* failure */
126788 + goto release_done;
126789 + pool->sp_fill -= 8;
126790 + } while ((pool->sp_fill + num) > BMAN_STOCKPILE_SZ);
126791 + /* do A */
126792 + copy_words(pool->sp + pool->sp_fill, bufs,
126793 + sizeof(struct bm_buffer) * num);
126794 + pool->sp_fill += num;
126795 + }
126796 + /* success */
126797 + ret = 0;
126798 +release_done:
126799 +#ifdef CONFIG_FSL_DPA_CHECKING
126800 + atomic_inc(&pool->in_use);
126801 +#endif
126802 + return ret;
126803 +}
126804 +EXPORT_SYMBOL(bman_release);
126805 +
126806 +static inline int __bman_acquire(struct bman_pool *pool, struct bm_buffer *bufs,
126807 + u8 num)
126808 +{
126809 + struct bman_portal *p = get_affine_portal();
126810 + struct bm_mc_command *mcc;
126811 + struct bm_mc_result *mcr;
126812 + __maybe_unused unsigned long irqflags;
126813 + int ret, i;
126814 +
126815 + PORTAL_IRQ_LOCK(p, irqflags);
126816 + mcc = bm_mc_start(&p->p);
126817 + mcc->acquire.bpid = pool->params.bpid;
126818 + bm_mc_commit(&p->p, BM_MCC_VERB_CMD_ACQUIRE |
126819 + (num & BM_MCC_VERB_ACQUIRE_BUFCOUNT));
126820 + while (!(mcr = bm_mc_result(&p->p)))
126821 + cpu_relax();
126822 + ret = mcr->verb & BM_MCR_VERB_ACQUIRE_BUFCOUNT;
126823 + if (bufs) {
126824 + for (i = 0; i < num; i++)
126825 + bufs[i].opaque =
126826 + be64_to_cpu(mcr->acquire.bufs[i].opaque);
126827 + }
126828 + PORTAL_IRQ_UNLOCK(p, irqflags);
126829 + put_affine_portal();
126830 + if (ret != num)
126831 + ret = -ENOMEM;
126832 + return ret;
126833 +}
126834 +
126835 +int bman_acquire(struct bman_pool *pool, struct bm_buffer *bufs, u8 num,
126836 + u32 flags)
126837 +{
126838 + int ret;
126839 +#ifdef CONFIG_FSL_DPA_CHECKING
126840 + if (!num || (num > 8))
126841 + return -EINVAL;
126842 + if (pool->params.flags & BMAN_POOL_FLAG_ONLY_RELEASE)
126843 + return -EINVAL;
126844 +#endif
126845 + /* Without stockpile, this API is a pass-through to the h/w operation */
126846 + if (!(pool->params.flags & BMAN_POOL_FLAG_STOCKPILE))
126847 + return __bman_acquire(pool, bufs, num);
126848 +#ifdef CONFIG_FSL_DPA_CHECKING
126849 + if (!atomic_dec_and_test(&pool->in_use)) {
126850 + pr_crit("Parallel attempts to enter bman_acquire() detected.");
126851 + panic("only one instance of bman_released/acquired allowed");
126852 + }
126853 +#endif
126854 + /* Two movements of buffers are possible, and can occur in either order.
126855 + * A: moving buffers from stockpile to the caller.
126856 + * B: moving buffers from hardware to the stockpile.
126857 + * Order 1: if there are already enough buffers in the stockpile for A
126858 + * then we want to do A first, and only do B if we trigger the
126859 + * stockpile-low threshold.
126860 + * Order 2: if there are not enough buffers in the stockpile for A,
126861 + * then we want to do B first, then do A if B had succeeded. However in
126862 + * this case B is dependent on how many buffers the user needs, not the
126863 + * stockpile-low threshold.
126864 + * Due to the different handling of B between the two cases, putting A
126865 + * and B in a while() loop would require quite obscure logic, so handle
126866 + * the different sequences explicitly. */
126867 + if (num <= pool->sp_fill) {
126868 + /* Order 1: do A */
126869 + copy_words(bufs, pool->sp + (pool->sp_fill - num),
126870 + sizeof(struct bm_buffer) * num);
126871 + pool->sp_fill -= num;
126872 + /* do B relative to STOCKPILE_LOW */
126873 + while (pool->sp_fill <= BMAN_STOCKPILE_LOW) {
126874 + ret = __bman_acquire(pool, pool->sp + pool->sp_fill, 8);
126875 + if (ret < 0)
126876 + ret = __bman_acquire(pool,
126877 + pool->sp + pool->sp_fill, 1);
126878 + if (ret < 0)
126879 + break;
126880 + pool->sp_fill += ret;
126881 + }
126882 + } else {
126883 + /* Order 2: do B relative to 'num' */
126884 + do {
126885 + ret = __bman_acquire(pool, pool->sp + pool->sp_fill, 8);
126886 + if (ret < 0)
126887 + ret = __bman_acquire(pool,
126888 + pool->sp + pool->sp_fill, 1);
126889 + if (ret < 0)
126890 + /* failure */
126891 + goto acquire_done;
126892 + pool->sp_fill += ret;
126893 + } while (pool->sp_fill < num);
126894 + /* do A */
126895 + copy_words(bufs, pool->sp + (pool->sp_fill - num),
126896 + sizeof(struct bm_buffer) * num);
126897 + pool->sp_fill -= num;
126898 + }
126899 + /* success */
126900 + ret = num;
126901 +acquire_done:
126902 +#ifdef CONFIG_FSL_DPA_CHECKING
126903 + atomic_inc(&pool->in_use);
126904 +#endif
126905 + return ret;
126906 +}
126907 +EXPORT_SYMBOL(bman_acquire);
126908 +
126909 +int bman_flush_stockpile(struct bman_pool *pool, u32 flags)
126910 +{
126911 + u8 num;
126912 + int ret;
126913 +
126914 + while (pool->sp_fill) {
126915 + num = ((pool->sp_fill > 8) ? 8 : pool->sp_fill);
126916 + ret = __bman_release(pool, pool->sp + (pool->sp_fill - num),
126917 + num, flags);
126918 + if (ret)
126919 + return ret;
126920 + pool->sp_fill -= num;
126921 + }
126922 + return 0;
126923 +}
126924 +EXPORT_SYMBOL(bman_flush_stockpile);
126925 +
126926 +int bman_query_pools(struct bm_pool_state *state)
126927 +{
126928 + struct bman_portal *p = get_affine_portal();
126929 + struct bm_mc_result *mcr;
126930 + __maybe_unused unsigned long irqflags;
126931 +
126932 + PORTAL_IRQ_LOCK(p, irqflags);
126933 + bm_mc_start(&p->p);
126934 + bm_mc_commit(&p->p, BM_MCC_VERB_CMD_QUERY);
126935 + while (!(mcr = bm_mc_result(&p->p)))
126936 + cpu_relax();
126937 + DPA_ASSERT((mcr->verb & BM_MCR_VERB_CMD_MASK) == BM_MCR_VERB_CMD_QUERY);
126938 + *state = mcr->query;
126939 + state->as.state.__state[0] = be32_to_cpu(state->as.state.__state[0]);
126940 + state->as.state.__state[1] = be32_to_cpu(state->as.state.__state[1]);
126941 + state->ds.state.__state[0] = be32_to_cpu(state->ds.state.__state[0]);
126942 + state->ds.state.__state[1] = be32_to_cpu(state->ds.state.__state[1]);
126943 + PORTAL_IRQ_UNLOCK(p, irqflags);
126944 + put_affine_portal();
126945 + return 0;
126946 +}
126947 +EXPORT_SYMBOL(bman_query_pools);
126948 +
126949 +#ifdef CONFIG_FSL_BMAN_CONFIG
126950 +u32 bman_query_free_buffers(struct bman_pool *pool)
126951 +{
126952 + return bm_pool_free_buffers(pool->params.bpid);
126953 +}
126954 +EXPORT_SYMBOL(bman_query_free_buffers);
126955 +
126956 +int bman_update_pool_thresholds(struct bman_pool *pool, const u32 *thresholds)
126957 +{
126958 + u32 bpid;
126959 +
126960 + bpid = bman_get_params(pool)->bpid;
126961 +
126962 + return bm_pool_set(bpid, thresholds);
126963 +}
126964 +EXPORT_SYMBOL(bman_update_pool_thresholds);
126965 +#endif
126966 +
126967 +int bman_shutdown_pool(u32 bpid)
126968 +{
126969 + struct bman_portal *p = get_affine_portal();
126970 + __maybe_unused unsigned long irqflags;
126971 + int ret;
126972 +
126973 + PORTAL_IRQ_LOCK(p, irqflags);
126974 + ret = bm_shutdown_pool(&p->p, bpid);
126975 + PORTAL_IRQ_UNLOCK(p, irqflags);
126976 + put_affine_portal();
126977 + return ret;
126978 +}
126979 +EXPORT_SYMBOL(bman_shutdown_pool);
126980 +
126981 +const struct bm_portal_config *bman_get_bm_portal_config(
126982 + struct bman_portal *portal)
126983 +{
126984 + return portal->sharing_redirect ? NULL : portal->config;
126985 +}
126986 --- /dev/null
126987 +++ b/drivers/staging/fsl_qbman/bman_low.h
126988 @@ -0,0 +1,565 @@
126989 +/* Copyright 2008-2011 Freescale Semiconductor, Inc.
126990 + *
126991 + * Redistribution and use in source and binary forms, with or without
126992 + * modification, are permitted provided that the following conditions are met:
126993 + * * Redistributions of source code must retain the above copyright
126994 + * notice, this list of conditions and the following disclaimer.
126995 + * * Redistributions in binary form must reproduce the above copyright
126996 + * notice, this list of conditions and the following disclaimer in the
126997 + * documentation and/or other materials provided with the distribution.
126998 + * * Neither the name of Freescale Semiconductor nor the
126999 + * names of its contributors may be used to endorse or promote products
127000 + * derived from this software without specific prior written permission.
127001 + *
127002 + *
127003 + * ALTERNATIVELY, this software may be distributed under the terms of the
127004 + * GNU General Public License ("GPL") as published by the Free Software
127005 + * Foundation, either version 2 of that License or (at your option) any
127006 + * later version.
127007 + *
127008 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
127009 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
127010 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
127011 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
127012 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
127013 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
127014 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
127015 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
127016 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
127017 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
127018 + */
127019 +
127020 +#include "bman_private.h"
127021 +
127022 +/***************************/
127023 +/* Portal register assists */
127024 +/***************************/
127025 +
127026 +#if defined(CONFIG_PPC32) || defined(CONFIG_PPC64)
127027 +
127028 +/* Cache-inhibited register offsets */
127029 +#define BM_REG_RCR_PI_CINH 0x0000
127030 +#define BM_REG_RCR_CI_CINH 0x0004
127031 +#define BM_REG_RCR_ITR 0x0008
127032 +#define BM_REG_CFG 0x0100
127033 +#define BM_REG_SCN(n) (0x0200 + ((n) << 2))
127034 +#define BM_REG_ISR 0x0e00
127035 +#define BM_REG_IIR 0x0e0c
127036 +
127037 +/* Cache-enabled register offsets */
127038 +#define BM_CL_CR 0x0000
127039 +#define BM_CL_RR0 0x0100
127040 +#define BM_CL_RR1 0x0140
127041 +#define BM_CL_RCR 0x1000
127042 +#define BM_CL_RCR_PI_CENA 0x3000
127043 +#define BM_CL_RCR_CI_CENA 0x3100
127044 +
127045 +#endif
127046 +
127047 +#if defined(CONFIG_ARM) || defined(CONFIG_ARM64)
127048 +
127049 +/* Cache-inhibited register offsets */
127050 +#define BM_REG_RCR_PI_CINH 0x3000
127051 +#define BM_REG_RCR_CI_CINH 0x3100
127052 +#define BM_REG_RCR_ITR 0x3200
127053 +#define BM_REG_CFG 0x3300
127054 +#define BM_REG_SCN(n) (0x3400 + ((n) << 6))
127055 +#define BM_REG_ISR 0x3e00
127056 +#define BM_REG_IIR 0x3ec0
127057 +
127058 +/* Cache-enabled register offsets */
127059 +#define BM_CL_CR 0x0000
127060 +#define BM_CL_RR0 0x0100
127061 +#define BM_CL_RR1 0x0140
127062 +#define BM_CL_RCR 0x1000
127063 +#define BM_CL_RCR_PI_CENA 0x3000
127064 +#define BM_CL_RCR_CI_CENA 0x3100
127065 +
127066 +#endif
127067 +
127068 +/* BTW, the drivers (and h/w programming model) already obtain the required
127069 + * synchronisation for portal accesses via lwsync(), hwsync(), and
127070 + * data-dependencies. Use of barrier()s or other order-preserving primitives
127071 + * simply degrade performance. Hence the use of the __raw_*() interfaces, which
127072 + * simply ensure that the compiler treats the portal registers as volatile (ie.
127073 + * non-coherent). */
127074 +
127075 +/* Cache-inhibited register access. */
127076 +#define __bm_in(bm, o) be32_to_cpu(__raw_readl((bm)->addr_ci + (o)))
127077 +#define __bm_out(bm, o, val) __raw_writel(cpu_to_be32(val), \
127078 + (bm)->addr_ci + (o));
127079 +#define bm_in(reg) __bm_in(&portal->addr, BM_REG_##reg)
127080 +#define bm_out(reg, val) __bm_out(&portal->addr, BM_REG_##reg, val)
127081 +
127082 +/* Cache-enabled (index) register access */
127083 +#define __bm_cl_touch_ro(bm, o) dcbt_ro((bm)->addr_ce + (o))
127084 +#define __bm_cl_touch_rw(bm, o) dcbt_rw((bm)->addr_ce + (o))
127085 +#define __bm_cl_in(bm, o) be32_to_cpu(__raw_readl((bm)->addr_ce + (o)))
127086 +#define __bm_cl_out(bm, o, val) \
127087 + do { \
127088 + u32 *__tmpclout = (bm)->addr_ce + (o); \
127089 + __raw_writel(cpu_to_be32(val), __tmpclout); \
127090 + dcbf(__tmpclout); \
127091 + } while (0)
127092 +#define __bm_cl_invalidate(bm, o) dcbi((bm)->addr_ce + (o))
127093 +#define bm_cl_touch_ro(reg) __bm_cl_touch_ro(&portal->addr, BM_CL_##reg##_CENA)
127094 +#define bm_cl_touch_rw(reg) __bm_cl_touch_rw(&portal->addr, BM_CL_##reg##_CENA)
127095 +#define bm_cl_in(reg) __bm_cl_in(&portal->addr, BM_CL_##reg##_CENA)
127096 +#define bm_cl_out(reg, val) __bm_cl_out(&portal->addr, BM_CL_##reg##_CENA, val)
127097 +#define bm_cl_invalidate(reg)\
127098 + __bm_cl_invalidate(&portal->addr, BM_CL_##reg##_CENA)
127099 +
127100 +/* Cyclic helper for rings. FIXME: once we are able to do fine-grain perf
127101 + * analysis, look at using the "extra" bit in the ring index registers to avoid
127102 + * cyclic issues. */
127103 +static inline u8 bm_cyc_diff(u8 ringsize, u8 first, u8 last)
127104 +{
127105 + /* 'first' is included, 'last' is excluded */
127106 + if (first <= last)
127107 + return last - first;
127108 + return ringsize + last - first;
127109 +}
127110 +
127111 +/* Portal modes.
127112 + * Enum types;
127113 + * pmode == production mode
127114 + * cmode == consumption mode,
127115 + * Enum values use 3 letter codes. First letter matches the portal mode,
127116 + * remaining two letters indicate;
127117 + * ci == cache-inhibited portal register
127118 + * ce == cache-enabled portal register
127119 + * vb == in-band valid-bit (cache-enabled)
127120 + */
127121 +enum bm_rcr_pmode { /* matches BCSP_CFG::RPM */
127122 + bm_rcr_pci = 0, /* PI index, cache-inhibited */
127123 + bm_rcr_pce = 1, /* PI index, cache-enabled */
127124 + bm_rcr_pvb = 2 /* valid-bit */
127125 +};
127126 +enum bm_rcr_cmode { /* s/w-only */
127127 + bm_rcr_cci, /* CI index, cache-inhibited */
127128 + bm_rcr_cce /* CI index, cache-enabled */
127129 +};
127130 +
127131 +
127132 +/* ------------------------- */
127133 +/* --- Portal structures --- */
127134 +
127135 +#define BM_RCR_SIZE 8
127136 +
127137 +struct bm_rcr {
127138 + struct bm_rcr_entry *ring, *cursor;
127139 + u8 ci, available, ithresh, vbit;
127140 +#ifdef CONFIG_FSL_DPA_CHECKING
127141 + u32 busy;
127142 + enum bm_rcr_pmode pmode;
127143 + enum bm_rcr_cmode cmode;
127144 +#endif
127145 +};
127146 +
127147 +struct bm_mc {
127148 + struct bm_mc_command *cr;
127149 + struct bm_mc_result *rr;
127150 + u8 rridx, vbit;
127151 +#ifdef CONFIG_FSL_DPA_CHECKING
127152 + enum {
127153 + /* Can only be _mc_start()ed */
127154 + mc_idle,
127155 + /* Can only be _mc_commit()ed or _mc_abort()ed */
127156 + mc_user,
127157 + /* Can only be _mc_retry()ed */
127158 + mc_hw
127159 + } state;
127160 +#endif
127161 +};
127162 +
127163 +struct bm_addr {
127164 + void __iomem *addr_ce; /* cache-enabled */
127165 + void __iomem *addr_ci; /* cache-inhibited */
127166 +};
127167 +
127168 +struct bm_portal {
127169 + struct bm_addr addr;
127170 + struct bm_rcr rcr;
127171 + struct bm_mc mc;
127172 + struct bm_portal_config config;
127173 +} ____cacheline_aligned;
127174 +
127175 +
127176 +/* --------------- */
127177 +/* --- RCR API --- */
127178 +
127179 +/* Bit-wise logic to wrap a ring pointer by clearing the "carry bit" */
127180 +#define RCR_CARRYCLEAR(p) \
127181 + (void *)((unsigned long)(p) & (~(unsigned long)(BM_RCR_SIZE << 6)))
127182 +
127183 +/* Bit-wise logic to convert a ring pointer to a ring index */
127184 +static inline u8 RCR_PTR2IDX(struct bm_rcr_entry *e)
127185 +{
127186 + return ((uintptr_t)e >> 6) & (BM_RCR_SIZE - 1);
127187 +}
127188 +
127189 +/* Increment the 'cursor' ring pointer, taking 'vbit' into account */
127190 +static inline void RCR_INC(struct bm_rcr *rcr)
127191 +{
127192 + /* NB: this is odd-looking, but experiments show that it generates
127193 + * fast code with essentially no branching overheads. We increment to
127194 + * the next RCR pointer and handle overflow and 'vbit'. */
127195 + struct bm_rcr_entry *partial = rcr->cursor + 1;
127196 + rcr->cursor = RCR_CARRYCLEAR(partial);
127197 + if (partial != rcr->cursor)
127198 + rcr->vbit ^= BM_RCR_VERB_VBIT;
127199 +}
127200 +
127201 +static inline int bm_rcr_init(struct bm_portal *portal, enum bm_rcr_pmode pmode,
127202 + __maybe_unused enum bm_rcr_cmode cmode)
127203 +{
127204 + /* This use of 'register', as well as all other occurrences, is because
127205 + * it has been observed to generate much faster code with gcc than is
127206 + * otherwise the case. */
127207 + register struct bm_rcr *rcr = &portal->rcr;
127208 + u32 cfg;
127209 + u8 pi;
127210 +
127211 + rcr->ring = portal->addr.addr_ce + BM_CL_RCR;
127212 + rcr->ci = bm_in(RCR_CI_CINH) & (BM_RCR_SIZE - 1);
127213 +
127214 + pi = bm_in(RCR_PI_CINH) & (BM_RCR_SIZE - 1);
127215 + rcr->cursor = rcr->ring + pi;
127216 + rcr->vbit = (bm_in(RCR_PI_CINH) & BM_RCR_SIZE) ? BM_RCR_VERB_VBIT : 0;
127217 + rcr->available = BM_RCR_SIZE - 1
127218 + - bm_cyc_diff(BM_RCR_SIZE, rcr->ci, pi);
127219 + rcr->ithresh = bm_in(RCR_ITR);
127220 +#ifdef CONFIG_FSL_DPA_CHECKING
127221 + rcr->busy = 0;
127222 + rcr->pmode = pmode;
127223 + rcr->cmode = cmode;
127224 +#endif
127225 + cfg = (bm_in(CFG) & 0xffffffe0) | (pmode & 0x3); /* BCSP_CFG::RPM */
127226 + bm_out(CFG, cfg);
127227 + return 0;
127228 +}
127229 +
127230 +static inline void bm_rcr_finish(struct bm_portal *portal)
127231 +{
127232 + register struct bm_rcr *rcr = &portal->rcr;
127233 + u8 pi = bm_in(RCR_PI_CINH) & (BM_RCR_SIZE - 1);
127234 + u8 ci = bm_in(RCR_CI_CINH) & (BM_RCR_SIZE - 1);
127235 + DPA_ASSERT(!rcr->busy);
127236 + if (pi != RCR_PTR2IDX(rcr->cursor))
127237 + pr_crit("losing uncommited RCR entries\n");
127238 + if (ci != rcr->ci)
127239 + pr_crit("missing existing RCR completions\n");
127240 + if (rcr->ci != RCR_PTR2IDX(rcr->cursor))
127241 + pr_crit("RCR destroyed unquiesced\n");
127242 +}
127243 +
127244 +static inline struct bm_rcr_entry *bm_rcr_start(struct bm_portal *portal)
127245 +{
127246 + register struct bm_rcr *rcr = &portal->rcr;
127247 + DPA_ASSERT(!rcr->busy);
127248 + if (!rcr->available)
127249 + return NULL;
127250 +#ifdef CONFIG_FSL_DPA_CHECKING
127251 + rcr->busy = 1;
127252 +#endif
127253 +#if defined(CONFIG_PPC32) || defined(CONFIG_PPC64)
127254 + dcbz_64(rcr->cursor);
127255 +#endif
127256 + return rcr->cursor;
127257 +}
127258 +
127259 +static inline void bm_rcr_abort(struct bm_portal *portal)
127260 +{
127261 + __maybe_unused register struct bm_rcr *rcr = &portal->rcr;
127262 + DPA_ASSERT(rcr->busy);
127263 +#ifdef CONFIG_FSL_DPA_CHECKING
127264 + rcr->busy = 0;
127265 +#endif
127266 +}
127267 +
127268 +static inline struct bm_rcr_entry *bm_rcr_pend_and_next(
127269 + struct bm_portal *portal, u8 myverb)
127270 +{
127271 + register struct bm_rcr *rcr = &portal->rcr;
127272 + DPA_ASSERT(rcr->busy);
127273 + DPA_ASSERT(rcr->pmode != bm_rcr_pvb);
127274 + if (rcr->available == 1)
127275 + return NULL;
127276 + rcr->cursor->__dont_write_directly__verb = myverb | rcr->vbit;
127277 + dcbf_64(rcr->cursor);
127278 + RCR_INC(rcr);
127279 + rcr->available--;
127280 +#if defined(CONFIG_PPC32) || defined(CONFIG_PPC64)
127281 + dcbz_64(rcr->cursor);
127282 +#endif
127283 + return rcr->cursor;
127284 +}
127285 +
127286 +static inline void bm_rcr_pci_commit(struct bm_portal *portal, u8 myverb)
127287 +{
127288 + register struct bm_rcr *rcr = &portal->rcr;
127289 + DPA_ASSERT(rcr->busy);
127290 + DPA_ASSERT(rcr->pmode == bm_rcr_pci);
127291 + rcr->cursor->__dont_write_directly__verb = myverb | rcr->vbit;
127292 + RCR_INC(rcr);
127293 + rcr->available--;
127294 + hwsync();
127295 + bm_out(RCR_PI_CINH, RCR_PTR2IDX(rcr->cursor));
127296 +#ifdef CONFIG_FSL_DPA_CHECKING
127297 + rcr->busy = 0;
127298 +#endif
127299 +}
127300 +
127301 +static inline void bm_rcr_pce_prefetch(struct bm_portal *portal)
127302 +{
127303 + __maybe_unused register struct bm_rcr *rcr = &portal->rcr;
127304 + DPA_ASSERT(rcr->pmode == bm_rcr_pce);
127305 + bm_cl_invalidate(RCR_PI);
127306 + bm_cl_touch_rw(RCR_PI);
127307 +}
127308 +
127309 +static inline void bm_rcr_pce_commit(struct bm_portal *portal, u8 myverb)
127310 +{
127311 + register struct bm_rcr *rcr = &portal->rcr;
127312 + DPA_ASSERT(rcr->busy);
127313 + DPA_ASSERT(rcr->pmode == bm_rcr_pce);
127314 + rcr->cursor->__dont_write_directly__verb = myverb | rcr->vbit;
127315 + RCR_INC(rcr);
127316 + rcr->available--;
127317 + lwsync();
127318 + bm_cl_out(RCR_PI, RCR_PTR2IDX(rcr->cursor));
127319 +#ifdef CONFIG_FSL_DPA_CHECKING
127320 + rcr->busy = 0;
127321 +#endif
127322 +}
127323 +
127324 +static inline void bm_rcr_pvb_commit(struct bm_portal *portal, u8 myverb)
127325 +{
127326 + register struct bm_rcr *rcr = &portal->rcr;
127327 + struct bm_rcr_entry *rcursor;
127328 + DPA_ASSERT(rcr->busy);
127329 + DPA_ASSERT(rcr->pmode == bm_rcr_pvb);
127330 + lwsync();
127331 + rcursor = rcr->cursor;
127332 + rcursor->__dont_write_directly__verb = myverb | rcr->vbit;
127333 + dcbf_64(rcursor);
127334 + RCR_INC(rcr);
127335 + rcr->available--;
127336 +#ifdef CONFIG_FSL_DPA_CHECKING
127337 + rcr->busy = 0;
127338 +#endif
127339 +}
127340 +
127341 +static inline u8 bm_rcr_cci_update(struct bm_portal *portal)
127342 +{
127343 + register struct bm_rcr *rcr = &portal->rcr;
127344 + u8 diff, old_ci = rcr->ci;
127345 + DPA_ASSERT(rcr->cmode == bm_rcr_cci);
127346 + rcr->ci = bm_in(RCR_CI_CINH) & (BM_RCR_SIZE - 1);
127347 + diff = bm_cyc_diff(BM_RCR_SIZE, old_ci, rcr->ci);
127348 + rcr->available += diff;
127349 + return diff;
127350 +}
127351 +
127352 +static inline void bm_rcr_cce_prefetch(struct bm_portal *portal)
127353 +{
127354 + __maybe_unused register struct bm_rcr *rcr = &portal->rcr;
127355 + DPA_ASSERT(rcr->cmode == bm_rcr_cce);
127356 + bm_cl_touch_ro(RCR_CI);
127357 +}
127358 +
127359 +static inline u8 bm_rcr_cce_update(struct bm_portal *portal)
127360 +{
127361 + register struct bm_rcr *rcr = &portal->rcr;
127362 + u8 diff, old_ci = rcr->ci;
127363 + DPA_ASSERT(rcr->cmode == bm_rcr_cce);
127364 + rcr->ci = bm_cl_in(RCR_CI) & (BM_RCR_SIZE - 1);
127365 + bm_cl_invalidate(RCR_CI);
127366 + diff = bm_cyc_diff(BM_RCR_SIZE, old_ci, rcr->ci);
127367 + rcr->available += diff;
127368 + return diff;
127369 +}
127370 +
127371 +static inline u8 bm_rcr_get_ithresh(struct bm_portal *portal)
127372 +{
127373 + register struct bm_rcr *rcr = &portal->rcr;
127374 + return rcr->ithresh;
127375 +}
127376 +
127377 +static inline void bm_rcr_set_ithresh(struct bm_portal *portal, u8 ithresh)
127378 +{
127379 + register struct bm_rcr *rcr = &portal->rcr;
127380 + rcr->ithresh = ithresh;
127381 + bm_out(RCR_ITR, ithresh);
127382 +}
127383 +
127384 +static inline u8 bm_rcr_get_avail(struct bm_portal *portal)
127385 +{
127386 + register struct bm_rcr *rcr = &portal->rcr;
127387 + return rcr->available;
127388 +}
127389 +
127390 +static inline u8 bm_rcr_get_fill(struct bm_portal *portal)
127391 +{
127392 + register struct bm_rcr *rcr = &portal->rcr;
127393 + return BM_RCR_SIZE - 1 - rcr->available;
127394 +}
127395 +
127396 +
127397 +/* ------------------------------ */
127398 +/* --- Management command API --- */
127399 +
127400 +static inline int bm_mc_init(struct bm_portal *portal)
127401 +{
127402 + register struct bm_mc *mc = &portal->mc;
127403 + mc->cr = portal->addr.addr_ce + BM_CL_CR;
127404 + mc->rr = portal->addr.addr_ce + BM_CL_RR0;
127405 + mc->rridx = (__raw_readb(&mc->cr->__dont_write_directly__verb) &
127406 + BM_MCC_VERB_VBIT) ? 0 : 1;
127407 + mc->vbit = mc->rridx ? BM_MCC_VERB_VBIT : 0;
127408 +#ifdef CONFIG_FSL_DPA_CHECKING
127409 + mc->state = mc_idle;
127410 +#endif
127411 + return 0;
127412 +}
127413 +
127414 +static inline void bm_mc_finish(struct bm_portal *portal)
127415 +{
127416 + __maybe_unused register struct bm_mc *mc = &portal->mc;
127417 + DPA_ASSERT(mc->state == mc_idle);
127418 +#ifdef CONFIG_FSL_DPA_CHECKING
127419 + if (mc->state != mc_idle)
127420 + pr_crit("Losing incomplete MC command\n");
127421 +#endif
127422 +}
127423 +
127424 +static inline struct bm_mc_command *bm_mc_start(struct bm_portal *portal)
127425 +{
127426 + register struct bm_mc *mc = &portal->mc;
127427 + DPA_ASSERT(mc->state == mc_idle);
127428 +#ifdef CONFIG_FSL_DPA_CHECKING
127429 + mc->state = mc_user;
127430 +#endif
127431 +#if defined(CONFIG_PPC32) || defined(CONFIG_PPC64)
127432 + dcbz_64(mc->cr);
127433 +#endif
127434 + return mc->cr;
127435 +}
127436 +
127437 +static inline void bm_mc_abort(struct bm_portal *portal)
127438 +{
127439 + __maybe_unused register struct bm_mc *mc = &portal->mc;
127440 + DPA_ASSERT(mc->state == mc_user);
127441 +#ifdef CONFIG_FSL_DPA_CHECKING
127442 + mc->state = mc_idle;
127443 +#endif
127444 +}
127445 +
127446 +static inline void bm_mc_commit(struct bm_portal *portal, u8 myverb)
127447 +{
127448 + register struct bm_mc *mc = &portal->mc;
127449 + struct bm_mc_result *rr = mc->rr + mc->rridx;
127450 + DPA_ASSERT(mc->state == mc_user);
127451 + lwsync();
127452 + mc->cr->__dont_write_directly__verb = myverb | mc->vbit;
127453 + dcbf(mc->cr);
127454 + dcbit_ro(rr);
127455 +#ifdef CONFIG_FSL_DPA_CHECKING
127456 + mc->state = mc_hw;
127457 +#endif
127458 +}
127459 +
127460 +static inline struct bm_mc_result *bm_mc_result(struct bm_portal *portal)
127461 +{
127462 + register struct bm_mc *mc = &portal->mc;
127463 + struct bm_mc_result *rr = mc->rr + mc->rridx;
127464 + DPA_ASSERT(mc->state == mc_hw);
127465 + /* The inactive response register's verb byte always returns zero until
127466 + * its command is submitted and completed. This includes the valid-bit,
127467 + * in case you were wondering... */
127468 + if (!__raw_readb(&rr->verb)) {
127469 + dcbit_ro(rr);
127470 + return NULL;
127471 + }
127472 + mc->rridx ^= 1;
127473 + mc->vbit ^= BM_MCC_VERB_VBIT;
127474 +#ifdef CONFIG_FSL_DPA_CHECKING
127475 + mc->state = mc_idle;
127476 +#endif
127477 + return rr;
127478 +}
127479 +
127480 +
127481 +/* ------------------------------------- */
127482 +/* --- Portal interrupt register API --- */
127483 +
127484 +static inline int bm_isr_init(__always_unused struct bm_portal *portal)
127485 +{
127486 + return 0;
127487 +}
127488 +
127489 +static inline void bm_isr_finish(__always_unused struct bm_portal *portal)
127490 +{
127491 +}
127492 +
127493 +#define SCN_REG(bpid) BM_REG_SCN((bpid) / 32)
127494 +#define SCN_BIT(bpid) (0x80000000 >> (bpid & 31))
127495 +static inline void bm_isr_bscn_mask(struct bm_portal *portal, u8 bpid,
127496 + int enable)
127497 +{
127498 + u32 val;
127499 + DPA_ASSERT(bpid < bman_pool_max);
127500 + /* REG_SCN for bpid=0..31, REG_SCN+4 for bpid=32..63 */
127501 + val = __bm_in(&portal->addr, SCN_REG(bpid));
127502 + if (enable)
127503 + val |= SCN_BIT(bpid);
127504 + else
127505 + val &= ~SCN_BIT(bpid);
127506 + __bm_out(&portal->addr, SCN_REG(bpid), val);
127507 +}
127508 +
127509 +static inline u32 __bm_isr_read(struct bm_portal *portal, enum bm_isr_reg n)
127510 +{
127511 +#if defined(CONFIG_ARM) || defined(CONFIG_ARM64)
127512 + return __bm_in(&portal->addr, BM_REG_ISR + (n << 6));
127513 +#else
127514 + return __bm_in(&portal->addr, BM_REG_ISR + (n << 2));
127515 +#endif
127516 +}
127517 +
127518 +static inline void __bm_isr_write(struct bm_portal *portal, enum bm_isr_reg n,
127519 + u32 val)
127520 +{
127521 +#if defined(CONFIG_ARM) || defined(CONFIG_ARM64)
127522 + __bm_out(&portal->addr, BM_REG_ISR + (n << 6), val);
127523 +#else
127524 + __bm_out(&portal->addr, BM_REG_ISR + (n << 2), val);
127525 +#endif
127526 +}
127527 +
127528 +/* Buffer Pool Cleanup */
127529 +static inline int bm_shutdown_pool(struct bm_portal *p, u32 bpid)
127530 +{
127531 + struct bm_mc_command *bm_cmd;
127532 + struct bm_mc_result *bm_res;
127533 +
127534 + int aq_count = 0;
127535 + bool stop = false;
127536 + while (!stop) {
127537 + /* Acquire buffers until empty */
127538 + bm_cmd = bm_mc_start(p);
127539 + bm_cmd->acquire.bpid = bpid;
127540 + bm_mc_commit(p, BM_MCC_VERB_CMD_ACQUIRE | 1);
127541 + while (!(bm_res = bm_mc_result(p)))
127542 + cpu_relax();
127543 + if (!(bm_res->verb & BM_MCR_VERB_ACQUIRE_BUFCOUNT)) {
127544 + /* Pool is empty */
127545 + /* TBD : Should we do a few extra iterations in
127546 + case some other some blocks keep buffers 'on deck',
127547 + which may also be problematic */
127548 + stop = true;
127549 + } else
127550 + ++aq_count;
127551 + }
127552 + return 0;
127553 +}
127554 --- /dev/null
127555 +++ b/drivers/staging/fsl_qbman/bman_private.h
127556 @@ -0,0 +1,166 @@
127557 +/* Copyright 2008-2012 Freescale Semiconductor, Inc.
127558 + *
127559 + * Redistribution and use in source and binary forms, with or without
127560 + * modification, are permitted provided that the following conditions are met:
127561 + * * Redistributions of source code must retain the above copyright
127562 + * notice, this list of conditions and the following disclaimer.
127563 + * * Redistributions in binary form must reproduce the above copyright
127564 + * notice, this list of conditions and the following disclaimer in the
127565 + * documentation and/or other materials provided with the distribution.
127566 + * * Neither the name of Freescale Semiconductor nor the
127567 + * names of its contributors may be used to endorse or promote products
127568 + * derived from this software without specific prior written permission.
127569 + *
127570 + *
127571 + * ALTERNATIVELY, this software may be distributed under the terms of the
127572 + * GNU General Public License ("GPL") as published by the Free Software
127573 + * Foundation, either version 2 of that License or (at your option) any
127574 + * later version.
127575 + *
127576 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
127577 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
127578 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
127579 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
127580 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
127581 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
127582 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
127583 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
127584 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
127585 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
127586 + */
127587 +
127588 +#include "dpa_sys.h"
127589 +#include <linux/fsl_bman.h>
127590 +
127591 +/* Revision info (for errata and feature handling) */
127592 +#define BMAN_REV10 0x0100
127593 +#define BMAN_REV20 0x0200
127594 +#define BMAN_REV21 0x0201
127595 +#define QBMAN_ANY_PORTAL_IDX 0xffffffff
127596 +extern u16 bman_ip_rev; /* 0 if uninitialised, otherwise QMAN_REVx */
127597 +
127598 +/*
127599 + * Global variables of the max portal/pool number this bman version supported
127600 + */
127601 +extern u16 bman_pool_max;
127602 +
127603 +/* used by CCSR and portal interrupt code */
127604 +enum bm_isr_reg {
127605 + bm_isr_status = 0,
127606 + bm_isr_enable = 1,
127607 + bm_isr_disable = 2,
127608 + bm_isr_inhibit = 3
127609 +};
127610 +
127611 +struct bm_portal_config {
127612 + /* Corenet portal addresses;
127613 + * [0]==cache-enabled, [1]==cache-inhibited. */
127614 + __iomem void *addr_virt[2];
127615 + struct resource addr_phys[2];
127616 + /* Allow these to be joined in lists */
127617 + struct list_head list;
127618 + /* User-visible portal configuration settings */
127619 + struct bman_portal_config public_cfg;
127620 + /* power management saved data */
127621 + u32 saved_isdr;
127622 +};
127623 +
127624 +#ifdef CONFIG_FSL_BMAN_CONFIG
127625 +/* Hooks from bman_driver.c to bman_config.c */
127626 +int bman_init_ccsr(struct device_node *node);
127627 +#endif
127628 +
127629 +/* Hooks from bman_driver.c in to bman_high.c */
127630 +struct bman_portal *bman_create_portal(
127631 + struct bman_portal *portal,
127632 + const struct bm_portal_config *config);
127633 +struct bman_portal *bman_create_affine_portal(
127634 + const struct bm_portal_config *config);
127635 +struct bman_portal *bman_create_affine_slave(struct bman_portal *redirect,
127636 + int cpu);
127637 +void bman_destroy_portal(struct bman_portal *bm);
127638 +
127639 +const struct bm_portal_config *bman_destroy_affine_portal(void);
127640 +
127641 +/* Hooks from fsl_usdpaa.c to bman_driver.c */
127642 +struct bm_portal_config *bm_get_unused_portal(void);
127643 +struct bm_portal_config *bm_get_unused_portal_idx(uint32_t idx);
127644 +void bm_put_unused_portal(struct bm_portal_config *pcfg);
127645 +void bm_set_liodns(struct bm_portal_config *pcfg);
127646 +
127647 +/* Pool logic in the portal driver, during initialisation, needs to know if
127648 + * there's access to CCSR or not (if not, it'll cripple the pool allocator). */
127649 +#ifdef CONFIG_FSL_BMAN_CONFIG
127650 +int bman_have_ccsr(void);
127651 +#else
127652 +#define bman_have_ccsr() 0
127653 +#endif
127654 +
127655 +/* Stockpile build constants. The _LOW value: when bman_acquire() is called and
127656 + * the stockpile fill-level is <= _LOW, an acquire is attempted from h/w but it
127657 + * might fail (if the buffer pool is depleted). So this value provides some
127658 + * "stagger" in that the bman_acquire() function will only fail if lots of bufs
127659 + * are requested at once or if h/w has been tested a couple of times without
127660 + * luck. The _HIGH value: when bman_release() is called and the stockpile
127661 + * fill-level is >= _HIGH, a release is attempted to h/w but it might fail (if
127662 + * the release ring is full). So this value provides some "stagger" so that
127663 + * ring-access is retried a couple of times prior to the API returning a
127664 + * failure. The following *must* be true;
127665 + * BMAN_STOCKPILE_HIGH-BMAN_STOCKPILE_LOW > 8
127666 + * (to avoid thrashing)
127667 + * BMAN_STOCKPILE_SZ >= 16
127668 + * (as the release logic expects to either send 8 buffers to hw prior to
127669 + * adding the given buffers to the stockpile or add the buffers to the
127670 + * stockpile before sending 8 to hw, as the API must be an all-or-nothing
127671 + * success/fail.)
127672 + */
127673 +#define BMAN_STOCKPILE_SZ 16u /* number of bufs in per-pool cache */
127674 +#define BMAN_STOCKPILE_LOW 2u /* when fill is <= this, acquire from hw */
127675 +#define BMAN_STOCKPILE_HIGH 14u /* when fill is >= this, release to hw */
127676 +
127677 +/*************************************************/
127678 +/* BMan s/w corenet portal, low-level i/face */
127679 +/*************************************************/
127680 +
127681 +/* Used by all portal interrupt registers except 'inhibit'
127682 + * This mask contains all the "irqsource" bits visible to API users
127683 + */
127684 +#define BM_PIRQ_VISIBLE (BM_PIRQ_RCRI | BM_PIRQ_BSCN)
127685 +
127686 +/* These are bm_<reg>_<verb>(). So for example, bm_disable_write() means "write
127687 + * the disable register" rather than "disable the ability to write". */
127688 +#define bm_isr_status_read(bm) __bm_isr_read(bm, bm_isr_status)
127689 +#define bm_isr_status_clear(bm, m) __bm_isr_write(bm, bm_isr_status, m)
127690 +#define bm_isr_enable_read(bm) __bm_isr_read(bm, bm_isr_enable)
127691 +#define bm_isr_enable_write(bm, v) __bm_isr_write(bm, bm_isr_enable, v)
127692 +#define bm_isr_disable_read(bm) __bm_isr_read(bm, bm_isr_disable)
127693 +#define bm_isr_disable_write(bm, v) __bm_isr_write(bm, bm_isr_disable, v)
127694 +#define bm_isr_inhibit(bm) __bm_isr_write(bm, bm_isr_inhibit, 1)
127695 +#define bm_isr_uninhibit(bm) __bm_isr_write(bm, bm_isr_inhibit, 0)
127696 +
127697 +#ifdef CONFIG_FSL_BMAN_CONFIG
127698 +/* Set depletion thresholds associated with a buffer pool. Requires that the
127699 + * operating system have access to Bman CCSR (ie. compiled in support and
127700 + * run-time access courtesy of the device-tree). */
127701 +int bm_pool_set(u32 bpid, const u32 *thresholds);
127702 +#define BM_POOL_THRESH_SW_ENTER 0
127703 +#define BM_POOL_THRESH_SW_EXIT 1
127704 +#define BM_POOL_THRESH_HW_ENTER 2
127705 +#define BM_POOL_THRESH_HW_EXIT 3
127706 +
127707 +/* Read the free buffer count for a given buffer */
127708 +u32 bm_pool_free_buffers(u32 bpid);
127709 +
127710 +__init int bman_init(void);
127711 +__init int bman_resource_init(void);
127712 +
127713 +const struct bm_portal_config *bman_get_bm_portal_config(
127714 + struct bman_portal *portal);
127715 +
127716 +/* power management */
127717 +#ifdef CONFIG_SUSPEND
127718 +void suspend_unused_bportal(void);
127719 +void resume_unused_bportal(void);
127720 +#endif
127721 +
127722 +#endif /* CONFIG_FSL_BMAN_CONFIG */
127723 --- /dev/null
127724 +++ b/drivers/staging/fsl_qbman/bman_test.c
127725 @@ -0,0 +1,56 @@
127726 +/* Copyright 2008-2011 Freescale Semiconductor, Inc.
127727 + *
127728 + * Redistribution and use in source and binary forms, with or without
127729 + * modification, are permitted provided that the following conditions are met:
127730 + * * Redistributions of source code must retain the above copyright
127731 + * notice, this list of conditions and the following disclaimer.
127732 + * * Redistributions in binary form must reproduce the above copyright
127733 + * notice, this list of conditions and the following disclaimer in the
127734 + * documentation and/or other materials provided with the distribution.
127735 + * * Neither the name of Freescale Semiconductor nor the
127736 + * names of its contributors may be used to endorse or promote products
127737 + * derived from this software without specific prior written permission.
127738 + *
127739 + *
127740 + * ALTERNATIVELY, this software may be distributed under the terms of the
127741 + * GNU General Public License ("GPL") as published by the Free Software
127742 + * Foundation, either version 2 of that License or (at your option) any
127743 + * later version.
127744 + *
127745 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
127746 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
127747 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
127748 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
127749 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
127750 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
127751 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
127752 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
127753 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
127754 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
127755 + */
127756 +
127757 +#include "bman_test.h"
127758 +
127759 +MODULE_AUTHOR("Geoff Thorpe");
127760 +MODULE_LICENSE("Dual BSD/GPL");
127761 +MODULE_DESCRIPTION("Bman testing");
127762 +
127763 +static int test_init(void)
127764 +{
127765 +#ifdef CONFIG_FSL_BMAN_TEST_HIGH
127766 + int loop = 1;
127767 + while (loop--)
127768 + bman_test_high();
127769 +#endif
127770 +#ifdef CONFIG_FSL_BMAN_TEST_THRESH
127771 + bman_test_thresh();
127772 +#endif
127773 + return 0;
127774 +}
127775 +
127776 +static void test_exit(void)
127777 +{
127778 +}
127779 +
127780 +module_init(test_init);
127781 +module_exit(test_exit);
127782 --- /dev/null
127783 +++ b/drivers/staging/fsl_qbman/bman_test.h
127784 @@ -0,0 +1,44 @@
127785 +/* Copyright 2008-2011 Freescale Semiconductor, Inc.
127786 + *
127787 + * Redistribution and use in source and binary forms, with or without
127788 + * modification, are permitted provided that the following conditions are met:
127789 + * * Redistributions of source code must retain the above copyright
127790 + * notice, this list of conditions and the following disclaimer.
127791 + * * Redistributions in binary form must reproduce the above copyright
127792 + * notice, this list of conditions and the following disclaimer in the
127793 + * documentation and/or other materials provided with the distribution.
127794 + * * Neither the name of Freescale Semiconductor nor the
127795 + * names of its contributors may be used to endorse or promote products
127796 + * derived from this software without specific prior written permission.
127797 + *
127798 + *
127799 + * ALTERNATIVELY, this software may be distributed under the terms of the
127800 + * GNU General Public License ("GPL") as published by the Free Software
127801 + * Foundation, either version 2 of that License or (at your option) any
127802 + * later version.
127803 + *
127804 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
127805 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
127806 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
127807 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
127808 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
127809 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
127810 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
127811 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
127812 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
127813 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
127814 + */
127815 +
127816 +#include <linux/kernel.h>
127817 +#include <linux/errno.h>
127818 +#include <linux/io.h>
127819 +#include <linux/slab.h>
127820 +#include <linux/module.h>
127821 +#include <linux/interrupt.h>
127822 +#include <linux/delay.h>
127823 +#include <linux/kthread.h>
127824 +
127825 +#include <linux/fsl_bman.h>
127826 +
127827 +void bman_test_high(void);
127828 +void bman_test_thresh(void);
127829 --- /dev/null
127830 +++ b/drivers/staging/fsl_qbman/bman_test_high.c
127831 @@ -0,0 +1,183 @@
127832 +/* Copyright 2008-2011 Freescale Semiconductor, Inc.
127833 + *
127834 + * Redistribution and use in source and binary forms, with or without
127835 + * modification, are permitted provided that the following conditions are met:
127836 + * * Redistributions of source code must retain the above copyright
127837 + * notice, this list of conditions and the following disclaimer.
127838 + * * Redistributions in binary form must reproduce the above copyright
127839 + * notice, this list of conditions and the following disclaimer in the
127840 + * documentation and/or other materials provided with the distribution.
127841 + * * Neither the name of Freescale Semiconductor nor the
127842 + * names of its contributors may be used to endorse or promote products
127843 + * derived from this software without specific prior written permission.
127844 + *
127845 + *
127846 + * ALTERNATIVELY, this software may be distributed under the terms of the
127847 + * GNU General Public License ("GPL") as published by the Free Software
127848 + * Foundation, either version 2 of that License or (at your option) any
127849 + * later version.
127850 + *
127851 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
127852 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
127853 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
127854 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
127855 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
127856 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
127857 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
127858 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
127859 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
127860 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
127861 + */
127862 +
127863 +#include "bman_test.h"
127864 +#include "bman_private.h"
127865 +
127866 +/*************/
127867 +/* constants */
127868 +/*************/
127869 +
127870 +#define PORTAL_OPAQUE ((void *)0xf00dbeef)
127871 +#define POOL_OPAQUE ((void *)0xdeadabba)
127872 +#define NUM_BUFS 93
127873 +#define LOOPS 3
127874 +#define BMAN_TOKEN_MASK 0x00FFFFFFFFFFLLU
127875 +
127876 +/***************/
127877 +/* global vars */
127878 +/***************/
127879 +
127880 +static struct bman_pool *pool;
127881 +static int depleted;
127882 +static struct bm_buffer bufs_in[NUM_BUFS] ____cacheline_aligned;
127883 +static struct bm_buffer bufs_out[NUM_BUFS] ____cacheline_aligned;
127884 +static int bufs_received;
127885 +
127886 +/* Predeclare the callback so we can instantiate pool parameters */
127887 +static void depletion_cb(struct bman_portal *, struct bman_pool *, void *, int);
127888 +
127889 +/**********************/
127890 +/* internal functions */
127891 +/**********************/
127892 +
127893 +static void bufs_init(void)
127894 +{
127895 + int i;
127896 + for (i = 0; i < NUM_BUFS; i++)
127897 + bm_buffer_set64(&bufs_in[i], 0xfedc01234567LLU * i);
127898 + bufs_received = 0;
127899 +}
127900 +
127901 +static inline int bufs_cmp(const struct bm_buffer *a, const struct bm_buffer *b)
127902 +{
127903 + if ((bman_ip_rev == BMAN_REV20) || (bman_ip_rev == BMAN_REV21)) {
127904 +
127905 + /* On SoCs with Bman revison 2.0, Bman only respects the 40
127906 + * LS-bits of buffer addresses, masking off the upper 8-bits on
127907 + * release commands. The API provides for 48-bit addresses
127908 + * because some SoCs support all 48-bits. When generating
127909 + * garbage addresses for testing, we either need to zero the
127910 + * upper 8-bits when releasing to Bman (otherwise we'll be
127911 + * disappointed when the buffers we acquire back from Bman
127912 + * don't match), or we need to mask the upper 8-bits off when
127913 + * comparing. We do the latter.
127914 + */
127915 + if ((bm_buffer_get64(a) & BMAN_TOKEN_MASK)
127916 + < (bm_buffer_get64(b) & BMAN_TOKEN_MASK))
127917 + return -1;
127918 + if ((bm_buffer_get64(a) & BMAN_TOKEN_MASK)
127919 + > (bm_buffer_get64(b) & BMAN_TOKEN_MASK))
127920 + return 1;
127921 + } else {
127922 + if (bm_buffer_get64(a) < bm_buffer_get64(b))
127923 + return -1;
127924 + if (bm_buffer_get64(a) > bm_buffer_get64(b))
127925 + return 1;
127926 + }
127927 +
127928 + return 0;
127929 +}
127930 +
127931 +static void bufs_confirm(void)
127932 +{
127933 + int i, j;
127934 + for (i = 0; i < NUM_BUFS; i++) {
127935 + int matches = 0;
127936 + for (j = 0; j < NUM_BUFS; j++)
127937 + if (!bufs_cmp(&bufs_in[i], &bufs_out[j]))
127938 + matches++;
127939 + BUG_ON(matches != 1);
127940 + }
127941 +}
127942 +
127943 +/********/
127944 +/* test */
127945 +/********/
127946 +
127947 +static void depletion_cb(struct bman_portal *__portal, struct bman_pool *__pool,
127948 + void *pool_ctx, int __depleted)
127949 +{
127950 + BUG_ON(__pool != pool);
127951 + BUG_ON(pool_ctx != POOL_OPAQUE);
127952 + depleted = __depleted;
127953 +}
127954 +
127955 +void bman_test_high(void)
127956 +{
127957 + struct bman_pool_params pparams = {
127958 + .flags = BMAN_POOL_FLAG_DEPLETION | BMAN_POOL_FLAG_DYNAMIC_BPID,
127959 + .cb = depletion_cb,
127960 + .cb_ctx = POOL_OPAQUE,
127961 + };
127962 + int i, loops = LOOPS;
127963 + struct bm_buffer tmp_buf;
127964 +
127965 + bufs_init();
127966 +
127967 + pr_info("BMAN: --- starting high-level test ---\n");
127968 +
127969 + pool = bman_new_pool(&pparams);
127970 + BUG_ON(!pool);
127971 +
127972 + /*******************/
127973 + /* Release buffers */
127974 + /*******************/
127975 +do_loop:
127976 + i = 0;
127977 + while (i < NUM_BUFS) {
127978 + u32 flags = BMAN_RELEASE_FLAG_WAIT;
127979 + int num = 8;
127980 + if ((i + num) > NUM_BUFS)
127981 + num = NUM_BUFS - i;
127982 + if ((i + num) == NUM_BUFS)
127983 + flags |= BMAN_RELEASE_FLAG_WAIT_SYNC;
127984 + if (bman_release(pool, bufs_in + i, num, flags))
127985 + panic("bman_release() failed\n");
127986 + i += num;
127987 + }
127988 +
127989 + /*******************/
127990 + /* Acquire buffers */
127991 + /*******************/
127992 + while (i > 0) {
127993 + int tmp, num = 8;
127994 + if (num > i)
127995 + num = i;
127996 + tmp = bman_acquire(pool, bufs_out + i - num, num, 0);
127997 + BUG_ON(tmp != num);
127998 + i -= num;
127999 + }
128000 +
128001 + i = bman_acquire(pool, &tmp_buf, 1, 0);
128002 + BUG_ON(i > 0);
128003 +
128004 + bufs_confirm();
128005 +
128006 + if (--loops)
128007 + goto do_loop;
128008 +
128009 + /************/
128010 + /* Clean up */
128011 + /************/
128012 + bman_free_pool(pool);
128013 + pr_info("BMAN: --- finished high-level test ---\n");
128014 +}
128015 --- /dev/null
128016 +++ b/drivers/staging/fsl_qbman/bman_test_thresh.c
128017 @@ -0,0 +1,196 @@
128018 +/* Copyright 2010-2011 Freescale Semiconductor, Inc.
128019 + *
128020 + * Redistribution and use in source and binary forms, with or without
128021 + * modification, are permitted provided that the following conditions are met:
128022 + * * Redistributions of source code must retain the above copyright
128023 + * notice, this list of conditions and the following disclaimer.
128024 + * * Redistributions in binary form must reproduce the above copyright
128025 + * notice, this list of conditions and the following disclaimer in the
128026 + * documentation and/or other materials provided with the distribution.
128027 + * * Neither the name of Freescale Semiconductor nor the
128028 + * names of its contributors may be used to endorse or promote products
128029 + * derived from this software without specific prior written permission.
128030 + *
128031 + *
128032 + * ALTERNATIVELY, this software may be distributed under the terms of the
128033 + * GNU General Public License ("GPL") as published by the Free Software
128034 + * Foundation, either version 2 of that License or (at your option) any
128035 + * later version.
128036 + *
128037 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
128038 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
128039 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
128040 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
128041 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
128042 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
128043 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
128044 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
128045 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
128046 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
128047 + */
128048 +
128049 +#include "bman_test.h"
128050 +
128051 +/* Test constants */
128052 +#define TEST_NUMBUFS 129728
128053 +#define TEST_EXIT 129536
128054 +#define TEST_ENTRY 129024
128055 +
128056 +struct affine_test_data {
128057 + struct task_struct *t;
128058 + int cpu;
128059 + int expect_affinity;
128060 + int drain;
128061 + int num_enter;
128062 + int num_exit;
128063 + struct list_head node;
128064 + struct completion wakethread;
128065 + struct completion wakeparent;
128066 +};
128067 +
128068 +static void cb_depletion(struct bman_portal *portal,
128069 + struct bman_pool *pool,
128070 + void *opaque,
128071 + int depleted)
128072 +{
128073 + struct affine_test_data *data = opaque;
128074 + int c = smp_processor_id();
128075 + pr_info("cb_depletion: bpid=%d, depleted=%d, cpu=%d, original=%d\n",
128076 + bman_get_params(pool)->bpid, !!depleted, c, data->cpu);
128077 + /* We should be executing on the CPU of the thread that owns the pool if
128078 + * and that CPU has an affine portal (ie. it isn't slaved). */
128079 + BUG_ON((c != data->cpu) && data->expect_affinity);
128080 + BUG_ON((c == data->cpu) && !data->expect_affinity);
128081 + if (depleted)
128082 + data->num_enter++;
128083 + else
128084 + data->num_exit++;
128085 +}
128086 +
128087 +/* Params used to set up a pool, this also dynamically allocates a BPID */
128088 +static const struct bman_pool_params params_nocb = {
128089 + .flags = BMAN_POOL_FLAG_DYNAMIC_BPID | BMAN_POOL_FLAG_THRESH,
128090 + .thresholds = { TEST_ENTRY, TEST_EXIT, 0, 0 }
128091 +};
128092 +
128093 +/* Params used to set up each cpu's pool with callbacks enabled */
128094 +static struct bman_pool_params params_cb = {
128095 + .bpid = 0, /* will be replaced to match pool_nocb */
128096 + .flags = BMAN_POOL_FLAG_DEPLETION,
128097 + .cb = cb_depletion
128098 +};
128099 +
128100 +static struct bman_pool *pool_nocb;
128101 +static LIST_HEAD(threads);
128102 +
128103 +static int affine_test(void *__data)
128104 +{
128105 + struct bman_pool *pool;
128106 + struct affine_test_data *data = __data;
128107 + struct bman_pool_params my_params = params_cb;
128108 +
128109 + pr_info("thread %d: starting\n", data->cpu);
128110 + /* create the pool */
128111 + my_params.cb_ctx = data;
128112 + pool = bman_new_pool(&my_params);
128113 + BUG_ON(!pool);
128114 + complete(&data->wakeparent);
128115 + wait_for_completion(&data->wakethread);
128116 + init_completion(&data->wakethread);
128117 +
128118 + /* if we're the drainer, we get signalled for that */
128119 + if (data->drain) {
128120 + struct bm_buffer buf;
128121 + int ret;
128122 + pr_info("thread %d: draining...\n", data->cpu);
128123 + do {
128124 + ret = bman_acquire(pool, &buf, 1, 0);
128125 + } while (ret > 0);
128126 + pr_info("thread %d: draining done.\n", data->cpu);
128127 + complete(&data->wakeparent);
128128 + wait_for_completion(&data->wakethread);
128129 + init_completion(&data->wakethread);
128130 + }
128131 +
128132 + /* cleanup */
128133 + bman_free_pool(pool);
128134 + while (!kthread_should_stop())
128135 + cpu_relax();
128136 + pr_info("thread %d: exiting\n", data->cpu);
128137 + return 0;
128138 +}
128139 +
128140 +static struct affine_test_data *start_affine_test(int cpu, int drain)
128141 +{
128142 + struct affine_test_data *data = kmalloc(sizeof(*data), GFP_KERNEL);
128143 +
128144 + if (!data)
128145 + return NULL;
128146 + data->cpu = cpu;
128147 + data->expect_affinity = cpumask_test_cpu(cpu, bman_affine_cpus());
128148 + data->drain = drain;
128149 + data->num_enter = 0;
128150 + data->num_exit = 0;
128151 + init_completion(&data->wakethread);
128152 + init_completion(&data->wakeparent);
128153 + list_add_tail(&data->node, &threads);
128154 + data->t = kthread_create(affine_test, data, "threshtest%d", cpu);
128155 + BUG_ON(IS_ERR(data->t));
128156 + kthread_bind(data->t, cpu);
128157 + wake_up_process(data->t);
128158 + return data;
128159 +}
128160 +
128161 +void bman_test_thresh(void)
128162 +{
128163 + int loop = TEST_NUMBUFS;
128164 + int ret, num_cpus = 0;
128165 + struct affine_test_data *data, *drainer = NULL;
128166 +
128167 + pr_info("bman_test_thresh: start\n");
128168 +
128169 + /* allocate a BPID and seed it */
128170 + pool_nocb = bman_new_pool(&params_nocb);
128171 + BUG_ON(!pool_nocb);
128172 + while (loop--) {
128173 + struct bm_buffer buf;
128174 + bm_buffer_set64(&buf, 0x0badbeef + loop);
128175 + ret = bman_release(pool_nocb, &buf, 1,
128176 + BMAN_RELEASE_FLAG_WAIT);
128177 + BUG_ON(ret);
128178 + }
128179 + while (!bman_rcr_is_empty())
128180 + cpu_relax();
128181 + pr_info("bman_test_thresh: buffers are in\n");
128182 +
128183 + /* create threads and wait for them to create pools */
128184 + params_cb.bpid = bman_get_params(pool_nocb)->bpid;
128185 + for_each_cpu(loop, cpu_online_mask) {
128186 + data = start_affine_test(loop, drainer ? 0 : 1);
128187 + BUG_ON(!data);
128188 + if (!drainer)
128189 + drainer = data;
128190 + num_cpus++;
128191 + wait_for_completion(&data->wakeparent);
128192 + }
128193 +
128194 + /* signal the drainer to start draining */
128195 + complete(&drainer->wakethread);
128196 + wait_for_completion(&drainer->wakeparent);
128197 + init_completion(&drainer->wakeparent);
128198 +
128199 + /* tear down */
128200 + list_for_each_entry_safe(data, drainer, &threads, node) {
128201 + complete(&data->wakethread);
128202 + ret = kthread_stop(data->t);
128203 + BUG_ON(ret);
128204 + list_del(&data->node);
128205 + /* check that we get the expected callbacks (and no others) */
128206 + BUG_ON(data->num_enter != 1);
128207 + BUG_ON(data->num_exit != 0);
128208 + kfree(data);
128209 + }
128210 + bman_free_pool(pool_nocb);
128211 +
128212 + pr_info("bman_test_thresh: done\n");
128213 +}
128214 --- /dev/null
128215 +++ b/drivers/staging/fsl_qbman/dpa_alloc.c
128216 @@ -0,0 +1,706 @@
128217 +/* Copyright 2009-2012 Freescale Semiconductor, Inc.
128218 + *
128219 + * Redistribution and use in source and binary forms, with or without
128220 + * modification, are permitted provided that the following conditions are met:
128221 + * * Redistributions of source code must retain the above copyright
128222 + * notice, this list of conditions and the following disclaimer.
128223 + * * Redistributions in binary form must reproduce the above copyright
128224 + * notice, this list of conditions and the following disclaimer in the
128225 + * documentation and/or other materials provided with the distribution.
128226 + * * Neither the name of Freescale Semiconductor nor the
128227 + * names of its contributors may be used to endorse or promote products
128228 + * derived from this software without specific prior written permission.
128229 + *
128230 + *
128231 + * ALTERNATIVELY, this software may be distributed under the terms of the
128232 + * GNU General Public License ("GPL") as published by the Free Software
128233 + * Foundation, either version 2 of that License or (at your option) any
128234 + * later version.
128235 + *
128236 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
128237 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
128238 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
128239 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
128240 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
128241 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
128242 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
128243 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
128244 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
128245 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
128246 + */
128247 +
128248 +#include "dpa_sys.h"
128249 +#include <linux/fsl_qman.h>
128250 +#include <linux/fsl_bman.h>
128251 +
128252 +/* Qman and Bman APIs are front-ends to the common code; */
128253 +
128254 +static DECLARE_DPA_ALLOC(bpalloc); /* BPID allocator */
128255 +static DECLARE_DPA_ALLOC(fqalloc); /* FQID allocator */
128256 +static DECLARE_DPA_ALLOC(qpalloc); /* pool-channel allocator */
128257 +static DECLARE_DPA_ALLOC(cgralloc); /* CGR ID allocator */
128258 +static DECLARE_DPA_ALLOC(ceetm0_challoc); /* CEETM Channel ID allocator */
128259 +static DECLARE_DPA_ALLOC(ceetm0_lfqidalloc); /* CEETM LFQID allocator */
128260 +static DECLARE_DPA_ALLOC(ceetm1_challoc); /* CEETM Channel ID allocator */
128261 +static DECLARE_DPA_ALLOC(ceetm1_lfqidalloc); /* CEETM LFQID allocator */
128262 +
128263 +/* This is a sort-of-conditional dpa_alloc_free() routine. Eg. when releasing
128264 + * FQIDs (probably from user-space), it can filter out those that aren't in the
128265 + * OOS state (better to leak a h/w resource than to crash). This function
128266 + * returns the number of invalid IDs that were not released. */
128267 +static u32 release_id_range(struct dpa_alloc *alloc, u32 id, u32 count,
128268 + int (*is_valid)(u32 id))
128269 +{
128270 + int valid_mode = 0;
128271 + u32 loop = id, total_invalid = 0;
128272 + while (loop < (id + count)) {
128273 + int isvalid = is_valid ? is_valid(loop) : 1;
128274 + if (!valid_mode) {
128275 + /* We're looking for a valid ID to terminate an invalid
128276 + * range */
128277 + if (isvalid) {
128278 + /* We finished a range of invalid IDs, a valid
128279 + * range is now underway */
128280 + valid_mode = 1;
128281 + count -= (loop - id);
128282 + id = loop;
128283 + } else
128284 + total_invalid++;
128285 + } else {
128286 + /* We're looking for an invalid ID to terminate a
128287 + * valid range */
128288 + if (!isvalid) {
128289 + /* Release the range of valid IDs, an unvalid
128290 + * range is now underway */
128291 + if (loop > id)
128292 + dpa_alloc_free(alloc, id, loop - id);
128293 + valid_mode = 0;
128294 + }
128295 + }
128296 + loop++;
128297 + }
128298 + /* Release any unterminated range of valid IDs */
128299 + if (valid_mode && count)
128300 + dpa_alloc_free(alloc, id, count);
128301 + return total_invalid;
128302 +}
128303 +
128304 +/* BPID allocator front-end */
128305 +
128306 +int bman_alloc_bpid_range(u32 *result, u32 count, u32 align, int partial)
128307 +{
128308 + return dpa_alloc_new(&bpalloc, result, count, align, partial);
128309 +}
128310 +EXPORT_SYMBOL(bman_alloc_bpid_range);
128311 +
128312 +static int bp_cleanup(u32 bpid)
128313 +{
128314 + return bman_shutdown_pool(bpid) == 0;
128315 +}
128316 +void bman_release_bpid_range(u32 bpid, u32 count)
128317 +{
128318 + u32 total_invalid = release_id_range(&bpalloc, bpid, count, bp_cleanup);
128319 + if (total_invalid)
128320 + pr_err("BPID range [%d..%d] (%d) had %d leaks\n",
128321 + bpid, bpid + count - 1, count, total_invalid);
128322 +}
128323 +EXPORT_SYMBOL(bman_release_bpid_range);
128324 +
128325 +void bman_seed_bpid_range(u32 bpid, u32 count)
128326 +{
128327 + dpa_alloc_seed(&bpalloc, bpid, count);
128328 +}
128329 +EXPORT_SYMBOL(bman_seed_bpid_range);
128330 +
128331 +int bman_reserve_bpid_range(u32 bpid, u32 count)
128332 +{
128333 + return dpa_alloc_reserve(&bpalloc, bpid, count);
128334 +}
128335 +EXPORT_SYMBOL(bman_reserve_bpid_range);
128336 +
128337 +
128338 +/* FQID allocator front-end */
128339 +
128340 +int qman_alloc_fqid_range(u32 *result, u32 count, u32 align, int partial)
128341 +{
128342 + return dpa_alloc_new(&fqalloc, result, count, align, partial);
128343 +}
128344 +EXPORT_SYMBOL(qman_alloc_fqid_range);
128345 +
128346 +static int fq_cleanup(u32 fqid)
128347 +{
128348 + return qman_shutdown_fq(fqid) == 0;
128349 +}
128350 +void qman_release_fqid_range(u32 fqid, u32 count)
128351 +{
128352 + u32 total_invalid = release_id_range(&fqalloc, fqid, count, fq_cleanup);
128353 + if (total_invalid)
128354 + pr_err("FQID range [%d..%d] (%d) had %d leaks\n",
128355 + fqid, fqid + count - 1, count, total_invalid);
128356 +}
128357 +EXPORT_SYMBOL(qman_release_fqid_range);
128358 +
128359 +int qman_reserve_fqid_range(u32 fqid, u32 count)
128360 +{
128361 + return dpa_alloc_reserve(&fqalloc, fqid, count);
128362 +}
128363 +EXPORT_SYMBOL(qman_reserve_fqid_range);
128364 +
128365 +void qman_seed_fqid_range(u32 fqid, u32 count)
128366 +{
128367 + dpa_alloc_seed(&fqalloc, fqid, count);
128368 +}
128369 +EXPORT_SYMBOL(qman_seed_fqid_range);
128370 +
128371 +/* Pool-channel allocator front-end */
128372 +
128373 +int qman_alloc_pool_range(u32 *result, u32 count, u32 align, int partial)
128374 +{
128375 + return dpa_alloc_new(&qpalloc, result, count, align, partial);
128376 +}
128377 +EXPORT_SYMBOL(qman_alloc_pool_range);
128378 +
128379 +static int qpool_cleanup(u32 qp)
128380 +{
128381 + /* We query all FQDs starting from
128382 + * FQID 1 until we get an "invalid FQID" error, looking for non-OOS FQDs
128383 + * whose destination channel is the pool-channel being released.
128384 + * When a non-OOS FQD is found we attempt to clean it up */
128385 + struct qman_fq fq = {
128386 + .fqid = 1
128387 + };
128388 + int err;
128389 + do {
128390 + struct qm_mcr_queryfq_np np;
128391 + err = qman_query_fq_np(&fq, &np);
128392 + if (err)
128393 + /* FQID range exceeded, found no problems */
128394 + return 1;
128395 + if ((np.state & QM_MCR_NP_STATE_MASK) != QM_MCR_NP_STATE_OOS) {
128396 + struct qm_fqd fqd;
128397 + err = qman_query_fq(&fq, &fqd);
128398 + BUG_ON(err);
128399 + if (fqd.dest.channel == qp) {
128400 + /* The channel is the FQ's target, clean it */
128401 + if (qman_shutdown_fq(fq.fqid) != 0)
128402 + /* Couldn't shut down the FQ
128403 + so the pool must be leaked */
128404 + return 0;
128405 + }
128406 + }
128407 + /* Move to the next FQID */
128408 + fq.fqid++;
128409 + } while (1);
128410 +}
128411 +void qman_release_pool_range(u32 qp, u32 count)
128412 +{
128413 + u32 total_invalid = release_id_range(&qpalloc, qp,
128414 + count, qpool_cleanup);
128415 + if (total_invalid) {
128416 + /* Pool channels are almost always used individually */
128417 + if (count == 1)
128418 + pr_err("Pool channel 0x%x had %d leaks\n",
128419 + qp, total_invalid);
128420 + else
128421 + pr_err("Pool channels [%d..%d] (%d) had %d leaks\n",
128422 + qp, qp + count - 1, count, total_invalid);
128423 + }
128424 +}
128425 +EXPORT_SYMBOL(qman_release_pool_range);
128426 +
128427 +
128428 +void qman_seed_pool_range(u32 poolid, u32 count)
128429 +{
128430 + dpa_alloc_seed(&qpalloc, poolid, count);
128431 +
128432 +}
128433 +EXPORT_SYMBOL(qman_seed_pool_range);
128434 +
128435 +int qman_reserve_pool_range(u32 poolid, u32 count)
128436 +{
128437 + return dpa_alloc_reserve(&qpalloc, poolid, count);
128438 +}
128439 +EXPORT_SYMBOL(qman_reserve_pool_range);
128440 +
128441 +
128442 +/* CGR ID allocator front-end */
128443 +
128444 +int qman_alloc_cgrid_range(u32 *result, u32 count, u32 align, int partial)
128445 +{
128446 + return dpa_alloc_new(&cgralloc, result, count, align, partial);
128447 +}
128448 +EXPORT_SYMBOL(qman_alloc_cgrid_range);
128449 +
128450 +static int cqr_cleanup(u32 cgrid)
128451 +{
128452 + /* We query all FQDs starting from
128453 + * FQID 1 until we get an "invalid FQID" error, looking for non-OOS FQDs
128454 + * whose CGR is the CGR being released.
128455 + */
128456 + struct qman_fq fq = {
128457 + .fqid = 1
128458 + };
128459 + int err;
128460 + do {
128461 + struct qm_mcr_queryfq_np np;
128462 + err = qman_query_fq_np(&fq, &np);
128463 + if (err)
128464 + /* FQID range exceeded, found no problems */
128465 + return 1;
128466 + if ((np.state & QM_MCR_NP_STATE_MASK) != QM_MCR_NP_STATE_OOS) {
128467 + struct qm_fqd fqd;
128468 + err = qman_query_fq(&fq, &fqd);
128469 + BUG_ON(err);
128470 + if ((fqd.fq_ctrl & QM_FQCTRL_CGE) &&
128471 + (fqd.cgid == cgrid)) {
128472 + pr_err("CRGID 0x%x is being used by FQID 0x%x,"
128473 + " CGR will be leaked\n",
128474 + cgrid, fq.fqid);
128475 + return 1;
128476 + }
128477 + }
128478 + /* Move to the next FQID */
128479 + fq.fqid++;
128480 + } while (1);
128481 +}
128482 +
128483 +void qman_release_cgrid_range(u32 cgrid, u32 count)
128484 +{
128485 + u32 total_invalid = release_id_range(&cgralloc, cgrid,
128486 + count, cqr_cleanup);
128487 + if (total_invalid)
128488 + pr_err("CGRID range [%d..%d] (%d) had %d leaks\n",
128489 + cgrid, cgrid + count - 1, count, total_invalid);
128490 +}
128491 +EXPORT_SYMBOL(qman_release_cgrid_range);
128492 +
128493 +void qman_seed_cgrid_range(u32 cgrid, u32 count)
128494 +{
128495 + dpa_alloc_seed(&cgralloc, cgrid, count);
128496 +
128497 +}
128498 +EXPORT_SYMBOL(qman_seed_cgrid_range);
128499 +
128500 +/* CEETM CHANNEL ID allocator front-end */
128501 +int qman_alloc_ceetm0_channel_range(u32 *result, u32 count, u32 align,
128502 + int partial)
128503 +{
128504 + return dpa_alloc_new(&ceetm0_challoc, result, count, align, partial);
128505 +}
128506 +EXPORT_SYMBOL(qman_alloc_ceetm0_channel_range);
128507 +
128508 +int qman_alloc_ceetm1_channel_range(u32 *result, u32 count, u32 align,
128509 + int partial)
128510 +{
128511 + return dpa_alloc_new(&ceetm1_challoc, result, count, align, partial);
128512 +}
128513 +EXPORT_SYMBOL(qman_alloc_ceetm1_channel_range);
128514 +
128515 +void qman_release_ceetm0_channel_range(u32 channelid, u32 count)
128516 +{
128517 + u32 total_invalid;
128518 +
128519 + total_invalid = release_id_range(&ceetm0_challoc, channelid, count,
128520 + NULL);
128521 + if (total_invalid)
128522 + pr_err("CEETM channel range [%d..%d] (%d) had %d leaks\n",
128523 + channelid, channelid + count - 1, count, total_invalid);
128524 +}
128525 +EXPORT_SYMBOL(qman_release_ceetm0_channel_range);
128526 +
128527 +void qman_seed_ceetm0_channel_range(u32 channelid, u32 count)
128528 +{
128529 + dpa_alloc_seed(&ceetm0_challoc, channelid, count);
128530 +
128531 +}
128532 +EXPORT_SYMBOL(qman_seed_ceetm0_channel_range);
128533 +
128534 +void qman_release_ceetm1_channel_range(u32 channelid, u32 count)
128535 +{
128536 + u32 total_invalid;
128537 + total_invalid = release_id_range(&ceetm1_challoc, channelid, count,
128538 + NULL);
128539 + if (total_invalid)
128540 + pr_err("CEETM channel range [%d..%d] (%d) had %d leaks\n",
128541 + channelid, channelid + count - 1, count, total_invalid);
128542 +}
128543 +EXPORT_SYMBOL(qman_release_ceetm1_channel_range);
128544 +
128545 +void qman_seed_ceetm1_channel_range(u32 channelid, u32 count)
128546 +{
128547 + dpa_alloc_seed(&ceetm1_challoc, channelid, count);
128548 +
128549 +}
128550 +EXPORT_SYMBOL(qman_seed_ceetm1_channel_range);
128551 +
128552 +/* CEETM LFQID allocator front-end */
128553 +int qman_alloc_ceetm0_lfqid_range(u32 *result, u32 count, u32 align,
128554 + int partial)
128555 +{
128556 + return dpa_alloc_new(&ceetm0_lfqidalloc, result, count, align, partial);
128557 +}
128558 +EXPORT_SYMBOL(qman_alloc_ceetm0_lfqid_range);
128559 +
128560 +int qman_alloc_ceetm1_lfqid_range(u32 *result, u32 count, u32 align,
128561 + int partial)
128562 +{
128563 + return dpa_alloc_new(&ceetm1_lfqidalloc, result, count, align, partial);
128564 +}
128565 +EXPORT_SYMBOL(qman_alloc_ceetm1_lfqid_range);
128566 +
128567 +void qman_release_ceetm0_lfqid_range(u32 lfqid, u32 count)
128568 +{
128569 + u32 total_invalid;
128570 +
128571 + total_invalid = release_id_range(&ceetm0_lfqidalloc, lfqid, count,
128572 + NULL);
128573 + if (total_invalid)
128574 + pr_err("CEETM LFQID range [0x%x..0x%x] (%d) had %d leaks\n",
128575 + lfqid, lfqid + count - 1, count, total_invalid);
128576 +}
128577 +EXPORT_SYMBOL(qman_release_ceetm0_lfqid_range);
128578 +
128579 +void qman_seed_ceetm0_lfqid_range(u32 lfqid, u32 count)
128580 +{
128581 + dpa_alloc_seed(&ceetm0_lfqidalloc, lfqid, count);
128582 +
128583 +}
128584 +EXPORT_SYMBOL(qman_seed_ceetm0_lfqid_range);
128585 +
128586 +void qman_release_ceetm1_lfqid_range(u32 lfqid, u32 count)
128587 +{
128588 + u32 total_invalid;
128589 +
128590 + total_invalid = release_id_range(&ceetm1_lfqidalloc, lfqid, count,
128591 + NULL);
128592 + if (total_invalid)
128593 + pr_err("CEETM LFQID range [0x%x..0x%x] (%d) had %d leaks\n",
128594 + lfqid, lfqid + count - 1, count, total_invalid);
128595 +}
128596 +EXPORT_SYMBOL(qman_release_ceetm1_lfqid_range);
128597 +
128598 +void qman_seed_ceetm1_lfqid_range(u32 lfqid, u32 count)
128599 +{
128600 + dpa_alloc_seed(&ceetm1_lfqidalloc, lfqid, count);
128601 +
128602 +}
128603 +EXPORT_SYMBOL(qman_seed_ceetm1_lfqid_range);
128604 +
128605 +
128606 +/* Everything else is the common backend to all the allocators */
128607 +
128608 +/* The allocator is a (possibly-empty) list of these; */
128609 +struct alloc_node {
128610 + struct list_head list;
128611 + u32 base;
128612 + u32 num;
128613 + /* refcount and is_alloced are only set
128614 + when the node is in the used list */
128615 + unsigned int refcount;
128616 + int is_alloced;
128617 +};
128618 +
128619 +/* #define DPA_ALLOC_DEBUG */
128620 +
128621 +#ifdef DPA_ALLOC_DEBUG
128622 +#define DPRINT pr_info
128623 +static void DUMP(struct dpa_alloc *alloc)
128624 +{
128625 + int off = 0;
128626 + char buf[256];
128627 + struct alloc_node *p;
128628 + pr_info("Free Nodes\n");
128629 + list_for_each_entry(p, &alloc->free, list) {
128630 + if (off < 255)
128631 + off += snprintf(buf + off, 255-off, "{%d,%d}",
128632 + p->base, p->base + p->num - 1);
128633 + }
128634 + pr_info("%s\n", buf);
128635 +
128636 + off = 0;
128637 + pr_info("Used Nodes\n");
128638 + list_for_each_entry(p, &alloc->used, list) {
128639 + if (off < 255)
128640 + off += snprintf(buf + off, 255-off, "{%d,%d}",
128641 + p->base, p->base + p->num - 1);
128642 + }
128643 + pr_info("%s\n", buf);
128644 +
128645 +
128646 +
128647 +}
128648 +#else
128649 +#define DPRINT(x...)
128650 +#define DUMP(a)
128651 +#endif
128652 +
128653 +int dpa_alloc_new(struct dpa_alloc *alloc, u32 *result, u32 count, u32 align,
128654 + int partial)
128655 +{
128656 + struct alloc_node *i = NULL, *next_best = NULL, *used_node = NULL;
128657 + u32 base, next_best_base = 0, num = 0, next_best_num = 0;
128658 + struct alloc_node *margin_left, *margin_right;
128659 +
128660 + *result = (u32)-1;
128661 + DPRINT("alloc_range(%d,%d,%d)\n", count, align, partial);
128662 + DUMP(alloc);
128663 + /* If 'align' is 0, it should behave as though it was 1 */
128664 + if (!align)
128665 + align = 1;
128666 + margin_left = kmalloc(sizeof(*margin_left), GFP_KERNEL);
128667 + if (!margin_left)
128668 + goto err;
128669 + margin_right = kmalloc(sizeof(*margin_right), GFP_KERNEL);
128670 + if (!margin_right) {
128671 + kfree(margin_left);
128672 + goto err;
128673 + }
128674 + spin_lock_irq(&alloc->lock);
128675 + list_for_each_entry(i, &alloc->free, list) {
128676 + base = (i->base + align - 1) / align;
128677 + base *= align;
128678 + if ((base - i->base) >= i->num)
128679 + /* alignment is impossible, regardless of count */
128680 + continue;
128681 + num = i->num - (base - i->base);
128682 + if (num >= count) {
128683 + /* this one will do nicely */
128684 + num = count;
128685 + goto done;
128686 + }
128687 + if (num > next_best_num) {
128688 + next_best = i;
128689 + next_best_base = base;
128690 + next_best_num = num;
128691 + }
128692 + }
128693 + if (partial && next_best) {
128694 + i = next_best;
128695 + base = next_best_base;
128696 + num = next_best_num;
128697 + } else
128698 + i = NULL;
128699 +done:
128700 + if (i) {
128701 + if (base != i->base) {
128702 + margin_left->base = i->base;
128703 + margin_left->num = base - i->base;
128704 + list_add_tail(&margin_left->list, &i->list);
128705 + } else
128706 + kfree(margin_left);
128707 + if ((base + num) < (i->base + i->num)) {
128708 + margin_right->base = base + num;
128709 + margin_right->num = (i->base + i->num) -
128710 + (base + num);
128711 + list_add(&margin_right->list, &i->list);
128712 + } else
128713 + kfree(margin_right);
128714 + list_del(&i->list);
128715 + kfree(i);
128716 + *result = base;
128717 + } else {
128718 + spin_unlock_irq(&alloc->lock);
128719 + kfree(margin_left);
128720 + kfree(margin_right);
128721 + }
128722 +
128723 +err:
128724 + DPRINT("returning %d\n", i ? num : -ENOMEM);
128725 + DUMP(alloc);
128726 + if (!i)
128727 + return -ENOMEM;
128728 +
128729 + /* Add the allocation to the used list with a refcount of 1 */
128730 + used_node = kmalloc(sizeof(*used_node), GFP_KERNEL);
128731 + if (!used_node) {
128732 + spin_unlock_irq(&alloc->lock);
128733 + return -ENOMEM;
128734 + }
128735 + used_node->base = *result;
128736 + used_node->num = num;
128737 + used_node->refcount = 1;
128738 + used_node->is_alloced = 1;
128739 + list_add_tail(&used_node->list, &alloc->used);
128740 + spin_unlock_irq(&alloc->lock);
128741 + return (int)num;
128742 +}
128743 +
128744 +/* Allocate the list node using GFP_ATOMIC, because we *really* want to avoid
128745 + * forcing error-handling on to users in the deallocation path. */
128746 +static void _dpa_alloc_free(struct dpa_alloc *alloc, u32 base_id, u32 count)
128747 +{
128748 + struct alloc_node *i, *node = kmalloc(sizeof(*node), GFP_ATOMIC);
128749 + BUG_ON(!node);
128750 + DPRINT("release_range(%d,%d)\n", base_id, count);
128751 + DUMP(alloc);
128752 + BUG_ON(!count);
128753 + spin_lock_irq(&alloc->lock);
128754 +
128755 +
128756 + node->base = base_id;
128757 + node->num = count;
128758 + list_for_each_entry(i, &alloc->free, list) {
128759 + if (i->base >= node->base) {
128760 + /* BUG_ON(any overlapping) */
128761 + BUG_ON(i->base < (node->base + node->num));
128762 + list_add_tail(&node->list, &i->list);
128763 + goto done;
128764 + }
128765 + }
128766 + list_add_tail(&node->list, &alloc->free);
128767 +done:
128768 + /* Merge to the left */
128769 + i = list_entry(node->list.prev, struct alloc_node, list);
128770 + if (node->list.prev != &alloc->free) {
128771 + BUG_ON((i->base + i->num) > node->base);
128772 + if ((i->base + i->num) == node->base) {
128773 + node->base = i->base;
128774 + node->num += i->num;
128775 + list_del(&i->list);
128776 + kfree(i);
128777 + }
128778 + }
128779 + /* Merge to the right */
128780 + i = list_entry(node->list.next, struct alloc_node, list);
128781 + if (node->list.next != &alloc->free) {
128782 + BUG_ON((node->base + node->num) > i->base);
128783 + if ((node->base + node->num) == i->base) {
128784 + node->num += i->num;
128785 + list_del(&i->list);
128786 + kfree(i);
128787 + }
128788 + }
128789 + spin_unlock_irq(&alloc->lock);
128790 + DUMP(alloc);
128791 +}
128792 +
128793 +
128794 +void dpa_alloc_free(struct dpa_alloc *alloc, u32 base_id, u32 count)
128795 +{
128796 + struct alloc_node *i = NULL;
128797 + spin_lock_irq(&alloc->lock);
128798 +
128799 + /* First find the node in the used list and decrement its ref count */
128800 + list_for_each_entry(i, &alloc->used, list) {
128801 + if (i->base == base_id && i->num == count) {
128802 + --i->refcount;
128803 + if (i->refcount == 0) {
128804 + list_del(&i->list);
128805 + spin_unlock_irq(&alloc->lock);
128806 + if (i->is_alloced)
128807 + _dpa_alloc_free(alloc, base_id, count);
128808 + kfree(i);
128809 + return;
128810 + }
128811 + spin_unlock_irq(&alloc->lock);
128812 + return;
128813 + }
128814 + }
128815 + /* Couldn't find the allocation */
128816 + pr_err("Attempt to free ID 0x%x COUNT %d that wasn't alloc'd or reserved\n",
128817 + base_id, count);
128818 + spin_unlock_irq(&alloc->lock);
128819 +}
128820 +
128821 +void dpa_alloc_seed(struct dpa_alloc *alloc, u32 base_id, u32 count)
128822 +{
128823 + /* Same as free but no previous allocation checking is needed */
128824 + _dpa_alloc_free(alloc, base_id, count);
128825 +}
128826 +
128827 +
128828 +int dpa_alloc_reserve(struct dpa_alloc *alloc, u32 base, u32 num)
128829 +{
128830 + struct alloc_node *i = NULL, *used_node;
128831 +
128832 + DPRINT("alloc_reserve(%d,%d)\n", base, num);
128833 + DUMP(alloc);
128834 +
128835 + spin_lock_irq(&alloc->lock);
128836 +
128837 + /* Check for the node in the used list.
128838 + If found, increase it's refcount */
128839 + list_for_each_entry(i, &alloc->used, list) {
128840 + if ((i->base == base) && (i->num == num)) {
128841 + ++i->refcount;
128842 + spin_unlock_irq(&alloc->lock);
128843 + return 0;
128844 + }
128845 + if ((base >= i->base) && (base < (i->base + i->num))) {
128846 + /* This is an attempt to reserve a region that was
128847 + already reserved or alloced with a different
128848 + base or num */
128849 + pr_err("Cannot reserve %d - %d, it overlaps with"
128850 + " existing reservation from %d - %d\n",
128851 + base, base + num - 1, i->base,
128852 + i->base + i->num - 1);
128853 + spin_unlock_irq(&alloc->lock);
128854 + return -1;
128855 + }
128856 + }
128857 + /* Check to make sure this ID isn't in the free list */
128858 + list_for_each_entry(i, &alloc->free, list) {
128859 + if ((base >= i->base) && (base < (i->base + i->num))) {
128860 + /* yep, the reservation is within this node */
128861 + pr_err("Cannot reserve %d - %d, it overlaps with"
128862 + " free range %d - %d and must be alloced\n",
128863 + base, base + num - 1,
128864 + i->base, i->base + i->num - 1);
128865 + spin_unlock_irq(&alloc->lock);
128866 + return -1;
128867 + }
128868 + }
128869 + /* Add the allocation to the used list with a refcount of 1 */
128870 + used_node = kmalloc(sizeof(*used_node), GFP_KERNEL);
128871 + if (!used_node) {
128872 + spin_unlock_irq(&alloc->lock);
128873 + return -ENOMEM;
128874 +
128875 + }
128876 + used_node->base = base;
128877 + used_node->num = num;
128878 + used_node->refcount = 1;
128879 + used_node->is_alloced = 0;
128880 + list_add_tail(&used_node->list, &alloc->used);
128881 + spin_unlock_irq(&alloc->lock);
128882 + return 0;
128883 +}
128884 +
128885 +
128886 +int dpa_alloc_pop(struct dpa_alloc *alloc, u32 *result, u32 *count)
128887 +{
128888 + struct alloc_node *i = NULL;
128889 + DPRINT("alloc_pop()\n");
128890 + DUMP(alloc);
128891 + spin_lock_irq(&alloc->lock);
128892 + if (!list_empty(&alloc->free)) {
128893 + i = list_entry(alloc->free.next, struct alloc_node, list);
128894 + list_del(&i->list);
128895 + }
128896 + spin_unlock_irq(&alloc->lock);
128897 + DPRINT("returning %d\n", i ? 0 : -ENOMEM);
128898 + DUMP(alloc);
128899 + if (!i)
128900 + return -ENOMEM;
128901 + *result = i->base;
128902 + *count = i->num;
128903 + kfree(i);
128904 + return 0;
128905 +}
128906 +
128907 +int dpa_alloc_check(struct dpa_alloc *list_head, u32 item)
128908 +{
128909 + struct alloc_node *i = NULL;
128910 + int res = 0;
128911 + DPRINT("alloc_check()\n");
128912 + spin_lock_irq(&list_head->lock);
128913 +
128914 + list_for_each_entry(i, &list_head->free, list) {
128915 + if ((item >= i->base) && (item < (i->base + i->num))) {
128916 + res = 1;
128917 + break;
128918 + }
128919 + }
128920 + spin_unlock_irq(&list_head->lock);
128921 + return res;
128922 +}
128923 --- /dev/null
128924 +++ b/drivers/staging/fsl_qbman/dpa_sys.h
128925 @@ -0,0 +1,259 @@
128926 +/* Copyright 2008-2012 Freescale Semiconductor, Inc.
128927 + *
128928 + * Redistribution and use in source and binary forms, with or without
128929 + * modification, are permitted provided that the following conditions are met:
128930 + * * Redistributions of source code must retain the above copyright
128931 + * notice, this list of conditions and the following disclaimer.
128932 + * * Redistributions in binary form must reproduce the above copyright
128933 + * notice, this list of conditions and the following disclaimer in the
128934 + * documentation and/or other materials provided with the distribution.
128935 + * * Neither the name of Freescale Semiconductor nor the
128936 + * names of its contributors may be used to endorse or promote products
128937 + * derived from this software without specific prior written permission.
128938 + *
128939 + *
128940 + * ALTERNATIVELY, this software may be distributed under the terms of the
128941 + * GNU General Public License ("GPL") as published by the Free Software
128942 + * Foundation, either version 2 of that License or (at your option) any
128943 + * later version.
128944 + *
128945 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
128946 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
128947 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
128948 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
128949 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
128950 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
128951 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
128952 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
128953 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
128954 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
128955 + */
128956 +
128957 +#ifndef DPA_SYS_H
128958 +#define DPA_SYS_H
128959 +
128960 +#include <linux/kernel.h>
128961 +#include <linux/errno.h>
128962 +#include <linux/io.h>
128963 +#include <linux/dma-mapping.h>
128964 +#include <linux/bootmem.h>
128965 +#include <linux/slab.h>
128966 +#include <linux/module.h>
128967 +#include <linux/init.h>
128968 +#include <linux/interrupt.h>
128969 +#include <linux/delay.h>
128970 +#include <linux/of_platform.h>
128971 +#include <linux/of_address.h>
128972 +#include <linux/of_irq.h>
128973 +#include <linux/kthread.h>
128974 +#include <linux/memblock.h>
128975 +#include <linux/completion.h>
128976 +#include <linux/log2.h>
128977 +#include <linux/types.h>
128978 +#include <linux/ioctl.h>
128979 +#include <linux/miscdevice.h>
128980 +#include <linux/uaccess.h>
128981 +#include <linux/debugfs.h>
128982 +#include <linux/seq_file.h>
128983 +#include <linux/device.h>
128984 +#include <linux/uio_driver.h>
128985 +#include <linux/smp.h>
128986 +#include <linux/fsl_hypervisor.h>
128987 +#include <linux/vmalloc.h>
128988 +#include <linux/ctype.h>
128989 +#include <linux/math64.h>
128990 +#include <linux/bitops.h>
128991 +
128992 +#include <linux/fsl_usdpaa.h>
128993 +
128994 +/* When copying aligned words or shorts, try to avoid memcpy() */
128995 +#define CONFIG_TRY_BETTER_MEMCPY
128996 +
128997 +/* For 2-element tables related to cache-inhibited and cache-enabled mappings */
128998 +#define DPA_PORTAL_CE 0
128999 +#define DPA_PORTAL_CI 1
129000 +
129001 +/***********************/
129002 +/* Misc inline assists */
129003 +/***********************/
129004 +
129005 +#if defined CONFIG_PPC32
129006 +#include "dpa_sys_ppc32.h"
129007 +#elif defined CONFIG_PPC64
129008 +#include "dpa_sys_ppc64.h"
129009 +#elif defined CONFIG_ARM
129010 +#include "dpa_sys_arm.h"
129011 +#elif defined CONFIG_ARM64
129012 +#include "dpa_sys_arm64.h"
129013 +#endif
129014 +
129015 +
129016 +#ifdef CONFIG_FSL_DPA_CHECKING
129017 +#define DPA_ASSERT(x) \
129018 + do { \
129019 + if (!(x)) { \
129020 + pr_crit("ASSERT: (%s:%d) %s\n", __FILE__, __LINE__, \
129021 + __stringify_1(x)); \
129022 + dump_stack(); \
129023 + panic("assertion failure"); \
129024 + } \
129025 + } while (0)
129026 +#else
129027 +#define DPA_ASSERT(x)
129028 +#endif
129029 +
129030 +/* memcpy() stuff - when you know alignments in advance */
129031 +#ifdef CONFIG_TRY_BETTER_MEMCPY
129032 +static inline void copy_words(void *dest, const void *src, size_t sz)
129033 +{
129034 + u32 *__dest = dest;
129035 + const u32 *__src = src;
129036 + size_t __sz = sz >> 2;
129037 + BUG_ON((unsigned long)dest & 0x3);
129038 + BUG_ON((unsigned long)src & 0x3);
129039 + BUG_ON(sz & 0x3);
129040 + while (__sz--)
129041 + *(__dest++) = *(__src++);
129042 +}
129043 +static inline void copy_shorts(void *dest, const void *src, size_t sz)
129044 +{
129045 + u16 *__dest = dest;
129046 + const u16 *__src = src;
129047 + size_t __sz = sz >> 1;
129048 + BUG_ON((unsigned long)dest & 0x1);
129049 + BUG_ON((unsigned long)src & 0x1);
129050 + BUG_ON(sz & 0x1);
129051 + while (__sz--)
129052 + *(__dest++) = *(__src++);
129053 +}
129054 +static inline void copy_bytes(void *dest, const void *src, size_t sz)
129055 +{
129056 + u8 *__dest = dest;
129057 + const u8 *__src = src;
129058 + while (sz--)
129059 + *(__dest++) = *(__src++);
129060 +}
129061 +#else
129062 +#define copy_words memcpy
129063 +#define copy_shorts memcpy
129064 +#define copy_bytes memcpy
129065 +#endif
129066 +
129067 +/************/
129068 +/* RB-trees */
129069 +/************/
129070 +
129071 +/* We encapsulate RB-trees so that its easier to use non-linux forms in
129072 + * non-linux systems. This also encapsulates the extra plumbing that linux code
129073 + * usually provides when using RB-trees. This encapsulation assumes that the
129074 + * data type held by the tree is u32. */
129075 +
129076 +struct dpa_rbtree {
129077 + struct rb_root root;
129078 +};
129079 +#define DPA_RBTREE { .root = RB_ROOT }
129080 +
129081 +static inline void dpa_rbtree_init(struct dpa_rbtree *tree)
129082 +{
129083 + tree->root = RB_ROOT;
129084 +}
129085 +
129086 +#define IMPLEMENT_DPA_RBTREE(name, type, node_field, val_field) \
129087 +static inline int name##_push(struct dpa_rbtree *tree, type *obj) \
129088 +{ \
129089 + struct rb_node *parent = NULL, **p = &tree->root.rb_node; \
129090 + while (*p) { \
129091 + u32 item; \
129092 + parent = *p; \
129093 + item = rb_entry(parent, type, node_field)->val_field; \
129094 + if (obj->val_field < item) \
129095 + p = &parent->rb_left; \
129096 + else if (obj->val_field > item) \
129097 + p = &parent->rb_right; \
129098 + else \
129099 + return -EBUSY; \
129100 + } \
129101 + rb_link_node(&obj->node_field, parent, p); \
129102 + rb_insert_color(&obj->node_field, &tree->root); \
129103 + return 0; \
129104 +} \
129105 +static inline void name##_del(struct dpa_rbtree *tree, type *obj) \
129106 +{ \
129107 + rb_erase(&obj->node_field, &tree->root); \
129108 +} \
129109 +static inline type *name##_find(struct dpa_rbtree *tree, u32 val) \
129110 +{ \
129111 + type *ret; \
129112 + struct rb_node *p = tree->root.rb_node; \
129113 + while (p) { \
129114 + ret = rb_entry(p, type, node_field); \
129115 + if (val < ret->val_field) \
129116 + p = p->rb_left; \
129117 + else if (val > ret->val_field) \
129118 + p = p->rb_right; \
129119 + else \
129120 + return ret; \
129121 + } \
129122 + return NULL; \
129123 +}
129124 +
129125 +/************/
129126 +/* Bootargs */
129127 +/************/
129128 +
129129 +/* Qman has "qportals=" and Bman has "bportals=", they use the same syntax
129130 + * though; a comma-separated list of items, each item being a cpu index and/or a
129131 + * range of cpu indices, and each item optionally be prefixed by "s" to indicate
129132 + * that the portal associated with that cpu should be shared. See bman_driver.c
129133 + * for more specifics. */
129134 +static int __parse_portals_cpu(const char **s, unsigned int *cpu)
129135 +{
129136 + *cpu = 0;
129137 + if (!isdigit(**s))
129138 + return -EINVAL;
129139 + while (isdigit(**s))
129140 + *cpu = *cpu * 10 + (*((*s)++) - '0');
129141 + return 0;
129142 +}
129143 +static inline int parse_portals_bootarg(char *str, struct cpumask *want_shared,
129144 + struct cpumask *want_unshared,
129145 + const char *argname)
129146 +{
129147 + const char *s = str;
129148 + unsigned int shared, cpu1, cpu2, loop;
129149 +
129150 +keep_going:
129151 + if (*s == 's') {
129152 + shared = 1;
129153 + s++;
129154 + } else
129155 + shared = 0;
129156 + if (__parse_portals_cpu(&s, &cpu1))
129157 + goto err;
129158 + if (*s == '-') {
129159 + s++;
129160 + if (__parse_portals_cpu(&s, &cpu2))
129161 + goto err;
129162 + if (cpu2 < cpu1)
129163 + goto err;
129164 + } else
129165 + cpu2 = cpu1;
129166 + for (loop = cpu1; loop <= cpu2; loop++)
129167 + cpumask_set_cpu(loop, shared ? want_shared : want_unshared);
129168 + if (*s == ',') {
129169 + s++;
129170 + goto keep_going;
129171 + } else if ((*s == '\0') || isspace(*s))
129172 + return 0;
129173 +err:
129174 + pr_crit("Malformed %s argument: %s, offset: %lu\n", argname, str,
129175 + (unsigned long)s - (unsigned long)str);
129176 + return -EINVAL;
129177 +}
129178 +#ifdef CONFIG_FSL_USDPAA
129179 +/* Hooks from fsl_usdpaa_irq.c to fsl_usdpaa.c */
129180 +int usdpaa_get_portal_config(struct file *filp, void *cinh,
129181 + enum usdpaa_portal_type ptype, unsigned int *irq,
129182 + void **iir_reg);
129183 +#endif
129184 +#endif /* DPA_SYS_H */
129185 --- /dev/null
129186 +++ b/drivers/staging/fsl_qbman/dpa_sys_arm.h
129187 @@ -0,0 +1,95 @@
129188 +/* Copyright 2016 Freescale Semiconductor, Inc.
129189 + *
129190 + * Redistribution and use in source and binary forms, with or without
129191 + * modification, are permitted provided that the following conditions are met:
129192 + * * Redistributions of source code must retain the above copyright
129193 + * notice, this list of conditions and the following disclaimer.
129194 + * * Redistributions in binary form must reproduce the above copyright
129195 + * notice, this list of conditions and the following disclaimer in the
129196 + * documentation and/or other materials provided with the distribution.
129197 + * * Neither the name of Freescale Semiconductor nor the
129198 + * names of its contributors may be used to endorse or promote products
129199 + * derived from this software without specific prior written permission.
129200 + *
129201 + *
129202 + * ALTERNATIVELY, this software may be distributed under the terms of the
129203 + * GNU General Public License ("GPL") as published by the Free Software
129204 + * Foundation, either version 2 of that License or (at your option) any
129205 + * later version.
129206 + *
129207 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
129208 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
129209 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
129210 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
129211 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
129212 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
129213 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
129214 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
129215 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
129216 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
129217 + */
129218 +
129219 +#ifndef DPA_SYS_ARM_H
129220 +#define DPA_SYS_ARM_H
129221 +
129222 +#include <asm/cacheflush.h>
129223 +#include <asm/barrier.h>
129224 +
129225 +/* Implementation of ARM specific routines */
129226 +
129227 +/* TODO: NB, we currently assume that hwsync() and lwsync() imply compiler
129228 + * barriers and that dcb*() won't fall victim to compiler or execution
129229 + * reordering with respect to other code/instructions that manipulate the same
129230 + * cacheline. */
129231 +#define hwsync() { asm volatile("dmb st" : : : "memory"); }
129232 +#define lwsync() { asm volatile("dmb st" : : : "memory"); }
129233 +#define dcbf(p) { asm volatile("mcr p15, 0, %0, c7, c10, 1" : : "r" (p) : "memory"); }
129234 +#define dcbt_ro(p) { asm volatile("pld [%0, #64];": : "r" (p)); }
129235 +#define dcbt_rw(p) { asm volatile("pldw [%0, #64];": : "r" (p)); }
129236 +#define dcbi(p) { asm volatile("mcr p15, 0, %0, c7, c6, 1" : : "r" (p) : "memory"); }
129237 +
129238 +#define dcbz_64(p) { memset(p, 0, sizeof(*p)); }
129239 +
129240 +#define dcbf_64(p) \
129241 + do { \
129242 + dcbf((u32)p); \
129243 + } while (0)
129244 +/* Commonly used combo */
129245 +#define dcbit_ro(p) \
129246 + do { \
129247 + dcbi((u32)p); \
129248 + dcbt_ro((u32)p); \
129249 + } while (0)
129250 +
129251 +static inline u64 mfatb(void)
129252 +{
129253 + return get_cycles();
129254 +}
129255 +
129256 +static inline u32 in_be32(volatile void *addr)
129257 +{
129258 + return be32_to_cpu(*((volatile u32 *) addr));
129259 +}
129260 +
129261 +static inline void out_be32(void *addr, u32 val)
129262 +{
129263 + *((u32 *) addr) = cpu_to_be32(val);
129264 +}
129265 +
129266 +
129267 +static inline void set_bits(unsigned long mask, volatile unsigned long *p)
129268 +{
129269 + *p |= mask;
129270 +}
129271 +static inline void clear_bits(unsigned long mask, volatile unsigned long *p)
129272 +{
129273 + *p &= ~mask;
129274 +}
129275 +
129276 +static inline void flush_dcache_range(unsigned long start, unsigned long stop)
129277 +{
129278 + __cpuc_flush_dcache_area((void *) start, stop - start);
129279 +}
129280 +
129281 +#define hard_smp_processor_id() raw_smp_processor_id()
129282 +#endif
129283 --- /dev/null
129284 +++ b/drivers/staging/fsl_qbman/dpa_sys_arm64.h
129285 @@ -0,0 +1,102 @@
129286 +/* Copyright 2014 Freescale Semiconductor, Inc.
129287 + *
129288 + * Redistribution and use in source and binary forms, with or without
129289 + * modification, are permitted provided that the following conditions are met:
129290 + * * Redistributions of source code must retain the above copyright
129291 + * notice, this list of conditions and the following disclaimer.
129292 + * * Redistributions in binary form must reproduce the above copyright
129293 + * notice, this list of conditions and the following disclaimer in the
129294 + * documentation and/or other materials provided with the distribution.
129295 + * * Neither the name of Freescale Semiconductor nor the
129296 + * names of its contributors may be used to endorse or promote products
129297 + * derived from this software without specific prior written permission.
129298 + *
129299 + *
129300 + * ALTERNATIVELY, this software may be distributed under the terms of the
129301 + * GNU General Public License ("GPL") as published by the Free Software
129302 + * Foundation, either version 2 of that License or (at your option) any
129303 + * later version.
129304 + *
129305 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
129306 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
129307 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
129308 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
129309 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
129310 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
129311 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
129312 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
129313 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
129314 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
129315 + */
129316 +
129317 +#ifndef DPA_SYS_ARM64_H
129318 +#define DPA_SYS_ARM64_H
129319 +
129320 +#include <asm/cacheflush.h>
129321 +#include <asm/barrier.h>
129322 +
129323 +/* Implementation of ARM 64 bit specific routines */
129324 +
129325 +/* TODO: NB, we currently assume that hwsync() and lwsync() imply compiler
129326 + * barriers and that dcb*() won't fall victim to compiler or execution
129327 + * reordering with respect to other code/instructions that manipulate the same
129328 + * cacheline. */
129329 +#define hwsync() { asm volatile("dmb st" : : : "memory"); }
129330 +#define lwsync() { asm volatile("dmb st" : : : "memory"); }
129331 +#define dcbf(p) { asm volatile("dc cvac, %0;" : : "r" (p) : "memory"); }
129332 +#define dcbt_ro(p) { asm volatile("prfm pldl1keep, [%0, #0]" : : "r" (p)); }
129333 +#define dcbt_rw(p) { asm volatile("prfm pstl1keep, [%0, #0]" : : "r" (p)); }
129334 +#define dcbi(p) { asm volatile("dc ivac, %0" : : "r"(p) : "memory"); }
129335 +#define dcbz(p) { asm volatile("dc zva, %0" : : "r" (p) : "memory"); }
129336 +
129337 +#define dcbz_64(p) \
129338 + do { \
129339 + dcbz(p); \
129340 + } while (0)
129341 +
129342 +#define dcbf_64(p) \
129343 + do { \
129344 + dcbf(p); \
129345 + } while (0)
129346 +/* Commonly used combo */
129347 +#define dcbit_ro(p) \
129348 + do { \
129349 + dcbi(p); \
129350 + dcbt_ro(p); \
129351 + } while (0)
129352 +
129353 +static inline u64 mfatb(void)
129354 +{
129355 + return get_cycles();
129356 +}
129357 +
129358 +static inline u32 in_be32(volatile void *addr)
129359 +{
129360 + return be32_to_cpu(*((volatile u32 *) addr));
129361 +}
129362 +
129363 +static inline void out_be32(void *addr, u32 val)
129364 +{
129365 + *((u32 *) addr) = cpu_to_be32(val);
129366 +}
129367 +
129368 +
129369 +static inline void set_bits(unsigned long mask, volatile unsigned long *p)
129370 +{
129371 + *p |= mask;
129372 +}
129373 +static inline void clear_bits(unsigned long mask, volatile unsigned long *p)
129374 +{
129375 + *p &= ~mask;
129376 +}
129377 +
129378 +static inline void flush_dcache_range(unsigned long start, unsigned long stop)
129379 +{
129380 + __flush_dcache_area((void *) start, stop - start);
129381 +}
129382 +
129383 +#define hard_smp_processor_id() raw_smp_processor_id()
129384 +
129385 +
129386 +
129387 +#endif
129388 --- /dev/null
129389 +++ b/drivers/staging/fsl_qbman/dpa_sys_ppc32.h
129390 @@ -0,0 +1,70 @@
129391 +/* Copyright 2014 Freescale Semiconductor, Inc.
129392 + *
129393 + * Redistribution and use in source and binary forms, with or without
129394 + * modification, are permitted provided that the following conditions are met:
129395 + * * Redistributions of source code must retain the above copyright
129396 + * notice, this list of conditions and the following disclaimer.
129397 + * * Redistributions in binary form must reproduce the above copyright
129398 + * notice, this list of conditions and the following disclaimer in the
129399 + * documentation and/or other materials provided with the distribution.
129400 + * * Neither the name of Freescale Semiconductor nor the
129401 + * names of its contributors may be used to endorse or promote products
129402 + * derived from this software without specific prior written permission.
129403 + *
129404 + *
129405 + * ALTERNATIVELY, this software may be distributed under the terms of the
129406 + * GNU General Public License ("GPL") as published by the Free Software
129407 + * Foundation, either version 2 of that License or (at your option) any
129408 + * later version.
129409 + *
129410 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
129411 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
129412 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
129413 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
129414 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
129415 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
129416 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
129417 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
129418 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
129419 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
129420 + */
129421 +
129422 +#ifndef DPA_SYS_PPC32_H
129423 +#define DPA_SYS_PPC32_H
129424 +
129425 +/* Implementation of PowerPC 32 bit specific routines */
129426 +
129427 +/* TODO: NB, we currently assume that hwsync() and lwsync() imply compiler
129428 + * barriers and that dcb*() won't fall victim to compiler or execution
129429 + * reordering with respect to other code/instructions that manipulate the same
129430 + * cacheline. */
129431 +#define hwsync() __asm__ __volatile__ ("sync" : : : "memory")
129432 +#define lwsync() __asm__ __volatile__ (stringify_in_c(LWSYNC) : : : "memory")
129433 +#define dcbf(p) __asm__ __volatile__ ("dcbf 0,%0" : : "r" (p) : "memory")
129434 +#define dcbt_ro(p) __asm__ __volatile__ ("dcbt 0,%0" : : "r" (p))
129435 +#define dcbt_rw(p) __asm__ __volatile__ ("dcbtst 0,%0" : : "r" (p))
129436 +#define dcbi(p) dcbf(p)
129437 +
129438 +#define dcbzl(p) __asm__ __volatile__ ("dcbzl 0,%0" : : "r" (p))
129439 +#define dcbz_64(p) dcbzl(p)
129440 +#define dcbf_64(p) dcbf(p)
129441 +
129442 +/* Commonly used combo */
129443 +#define dcbit_ro(p) \
129444 + do { \
129445 + dcbi(p); \
129446 + dcbt_ro(p); \
129447 + } while (0)
129448 +
129449 +static inline u64 mfatb(void)
129450 +{
129451 + u32 hi, lo, chk;
129452 + do {
129453 + hi = mfspr(SPRN_ATBU);
129454 + lo = mfspr(SPRN_ATBL);
129455 + chk = mfspr(SPRN_ATBU);
129456 + } while (unlikely(hi != chk));
129457 + return ((u64)hi << 32) | (u64)lo;
129458 +}
129459 +
129460 +#endif
129461 --- /dev/null
129462 +++ b/drivers/staging/fsl_qbman/dpa_sys_ppc64.h
129463 @@ -0,0 +1,79 @@
129464 +/* Copyright 2014 Freescale Semiconductor, Inc.
129465 + *
129466 + * Redistribution and use in source and binary forms, with or without
129467 + * modification, are permitted provided that the following conditions are met:
129468 + * * Redistributions of source code must retain the above copyright
129469 + * notice, this list of conditions and the following disclaimer.
129470 + * * Redistributions in binary form must reproduce the above copyright
129471 + * notice, this list of conditions and the following disclaimer in the
129472 + * documentation and/or other materials provided with the distribution.
129473 + * * Neither the name of Freescale Semiconductor nor the
129474 + * names of its contributors may be used to endorse or promote products
129475 + * derived from this software without specific prior written permission.
129476 + *
129477 + *
129478 + * ALTERNATIVELY, this software may be distributed under the terms of the
129479 + * GNU General Public License ("GPL") as published by the Free Software
129480 + * Foundation, either version 2 of that License or (at your option) any
129481 + * later version.
129482 + *
129483 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
129484 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
129485 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
129486 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
129487 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
129488 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
129489 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
129490 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
129491 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
129492 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
129493 + */
129494 +
129495 +#ifndef DPA_SYS_PPC64_H
129496 +#define DPA_SYS_PPC64_H
129497 +
129498 +/* Implementation of PowerPC 64 bit specific routines */
129499 +
129500 +/* TODO: NB, we currently assume that hwsync() and lwsync() imply compiler
129501 + * barriers and that dcb*() won't fall victim to compiler or execution
129502 + * reordering with respect to other code/instructions that manipulate the same
129503 + * cacheline. */
129504 +#define hwsync() __asm__ __volatile__ ("sync" : : : "memory")
129505 +#define lwsync() __asm__ __volatile__ (stringify_in_c(LWSYNC) : : : "memory")
129506 +#define dcbf(p) __asm__ __volatile__ ("dcbf 0,%0" : : "r" (p) : "memory")
129507 +#define dcbt_ro(p) __asm__ __volatile__ ("dcbt 0,%0" : : "r" (p))
129508 +#define dcbt_rw(p) __asm__ __volatile__ ("dcbtst 0,%0" : : "r" (p))
129509 +#define dcbi(p) dcbf(p)
129510 +
129511 +#define dcbz(p) __asm__ __volatile__ ("dcbz 0,%0" : : "r" (p))
129512 +#define dcbz_64(p) \
129513 + do { \
129514 + dcbz((void*)p + 32); \
129515 + dcbz(p); \
129516 + } while (0)
129517 +#define dcbf_64(p) \
129518 + do { \
129519 + dcbf((void*)p + 32); \
129520 + dcbf(p); \
129521 + } while (0)
129522 +/* Commonly used combo */
129523 +#define dcbit_ro(p) \
129524 + do { \
129525 + dcbi(p); \
129526 + dcbi((void*)p + 32); \
129527 + dcbt_ro(p); \
129528 + dcbt_ro((void*)p + 32); \
129529 + } while (0)
129530 +
129531 +static inline u64 mfatb(void)
129532 +{
129533 + u32 hi, lo, chk;
129534 + do {
129535 + hi = mfspr(SPRN_ATBU);
129536 + lo = mfspr(SPRN_ATBL);
129537 + chk = mfspr(SPRN_ATBU);
129538 + } while (unlikely(hi != chk));
129539 + return ((u64)hi << 32) | (u64)lo;
129540 +}
129541 +
129542 +#endif
129543 --- /dev/null
129544 +++ b/drivers/staging/fsl_qbman/fsl_usdpaa.c
129545 @@ -0,0 +1,2007 @@
129546 +/* Copyright (C) 2008-2012 Freescale Semiconductor, Inc.
129547 + * Authors: Andy Fleming <afleming@freescale.com>
129548 + * Timur Tabi <timur@freescale.com>
129549 + * Geoff Thorpe <Geoff.Thorpe@freescale.com>
129550 + *
129551 + * This file is licensed under the terms of the GNU General Public License
129552 + * version 2. This program is licensed "as is" without any warranty of any
129553 + * kind, whether express or implied.
129554 + */
129555 +
129556 +
129557 +#include <linux/miscdevice.h>
129558 +#include <linux/fs.h>
129559 +#include <linux/cdev.h>
129560 +#include <linux/mm.h>
129561 +#include <linux/of.h>
129562 +#include <linux/memblock.h>
129563 +#include <linux/slab.h>
129564 +#include <linux/mman.h>
129565 +#include <linux/of_reserved_mem.h>
129566 +
129567 +#if !(defined(CONFIG_ARM) || defined(CONFIG_ARM64))
129568 +#include <mm/mmu_decl.h>
129569 +#endif
129570 +
129571 +#include "dpa_sys.h"
129572 +#include <linux/fsl_usdpaa.h>
129573 +#include "bman_low.h"
129574 +#include "qman_low.h"
129575 +
129576 +/* Physical address range of the memory reservation, exported for mm/mem.c */
129577 +static u64 phys_start;
129578 +static u64 phys_size;
129579 +static u64 arg_phys_size;
129580 +
129581 +/* PFN versions of the above */
129582 +static unsigned long pfn_start;
129583 +static unsigned long pfn_size;
129584 +
129585 +/* Memory reservations are manipulated under this spinlock (which is why 'refs'
129586 + * isn't atomic_t). */
129587 +static DEFINE_SPINLOCK(mem_lock);
129588 +
129589 +/* The range of TLB1 indices */
129590 +static unsigned int first_tlb;
129591 +static unsigned int num_tlb = 1;
129592 +static unsigned int current_tlb; /* loops around for fault handling */
129593 +
129594 +/* Memory reservation is represented as a list of 'mem_fragment's, some of which
129595 + * may be mapped. Unmapped fragments are always merged where possible. */
129596 +static LIST_HEAD(mem_list);
129597 +
129598 +struct mem_mapping;
129599 +
129600 +/* Memory fragments are in 'mem_list'. */
129601 +struct mem_fragment {
129602 + u64 base;
129603 + u64 len;
129604 + unsigned long pfn_base; /* PFN version of 'base' */
129605 + unsigned long pfn_len; /* PFN version of 'len' */
129606 + unsigned int refs; /* zero if unmapped */
129607 + u64 root_len; /* Size of the orignal fragment */
129608 + unsigned long root_pfn; /* PFN of the orignal fragment */
129609 + struct list_head list;
129610 + /* if mapped, flags+name captured at creation time */
129611 + u32 flags;
129612 + char name[USDPAA_DMA_NAME_MAX];
129613 + u64 map_len;
129614 + /* support multi-process locks per-memory-fragment. */
129615 + int has_locking;
129616 + wait_queue_head_t wq;
129617 + struct mem_mapping *owner;
129618 +};
129619 +
129620 +/* Mappings of memory fragments in 'struct ctx'. These are created from
129621 + * ioctl(USDPAA_IOCTL_DMA_MAP), though the actual mapping then happens via a
129622 + * mmap(). */
129623 +struct mem_mapping {
129624 + struct mem_fragment *root_frag;
129625 + u32 frag_count;
129626 + u64 total_size;
129627 + struct list_head list;
129628 + int refs;
129629 + void *virt_addr;
129630 +};
129631 +
129632 +struct portal_mapping {
129633 + struct usdpaa_ioctl_portal_map user;
129634 + union {
129635 + struct qm_portal_config *qportal;
129636 + struct bm_portal_config *bportal;
129637 + };
129638 + /* Declare space for the portals in case the process
129639 + exits unexpectedly and needs to be cleaned by the kernel */
129640 + union {
129641 + struct qm_portal qman_portal_low;
129642 + struct bm_portal bman_portal_low;
129643 + };
129644 + struct list_head list;
129645 + struct resource *phys;
129646 + struct iommu_domain *iommu_domain;
129647 +};
129648 +
129649 +/* Track the DPAA resources the process is using */
129650 +struct active_resource {
129651 + struct list_head list;
129652 + u32 id;
129653 + u32 num;
129654 + unsigned int refcount;
129655 +};
129656 +
129657 +/* Per-FD state (which should also be per-process but we don't enforce that) */
129658 +struct ctx {
129659 + /* Lock to protect the context */
129660 + spinlock_t lock;
129661 + /* Allocated resources get put here for accounting */
129662 + struct list_head resources[usdpaa_id_max];
129663 + /* list of DMA maps */
129664 + struct list_head maps;
129665 + /* list of portal maps */
129666 + struct list_head portals;
129667 +};
129668 +
129669 +/* Different resource classes */
129670 +static const struct alloc_backend {
129671 + enum usdpaa_id_type id_type;
129672 + int (*alloc)(u32 *, u32, u32, int);
129673 + void (*release)(u32 base, unsigned int count);
129674 + int (*reserve)(u32 base, unsigned int count);
129675 + const char *acronym;
129676 +} alloc_backends[] = {
129677 + {
129678 + .id_type = usdpaa_id_fqid,
129679 + .alloc = qman_alloc_fqid_range,
129680 + .release = qman_release_fqid_range,
129681 + .reserve = qman_reserve_fqid_range,
129682 + .acronym = "FQID"
129683 + },
129684 + {
129685 + .id_type = usdpaa_id_bpid,
129686 + .alloc = bman_alloc_bpid_range,
129687 + .release = bman_release_bpid_range,
129688 + .reserve = bman_reserve_bpid_range,
129689 + .acronym = "BPID"
129690 + },
129691 + {
129692 + .id_type = usdpaa_id_qpool,
129693 + .alloc = qman_alloc_pool_range,
129694 + .release = qman_release_pool_range,
129695 + .reserve = qman_reserve_pool_range,
129696 + .acronym = "QPOOL"
129697 + },
129698 + {
129699 + .id_type = usdpaa_id_cgrid,
129700 + .alloc = qman_alloc_cgrid_range,
129701 + .release = qman_release_cgrid_range,
129702 + .acronym = "CGRID"
129703 + },
129704 + {
129705 + .id_type = usdpaa_id_ceetm0_lfqid,
129706 + .alloc = qman_alloc_ceetm0_lfqid_range,
129707 + .release = qman_release_ceetm0_lfqid_range,
129708 + .acronym = "CEETM0_LFQID"
129709 + },
129710 + {
129711 + .id_type = usdpaa_id_ceetm0_channelid,
129712 + .alloc = qman_alloc_ceetm0_channel_range,
129713 + .release = qman_release_ceetm0_channel_range,
129714 + .acronym = "CEETM0_LFQID"
129715 + },
129716 + {
129717 + .id_type = usdpaa_id_ceetm1_lfqid,
129718 + .alloc = qman_alloc_ceetm1_lfqid_range,
129719 + .release = qman_release_ceetm1_lfqid_range,
129720 + .acronym = "CEETM1_LFQID"
129721 + },
129722 + {
129723 + .id_type = usdpaa_id_ceetm1_channelid,
129724 + .alloc = qman_alloc_ceetm1_channel_range,
129725 + .release = qman_release_ceetm1_channel_range,
129726 + .acronym = "CEETM1_LFQID"
129727 + },
129728 + {
129729 + /* This terminates the array */
129730 + .id_type = usdpaa_id_max
129731 + }
129732 +};
129733 +
129734 +/* Determines the largest acceptable page size for a given size
129735 + The sizes are determined by what the TLB1 acceptable page sizes are */
129736 +static u32 largest_page_size(u32 size)
129737 +{
129738 + int shift = 30; /* Start at 1G size */
129739 + if (size < 4096)
129740 + return 0;
129741 + do {
129742 + if (size >= (1<<shift))
129743 + return 1<<shift;
129744 + shift -= 2;
129745 + } while (shift >= 12); /* Up to 4k */
129746 + return 0;
129747 +}
129748 +
129749 +/* Determine if value is power of 4 */
129750 +static inline bool is_power_of_4(u64 x)
129751 +{
129752 + if (x == 0 || ((x & (x - 1)) != 0))
129753 + return false;
129754 + return !!(x & 0x5555555555555555ull);
129755 +}
129756 +
129757 +/* Helper for ioctl_dma_map() when we have a larger fragment than we need. This
129758 + * splits the fragment into 4 and returns the upper-most. (The caller can loop
129759 + * until it has a suitable fragment size.) */
129760 +static struct mem_fragment *split_frag(struct mem_fragment *frag)
129761 +{
129762 + struct mem_fragment *x[3];
129763 +
129764 + x[0] = kmalloc(sizeof(struct mem_fragment), GFP_ATOMIC);
129765 + x[1] = kmalloc(sizeof(struct mem_fragment), GFP_ATOMIC);
129766 + x[2] = kmalloc(sizeof(struct mem_fragment), GFP_ATOMIC);
129767 + if (!x[0] || !x[1] || !x[2]) {
129768 + kfree(x[0]);
129769 + kfree(x[1]);
129770 + kfree(x[2]);
129771 + return NULL;
129772 + }
129773 + BUG_ON(frag->refs);
129774 + frag->len >>= 2;
129775 + frag->pfn_len >>= 2;
129776 + x[0]->base = frag->base + frag->len;
129777 + x[1]->base = x[0]->base + frag->len;
129778 + x[2]->base = x[1]->base + frag->len;
129779 + x[0]->len = x[1]->len = x[2]->len = frag->len;
129780 + x[0]->pfn_base = frag->pfn_base + frag->pfn_len;
129781 + x[1]->pfn_base = x[0]->pfn_base + frag->pfn_len;
129782 + x[2]->pfn_base = x[1]->pfn_base + frag->pfn_len;
129783 + x[0]->pfn_len = x[1]->pfn_len = x[2]->pfn_len = frag->pfn_len;
129784 + x[0]->refs = x[1]->refs = x[2]->refs = 0;
129785 + x[0]->root_len = x[1]->root_len = x[2]->root_len = frag->root_len;
129786 + x[0]->root_pfn = x[1]->root_pfn = x[2]->root_pfn = frag->root_pfn;
129787 + x[0]->name[0] = x[1]->name[0] = x[2]->name[0] = 0;
129788 + list_add_tail(&x[0]->list, &frag->list);
129789 + list_add_tail(&x[1]->list, &x[0]->list);
129790 + list_add_tail(&x[2]->list, &x[1]->list);
129791 + return x[2];
129792 +}
129793 +
129794 +static __maybe_unused void dump_frags(void)
129795 +{
129796 + struct mem_fragment *frag;
129797 + int i = 0;
129798 + list_for_each_entry(frag, &mem_list, list) {
129799 + 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",
129800 + i, frag->base, frag->pfn_base,
129801 + frag->len, frag->root_len, frag->root_pfn,
129802 + frag->refs, frag->name);
129803 + ++i;
129804 + }
129805 +}
129806 +
129807 +/* Walk the list of fragments and adjoin neighbouring segments if possible */
129808 +static void compress_frags(void)
129809 +{
129810 + /* Walk the fragment list and combine fragments */
129811 + struct mem_fragment *frag, *nxtfrag;
129812 + u64 len = 0;
129813 +
129814 + int i, numfrags;
129815 +
129816 +
129817 + frag = list_entry(mem_list.next, struct mem_fragment, list);
129818 +
129819 + while (&frag->list != &mem_list) {
129820 + /* Must combine consecutive fragemenst with
129821 + same root_pfn such that they are power of 4 */
129822 + if (frag->refs != 0) {
129823 + frag = list_entry(frag->list.next,
129824 + struct mem_fragment, list);
129825 + continue; /* Not this window */
129826 + }
129827 + len = frag->len;
129828 + numfrags = 0;
129829 + nxtfrag = list_entry(frag->list.next,
129830 + struct mem_fragment, list);
129831 + while (true) {
129832 + if (&nxtfrag->list == &mem_list) {
129833 + numfrags = 0;
129834 + break; /* End of list */
129835 + }
129836 + if (nxtfrag->refs) {
129837 + numfrags = 0;
129838 + break; /* In use still */
129839 + }
129840 + if (nxtfrag->root_pfn != frag->root_pfn) {
129841 + numfrags = 0;
129842 + break; /* Crosses root fragment boundary */
129843 + }
129844 + len += nxtfrag->len;
129845 + numfrags++;
129846 + if (is_power_of_4(len)) {
129847 + /* These fragments can be combined */
129848 + break;
129849 + }
129850 + nxtfrag = list_entry(nxtfrag->list.next,
129851 + struct mem_fragment, list);
129852 + }
129853 + if (numfrags == 0) {
129854 + frag = list_entry(frag->list.next,
129855 + struct mem_fragment, list);
129856 + continue; /* try the next window */
129857 + }
129858 + for (i = 0; i < numfrags; i++) {
129859 + struct mem_fragment *todel =
129860 + list_entry(nxtfrag->list.prev,
129861 + struct mem_fragment, list);
129862 + nxtfrag->len += todel->len;
129863 + nxtfrag->pfn_len += todel->pfn_len;
129864 + list_del(&todel->list);
129865 + }
129866 + /* Re evaluate the list, things may merge now */
129867 + frag = list_entry(mem_list.next, struct mem_fragment, list);
129868 + }
129869 +}
129870 +
129871 +/* Hook from arch/powerpc/mm/mem.c */
129872 +int usdpaa_test_fault(unsigned long pfn, u64 *phys_addr, u64 *size)
129873 +{
129874 + struct mem_fragment *frag;
129875 + int idx = -1;
129876 + if ((pfn < pfn_start) || (pfn >= (pfn_start + pfn_size)))
129877 + return -1;
129878 + /* It's in-range, we need to find the fragment */
129879 + spin_lock(&mem_lock);
129880 + list_for_each_entry(frag, &mem_list, list) {
129881 + if ((pfn >= frag->pfn_base) && (pfn < (frag->pfn_base +
129882 + frag->pfn_len))) {
129883 + *phys_addr = frag->base;
129884 + *size = frag->len;
129885 + idx = current_tlb++;
129886 + if (current_tlb >= (first_tlb + num_tlb))
129887 + current_tlb = first_tlb;
129888 + break;
129889 + }
129890 + }
129891 + spin_unlock(&mem_lock);
129892 + return idx;
129893 +}
129894 +
129895 +static int usdpaa_open(struct inode *inode, struct file *filp)
129896 +{
129897 + const struct alloc_backend *backend = &alloc_backends[0];
129898 + struct ctx *ctx = kmalloc(sizeof(struct ctx), GFP_KERNEL);
129899 + if (!ctx)
129900 + return -ENOMEM;
129901 + filp->private_data = ctx;
129902 +
129903 + while (backend->id_type != usdpaa_id_max) {
129904 + INIT_LIST_HEAD(&ctx->resources[backend->id_type]);
129905 + backend++;
129906 + }
129907 +
129908 + INIT_LIST_HEAD(&ctx->maps);
129909 + INIT_LIST_HEAD(&ctx->portals);
129910 + spin_lock_init(&ctx->lock);
129911 +
129912 + //filp->f_mapping->backing_dev_info = &directly_mappable_cdev_bdi;
129913 +
129914 + return 0;
129915 +}
129916 +
129917 +#define DQRR_MAXFILL 15
129918 +
129919 +
129920 +/* Invalidate a portal */
129921 +void dbci_portal(void *addr)
129922 +{
129923 + int i;
129924 +
129925 + for (i = 0; i < 0x4000; i += 64)
129926 + dcbi(addr + i);
129927 +}
129928 +
129929 +/* Reset a QMan portal to its default state */
129930 +static int init_qm_portal(struct qm_portal_config *config,
129931 + struct qm_portal *portal)
129932 +{
129933 + const struct qm_dqrr_entry *dqrr = NULL;
129934 + int i;
129935 +
129936 + portal->addr.addr_ce = config->addr_virt[DPA_PORTAL_CE];
129937 + portal->addr.addr_ci = config->addr_virt[DPA_PORTAL_CI];
129938 +
129939 + /* Make sure interrupts are inhibited */
129940 + qm_out(IIR, 1);
129941 +
129942 + /*
129943 + * Invalidate the entire CE portal are to ensure no stale
129944 + * cachelines are present. This should be done on all
129945 + * cores as the portal is mapped as M=0 (non-coherent).
129946 + */
129947 + on_each_cpu(dbci_portal, portal->addr.addr_ce, 1);
129948 +
129949 + /* Initialize the DQRR. This will stop any dequeue
129950 + commands that are in progress */
129951 + if (qm_dqrr_init(portal, config, qm_dqrr_dpush, qm_dqrr_pvb,
129952 + qm_dqrr_cdc, DQRR_MAXFILL)) {
129953 + pr_err("qm_dqrr_init() failed when trying to"
129954 + " recover portal, portal will be leaked\n");
129955 + return 1;
129956 + }
129957 +
129958 + /* Discard any entries on the DQRR */
129959 + /* If we consume the ring twice something is wrong */
129960 + for (i = 0; i < DQRR_MAXFILL * 2; i++) {
129961 + qm_dqrr_pvb_update(portal);
129962 + dqrr = qm_dqrr_current(portal);
129963 + if (!dqrr)
129964 + break;
129965 + qm_dqrr_cdc_consume_1ptr(portal, dqrr, 0);
129966 + qm_dqrr_pvb_update(portal);
129967 + qm_dqrr_next(portal);
129968 + }
129969 + /* Initialize the EQCR */
129970 + if (qm_eqcr_init(portal, qm_eqcr_pvb,
129971 + qm_eqcr_get_ci_stashing(portal), 1)) {
129972 + pr_err("Qman EQCR initialisation failed\n");
129973 + return 1;
129974 + }
129975 + /* initialize the MR */
129976 + if (qm_mr_init(portal, qm_mr_pvb, qm_mr_cci)) {
129977 + pr_err("Qman MR initialisation failed\n");
129978 + return 1;
129979 + }
129980 + qm_mr_pvb_update(portal);
129981 + while (qm_mr_current(portal)) {
129982 + qm_mr_next(portal);
129983 + qm_mr_cci_consume_to_current(portal);
129984 + qm_mr_pvb_update(portal);
129985 + }
129986 +
129987 + if (qm_mc_init(portal)) {
129988 + pr_err("Qman MC initialisation failed\n");
129989 + return 1;
129990 + }
129991 + return 0;
129992 +}
129993 +
129994 +static int init_bm_portal(struct bm_portal_config *config,
129995 + struct bm_portal *portal)
129996 +{
129997 + portal->addr.addr_ce = config->addr_virt[DPA_PORTAL_CE];
129998 + portal->addr.addr_ci = config->addr_virt[DPA_PORTAL_CI];
129999 +
130000 + /*
130001 + * Invalidate the entire CE portal are to ensure no stale
130002 + * cachelines are present. This should be done on all
130003 + * cores as the portal is mapped as M=0 (non-coherent).
130004 + */
130005 + on_each_cpu(dbci_portal, portal->addr.addr_ce, 1);
130006 +
130007 + if (bm_rcr_init(portal, bm_rcr_pvb, bm_rcr_cce)) {
130008 + pr_err("Bman RCR initialisation failed\n");
130009 + return 1;
130010 + }
130011 + if (bm_mc_init(portal)) {
130012 + pr_err("Bman MC initialisation failed\n");
130013 + return 1;
130014 + }
130015 + return 0;
130016 +}
130017 +
130018 +/* Function that will scan all FQ's in the system. For each FQ that is not
130019 + OOS it will call the check_channel helper to determine if the FQ should
130020 + be torn down. If the check_channel helper returns true the FQ will be
130021 + transitioned to the OOS state */
130022 +static int qm_check_and_destroy_fqs(struct qm_portal *portal, void *ctx,
130023 + bool (*check_channel)(void*, u32))
130024 +{
130025 + u32 fq_id = 0;
130026 + while (1) {
130027 + struct qm_mc_command *mcc;
130028 + struct qm_mc_result *mcr;
130029 + u8 state;
130030 + u32 channel;
130031 +
130032 + /* Determine the channel for the FQID */
130033 + mcc = qm_mc_start(portal);
130034 + mcc->queryfq.fqid = fq_id;
130035 + qm_mc_commit(portal, QM_MCC_VERB_QUERYFQ);
130036 + while (!(mcr = qm_mc_result(portal)))
130037 + cpu_relax();
130038 + DPA_ASSERT((mcr->verb & QM_MCR_VERB_MASK)
130039 + == QM_MCR_VERB_QUERYFQ);
130040 + if (mcr->result != QM_MCR_RESULT_OK)
130041 + break; /* End of valid FQIDs */
130042 +
130043 + channel = mcr->queryfq.fqd.dest.channel;
130044 + /* Determine the state of the FQID */
130045 + mcc = qm_mc_start(portal);
130046 + mcc->queryfq_np.fqid = fq_id;
130047 + qm_mc_commit(portal, QM_MCC_VERB_QUERYFQ_NP);
130048 + while (!(mcr = qm_mc_result(portal)))
130049 + cpu_relax();
130050 + DPA_ASSERT((mcr->verb & QM_MCR_VERB_MASK)
130051 + == QM_MCR_VERB_QUERYFQ_NP);
130052 + state = mcr->queryfq_np.state & QM_MCR_NP_STATE_MASK;
130053 + if (state == QM_MCR_NP_STATE_OOS)
130054 + /* Already OOS, no need to do anymore checks */
130055 + goto next;
130056 +
130057 + if (check_channel(ctx, channel))
130058 + qm_shutdown_fq(&portal, 1, fq_id);
130059 + next:
130060 + ++fq_id;
130061 + }
130062 + return 0;
130063 +}
130064 +
130065 +static bool check_channel_device(void *_ctx, u32 channel)
130066 +{
130067 + struct ctx *ctx = _ctx;
130068 + struct portal_mapping *portal, *tmpportal;
130069 + struct active_resource *res;
130070 +
130071 + /* See if the FQ is destined for one of the portals we're cleaning up */
130072 + list_for_each_entry_safe(portal, tmpportal, &ctx->portals, list) {
130073 + if (portal->user.type == usdpaa_portal_qman) {
130074 + if (portal->qportal->public_cfg.channel == channel) {
130075 + /* This FQs destination is a portal
130076 + we're cleaning, send a retire */
130077 + return true;
130078 + }
130079 + }
130080 + }
130081 +
130082 + /* Check the pool channels that will be released as well */
130083 + list_for_each_entry(res, &ctx->resources[usdpaa_id_qpool], list) {
130084 + if ((res->id >= channel) &&
130085 + ((res->id + res->num - 1) <= channel))
130086 + return true;
130087 + }
130088 + return false;
130089 +}
130090 +
130091 +static bool check_portal_channel(void *ctx, u32 channel)
130092 +{
130093 + u32 portal_channel = *(u32 *)ctx;
130094 + if (portal_channel == channel) {
130095 + /* This FQs destination is a portal
130096 + we're cleaning, send a retire */
130097 + return true;
130098 + }
130099 + return false;
130100 +}
130101 +
130102 +
130103 +
130104 +
130105 +static int usdpaa_release(struct inode *inode, struct file *filp)
130106 +{
130107 + struct ctx *ctx = filp->private_data;
130108 + struct mem_mapping *map, *tmpmap;
130109 + struct portal_mapping *portal, *tmpportal;
130110 + const struct alloc_backend *backend = &alloc_backends[0];
130111 + struct active_resource *res;
130112 + struct qm_portal *qm_cleanup_portal = NULL;
130113 + struct bm_portal *bm_cleanup_portal = NULL;
130114 + struct qm_portal_config *qm_alloced_portal = NULL;
130115 + struct bm_portal_config *bm_alloced_portal = NULL;
130116 +
130117 + struct qm_portal *portal_array[qman_portal_max];
130118 + int portal_count = 0;
130119 +
130120 + /* Ensure the release operation cannot be migrated to another
130121 + CPU as CPU specific variables may be needed during cleanup */
130122 +#ifdef CONFIG_PREEMPT_RT_FULL
130123 + migrate_disable();
130124 +#endif
130125 + /* The following logic is used to recover resources that were not
130126 + correctly released by the process that is closing the FD.
130127 + Step 1: syncronize the HW with the qm_portal/bm_portal structures
130128 + in the kernel
130129 + */
130130 +
130131 + list_for_each_entry_safe(portal, tmpportal, &ctx->portals, list) {
130132 + /* Try to recover any portals that weren't shut down */
130133 + if (portal->user.type == usdpaa_portal_qman) {
130134 + portal_array[portal_count] = &portal->qman_portal_low;
130135 + ++portal_count;
130136 + init_qm_portal(portal->qportal,
130137 + &portal->qman_portal_low);
130138 + if (!qm_cleanup_portal) {
130139 + qm_cleanup_portal = &portal->qman_portal_low;
130140 + } else {
130141 + /* Clean FQs on the dedicated channel */
130142 + u32 chan = portal->qportal->public_cfg.channel;
130143 + qm_check_and_destroy_fqs(
130144 + &portal->qman_portal_low, &chan,
130145 + check_portal_channel);
130146 + }
130147 + } else {
130148 + /* BMAN */
130149 + init_bm_portal(portal->bportal,
130150 + &portal->bman_portal_low);
130151 + if (!bm_cleanup_portal)
130152 + bm_cleanup_portal = &portal->bman_portal_low;
130153 + }
130154 + }
130155 + /* If no portal was found, allocate one for cleanup */
130156 + if (!qm_cleanup_portal) {
130157 + qm_alloced_portal = qm_get_unused_portal();
130158 + if (!qm_alloced_portal) {
130159 + pr_crit("No QMan portal avalaible for cleanup\n");
130160 +#ifdef CONFIG_PREEMPT_RT_FULL
130161 + migrate_enable();
130162 +#endif
130163 + return -1;
130164 + }
130165 + qm_cleanup_portal = kmalloc(sizeof(struct qm_portal),
130166 + GFP_KERNEL);
130167 + if (!qm_cleanup_portal) {
130168 +#ifdef CONFIG_PREEMPT_RT_FULL
130169 + migrate_enable();
130170 +#endif
130171 + return -ENOMEM;
130172 + }
130173 + init_qm_portal(qm_alloced_portal, qm_cleanup_portal);
130174 + portal_array[portal_count] = qm_cleanup_portal;
130175 + ++portal_count;
130176 + }
130177 + if (!bm_cleanup_portal) {
130178 + bm_alloced_portal = bm_get_unused_portal();
130179 + if (!bm_alloced_portal) {
130180 + pr_crit("No BMan portal avalaible for cleanup\n");
130181 +#ifdef CONFIG_PREEMPT_RT_FULL
130182 + migrate_enable();
130183 +#endif
130184 + return -1;
130185 + }
130186 + bm_cleanup_portal = kmalloc(sizeof(struct bm_portal),
130187 + GFP_KERNEL);
130188 + if (!bm_cleanup_portal) {
130189 +#ifdef CONFIG_PREEMPT_RT_FULL
130190 + migrate_enable();
130191 +#endif
130192 + return -ENOMEM;
130193 + }
130194 + init_bm_portal(bm_alloced_portal, bm_cleanup_portal);
130195 + }
130196 +
130197 + /* OOS the FQs associated with this process */
130198 + qm_check_and_destroy_fqs(qm_cleanup_portal, ctx, check_channel_device);
130199 +
130200 + while (backend->id_type != usdpaa_id_max) {
130201 + int leaks = 0;
130202 + list_for_each_entry(res, &ctx->resources[backend->id_type],
130203 + list) {
130204 + if (backend->id_type == usdpaa_id_fqid) {
130205 + int i = 0;
130206 + for (; i < res->num; i++) {
130207 + /* Clean FQs with the cleanup portal */
130208 + qm_shutdown_fq(portal_array,
130209 + portal_count,
130210 + res->id + i);
130211 + }
130212 + }
130213 + leaks += res->num;
130214 + backend->release(res->id, res->num);
130215 + }
130216 + if (leaks)
130217 + pr_crit("USDPAA process leaking %d %s%s\n", leaks,
130218 + backend->acronym, (leaks > 1) ? "s" : "");
130219 + backend++;
130220 + }
130221 + /* Release any DMA regions */
130222 + spin_lock(&mem_lock);
130223 + list_for_each_entry_safe(map, tmpmap, &ctx->maps, list) {
130224 + struct mem_fragment *current_frag = map->root_frag;
130225 + int i;
130226 + if (map->root_frag->has_locking &&
130227 + (map->root_frag->owner == map)) {
130228 + map->root_frag->owner = NULL;
130229 + wake_up(&map->root_frag->wq);
130230 + }
130231 + /* Check each fragment and merge if the ref count is 0 */
130232 + for (i = 0; i < map->frag_count; i++) {
130233 + --current_frag->refs;
130234 + current_frag = list_entry(current_frag->list.prev,
130235 + struct mem_fragment, list);
130236 + }
130237 +
130238 + compress_frags();
130239 + list_del(&map->list);
130240 + kfree(map);
130241 + }
130242 + spin_unlock(&mem_lock);
130243 +
130244 + /* Return portals */
130245 + list_for_each_entry_safe(portal, tmpportal, &ctx->portals, list) {
130246 + if (portal->user.type == usdpaa_portal_qman) {
130247 + /* Give the portal back to the allocator */
130248 + init_qm_portal(portal->qportal,
130249 + &portal->qman_portal_low);
130250 + qm_put_unused_portal(portal->qportal);
130251 + } else {
130252 + init_bm_portal(portal->bportal,
130253 + &portal->bman_portal_low);
130254 + bm_put_unused_portal(portal->bportal);
130255 + }
130256 + list_del(&portal->list);
130257 + kfree(portal);
130258 + }
130259 + if (qm_alloced_portal) {
130260 + qm_put_unused_portal(qm_alloced_portal);
130261 + kfree(qm_cleanup_portal);
130262 + }
130263 + if (bm_alloced_portal) {
130264 + bm_put_unused_portal(bm_alloced_portal);
130265 + kfree(bm_cleanup_portal);
130266 + }
130267 +
130268 + kfree(ctx);
130269 +#ifdef CONFIG_PREEMPT_RT_FULL
130270 + migrate_enable();
130271 +#endif
130272 + return 0;
130273 +}
130274 +
130275 +static int check_mmap_dma(struct ctx *ctx, struct vm_area_struct *vma,
130276 + int *match, unsigned long *pfn)
130277 +{
130278 + struct mem_mapping *map;
130279 +
130280 + list_for_each_entry(map, &ctx->maps, list) {
130281 + int i;
130282 + struct mem_fragment *frag = map->root_frag;
130283 +
130284 + for (i = 0; i < map->frag_count; i++) {
130285 + if (frag->pfn_base == vma->vm_pgoff) {
130286 + *match = 1;
130287 + *pfn = frag->pfn_base;
130288 + return 0;
130289 + }
130290 + frag = list_entry(frag->list.next, struct mem_fragment,
130291 + list);
130292 + }
130293 + }
130294 + *match = 0;
130295 + return 0;
130296 +}
130297 +
130298 +static int check_mmap_resource(struct resource *res, struct vm_area_struct *vma,
130299 + int *match, unsigned long *pfn)
130300 +{
130301 + *pfn = res->start >> PAGE_SHIFT;
130302 + if (*pfn == vma->vm_pgoff) {
130303 + *match = 1;
130304 + if ((vma->vm_end - vma->vm_start) != resource_size(res))
130305 + return -EINVAL;
130306 + } else
130307 + *match = 0;
130308 + return 0;
130309 +}
130310 +
130311 +static int check_mmap_portal(struct ctx *ctx, struct vm_area_struct *vma,
130312 + int *match, unsigned long *pfn)
130313 +{
130314 + struct portal_mapping *portal;
130315 + int ret;
130316 +
130317 + list_for_each_entry(portal, &ctx->portals, list) {
130318 + ret = check_mmap_resource(&portal->phys[DPA_PORTAL_CE], vma,
130319 + match, pfn);
130320 + if (*match) {
130321 + vma->vm_page_prot =
130322 +#if defined(CONFIG_ARM) || defined(CONFIG_ARM64)
130323 + pgprot_cached_ns(vma->vm_page_prot);
130324 +#else
130325 + pgprot_cached_noncoherent(vma->vm_page_prot);
130326 +#endif
130327 + return ret;
130328 + }
130329 + ret = check_mmap_resource(&portal->phys[DPA_PORTAL_CI], vma,
130330 + match, pfn);
130331 + if (*match) {
130332 + vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
130333 + return ret;
130334 + }
130335 + }
130336 + *match = 0;
130337 + return 0;
130338 +}
130339 +
130340 +static int usdpaa_mmap(struct file *filp, struct vm_area_struct *vma)
130341 +{
130342 + struct ctx *ctx = filp->private_data;
130343 + unsigned long pfn = 0;
130344 + int match, ret;
130345 +
130346 + spin_lock(&mem_lock);
130347 + ret = check_mmap_dma(ctx, vma, &match, &pfn);
130348 + if (!match)
130349 + ret = check_mmap_portal(ctx, vma, &match, &pfn);
130350 + spin_unlock(&mem_lock);
130351 + if (!match)
130352 + return -EINVAL;
130353 + if (!ret)
130354 + ret = remap_pfn_range(vma, vma->vm_start, pfn,
130355 + vma->vm_end - vma->vm_start,
130356 + vma->vm_page_prot);
130357 + return ret;
130358 +}
130359 +
130360 +/* Return the nearest rounded-up address >= 'addr' that is 'sz'-aligned. 'sz'
130361 + * must be a power of 2, but both 'addr' and 'sz' can be expressions. */
130362 +#define USDPAA_MEM_ROUNDUP(addr, sz) \
130363 + ({ \
130364 + unsigned long foo_align = (sz) - 1; \
130365 + ((addr) + foo_align) & ~foo_align; \
130366 + })
130367 +/* Searching for a size-aligned virtual address range starting from 'addr' */
130368 +static unsigned long usdpaa_get_unmapped_area(struct file *file,
130369 + unsigned long addr,
130370 + unsigned long len,
130371 + unsigned long pgoff,
130372 + unsigned long flags)
130373 +{
130374 + struct vm_area_struct *vma;
130375 +
130376 + if (len % PAGE_SIZE)
130377 + return -EINVAL;
130378 + if (!len)
130379 + return -EINVAL;
130380 +
130381 + /* Need to align the address to the largest pagesize of the mapping
130382 + * because the MMU requires the virtual address to have the same
130383 + * alignment as the physical address */
130384 + addr = USDPAA_MEM_ROUNDUP(addr, largest_page_size(len));
130385 + vma = find_vma(current->mm, addr);
130386 + /* Keep searching until we reach the end of currently-used virtual
130387 + * address-space or we find a big enough gap. */
130388 + while (vma) {
130389 + if ((addr + len) < vma->vm_start)
130390 + return addr;
130391 +
130392 + addr = USDPAA_MEM_ROUNDUP(vma->vm_end, largest_page_size(len));
130393 + vma = vma->vm_next;
130394 + }
130395 + if ((TASK_SIZE - len) < addr)
130396 + return -ENOMEM;
130397 + return addr;
130398 +}
130399 +
130400 +static long ioctl_id_alloc(struct ctx *ctx, void __user *arg)
130401 +{
130402 + struct usdpaa_ioctl_id_alloc i;
130403 + const struct alloc_backend *backend;
130404 + struct active_resource *res;
130405 + int ret = copy_from_user(&i, arg, sizeof(i));
130406 + if (ret)
130407 + return ret;
130408 + if ((i.id_type >= usdpaa_id_max) || !i.num)
130409 + return -EINVAL;
130410 + backend = &alloc_backends[i.id_type];
130411 + /* Allocate the required resource type */
130412 + ret = backend->alloc(&i.base, i.num, i.align, i.partial);
130413 + if (ret < 0)
130414 + return ret;
130415 + i.num = ret;
130416 + /* Copy the result to user-space */
130417 + ret = copy_to_user(arg, &i, sizeof(i));
130418 + if (ret) {
130419 + backend->release(i.base, i.num);
130420 + return ret;
130421 + }
130422 + /* Assign the allocated range to the FD accounting */
130423 + res = kmalloc(sizeof(*res), GFP_KERNEL);
130424 + if (!res) {
130425 + backend->release(i.base, i.num);
130426 + return -ENOMEM;
130427 + }
130428 + spin_lock(&ctx->lock);
130429 + res->id = i.base;
130430 + res->num = i.num;
130431 + res->refcount = 1;
130432 + list_add(&res->list, &ctx->resources[i.id_type]);
130433 + spin_unlock(&ctx->lock);
130434 + return 0;
130435 +}
130436 +
130437 +static long ioctl_id_release(struct ctx *ctx, void __user *arg)
130438 +{
130439 + struct usdpaa_ioctl_id_release i;
130440 + const struct alloc_backend *backend;
130441 + struct active_resource *tmp, *pos;
130442 +
130443 + int ret = copy_from_user(&i, arg, sizeof(i));
130444 + if (ret)
130445 + return ret;
130446 + if ((i.id_type >= usdpaa_id_max) || !i.num)
130447 + return -EINVAL;
130448 + backend = &alloc_backends[i.id_type];
130449 + /* Pull the range out of the FD accounting - the range is valid iff this
130450 + * succeeds. */
130451 + spin_lock(&ctx->lock);
130452 + list_for_each_entry_safe(pos, tmp, &ctx->resources[i.id_type], list) {
130453 + if (pos->id == i.base && pos->num == i.num) {
130454 + pos->refcount--;
130455 + if (pos->refcount) {
130456 + spin_unlock(&ctx->lock);
130457 + return 0; /* Still being used */
130458 + }
130459 + list_del(&pos->list);
130460 + kfree(pos);
130461 + spin_unlock(&ctx->lock);
130462 + goto found;
130463 + }
130464 + }
130465 + /* Failed to find the resource */
130466 + spin_unlock(&ctx->lock);
130467 + pr_err("Couldn't find resource type %d base 0x%x num %d\n",
130468 + i.id_type, i.base, i.num);
130469 + return -EINVAL;
130470 +found:
130471 + /* Release the resource to the backend */
130472 + backend->release(i.base, i.num);
130473 + return 0;
130474 +}
130475 +
130476 +static long ioctl_id_reserve(struct ctx *ctx, void __user *arg)
130477 +{
130478 + struct usdpaa_ioctl_id_reserve i;
130479 + const struct alloc_backend *backend;
130480 + struct active_resource *tmp, *pos;
130481 +
130482 + int ret = copy_from_user(&i, arg, sizeof(i));
130483 + if (ret)
130484 + return ret;
130485 + if ((i.id_type >= usdpaa_id_max) || !i.num)
130486 + return -EINVAL;
130487 + backend = &alloc_backends[i.id_type];
130488 + if (!backend->reserve)
130489 + return -EINVAL;
130490 + /* Pull the range out of the FD accounting - the range is valid iff this
130491 + * succeeds. */
130492 + spin_lock(&ctx->lock);
130493 + list_for_each_entry_safe(pos, tmp, &ctx->resources[i.id_type], list) {
130494 + if (pos->id == i.base && pos->num == i.num) {
130495 + pos->refcount++;
130496 + spin_unlock(&ctx->lock);
130497 + return 0;
130498 + }
130499 + }
130500 +
130501 + /* Failed to find the resource */
130502 + spin_unlock(&ctx->lock);
130503 +
130504 + /* Reserve the resource in the backend */
130505 + ret = backend->reserve(i.base, i.num);
130506 + if (ret)
130507 + return ret;
130508 + /* Assign the reserved range to the FD accounting */
130509 + pos = kmalloc(sizeof(*pos), GFP_KERNEL);
130510 + if (!pos) {
130511 + backend->release(i.base, i.num);
130512 + return -ENOMEM;
130513 + }
130514 + spin_lock(&ctx->lock);
130515 + pos->id = i.base;
130516 + pos->num = i.num;
130517 + pos->refcount = 1;
130518 + list_add(&pos->list, &ctx->resources[i.id_type]);
130519 + spin_unlock(&ctx->lock);
130520 + return 0;
130521 +}
130522 +
130523 +static long ioctl_dma_map(struct file *fp, struct ctx *ctx,
130524 + struct usdpaa_ioctl_dma_map *i)
130525 +{
130526 + struct mem_fragment *frag, *start_frag, *next_frag;
130527 + struct mem_mapping *map, *tmp;
130528 + int ret = 0;
130529 + u32 largest_page, so_far = 0;
130530 + int frag_count = 0;
130531 + unsigned long next_addr = PAGE_SIZE, populate;
130532 +
130533 + /* error checking to ensure values copied from user space are valid */
130534 + if (i->len % PAGE_SIZE)
130535 + return -EINVAL;
130536 +
130537 + map = kmalloc(sizeof(*map), GFP_KERNEL);
130538 + if (!map)
130539 + return -ENOMEM;
130540 +
130541 + spin_lock(&mem_lock);
130542 + if (i->flags & USDPAA_DMA_FLAG_SHARE) {
130543 + list_for_each_entry(frag, &mem_list, list) {
130544 + if (frag->refs && (frag->flags &
130545 + USDPAA_DMA_FLAG_SHARE) &&
130546 + !strncmp(i->name, frag->name,
130547 + USDPAA_DMA_NAME_MAX)) {
130548 + /* Matching entry */
130549 + if ((i->flags & USDPAA_DMA_FLAG_CREATE) &&
130550 + !(i->flags & USDPAA_DMA_FLAG_LAZY)) {
130551 + ret = -EBUSY;
130552 + goto out;
130553 + }
130554 +
130555 + /* Check to ensure size matches record */
130556 + if (i->len != frag->map_len && i->len) {
130557 + pr_err("ioctl_dma_map() Size requested does not match %s and is none zero\n",
130558 + frag->name);
130559 + return -EINVAL;
130560 + }
130561 +
130562 + /* Check if this has already been mapped
130563 + to this process */
130564 + list_for_each_entry(tmp, &ctx->maps, list)
130565 + if (tmp->root_frag == frag) {
130566 + /* Already mapped, just need to
130567 + inc ref count */
130568 + tmp->refs++;
130569 + kfree(map);
130570 + i->did_create = 0;
130571 + i->len = tmp->total_size;
130572 + i->phys_addr = frag->base;
130573 + i->ptr = tmp->virt_addr;
130574 + spin_unlock(&mem_lock);
130575 + return 0;
130576 + }
130577 + /* Matching entry - just need to map */
130578 + i->has_locking = frag->has_locking;
130579 + i->did_create = 0;
130580 + i->len = frag->map_len;
130581 + start_frag = frag;
130582 + goto do_map;
130583 + }
130584 + }
130585 + /* No matching entry */
130586 + if (!(i->flags & USDPAA_DMA_FLAG_CREATE)) {
130587 + pr_err("ioctl_dma_map() No matching entry\n");
130588 + ret = -ENOMEM;
130589 + goto out;
130590 + }
130591 + }
130592 + /* New fragment required, size must be provided. */
130593 + if (!i->len) {
130594 + ret = -EINVAL;
130595 + goto out;
130596 + }
130597 +
130598 + /* Find one of more contiguous fragments that satisfy the total length
130599 + trying to minimize the number of fragments
130600 + compute the largest page size that the allocation could use */
130601 + largest_page = largest_page_size(i->len);
130602 + start_frag = NULL;
130603 + while (largest_page &&
130604 + largest_page <= largest_page_size(phys_size) &&
130605 + start_frag == NULL) {
130606 + /* Search the list for a frag of that size */
130607 + list_for_each_entry(frag, &mem_list, list) {
130608 + if (!frag->refs && (frag->len == largest_page)) {
130609 + /* See if the next x fragments are free
130610 + and can accomidate the size */
130611 + u32 found_size = largest_page;
130612 + next_frag = list_entry(frag->list.prev,
130613 + struct mem_fragment,
130614 + list);
130615 + /* If the fragement is too small check
130616 + if the neighbours cab support it */
130617 + while (found_size < i->len) {
130618 + if (&mem_list == &next_frag->list)
130619 + break; /* End of list */
130620 + if (next_frag->refs != 0 ||
130621 + next_frag->len == 0)
130622 + break; /* not enough space */
130623 + found_size += next_frag->len;
130624 + next_frag = list_entry(
130625 + next_frag->list.prev,
130626 + struct mem_fragment,
130627 + list);
130628 + }
130629 + if (found_size >= i->len) {
130630 + /* Success! there is enough contigous
130631 + free space */
130632 + start_frag = frag;
130633 + break;
130634 + }
130635 + }
130636 + } /* next frag loop */
130637 + /* Couldn't statisfy the request with this
130638 + largest page size, try a smaller one */
130639 + largest_page <<= 2;
130640 + }
130641 + if (start_frag == NULL) {
130642 + /* Couldn't find proper amount of space */
130643 + ret = -ENOMEM;
130644 + goto out;
130645 + }
130646 + i->did_create = 1;
130647 +do_map:
130648 + /* Verify there is sufficient space to do the mapping */
130649 + down_write(&current->mm->mmap_sem);
130650 + next_addr = usdpaa_get_unmapped_area(fp, next_addr, i->len, 0, 0);
130651 + up_write(&current->mm->mmap_sem);
130652 +
130653 + if (next_addr & ~PAGE_MASK) {
130654 + ret = -ENOMEM;
130655 + goto out;
130656 + }
130657 +
130658 + /* We may need to divide the final fragment to accomidate the mapping */
130659 + next_frag = start_frag;
130660 + while (so_far != i->len) {
130661 + BUG_ON(next_frag->len == 0);
130662 + while ((next_frag->len + so_far) > i->len) {
130663 + /* Split frag until they match */
130664 + split_frag(next_frag);
130665 + }
130666 + so_far += next_frag->len;
130667 + next_frag->refs++;
130668 + ++frag_count;
130669 + next_frag = list_entry(next_frag->list.prev,
130670 + struct mem_fragment, list);
130671 + }
130672 + if (i->did_create) {
130673 + size_t name_len = 0;
130674 + start_frag->flags = i->flags;
130675 + strncpy(start_frag->name, i->name, USDPAA_DMA_NAME_MAX);
130676 + name_len = strnlen(start_frag->name, USDPAA_DMA_NAME_MAX);
130677 + if (name_len >= USDPAA_DMA_NAME_MAX) {
130678 + ret = -EFAULT;
130679 + goto out;
130680 + }
130681 + start_frag->map_len = i->len;
130682 + start_frag->has_locking = i->has_locking;
130683 + init_waitqueue_head(&start_frag->wq);
130684 + start_frag->owner = NULL;
130685 + }
130686 +
130687 + /* Setup the map entry */
130688 + map->root_frag = start_frag;
130689 + map->total_size = i->len;
130690 + map->frag_count = frag_count;
130691 + map->refs = 1;
130692 + list_add(&map->list, &ctx->maps);
130693 + i->phys_addr = start_frag->base;
130694 +out:
130695 + spin_unlock(&mem_lock);
130696 +
130697 + if (!ret) {
130698 + unsigned long longret;
130699 + down_write(&current->mm->mmap_sem);
130700 + longret = do_mmap_pgoff(fp, next_addr, map->total_size,
130701 + PROT_READ |
130702 + (i->flags &
130703 + USDPAA_DMA_FLAG_RDONLY ? 0
130704 + : PROT_WRITE),
130705 + MAP_SHARED,
130706 + start_frag->pfn_base,
130707 + &populate);
130708 + up_write(&current->mm->mmap_sem);
130709 + if (longret & ~PAGE_MASK) {
130710 + ret = (int)longret;
130711 + } else {
130712 + i->ptr = (void *)longret;
130713 + map->virt_addr = i->ptr;
130714 + }
130715 + } else
130716 + kfree(map);
130717 + return ret;
130718 +}
130719 +
130720 +static long ioctl_dma_unmap(struct ctx *ctx, void __user *arg)
130721 +{
130722 + struct mem_mapping *map;
130723 + struct vm_area_struct *vma;
130724 + int ret, i;
130725 + struct mem_fragment *current_frag;
130726 + size_t sz;
130727 + unsigned long base;
130728 + unsigned long vaddr;
130729 +
130730 + down_write(&current->mm->mmap_sem);
130731 + vma = find_vma(current->mm, (unsigned long)arg);
130732 + if (!vma || (vma->vm_start > (unsigned long)arg)) {
130733 + up_write(&current->mm->mmap_sem);
130734 + return -EFAULT;
130735 + }
130736 + spin_lock(&mem_lock);
130737 + list_for_each_entry(map, &ctx->maps, list) {
130738 + if (map->root_frag->pfn_base == vma->vm_pgoff) {
130739 + /* Drop the map lock if we hold it */
130740 + if (map->root_frag->has_locking &&
130741 + (map->root_frag->owner == map)) {
130742 + map->root_frag->owner = NULL;
130743 + wake_up(&map->root_frag->wq);
130744 + }
130745 + goto map_match;
130746 + }
130747 + }
130748 + /* Failed to find a matching mapping for this process */
130749 + ret = -EFAULT;
130750 + spin_unlock(&mem_lock);
130751 + goto out;
130752 +map_match:
130753 + map->refs--;
130754 + if (map->refs != 0) {
130755 + /* Another call the dma_map is referencing this */
130756 + ret = 0;
130757 + spin_unlock(&mem_lock);
130758 + goto out;
130759 + }
130760 +
130761 + current_frag = map->root_frag;
130762 + vaddr = (unsigned long) map->virt_addr;
130763 + for (i = 0; i < map->frag_count; i++) {
130764 + DPA_ASSERT(current_frag->refs > 0);
130765 + --current_frag->refs;
130766 +#if !(defined(CONFIG_ARM) || defined(CONFIG_ARM64))
130767 + /*
130768 + * Make sure we invalidate the TLB entry for
130769 + * this fragment, otherwise a remap of a different
130770 + * page to this vaddr would give acces to an
130771 + * incorrect piece of memory
130772 + */
130773 + cleartlbcam(vaddr, mfspr(SPRN_PID));
130774 +#endif
130775 + vaddr += current_frag->len;
130776 + current_frag = list_entry(current_frag->list.prev,
130777 + struct mem_fragment, list);
130778 + }
130779 + map->root_frag->name[0] = 0;
130780 + list_del(&map->list);
130781 + compress_frags();
130782 + spin_unlock(&mem_lock);
130783 +
130784 + base = vma->vm_start;
130785 + sz = vma->vm_end - vma->vm_start;
130786 + do_munmap(current->mm, base, sz);
130787 + ret = 0;
130788 + out:
130789 + up_write(&current->mm->mmap_sem);
130790 + return ret;
130791 +}
130792 +
130793 +static long ioctl_dma_stats(struct ctx *ctx, void __user *arg)
130794 +{
130795 + struct mem_fragment *frag;
130796 + struct usdpaa_ioctl_dma_used result;
130797 +
130798 + result.free_bytes = 0;
130799 + result.total_bytes = phys_size;
130800 +
130801 + list_for_each_entry(frag, &mem_list, list) {
130802 + if (frag->refs == 0)
130803 + result.free_bytes += frag->len;
130804 + }
130805 +
130806 + return copy_to_user(arg, &result, sizeof(result)); }
130807 +
130808 +static int test_lock(struct mem_mapping *map)
130809 +{
130810 + int ret = 0;
130811 + spin_lock(&mem_lock);
130812 + if (!map->root_frag->owner) {
130813 + map->root_frag->owner = map;
130814 + ret = 1;
130815 + }
130816 + spin_unlock(&mem_lock);
130817 + return ret;
130818 +}
130819 +
130820 +static long ioctl_dma_lock(struct ctx *ctx, void __user *arg)
130821 +{
130822 + struct mem_mapping *map;
130823 + struct vm_area_struct *vma;
130824 +
130825 + down_read(&current->mm->mmap_sem);
130826 + vma = find_vma(current->mm, (unsigned long)arg);
130827 + if (!vma || (vma->vm_start > (unsigned long)arg)) {
130828 + up_read(&current->mm->mmap_sem);
130829 + return -EFAULT;
130830 + }
130831 + spin_lock(&mem_lock);
130832 + list_for_each_entry(map, &ctx->maps, list) {
130833 + if (map->root_frag->pfn_base == vma->vm_pgoff)
130834 + goto map_match;
130835 + }
130836 + map = NULL;
130837 +map_match:
130838 + spin_unlock(&mem_lock);
130839 + up_read(&current->mm->mmap_sem);
130840 +
130841 + if (!map)
130842 + return -EFAULT;
130843 + if (!map->root_frag->has_locking)
130844 + return -ENODEV;
130845 + return wait_event_interruptible(map->root_frag->wq, test_lock(map));
130846 +}
130847 +
130848 +static long ioctl_dma_unlock(struct ctx *ctx, void __user *arg)
130849 +{
130850 + struct mem_mapping *map;
130851 + struct vm_area_struct *vma;
130852 + int ret;
130853 +
130854 + down_read(&current->mm->mmap_sem);
130855 + vma = find_vma(current->mm, (unsigned long)arg);
130856 + if (!vma || (vma->vm_start > (unsigned long)arg))
130857 + ret = -EFAULT;
130858 + else {
130859 + spin_lock(&mem_lock);
130860 + list_for_each_entry(map, &ctx->maps, list) {
130861 + if (map->root_frag->pfn_base == vma->vm_pgoff) {
130862 + if (!map->root_frag->has_locking)
130863 + ret = -ENODEV;
130864 + else if (map->root_frag->owner == map) {
130865 + map->root_frag->owner = NULL;
130866 + wake_up(&map->root_frag->wq);
130867 + ret = 0;
130868 + } else
130869 + ret = -EBUSY;
130870 + goto map_match;
130871 + }
130872 + }
130873 + ret = -EINVAL;
130874 +map_match:
130875 + spin_unlock(&mem_lock);
130876 + }
130877 + up_read(&current->mm->mmap_sem);
130878 + return ret;
130879 +}
130880 +
130881 +static int portal_mmap(struct file *fp, struct resource *res, void **ptr)
130882 +{
130883 + unsigned long longret = 0, populate;
130884 + resource_size_t len;
130885 +
130886 + down_write(&current->mm->mmap_sem);
130887 + len = resource_size(res);
130888 + if (len != (unsigned long)len)
130889 + return -EINVAL;
130890 + longret = do_mmap_pgoff(fp, PAGE_SIZE, (unsigned long)len,
130891 + PROT_READ | PROT_WRITE, MAP_SHARED,
130892 + res->start >> PAGE_SHIFT, &populate);
130893 + up_write(&current->mm->mmap_sem);
130894 +
130895 + if (longret & ~PAGE_MASK)
130896 + return (int)longret;
130897 +
130898 + *ptr = (void *) longret;
130899 + return 0;
130900 +}
130901 +
130902 +static void portal_munmap(struct resource *res, void *ptr)
130903 +{
130904 + down_write(&current->mm->mmap_sem);
130905 + do_munmap(current->mm, (unsigned long)ptr, resource_size(res));
130906 + up_write(&current->mm->mmap_sem);
130907 +}
130908 +
130909 +static long ioctl_portal_map(struct file *fp, struct ctx *ctx,
130910 + struct usdpaa_ioctl_portal_map *arg)
130911 +{
130912 + struct portal_mapping *mapping = kmalloc(sizeof(*mapping), GFP_KERNEL);
130913 + int ret;
130914 +
130915 + if (!mapping)
130916 + return -ENOMEM;
130917 +
130918 + mapping->user = *arg;
130919 + mapping->iommu_domain = NULL;
130920 +
130921 + if (mapping->user.type == usdpaa_portal_qman) {
130922 + mapping->qportal =
130923 + qm_get_unused_portal_idx(mapping->user.index);
130924 + if (!mapping->qportal) {
130925 + ret = -ENODEV;
130926 + goto err_get_portal;
130927 + }
130928 + mapping->phys = &mapping->qportal->addr_phys[0];
130929 + mapping->user.channel = mapping->qportal->public_cfg.channel;
130930 + mapping->user.pools = mapping->qportal->public_cfg.pools;
130931 + mapping->user.index = mapping->qportal->public_cfg.index;
130932 + } else if (mapping->user.type == usdpaa_portal_bman) {
130933 + mapping->bportal =
130934 + bm_get_unused_portal_idx(mapping->user.index);
130935 + if (!mapping->bportal) {
130936 + ret = -ENODEV;
130937 + goto err_get_portal;
130938 + }
130939 + mapping->phys = &mapping->bportal->addr_phys[0];
130940 + mapping->user.index = mapping->bportal->public_cfg.index;
130941 + } else {
130942 + ret = -EINVAL;
130943 + goto err_copy_from_user;
130944 + }
130945 + /* Need to put pcfg in ctx's list before the mmaps because the mmap
130946 + * handlers look it up. */
130947 + spin_lock(&mem_lock);
130948 + list_add(&mapping->list, &ctx->portals);
130949 + spin_unlock(&mem_lock);
130950 + ret = portal_mmap(fp, &mapping->phys[DPA_PORTAL_CE],
130951 + &mapping->user.addr.cena);
130952 + if (ret)
130953 + goto err_mmap_cena;
130954 + ret = portal_mmap(fp, &mapping->phys[DPA_PORTAL_CI],
130955 + &mapping->user.addr.cinh);
130956 + if (ret)
130957 + goto err_mmap_cinh;
130958 + *arg = mapping->user;
130959 + return ret;
130960 +
130961 +err_mmap_cinh:
130962 + portal_munmap(&mapping->phys[DPA_PORTAL_CE], mapping->user.addr.cena);
130963 +err_mmap_cena:
130964 + if ((mapping->user.type == usdpaa_portal_qman) && mapping->qportal)
130965 + qm_put_unused_portal(mapping->qportal);
130966 + else if ((mapping->user.type == usdpaa_portal_bman) && mapping->bportal)
130967 + bm_put_unused_portal(mapping->bportal);
130968 + spin_lock(&mem_lock);
130969 + list_del(&mapping->list);
130970 + spin_unlock(&mem_lock);
130971 +err_get_portal:
130972 +err_copy_from_user:
130973 + kfree(mapping);
130974 + return ret;
130975 +}
130976 +
130977 +static long ioctl_portal_unmap(struct ctx *ctx, struct usdpaa_portal_map *i)
130978 +{
130979 + struct portal_mapping *mapping;
130980 + struct vm_area_struct *vma;
130981 + unsigned long pfn;
130982 + u32 channel;
130983 +
130984 + /* Get the PFN corresponding to one of the virt addresses */
130985 + down_read(&current->mm->mmap_sem);
130986 + vma = find_vma(current->mm, (unsigned long)i->cinh);
130987 + if (!vma || (vma->vm_start > (unsigned long)i->cinh)) {
130988 + up_read(&current->mm->mmap_sem);
130989 + return -EFAULT;
130990 + }
130991 + pfn = vma->vm_pgoff;
130992 + up_read(&current->mm->mmap_sem);
130993 +
130994 + /* Find the corresponding portal */
130995 + spin_lock(&mem_lock);
130996 + list_for_each_entry(mapping, &ctx->portals, list) {
130997 + if (pfn == (mapping->phys[DPA_PORTAL_CI].start >> PAGE_SHIFT))
130998 + goto found;
130999 + }
131000 + mapping = NULL;
131001 +found:
131002 + if (mapping)
131003 + list_del(&mapping->list);
131004 + spin_unlock(&mem_lock);
131005 + if (!mapping)
131006 + return -ENODEV;
131007 + portal_munmap(&mapping->phys[DPA_PORTAL_CI], mapping->user.addr.cinh);
131008 + portal_munmap(&mapping->phys[DPA_PORTAL_CE], mapping->user.addr.cena);
131009 + if (mapping->user.type == usdpaa_portal_qman) {
131010 + init_qm_portal(mapping->qportal,
131011 + &mapping->qman_portal_low);
131012 +
131013 + /* Tear down any FQs this portal is referencing */
131014 + channel = mapping->qportal->public_cfg.channel;
131015 + qm_check_and_destroy_fqs(&mapping->qman_portal_low,
131016 + &channel,
131017 + check_portal_channel);
131018 + qm_put_unused_portal(mapping->qportal);
131019 + } else if (mapping->user.type == usdpaa_portal_bman) {
131020 + init_bm_portal(mapping->bportal,
131021 + &mapping->bman_portal_low);
131022 + bm_put_unused_portal(mapping->bportal);
131023 + }
131024 + kfree(mapping);
131025 + return 0;
131026 +}
131027 +
131028 +static void portal_config_pamu(struct qm_portal_config *pcfg, uint8_t sdest,
131029 + uint32_t cpu, uint32_t cache, uint32_t window)
131030 +{
131031 +#ifdef CONFIG_FSL_PAMU
131032 + int ret;
131033 + int window_count = 1;
131034 + struct iommu_domain_geometry geom_attr;
131035 + struct pamu_stash_attribute stash_attr;
131036 +
131037 + pcfg->iommu_domain = iommu_domain_alloc(&platform_bus_type);
131038 + if (!pcfg->iommu_domain) {
131039 + pr_err(KBUILD_MODNAME ":%s(): iommu_domain_alloc() failed",
131040 + __func__);
131041 + goto _no_iommu;
131042 + }
131043 + geom_attr.aperture_start = 0;
131044 + geom_attr.aperture_end =
131045 + ((dma_addr_t)1 << min(8 * sizeof(dma_addr_t), (size_t)36)) - 1;
131046 + geom_attr.force_aperture = true;
131047 + ret = iommu_domain_set_attr(pcfg->iommu_domain, DOMAIN_ATTR_GEOMETRY,
131048 + &geom_attr);
131049 + if (ret < 0) {
131050 + pr_err(KBUILD_MODNAME ":%s(): iommu_domain_set_attr() = %d",
131051 + __func__, ret);
131052 + goto _iommu_domain_free;
131053 + }
131054 + ret = iommu_domain_set_attr(pcfg->iommu_domain, DOMAIN_ATTR_WINDOWS,
131055 + &window_count);
131056 + if (ret < 0) {
131057 + pr_err(KBUILD_MODNAME ":%s(): iommu_domain_set_attr() = %d",
131058 + __func__, ret);
131059 + goto _iommu_domain_free;
131060 + }
131061 + stash_attr.cpu = cpu;
131062 + stash_attr.cache = cache;
131063 + /* set stash information for the window */
131064 + stash_attr.window = 0;
131065 +
131066 + ret = iommu_domain_set_attr(pcfg->iommu_domain,
131067 + DOMAIN_ATTR_FSL_PAMU_STASH,
131068 + &stash_attr);
131069 + if (ret < 0) {
131070 + pr_err(KBUILD_MODNAME ":%s(): iommu_domain_set_attr() = %d",
131071 + __func__, ret);
131072 + goto _iommu_domain_free;
131073 + }
131074 + ret = iommu_domain_window_enable(pcfg->iommu_domain, 0, 0, 1ULL << 36,
131075 + IOMMU_READ | IOMMU_WRITE);
131076 + if (ret < 0) {
131077 + pr_err(KBUILD_MODNAME ":%s(): iommu_domain_window_enable() = %d",
131078 + __func__, ret);
131079 + goto _iommu_domain_free;
131080 + }
131081 + ret = iommu_attach_device(pcfg->iommu_domain, &pcfg->dev);
131082 + if (ret < 0) {
131083 + pr_err(KBUILD_MODNAME ":%s(): iommu_device_attach() = %d",
131084 + __func__, ret);
131085 + goto _iommu_domain_free;
131086 + }
131087 + ret = iommu_domain_set_attr(pcfg->iommu_domain,
131088 + DOMAIN_ATTR_FSL_PAMU_ENABLE,
131089 + &window_count);
131090 + if (ret < 0) {
131091 + pr_err(KBUILD_MODNAME ":%s(): iommu_domain_set_attr() = %d",
131092 + __func__, ret);
131093 + goto _iommu_detach_device;
131094 + }
131095 +_no_iommu:
131096 +#endif
131097 +
131098 +#ifdef CONFIG_FSL_QMAN_CONFIG
131099 + if (qman_set_sdest(pcfg->public_cfg.channel, sdest))
131100 +#endif
131101 + pr_warn("Failed to set QMan portal's stash request queue\n");
131102 +
131103 + return;
131104 +
131105 +#ifdef CONFIG_FSL_PAMU
131106 +_iommu_detach_device:
131107 + iommu_detach_device(pcfg->iommu_domain, NULL);
131108 +_iommu_domain_free:
131109 + iommu_domain_free(pcfg->iommu_domain);
131110 +#endif
131111 +}
131112 +
131113 +static long ioctl_allocate_raw_portal(struct file *fp, struct ctx *ctx,
131114 + struct usdpaa_ioctl_raw_portal *arg)
131115 +{
131116 + struct portal_mapping *mapping = kmalloc(sizeof(*mapping), GFP_KERNEL);
131117 + int ret;
131118 +
131119 + if (!mapping)
131120 + return -ENOMEM;
131121 +
131122 + mapping->user.type = arg->type;
131123 + mapping->iommu_domain = NULL;
131124 + if (arg->type == usdpaa_portal_qman) {
131125 + mapping->qportal = qm_get_unused_portal_idx(arg->index);
131126 + if (!mapping->qportal) {
131127 + ret = -ENODEV;
131128 + goto err;
131129 + }
131130 + mapping->phys = &mapping->qportal->addr_phys[0];
131131 + arg->index = mapping->qportal->public_cfg.index;
131132 + arg->cinh = mapping->qportal->addr_phys[DPA_PORTAL_CI].start;
131133 + arg->cena = mapping->qportal->addr_phys[DPA_PORTAL_CE].start;
131134 + if (arg->enable_stash) {
131135 + /* Setup the PAMU with the supplied parameters */
131136 + portal_config_pamu(mapping->qportal, arg->sdest,
131137 + arg->cpu, arg->cache, arg->window);
131138 + }
131139 + } else if (mapping->user.type == usdpaa_portal_bman) {
131140 + mapping->bportal =
131141 + bm_get_unused_portal_idx(arg->index);
131142 + if (!mapping->bportal) {
131143 + ret = -ENODEV;
131144 + goto err;
131145 + }
131146 + mapping->phys = &mapping->bportal->addr_phys[0];
131147 + arg->index = mapping->bportal->public_cfg.index;
131148 + arg->cinh = mapping->bportal->addr_phys[DPA_PORTAL_CI].start;
131149 + arg->cena = mapping->bportal->addr_phys[DPA_PORTAL_CE].start;
131150 + } else {
131151 + ret = -EINVAL;
131152 + goto err;
131153 + }
131154 + /* Need to put pcfg in ctx's list before the mmaps because the mmap
131155 + * handlers look it up. */
131156 + spin_lock(&mem_lock);
131157 + list_add(&mapping->list, &ctx->portals);
131158 + spin_unlock(&mem_lock);
131159 + return 0;
131160 +err:
131161 + kfree(mapping);
131162 + return ret;
131163 +}
131164 +
131165 +static long ioctl_free_raw_portal(struct file *fp, struct ctx *ctx,
131166 + struct usdpaa_ioctl_raw_portal *arg)
131167 +{
131168 + struct portal_mapping *mapping;
131169 + u32 channel;
131170 +
131171 + /* Find the corresponding portal */
131172 + spin_lock(&mem_lock);
131173 + list_for_each_entry(mapping, &ctx->portals, list) {
131174 + if (mapping->phys[DPA_PORTAL_CI].start == arg->cinh)
131175 + goto found;
131176 + }
131177 + mapping = NULL;
131178 +found:
131179 + if (mapping)
131180 + list_del(&mapping->list);
131181 + spin_unlock(&mem_lock);
131182 + if (!mapping)
131183 + return -ENODEV;
131184 + if (mapping->user.type == usdpaa_portal_qman) {
131185 + init_qm_portal(mapping->qportal,
131186 + &mapping->qman_portal_low);
131187 +
131188 + /* Tear down any FQs this portal is referencing */
131189 + channel = mapping->qportal->public_cfg.channel;
131190 + qm_check_and_destroy_fqs(&mapping->qman_portal_low,
131191 + &channel,
131192 + check_portal_channel);
131193 + qm_put_unused_portal(mapping->qportal);
131194 + } else if (mapping->user.type == usdpaa_portal_bman) {
131195 + init_bm_portal(mapping->bportal,
131196 + &mapping->bman_portal_low);
131197 + bm_put_unused_portal(mapping->bportal);
131198 + }
131199 + kfree(mapping);
131200 + return 0;
131201 +}
131202 +
131203 +static long usdpaa_ioctl(struct file *fp, unsigned int cmd, unsigned long arg)
131204 +{
131205 + struct ctx *ctx = fp->private_data;
131206 + void __user *a = (void __user *)arg;
131207 + switch (cmd) {
131208 + case USDPAA_IOCTL_ID_ALLOC:
131209 + return ioctl_id_alloc(ctx, a);
131210 + case USDPAA_IOCTL_ID_RELEASE:
131211 + return ioctl_id_release(ctx, a);
131212 + case USDPAA_IOCTL_ID_RESERVE:
131213 + return ioctl_id_reserve(ctx, a);
131214 + case USDPAA_IOCTL_DMA_MAP:
131215 + {
131216 + struct usdpaa_ioctl_dma_map input;
131217 + int ret;
131218 + if (copy_from_user(&input, a, sizeof(input)))
131219 + return -EFAULT;
131220 + ret = ioctl_dma_map(fp, ctx, &input);
131221 + if (copy_to_user(a, &input, sizeof(input)))
131222 + return -EFAULT;
131223 + return ret;
131224 + }
131225 + case USDPAA_IOCTL_DMA_UNMAP:
131226 + return ioctl_dma_unmap(ctx, a);
131227 + case USDPAA_IOCTL_DMA_LOCK:
131228 + return ioctl_dma_lock(ctx, a);
131229 + case USDPAA_IOCTL_DMA_UNLOCK:
131230 + return ioctl_dma_unlock(ctx, a);
131231 + case USDPAA_IOCTL_PORTAL_MAP:
131232 + {
131233 + struct usdpaa_ioctl_portal_map input;
131234 + int ret;
131235 + if (copy_from_user(&input, a, sizeof(input)))
131236 + return -EFAULT;
131237 + ret = ioctl_portal_map(fp, ctx, &input);
131238 + if (copy_to_user(a, &input, sizeof(input)))
131239 + return -EFAULT;
131240 + return ret;
131241 + }
131242 + case USDPAA_IOCTL_PORTAL_UNMAP:
131243 + {
131244 + struct usdpaa_portal_map input;
131245 + if (copy_from_user(&input, a, sizeof(input)))
131246 + return -EFAULT;
131247 + return ioctl_portal_unmap(ctx, &input);
131248 + }
131249 + case USDPAA_IOCTL_DMA_USED:
131250 + return ioctl_dma_stats(ctx, a);
131251 + case USDPAA_IOCTL_ALLOC_RAW_PORTAL:
131252 + {
131253 + struct usdpaa_ioctl_raw_portal input;
131254 + int ret;
131255 + if (copy_from_user(&input, a, sizeof(input)))
131256 + return -EFAULT;
131257 + ret = ioctl_allocate_raw_portal(fp, ctx, &input);
131258 + if (copy_to_user(a, &input, sizeof(input)))
131259 + return -EFAULT;
131260 + return ret;
131261 + }
131262 + case USDPAA_IOCTL_FREE_RAW_PORTAL:
131263 + {
131264 + struct usdpaa_ioctl_raw_portal input;
131265 + if (copy_from_user(&input, a, sizeof(input)))
131266 + return -EFAULT;
131267 + return ioctl_free_raw_portal(fp, ctx, &input);
131268 + }
131269 + }
131270 + return -EINVAL;
131271 +}
131272 +
131273 +static long usdpaa_ioctl_compat(struct file *fp, unsigned int cmd,
131274 + unsigned long arg)
131275 +{
131276 +#ifdef CONFIG_COMPAT
131277 + struct ctx *ctx = fp->private_data;
131278 + void __user *a = (void __user *)arg;
131279 +#endif
131280 + switch (cmd) {
131281 +#ifdef CONFIG_COMPAT
131282 + case USDPAA_IOCTL_DMA_MAP_COMPAT:
131283 + {
131284 + int ret;
131285 + struct usdpaa_ioctl_dma_map_compat input;
131286 + struct usdpaa_ioctl_dma_map converted;
131287 +
131288 + if (copy_from_user(&input, a, sizeof(input)))
131289 + return -EFAULT;
131290 +
131291 + converted.ptr = compat_ptr(input.ptr);
131292 + converted.phys_addr = input.phys_addr;
131293 + converted.len = input.len;
131294 + converted.flags = input.flags;
131295 + strncpy(converted.name, input.name, USDPAA_DMA_NAME_MAX);
131296 + converted.has_locking = input.has_locking;
131297 + converted.did_create = input.did_create;
131298 +
131299 + ret = ioctl_dma_map(fp, ctx, &converted);
131300 + input.ptr = ptr_to_compat(converted.ptr);
131301 + input.phys_addr = converted.phys_addr;
131302 + input.len = converted.len;
131303 + input.flags = converted.flags;
131304 + strncpy(input.name, converted.name, USDPAA_DMA_NAME_MAX);
131305 + input.has_locking = converted.has_locking;
131306 + input.did_create = converted.did_create;
131307 + if (copy_to_user(a, &input, sizeof(input)))
131308 + return -EFAULT;
131309 + return ret;
131310 + }
131311 + case USDPAA_IOCTL_PORTAL_MAP_COMPAT:
131312 + {
131313 + int ret;
131314 + struct compat_usdpaa_ioctl_portal_map input;
131315 + struct usdpaa_ioctl_portal_map converted;
131316 + if (copy_from_user(&input, a, sizeof(input)))
131317 + return -EFAULT;
131318 + converted.type = input.type;
131319 + converted.index = input.index;
131320 + ret = ioctl_portal_map(fp, ctx, &converted);
131321 + input.addr.cinh = ptr_to_compat(converted.addr.cinh);
131322 + input.addr.cena = ptr_to_compat(converted.addr.cena);
131323 + input.channel = converted.channel;
131324 + input.pools = converted.pools;
131325 + input.index = converted.index;
131326 + if (copy_to_user(a, &input, sizeof(input)))
131327 + return -EFAULT;
131328 + return ret;
131329 + }
131330 + case USDPAA_IOCTL_PORTAL_UNMAP_COMPAT:
131331 + {
131332 + struct usdpaa_portal_map_compat input;
131333 + struct usdpaa_portal_map converted;
131334 +
131335 + if (copy_from_user(&input, a, sizeof(input)))
131336 + return -EFAULT;
131337 + converted.cinh = compat_ptr(input.cinh);
131338 + converted.cena = compat_ptr(input.cena);
131339 + return ioctl_portal_unmap(ctx, &converted);
131340 + }
131341 + case USDPAA_IOCTL_ALLOC_RAW_PORTAL_COMPAT:
131342 + {
131343 + int ret;
131344 + struct usdpaa_ioctl_raw_portal converted;
131345 + struct compat_ioctl_raw_portal input;
131346 + if (copy_from_user(&input, a, sizeof(input)))
131347 + return -EFAULT;
131348 + converted.type = input.type;
131349 + converted.index = input.index;
131350 + converted.enable_stash = input.enable_stash;
131351 + converted.cpu = input.cpu;
131352 + converted.cache = input.cache;
131353 + converted.window = input.window;
131354 + converted.sdest = input.sdest;
131355 + ret = ioctl_allocate_raw_portal(fp, ctx, &converted);
131356 +
131357 + input.cinh = converted.cinh;
131358 + input.cena = converted.cena;
131359 + input.index = converted.index;
131360 +
131361 + if (copy_to_user(a, &input, sizeof(input)))
131362 + return -EFAULT;
131363 + return ret;
131364 + }
131365 + case USDPAA_IOCTL_FREE_RAW_PORTAL_COMPAT:
131366 + {
131367 + struct usdpaa_ioctl_raw_portal converted;
131368 + struct compat_ioctl_raw_portal input;
131369 + if (copy_from_user(&input, a, sizeof(input)))
131370 + return -EFAULT;
131371 + converted.type = input.type;
131372 + converted.index = input.index;
131373 + converted.cinh = input.cinh;
131374 + converted.cena = input.cena;
131375 + return ioctl_free_raw_portal(fp, ctx, &converted);
131376 + }
131377 +#endif
131378 + default:
131379 + return usdpaa_ioctl(fp, cmd, arg);
131380 + }
131381 + return -EINVAL;
131382 +}
131383 +
131384 +int usdpaa_get_portal_config(struct file *filp, void *cinh,
131385 + enum usdpaa_portal_type ptype, unsigned int *irq,
131386 + void **iir_reg)
131387 +{
131388 + /* Walk the list of portals for filp and return the config
131389 + for the portal that matches the hint */
131390 + struct ctx *context;
131391 + struct portal_mapping *portal;
131392 +
131393 + /* First sanitize the filp */
131394 + if (filp->f_op->open != usdpaa_open)
131395 + return -ENODEV;
131396 + context = filp->private_data;
131397 + spin_lock(&context->lock);
131398 + list_for_each_entry(portal, &context->portals, list) {
131399 + if (portal->user.type == ptype &&
131400 + portal->user.addr.cinh == cinh) {
131401 + if (ptype == usdpaa_portal_qman) {
131402 + *irq = portal->qportal->public_cfg.irq;
131403 + *iir_reg = portal->qportal->addr_virt[1] +
131404 + QM_REG_IIR;
131405 + } else {
131406 + *irq = portal->bportal->public_cfg.irq;
131407 + *iir_reg = portal->bportal->addr_virt[1] +
131408 + BM_REG_IIR;
131409 + }
131410 + spin_unlock(&context->lock);
131411 + return 0;
131412 + }
131413 + }
131414 + spin_unlock(&context->lock);
131415 + return -EINVAL;
131416 +}
131417 +
131418 +static const struct file_operations usdpaa_fops = {
131419 + .open = usdpaa_open,
131420 + .release = usdpaa_release,
131421 + .mmap = usdpaa_mmap,
131422 + .get_unmapped_area = usdpaa_get_unmapped_area,
131423 + .unlocked_ioctl = usdpaa_ioctl,
131424 + .compat_ioctl = usdpaa_ioctl_compat
131425 +};
131426 +
131427 +static struct miscdevice usdpaa_miscdev = {
131428 + .name = "fsl-usdpaa",
131429 + .fops = &usdpaa_fops,
131430 + .minor = MISC_DYNAMIC_MINOR,
131431 +};
131432 +
131433 +/* Early-boot memory allocation. The boot-arg "usdpaa_mem=<x>" is used to
131434 + * indicate how much memory (if any) to allocate during early boot. If the
131435 + * format "usdpaa_mem=<x>,<y>" is used, then <y> will be interpreted as the
131436 + * number of TLB1 entries to reserve (default is 1). If there are more mappings
131437 + * than there are TLB1 entries, fault-handling will occur. */
131438 +
131439 +static __init int usdpaa_mem(char *arg)
131440 +{
131441 + pr_warn("uspdaa_mem argument is depracated\n");
131442 + arg_phys_size = memparse(arg, &arg);
131443 + num_tlb = 1;
131444 + if (*arg == ',') {
131445 + unsigned long ul;
131446 + int err = kstrtoul(arg + 1, 0, &ul);
131447 + if (err < 0) {
131448 + num_tlb = 1;
131449 + pr_warn("ERROR, usdpaa_mem arg is invalid\n");
131450 + } else
131451 + num_tlb = (unsigned int)ul;
131452 + }
131453 + return 0;
131454 +}
131455 +early_param("usdpaa_mem", usdpaa_mem);
131456 +
131457 +static int usdpaa_mem_init(struct reserved_mem *rmem)
131458 +{
131459 + phys_start = rmem->base;
131460 + phys_size = rmem->size;
131461 +
131462 + WARN_ON(!(phys_start && phys_size));
131463 +
131464 + return 0;
131465 +}
131466 +RESERVEDMEM_OF_DECLARE(usdpaa_mem_init, "fsl,usdpaa-mem", usdpaa_mem_init);
131467 +
131468 +__init int fsl_usdpaa_init_early(void)
131469 +{
131470 + if (!phys_size || !phys_start) {
131471 + pr_info("No USDPAA memory, no 'fsl,usdpaa-mem' in device-tree\n");
131472 + return 0;
131473 + }
131474 + if (phys_size % PAGE_SIZE) {
131475 + pr_err("'fsl,usdpaa-mem' size must be a multiple of page size\n");
131476 + phys_size = 0;
131477 + return 0;
131478 + }
131479 + if (arg_phys_size && phys_size != arg_phys_size) {
131480 + pr_err("'usdpaa_mem argument size (0x%llx) does not match device tree size (0x%llx)\n",
131481 + arg_phys_size, phys_size);
131482 + phys_size = 0;
131483 + return 0;
131484 + }
131485 + pfn_start = phys_start >> PAGE_SHIFT;
131486 + pfn_size = phys_size >> PAGE_SHIFT;
131487 +#ifdef CONFIG_PPC
131488 + first_tlb = current_tlb = tlbcam_index;
131489 + tlbcam_index += num_tlb;
131490 +#endif
131491 + pr_info("USDPAA region at %llx:%llx(%lx:%lx), %d TLB1 entries)\n",
131492 + phys_start, phys_size, pfn_start, pfn_size, num_tlb);
131493 + return 0;
131494 +}
131495 +subsys_initcall(fsl_usdpaa_init_early);
131496 +
131497 +
131498 +static int __init usdpaa_init(void)
131499 +{
131500 + struct mem_fragment *frag;
131501 + int ret;
131502 + u64 tmp_size = phys_size;
131503 + u64 tmp_start = phys_start;
131504 + u64 tmp_pfn_size = pfn_size;
131505 + u64 tmp_pfn_start = pfn_start;
131506 +
131507 + pr_info("Freescale USDPAA process driver\n");
131508 + if (!phys_start) {
131509 + pr_warn("fsl-usdpaa: no region found\n");
131510 + return 0;
131511 + }
131512 +
131513 + while (tmp_size != 0) {
131514 + u32 frag_size = largest_page_size(tmp_size);
131515 + frag = kmalloc(sizeof(*frag), GFP_KERNEL);
131516 + if (!frag) {
131517 + pr_err("Failed to setup USDPAA memory accounting\n");
131518 + return -ENOMEM;
131519 + }
131520 + frag->base = tmp_start;
131521 + frag->len = frag->root_len = frag_size;
131522 + frag->root_pfn = tmp_pfn_start;
131523 + frag->pfn_base = tmp_pfn_start;
131524 + frag->pfn_len = frag_size / PAGE_SIZE;
131525 + frag->refs = 0;
131526 + init_waitqueue_head(&frag->wq);
131527 + frag->owner = NULL;
131528 + list_add(&frag->list, &mem_list);
131529 +
131530 + /* Adjust for this frag */
131531 + tmp_start += frag_size;
131532 + tmp_size -= frag_size;
131533 + tmp_pfn_start += frag_size / PAGE_SIZE;
131534 + tmp_pfn_size -= frag_size / PAGE_SIZE;
131535 + }
131536 + ret = misc_register(&usdpaa_miscdev);
131537 + if (ret)
131538 + pr_err("fsl-usdpaa: failed to register misc device\n");
131539 + return ret;
131540 +}
131541 +
131542 +static void __exit usdpaa_exit(void)
131543 +{
131544 + misc_deregister(&usdpaa_miscdev);
131545 +}
131546 +
131547 +module_init(usdpaa_init);
131548 +module_exit(usdpaa_exit);
131549 +
131550 +MODULE_LICENSE("GPL");
131551 +MODULE_AUTHOR("Freescale Semiconductor");
131552 +MODULE_DESCRIPTION("Freescale USDPAA process driver");
131553 --- /dev/null
131554 +++ b/drivers/staging/fsl_qbman/fsl_usdpaa_irq.c
131555 @@ -0,0 +1,289 @@
131556 +/* Copyright (c) 2013 Freescale Semiconductor, Inc.
131557 + * All rights reserved.
131558 + *
131559 + * Redistribution and use in source and binary forms, with or without
131560 + * modification, are permitted provided that the following conditions are met:
131561 + * * Redistributions of source code must retain the above copyright
131562 + * notice, this list of conditions and the following disclaimer.
131563 + * * Redistributions in binary form must reproduce the above copyright
131564 + * notice, this list of conditions and the following disclaimer in the
131565 + * documentation and/or other materials provided with the distribution.
131566 + * * Neither the name of Freescale Semiconductor nor the
131567 + * names of its contributors may be used to endorse or promote products
131568 + * derived from this software without specific prior written permission.
131569 + *
131570 + *
131571 + * ALTERNATIVELY, this software may be distributed under the terms of the
131572 + * GNU General Public License ("GPL") as published by the Free Software
131573 + * Foundation, either version 2 of that License or (at your option) any
131574 + * later version.
131575 + *
131576 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
131577 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
131578 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
131579 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
131580 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
131581 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
131582 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
131583 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
131584 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
131585 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
131586 + */
131587 +
131588 +/* define a device that allows USPDAA processes to open a file
131589 + descriptor and specify which IRQ it wants to montior using an ioctl()
131590 + When an IRQ is received, the device becomes readable so that a process
131591 + can use read() or select() type calls to monitor for IRQs */
131592 +
131593 +#include <linux/miscdevice.h>
131594 +#include <linux/fs.h>
131595 +#include <linux/cdev.h>
131596 +#include <linux/slab.h>
131597 +#include <linux/interrupt.h>
131598 +#include <linux/poll.h>
131599 +#include <linux/uaccess.h>
131600 +#include <linux/fsl_usdpaa.h>
131601 +#include <linux/module.h>
131602 +#include <linux/fdtable.h>
131603 +#include <linux/file.h>
131604 +
131605 +#include "qman_low.h"
131606 +#include "bman_low.h"
131607 +
131608 +struct usdpaa_irq_ctx {
131609 + int irq_set; /* Set to true once the irq is set via ioctl */
131610 + unsigned int irq_num;
131611 + u32 last_irq_count; /* Last value returned from read */
131612 + u32 irq_count; /* Number of irqs since last read */
131613 + wait_queue_head_t wait_queue; /* Waiting processes */
131614 + spinlock_t lock;
131615 + void *inhibit_addr; /* inhibit register address */
131616 + struct file *usdpaa_filp;
131617 + char irq_name[128];
131618 +};
131619 +
131620 +static int usdpaa_irq_open(struct inode *inode, struct file *filp)
131621 +{
131622 + struct usdpaa_irq_ctx *ctx = kmalloc(sizeof(*ctx), GFP_KERNEL);
131623 + if (!ctx)
131624 + return -ENOMEM;
131625 + ctx->irq_set = 0;
131626 + ctx->irq_count = 0;
131627 + ctx->last_irq_count = 0;
131628 + init_waitqueue_head(&ctx->wait_queue);
131629 + spin_lock_init(&ctx->lock);
131630 + filp->private_data = ctx;
131631 + return 0;
131632 +}
131633 +
131634 +static int usdpaa_irq_release(struct inode *inode, struct file *filp)
131635 +{
131636 + struct usdpaa_irq_ctx *ctx = filp->private_data;
131637 + if (ctx->irq_set) {
131638 + /* Inhibit the IRQ */
131639 + out_be32(ctx->inhibit_addr, 0x1);
131640 + irq_set_affinity_hint(ctx->irq_num, NULL);
131641 + free_irq(ctx->irq_num, ctx);
131642 + ctx->irq_set = 0;
131643 + fput(ctx->usdpaa_filp);
131644 + }
131645 + kfree(filp->private_data);
131646 + return 0;
131647 +}
131648 +
131649 +static irqreturn_t usdpaa_irq_handler(int irq, void *_ctx)
131650 +{
131651 + unsigned long flags;
131652 + struct usdpaa_irq_ctx *ctx = _ctx;
131653 + spin_lock_irqsave(&ctx->lock, flags);
131654 + ++ctx->irq_count;
131655 + spin_unlock_irqrestore(&ctx->lock, flags);
131656 + wake_up_all(&ctx->wait_queue);
131657 + /* Set the inhibit register. This will be reenabled
131658 + once the USDPAA code handles the IRQ */
131659 + out_be32(ctx->inhibit_addr, 0x1);
131660 + pr_info("Inhibit at %p count %d", ctx->inhibit_addr, ctx->irq_count);
131661 + return IRQ_HANDLED;
131662 +}
131663 +
131664 +static int map_irq(struct file *fp, struct usdpaa_ioctl_irq_map *irq_map)
131665 +{
131666 + struct usdpaa_irq_ctx *ctx = fp->private_data;
131667 + int ret;
131668 +
131669 + if (ctx->irq_set) {
131670 + pr_debug("Setting USDPAA IRQ when it was already set!\n");
131671 + return -EBUSY;
131672 + }
131673 +
131674 + ctx->usdpaa_filp = fget(irq_map->fd);
131675 + if (!ctx->usdpaa_filp) {
131676 + pr_debug("USDPAA fget(%d) returned NULL\n", irq_map->fd);
131677 + return -EINVAL;
131678 + }
131679 +
131680 + ret = usdpaa_get_portal_config(ctx->usdpaa_filp, irq_map->portal_cinh,
131681 + irq_map->type, &ctx->irq_num,
131682 + &ctx->inhibit_addr);
131683 + if (ret) {
131684 + pr_debug("USDPAA IRQ couldn't identify portal\n");
131685 + fput(ctx->usdpaa_filp);
131686 + return ret;
131687 + }
131688 +
131689 + ctx->irq_set = 1;
131690 +
131691 + snprintf(ctx->irq_name, sizeof(ctx->irq_name),
131692 + "usdpaa_irq %d", ctx->irq_num);
131693 +
131694 + ret = request_irq(ctx->irq_num, usdpaa_irq_handler, 0,
131695 + ctx->irq_name, ctx);
131696 + if (ret) {
131697 + pr_err("USDPAA request_irq(%d) failed, ret= %d\n",
131698 + ctx->irq_num, ret);
131699 + ctx->irq_set = 0;
131700 + fput(ctx->usdpaa_filp);
131701 + return ret;
131702 + }
131703 + ret = irq_set_affinity(ctx->irq_num, &current->cpus_allowed);
131704 + if (ret)
131705 + pr_err("USDPAA irq_set_affinity() failed, ret= %d\n", ret);
131706 +
131707 + ret = irq_set_affinity_hint(ctx->irq_num, &current->cpus_allowed);
131708 + if (ret)
131709 + pr_err("USDPAA irq_set_affinity_hint() failed, ret= %d\n", ret);
131710 +
131711 + return 0;
131712 +}
131713 +
131714 +static long usdpaa_irq_ioctl(struct file *fp, unsigned int cmd,
131715 + unsigned long arg)
131716 +{
131717 + int ret;
131718 + struct usdpaa_ioctl_irq_map irq_map;
131719 +
131720 + if (cmd != USDPAA_IOCTL_PORTAL_IRQ_MAP) {
131721 + pr_debug("USDPAA IRQ unknown command 0x%x\n", cmd);
131722 + return -EINVAL;
131723 + }
131724 +
131725 + ret = copy_from_user(&irq_map, (void __user *)arg,
131726 + sizeof(irq_map));
131727 + if (ret)
131728 + return ret;
131729 + return map_irq(fp, &irq_map);
131730 +}
131731 +
131732 +static ssize_t usdpaa_irq_read(struct file *filp, char __user *buff,
131733 + size_t count, loff_t *offp)
131734 +{
131735 + struct usdpaa_irq_ctx *ctx = filp->private_data;
131736 + int ret;
131737 +
131738 + if (!ctx->irq_set) {
131739 + pr_debug("Reading USDPAA IRQ before it was set\n");
131740 + return -EINVAL;
131741 + }
131742 +
131743 + if (count < sizeof(ctx->irq_count)) {
131744 + pr_debug("USDPAA IRQ Read too small\n");
131745 + return -EINVAL;
131746 + }
131747 + if (ctx->irq_count == ctx->last_irq_count) {
131748 + if (filp->f_flags & O_NONBLOCK)
131749 + return -EAGAIN;
131750 +
131751 + ret = wait_event_interruptible(ctx->wait_queue,
131752 + ctx->irq_count != ctx->last_irq_count);
131753 + if (ret == -ERESTARTSYS)
131754 + return ret;
131755 + }
131756 +
131757 + ctx->last_irq_count = ctx->irq_count;
131758 +
131759 + if (copy_to_user(buff, &ctx->last_irq_count,
131760 + sizeof(ctx->last_irq_count)))
131761 + return -EFAULT;
131762 + return sizeof(ctx->irq_count);
131763 +}
131764 +
131765 +static unsigned int usdpaa_irq_poll(struct file *filp, poll_table *wait)
131766 +{
131767 + struct usdpaa_irq_ctx *ctx = filp->private_data;
131768 + unsigned int ret = 0;
131769 + unsigned long flags;
131770 +
131771 + if (!ctx->irq_set)
131772 + return POLLHUP;
131773 +
131774 + poll_wait(filp, &ctx->wait_queue, wait);
131775 +
131776 + spin_lock_irqsave(&ctx->lock, flags);
131777 + if (ctx->irq_count != ctx->last_irq_count)
131778 + ret |= POLLIN | POLLRDNORM;
131779 + spin_unlock_irqrestore(&ctx->lock, flags);
131780 + return ret;
131781 +}
131782 +
131783 +static long usdpaa_irq_ioctl_compat(struct file *fp, unsigned int cmd,
131784 + unsigned long arg)
131785 +{
131786 +#ifdef CONFIG_COMPAT
131787 + void __user *a = (void __user *)arg;
131788 +#endif
131789 + switch (cmd) {
131790 +#ifdef CONFIG_COMPAT
131791 + case USDPAA_IOCTL_PORTAL_IRQ_MAP_COMPAT:
131792 + {
131793 + struct compat_ioctl_irq_map input;
131794 + struct usdpaa_ioctl_irq_map converted;
131795 + if (copy_from_user(&input, a, sizeof(input)))
131796 + return -EFAULT;
131797 + converted.type = input.type;
131798 + converted.fd = input.fd;
131799 + converted.portal_cinh = compat_ptr(input.portal_cinh);
131800 + return map_irq(fp, &converted);
131801 + }
131802 +#endif
131803 + default:
131804 + return usdpaa_irq_ioctl(fp, cmd, arg);
131805 + }
131806 +}
131807 +
131808 +static const struct file_operations usdpaa_irq_fops = {
131809 + .open = usdpaa_irq_open,
131810 + .release = usdpaa_irq_release,
131811 + .unlocked_ioctl = usdpaa_irq_ioctl,
131812 + .compat_ioctl = usdpaa_irq_ioctl_compat,
131813 + .read = usdpaa_irq_read,
131814 + .poll = usdpaa_irq_poll
131815 +};
131816 +
131817 +static struct miscdevice usdpaa_miscdev = {
131818 + .name = "fsl-usdpaa-irq",
131819 + .fops = &usdpaa_irq_fops,
131820 + .minor = MISC_DYNAMIC_MINOR,
131821 +};
131822 +
131823 +static int __init usdpaa_irq_init(void)
131824 +{
131825 + int ret;
131826 +
131827 + pr_info("Freescale USDPAA process IRQ driver\n");
131828 + ret = misc_register(&usdpaa_miscdev);
131829 + if (ret)
131830 + pr_err("fsl-usdpaa-irq: failed to register misc device\n");
131831 + return ret;
131832 +}
131833 +
131834 +static void __exit usdpaa_irq_exit(void)
131835 +{
131836 + misc_deregister(&usdpaa_miscdev);
131837 +}
131838 +
131839 +module_init(usdpaa_irq_init);
131840 +module_exit(usdpaa_irq_exit);
131841 +
131842 +MODULE_LICENSE("GPL");
131843 +MODULE_AUTHOR("Freescale Semiconductor");
131844 +MODULE_DESCRIPTION("Freescale USDPAA process IRQ driver");
131845 --- /dev/null
131846 +++ b/drivers/staging/fsl_qbman/qbman_driver.c
131847 @@ -0,0 +1,88 @@
131848 +/* Copyright 2013 Freescale Semiconductor, Inc.
131849 + *
131850 + * Redistribution and use in source and binary forms, with or without
131851 + * modification, are permitted provided that the following conditions are met:
131852 + * * Redistributions of source code must retain the above copyright
131853 + * notice, this list of conditions and the following disclaimer.
131854 + * * Redistributions in binary form must reproduce the above copyright
131855 + * notice, this list of conditions and the following disclaimer in the
131856 + * documentation and/or other materials provided with the distribution.
131857 + * * Neither the name of Freescale Semiconductor nor the
131858 + * names of its contributors may be used to endorse or promote products
131859 + * derived from this software without specific prior written permission.
131860 + *
131861 + *
131862 + * ALTERNATIVELY, this software may be distributed under the terms of the
131863 + * GNU General Public License ("GPL") as published by the Free Software
131864 + * Foundation, either version 2 of that License or (at your option) any
131865 + * later version.
131866 + *
131867 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
131868 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
131869 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
131870 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
131871 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
131872 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
131873 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
131874 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
131875 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
131876 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
131877 + */
131878 +
131879 +#include <linux/time.h>
131880 +#include "qman_private.h"
131881 +#include "bman_private.h"
131882 +__init void qman_init_early(void);
131883 +__init void bman_init_early(void);
131884 +
131885 +static __init int qbman_init(void)
131886 +{
131887 + struct device_node *dn;
131888 + u32 is_portal_available;
131889 +
131890 + bman_init();
131891 + qman_init();
131892 +
131893 + is_portal_available = 0;
131894 + for_each_compatible_node(dn, NULL, "fsl,qman-portal") {
131895 + if (!of_device_is_available(dn))
131896 + continue;
131897 + else
131898 + is_portal_available = 1;
131899 + }
131900 +
131901 + if (!qman_have_ccsr() && is_portal_available) {
131902 + struct qman_fq fq = {
131903 + .fqid = 1
131904 + };
131905 + struct qm_mcr_queryfq_np np;
131906 + int err, retry = CONFIG_FSL_QMAN_INIT_TIMEOUT;
131907 + struct timespec nowts, diffts, startts = current_kernel_time();
131908 + /* Loop while querying given fqid succeeds or time out */
131909 + while (1) {
131910 + err = qman_query_fq_np(&fq, &np);
131911 + if (!err) {
131912 + /* success, control-plane has configured QMan */
131913 + break;
131914 + } else if (err != -ERANGE) {
131915 + pr_err("QMan: I/O error, continuing anyway\n");
131916 + break;
131917 + }
131918 + nowts = current_kernel_time();
131919 + diffts = timespec_sub(nowts, startts);
131920 + if (diffts.tv_sec > 0) {
131921 + if (!retry--) {
131922 + pr_err("QMan: time out, control-plane"
131923 + " dead?\n");
131924 + break;
131925 + }
131926 + pr_warn("QMan: polling for the control-plane"
131927 + " (%d)\n", retry);
131928 + }
131929 + }
131930 + }
131931 + bman_resource_init();
131932 + qman_resource_init();
131933 + return 0;
131934 +}
131935 +subsys_initcall(qbman_init);
131936 --- /dev/null
131937 +++ b/drivers/staging/fsl_qbman/qman_config.c
131938 @@ -0,0 +1,1224 @@
131939 +/* Copyright 2008-2012 Freescale Semiconductor, Inc.
131940 + *
131941 + * Redistribution and use in source and binary forms, with or without
131942 + * modification, are permitted provided that the following conditions are met:
131943 + * * Redistributions of source code must retain the above copyright
131944 + * notice, this list of conditions and the following disclaimer.
131945 + * * Redistributions in binary form must reproduce the above copyright
131946 + * notice, this list of conditions and the following disclaimer in the
131947 + * documentation and/or other materials provided with the distribution.
131948 + * * Neither the name of Freescale Semiconductor nor the
131949 + * names of its contributors may be used to endorse or promote products
131950 + * derived from this software without specific prior written permission.
131951 + *
131952 + *
131953 + * ALTERNATIVELY, this software may be distributed under the terms of the
131954 + * GNU General Public License ("GPL") as published by the Free Software
131955 + * Foundation, either version 2 of that License or (at your option) any
131956 + * later version.
131957 + *
131958 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
131959 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
131960 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
131961 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
131962 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
131963 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
131964 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
131965 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
131966 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
131967 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
131968 + */
131969 +
131970 +#include <asm/cacheflush.h>
131971 +#include "qman_private.h"
131972 +#include <linux/highmem.h>
131973 +#include <linux/of_reserved_mem.h>
131974 +
131975 +/* Last updated for v00.800 of the BG */
131976 +
131977 +/* Register offsets */
131978 +#define REG_QCSP_LIO_CFG(n) (0x0000 + ((n) * 0x10))
131979 +#define REG_QCSP_IO_CFG(n) (0x0004 + ((n) * 0x10))
131980 +#define REG_QCSP_DD_CFG(n) (0x000c + ((n) * 0x10))
131981 +#define REG_DD_CFG 0x0200
131982 +#define REG_DCP_CFG(n) (0x0300 + ((n) * 0x10))
131983 +#define REG_DCP_DD_CFG(n) (0x0304 + ((n) * 0x10))
131984 +#define REG_DCP_DLM_AVG(n) (0x030c + ((n) * 0x10))
131985 +#define REG_PFDR_FPC 0x0400
131986 +#define REG_PFDR_FP_HEAD 0x0404
131987 +#define REG_PFDR_FP_TAIL 0x0408
131988 +#define REG_PFDR_FP_LWIT 0x0410
131989 +#define REG_PFDR_CFG 0x0414
131990 +#define REG_SFDR_CFG 0x0500
131991 +#define REG_SFDR_IN_USE 0x0504
131992 +#define REG_WQ_CS_CFG(n) (0x0600 + ((n) * 0x04))
131993 +#define REG_WQ_DEF_ENC_WQID 0x0630
131994 +#define REG_WQ_SC_DD_CFG(n) (0x640 + ((n) * 0x04))
131995 +#define REG_WQ_PC_DD_CFG(n) (0x680 + ((n) * 0x04))
131996 +#define REG_WQ_DC0_DD_CFG(n) (0x6c0 + ((n) * 0x04))
131997 +#define REG_WQ_DC1_DD_CFG(n) (0x700 + ((n) * 0x04))
131998 +#define REG_WQ_DCn_DD_CFG(n) (0x6c0 + ((n) * 0x40)) /* n=2,3 */
131999 +#define REG_CM_CFG 0x0800
132000 +#define REG_ECSR 0x0a00
132001 +#define REG_ECIR 0x0a04
132002 +#define REG_EADR 0x0a08
132003 +#define REG_ECIR2 0x0a0c
132004 +#define REG_EDATA(n) (0x0a10 + ((n) * 0x04))
132005 +#define REG_SBEC(n) (0x0a80 + ((n) * 0x04))
132006 +#define REG_MCR 0x0b00
132007 +#define REG_MCP(n) (0x0b04 + ((n) * 0x04))
132008 +#define REG_MISC_CFG 0x0be0
132009 +#define REG_HID_CFG 0x0bf0
132010 +#define REG_IDLE_STAT 0x0bf4
132011 +#define REG_IP_REV_1 0x0bf8
132012 +#define REG_IP_REV_2 0x0bfc
132013 +#define REG_FQD_BARE 0x0c00
132014 +#define REG_PFDR_BARE 0x0c20
132015 +#define REG_offset_BAR 0x0004 /* relative to REG_[FQD|PFDR]_BARE */
132016 +#define REG_offset_AR 0x0010 /* relative to REG_[FQD|PFDR]_BARE */
132017 +#define REG_QCSP_BARE 0x0c80
132018 +#define REG_QCSP_BAR 0x0c84
132019 +#define REG_CI_SCHED_CFG 0x0d00
132020 +#define REG_SRCIDR 0x0d04
132021 +#define REG_LIODNR 0x0d08
132022 +#define REG_CI_RLM_AVG 0x0d14
132023 +#define REG_ERR_ISR 0x0e00 /* + "enum qm_isr_reg" */
132024 +#define REG_REV3_QCSP_LIO_CFG(n) (0x1000 + ((n) * 0x10))
132025 +#define REG_REV3_QCSP_IO_CFG(n) (0x1004 + ((n) * 0x10))
132026 +#define REG_REV3_QCSP_DD_CFG(n) (0x100c + ((n) * 0x10))
132027 +#define REG_CEETM_CFG_IDX 0x900
132028 +#define REG_CEETM_CFG_PRES 0x904
132029 +#define REG_CEETM_XSFDR_IN_USE 0x908
132030 +
132031 +/* Assists for QMAN_MCR */
132032 +#define MCR_INIT_PFDR 0x01000000
132033 +#define MCR_get_rslt(v) (u8)((v) >> 24)
132034 +#define MCR_rslt_idle(r) (!rslt || (rslt >= 0xf0))
132035 +#define MCR_rslt_ok(r) (rslt == 0xf0)
132036 +#define MCR_rslt_eaccess(r) (rslt == 0xf8)
132037 +#define MCR_rslt_inval(r) (rslt == 0xff)
132038 +
132039 +struct qman;
132040 +
132041 +/* Follows WQ_CS_CFG0-5 */
132042 +enum qm_wq_class {
132043 + qm_wq_portal = 0,
132044 + qm_wq_pool = 1,
132045 + qm_wq_fman0 = 2,
132046 + qm_wq_fman1 = 3,
132047 + qm_wq_caam = 4,
132048 + qm_wq_pme = 5,
132049 + qm_wq_first = qm_wq_portal,
132050 + qm_wq_last = qm_wq_pme
132051 +};
132052 +
132053 +/* Follows FQD_[BARE|BAR|AR] and PFDR_[BARE|BAR|AR] */
132054 +enum qm_memory {
132055 + qm_memory_fqd,
132056 + qm_memory_pfdr
132057 +};
132058 +
132059 +/* Used by all error interrupt registers except 'inhibit' */
132060 +#define QM_EIRQ_CIDE 0x20000000 /* Corenet Initiator Data Error */
132061 +#define QM_EIRQ_CTDE 0x10000000 /* Corenet Target Data Error */
132062 +#define QM_EIRQ_CITT 0x08000000 /* Corenet Invalid Target Transaction */
132063 +#define QM_EIRQ_PLWI 0x04000000 /* PFDR Low Watermark */
132064 +#define QM_EIRQ_MBEI 0x02000000 /* Multi-bit ECC Error */
132065 +#define QM_EIRQ_SBEI 0x01000000 /* Single-bit ECC Error */
132066 +#define QM_EIRQ_PEBI 0x00800000 /* PFDR Enqueues Blocked Interrupt */
132067 +#define QM_EIRQ_IFSI 0x00020000 /* Invalid FQ Flow Control State */
132068 +#define QM_EIRQ_ICVI 0x00010000 /* Invalid Command Verb */
132069 +#define QM_EIRQ_IDDI 0x00000800 /* Invalid Dequeue (Direct-connect) */
132070 +#define QM_EIRQ_IDFI 0x00000400 /* Invalid Dequeue FQ */
132071 +#define QM_EIRQ_IDSI 0x00000200 /* Invalid Dequeue Source */
132072 +#define QM_EIRQ_IDQI 0x00000100 /* Invalid Dequeue Queue */
132073 +#define QM_EIRQ_IECE 0x00000010 /* Invalid Enqueue Configuration */
132074 +#define QM_EIRQ_IEOI 0x00000008 /* Invalid Enqueue Overflow */
132075 +#define QM_EIRQ_IESI 0x00000004 /* Invalid Enqueue State */
132076 +#define QM_EIRQ_IECI 0x00000002 /* Invalid Enqueue Channel */
132077 +#define QM_EIRQ_IEQI 0x00000001 /* Invalid Enqueue Queue */
132078 +
132079 +/* QMAN_ECIR valid error bit */
132080 +#define PORTAL_ECSR_ERR (QM_EIRQ_IEQI | QM_EIRQ_IESI | QM_EIRQ_IEOI | \
132081 + QM_EIRQ_IDQI | QM_EIRQ_IDSI | QM_EIRQ_IDFI | \
132082 + QM_EIRQ_IDDI | QM_EIRQ_ICVI | QM_EIRQ_IFSI)
132083 +#define FQID_ECSR_ERR (QM_EIRQ_IEQI | QM_EIRQ_IECI | QM_EIRQ_IESI | \
132084 + QM_EIRQ_IEOI | QM_EIRQ_IDQI | QM_EIRQ_IDFI | \
132085 + QM_EIRQ_IFSI)
132086 +
132087 +union qman_ecir {
132088 + u32 ecir_raw;
132089 + struct {
132090 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
132091 + u32 __reserved:2;
132092 + u32 portal_type:1;
132093 + u32 portal_num:5;
132094 + u32 fqid:24;
132095 +#else
132096 + u32 fqid:24;
132097 + u32 portal_num:5;
132098 + u32 portal_type:1;
132099 + u32 __reserved:2;
132100 +#endif
132101 + } __packed info;
132102 +};
132103 +
132104 +union qman_ecir2 {
132105 + u32 ecir2_raw;
132106 + struct {
132107 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
132108 + u32 portal_type:1;
132109 + u32 __reserved:21;
132110 + u32 portal_num:10;
132111 +#else
132112 + u32 portal_num:10;
132113 + u32 __reserved:21;
132114 + u32 portal_type:1;
132115 +#endif
132116 + } __packed info;
132117 +};
132118 +
132119 +union qman_eadr {
132120 + u32 eadr_raw;
132121 + struct {
132122 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
132123 + u32 __reserved1:4;
132124 + u32 memid:4;
132125 + u32 __reserved2:12;
132126 + u32 eadr:12;
132127 +#else
132128 + u32 eadr:12;
132129 + u32 __reserved2:12;
132130 + u32 memid:4;
132131 + u32 __reserved1:4;
132132 +#endif
132133 + } __packed info;
132134 + struct {
132135 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
132136 + u32 __reserved1:3;
132137 + u32 memid:5;
132138 + u32 __reserved:8;
132139 + u32 eadr:16;
132140 +#else
132141 + u32 eadr:16;
132142 + u32 __reserved:8;
132143 + u32 memid:5;
132144 + u32 __reserved1:3;
132145 +#endif
132146 + } __packed info_rev3;
132147 +};
132148 +
132149 +struct qman_hwerr_txt {
132150 + u32 mask;
132151 + const char *txt;
132152 +};
132153 +
132154 +#define QMAN_HWE_TXT(a, b) { .mask = QM_EIRQ_##a, .txt = b }
132155 +
132156 +static const struct qman_hwerr_txt qman_hwerr_txts[] = {
132157 + QMAN_HWE_TXT(CIDE, "Corenet Initiator Data Error"),
132158 + QMAN_HWE_TXT(CTDE, "Corenet Target Data Error"),
132159 + QMAN_HWE_TXT(CITT, "Corenet Invalid Target Transaction"),
132160 + QMAN_HWE_TXT(PLWI, "PFDR Low Watermark"),
132161 + QMAN_HWE_TXT(MBEI, "Multi-bit ECC Error"),
132162 + QMAN_HWE_TXT(SBEI, "Single-bit ECC Error"),
132163 + QMAN_HWE_TXT(PEBI, "PFDR Enqueues Blocked Interrupt"),
132164 + QMAN_HWE_TXT(ICVI, "Invalid Command Verb"),
132165 + QMAN_HWE_TXT(IFSI, "Invalid Flow Control State"),
132166 + QMAN_HWE_TXT(IDDI, "Invalid Dequeue (Direct-connect)"),
132167 + QMAN_HWE_TXT(IDFI, "Invalid Dequeue FQ"),
132168 + QMAN_HWE_TXT(IDSI, "Invalid Dequeue Source"),
132169 + QMAN_HWE_TXT(IDQI, "Invalid Dequeue Queue"),
132170 + QMAN_HWE_TXT(IECE, "Invalid Enqueue Configuration"),
132171 + QMAN_HWE_TXT(IEOI, "Invalid Enqueue Overflow"),
132172 + QMAN_HWE_TXT(IESI, "Invalid Enqueue State"),
132173 + QMAN_HWE_TXT(IECI, "Invalid Enqueue Channel"),
132174 + QMAN_HWE_TXT(IEQI, "Invalid Enqueue Queue")
132175 +};
132176 +#define QMAN_HWE_COUNT (sizeof(qman_hwerr_txts)/sizeof(struct qman_hwerr_txt))
132177 +
132178 +struct qman_error_info_mdata {
132179 + u16 addr_mask;
132180 + u16 bits;
132181 + const char *txt;
132182 +};
132183 +
132184 +#define QMAN_ERR_MDATA(a, b, c) { .addr_mask = a, .bits = b, .txt = c}
132185 +static const struct qman_error_info_mdata error_mdata[] = {
132186 + QMAN_ERR_MDATA(0x01FF, 24, "FQD cache tag memory 0"),
132187 + QMAN_ERR_MDATA(0x01FF, 24, "FQD cache tag memory 1"),
132188 + QMAN_ERR_MDATA(0x01FF, 24, "FQD cache tag memory 2"),
132189 + QMAN_ERR_MDATA(0x01FF, 24, "FQD cache tag memory 3"),
132190 + QMAN_ERR_MDATA(0x0FFF, 512, "FQD cache memory"),
132191 + QMAN_ERR_MDATA(0x07FF, 128, "SFDR memory"),
132192 + QMAN_ERR_MDATA(0x01FF, 72, "WQ context memory"),
132193 + QMAN_ERR_MDATA(0x00FF, 240, "CGR memory"),
132194 + QMAN_ERR_MDATA(0x00FF, 302, "Internal Order Restoration List memory"),
132195 + QMAN_ERR_MDATA(0x01FF, 256, "SW portal ring memory"),
132196 + QMAN_ERR_MDATA(0x07FF, 181, "CEETM class queue descriptor memory"),
132197 + QMAN_ERR_MDATA(0x0FFF, 140, "CEETM extended SFDR memory"),
132198 + QMAN_ERR_MDATA(0x0FFF, 25, "CEETM logical FQ mapping memory"),
132199 + QMAN_ERR_MDATA(0x0FFF, 96, "CEETM dequeue context memory"),
132200 + QMAN_ERR_MDATA(0x07FF, 396, "CEETM ccgr memory"),
132201 + QMAN_ERR_MDATA(0x00FF, 146, "CEETM CQ channel shaping memory"),
132202 + QMAN_ERR_MDATA(0x007F, 256, "CEETM CQ channel scheduling memory"),
132203 + QMAN_ERR_MDATA(0x01FF, 88, "CEETM dequeue statistics memory"),
132204 +};
132205 +#define QMAN_ERR_MDATA_COUNT \
132206 + (sizeof(error_mdata)/sizeof(struct qman_error_info_mdata))
132207 +
132208 +/* Add this in Kconfig */
132209 +#define QMAN_ERRS_TO_UNENABLE (QM_EIRQ_PLWI | QM_EIRQ_PEBI)
132210 +
132211 +/**
132212 + * qm_err_isr_<reg>_<verb> - Manipulate global interrupt registers
132213 + * @v: for accessors that write values, this is the 32-bit value
132214 + *
132215 + * Manipulates QMAN_ERR_ISR, QMAN_ERR_IER, QMAN_ERR_ISDR, QMAN_ERR_IIR. All
132216 + * manipulations except qm_err_isr_[un]inhibit() use 32-bit masks composed of
132217 + * the QM_EIRQ_*** definitions. Note that "qm_err_isr_enable_write" means
132218 + * "write the enable register" rather than "enable the write register"!
132219 + */
132220 +#define qm_err_isr_status_read(qm) \
132221 + __qm_err_isr_read(qm, qm_isr_status)
132222 +#define qm_err_isr_status_clear(qm, m) \
132223 + __qm_err_isr_write(qm, qm_isr_status, m)
132224 +#define qm_err_isr_enable_read(qm) \
132225 + __qm_err_isr_read(qm, qm_isr_enable)
132226 +#define qm_err_isr_enable_write(qm, v) \
132227 + __qm_err_isr_write(qm, qm_isr_enable, v)
132228 +#define qm_err_isr_disable_read(qm) \
132229 + __qm_err_isr_read(qm, qm_isr_disable)
132230 +#define qm_err_isr_disable_write(qm, v) \
132231 + __qm_err_isr_write(qm, qm_isr_disable, v)
132232 +#define qm_err_isr_inhibit(qm) \
132233 + __qm_err_isr_write(qm, qm_isr_inhibit, 1)
132234 +#define qm_err_isr_uninhibit(qm) \
132235 + __qm_err_isr_write(qm, qm_isr_inhibit, 0)
132236 +
132237 +/*
132238 + * TODO: unimplemented registers
132239 + *
132240 + * Keeping a list here of Qman registers I have not yet covered;
132241 + * QCSP_DD_IHRSR, QCSP_DD_IHRFR, QCSP_DD_HASR,
132242 + * DCP_DD_IHRSR, DCP_DD_IHRFR, DCP_DD_HASR, CM_CFG,
132243 + * QMAN_EECC, QMAN_SBET, QMAN_EINJ, QMAN_SBEC0-12
132244 + */
132245 +
132246 +/* Encapsulate "struct qman *" as a cast of the register space address. */
132247 +
132248 +static struct qman *qm_create(void *regs)
132249 +{
132250 + return (struct qman *)regs;
132251 +}
132252 +
132253 +static inline u32 __qm_in(struct qman *qm, u32 offset)
132254 +{
132255 + return in_be32((void *)qm + offset);
132256 +}
132257 +static inline void __qm_out(struct qman *qm, u32 offset, u32 val)
132258 +{
132259 + out_be32((void *)qm + offset, val);
132260 +}
132261 +#define qm_in(reg) __qm_in(qm, REG_##reg)
132262 +#define qm_out(reg, val) __qm_out(qm, REG_##reg, val)
132263 +
132264 +static u32 __qm_err_isr_read(struct qman *qm, enum qm_isr_reg n)
132265 +{
132266 + return __qm_in(qm, REG_ERR_ISR + (n << 2));
132267 +}
132268 +
132269 +static void __qm_err_isr_write(struct qman *qm, enum qm_isr_reg n, u32 val)
132270 +{
132271 + __qm_out(qm, REG_ERR_ISR + (n << 2), val);
132272 +}
132273 +
132274 +static void qm_set_dc(struct qman *qm, enum qm_dc_portal portal,
132275 + int ed, u8 sernd)
132276 +{
132277 + DPA_ASSERT(!ed || (portal == qm_dc_portal_fman0) ||
132278 + (portal == qm_dc_portal_fman1));
132279 + if ((qman_ip_rev & 0xFF00) >= QMAN_REV30)
132280 + qm_out(DCP_CFG(portal), (ed ? 0x1000 : 0) | (sernd & 0x3ff));
132281 + else
132282 + qm_out(DCP_CFG(portal), (ed ? 0x100 : 0) | (sernd & 0x1f));
132283 +}
132284 +
132285 +static void qm_set_wq_scheduling(struct qman *qm, enum qm_wq_class wq_class,
132286 + u8 cs_elev, u8 csw2, u8 csw3, u8 csw4, u8 csw5,
132287 + u8 csw6, u8 csw7)
132288 +{
132289 + qm_out(WQ_CS_CFG(wq_class), ((cs_elev & 0xff) << 24) |
132290 + ((csw2 & 0x7) << 20) | ((csw3 & 0x7) << 16) |
132291 + ((csw4 & 0x7) << 12) | ((csw5 & 0x7) << 8) |
132292 + ((csw6 & 0x7) << 4) | (csw7 & 0x7));
132293 +}
132294 +
132295 +static void qm_set_hid(struct qman *qm)
132296 +{
132297 + qm_out(HID_CFG, 0);
132298 +}
132299 +
132300 +static void qm_set_corenet_initiator(struct qman *qm)
132301 +{
132302 + qm_out(CI_SCHED_CFG,
132303 + 0x80000000 | /* write srcciv enable */
132304 + (CONFIG_FSL_QMAN_CI_SCHED_CFG_SRCCIV << 24) |
132305 + (CONFIG_FSL_QMAN_CI_SCHED_CFG_SRQ_W << 8) |
132306 + (CONFIG_FSL_QMAN_CI_SCHED_CFG_RW_W << 4) |
132307 + CONFIG_FSL_QMAN_CI_SCHED_CFG_BMAN_W);
132308 +}
132309 +
132310 +static void qm_get_version(struct qman *qm, u16 *id, u8 *major, u8 *minor,
132311 + u8 *cfg)
132312 +{
132313 + u32 v = qm_in(IP_REV_1);
132314 + u32 v2 = qm_in(IP_REV_2);
132315 + *id = (v >> 16);
132316 + *major = (v >> 8) & 0xff;
132317 + *minor = v & 0xff;
132318 + *cfg = v2 & 0xff;
132319 +}
132320 +
132321 +static void qm_set_memory(struct qman *qm, enum qm_memory memory, u64 ba,
132322 + int enable, int prio, int stash, u32 size)
132323 +{
132324 + u32 offset = (memory == qm_memory_fqd) ? REG_FQD_BARE : REG_PFDR_BARE;
132325 + u32 exp = ilog2(size);
132326 + /* choke if size isn't within range */
132327 + DPA_ASSERT((size >= 4096) && (size <= 1073741824) &&
132328 + is_power_of_2(size));
132329 + /* choke if 'ba' has lower-alignment than 'size' */
132330 + DPA_ASSERT(!(ba & (size - 1)));
132331 + __qm_out(qm, offset, upper_32_bits(ba));
132332 + __qm_out(qm, offset + REG_offset_BAR, lower_32_bits(ba));
132333 + __qm_out(qm, offset + REG_offset_AR,
132334 + (enable ? 0x80000000 : 0) |
132335 + (prio ? 0x40000000 : 0) |
132336 + (stash ? 0x20000000 : 0) |
132337 + (exp - 1));
132338 +}
132339 +
132340 +static void qm_set_pfdr_threshold(struct qman *qm, u32 th, u8 k)
132341 +{
132342 + qm_out(PFDR_FP_LWIT, th & 0xffffff);
132343 + qm_out(PFDR_CFG, k);
132344 +}
132345 +
132346 +static void qm_set_sfdr_threshold(struct qman *qm, u16 th)
132347 +{
132348 + qm_out(SFDR_CFG, th & 0x3ff);
132349 +}
132350 +
132351 +static int qm_init_pfdr(struct qman *qm, u32 pfdr_start, u32 num)
132352 +{
132353 + u8 rslt = MCR_get_rslt(qm_in(MCR));
132354 +
132355 + DPA_ASSERT(pfdr_start && !(pfdr_start & 7) && !(num & 7) && num);
132356 + /* Make sure the command interface is 'idle' */
132357 + if (!MCR_rslt_idle(rslt))
132358 + panic("QMAN_MCR isn't idle");
132359 +
132360 + /* Write the MCR command params then the verb */
132361 + qm_out(MCP(0), pfdr_start);
132362 + /* TODO: remove this - it's a workaround for a model bug that is
132363 + * corrected in more recent versions. We use the workaround until
132364 + * everyone has upgraded. */
132365 + qm_out(MCP(1), (pfdr_start + num - 16));
132366 + lwsync();
132367 + qm_out(MCR, MCR_INIT_PFDR);
132368 + /* Poll for the result */
132369 + do {
132370 + rslt = MCR_get_rslt(qm_in(MCR));
132371 + } while (!MCR_rslt_idle(rslt));
132372 + if (MCR_rslt_ok(rslt))
132373 + return 0;
132374 + if (MCR_rslt_eaccess(rslt))
132375 + return -EACCES;
132376 + if (MCR_rslt_inval(rslt))
132377 + return -EINVAL;
132378 + pr_crit("Unexpected result from MCR_INIT_PFDR: %02x\n", rslt);
132379 + return -ENOSYS;
132380 +}
132381 +
132382 +/*****************/
132383 +/* Config driver */
132384 +/*****************/
132385 +
132386 +#define DEFAULT_FQD_SZ (PAGE_SIZE << CONFIG_FSL_QMAN_FQD_SZ)
132387 +#define DEFAULT_PFDR_SZ (PAGE_SIZE << CONFIG_FSL_QMAN_PFDR_SZ)
132388 +
132389 +/* We support only one of these */
132390 +static struct qman *qm;
132391 +static struct device_node *qm_node;
132392 +
132393 +/* And this state belongs to 'qm'. It is set during fsl_qman_init(), but used
132394 + * during qman_init_ccsr(). */
132395 +static dma_addr_t fqd_a, pfdr_a;
132396 +static size_t fqd_sz = DEFAULT_FQD_SZ, pfdr_sz = DEFAULT_PFDR_SZ;
132397 +
132398 +static int qman_fqd(struct reserved_mem *rmem)
132399 +{
132400 + fqd_a = rmem->base;
132401 + fqd_sz = rmem->size;
132402 +
132403 + WARN_ON(!(fqd_a && fqd_sz));
132404 +
132405 + return 0;
132406 +}
132407 +RESERVEDMEM_OF_DECLARE(qman_fqd, "fsl,qman-fqd", qman_fqd);
132408 +
132409 +static int qman_pfdr(struct reserved_mem *rmem)
132410 +{
132411 + pfdr_a = rmem->base;
132412 + pfdr_sz = rmem->size;
132413 +
132414 + WARN_ON(!(pfdr_a && pfdr_sz));
132415 +
132416 + return 0;
132417 +}
132418 +RESERVEDMEM_OF_DECLARE(qman_fbpr, "fsl,qman-pfdr", qman_pfdr);
132419 +
132420 +size_t get_qman_fqd_size()
132421 +{
132422 + return fqd_sz;
132423 +}
132424 +
132425 +/* Parse the <name> property to extract the memory location and size and
132426 + * memblock_reserve() it. If it isn't supplied, memblock_alloc() the default
132427 + * size. Also flush this memory range from data cache so that QMAN originated
132428 + * transactions for this memory region could be marked non-coherent.
132429 + */
132430 +static __init int parse_mem_property(struct device_node *node, const char *name,
132431 + dma_addr_t *addr, size_t *sz, int zero)
132432 +{
132433 + int ret;
132434 +
132435 + /* If using a "zero-pma", don't try to zero it, even if you asked */
132436 + if (zero && of_find_property(node, "zero-pma", &ret)) {
132437 + pr_info(" it's a 'zero-pma', not zeroing from s/w\n");
132438 + zero = 0;
132439 + }
132440 +
132441 + if (zero) {
132442 + /* map as cacheable, non-guarded */
132443 +#if defined(CONFIG_ARM) || defined(CONFIG_ARM64)
132444 + void __iomem *tmpp = ioremap_cache(*addr, *sz);
132445 +#else
132446 + void __iomem *tmpp = ioremap(*addr, *sz);
132447 +#endif
132448 +
132449 + if (!tmpp)
132450 + return -ENOMEM;
132451 + memset_io(tmpp, 0, *sz);
132452 + flush_dcache_range((unsigned long)tmpp,
132453 + (unsigned long)tmpp + *sz);
132454 + iounmap(tmpp);
132455 + }
132456 +
132457 + return 0;
132458 +}
132459 +
132460 +/* TODO:
132461 + * - there is obviously no handling of errors,
132462 + * - the calls to qm_set_memory() hard-code the priority and CPC-stashing for
132463 + * both memory resources to zero.
132464 + */
132465 +static int __init fsl_qman_init(struct device_node *node)
132466 +{
132467 + struct resource res;
132468 + resource_size_t len;
132469 + u32 __iomem *regs;
132470 + const char *s;
132471 + int ret, standby = 0;
132472 + u16 id;
132473 + u8 major, minor, cfg;
132474 + ret = of_address_to_resource(node, 0, &res);
132475 + if (ret) {
132476 + pr_err("Can't get %s property '%s'\n", node->full_name, "reg");
132477 + return ret;
132478 + }
132479 + s = of_get_property(node, "fsl,hv-claimable", &ret);
132480 + if (s && !strcmp(s, "standby"))
132481 + standby = 1;
132482 + if (!standby) {
132483 + ret = parse_mem_property(node, "fsl,qman-fqd",
132484 + &fqd_a, &fqd_sz, 1);
132485 + pr_info("qman-fqd addr %pad size 0x%zx\n", &fqd_a, fqd_sz);
132486 + BUG_ON(ret);
132487 + ret = parse_mem_property(node, "fsl,qman-pfdr",
132488 + &pfdr_a, &pfdr_sz, 0);
132489 + pr_info("qman-pfdr addr %pad size 0x%zx\n", &pfdr_a, pfdr_sz);
132490 + BUG_ON(ret);
132491 + }
132492 + /* Global configuration */
132493 + len = resource_size(&res);
132494 + if (len != (unsigned long)len)
132495 + return -EINVAL;
132496 + regs = ioremap(res.start, (unsigned long)len);
132497 + qm = qm_create(regs);
132498 + qm_node = node;
132499 + qm_get_version(qm, &id, &major, &minor, &cfg);
132500 + pr_info("Qman ver:%04x,%02x,%02x,%02x\n", id, major, minor, cfg);
132501 + if (!qman_ip_rev) {
132502 + if ((major == 1) && (minor == 0)) {
132503 + pr_err("QMAN rev1.0 on P4080 rev1 is not supported!\n");
132504 + iounmap(regs);
132505 + return -ENODEV;
132506 + } else if ((major == 1) && (minor == 1))
132507 + qman_ip_rev = QMAN_REV11;
132508 + else if ((major == 1) && (minor == 2))
132509 + qman_ip_rev = QMAN_REV12;
132510 + else if ((major == 2) && (minor == 0))
132511 + qman_ip_rev = QMAN_REV20;
132512 + else if ((major == 3) && (minor == 0))
132513 + qman_ip_rev = QMAN_REV30;
132514 + else if ((major == 3) && (minor == 1))
132515 + qman_ip_rev = QMAN_REV31;
132516 + else if ((major == 3) && (minor == 2))
132517 + qman_ip_rev = QMAN_REV32;
132518 + else {
132519 + pr_warn("unknown Qman version, default to rev1.1\n");
132520 + qman_ip_rev = QMAN_REV11;
132521 + }
132522 + qman_ip_cfg = cfg;
132523 + }
132524 +
132525 + if (standby) {
132526 + pr_info(" -> in standby mode\n");
132527 + return 0;
132528 + }
132529 + return 0;
132530 +}
132531 +
132532 +int qman_have_ccsr(void)
132533 +{
132534 + return qm ? 1 : 0;
132535 +}
132536 +
132537 +__init int qman_init_early(void)
132538 +{
132539 + struct device_node *dn;
132540 + int ret;
132541 +
132542 + for_each_compatible_node(dn, NULL, "fsl,qman") {
132543 + if (qm)
132544 + pr_err("%s: only one 'fsl,qman' allowed\n",
132545 + dn->full_name);
132546 + else {
132547 + if (!of_device_is_available(dn))
132548 + continue;
132549 +
132550 + ret = fsl_qman_init(dn);
132551 + BUG_ON(ret);
132552 + }
132553 + }
132554 + return 0;
132555 +}
132556 +postcore_initcall_sync(qman_init_early);
132557 +
132558 +static void log_edata_bits(u32 bit_count)
132559 +{
132560 + u32 i, j, mask = 0xffffffff;
132561 +
132562 + pr_warn("Qman ErrInt, EDATA:\n");
132563 + i = bit_count/32;
132564 + if (bit_count%32) {
132565 + i++;
132566 + mask = ~(mask << bit_count%32);
132567 + }
132568 + j = 16-i;
132569 + pr_warn(" 0x%08x\n", qm_in(EDATA(j)) & mask);
132570 + j++;
132571 + for (; j < 16; j++)
132572 + pr_warn(" 0x%08x\n", qm_in(EDATA(j)));
132573 +}
132574 +
132575 +static void log_additional_error_info(u32 isr_val, u32 ecsr_val)
132576 +{
132577 + union qman_ecir ecir_val;
132578 + union qman_eadr eadr_val;
132579 +
132580 + ecir_val.ecir_raw = qm_in(ECIR);
132581 + /* Is portal info valid */
132582 + if ((qman_ip_rev & 0xFF00) >= QMAN_REV30) {
132583 + union qman_ecir2 ecir2_val;
132584 + ecir2_val.ecir2_raw = qm_in(ECIR2);
132585 + if (ecsr_val & PORTAL_ECSR_ERR) {
132586 + pr_warn("Qman ErrInt: %s id %d\n",
132587 + (ecir2_val.info.portal_type) ?
132588 + "DCP" : "SWP", ecir2_val.info.portal_num);
132589 + }
132590 + if (ecsr_val & (FQID_ECSR_ERR | QM_EIRQ_IECE)) {
132591 + pr_warn("Qman ErrInt: ecir.fqid 0x%x\n",
132592 + ecir_val.info.fqid);
132593 + }
132594 + if (ecsr_val & (QM_EIRQ_SBEI|QM_EIRQ_MBEI)) {
132595 + eadr_val.eadr_raw = qm_in(EADR);
132596 + pr_warn("Qman ErrInt: EADR Memory: %s, 0x%x\n",
132597 + error_mdata[eadr_val.info_rev3.memid].txt,
132598 + error_mdata[eadr_val.info_rev3.memid].addr_mask
132599 + & eadr_val.info_rev3.eadr);
132600 + log_edata_bits(
132601 + error_mdata[eadr_val.info_rev3.memid].bits);
132602 + }
132603 + } else {
132604 + if (ecsr_val & PORTAL_ECSR_ERR) {
132605 + pr_warn("Qman ErrInt: %s id %d\n",
132606 + (ecir_val.info.portal_type) ?
132607 + "DCP" : "SWP", ecir_val.info.portal_num);
132608 + }
132609 + if (ecsr_val & FQID_ECSR_ERR) {
132610 + pr_warn("Qman ErrInt: ecir.fqid 0x%x\n",
132611 + ecir_val.info.fqid);
132612 + }
132613 + if (ecsr_val & (QM_EIRQ_SBEI|QM_EIRQ_MBEI)) {
132614 + eadr_val.eadr_raw = qm_in(EADR);
132615 + pr_warn("Qman ErrInt: EADR Memory: %s, 0x%x\n",
132616 + error_mdata[eadr_val.info.memid].txt,
132617 + error_mdata[eadr_val.info.memid].addr_mask
132618 + & eadr_val.info.eadr);
132619 + log_edata_bits(error_mdata[eadr_val.info.memid].bits);
132620 + }
132621 + }
132622 +}
132623 +
132624 +/* Qman interrupt handler */
132625 +static irqreturn_t qman_isr(int irq, void *ptr)
132626 +{
132627 + u32 isr_val, ier_val, ecsr_val, isr_mask, i;
132628 +
132629 + ier_val = qm_err_isr_enable_read(qm);
132630 + isr_val = qm_err_isr_status_read(qm);
132631 + ecsr_val = qm_in(ECSR);
132632 + isr_mask = isr_val & ier_val;
132633 +
132634 + if (!isr_mask)
132635 + return IRQ_NONE;
132636 + for (i = 0; i < QMAN_HWE_COUNT; i++) {
132637 + if (qman_hwerr_txts[i].mask & isr_mask) {
132638 + pr_warn("Qman ErrInt: %s\n", qman_hwerr_txts[i].txt);
132639 + if (qman_hwerr_txts[i].mask & ecsr_val) {
132640 + log_additional_error_info(isr_mask, ecsr_val);
132641 + /* Re-arm error capture registers */
132642 + qm_out(ECSR, ecsr_val);
132643 + }
132644 + if (qman_hwerr_txts[i].mask & QMAN_ERRS_TO_UNENABLE) {
132645 + pr_devel("Qman un-enabling error 0x%x\n",
132646 + qman_hwerr_txts[i].mask);
132647 + ier_val &= ~qman_hwerr_txts[i].mask;
132648 + qm_err_isr_enable_write(qm, ier_val);
132649 + }
132650 + }
132651 + }
132652 + qm_err_isr_status_clear(qm, isr_val);
132653 + return IRQ_HANDLED;
132654 +}
132655 +
132656 +static int __bind_irq(void)
132657 +{
132658 + int ret, err_irq;
132659 +
132660 + err_irq = of_irq_to_resource(qm_node, 0, NULL);
132661 + if (err_irq == 0) {
132662 + pr_info("Can't get %s property '%s'\n", qm_node->full_name,
132663 + "interrupts");
132664 + return -ENODEV;
132665 + }
132666 + ret = request_irq(err_irq, qman_isr, IRQF_SHARED, "qman-err", qm_node);
132667 + if (ret) {
132668 + pr_err("request_irq() failed %d for '%s'\n", ret,
132669 + qm_node->full_name);
132670 + return -ENODEV;
132671 + }
132672 + /* Write-to-clear any stale bits, (eg. starvation being asserted prior
132673 + * to resource allocation during driver init). */
132674 + qm_err_isr_status_clear(qm, 0xffffffff);
132675 + /* Enable Error Interrupts */
132676 + qm_err_isr_enable_write(qm, 0xffffffff);
132677 + return 0;
132678 +}
132679 +
132680 +int qman_init_ccsr(struct device_node *node)
132681 +{
132682 + int ret;
132683 + if (!qman_have_ccsr())
132684 + return 0;
132685 + if (node != qm_node)
132686 + return -EINVAL;
132687 +#if defined(CONFIG_ARM) || defined(CONFIG_ARM64)
132688 + /* TEMP for LS1043 : should be done in uboot */
132689 + qm_out(QCSP_BARE, 0x5);
132690 + qm_out(QCSP_BAR, 0x0);
132691 +#endif
132692 + /* FQD memory */
132693 + qm_set_memory(qm, qm_memory_fqd, fqd_a, 1, 0, 0, fqd_sz);
132694 + /* PFDR memory */
132695 + qm_set_memory(qm, qm_memory_pfdr, pfdr_a, 1, 0, 0, pfdr_sz);
132696 + qm_init_pfdr(qm, 8, pfdr_sz / 64 - 8);
132697 + /* thresholds */
132698 + qm_set_pfdr_threshold(qm, 512, 64);
132699 + qm_set_sfdr_threshold(qm, 128);
132700 + /* clear stale PEBI bit from interrupt status register */
132701 + qm_err_isr_status_clear(qm, QM_EIRQ_PEBI);
132702 + /* corenet initiator settings */
132703 + qm_set_corenet_initiator(qm);
132704 + /* HID settings */
132705 + qm_set_hid(qm);
132706 + /* Set scheduling weights to defaults */
132707 + for (ret = qm_wq_first; ret <= qm_wq_last; ret++)
132708 + qm_set_wq_scheduling(qm, ret, 0, 0, 0, 0, 0, 0, 0);
132709 + /* We are not prepared to accept ERNs for hardware enqueues */
132710 + qm_set_dc(qm, qm_dc_portal_fman0, 1, 0);
132711 + qm_set_dc(qm, qm_dc_portal_fman1, 1, 0);
132712 + /* Initialise Error Interrupt Handler */
132713 + ret = __bind_irq();
132714 + if (ret)
132715 + return ret;
132716 + return 0;
132717 +}
132718 +
132719 +#define LIO_CFG_LIODN_MASK 0x0fff0000
132720 +void qman_liodn_fixup(u16 channel)
132721 +{
132722 + static int done;
132723 + static u32 liodn_offset;
132724 + u32 before, after;
132725 + int idx = channel - QM_CHANNEL_SWPORTAL0;
132726 +
132727 + if (!qman_have_ccsr())
132728 + return;
132729 + if ((qman_ip_rev & 0xFF00) >= QMAN_REV30)
132730 + before = qm_in(REV3_QCSP_LIO_CFG(idx));
132731 + else
132732 + before = qm_in(QCSP_LIO_CFG(idx));
132733 + if (!done) {
132734 + liodn_offset = before & LIO_CFG_LIODN_MASK;
132735 + done = 1;
132736 + return;
132737 + }
132738 + after = (before & (~LIO_CFG_LIODN_MASK)) | liodn_offset;
132739 + if ((qman_ip_rev & 0xFF00) >= QMAN_REV30)
132740 + qm_out(REV3_QCSP_LIO_CFG(idx), after);
132741 + else
132742 + qm_out(QCSP_LIO_CFG(idx), after);
132743 +}
132744 +
132745 +#define IO_CFG_SDEST_MASK 0x00ff0000
132746 +int qman_set_sdest(u16 channel, unsigned int cpu_idx)
132747 +{
132748 + int idx = channel - QM_CHANNEL_SWPORTAL0;
132749 + u32 before, after;
132750 +
132751 + if (!qman_have_ccsr())
132752 + return -ENODEV;
132753 + if ((qman_ip_rev & 0xFF00) == QMAN_REV31) {
132754 + /* LS1043A - only one L2 cache */
132755 + cpu_idx = 0;
132756 + }
132757 +
132758 + if ((qman_ip_rev & 0xFF00) >= QMAN_REV30) {
132759 + before = qm_in(REV3_QCSP_IO_CFG(idx));
132760 + /* Each pair of vcpu share the same SRQ(SDEST) */
132761 + cpu_idx /= 2;
132762 + after = (before & (~IO_CFG_SDEST_MASK)) | (cpu_idx << 16);
132763 + qm_out(REV3_QCSP_IO_CFG(idx), after);
132764 + } else {
132765 + before = qm_in(QCSP_IO_CFG(idx));
132766 + after = (before & (~IO_CFG_SDEST_MASK)) | (cpu_idx << 16);
132767 + qm_out(QCSP_IO_CFG(idx), after);
132768 + }
132769 + return 0;
132770 +}
132771 +
132772 +#define MISC_CFG_WPM_MASK 0x00000002
132773 +int qm_set_wpm(int wpm)
132774 +{
132775 + u32 before;
132776 + u32 after;
132777 +
132778 + if (!qman_have_ccsr())
132779 + return -ENODEV;
132780 +
132781 + before = qm_in(MISC_CFG);
132782 + after = (before & (~MISC_CFG_WPM_MASK)) | (wpm << 1);
132783 + qm_out(MISC_CFG, after);
132784 + return 0;
132785 +}
132786 +
132787 +int qm_get_wpm(int *wpm)
132788 +{
132789 + u32 before;
132790 +
132791 + if (!qman_have_ccsr())
132792 + return -ENODEV;
132793 +
132794 + before = qm_in(MISC_CFG);
132795 + *wpm = (before & MISC_CFG_WPM_MASK) >> 1;
132796 + return 0;
132797 +}
132798 +
132799 +/* CEETM_CFG_PRES register has PRES field which is calculated by:
132800 + * PRES = (2^22 / credit update reference period) * QMan clock period
132801 + * = (2^22 * 10^9)/ CONFIG_QMAN_CEETM_UPDATE_PERIOD) / qman_clk
132802 + */
132803 +
132804 +int qman_ceetm_set_prescaler(enum qm_dc_portal portal)
132805 +{
132806 + u64 temp;
132807 + u16 pres;
132808 +
132809 + if (!qman_have_ccsr())
132810 + return -ENODEV;
132811 +
132812 + temp = 0x400000 * 100;
132813 + do_div(temp, CONFIG_QMAN_CEETM_UPDATE_PERIOD);
132814 + temp *= 10000000;
132815 + do_div(temp, qman_clk);
132816 + pres = (u16) temp;
132817 + qm_out(CEETM_CFG_IDX, portal);
132818 + qm_out(CEETM_CFG_PRES, pres);
132819 + return 0;
132820 +}
132821 +
132822 +int qman_ceetm_get_prescaler(u16 *pres)
132823 +{
132824 + if (!qman_have_ccsr())
132825 + return -ENODEV;
132826 + *pres = (u16)qm_in(CEETM_CFG_PRES);
132827 + return 0;
132828 +}
132829 +
132830 +#define DCP_CFG_CEETME_MASK 0xFFFF0000
132831 +#define QM_SP_ENABLE_CEETM(n) (0x80000000 >> (n))
132832 +int qman_sp_enable_ceetm_mode(enum qm_dc_portal portal, u16 sub_portal)
132833 +{
132834 + u32 dcp_cfg;
132835 +
132836 + if (!qman_have_ccsr())
132837 + return -ENODEV;
132838 +
132839 + dcp_cfg = qm_in(DCP_CFG(portal));
132840 + dcp_cfg |= QM_SP_ENABLE_CEETM(sub_portal);
132841 + qm_out(DCP_CFG(portal), dcp_cfg);
132842 + return 0;
132843 +}
132844 +
132845 +int qman_sp_disable_ceetm_mode(enum qm_dc_portal portal, u16 sub_portal)
132846 +{
132847 + u32 dcp_cfg;
132848 +
132849 + if (!qman_have_ccsr())
132850 + return -ENODEV;
132851 + dcp_cfg = qm_in(DCP_CFG(portal));
132852 + dcp_cfg &= ~(QM_SP_ENABLE_CEETM(sub_portal));
132853 + qm_out(DCP_CFG(portal), dcp_cfg);
132854 + return 0;
132855 +}
132856 +
132857 +int qman_ceetm_get_xsfdr(enum qm_dc_portal portal, unsigned int *num)
132858 +{
132859 + if (!qman_have_ccsr())
132860 + return -ENODEV;
132861 + *num = qm_in(CEETM_XSFDR_IN_USE);
132862 + return 0;
132863 +}
132864 +EXPORT_SYMBOL(qman_ceetm_get_xsfdr);
132865 +
132866 +#ifdef CONFIG_SYSFS
132867 +
132868 +#define DRV_NAME "fsl-qman"
132869 +#define DCP_MAX_ID 3
132870 +#define DCP_MIN_ID 0
132871 +
132872 +static ssize_t show_pfdr_fpc(struct device *dev,
132873 + struct device_attribute *dev_attr, char *buf)
132874 +{
132875 + return snprintf(buf, PAGE_SIZE, "%u\n", qm_in(PFDR_FPC));
132876 +};
132877 +
132878 +static ssize_t show_dlm_avg(struct device *dev,
132879 + struct device_attribute *dev_attr, char *buf)
132880 +{
132881 + u32 data;
132882 + int i;
132883 +
132884 + if (!sscanf(dev_attr->attr.name, "dcp%d_dlm_avg", &i))
132885 + return -EINVAL;
132886 + if (i < DCP_MIN_ID || i > DCP_MAX_ID)
132887 + return -EINVAL;
132888 + data = qm_in(DCP_DLM_AVG(i));
132889 + return snprintf(buf, PAGE_SIZE, "%d.%08d\n", data>>8,
132890 + (data & 0x000000ff)*390625);
132891 +};
132892 +
132893 +static ssize_t set_dlm_avg(struct device *dev,
132894 + struct device_attribute *dev_attr, const char *buf, size_t count)
132895 +{
132896 + unsigned long val;
132897 + int i;
132898 +
132899 + if (!sscanf(dev_attr->attr.name, "dcp%d_dlm_avg", &i))
132900 + return -EINVAL;
132901 + if (i < DCP_MIN_ID || i > DCP_MAX_ID)
132902 + return -EINVAL;
132903 + if (kstrtoul(buf, 0, &val)) {
132904 + dev_dbg(dev, "invalid input %s\n", buf);
132905 + return -EINVAL;
132906 + }
132907 + qm_out(DCP_DLM_AVG(i), val);
132908 + return count;
132909 +};
132910 +
132911 +static ssize_t show_pfdr_cfg(struct device *dev,
132912 + struct device_attribute *dev_attr, char *buf)
132913 +{
132914 + return snprintf(buf, PAGE_SIZE, "%u\n", qm_in(PFDR_CFG));
132915 +};
132916 +
132917 +static ssize_t set_pfdr_cfg(struct device *dev,
132918 + struct device_attribute *dev_attr, const char *buf, size_t count)
132919 +{
132920 + unsigned long val;
132921 +
132922 + if (kstrtoul(buf, 0, &val)) {
132923 + dev_dbg(dev, "invalid input %s\n", buf);
132924 + return -EINVAL;
132925 + }
132926 + qm_out(PFDR_CFG, val);
132927 + return count;
132928 +};
132929 +
132930 +static ssize_t show_sfdr_in_use(struct device *dev,
132931 + struct device_attribute *dev_attr, char *buf)
132932 +{
132933 + return snprintf(buf, PAGE_SIZE, "%u\n", qm_in(SFDR_IN_USE));
132934 +};
132935 +
132936 +static ssize_t show_idle_stat(struct device *dev,
132937 + struct device_attribute *dev_attr, char *buf)
132938 +{
132939 + return snprintf(buf, PAGE_SIZE, "%u\n", qm_in(IDLE_STAT));
132940 +};
132941 +
132942 +static ssize_t show_ci_rlm_avg(struct device *dev,
132943 + struct device_attribute *dev_attr, char *buf)
132944 +{
132945 + u32 data = qm_in(CI_RLM_AVG);
132946 + return snprintf(buf, PAGE_SIZE, "%d.%08d\n", data>>8,
132947 + (data & 0x000000ff)*390625);
132948 +};
132949 +
132950 +static ssize_t set_ci_rlm_avg(struct device *dev,
132951 + struct device_attribute *dev_attr, const char *buf, size_t count)
132952 +{
132953 + unsigned long val;
132954 +
132955 + if (kstrtoul(buf, 0, &val)) {
132956 + dev_dbg(dev, "invalid input %s\n", buf);
132957 + return -EINVAL;
132958 + }
132959 + qm_out(CI_RLM_AVG, val);
132960 + return count;
132961 +};
132962 +
132963 +static ssize_t show_err_isr(struct device *dev,
132964 + struct device_attribute *dev_attr, char *buf)
132965 +{
132966 + return snprintf(buf, PAGE_SIZE, "0x%08x\n", qm_in(ERR_ISR));
132967 +};
132968 +
132969 +#define SBEC_MAX_ID 14
132970 +#define SBEC_MIN_ID 0
132971 +
132972 +static ssize_t show_sbec(struct device *dev,
132973 + struct device_attribute *dev_attr, char *buf)
132974 +{
132975 + int i;
132976 +
132977 + if (!sscanf(dev_attr->attr.name, "sbec_%d", &i))
132978 + return -EINVAL;
132979 + if (i < SBEC_MIN_ID || i > SBEC_MAX_ID)
132980 + return -EINVAL;
132981 + return snprintf(buf, PAGE_SIZE, "%u\n", qm_in(SBEC(i)));
132982 +};
132983 +
132984 +static DEVICE_ATTR(pfdr_fpc, S_IRUSR, show_pfdr_fpc, NULL);
132985 +static DEVICE_ATTR(pfdr_cfg, S_IRUSR, show_pfdr_cfg, set_pfdr_cfg);
132986 +static DEVICE_ATTR(idle_stat, S_IRUSR, show_idle_stat, NULL);
132987 +static DEVICE_ATTR(ci_rlm_avg, (S_IRUSR|S_IWUSR),
132988 + show_ci_rlm_avg, set_ci_rlm_avg);
132989 +static DEVICE_ATTR(err_isr, S_IRUSR, show_err_isr, NULL);
132990 +static DEVICE_ATTR(sfdr_in_use, S_IRUSR, show_sfdr_in_use, NULL);
132991 +
132992 +static DEVICE_ATTR(dcp0_dlm_avg, (S_IRUSR|S_IWUSR), show_dlm_avg, set_dlm_avg);
132993 +static DEVICE_ATTR(dcp1_dlm_avg, (S_IRUSR|S_IWUSR), show_dlm_avg, set_dlm_avg);
132994 +static DEVICE_ATTR(dcp2_dlm_avg, (S_IRUSR|S_IWUSR), show_dlm_avg, set_dlm_avg);
132995 +static DEVICE_ATTR(dcp3_dlm_avg, (S_IRUSR|S_IWUSR), show_dlm_avg, set_dlm_avg);
132996 +
132997 +static DEVICE_ATTR(sbec_0, S_IRUSR, show_sbec, NULL);
132998 +static DEVICE_ATTR(sbec_1, S_IRUSR, show_sbec, NULL);
132999 +static DEVICE_ATTR(sbec_2, S_IRUSR, show_sbec, NULL);
133000 +static DEVICE_ATTR(sbec_3, S_IRUSR, show_sbec, NULL);
133001 +static DEVICE_ATTR(sbec_4, S_IRUSR, show_sbec, NULL);
133002 +static DEVICE_ATTR(sbec_5, S_IRUSR, show_sbec, NULL);
133003 +static DEVICE_ATTR(sbec_6, S_IRUSR, show_sbec, NULL);
133004 +static DEVICE_ATTR(sbec_7, S_IRUSR, show_sbec, NULL);
133005 +static DEVICE_ATTR(sbec_8, S_IRUSR, show_sbec, NULL);
133006 +static DEVICE_ATTR(sbec_9, S_IRUSR, show_sbec, NULL);
133007 +static DEVICE_ATTR(sbec_10, S_IRUSR, show_sbec, NULL);
133008 +static DEVICE_ATTR(sbec_11, S_IRUSR, show_sbec, NULL);
133009 +static DEVICE_ATTR(sbec_12, S_IRUSR, show_sbec, NULL);
133010 +static DEVICE_ATTR(sbec_13, S_IRUSR, show_sbec, NULL);
133011 +static DEVICE_ATTR(sbec_14, S_IRUSR, show_sbec, NULL);
133012 +
133013 +static struct attribute *qman_dev_attributes[] = {
133014 + &dev_attr_pfdr_fpc.attr,
133015 + &dev_attr_pfdr_cfg.attr,
133016 + &dev_attr_idle_stat.attr,
133017 + &dev_attr_ci_rlm_avg.attr,
133018 + &dev_attr_err_isr.attr,
133019 + &dev_attr_dcp0_dlm_avg.attr,
133020 + &dev_attr_dcp1_dlm_avg.attr,
133021 + &dev_attr_dcp2_dlm_avg.attr,
133022 + &dev_attr_dcp3_dlm_avg.attr,
133023 + /* sfdr_in_use will be added if necessary */
133024 + NULL
133025 +};
133026 +
133027 +static struct attribute *qman_dev_ecr_attributes[] = {
133028 + &dev_attr_sbec_0.attr,
133029 + &dev_attr_sbec_1.attr,
133030 + &dev_attr_sbec_2.attr,
133031 + &dev_attr_sbec_3.attr,
133032 + &dev_attr_sbec_4.attr,
133033 + &dev_attr_sbec_5.attr,
133034 + &dev_attr_sbec_6.attr,
133035 + &dev_attr_sbec_7.attr,
133036 + &dev_attr_sbec_8.attr,
133037 + &dev_attr_sbec_9.attr,
133038 + &dev_attr_sbec_10.attr,
133039 + &dev_attr_sbec_11.attr,
133040 + &dev_attr_sbec_12.attr,
133041 + &dev_attr_sbec_13.attr,
133042 + &dev_attr_sbec_14.attr,
133043 + NULL
133044 +};
133045 +
133046 +/* root level */
133047 +static const struct attribute_group qman_dev_attr_grp = {
133048 + .name = NULL,
133049 + .attrs = qman_dev_attributes
133050 +};
133051 +static const struct attribute_group qman_dev_ecr_grp = {
133052 + .name = "error_capture",
133053 + .attrs = qman_dev_ecr_attributes
133054 +};
133055 +
133056 +static int of_fsl_qman_remove(struct platform_device *ofdev)
133057 +{
133058 + sysfs_remove_group(&ofdev->dev.kobj, &qman_dev_attr_grp);
133059 + return 0;
133060 +};
133061 +
133062 +static int of_fsl_qman_probe(struct platform_device *ofdev)
133063 +{
133064 + int ret;
133065 +
133066 + ret = sysfs_create_group(&ofdev->dev.kobj, &qman_dev_attr_grp);
133067 + if (ret)
133068 + goto done;
133069 + ret = sysfs_add_file_to_group(&ofdev->dev.kobj,
133070 + &dev_attr_sfdr_in_use.attr, qman_dev_attr_grp.name);
133071 + if (ret)
133072 + goto del_group_0;
133073 + ret = sysfs_create_group(&ofdev->dev.kobj, &qman_dev_ecr_grp);
133074 + if (ret)
133075 + goto del_group_0;
133076 +
133077 + goto done;
133078 +
133079 +del_group_0:
133080 + sysfs_remove_group(&ofdev->dev.kobj, &qman_dev_attr_grp);
133081 +done:
133082 + if (ret)
133083 + dev_err(&ofdev->dev,
133084 + "Cannot create dev attributes ret=%d\n", ret);
133085 + return ret;
133086 +};
133087 +
133088 +static struct of_device_id of_fsl_qman_ids[] = {
133089 + {
133090 + .compatible = "fsl,qman",
133091 + },
133092 + {}
133093 +};
133094 +MODULE_DEVICE_TABLE(of, of_fsl_qman_ids);
133095 +
133096 +#ifdef CONFIG_SUSPEND
133097 +
133098 +static u32 saved_isdr;
133099 +static int qman_pm_suspend_noirq(struct device *dev)
133100 +{
133101 + uint32_t idle_state;
133102 +
133103 + suspend_unused_qportal();
133104 + /* save isdr, disable all, clear isr */
133105 + saved_isdr = qm_err_isr_disable_read(qm);
133106 + qm_err_isr_disable_write(qm, 0xffffffff);
133107 + qm_err_isr_status_clear(qm, 0xffffffff);
133108 + idle_state = qm_in(IDLE_STAT);
133109 + if (!(idle_state & 0x1)) {
133110 + pr_err("Qman not idle 0x%x aborting\n", idle_state);
133111 + qm_err_isr_disable_write(qm, saved_isdr);
133112 + resume_unused_qportal();
133113 + return -EBUSY;
133114 + }
133115 +#ifdef CONFIG_PM_DEBUG
133116 + pr_info("Qman suspend code, IDLE_STAT = 0x%x\n", idle_state);
133117 +#endif
133118 + return 0;
133119 +}
133120 +
133121 +static int qman_pm_resume_noirq(struct device *dev)
133122 +{
133123 + /* restore isdr */
133124 + qm_err_isr_disable_write(qm, saved_isdr);
133125 + resume_unused_qportal();
133126 + return 0;
133127 +}
133128 +#else
133129 +#define qman_pm_suspend_noirq NULL
133130 +#define qman_pm_resume_noirq NULL
133131 +#endif
133132 +
133133 +static const struct dev_pm_ops qman_pm_ops = {
133134 + .suspend_noirq = qman_pm_suspend_noirq,
133135 + .resume_noirq = qman_pm_resume_noirq,
133136 +};
133137 +
133138 +static struct platform_driver of_fsl_qman_driver = {
133139 + .driver = {
133140 + .owner = THIS_MODULE,
133141 + .name = DRV_NAME,
133142 + .of_match_table = of_fsl_qman_ids,
133143 + .pm = &qman_pm_ops,
133144 + },
133145 + .probe = of_fsl_qman_probe,
133146 + .remove = of_fsl_qman_remove,
133147 +};
133148 +
133149 +static int qman_ctrl_init(void)
133150 +{
133151 + return platform_driver_register(&of_fsl_qman_driver);
133152 +}
133153 +
133154 +static void qman_ctrl_exit(void)
133155 +{
133156 + platform_driver_unregister(&of_fsl_qman_driver);
133157 +}
133158 +
133159 +module_init(qman_ctrl_init);
133160 +module_exit(qman_ctrl_exit);
133161 +
133162 +#endif /* CONFIG_SYSFS */
133163 --- /dev/null
133164 +++ b/drivers/staging/fsl_qbman/qman_debugfs.c
133165 @@ -0,0 +1,1594 @@
133166 +/* Copyright 2010-2011 Freescale Semiconductor, Inc.
133167 + *
133168 + * Redistribution and use in source and binary forms, with or without
133169 + * modification, are permitted provided that the following conditions are met:
133170 + * * Redistributions of source code must retain the above copyright
133171 + * notice, this list of conditions and the following disclaimer.
133172 + * * Redistributions in binary form must reproduce the above copyright
133173 + * notice, this list of conditions and the following disclaimer in the
133174 + * documentation and/or other materials provided with the distribution.
133175 + * * Neither the name of Freescale Semiconductor nor the
133176 + * names of its contributors may be used to endorse or promote products
133177 + * derived from this software without specific prior written permission.
133178 + *
133179 + *
133180 + * ALTERNATIVELY, this software may be distributed under the terms of the
133181 + * GNU General Public License ("GPL") as published by the Free Software
133182 + * Foundation, either version 2 of that License or (at your option) any
133183 + * later version.
133184 + *
133185 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
133186 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
133187 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
133188 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
133189 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
133190 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
133191 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
133192 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
133193 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
133194 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
133195 + */
133196 +#include "qman_private.h"
133197 +
133198 +#define MAX_FQID (0x00ffffff)
133199 +#define QM_FQD_BLOCK_SIZE 64
133200 +#define QM_FQD_AR (0xC10)
133201 +
133202 +static u32 fqid_max;
133203 +static u64 qman_ccsr_start;
133204 +static u64 qman_ccsr_size;
133205 +
133206 +static const char * const state_txt[] = {
133207 + "Out of Service",
133208 + "Retired",
133209 + "Tentatively Scheduled",
133210 + "Truly Scheduled",
133211 + "Parked",
133212 + "Active, Active Held or Held Suspended",
133213 + "Unknown State 6",
133214 + "Unknown State 7",
133215 + NULL,
133216 +};
133217 +
133218 +static const u8 fqd_states[] = {
133219 + QM_MCR_NP_STATE_OOS, QM_MCR_NP_STATE_RETIRED, QM_MCR_NP_STATE_TEN_SCHED,
133220 + QM_MCR_NP_STATE_TRU_SCHED, QM_MCR_NP_STATE_PARKED,
133221 + QM_MCR_NP_STATE_ACTIVE};
133222 +
133223 +struct mask_to_text {
133224 + u16 mask;
133225 + const char *txt;
133226 +};
133227 +
133228 +struct mask_filter_s {
133229 + u16 mask;
133230 + u8 filter;
133231 +};
133232 +
133233 +static const struct mask_filter_s mask_filter[] = {
133234 + {QM_FQCTRL_PREFERINCACHE, 0},
133235 + {QM_FQCTRL_PREFERINCACHE, 1},
133236 + {QM_FQCTRL_HOLDACTIVE, 0},
133237 + {QM_FQCTRL_HOLDACTIVE, 1},
133238 + {QM_FQCTRL_AVOIDBLOCK, 0},
133239 + {QM_FQCTRL_AVOIDBLOCK, 1},
133240 + {QM_FQCTRL_FORCESFDR, 0},
133241 + {QM_FQCTRL_FORCESFDR, 1},
133242 + {QM_FQCTRL_CPCSTASH, 0},
133243 + {QM_FQCTRL_CPCSTASH, 1},
133244 + {QM_FQCTRL_CTXASTASHING, 0},
133245 + {QM_FQCTRL_CTXASTASHING, 1},
133246 + {QM_FQCTRL_ORP, 0},
133247 + {QM_FQCTRL_ORP, 1},
133248 + {QM_FQCTRL_TDE, 0},
133249 + {QM_FQCTRL_TDE, 1},
133250 + {QM_FQCTRL_CGE, 0},
133251 + {QM_FQCTRL_CGE, 1}
133252 +};
133253 +
133254 +static const struct mask_to_text fq_ctrl_text_list[] = {
133255 + {
133256 + .mask = QM_FQCTRL_PREFERINCACHE,
133257 + .txt = "Prefer in cache",
133258 + },
133259 + {
133260 + .mask = QM_FQCTRL_HOLDACTIVE,
133261 + .txt = "Hold active in portal",
133262 + },
133263 + {
133264 + .mask = QM_FQCTRL_AVOIDBLOCK,
133265 + .txt = "Avoid Blocking",
133266 + },
133267 + {
133268 + .mask = QM_FQCTRL_FORCESFDR,
133269 + .txt = "High-priority SFDRs",
133270 + },
133271 + {
133272 + .mask = QM_FQCTRL_CPCSTASH,
133273 + .txt = "CPC Stash Enable",
133274 + },
133275 + {
133276 + .mask = QM_FQCTRL_CTXASTASHING,
133277 + .txt = "Context-A stashing",
133278 + },
133279 + {
133280 + .mask = QM_FQCTRL_ORP,
133281 + .txt = "ORP Enable",
133282 + },
133283 + {
133284 + .mask = QM_FQCTRL_TDE,
133285 + .txt = "Tail-Drop Enable",
133286 + },
133287 + {
133288 + .mask = QM_FQCTRL_CGE,
133289 + .txt = "Congestion Group Enable",
133290 + },
133291 + {
133292 + .mask = 0,
133293 + .txt = NULL,
133294 + }
133295 +};
133296 +
133297 +static const char *get_fqd_ctrl_text(u16 mask)
133298 +{
133299 + int i = 0;
133300 +
133301 + while (fq_ctrl_text_list[i].txt != NULL) {
133302 + if (fq_ctrl_text_list[i].mask == mask)
133303 + return fq_ctrl_text_list[i].txt;
133304 + i++;
133305 + }
133306 + return NULL;
133307 +}
133308 +
133309 +static const struct mask_to_text stashing_text_list[] = {
133310 + {
133311 + .mask = QM_STASHING_EXCL_CTX,
133312 + .txt = "FQ Ctx Stash"
133313 + },
133314 + {
133315 + .mask = QM_STASHING_EXCL_DATA,
133316 + .txt = "Frame Data Stash",
133317 + },
133318 + {
133319 + .mask = QM_STASHING_EXCL_ANNOTATION,
133320 + .txt = "Frame Annotation Stash",
133321 + },
133322 + {
133323 + .mask = 0,
133324 + .txt = NULL,
133325 + },
133326 +};
133327 +
133328 +static int user_input_convert(const char __user *user_buf, size_t count,
133329 + unsigned long *val)
133330 +{
133331 + char buf[12];
133332 +
133333 + if (count > sizeof(buf) - 1)
133334 + return -EINVAL;
133335 + if (copy_from_user(buf, user_buf, count))
133336 + return -EFAULT;
133337 + buf[count] = '\0';
133338 + if (kstrtoul(buf, 0, val))
133339 + return -EINVAL;
133340 + return 0;
133341 +}
133342 +
133343 +struct line_buffer_fq {
133344 + u32 buf[8];
133345 + u32 buf_cnt;
133346 + int line_cnt;
133347 +};
133348 +
133349 +static void add_to_line_buffer(struct line_buffer_fq *line_buf, u32 fqid,
133350 + struct seq_file *file)
133351 +{
133352 + line_buf->buf[line_buf->buf_cnt] = fqid;
133353 + line_buf->buf_cnt++;
133354 + if (line_buf->buf_cnt == 8) {
133355 + /* Buffer is full, flush it */
133356 + if (line_buf->line_cnt != 0)
133357 + seq_puts(file, ",\n");
133358 + seq_printf(file, "0x%06x,0x%06x,0x%06x,0x%06x,0x%06x,"
133359 + "0x%06x,0x%06x,0x%06x",
133360 + line_buf->buf[0], line_buf->buf[1], line_buf->buf[2],
133361 + line_buf->buf[3], line_buf->buf[4], line_buf->buf[5],
133362 + line_buf->buf[6], line_buf->buf[7]);
133363 + line_buf->buf_cnt = 0;
133364 + line_buf->line_cnt++;
133365 + }
133366 +}
133367 +
133368 +static void flush_line_buffer(struct line_buffer_fq *line_buf,
133369 + struct seq_file *file)
133370 +{
133371 + if (line_buf->buf_cnt) {
133372 + int y = 0;
133373 + if (line_buf->line_cnt != 0)
133374 + seq_puts(file, ",\n");
133375 + while (y != line_buf->buf_cnt) {
133376 + if (y+1 == line_buf->buf_cnt)
133377 + seq_printf(file, "0x%06x", line_buf->buf[y]);
133378 + else
133379 + seq_printf(file, "0x%06x,", line_buf->buf[y]);
133380 + y++;
133381 + }
133382 + line_buf->line_cnt++;
133383 + }
133384 + if (line_buf->line_cnt)
133385 + seq_putc(file, '\n');
133386 +}
133387 +
133388 +static struct dentry *dfs_root; /* debugfs root directory */
133389 +
133390 +/*******************************************************************************
133391 + * Query Frame Queue Non Programmable Fields
133392 + ******************************************************************************/
133393 +struct query_fq_np_fields_data_s {
133394 + u32 fqid;
133395 +};
133396 +static struct query_fq_np_fields_data_s query_fq_np_fields_data = {
133397 + .fqid = 1,
133398 +};
133399 +
133400 +static int query_fq_np_fields_show(struct seq_file *file, void *offset)
133401 +{
133402 + int ret;
133403 + struct qm_mcr_queryfq_np np;
133404 + struct qman_fq fq;
133405 +
133406 + fq.fqid = query_fq_np_fields_data.fqid;
133407 + ret = qman_query_fq_np(&fq, &np);
133408 + if (ret)
133409 + return ret;
133410 + /* Print state */
133411 + seq_printf(file, "Query FQ Non Programmable Fields Result fqid 0x%x\n",
133412 + fq.fqid);
133413 + seq_printf(file, " force eligible pending: %s\n",
133414 + (np.state & QM_MCR_NP_STATE_FE) ? "yes" : "no");
133415 + seq_printf(file, " retirement pending: %s\n",
133416 + (np.state & QM_MCR_NP_STATE_R) ? "yes" : "no");
133417 + seq_printf(file, " state: %s\n",
133418 + state_txt[np.state & QM_MCR_NP_STATE_MASK]);
133419 + seq_printf(file, " fq_link: 0x%x\n", np.fqd_link);
133420 + seq_printf(file, " odp_seq: %u\n", np.odp_seq);
133421 + seq_printf(file, " orp_nesn: %u\n", np.orp_nesn);
133422 + seq_printf(file, " orp_ea_hseq: %u\n", np.orp_ea_hseq);
133423 + seq_printf(file, " orp_ea_tseq: %u\n", np.orp_ea_tseq);
133424 + seq_printf(file, " orp_ea_hptr: 0x%x\n", np.orp_ea_hptr);
133425 + seq_printf(file, " orp_ea_tptr: 0x%x\n", np.orp_ea_tptr);
133426 + seq_printf(file, " pfdr_hptr: 0x%x\n", np.pfdr_hptr);
133427 + seq_printf(file, " pfdr_tptr: 0x%x\n", np.pfdr_tptr);
133428 + seq_printf(file, " is: ics_surp contains a %s\n",
133429 + (np.is) ? "deficit" : "surplus");
133430 + seq_printf(file, " ics_surp: %u\n", np.ics_surp);
133431 + seq_printf(file, " byte_cnt: %u\n", np.byte_cnt);
133432 + seq_printf(file, " frm_cnt: %u\n", np.frm_cnt);
133433 + seq_printf(file, " ra1_sfdr: 0x%x\n", np.ra1_sfdr);
133434 + seq_printf(file, " ra2_sfdr: 0x%x\n", np.ra2_sfdr);
133435 + seq_printf(file, " od1_sfdr: 0x%x\n", np.od1_sfdr);
133436 + seq_printf(file, " od2_sfdr: 0x%x\n", np.od2_sfdr);
133437 + seq_printf(file, " od3_sfdr: 0x%x\n", np.od3_sfdr);
133438 + return 0;
133439 +}
133440 +
133441 +static int query_fq_np_fields_open(struct inode *inode,
133442 + struct file *file)
133443 +{
133444 + return single_open(file, query_fq_np_fields_show, NULL);
133445 +}
133446 +
133447 +static ssize_t query_fq_np_fields_write(struct file *f,
133448 + const char __user *buf, size_t count, loff_t *off)
133449 +{
133450 + int ret;
133451 + unsigned long val;
133452 +
133453 + ret = user_input_convert(buf, count, &val);
133454 + if (ret)
133455 + return ret;
133456 + if (val > MAX_FQID)
133457 + return -EINVAL;
133458 + query_fq_np_fields_data.fqid = (u32)val;
133459 + return count;
133460 +}
133461 +
133462 +static const struct file_operations query_fq_np_fields_fops = {
133463 + .owner = THIS_MODULE,
133464 + .open = query_fq_np_fields_open,
133465 + .read = seq_read,
133466 + .write = query_fq_np_fields_write,
133467 + .release = single_release,
133468 +};
133469 +
133470 +/*******************************************************************************
133471 + * Frame Queue Programmable Fields
133472 + ******************************************************************************/
133473 +struct query_fq_fields_data_s {
133474 + u32 fqid;
133475 +};
133476 +
133477 +static struct query_fq_fields_data_s query_fq_fields_data = {
133478 + .fqid = 1,
133479 +};
133480 +
133481 +static int query_fq_fields_show(struct seq_file *file, void *offset)
133482 +{
133483 + int ret;
133484 + struct qm_fqd fqd;
133485 + struct qman_fq fq;
133486 + int i = 0;
133487 +
133488 + memset(&fqd, 0, sizeof(struct qm_fqd));
133489 + fq.fqid = query_fq_fields_data.fqid;
133490 + ret = qman_query_fq(&fq, &fqd);
133491 + if (ret)
133492 + return ret;
133493 + seq_printf(file, "Query FQ Programmable Fields Result fqid 0x%x\n",
133494 + fq.fqid);
133495 + seq_printf(file, " orprws: %u\n", fqd.orprws);
133496 + seq_printf(file, " oa: %u\n", fqd.oa);
133497 + seq_printf(file, " olws: %u\n", fqd.olws);
133498 +
133499 + seq_printf(file, " cgid: %u\n", fqd.cgid);
133500 +
133501 + if ((fqd.fq_ctrl & QM_FQCTRL_MASK) == 0)
133502 + seq_puts(file, " fq_ctrl: None\n");
133503 + else {
133504 + i = 0;
133505 + seq_puts(file, " fq_ctrl:\n");
133506 + while (fq_ctrl_text_list[i].txt != NULL) {
133507 + if ((fqd.fq_ctrl & QM_FQCTRL_MASK) &
133508 + fq_ctrl_text_list[i].mask)
133509 + seq_printf(file, " %s\n",
133510 + fq_ctrl_text_list[i].txt);
133511 + i++;
133512 + }
133513 + }
133514 + seq_printf(file, " dest_channel: %u\n", fqd.dest.channel);
133515 + seq_printf(file, " dest_wq: %u\n", fqd.dest.wq);
133516 + seq_printf(file, " ics_cred: %u\n", fqd.ics_cred);
133517 + seq_printf(file, " td_mant: %u\n", fqd.td.mant);
133518 + seq_printf(file, " td_exp: %u\n", fqd.td.exp);
133519 +
133520 + seq_printf(file, " ctx_b: 0x%x\n", fqd.context_b);
133521 +
133522 + seq_printf(file, " ctx_a: 0x%llx\n", qm_fqd_stashing_get64(&fqd));
133523 + /* Any stashing configured */
133524 + if ((fqd.context_a.stashing.exclusive & 0x7) == 0)
133525 + seq_puts(file, " ctx_a_stash_exclusive: None\n");
133526 + else {
133527 + seq_puts(file, " ctx_a_stash_exclusive:\n");
133528 + i = 0;
133529 + while (stashing_text_list[i].txt != NULL) {
133530 + if ((fqd.fq_ctrl & 0x7) & stashing_text_list[i].mask)
133531 + seq_printf(file, " %s\n",
133532 + stashing_text_list[i].txt);
133533 + i++;
133534 + }
133535 + }
133536 + seq_printf(file, " ctx_a_stash_annotation_cl: %u\n",
133537 + fqd.context_a.stashing.annotation_cl);
133538 + seq_printf(file, " ctx_a_stash_data_cl: %u\n",
133539 + fqd.context_a.stashing.data_cl);
133540 + seq_printf(file, " ctx_a_stash_context_cl: %u\n",
133541 + fqd.context_a.stashing.context_cl);
133542 + return 0;
133543 +}
133544 +
133545 +static int query_fq_fields_open(struct inode *inode,
133546 + struct file *file)
133547 +{
133548 + return single_open(file, query_fq_fields_show, NULL);
133549 +}
133550 +
133551 +static ssize_t query_fq_fields_write(struct file *f,
133552 + const char __user *buf, size_t count, loff_t *off)
133553 +{
133554 + int ret;
133555 + unsigned long val;
133556 +
133557 + ret = user_input_convert(buf, count, &val);
133558 + if (ret)
133559 + return ret;
133560 + if (val > MAX_FQID)
133561 + return -EINVAL;
133562 + query_fq_fields_data.fqid = (u32)val;
133563 + return count;
133564 +}
133565 +
133566 +static const struct file_operations query_fq_fields_fops = {
133567 + .owner = THIS_MODULE,
133568 + .open = query_fq_fields_open,
133569 + .read = seq_read,
133570 + .write = query_fq_fields_write,
133571 + .release = single_release,
133572 +};
133573 +
133574 +/*******************************************************************************
133575 + * Query WQ lengths
133576 + ******************************************************************************/
133577 +struct query_wq_lengths_data_s {
133578 + union {
133579 + u16 channel_wq; /* ignores wq (3 lsbits) */
133580 + struct {
133581 + u16 id:13; /* qm_channel */
133582 + u16 __reserved:3;
133583 + } __packed channel;
133584 + };
133585 +};
133586 +static struct query_wq_lengths_data_s query_wq_lengths_data;
133587 +static int query_wq_lengths_show(struct seq_file *file, void *offset)
133588 +{
133589 + int ret;
133590 + struct qm_mcr_querywq wq;
133591 + int i;
133592 +
133593 + memset(&wq, 0, sizeof(struct qm_mcr_querywq));
133594 + wq.channel.id = query_wq_lengths_data.channel.id;
133595 + ret = qman_query_wq(0, &wq);
133596 + if (ret)
133597 + return ret;
133598 + seq_printf(file, "Query Result For Channel: 0x%x\n", wq.channel.id);
133599 + for (i = 0; i < 8; i++)
133600 + /* mask out upper 4 bits since they are not part of length */
133601 + seq_printf(file, " wq%d_len : %u\n", i, wq.wq_len[i] & 0x0fff);
133602 + return 0;
133603 +}
133604 +
133605 +static int query_wq_lengths_open(struct inode *inode,
133606 + struct file *file)
133607 +{
133608 + return single_open(file, query_wq_lengths_show, NULL);
133609 +}
133610 +
133611 +static ssize_t query_wq_lengths_write(struct file *f,
133612 + const char __user *buf, size_t count, loff_t *off)
133613 +{
133614 + int ret;
133615 + unsigned long val;
133616 +
133617 + ret = user_input_convert(buf, count, &val);
133618 + if (ret)
133619 + return ret;
133620 + if (val > 0xfff8)
133621 + return -EINVAL;
133622 + query_wq_lengths_data.channel.id = (u16)val;
133623 + return count;
133624 +}
133625 +
133626 +static const struct file_operations query_wq_lengths_fops = {
133627 + .owner = THIS_MODULE,
133628 + .open = query_wq_lengths_open,
133629 + .read = seq_read,
133630 + .write = query_wq_lengths_write,
133631 + .release = single_release,
133632 +};
133633 +
133634 +/*******************************************************************************
133635 + * Query CGR
133636 + ******************************************************************************/
133637 +struct query_cgr_s {
133638 + u8 cgid;
133639 +};
133640 +static struct query_cgr_s query_cgr_data;
133641 +
133642 +static int query_cgr_show(struct seq_file *file, void *offset)
133643 +{
133644 + int ret;
133645 + struct qm_mcr_querycgr cgrd;
133646 + struct qman_cgr cgr;
133647 + int i, j;
133648 + u32 mask;
133649 +
133650 + memset(&cgr, 0, sizeof(cgr));
133651 + memset(&cgrd, 0, sizeof(cgrd));
133652 + cgr.cgrid = query_cgr_data.cgid;
133653 + ret = qman_query_cgr(&cgr, &cgrd);
133654 + if (ret)
133655 + return ret;
133656 + seq_printf(file, "Query CGR id 0x%x\n", cgr.cgrid);
133657 + seq_printf(file, " wr_parm_g MA: %u, Mn: %u, SA: %u, Sn: %u, Pn: %u\n",
133658 + cgrd.cgr.wr_parm_g.MA, cgrd.cgr.wr_parm_g.Mn,
133659 + cgrd.cgr.wr_parm_g.SA, cgrd.cgr.wr_parm_g.Sn,
133660 + cgrd.cgr.wr_parm_g.Pn);
133661 +
133662 + seq_printf(file, " wr_parm_y MA: %u, Mn: %u, SA: %u, Sn: %u, Pn: %u\n",
133663 + cgrd.cgr.wr_parm_y.MA, cgrd.cgr.wr_parm_y.Mn,
133664 + cgrd.cgr.wr_parm_y.SA, cgrd.cgr.wr_parm_y.Sn,
133665 + cgrd.cgr.wr_parm_y.Pn);
133666 +
133667 + seq_printf(file, " wr_parm_r MA: %u, Mn: %u, SA: %u, Sn: %u, Pn: %u\n",
133668 + cgrd.cgr.wr_parm_r.MA, cgrd.cgr.wr_parm_r.Mn,
133669 + cgrd.cgr.wr_parm_r.SA, cgrd.cgr.wr_parm_r.Sn,
133670 + cgrd.cgr.wr_parm_r.Pn);
133671 +
133672 + seq_printf(file, " wr_en_g: %u, wr_en_y: %u, we_en_r: %u\n",
133673 + cgrd.cgr.wr_en_g, cgrd.cgr.wr_en_y, cgrd.cgr.wr_en_r);
133674 +
133675 + seq_printf(file, " cscn_en: %u\n", cgrd.cgr.cscn_en);
133676 + if ((qman_ip_rev & 0xFF00) >= QMAN_REV30) {
133677 + seq_puts(file, " cscn_targ_dcp:\n");
133678 + mask = 0x80000000;
133679 + for (i = 0; i < 32; i++) {
133680 + if (cgrd.cgr.cscn_targ & mask)
133681 + seq_printf(file, " send CSCN to dcp %u\n",
133682 + (31 - i));
133683 + mask >>= 1;
133684 + }
133685 +
133686 + seq_puts(file, " cscn_targ_swp:\n");
133687 + for (i = 0; i < 4; i++) {
133688 + mask = 0x80000000;
133689 + for (j = 0; j < 32; j++) {
133690 + if (cgrd.cscn_targ_swp[i] & mask)
133691 + seq_printf(file, " send CSCN to swp"
133692 + " %u\n", (127 - (i * 32) - j));
133693 + mask >>= 1;
133694 + }
133695 + }
133696 + } else {
133697 + seq_printf(file, " cscn_targ: %u\n", cgrd.cgr.cscn_targ);
133698 + }
133699 + seq_printf(file, " cstd_en: %u\n", cgrd.cgr.cstd_en);
133700 + seq_printf(file, " cs: %u\n", cgrd.cgr.cs);
133701 +
133702 + seq_printf(file, " cs_thresh_TA: %u, cs_thresh_Tn: %u\n",
133703 + cgrd.cgr.cs_thres.TA, cgrd.cgr.cs_thres.Tn);
133704 +
133705 + seq_printf(file, " mode: %s\n",
133706 + (cgrd.cgr.mode & QMAN_CGR_MODE_FRAME) ?
133707 + "frame count" : "byte count");
133708 + seq_printf(file, " i_bcnt: %llu\n", qm_mcr_querycgr_i_get64(&cgrd));
133709 + seq_printf(file, " a_bcnt: %llu\n", qm_mcr_querycgr_a_get64(&cgrd));
133710 +
133711 + return 0;
133712 +}
133713 +
133714 +static int query_cgr_open(struct inode *inode, struct file *file)
133715 +{
133716 + return single_open(file, query_cgr_show, NULL);
133717 +}
133718 +
133719 +static ssize_t query_cgr_write(struct file *f, const char __user *buf,
133720 + size_t count, loff_t *off)
133721 +{
133722 + int ret;
133723 + unsigned long val;
133724 +
133725 + ret = user_input_convert(buf, count, &val);
133726 + if (ret)
133727 + return ret;
133728 + if (val > 0xff)
133729 + return -EINVAL;
133730 + query_cgr_data.cgid = (u8)val;
133731 + return count;
133732 +}
133733 +
133734 +static const struct file_operations query_cgr_fops = {
133735 + .owner = THIS_MODULE,
133736 + .open = query_cgr_open,
133737 + .read = seq_read,
133738 + .write = query_cgr_write,
133739 + .release = single_release,
133740 +};
133741 +
133742 +/*******************************************************************************
133743 + * Test Write CGR
133744 + ******************************************************************************/
133745 +struct test_write_cgr_s {
133746 + u64 i_bcnt;
133747 + u8 cgid;
133748 +};
133749 +static struct test_write_cgr_s test_write_cgr_data;
133750 +
133751 +static int testwrite_cgr_show(struct seq_file *file, void *offset)
133752 +{
133753 + int ret;
133754 + struct qm_mcr_cgrtestwrite result;
133755 + struct qman_cgr cgr;
133756 + u64 i_bcnt;
133757 +
133758 + memset(&cgr, 0, sizeof(struct qman_cgr));
133759 + memset(&result, 0, sizeof(struct qm_mcr_cgrtestwrite));
133760 + cgr.cgrid = test_write_cgr_data.cgid;
133761 + i_bcnt = test_write_cgr_data.i_bcnt;
133762 + ret = qman_testwrite_cgr(&cgr, i_bcnt, &result);
133763 + if (ret)
133764 + return ret;
133765 + seq_printf(file, "CGR Test Write CGR id 0x%x\n", cgr.cgrid);
133766 + seq_printf(file, " wr_parm_g MA: %u, Mn: %u, SA: %u, Sn: %u, Pn: %u\n",
133767 + result.cgr.wr_parm_g.MA, result.cgr.wr_parm_g.Mn,
133768 + result.cgr.wr_parm_g.SA, result.cgr.wr_parm_g.Sn,
133769 + result.cgr.wr_parm_g.Pn);
133770 + seq_printf(file, " wr_parm_y MA: %u, Mn: %u, SA: %u, Sn: %u, Pn: %u\n",
133771 + result.cgr.wr_parm_y.MA, result.cgr.wr_parm_y.Mn,
133772 + result.cgr.wr_parm_y.SA, result.cgr.wr_parm_y.Sn,
133773 + result.cgr.wr_parm_y.Pn);
133774 + seq_printf(file, " wr_parm_r MA: %u, Mn: %u, SA: %u, Sn: %u, Pn: %u\n",
133775 + result.cgr.wr_parm_r.MA, result.cgr.wr_parm_r.Mn,
133776 + result.cgr.wr_parm_r.SA, result.cgr.wr_parm_r.Sn,
133777 + result.cgr.wr_parm_r.Pn);
133778 + seq_printf(file, " wr_en_g: %u, wr_en_y: %u, we_en_r: %u\n",
133779 + result.cgr.wr_en_g, result.cgr.wr_en_y, result.cgr.wr_en_r);
133780 + seq_printf(file, " cscn_en: %u\n", result.cgr.cscn_en);
133781 + seq_printf(file, " cscn_targ: %u\n", result.cgr.cscn_targ);
133782 + seq_printf(file, " cstd_en: %u\n", result.cgr.cstd_en);
133783 + seq_printf(file, " cs: %u\n", result.cgr.cs);
133784 + seq_printf(file, " cs_thresh_TA: %u, cs_thresh_Tn: %u\n",
133785 + result.cgr.cs_thres.TA, result.cgr.cs_thres.Tn);
133786 +
133787 + /* Add Mode for Si 2 */
133788 + seq_printf(file, " mode: %s\n",
133789 + (result.cgr.mode & QMAN_CGR_MODE_FRAME) ?
133790 + "frame count" : "byte count");
133791 +
133792 + seq_printf(file, " i_bcnt: %llu\n",
133793 + qm_mcr_cgrtestwrite_i_get64(&result));
133794 + seq_printf(file, " a_bcnt: %llu\n",
133795 + qm_mcr_cgrtestwrite_a_get64(&result));
133796 + seq_printf(file, " wr_prob_g: %u\n", result.wr_prob_g);
133797 + seq_printf(file, " wr_prob_y: %u\n", result.wr_prob_y);
133798 + seq_printf(file, " wr_prob_r: %u\n", result.wr_prob_r);
133799 + return 0;
133800 +}
133801 +
133802 +static int testwrite_cgr_open(struct inode *inode, struct file *file)
133803 +{
133804 + return single_open(file, testwrite_cgr_show, NULL);
133805 +}
133806 +
133807 +static const struct file_operations testwrite_cgr_fops = {
133808 + .owner = THIS_MODULE,
133809 + .open = testwrite_cgr_open,
133810 + .read = seq_read,
133811 + .release = single_release,
133812 +};
133813 +
133814 +
133815 +static int testwrite_cgr_ibcnt_show(struct seq_file *file, void *offset)
133816 +{
133817 + seq_printf(file, "i_bcnt: %llu\n", test_write_cgr_data.i_bcnt);
133818 + return 0;
133819 +}
133820 +static int testwrite_cgr_ibcnt_open(struct inode *inode, struct file *file)
133821 +{
133822 + return single_open(file, testwrite_cgr_ibcnt_show, NULL);
133823 +}
133824 +
133825 +static ssize_t testwrite_cgr_ibcnt_write(struct file *f, const char __user *buf,
133826 + size_t count, loff_t *off)
133827 +{
133828 + int ret;
133829 + unsigned long val;
133830 +
133831 + ret = user_input_convert(buf, count, &val);
133832 + if (ret)
133833 + return ret;
133834 + test_write_cgr_data.i_bcnt = val;
133835 + return count;
133836 +}
133837 +
133838 +static const struct file_operations teswrite_cgr_ibcnt_fops = {
133839 + .owner = THIS_MODULE,
133840 + .open = testwrite_cgr_ibcnt_open,
133841 + .read = seq_read,
133842 + .write = testwrite_cgr_ibcnt_write,
133843 + .release = single_release,
133844 +};
133845 +
133846 +static int testwrite_cgr_cgrid_show(struct seq_file *file, void *offset)
133847 +{
133848 + seq_printf(file, "cgrid: %u\n", (u32)test_write_cgr_data.cgid);
133849 + return 0;
133850 +}
133851 +static int testwrite_cgr_cgrid_open(struct inode *inode, struct file *file)
133852 +{
133853 + return single_open(file, testwrite_cgr_cgrid_show, NULL);
133854 +}
133855 +
133856 +static ssize_t testwrite_cgr_cgrid_write(struct file *f, const char __user *buf,
133857 + size_t count, loff_t *off)
133858 +{
133859 + int ret;
133860 + unsigned long val;
133861 +
133862 + ret = user_input_convert(buf, count, &val);
133863 + if (ret)
133864 + return ret;
133865 + if (val > 0xff)
133866 + return -EINVAL;
133867 + test_write_cgr_data.cgid = (u8)val;
133868 + return count;
133869 +}
133870 +
133871 +static const struct file_operations teswrite_cgr_cgrid_fops = {
133872 + .owner = THIS_MODULE,
133873 + .open = testwrite_cgr_cgrid_open,
133874 + .read = seq_read,
133875 + .write = testwrite_cgr_cgrid_write,
133876 + .release = single_release,
133877 +};
133878 +
133879 +/*******************************************************************************
133880 + * Query Congestion State
133881 + ******************************************************************************/
133882 +static int query_congestion_show(struct seq_file *file, void *offset)
133883 +{
133884 + int ret;
133885 + struct qm_mcr_querycongestion cs;
133886 + int i, j, in_cong = 0;
133887 + u32 mask;
133888 +
133889 + memset(&cs, 0, sizeof(struct qm_mcr_querycongestion));
133890 + ret = qman_query_congestion(&cs);
133891 + if (ret)
133892 + return ret;
133893 + seq_puts(file, "Query Congestion Result\n");
133894 + for (i = 0; i < 8; i++) {
133895 + mask = 0x80000000;
133896 + for (j = 0; j < 32; j++) {
133897 + if (cs.state.__state[i] & mask) {
133898 + in_cong = 1;
133899 + seq_printf(file, " cg %u: %s\n", (i*32)+j,
133900 + "in congestion");
133901 + }
133902 + mask >>= 1;
133903 + }
133904 + }
133905 + if (!in_cong)
133906 + seq_puts(file, " All congestion groups not congested.\n");
133907 + return 0;
133908 +}
133909 +
133910 +static int query_congestion_open(struct inode *inode, struct file *file)
133911 +{
133912 + return single_open(file, query_congestion_show, NULL);
133913 +}
133914 +
133915 +static const struct file_operations query_congestion_fops = {
133916 + .owner = THIS_MODULE,
133917 + .open = query_congestion_open,
133918 + .read = seq_read,
133919 + .release = single_release,
133920 +};
133921 +
133922 +/*******************************************************************************
133923 + * Query CCGR
133924 + ******************************************************************************/
133925 +struct query_ccgr_s {
133926 + u32 ccgid;
133927 +};
133928 +static struct query_ccgr_s query_ccgr_data;
133929 +
133930 +static int query_ccgr_show(struct seq_file *file, void *offset)
133931 +{
133932 + int ret;
133933 + struct qm_mcr_ceetm_ccgr_query ccgr_query;
133934 + struct qm_mcc_ceetm_ccgr_query query_opts;
133935 + int i, j;
133936 + u32 mask;
133937 +
133938 + memset(&ccgr_query, 0, sizeof(struct qm_mcr_ceetm_ccgr_query));
133939 + memset(&query_opts, 0, sizeof(struct qm_mcc_ceetm_ccgr_query));
133940 +
133941 + if ((qman_ip_rev & 0xFF00) < QMAN_REV30)
133942 + return -EINVAL;
133943 +
133944 + seq_printf(file, "Query CCGID %x\n", query_ccgr_data.ccgid);
133945 + query_opts.dcpid = ((query_ccgr_data.ccgid & 0xFF000000) >> 24);
133946 + query_opts.ccgrid = query_ccgr_data.ccgid & 0x000001FF;
133947 + ret = qman_ceetm_query_ccgr(&query_opts, &ccgr_query);
133948 + if (ret)
133949 + return ret;
133950 + seq_printf(file, "Query CCGR id %x in DCP %d\n", query_opts.ccgrid,
133951 + query_opts.dcpid);
133952 + seq_printf(file, " wr_parm_g MA: %u, Mn: %u, SA: %u, Sn: %u, Pn: %u\n",
133953 + ccgr_query.cm_query.wr_parm_g.MA,
133954 + ccgr_query.cm_query.wr_parm_g.Mn,
133955 + ccgr_query.cm_query.wr_parm_g.SA,
133956 + ccgr_query.cm_query.wr_parm_g.Sn,
133957 + ccgr_query.cm_query.wr_parm_g.Pn);
133958 +
133959 + seq_printf(file, " wr_parm_y MA: %u, Mn: %u, SA: %u, Sn: %u, Pn: %u\n",
133960 + ccgr_query.cm_query.wr_parm_y.MA,
133961 + ccgr_query.cm_query.wr_parm_y.Mn,
133962 + ccgr_query.cm_query.wr_parm_y.SA,
133963 + ccgr_query.cm_query.wr_parm_y.Sn,
133964 + ccgr_query.cm_query.wr_parm_y.Pn);
133965 +
133966 + seq_printf(file, " wr_parm_r MA: %u, Mn: %u, SA: %u, Sn: %u, Pn: %u\n",
133967 + ccgr_query.cm_query.wr_parm_r.MA,
133968 + ccgr_query.cm_query.wr_parm_r.Mn,
133969 + ccgr_query.cm_query.wr_parm_r.SA,
133970 + ccgr_query.cm_query.wr_parm_r.Sn,
133971 + ccgr_query.cm_query.wr_parm_r.Pn);
133972 +
133973 + seq_printf(file, " wr_en_g: %u, wr_en_y: %u, we_en_r: %u\n",
133974 + ccgr_query.cm_query.ctl_wr_en_g,
133975 + ccgr_query.cm_query.ctl_wr_en_y,
133976 + ccgr_query.cm_query.ctl_wr_en_r);
133977 +
133978 + seq_printf(file, " cscn_en: %u\n", ccgr_query.cm_query.ctl_cscn_en);
133979 + seq_puts(file, " cscn_targ_dcp:\n");
133980 + mask = 0x80000000;
133981 + for (i = 0; i < 32; i++) {
133982 + if (ccgr_query.cm_query.cscn_targ_dcp & mask)
133983 + seq_printf(file, " send CSCN to dcp %u\n", (31 - i));
133984 + mask >>= 1;
133985 + }
133986 +
133987 + seq_puts(file, " cscn_targ_swp:\n");
133988 + for (i = 0; i < 4; i++) {
133989 + mask = 0x80000000;
133990 + for (j = 0; j < 32; j++) {
133991 + if (ccgr_query.cm_query.cscn_targ_swp[i] & mask)
133992 + seq_printf(file, " send CSCN to swp"
133993 + "%u\n", (127 - (i * 32) - j));
133994 + mask >>= 1;
133995 + }
133996 + }
133997 +
133998 + seq_printf(file, " td_en: %u\n", ccgr_query.cm_query.ctl_td_en);
133999 +
134000 + seq_printf(file, " cs_thresh_in_TA: %u, cs_thresh_in_Tn: %u\n",
134001 + ccgr_query.cm_query.cs_thres.TA,
134002 + ccgr_query.cm_query.cs_thres.Tn);
134003 +
134004 + seq_printf(file, " cs_thresh_out_TA: %u, cs_thresh_out_Tn: %u\n",
134005 + ccgr_query.cm_query.cs_thres_x.TA,
134006 + ccgr_query.cm_query.cs_thres_x.Tn);
134007 +
134008 + seq_printf(file, " td_thresh_TA: %u, td_thresh_Tn: %u\n",
134009 + ccgr_query.cm_query.td_thres.TA,
134010 + ccgr_query.cm_query.td_thres.Tn);
134011 +
134012 + seq_printf(file, " mode: %s\n",
134013 + (ccgr_query.cm_query.ctl_mode &
134014 + QMAN_CGR_MODE_FRAME) ?
134015 + "frame count" : "byte count");
134016 + seq_printf(file, " i_cnt: %llu\n", (u64)ccgr_query.cm_query.i_cnt);
134017 + seq_printf(file, " a_cnt: %llu\n", (u64)ccgr_query.cm_query.a_cnt);
134018 +
134019 + return 0;
134020 +}
134021 +
134022 +static int query_ccgr_open(struct inode *inode, struct file *file)
134023 +{
134024 + return single_open(file, query_ccgr_show, NULL);
134025 +}
134026 +
134027 +static ssize_t query_ccgr_write(struct file *f, const char __user *buf,
134028 + size_t count, loff_t *off)
134029 +{
134030 + int ret;
134031 + unsigned long val;
134032 +
134033 + ret = user_input_convert(buf, count, &val);
134034 + if (ret)
134035 + return ret;
134036 + query_ccgr_data.ccgid = val;
134037 + return count;
134038 +}
134039 +
134040 +static const struct file_operations query_ccgr_fops = {
134041 + .owner = THIS_MODULE,
134042 + .open = query_ccgr_open,
134043 + .read = seq_read,
134044 + .write = query_ccgr_write,
134045 + .release = single_release,
134046 +};
134047 +/*******************************************************************************
134048 + * QMan register
134049 + ******************************************************************************/
134050 +struct qman_register_s {
134051 + u32 val;
134052 +};
134053 +static struct qman_register_s qman_register_data;
134054 +
134055 +static void init_ccsrmempeek(void)
134056 +{
134057 + struct device_node *dn;
134058 + const u32 *regaddr_p;
134059 +
134060 + dn = of_find_compatible_node(NULL, NULL, "fsl,qman");
134061 + if (!dn) {
134062 + pr_info("No fsl,qman node\n");
134063 + return;
134064 + }
134065 + regaddr_p = of_get_address(dn, 0, &qman_ccsr_size, NULL);
134066 + if (!regaddr_p) {
134067 + of_node_put(dn);
134068 + return;
134069 + }
134070 + qman_ccsr_start = of_translate_address(dn, regaddr_p);
134071 + of_node_put(dn);
134072 +}
134073 +/* This function provides access to QMan ccsr memory map */
134074 +static int qman_ccsrmempeek(u32 *val, u32 offset)
134075 +{
134076 + void __iomem *addr;
134077 + u64 phys_addr;
134078 +
134079 + if (!qman_ccsr_start)
134080 + return -EINVAL;
134081 +
134082 + if (offset > (qman_ccsr_size - sizeof(u32)))
134083 + return -EINVAL;
134084 +
134085 + phys_addr = qman_ccsr_start + offset;
134086 + addr = ioremap(phys_addr, sizeof(u32));
134087 + if (!addr) {
134088 + pr_err("ccsrmempeek, ioremap failed\n");
134089 + return -EINVAL;
134090 + }
134091 + *val = in_be32(addr);
134092 + iounmap(addr);
134093 + return 0;
134094 +}
134095 +
134096 +static int qman_ccsrmempeek_show(struct seq_file *file, void *offset)
134097 +{
134098 + u32 b;
134099 +
134100 + qman_ccsrmempeek(&b, qman_register_data.val);
134101 + seq_printf(file, "QMan register offset = 0x%x\n",
134102 + qman_register_data.val);
134103 + seq_printf(file, "value = 0x%08x\n", b);
134104 +
134105 + return 0;
134106 +}
134107 +
134108 +static int qman_ccsrmempeek_open(struct inode *inode, struct file *file)
134109 +{
134110 + return single_open(file, qman_ccsrmempeek_show, NULL);
134111 +}
134112 +
134113 +static ssize_t qman_ccsrmempeek_write(struct file *f, const char __user *buf,
134114 + size_t count, loff_t *off)
134115 +{
134116 + int ret;
134117 + unsigned long val;
134118 +
134119 + ret = user_input_convert(buf, count, &val);
134120 + if (ret)
134121 + return ret;
134122 + /* multiple of 4 */
134123 + if (val > (qman_ccsr_size - sizeof(u32))) {
134124 + pr_info("Input 0x%lx > 0x%llx\n",
134125 + val, (qman_ccsr_size - sizeof(u32)));
134126 + return -EINVAL;
134127 + }
134128 + if (val & 0x3) {
134129 + pr_info("Input 0x%lx not multiple of 4\n", val);
134130 + return -EINVAL;
134131 + }
134132 + qman_register_data.val = val;
134133 + return count;
134134 +}
134135 +
134136 +static const struct file_operations qman_ccsrmempeek_fops = {
134137 + .owner = THIS_MODULE,
134138 + .open = qman_ccsrmempeek_open,
134139 + .read = seq_read,
134140 + .write = qman_ccsrmempeek_write,
134141 +};
134142 +
134143 +/*******************************************************************************
134144 + * QMan state
134145 + ******************************************************************************/
134146 +static int qman_fqd_state_show(struct seq_file *file, void *offset)
134147 +{
134148 + struct qm_mcr_queryfq_np np;
134149 + struct qman_fq fq;
134150 + struct line_buffer_fq line_buf;
134151 + int ret, i;
134152 + u8 *state = file->private;
134153 + u32 qm_fq_state_cnt[ARRAY_SIZE(fqd_states)];
134154 +
134155 + memset(qm_fq_state_cnt, 0, sizeof(qm_fq_state_cnt));
134156 + memset(&line_buf, 0, sizeof(line_buf));
134157 +
134158 + seq_printf(file, "List of fq ids in state: %s\n", state_txt[*state]);
134159 +
134160 + for (i = 1; i < fqid_max; i++) {
134161 + fq.fqid = i;
134162 + ret = qman_query_fq_np(&fq, &np);
134163 + if (ret)
134164 + return ret;
134165 + if (*state == (np.state & QM_MCR_NP_STATE_MASK))
134166 + add_to_line_buffer(&line_buf, fq.fqid, file);
134167 + /* Keep a summary count of all states */
134168 + if ((np.state & QM_MCR_NP_STATE_MASK) < ARRAY_SIZE(fqd_states))
134169 + qm_fq_state_cnt[(np.state & QM_MCR_NP_STATE_MASK)]++;
134170 + }
134171 + flush_line_buffer(&line_buf, file);
134172 +
134173 + for (i = 0; i < ARRAY_SIZE(fqd_states); i++) {
134174 + seq_printf(file, "%s count = %u\n", state_txt[i],
134175 + qm_fq_state_cnt[i]);
134176 + }
134177 + return 0;
134178 +}
134179 +
134180 +static int qman_fqd_state_open(struct inode *inode, struct file *file)
134181 +{
134182 + return single_open(file, qman_fqd_state_show, inode->i_private);
134183 +}
134184 +
134185 +static const struct file_operations qman_fqd_state_fops = {
134186 + .owner = THIS_MODULE,
134187 + .open = qman_fqd_state_open,
134188 + .read = seq_read,
134189 +};
134190 +
134191 +static int qman_fqd_ctrl_show(struct seq_file *file, void *offset)
134192 +{
134193 + struct qm_fqd fqd;
134194 + struct qman_fq fq;
134195 + u32 fq_en_cnt = 0, fq_di_cnt = 0;
134196 + int ret, i;
134197 + struct mask_filter_s *data = file->private;
134198 + const char *ctrl_txt = get_fqd_ctrl_text(data->mask);
134199 + struct line_buffer_fq line_buf;
134200 +
134201 + memset(&line_buf, 0, sizeof(line_buf));
134202 + seq_printf(file, "List of fq ids with: %s :%s\n",
134203 + ctrl_txt, (data->filter) ? "enabled" : "disabled");
134204 + for (i = 1; i < fqid_max; i++) {
134205 + fq.fqid = i;
134206 + memset(&fqd, 0, sizeof(struct qm_fqd));
134207 + ret = qman_query_fq(&fq, &fqd);
134208 + if (ret)
134209 + return ret;
134210 + if (data->filter) {
134211 + if (fqd.fq_ctrl & data->mask)
134212 + add_to_line_buffer(&line_buf, fq.fqid, file);
134213 + } else {
134214 + if (!(fqd.fq_ctrl & data->mask))
134215 + add_to_line_buffer(&line_buf, fq.fqid, file);
134216 + }
134217 + if (fqd.fq_ctrl & data->mask)
134218 + fq_en_cnt++;
134219 + else
134220 + fq_di_cnt++;
134221 + }
134222 + flush_line_buffer(&line_buf, file);
134223 +
134224 + seq_printf(file, "Total FQD with: %s : enabled = %u\n",
134225 + ctrl_txt, fq_en_cnt);
134226 + seq_printf(file, "Total FQD with: %s : disabled = %u\n",
134227 + ctrl_txt, fq_di_cnt);
134228 + return 0;
134229 +}
134230 +
134231 +/*******************************************************************************
134232 + * QMan ctrl CGE, TDE, ORP, CTX, CPC, SFDR, BLOCK, HOLD, CACHE
134233 + ******************************************************************************/
134234 +static int qman_fqd_ctrl_open(struct inode *inode, struct file *file)
134235 +{
134236 + return single_open(file, qman_fqd_ctrl_show, inode->i_private);
134237 +}
134238 +
134239 +static const struct file_operations qman_fqd_ctrl_fops = {
134240 + .owner = THIS_MODULE,
134241 + .open = qman_fqd_ctrl_open,
134242 + .read = seq_read,
134243 +};
134244 +
134245 +/*******************************************************************************
134246 + * QMan ctrl summary
134247 + ******************************************************************************/
134248 +/*******************************************************************************
134249 + * QMan summary state
134250 + ******************************************************************************/
134251 +static int qman_fqd_non_prog_summary_show(struct seq_file *file, void *offset)
134252 +{
134253 + struct qm_mcr_queryfq_np np;
134254 + struct qman_fq fq;
134255 + int ret, i;
134256 + u32 qm_fq_state_cnt[ARRAY_SIZE(fqd_states)];
134257 +
134258 + memset(qm_fq_state_cnt, 0, sizeof(qm_fq_state_cnt));
134259 +
134260 + for (i = 1; i < fqid_max; i++) {
134261 + fq.fqid = i;
134262 + ret = qman_query_fq_np(&fq, &np);
134263 + if (ret)
134264 + return ret;
134265 + /* Keep a summary count of all states */
134266 + if ((np.state & QM_MCR_NP_STATE_MASK) < ARRAY_SIZE(fqd_states))
134267 + qm_fq_state_cnt[(np.state & QM_MCR_NP_STATE_MASK)]++;
134268 + }
134269 +
134270 + for (i = 0; i < ARRAY_SIZE(fqd_states); i++) {
134271 + seq_printf(file, "%s count = %u\n", state_txt[i],
134272 + qm_fq_state_cnt[i]);
134273 + }
134274 + return 0;
134275 +}
134276 +
134277 +static int qman_fqd_prog_summary_show(struct seq_file *file, void *offset)
134278 +{
134279 + struct qm_fqd fqd;
134280 + struct qman_fq fq;
134281 + int ret, i , j;
134282 + u32 qm_prog_cnt[ARRAY_SIZE(mask_filter)/2];
134283 +
134284 + memset(qm_prog_cnt, 0, sizeof(qm_prog_cnt));
134285 +
134286 + for (i = 1; i < fqid_max; i++) {
134287 + memset(&fqd, 0, sizeof(struct qm_fqd));
134288 + fq.fqid = i;
134289 + ret = qman_query_fq(&fq, &fqd);
134290 + if (ret)
134291 + return ret;
134292 + /* Keep a summary count of all states */
134293 + for (j = 0; j < ARRAY_SIZE(mask_filter); j += 2)
134294 + if ((fqd.fq_ctrl & QM_FQCTRL_MASK) &
134295 + mask_filter[j].mask)
134296 + qm_prog_cnt[j/2]++;
134297 + }
134298 + for (i = 0; i < ARRAY_SIZE(mask_filter) / 2; i++) {
134299 + seq_printf(file, "%s count = %u\n",
134300 + get_fqd_ctrl_text(mask_filter[i*2].mask),
134301 + qm_prog_cnt[i]);
134302 + }
134303 + return 0;
134304 +}
134305 +
134306 +static int qman_fqd_summary_show(struct seq_file *file, void *offset)
134307 +{
134308 + int ret;
134309 +
134310 + /* Display summary of non programmable fields */
134311 + ret = qman_fqd_non_prog_summary_show(file, offset);
134312 + if (ret)
134313 + return ret;
134314 + seq_puts(file, "-----------------------------------------\n");
134315 + /* Display programmable fields */
134316 + ret = qman_fqd_prog_summary_show(file, offset);
134317 + if (ret)
134318 + return ret;
134319 + return 0;
134320 +}
134321 +
134322 +static int qman_fqd_summary_open(struct inode *inode, struct file *file)
134323 +{
134324 + return single_open(file, qman_fqd_summary_show, NULL);
134325 +}
134326 +
134327 +static const struct file_operations qman_fqd_summary_fops = {
134328 + .owner = THIS_MODULE,
134329 + .open = qman_fqd_summary_open,
134330 + .read = seq_read,
134331 +};
134332 +
134333 +/*******************************************************************************
134334 + * QMan destination work queue
134335 + ******************************************************************************/
134336 +struct qman_dest_wq_s {
134337 + u16 wq_id;
134338 +};
134339 +static struct qman_dest_wq_s qman_dest_wq_data = {
134340 + .wq_id = 0,
134341 +};
134342 +
134343 +static int qman_fqd_dest_wq_show(struct seq_file *file, void *offset)
134344 +{
134345 + struct qm_fqd fqd;
134346 + struct qman_fq fq;
134347 + int ret, i;
134348 + u16 *wq, wq_id = qman_dest_wq_data.wq_id;
134349 + struct line_buffer_fq line_buf;
134350 +
134351 + memset(&line_buf, 0, sizeof(line_buf));
134352 + /* use vmalloc : need to allocate large memory region and don't
134353 + * require the memory to be physically contiguous. */
134354 + wq = vzalloc(sizeof(u16) * (0xFFFF+1));
134355 + if (!wq)
134356 + return -ENOMEM;
134357 +
134358 + seq_printf(file, "List of fq ids with destination work queue id"
134359 + " = 0x%x\n", wq_id);
134360 +
134361 + for (i = 1; i < fqid_max; i++) {
134362 + fq.fqid = i;
134363 + memset(&fqd, 0, sizeof(struct qm_fqd));
134364 + ret = qman_query_fq(&fq, &fqd);
134365 + if (ret) {
134366 + vfree(wq);
134367 + return ret;
134368 + }
134369 + if (wq_id == fqd.dest_wq)
134370 + add_to_line_buffer(&line_buf, fq.fqid, file);
134371 + wq[fqd.dest_wq]++;
134372 + }
134373 + flush_line_buffer(&line_buf, file);
134374 +
134375 + seq_puts(file, "Summary of all FQD destination work queue values\n");
134376 + for (i = 0; i < 0xFFFF; i++) {
134377 + if (wq[i])
134378 + seq_printf(file, "Channel: 0x%x WQ: 0x%x WQ_ID: 0x%x, "
134379 + "count = %u\n", i >> 3, i & 0x3, i, wq[i]);
134380 + }
134381 + vfree(wq);
134382 + return 0;
134383 +}
134384 +
134385 +static ssize_t qman_fqd_dest_wq_write(struct file *f, const char __user *buf,
134386 + size_t count, loff_t *off)
134387 +{
134388 + int ret;
134389 + unsigned long val;
134390 +
134391 + ret = user_input_convert(buf, count, &val);
134392 + if (ret)
134393 + return ret;
134394 + if (val > 0xFFFF)
134395 + return -EINVAL;
134396 + qman_dest_wq_data.wq_id = val;
134397 + return count;
134398 +}
134399 +
134400 +static int qman_fqd_dest_wq_open(struct inode *inode, struct file *file)
134401 +{
134402 + return single_open(file, qman_fqd_dest_wq_show, NULL);
134403 +}
134404 +
134405 +static const struct file_operations qman_fqd_dest_wq_fops = {
134406 + .owner = THIS_MODULE,
134407 + .open = qman_fqd_dest_wq_open,
134408 + .read = seq_read,
134409 + .write = qman_fqd_dest_wq_write,
134410 +};
134411 +
134412 +/*******************************************************************************
134413 + * QMan Intra-Class Scheduling Credit
134414 + ******************************************************************************/
134415 +static int qman_fqd_cred_show(struct seq_file *file, void *offset)
134416 +{
134417 + struct qm_fqd fqd;
134418 + struct qman_fq fq;
134419 + int ret, i;
134420 + u32 fq_cnt = 0;
134421 + struct line_buffer_fq line_buf;
134422 +
134423 + memset(&line_buf, 0, sizeof(line_buf));
134424 + seq_puts(file, "List of fq ids with Intra-Class Scheduling Credit > 0"
134425 + "\n");
134426 +
134427 + for (i = 1; i < fqid_max; i++) {
134428 + fq.fqid = i;
134429 + memset(&fqd, 0, sizeof(struct qm_fqd));
134430 + ret = qman_query_fq(&fq, &fqd);
134431 + if (ret)
134432 + return ret;
134433 + if (fqd.ics_cred > 0) {
134434 + add_to_line_buffer(&line_buf, fq.fqid, file);
134435 + fq_cnt++;
134436 + }
134437 + }
134438 + flush_line_buffer(&line_buf, file);
134439 +
134440 + seq_printf(file, "Total FQD with ics_cred > 0 = %d\n", fq_cnt);
134441 + return 0;
134442 +}
134443 +
134444 +static int qman_fqd_cred_open(struct inode *inode, struct file *file)
134445 +{
134446 + return single_open(file, qman_fqd_cred_show, NULL);
134447 +}
134448 +
134449 +static const struct file_operations qman_fqd_cred_fops = {
134450 + .owner = THIS_MODULE,
134451 + .open = qman_fqd_cred_open,
134452 + .read = seq_read,
134453 +};
134454 +
134455 +/*******************************************************************************
134456 + * Class Queue Fields
134457 + ******************************************************************************/
134458 +struct query_cq_fields_data_s {
134459 + u32 cqid;
134460 +};
134461 +
134462 +static struct query_cq_fields_data_s query_cq_fields_data = {
134463 + .cqid = 1,
134464 +};
134465 +
134466 +static int query_cq_fields_show(struct seq_file *file, void *offset)
134467 +{
134468 + int ret;
134469 + struct qm_mcr_ceetm_cq_query query_result;
134470 + unsigned int cqid;
134471 + unsigned int portal;
134472 +
134473 + if ((qman_ip_rev & 0xFF00) < QMAN_REV30)
134474 + return -EINVAL;
134475 +
134476 + cqid = query_cq_fields_data.cqid & 0x00FFFFFF;
134477 + portal = query_cq_fields_data.cqid >> 24;
134478 + if (portal > qm_dc_portal_fman1)
134479 + return -EINVAL;
134480 +
134481 + ret = qman_ceetm_query_cq(cqid, portal, &query_result);
134482 + if (ret)
134483 + return ret;
134484 + seq_printf(file, "Query CQ Fields Result cqid 0x%x on DCP %d\n",
134485 + cqid, portal);
134486 + seq_printf(file, " ccgid: %u\n", query_result.ccgid);
134487 + seq_printf(file, " state: %u\n", query_result.state);
134488 + seq_printf(file, " pfdr_hptr: %u\n", query_result.pfdr_hptr);
134489 + seq_printf(file, " pfdr_tptr: %u\n", query_result.pfdr_tptr);
134490 + seq_printf(file, " od1_xsfdr: %u\n", query_result.od1_xsfdr);
134491 + seq_printf(file, " od2_xsfdr: %u\n", query_result.od2_xsfdr);
134492 + seq_printf(file, " od3_xsfdr: %u\n", query_result.od3_xsfdr);
134493 + seq_printf(file, " od4_xsfdr: %u\n", query_result.od4_xsfdr);
134494 + seq_printf(file, " od5_xsfdr: %u\n", query_result.od5_xsfdr);
134495 + seq_printf(file, " od6_xsfdr: %u\n", query_result.od6_xsfdr);
134496 + seq_printf(file, " ra1_xsfdr: %u\n", query_result.ra1_xsfdr);
134497 + seq_printf(file, " ra2_xsfdr: %u\n", query_result.ra2_xsfdr);
134498 + seq_printf(file, " frame_count: %u\n", query_result.frm_cnt);
134499 +
134500 + return 0;
134501 +}
134502 +
134503 +static int query_cq_fields_open(struct inode *inode,
134504 + struct file *file)
134505 +{
134506 + return single_open(file, query_cq_fields_show, NULL);
134507 +}
134508 +
134509 +static ssize_t query_cq_fields_write(struct file *f,
134510 + const char __user *buf, size_t count, loff_t *off)
134511 +{
134512 + int ret;
134513 + unsigned long val;
134514 +
134515 + ret = user_input_convert(buf, count, &val);
134516 + if (ret)
134517 + return ret;
134518 + query_cq_fields_data.cqid = (u32)val;
134519 + return count;
134520 +}
134521 +
134522 +static const struct file_operations query_cq_fields_fops = {
134523 + .owner = THIS_MODULE,
134524 + .open = query_cq_fields_open,
134525 + .read = seq_read,
134526 + .write = query_cq_fields_write,
134527 + .release = single_release,
134528 +};
134529 +
134530 +/*******************************************************************************
134531 + * READ CEETM_XSFDR_IN_USE
134532 + ******************************************************************************/
134533 +struct query_ceetm_xsfdr_data_s {
134534 + enum qm_dc_portal dcp_portal;
134535 +};
134536 +
134537 +static struct query_ceetm_xsfdr_data_s query_ceetm_xsfdr_data;
134538 +
134539 +static int query_ceetm_xsfdr_show(struct seq_file *file, void *offset)
134540 +{
134541 + int ret;
134542 + unsigned int xsfdr_in_use;
134543 + enum qm_dc_portal portal;
134544 +
134545 +
134546 + if (qman_ip_rev < QMAN_REV31)
134547 + return -EINVAL;
134548 +
134549 + portal = query_ceetm_xsfdr_data.dcp_portal;
134550 + ret = qman_ceetm_get_xsfdr(portal, &xsfdr_in_use);
134551 + if (ret) {
134552 + seq_printf(file, "Read CEETM_XSFDR_IN_USE on DCP %d failed\n",
134553 + portal);
134554 + return ret;
134555 + }
134556 +
134557 + seq_printf(file, "DCP%d: CEETM_XSFDR_IN_USE number is %u\n", portal,
134558 + (xsfdr_in_use & 0x1FFF));
134559 + return 0;
134560 +}
134561 +
134562 +static int query_ceetm_xsfdr_open(struct inode *inode,
134563 + struct file *file)
134564 +{
134565 + return single_open(file, query_ceetm_xsfdr_show, NULL);
134566 +}
134567 +
134568 +static ssize_t query_ceetm_xsfdr_write(struct file *f,
134569 + const char __user *buf, size_t count, loff_t *off)
134570 +{
134571 + int ret;
134572 + unsigned long val;
134573 +
134574 + ret = user_input_convert(buf, count, &val);
134575 + if (ret)
134576 + return ret;
134577 + if (val > qm_dc_portal_fman1)
134578 + return -EINVAL;
134579 + query_ceetm_xsfdr_data.dcp_portal = (u32)val;
134580 + return count;
134581 +}
134582 +
134583 +static const struct file_operations query_ceetm_xsfdr_fops = {
134584 + .owner = THIS_MODULE,
134585 + .open = query_ceetm_xsfdr_open,
134586 + .read = seq_read,
134587 + .write = query_ceetm_xsfdr_write,
134588 + .release = single_release,
134589 +};
134590 +
134591 +/* helper macros used in qman_debugfs_module_init */
134592 +#define QMAN_DBGFS_ENTRY(name, mode, parent, data, fops) \
134593 + do { \
134594 + d = debugfs_create_file(name, \
134595 + mode, parent, \
134596 + data, \
134597 + fops); \
134598 + if (d == NULL) { \
134599 + ret = -ENOMEM; \
134600 + goto _return; \
134601 + } \
134602 + } while (0)
134603 +
134604 +/* dfs_root as parent */
134605 +#define QMAN_DBGFS_ENTRY_ROOT(name, mode, data, fops) \
134606 + QMAN_DBGFS_ENTRY(name, mode, dfs_root, data, fops)
134607 +
134608 +/* fqd_root as parent */
134609 +#define QMAN_DBGFS_ENTRY_FQDROOT(name, mode, data, fops) \
134610 + QMAN_DBGFS_ENTRY(name, mode, fqd_root, data, fops)
134611 +
134612 +/* fqd state */
134613 +#define QMAN_DBGFS_ENTRY_FQDSTATE(name, index) \
134614 + QMAN_DBGFS_ENTRY_FQDROOT(name, S_IRUGO, \
134615 + (void *)&mask_filter[index], &qman_fqd_ctrl_fops)
134616 +
134617 +static int __init qman_debugfs_module_init(void)
134618 +{
134619 + int ret = 0;
134620 + struct dentry *d, *fqd_root;
134621 + u32 reg;
134622 +
134623 + fqid_max = 0;
134624 + init_ccsrmempeek();
134625 + if (qman_ccsr_start) {
134626 + if (!qman_ccsrmempeek(&reg, QM_FQD_AR)) {
134627 + /* extract the size of the FQD window */
134628 + reg = reg & 0x3f;
134629 + /* calculate valid frame queue descriptor range */
134630 + fqid_max = (1 << (reg + 1)) / QM_FQD_BLOCK_SIZE;
134631 + }
134632 + }
134633 + dfs_root = debugfs_create_dir("qman", NULL);
134634 + fqd_root = debugfs_create_dir("fqd", dfs_root);
134635 + if (dfs_root == NULL || fqd_root == NULL) {
134636 + ret = -ENOMEM;
134637 + pr_err("Cannot create qman/fqd debugfs dir\n");
134638 + goto _return;
134639 + }
134640 + if (fqid_max) {
134641 + QMAN_DBGFS_ENTRY_ROOT("ccsrmempeek", S_IRUGO | S_IWUGO,
134642 + NULL, &qman_ccsrmempeek_fops);
134643 + }
134644 + QMAN_DBGFS_ENTRY_ROOT("query_fq_np_fields", S_IRUGO | S_IWUGO,
134645 + &query_fq_np_fields_data, &query_fq_np_fields_fops);
134646 +
134647 + QMAN_DBGFS_ENTRY_ROOT("query_fq_fields", S_IRUGO | S_IWUGO,
134648 + &query_fq_fields_data, &query_fq_fields_fops);
134649 +
134650 + QMAN_DBGFS_ENTRY_ROOT("query_wq_lengths", S_IRUGO | S_IWUGO,
134651 + &query_wq_lengths_data, &query_wq_lengths_fops);
134652 +
134653 + QMAN_DBGFS_ENTRY_ROOT("query_cgr", S_IRUGO | S_IWUGO,
134654 + &query_cgr_data, &query_cgr_fops);
134655 +
134656 + QMAN_DBGFS_ENTRY_ROOT("query_congestion", S_IRUGO,
134657 + NULL, &query_congestion_fops);
134658 +
134659 + QMAN_DBGFS_ENTRY_ROOT("testwrite_cgr", S_IRUGO,
134660 + NULL, &testwrite_cgr_fops);
134661 +
134662 + QMAN_DBGFS_ENTRY_ROOT("testwrite_cgr_cgrid", S_IRUGO | S_IWUGO,
134663 + NULL, &teswrite_cgr_cgrid_fops);
134664 +
134665 + QMAN_DBGFS_ENTRY_ROOT("testwrite_cgr_ibcnt", S_IRUGO | S_IWUGO,
134666 + NULL, &teswrite_cgr_ibcnt_fops);
134667 +
134668 + QMAN_DBGFS_ENTRY_ROOT("query_ceetm_ccgr", S_IRUGO | S_IWUGO,
134669 + &query_ccgr_data, &query_ccgr_fops);
134670 + /* Create files with fqd_root as parent */
134671 +
134672 + QMAN_DBGFS_ENTRY_FQDROOT("stateoos", S_IRUGO,
134673 + (void *)&fqd_states[QM_MCR_NP_STATE_OOS], &qman_fqd_state_fops);
134674 +
134675 + QMAN_DBGFS_ENTRY_FQDROOT("state_retired", S_IRUGO,
134676 + (void *)&fqd_states[QM_MCR_NP_STATE_RETIRED],
134677 + &qman_fqd_state_fops);
134678 +
134679 + QMAN_DBGFS_ENTRY_FQDROOT("state_tentatively_sched", S_IRUGO,
134680 + (void *)&fqd_states[QM_MCR_NP_STATE_TEN_SCHED],
134681 + &qman_fqd_state_fops);
134682 +
134683 + QMAN_DBGFS_ENTRY_FQDROOT("state_truly_sched", S_IRUGO,
134684 + (void *)&fqd_states[QM_MCR_NP_STATE_TRU_SCHED],
134685 + &qman_fqd_state_fops);
134686 +
134687 + QMAN_DBGFS_ENTRY_FQDROOT("state_parked", S_IRUGO,
134688 + (void *)&fqd_states[QM_MCR_NP_STATE_PARKED],
134689 + &qman_fqd_state_fops);
134690 +
134691 + QMAN_DBGFS_ENTRY_FQDROOT("state_active", S_IRUGO,
134692 + (void *)&fqd_states[QM_MCR_NP_STATE_ACTIVE],
134693 + &qman_fqd_state_fops);
134694 + QMAN_DBGFS_ENTRY_ROOT("query_cq_fields", S_IRUGO | S_IWUGO,
134695 + &query_cq_fields_data, &query_cq_fields_fops);
134696 + QMAN_DBGFS_ENTRY_ROOT("query_ceetm_xsfdr_in_use", S_IRUGO | S_IWUGO,
134697 + &query_ceetm_xsfdr_data, &query_ceetm_xsfdr_fops);
134698 +
134699 +
134700 + QMAN_DBGFS_ENTRY_FQDSTATE("cge_enable", 17);
134701 +
134702 + QMAN_DBGFS_ENTRY_FQDSTATE("cge_disable", 16);
134703 +
134704 + QMAN_DBGFS_ENTRY_FQDSTATE("tde_enable", 15);
134705 +
134706 + QMAN_DBGFS_ENTRY_FQDSTATE("tde_disable", 14);
134707 +
134708 + QMAN_DBGFS_ENTRY_FQDSTATE("orp_enable", 13);
134709 +
134710 + QMAN_DBGFS_ENTRY_FQDSTATE("orp_disable", 12);
134711 +
134712 + QMAN_DBGFS_ENTRY_FQDSTATE("ctx_a_stashing_enable", 11);
134713 +
134714 + QMAN_DBGFS_ENTRY_FQDSTATE("ctx_a_stashing_disable", 10);
134715 +
134716 + QMAN_DBGFS_ENTRY_FQDSTATE("cpc_enable", 9);
134717 +
134718 + QMAN_DBGFS_ENTRY_FQDSTATE("cpc_disable", 8);
134719 +
134720 + QMAN_DBGFS_ENTRY_FQDSTATE("sfdr_enable", 7);
134721 +
134722 + QMAN_DBGFS_ENTRY_FQDSTATE("sfdr_disable", 6);
134723 +
134724 + QMAN_DBGFS_ENTRY_FQDSTATE("avoid_blocking_enable", 5);
134725 +
134726 + QMAN_DBGFS_ENTRY_FQDSTATE("avoid_blocking_disable", 4);
134727 +
134728 + QMAN_DBGFS_ENTRY_FQDSTATE("hold_active_enable", 3);
134729 +
134730 + QMAN_DBGFS_ENTRY_FQDSTATE("hold_active_disable", 2);
134731 +
134732 + QMAN_DBGFS_ENTRY_FQDSTATE("prefer_in_cache_enable", 1);
134733 +
134734 + QMAN_DBGFS_ENTRY_FQDSTATE("prefer_in_cache_disable", 0);
134735 +
134736 + QMAN_DBGFS_ENTRY_FQDROOT("summary", S_IRUGO,
134737 + NULL, &qman_fqd_summary_fops);
134738 +
134739 + QMAN_DBGFS_ENTRY_FQDROOT("wq", S_IRUGO | S_IWUGO,
134740 + NULL, &qman_fqd_dest_wq_fops);
134741 +
134742 + QMAN_DBGFS_ENTRY_FQDROOT("cred", S_IRUGO,
134743 + NULL, &qman_fqd_cred_fops);
134744 +
134745 + return 0;
134746 +
134747 +_return:
134748 + debugfs_remove_recursive(dfs_root);
134749 + return ret;
134750 +}
134751 +
134752 +static void __exit qman_debugfs_module_exit(void)
134753 +{
134754 + debugfs_remove_recursive(dfs_root);
134755 +}
134756 +
134757 +module_init(qman_debugfs_module_init);
134758 +module_exit(qman_debugfs_module_exit);
134759 +MODULE_LICENSE("Dual BSD/GPL");
134760 --- /dev/null
134761 +++ b/drivers/staging/fsl_qbman/qman_driver.c
134762 @@ -0,0 +1,977 @@
134763 +/* Copyright 2008-2012 Freescale Semiconductor, Inc.
134764 + *
134765 + * Redistribution and use in source and binary forms, with or without
134766 + * modification, are permitted provided that the following conditions are met:
134767 + * * Redistributions of source code must retain the above copyright
134768 + * notice, this list of conditions and the following disclaimer.
134769 + * * Redistributions in binary form must reproduce the above copyright
134770 + * notice, this list of conditions and the following disclaimer in the
134771 + * documentation and/or other materials provided with the distribution.
134772 + * * Neither the name of Freescale Semiconductor nor the
134773 + * names of its contributors may be used to endorse or promote products
134774 + * derived from this software without specific prior written permission.
134775 + *
134776 + *
134777 + * ALTERNATIVELY, this software may be distributed under the terms of the
134778 + * GNU General Public License ("GPL") as published by the Free Software
134779 + * Foundation, either version 2 of that License or (at your option) any
134780 + * later version.
134781 + *
134782 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
134783 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
134784 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
134785 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
134786 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
134787 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
134788 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
134789 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
134790 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
134791 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
134792 + */
134793 +
134794 +#include "qman_private.h"
134795 +
134796 +#include <asm/smp.h> /* hard_smp_processor_id() if !CONFIG_SMP */
134797 +#ifdef CONFIG_HOTPLUG_CPU
134798 +#include <linux/cpu.h>
134799 +#endif
134800 +
134801 +/* Global variable containing revision id (even on non-control plane systems
134802 + * where CCSR isn't available) */
134803 +u16 qman_ip_rev;
134804 +EXPORT_SYMBOL(qman_ip_rev);
134805 +u8 qman_ip_cfg;
134806 +EXPORT_SYMBOL(qman_ip_cfg);
134807 +u16 qm_channel_pool1 = QMAN_CHANNEL_POOL1;
134808 +EXPORT_SYMBOL(qm_channel_pool1);
134809 +u16 qm_channel_caam = QMAN_CHANNEL_CAAM;
134810 +EXPORT_SYMBOL(qm_channel_caam);
134811 +u16 qm_channel_pme = QMAN_CHANNEL_PME;
134812 +EXPORT_SYMBOL(qm_channel_pme);
134813 +u16 qm_channel_dce = QMAN_CHANNEL_DCE;
134814 +EXPORT_SYMBOL(qm_channel_dce);
134815 +u16 qman_portal_max;
134816 +EXPORT_SYMBOL(qman_portal_max);
134817 +
134818 +u32 qman_clk;
134819 +struct qm_ceetm qman_ceetms[QMAN_CEETM_MAX];
134820 +/* the qman ceetm instances on the given SoC */
134821 +u8 num_ceetms;
134822 +
134823 +/* For these variables, and the portal-initialisation logic, the
134824 + * comments in bman_driver.c apply here so won't be repeated. */
134825 +static struct qman_portal *shared_portals[NR_CPUS];
134826 +static int num_shared_portals;
134827 +static int shared_portals_idx;
134828 +static LIST_HEAD(unused_pcfgs);
134829 +static DEFINE_SPINLOCK(unused_pcfgs_lock);
134830 +
134831 +/* A SDQCR mask comprising all the available/visible pool channels */
134832 +static u32 pools_sdqcr;
134833 +
134834 +#define STR_ERR_NOPROP "No '%s' property in node %s\n"
134835 +#define STR_ERR_CELL "'%s' is not a %d-cell range in node %s\n"
134836 +#define STR_FQID_RANGE "fsl,fqid-range"
134837 +#define STR_POOL_CHAN_RANGE "fsl,pool-channel-range"
134838 +#define STR_CGRID_RANGE "fsl,cgrid-range"
134839 +
134840 +/* A "fsl,fqid-range" node; release the given range to the allocator */
134841 +static __init int fsl_fqid_range_init(struct device_node *node)
134842 +{
134843 + int ret;
134844 + const u32 *range = of_get_property(node, STR_FQID_RANGE, &ret);
134845 + if (!range) {
134846 + pr_err(STR_ERR_NOPROP, STR_FQID_RANGE, node->full_name);
134847 + return -EINVAL;
134848 + }
134849 + if (ret != 8) {
134850 + pr_err(STR_ERR_CELL, STR_FQID_RANGE, 2, node->full_name);
134851 + return -EINVAL;
134852 + }
134853 + qman_seed_fqid_range(be32_to_cpu(range[0]), be32_to_cpu(range[1]));
134854 + pr_info("Qman: FQID allocator includes range %d:%d\n",
134855 + be32_to_cpu(range[0]), be32_to_cpu(range[1]));
134856 + return 0;
134857 +}
134858 +
134859 +/* A "fsl,pool-channel-range" node; add to the SDQCR mask only */
134860 +static __init int fsl_pool_channel_range_sdqcr(struct device_node *node)
134861 +{
134862 + int ret;
134863 + const u32 *chanid = of_get_property(node, STR_POOL_CHAN_RANGE, &ret);
134864 + if (!chanid) {
134865 + pr_err(STR_ERR_NOPROP, STR_POOL_CHAN_RANGE, node->full_name);
134866 + return -EINVAL;
134867 + }
134868 + if (ret != 8) {
134869 + pr_err(STR_ERR_CELL, STR_POOL_CHAN_RANGE, 1, node->full_name);
134870 + return -EINVAL;
134871 + }
134872 + for (ret = 0; ret < be32_to_cpu(chanid[1]); ret++)
134873 + pools_sdqcr |= QM_SDQCR_CHANNELS_POOL_CONV(be32_to_cpu(chanid[0]) + ret);
134874 + return 0;
134875 +}
134876 +
134877 +/* A "fsl,pool-channel-range" node; release the given range to the allocator */
134878 +static __init int fsl_pool_channel_range_init(struct device_node *node)
134879 +{
134880 + int ret;
134881 + const u32 *chanid = of_get_property(node, STR_POOL_CHAN_RANGE, &ret);
134882 + if (!chanid) {
134883 + pr_err(STR_ERR_NOPROP, STR_POOL_CHAN_RANGE, node->full_name);
134884 + return -EINVAL;
134885 + }
134886 + if (ret != 8) {
134887 + pr_err(STR_ERR_CELL, STR_POOL_CHAN_RANGE, 1, node->full_name);
134888 + return -EINVAL;
134889 + }
134890 + qman_seed_pool_range(be32_to_cpu(chanid[0]), be32_to_cpu(chanid[1]));
134891 + pr_info("Qman: pool channel allocator includes range %d:%d\n",
134892 + be32_to_cpu(chanid[0]), be32_to_cpu(chanid[1]));
134893 + return 0;
134894 +}
134895 +
134896 +/* A "fsl,cgrid-range" node; release the given range to the allocator */
134897 +static __init int fsl_cgrid_range_init(struct device_node *node)
134898 +{
134899 + struct qman_cgr cgr;
134900 + int ret, errors = 0;
134901 + const u32 *range = of_get_property(node, STR_CGRID_RANGE, &ret);
134902 + if (!range) {
134903 + pr_err(STR_ERR_NOPROP, STR_CGRID_RANGE, node->full_name);
134904 + return -EINVAL;
134905 + }
134906 + if (ret != 8) {
134907 + pr_err(STR_ERR_CELL, STR_CGRID_RANGE, 2, node->full_name);
134908 + return -EINVAL;
134909 + }
134910 + qman_seed_cgrid_range(be32_to_cpu(range[0]), be32_to_cpu(range[1]));
134911 + pr_info("Qman: CGRID allocator includes range %d:%d\n",
134912 + be32_to_cpu(range[0]), be32_to_cpu(range[1]));
134913 + for (cgr.cgrid = 0; cgr.cgrid < __CGR_NUM; cgr.cgrid++) {
134914 + ret = qman_modify_cgr(&cgr, QMAN_CGR_FLAG_USE_INIT, NULL);
134915 + if (ret)
134916 + errors++;
134917 + }
134918 + if (errors)
134919 + pr_err("Warning: %d error%s while initialising CGRs %d:%d\n",
134920 + errors, (errors > 1) ? "s" : "", range[0], range[1]);
134921 + return 0;
134922 +}
134923 +
134924 +static __init int fsl_ceetm_init(struct device_node *node)
134925 +{
134926 + enum qm_dc_portal dcp_portal;
134927 + struct qm_ceetm_sp *sp;
134928 + struct qm_ceetm_lni *lni;
134929 + int ret, i;
134930 + const u32 *range;
134931 +
134932 + /* Find LFQID range */
134933 + range = of_get_property(node, "fsl,ceetm-lfqid-range", &ret);
134934 + if (!range) {
134935 + pr_err("No fsl,ceetm-lfqid-range in node %s\n",
134936 + node->full_name);
134937 + return -EINVAL;
134938 + }
134939 + if (ret != 8) {
134940 + pr_err("fsl,ceetm-lfqid-range is not a 2-cell range in node"
134941 + " %s\n", node->full_name);
134942 + return -EINVAL;
134943 + }
134944 +
134945 + dcp_portal = (be32_to_cpu(range[0]) & 0x0F0000) >> 16;
134946 + if (dcp_portal > qm_dc_portal_fman1) {
134947 + pr_err("The DCP portal %d doesn't support CEETM\n", dcp_portal);
134948 + return -EINVAL;
134949 + }
134950 +
134951 + if (dcp_portal == qm_dc_portal_fman0)
134952 + qman_seed_ceetm0_lfqid_range(be32_to_cpu(range[0]), be32_to_cpu(range[1]));
134953 + if (dcp_portal == qm_dc_portal_fman1)
134954 + qman_seed_ceetm1_lfqid_range(be32_to_cpu(range[0]), be32_to_cpu(range[1]));
134955 + pr_debug("Qman: The lfqid allocator of CEETM %d includes range"
134956 + " 0x%x:0x%x\n", dcp_portal, be32_to_cpu(range[0]), be32_to_cpu(range[1]));
134957 +
134958 + qman_ceetms[dcp_portal].idx = dcp_portal;
134959 + INIT_LIST_HEAD(&qman_ceetms[dcp_portal].sub_portals);
134960 + INIT_LIST_HEAD(&qman_ceetms[dcp_portal].lnis);
134961 +
134962 + /* Find Sub-portal range */
134963 + range = of_get_property(node, "fsl,ceetm-sp-range", &ret);
134964 + if (!range) {
134965 + pr_err("No fsl,ceetm-sp-range in node %s\n", node->full_name);
134966 + return -EINVAL;
134967 + }
134968 + if (ret != 8) {
134969 + pr_err("fsl,ceetm-sp-range is not a 2-cell range in node %s\n",
134970 + node->full_name);
134971 + return -EINVAL;
134972 + }
134973 +
134974 + for (i = 0; i < be32_to_cpu(range[1]); i++) {
134975 + sp = kzalloc(sizeof(*sp), GFP_KERNEL);
134976 + if (!sp) {
134977 + pr_err("Can't alloc memory for sub-portal %d\n",
134978 + range[0] + i);
134979 + return -ENOMEM;
134980 + }
134981 + sp->idx = be32_to_cpu(range[0]) + i;
134982 + sp->dcp_idx = dcp_portal;
134983 + sp->is_claimed = 0;
134984 + list_add_tail(&sp->node, &qman_ceetms[dcp_portal].sub_portals);
134985 + sp++;
134986 + }
134987 + pr_debug("Qman: Reserve sub-portal %d:%d for CEETM %d\n",
134988 + be32_to_cpu(range[0]), be32_to_cpu(range[1]), dcp_portal);
134989 + qman_ceetms[dcp_portal].sp_range[0] = be32_to_cpu(range[0]);
134990 + qman_ceetms[dcp_portal].sp_range[1] = be32_to_cpu(range[1]);
134991 +
134992 + /* Find LNI range */
134993 + range = of_get_property(node, "fsl,ceetm-lni-range", &ret);
134994 + if (!range) {
134995 + pr_err("No fsl,ceetm-lni-range in node %s\n", node->full_name);
134996 + return -EINVAL;
134997 + }
134998 + if (ret != 8) {
134999 + pr_err("fsl,ceetm-lni-range is not a 2-cell range in node %s\n",
135000 + node->full_name);
135001 + return -EINVAL;
135002 + }
135003 +
135004 + for (i = 0; i < be32_to_cpu(range[1]); i++) {
135005 + lni = kzalloc(sizeof(*lni), GFP_KERNEL);
135006 + if (!lni) {
135007 + pr_err("Can't alloc memory for LNI %d\n",
135008 + range[0] + i);
135009 + return -ENOMEM;
135010 + }
135011 + lni->idx = be32_to_cpu(range[0]) + i;
135012 + lni->dcp_idx = dcp_portal;
135013 + lni->is_claimed = 0;
135014 + INIT_LIST_HEAD(&lni->channels);
135015 + list_add_tail(&lni->node, &qman_ceetms[dcp_portal].lnis);
135016 + lni++;
135017 + }
135018 + pr_debug("Qman: Reserve LNI %d:%d for CEETM %d\n",
135019 + be32_to_cpu(range[0]), be32_to_cpu(range[1]), dcp_portal);
135020 + qman_ceetms[dcp_portal].lni_range[0] = be32_to_cpu(range[0]);
135021 + qman_ceetms[dcp_portal].lni_range[1] = be32_to_cpu(range[1]);
135022 +
135023 + /* Find CEETM channel range */
135024 + range = of_get_property(node, "fsl,ceetm-channel-range", &ret);
135025 + if (!range) {
135026 + pr_err("No fsl,ceetm-channel-range in node %s\n",
135027 + node->full_name);
135028 + return -EINVAL;
135029 + }
135030 + if (ret != 8) {
135031 + pr_err("fsl,ceetm-channel-range is not a 2-cell range in node"
135032 + "%s\n", node->full_name);
135033 + return -EINVAL;
135034 + }
135035 +
135036 + if (dcp_portal == qm_dc_portal_fman0)
135037 + qman_seed_ceetm0_channel_range(be32_to_cpu(range[0]), be32_to_cpu(range[1]));
135038 + if (dcp_portal == qm_dc_portal_fman1)
135039 + qman_seed_ceetm1_channel_range(be32_to_cpu(range[0]), be32_to_cpu(range[1]));
135040 + pr_debug("Qman: The channel allocator of CEETM %d includes"
135041 + " range %d:%d\n", dcp_portal, be32_to_cpu(range[0]), be32_to_cpu(range[1]));
135042 +
135043 + /* Set CEETM PRES register */
135044 + ret = qman_ceetm_set_prescaler(dcp_portal);
135045 + if (ret)
135046 + return ret;
135047 + return 0;
135048 +}
135049 +
135050 +static void qman_get_ip_revision(struct device_node *dn)
135051 +{
135052 + u16 ip_rev = 0;
135053 + u8 ip_cfg = QMAN_REV_CFG_0;
135054 + for_each_compatible_node(dn, NULL, "fsl,qman-portal") {
135055 + if (!of_device_is_available(dn))
135056 + continue;
135057 + if (of_device_is_compatible(dn, "fsl,qman-portal-1.0") ||
135058 + of_device_is_compatible(dn, "fsl,qman-portal-1.0.0")) {
135059 + pr_err("QMAN rev1.0 on P4080 rev1 is not supported!\n");
135060 + BUG_ON(1);
135061 + } else if (of_device_is_compatible(dn, "fsl,qman-portal-1.1") ||
135062 + of_device_is_compatible(dn, "fsl,qman-portal-1.1.0")) {
135063 + ip_rev = QMAN_REV11;
135064 + qman_portal_max = 10;
135065 + } else if (of_device_is_compatible(dn, "fsl,qman-portal-1.2") ||
135066 + of_device_is_compatible(dn, "fsl,qman-portal-1.2.0")) {
135067 + ip_rev = QMAN_REV12;
135068 + qman_portal_max = 10;
135069 + } else if (of_device_is_compatible(dn, "fsl,qman-portal-2.0") ||
135070 + of_device_is_compatible(dn, "fsl,qman-portal-2.0.0")) {
135071 + ip_rev = QMAN_REV20;
135072 + qman_portal_max = 3;
135073 + } else if (of_device_is_compatible(dn,
135074 + "fsl,qman-portal-3.0.0")) {
135075 + ip_rev = QMAN_REV30;
135076 + qman_portal_max = 50;
135077 + } else if (of_device_is_compatible(dn,
135078 + "fsl,qman-portal-3.0.1")) {
135079 + ip_rev = QMAN_REV30;
135080 + qman_portal_max = 25;
135081 + ip_cfg = QMAN_REV_CFG_1;
135082 + } else if (of_device_is_compatible(dn,
135083 + "fsl,qman-portal-3.1.0")) {
135084 + ip_rev = QMAN_REV31;
135085 + qman_portal_max = 50;
135086 + } else if (of_device_is_compatible(dn,
135087 + "fsl,qman-portal-3.1.1")) {
135088 + ip_rev = QMAN_REV31;
135089 + qman_portal_max = 25;
135090 + ip_cfg = QMAN_REV_CFG_1;
135091 + } else if (of_device_is_compatible(dn,
135092 + "fsl,qman-portal-3.1.2")) {
135093 + ip_rev = QMAN_REV31;
135094 + qman_portal_max = 18;
135095 + ip_cfg = QMAN_REV_CFG_2;
135096 + } else if (of_device_is_compatible(dn,
135097 + "fsl,qman-portal-3.1.3")) {
135098 + ip_rev = QMAN_REV31;
135099 + qman_portal_max = 10;
135100 + ip_cfg = QMAN_REV_CFG_3;
135101 + } else if (of_device_is_compatible(dn,
135102 + "fsl,qman-portal-3.2.0")) {
135103 + ip_rev = QMAN_REV32;
135104 + qman_portal_max = 10;
135105 + ip_cfg = QMAN_REV_CFG_3; // TODO: Verify for ls1043
135106 + } else if (of_device_is_compatible(dn,
135107 + "fsl,qman-portal-3.2.1")) {
135108 + ip_rev = QMAN_REV32;
135109 + qman_portal_max = 10;
135110 + ip_cfg = QMAN_REV_CFG_3;
135111 + } else {
135112 + pr_warn("unknown QMan version in portal node,"
135113 + "default to rev1.1\n");
135114 + ip_rev = QMAN_REV11;
135115 + qman_portal_max = 10;
135116 + }
135117 +
135118 + if (!qman_ip_rev) {
135119 + if (ip_rev) {
135120 + qman_ip_rev = ip_rev;
135121 + qman_ip_cfg = ip_cfg;
135122 + } else {
135123 + pr_warn("unknown Qman version,"
135124 + " default to rev1.1\n");
135125 + qman_ip_rev = QMAN_REV11;
135126 + qman_ip_cfg = QMAN_REV_CFG_0;
135127 + }
135128 + } else if (ip_rev && (qman_ip_rev != ip_rev))
135129 + pr_warn("Revision=0x%04x, but portal '%s' has"
135130 + " 0x%04x\n",
135131 + qman_ip_rev, dn->full_name, ip_rev);
135132 + if (qman_ip_rev == ip_rev)
135133 + break;
135134 + }
135135 +}
135136 +
135137 +/* Parse a portal node, perform generic mapping duties and return the config. It
135138 + * is not known at this stage for what purpose (or even if) the portal will be
135139 + * used. */
135140 +static struct qm_portal_config * __init parse_pcfg(struct device_node *node)
135141 +{
135142 + struct qm_portal_config *pcfg;
135143 + const u32 *index_p;
135144 + u32 index, channel;
135145 + int irq, ret;
135146 + resource_size_t len;
135147 +
135148 + pcfg = kmalloc(sizeof(*pcfg), GFP_KERNEL);
135149 + if (!pcfg) {
135150 + pr_err("can't allocate portal config");
135151 + return NULL;
135152 + }
135153 +
135154 + /*
135155 + * This is a *horrible hack*, but the IOMMU/PAMU driver needs a
135156 + * 'struct device' in order to get the PAMU stashing setup and the QMan
135157 + * portal [driver] won't function at all without ring stashing
135158 + *
135159 + * Making the QMan portal driver nice and proper is part of the
135160 + * upstreaming effort
135161 + */
135162 + pcfg->dev.bus = &platform_bus_type;
135163 + pcfg->dev.of_node = node;
135164 +#ifdef CONFIG_FSL_PAMU
135165 + pcfg->dev.archdata.iommu_domain = NULL;
135166 +#endif
135167 +
135168 + ret = of_address_to_resource(node, DPA_PORTAL_CE,
135169 + &pcfg->addr_phys[DPA_PORTAL_CE]);
135170 + if (ret) {
135171 + pr_err("Can't get %s property '%s'\n", node->full_name,
135172 + "reg::CE");
135173 + goto err;
135174 + }
135175 + ret = of_address_to_resource(node, DPA_PORTAL_CI,
135176 + &pcfg->addr_phys[DPA_PORTAL_CI]);
135177 + if (ret) {
135178 + pr_err("Can't get %s property '%s'\n", node->full_name,
135179 + "reg::CI");
135180 + goto err;
135181 + }
135182 + index_p = of_get_property(node, "cell-index", &ret);
135183 + if (!index_p || (ret != 4)) {
135184 + pr_err("Can't get %s property '%s'\n", node->full_name,
135185 + "cell-index");
135186 + goto err;
135187 + }
135188 + index = be32_to_cpu(*index_p);
135189 + if (index >= qman_portal_max) {
135190 + pr_err("QMan portal index %d is beyond max (%d)\n",
135191 + index, qman_portal_max);
135192 + goto err;
135193 + }
135194 +
135195 + channel = index + QM_CHANNEL_SWPORTAL0;
135196 + pcfg->public_cfg.channel = channel;
135197 + pcfg->public_cfg.cpu = -1;
135198 + irq = irq_of_parse_and_map(node, 0);
135199 + if (irq == 0) {
135200 + pr_err("Can't get %s property '%s'\n", node->full_name,
135201 + "interrupts");
135202 + goto err;
135203 + }
135204 + pcfg->public_cfg.irq = irq;
135205 + pcfg->public_cfg.index = index;
135206 +#ifdef CONFIG_FSL_QMAN_CONFIG
135207 + /* We need the same LIODN offset for all portals */
135208 + qman_liodn_fixup(pcfg->public_cfg.channel);
135209 +#endif
135210 +
135211 + len = resource_size(&pcfg->addr_phys[DPA_PORTAL_CE]);
135212 + if (len != (unsigned long)len)
135213 + goto err;
135214 +
135215 +#if defined(CONFIG_ARM) || defined(CONFIG_ARM64)
135216 + pcfg->addr_virt[DPA_PORTAL_CE] = ioremap_cache_ns(
135217 + pcfg->addr_phys[DPA_PORTAL_CE].start,
135218 + resource_size(&pcfg->addr_phys[DPA_PORTAL_CE]));
135219 +
135220 + pcfg->addr_virt[DPA_PORTAL_CI] = ioremap(
135221 + pcfg->addr_phys[DPA_PORTAL_CI].start,
135222 + resource_size(&pcfg->addr_phys[DPA_PORTAL_CI]));
135223 +#else
135224 + pcfg->addr_virt[DPA_PORTAL_CE] = ioremap_prot(
135225 + pcfg->addr_phys[DPA_PORTAL_CE].start,
135226 + (unsigned long)len,
135227 + 0);
135228 + pcfg->addr_virt[DPA_PORTAL_CI] = ioremap_prot(
135229 + pcfg->addr_phys[DPA_PORTAL_CI].start,
135230 + resource_size(&pcfg->addr_phys[DPA_PORTAL_CI]),
135231 + _PAGE_GUARDED | _PAGE_NO_CACHE);
135232 +#endif
135233 + return pcfg;
135234 +err:
135235 + kfree(pcfg);
135236 + return NULL;
135237 +}
135238 +
135239 +static struct qm_portal_config *get_pcfg(struct list_head *list)
135240 +{
135241 + struct qm_portal_config *pcfg;
135242 + if (list_empty(list))
135243 + return NULL;
135244 + pcfg = list_entry(list->prev, struct qm_portal_config, list);
135245 + list_del(&pcfg->list);
135246 + return pcfg;
135247 +}
135248 +
135249 +static struct qm_portal_config *get_pcfg_idx(struct list_head *list, u32 idx)
135250 +{
135251 + struct qm_portal_config *pcfg;
135252 + if (list_empty(list))
135253 + return NULL;
135254 + list_for_each_entry(pcfg, list, list) {
135255 + if (pcfg->public_cfg.index == idx) {
135256 + list_del(&pcfg->list);
135257 + return pcfg;
135258 + }
135259 + }
135260 + return NULL;
135261 +}
135262 +
135263 +static void portal_set_cpu(struct qm_portal_config *pcfg, int cpu)
135264 +{
135265 +#ifdef CONFIG_FSL_PAMU
135266 + int ret;
135267 + int window_count = 1;
135268 + struct iommu_domain_geometry geom_attr;
135269 + struct pamu_stash_attribute stash_attr;
135270 +
135271 + pcfg->iommu_domain = iommu_domain_alloc(&platform_bus_type);
135272 + if (!pcfg->iommu_domain) {
135273 + pr_err(KBUILD_MODNAME ":%s(): iommu_domain_alloc() failed",
135274 + __func__);
135275 + goto _no_iommu;
135276 + }
135277 + geom_attr.aperture_start = 0;
135278 + geom_attr.aperture_end =
135279 + ((dma_addr_t)1 << min(8 * sizeof(dma_addr_t), (size_t)36)) - 1;
135280 + geom_attr.force_aperture = true;
135281 + ret = iommu_domain_set_attr(pcfg->iommu_domain, DOMAIN_ATTR_GEOMETRY,
135282 + &geom_attr);
135283 + if (ret < 0) {
135284 + pr_err(KBUILD_MODNAME ":%s(): iommu_domain_set_attr() = %d",
135285 + __func__, ret);
135286 + goto _iommu_domain_free;
135287 + }
135288 + ret = iommu_domain_set_attr(pcfg->iommu_domain, DOMAIN_ATTR_WINDOWS,
135289 + &window_count);
135290 + if (ret < 0) {
135291 + pr_err(KBUILD_MODNAME ":%s(): iommu_domain_set_attr() = %d",
135292 + __func__, ret);
135293 + goto _iommu_domain_free;
135294 + }
135295 + stash_attr.cpu = cpu;
135296 + stash_attr.cache = PAMU_ATTR_CACHE_L1;
135297 + /* set stash information for the window */
135298 + stash_attr.window = 0;
135299 + ret = iommu_domain_set_attr(pcfg->iommu_domain,
135300 + DOMAIN_ATTR_FSL_PAMU_STASH,
135301 + &stash_attr);
135302 + if (ret < 0) {
135303 + pr_err(KBUILD_MODNAME ":%s(): iommu_domain_set_attr() = %d",
135304 + __func__, ret);
135305 + goto _iommu_domain_free;
135306 + }
135307 + ret = iommu_domain_window_enable(pcfg->iommu_domain, 0, 0, 1ULL << 36,
135308 + IOMMU_READ | IOMMU_WRITE);
135309 + if (ret < 0) {
135310 + pr_err(KBUILD_MODNAME ":%s(): iommu_domain_window_enable() = %d",
135311 + __func__, ret);
135312 + goto _iommu_domain_free;
135313 + }
135314 + ret = iommu_attach_device(pcfg->iommu_domain, &pcfg->dev);
135315 + if (ret < 0) {
135316 + pr_err(KBUILD_MODNAME ":%s(): iommu_device_attach() = %d",
135317 + __func__, ret);
135318 + goto _iommu_domain_free;
135319 + }
135320 + ret = iommu_domain_set_attr(pcfg->iommu_domain,
135321 + DOMAIN_ATTR_FSL_PAMU_ENABLE,
135322 + &window_count);
135323 + if (ret < 0) {
135324 + pr_err(KBUILD_MODNAME ":%s(): iommu_domain_set_attr() = %d",
135325 + __func__, ret);
135326 + goto _iommu_detach_device;
135327 + }
135328 +
135329 +_no_iommu:
135330 +#endif
135331 +#ifdef CONFIG_FSL_QMAN_CONFIG
135332 + if (qman_set_sdest(pcfg->public_cfg.channel, cpu))
135333 +#endif
135334 + pr_warn("Failed to set QMan portal's stash request queue\n");
135335 +
135336 + return;
135337 +
135338 +#ifdef CONFIG_FSL_PAMU
135339 +_iommu_detach_device:
135340 + iommu_detach_device(pcfg->iommu_domain, NULL);
135341 +_iommu_domain_free:
135342 + iommu_domain_free(pcfg->iommu_domain);
135343 +#endif
135344 +}
135345 +
135346 +struct qm_portal_config *qm_get_unused_portal_idx(u32 idx)
135347 +{
135348 + struct qm_portal_config *ret;
135349 + spin_lock(&unused_pcfgs_lock);
135350 + if (idx == QBMAN_ANY_PORTAL_IDX)
135351 + ret = get_pcfg(&unused_pcfgs);
135352 + else
135353 + ret = get_pcfg_idx(&unused_pcfgs, idx);
135354 + spin_unlock(&unused_pcfgs_lock);
135355 + /* Bind stashing LIODNs to the CPU we are currently executing on, and
135356 + * set the portal to use the stashing request queue corresonding to the
135357 + * cpu as well. The user-space driver assumption is that the pthread has
135358 + * to already be affine to one cpu only before opening a portal. If that
135359 + * check is circumvented, the only risk is a performance degradation -
135360 + * stashing will go to whatever cpu they happened to be running on when
135361 + * opening the device file, and if that isn't the cpu they subsequently
135362 + * bind to and do their polling on, tough. */
135363 + if (ret)
135364 + portal_set_cpu(ret, hard_smp_processor_id());
135365 + return ret;
135366 +}
135367 +
135368 +struct qm_portal_config *qm_get_unused_portal(void)
135369 +{
135370 + return qm_get_unused_portal_idx(QBMAN_ANY_PORTAL_IDX);
135371 +}
135372 +
135373 +void qm_put_unused_portal(struct qm_portal_config *pcfg)
135374 +{
135375 + spin_lock(&unused_pcfgs_lock);
135376 + list_add(&pcfg->list, &unused_pcfgs);
135377 + spin_unlock(&unused_pcfgs_lock);
135378 +}
135379 +
135380 +static struct qman_portal *init_pcfg(struct qm_portal_config *pcfg)
135381 +{
135382 + struct qman_portal *p;
135383 +
135384 + pcfg->iommu_domain = NULL;
135385 + portal_set_cpu(pcfg, pcfg->public_cfg.cpu);
135386 + p = qman_create_affine_portal(pcfg, NULL);
135387 + if (p) {
135388 + u32 irq_sources = 0;
135389 + /* Determine what should be interrupt-vs-poll driven */
135390 +#ifdef CONFIG_FSL_DPA_PIRQ_SLOW
135391 + irq_sources |= QM_PIRQ_EQCI | QM_PIRQ_EQRI | QM_PIRQ_MRI |
135392 + QM_PIRQ_CSCI | QM_PIRQ_CCSCI;
135393 +#endif
135394 +#ifdef CONFIG_FSL_DPA_PIRQ_FAST
135395 + irq_sources |= QM_PIRQ_DQRI;
135396 +#endif
135397 + qman_p_irqsource_add(p, irq_sources);
135398 + pr_info("Qman portal %sinitialised, cpu %d\n",
135399 + pcfg->public_cfg.is_shared ? "(shared) " : "",
135400 + pcfg->public_cfg.cpu);
135401 + } else
135402 + pr_crit("Qman portal failure on cpu %d\n",
135403 + pcfg->public_cfg.cpu);
135404 + return p;
135405 +}
135406 +
135407 +static void init_slave(int cpu)
135408 +{
135409 + struct qman_portal *p;
135410 + struct cpumask oldmask = current->cpus_allowed;
135411 + set_cpus_allowed_ptr(current, get_cpu_mask(cpu));
135412 + p = qman_create_affine_slave(shared_portals[shared_portals_idx++], cpu);
135413 + if (!p)
135414 + pr_err("Qman slave portal failure on cpu %d\n", cpu);
135415 + else
135416 + pr_info("Qman portal %sinitialised, cpu %d\n", "(slave) ", cpu);
135417 + set_cpus_allowed_ptr(current, &oldmask);
135418 + if (shared_portals_idx >= num_shared_portals)
135419 + shared_portals_idx = 0;
135420 +}
135421 +
135422 +static struct cpumask want_unshared __initdata;
135423 +static struct cpumask want_shared __initdata;
135424 +
135425 +static int __init parse_qportals(char *str)
135426 +{
135427 + return parse_portals_bootarg(str, &want_shared, &want_unshared,
135428 + "qportals");
135429 +}
135430 +__setup("qportals=", parse_qportals);
135431 +
135432 +static void qman_portal_update_sdest(const struct qm_portal_config *pcfg,
135433 + unsigned int cpu)
135434 +{
135435 +#ifdef CONFIG_FSL_PAMU
135436 + struct pamu_stash_attribute stash_attr;
135437 + int ret;
135438 +
135439 + if (pcfg->iommu_domain) {
135440 + stash_attr.cpu = cpu;
135441 + stash_attr.cache = PAMU_ATTR_CACHE_L1;
135442 + /* set stash information for the window */
135443 + stash_attr.window = 0;
135444 + ret = iommu_domain_set_attr(pcfg->iommu_domain,
135445 + DOMAIN_ATTR_FSL_PAMU_STASH, &stash_attr);
135446 + if (ret < 0) {
135447 + pr_err("Failed to update pamu stash setting\n");
135448 + return;
135449 + }
135450 + }
135451 +#endif
135452 +#ifdef CONFIG_FSL_QMAN_CONFIG
135453 + if (qman_set_sdest(pcfg->public_cfg.channel, cpu))
135454 + pr_warn("Failed to update portal's stash request queue\n");
135455 +#endif
135456 +}
135457 +
135458 +static int qman_offline_cpu(unsigned int cpu)
135459 +{
135460 + struct qman_portal *p;
135461 + const struct qm_portal_config *pcfg;
135462 + p = (struct qman_portal *)affine_portals[cpu];
135463 + if (p) {
135464 + pcfg = qman_get_qm_portal_config(p);
135465 + if (pcfg) {
135466 + irq_set_affinity(pcfg->public_cfg.irq, cpumask_of(0));
135467 + qman_portal_update_sdest(pcfg, 0);
135468 + }
135469 + }
135470 + return 0;
135471 +}
135472 +
135473 +#ifdef CONFIG_HOTPLUG_CPU
135474 +static int qman_online_cpu(unsigned int cpu)
135475 +{
135476 + struct qman_portal *p;
135477 + const struct qm_portal_config *pcfg;
135478 + p = (struct qman_portal *)affine_portals[cpu];
135479 + if (p) {
135480 + pcfg = qman_get_qm_portal_config(p);
135481 + if (pcfg) {
135482 + irq_set_affinity(pcfg->public_cfg.irq, cpumask_of(cpu));
135483 + qman_portal_update_sdest(pcfg, cpu);
135484 + }
135485 + }
135486 + return 0;
135487 +}
135488 +
135489 +static int qman_hotplug_cpu_callback(struct notifier_block *nfb,
135490 + unsigned long action, void *hcpu)
135491 +{
135492 + unsigned int cpu = (unsigned long)hcpu;
135493 +
135494 + switch (action) {
135495 + case CPU_ONLINE:
135496 + case CPU_ONLINE_FROZEN:
135497 + qman_online_cpu(cpu);
135498 + break;
135499 + case CPU_DOWN_PREPARE:
135500 + case CPU_DOWN_PREPARE_FROZEN:
135501 + qman_offline_cpu(cpu);
135502 + default:
135503 + break;
135504 + }
135505 + return NOTIFY_OK;
135506 +}
135507 +
135508 +static struct notifier_block qman_hotplug_cpu_notifier = {
135509 + .notifier_call = qman_hotplug_cpu_callback,
135510 +};
135511 +#endif /* CONFIG_HOTPLUG_CPU */
135512 +
135513 +__init int qman_init(void)
135514 +{
135515 + struct cpumask slave_cpus;
135516 + struct cpumask unshared_cpus = *cpu_none_mask;
135517 + struct cpumask shared_cpus = *cpu_none_mask;
135518 + LIST_HEAD(unshared_pcfgs);
135519 + LIST_HEAD(shared_pcfgs);
135520 + struct device_node *dn;
135521 + struct qm_portal_config *pcfg;
135522 + struct qman_portal *p;
135523 + int cpu, ret;
135524 + const u32 *clk;
135525 + struct cpumask offline_cpus;
135526 +
135527 + /* Initialise the Qman (CCSR) device */
135528 + for_each_compatible_node(dn, NULL, "fsl,qman") {
135529 + if (!qman_init_ccsr(dn))
135530 + pr_info("Qman err interrupt handler present\n");
135531 + else
135532 + pr_err("Qman CCSR setup failed\n");
135533 +
135534 + clk = of_get_property(dn, "clock-frequency", NULL);
135535 + if (!clk)
135536 + pr_warn("Can't find Qman clock frequency\n");
135537 + else
135538 + qman_clk = be32_to_cpu(*clk);
135539 + }
135540 +#ifdef CONFIG_FSL_QMAN_FQ_LOOKUP
135541 + /* Setup lookup table for FQ demux */
135542 + ret = qman_setup_fq_lookup_table(get_qman_fqd_size()/64);
135543 + if (ret)
135544 + return ret;
135545 +#endif
135546 +
135547 + /* Get qman ip revision */
135548 + qman_get_ip_revision(dn);
135549 + if ((qman_ip_rev & 0xff00) >= QMAN_REV30) {
135550 + qm_channel_pool1 = QMAN_CHANNEL_POOL1_REV3;
135551 + qm_channel_caam = QMAN_CHANNEL_CAAM_REV3;
135552 + qm_channel_pme = QMAN_CHANNEL_PME_REV3;
135553 + }
135554 +
135555 + if ((qman_ip_rev == QMAN_REV31) && (qman_ip_cfg == QMAN_REV_CFG_2))
135556 + qm_channel_dce = QMAN_CHANNEL_DCE_QMANREV312;
135557 +
135558 + /*
135559 + * Parse the ceetm node to get how many ceetm instances are supported
135560 + * on the current silicon. num_ceetms must be confirmed before portals
135561 + * are intiailized.
135562 + */
135563 + num_ceetms = 0;
135564 + for_each_compatible_node(dn, NULL, "fsl,qman-ceetm")
135565 + num_ceetms++;
135566 +
135567 + /* Parse pool channels into the SDQCR mask. (Must happen before portals
135568 + * are initialised.) */
135569 + for_each_compatible_node(dn, NULL, "fsl,pool-channel-range") {
135570 + ret = fsl_pool_channel_range_sdqcr(dn);
135571 + if (ret)
135572 + return ret;
135573 + }
135574 +
135575 + memset(affine_portals, 0, sizeof(void *) * num_possible_cpus());
135576 + /* Initialise portals. See bman_driver.c for comments */
135577 + for_each_compatible_node(dn, NULL, "fsl,qman-portal") {
135578 + if (!of_device_is_available(dn))
135579 + continue;
135580 + pcfg = parse_pcfg(dn);
135581 + if (pcfg) {
135582 + pcfg->public_cfg.pools = pools_sdqcr;
135583 + list_add_tail(&pcfg->list, &unused_pcfgs);
135584 + }
135585 + }
135586 + for_each_possible_cpu(cpu) {
135587 + if (cpumask_test_cpu(cpu, &want_shared)) {
135588 + pcfg = get_pcfg(&unused_pcfgs);
135589 + if (!pcfg)
135590 + break;
135591 + pcfg->public_cfg.cpu = cpu;
135592 + list_add_tail(&pcfg->list, &shared_pcfgs);
135593 + cpumask_set_cpu(cpu, &shared_cpus);
135594 + }
135595 + if (cpumask_test_cpu(cpu, &want_unshared)) {
135596 + if (cpumask_test_cpu(cpu, &shared_cpus))
135597 + continue;
135598 + pcfg = get_pcfg(&unused_pcfgs);
135599 + if (!pcfg)
135600 + break;
135601 + pcfg->public_cfg.cpu = cpu;
135602 + list_add_tail(&pcfg->list, &unshared_pcfgs);
135603 + cpumask_set_cpu(cpu, &unshared_cpus);
135604 + }
135605 + }
135606 + if (list_empty(&shared_pcfgs) && list_empty(&unshared_pcfgs)) {
135607 + for_each_online_cpu(cpu) {
135608 + pcfg = get_pcfg(&unused_pcfgs);
135609 + if (!pcfg)
135610 + break;
135611 + pcfg->public_cfg.cpu = cpu;
135612 + list_add_tail(&pcfg->list, &unshared_pcfgs);
135613 + cpumask_set_cpu(cpu, &unshared_cpus);
135614 + }
135615 + }
135616 + cpumask_andnot(&slave_cpus, cpu_possible_mask, &shared_cpus);
135617 + cpumask_andnot(&slave_cpus, &slave_cpus, &unshared_cpus);
135618 + if (cpumask_empty(&slave_cpus)) {
135619 + if (!list_empty(&shared_pcfgs)) {
135620 + cpumask_or(&unshared_cpus, &unshared_cpus,
135621 + &shared_cpus);
135622 + cpumask_clear(&shared_cpus);
135623 + list_splice_tail(&shared_pcfgs, &unshared_pcfgs);
135624 + INIT_LIST_HEAD(&shared_pcfgs);
135625 + }
135626 + } else {
135627 + if (list_empty(&shared_pcfgs)) {
135628 + pcfg = get_pcfg(&unshared_pcfgs);
135629 + if (!pcfg) {
135630 + pr_crit("No QMan portals available!\n");
135631 + return 0;
135632 + }
135633 + cpumask_clear_cpu(pcfg->public_cfg.cpu, &unshared_cpus);
135634 + cpumask_set_cpu(pcfg->public_cfg.cpu, &shared_cpus);
135635 + list_add_tail(&pcfg->list, &shared_pcfgs);
135636 + }
135637 + }
135638 + list_for_each_entry(pcfg, &unshared_pcfgs, list) {
135639 + pcfg->public_cfg.is_shared = 0;
135640 + p = init_pcfg(pcfg);
135641 + if (!p) {
135642 + pr_crit("Unable to configure portals\n");
135643 + return 0;
135644 + }
135645 + }
135646 + list_for_each_entry(pcfg, &shared_pcfgs, list) {
135647 + pcfg->public_cfg.is_shared = 1;
135648 + p = init_pcfg(pcfg);
135649 + if (p)
135650 + shared_portals[num_shared_portals++] = p;
135651 + }
135652 + if (!cpumask_empty(&slave_cpus))
135653 + for_each_cpu(cpu, &slave_cpus)
135654 + init_slave(cpu);
135655 + pr_info("Qman portals initialised\n");
135656 + cpumask_andnot(&offline_cpus, cpu_possible_mask, cpu_online_mask);
135657 + for_each_cpu(cpu, &offline_cpus)
135658 + qman_offline_cpu(cpu);
135659 +#ifdef CONFIG_HOTPLUG_CPU
135660 + register_hotcpu_notifier(&qman_hotplug_cpu_notifier);
135661 +#endif
135662 + return 0;
135663 +}
135664 +
135665 +__init int qman_resource_init(void)
135666 +{
135667 + struct device_node *dn;
135668 + int ret;
135669 +
135670 + /* Initialise FQID allocation ranges */
135671 + for_each_compatible_node(dn, NULL, "fsl,fqid-range") {
135672 + ret = fsl_fqid_range_init(dn);
135673 + if (ret)
135674 + return ret;
135675 + }
135676 + /* Initialise CGRID allocation ranges */
135677 + for_each_compatible_node(dn, NULL, "fsl,cgrid-range") {
135678 + ret = fsl_cgrid_range_init(dn);
135679 + if (ret)
135680 + return ret;
135681 + }
135682 + /* Parse pool channels into the allocator. (Must happen after portals
135683 + * are initialised.) */
135684 + for_each_compatible_node(dn, NULL, "fsl,pool-channel-range") {
135685 + ret = fsl_pool_channel_range_init(dn);
135686 + if (ret)
135687 + return ret;
135688 + }
135689 +
135690 + /* Parse CEETM */
135691 + for_each_compatible_node(dn, NULL, "fsl,qman-ceetm") {
135692 + ret = fsl_ceetm_init(dn);
135693 + if (ret)
135694 + return ret;
135695 + }
135696 + return 0;
135697 +}
135698 +
135699 +#ifdef CONFIG_SUSPEND
135700 +void suspend_unused_qportal(void)
135701 +{
135702 + struct qm_portal_config *pcfg;
135703 +
135704 + if (list_empty(&unused_pcfgs))
135705 + return;
135706 +
135707 + list_for_each_entry(pcfg, &unused_pcfgs, list) {
135708 +#ifdef CONFIG_PM_DEBUG
135709 + pr_info("Need to save qportal %d\n", pcfg->public_cfg.index);
135710 +#endif
135711 + /* save isdr, disable all via isdr, clear isr */
135712 + pcfg->saved_isdr =
135713 + __raw_readl(pcfg->addr_virt[DPA_PORTAL_CI] + 0xe08);
135714 + __raw_writel(0xffffffff, pcfg->addr_virt[DPA_PORTAL_CI] +
135715 + 0xe08);
135716 + __raw_writel(0xffffffff, pcfg->addr_virt[DPA_PORTAL_CI] +
135717 + 0xe00);
135718 + }
135719 + return;
135720 +}
135721 +
135722 +void resume_unused_qportal(void)
135723 +{
135724 + struct qm_portal_config *pcfg;
135725 +
135726 + if (list_empty(&unused_pcfgs))
135727 + return;
135728 +
135729 + list_for_each_entry(pcfg, &unused_pcfgs, list) {
135730 +#ifdef CONFIG_PM_DEBUG
135731 + pr_info("Need to resume qportal %d\n", pcfg->public_cfg.index);
135732 +#endif
135733 + /* restore isdr */
135734 + __raw_writel(pcfg->saved_isdr,
135735 + pcfg->addr_virt[DPA_PORTAL_CI] + 0xe08);
135736 + }
135737 + return;
135738 +}
135739 +#endif
135740 --- /dev/null
135741 +++ b/drivers/staging/fsl_qbman/qman_high.c
135742 @@ -0,0 +1,5669 @@
135743 +/* Copyright 2008-2012 Freescale Semiconductor, Inc.
135744 + *
135745 + * Redistribution and use in source and binary forms, with or without
135746 + * modification, are permitted provided that the following conditions are met:
135747 + * * Redistributions of source code must retain the above copyright
135748 + * notice, this list of conditions and the following disclaimer.
135749 + * * Redistributions in binary form must reproduce the above copyright
135750 + * notice, this list of conditions and the following disclaimer in the
135751 + * documentation and/or other materials provided with the distribution.
135752 + * * Neither the name of Freescale Semiconductor nor the
135753 + * names of its contributors may be used to endorse or promote products
135754 + * derived from this software without specific prior written permission.
135755 + *
135756 + *
135757 + * ALTERNATIVELY, this software may be distributed under the terms of the
135758 + * GNU General Public License ("GPL") as published by the Free Software
135759 + * Foundation, either version 2 of that License or (at your option) any
135760 + * later version.
135761 + *
135762 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
135763 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
135764 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
135765 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
135766 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
135767 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
135768 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
135769 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
135770 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
135771 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
135772 + */
135773 +
135774 +#include "qman_low.h"
135775 +
135776 +/* Compilation constants */
135777 +#define DQRR_MAXFILL 15
135778 +#define EQCR_ITHRESH 4 /* if EQCR congests, interrupt threshold */
135779 +#define IRQNAME "QMan portal %d"
135780 +#define MAX_IRQNAME 16 /* big enough for "QMan portal %d" */
135781 +
135782 +/* Divide 'n' by 'd', rounding down if 'r' is negative, rounding up if it's
135783 + * positive, and rounding to the closest value if it's zero. NB, this macro
135784 + * implicitly upgrades parameters to unsigned 64-bit, so feed it with types
135785 + * that are compatible with this. NB, these arguments should not be expressions
135786 + * unless it is safe for them to be evaluated multiple times. Eg. do not pass
135787 + * in "some_value++" as a parameter to the macro! */
135788 +#define ROUNDING(n, d, r) \
135789 + (((r) < 0) ? div64_u64((n), (d)) : \
135790 + (((r) > 0) ? div64_u64(((n) + (d) - 1), (d)) : \
135791 + div64_u64(((n) + ((d) / 2)), (d))))
135792 +
135793 +/* Lock/unlock frame queues, subject to the "LOCKED" flag. This is about
135794 + * inter-processor locking only. Note, FQLOCK() is always called either under a
135795 + * local_irq_save() or from interrupt context - hence there's no need for irq
135796 + * protection (and indeed, attempting to nest irq-protection doesn't work, as
135797 + * the "irq en/disable" machinery isn't recursive...). */
135798 +#define FQLOCK(fq) \
135799 + do { \
135800 + struct qman_fq *__fq478 = (fq); \
135801 + if (fq_isset(__fq478, QMAN_FQ_FLAG_LOCKED)) \
135802 + spin_lock(&__fq478->fqlock); \
135803 + } while (0)
135804 +#define FQUNLOCK(fq) \
135805 + do { \
135806 + struct qman_fq *__fq478 = (fq); \
135807 + if (fq_isset(__fq478, QMAN_FQ_FLAG_LOCKED)) \
135808 + spin_unlock(&__fq478->fqlock); \
135809 + } while (0)
135810 +
135811 +static inline void fq_set(struct qman_fq *fq, u32 mask)
135812 +{
135813 + set_bits(mask, &fq->flags);
135814 +}
135815 +static inline void fq_clear(struct qman_fq *fq, u32 mask)
135816 +{
135817 + clear_bits(mask, &fq->flags);
135818 +}
135819 +static inline int fq_isset(struct qman_fq *fq, u32 mask)
135820 +{
135821 + return fq->flags & mask;
135822 +}
135823 +static inline int fq_isclear(struct qman_fq *fq, u32 mask)
135824 +{
135825 + return !(fq->flags & mask);
135826 +}
135827 +
135828 +struct qman_portal {
135829 + struct qm_portal p;
135830 + unsigned long bits; /* PORTAL_BITS_*** - dynamic, strictly internal */
135831 + unsigned long irq_sources;
135832 + u32 use_eqcr_ci_stashing;
135833 + u32 slowpoll; /* only used when interrupts are off */
135834 + struct qman_fq *vdqcr_owned; /* only 1 volatile dequeue at a time */
135835 +#ifdef CONFIG_FSL_DPA_CAN_WAIT_SYNC
135836 + struct qman_fq *eqci_owned; /* only 1 enqueue WAIT_SYNC at a time */
135837 +#endif
135838 +#ifdef CONFIG_FSL_DPA_PORTAL_SHARE
135839 + raw_spinlock_t sharing_lock; /* only used if is_shared */
135840 + int is_shared;
135841 + struct qman_portal *sharing_redirect;
135842 +#endif
135843 + u32 sdqcr;
135844 + int dqrr_disable_ref;
135845 + /* A portal-specific handler for DCP ERNs. If this is NULL, the global
135846 + * handler is called instead. */
135847 + qman_cb_dc_ern cb_dc_ern;
135848 + /* When the cpu-affine portal is activated, this is non-NULL */
135849 + const struct qm_portal_config *config;
135850 + /* This is needed for providing a non-NULL device to dma_map_***() */
135851 + struct platform_device *pdev;
135852 + struct dpa_rbtree retire_table;
135853 + char irqname[MAX_IRQNAME];
135854 + /* 2-element array. cgrs[0] is mask, cgrs[1] is snapshot. */
135855 + struct qman_cgrs *cgrs;
135856 + /* linked-list of CSCN handlers. */
135857 + struct list_head cgr_cbs;
135858 + /* list lock */
135859 + spinlock_t cgr_lock;
135860 + /* 2-element array. ccgrs[0] is mask, ccgrs[1] is snapshot. */
135861 + struct qman_ccgrs *ccgrs[QMAN_CEETM_MAX];
135862 + /* 256-element array, each is a linked-list of CCSCN handlers. */
135863 + struct list_head ccgr_cbs[QMAN_CEETM_MAX];
135864 + /* list lock */
135865 + spinlock_t ccgr_lock;
135866 + /* track if memory was allocated by the driver */
135867 + u8 alloced;
135868 + /* power management data */
135869 + u32 save_isdr;
135870 +#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
135871 + /* Keep a shadow copy of the DQRR on LE systems as the SW needs to
135872 + * do byte swaps of DQRR read only memory. First entry must be aligned
135873 + * to 2 ** 10 to ensure DQRR index calculations based shadow copy
135874 + * address (6 bits for address shift + 4 bits for the DQRR size).
135875 + */
135876 + struct qm_dqrr_entry shadow_dqrr[QM_DQRR_SIZE] __aligned(1024);
135877 +#endif
135878 +};
135879 +
135880 +#ifdef CONFIG_FSL_DPA_PORTAL_SHARE
135881 +#define PORTAL_IRQ_LOCK(p, irqflags) \
135882 + do { \
135883 + if ((p)->is_shared) \
135884 + raw_spin_lock_irqsave(&(p)->sharing_lock, irqflags); \
135885 + else \
135886 + local_irq_save(irqflags); \
135887 + } while (0)
135888 +#define PORTAL_IRQ_UNLOCK(p, irqflags) \
135889 + do { \
135890 + if ((p)->is_shared) \
135891 + raw_spin_unlock_irqrestore(&(p)->sharing_lock, \
135892 + irqflags); \
135893 + else \
135894 + local_irq_restore(irqflags); \
135895 + } while (0)
135896 +#else
135897 +#define PORTAL_IRQ_LOCK(p, irqflags) local_irq_save(irqflags)
135898 +#define PORTAL_IRQ_UNLOCK(p, irqflags) local_irq_restore(irqflags)
135899 +#endif
135900 +
135901 +/* Global handler for DCP ERNs. Used when the portal receiving the message does
135902 + * not have a portal-specific handler. */
135903 +static qman_cb_dc_ern cb_dc_ern;
135904 +
135905 +static cpumask_t affine_mask;
135906 +static DEFINE_SPINLOCK(affine_mask_lock);
135907 +static u16 affine_channels[NR_CPUS];
135908 +static DEFINE_PER_CPU(struct qman_portal, qman_affine_portal);
135909 +void *affine_portals[NR_CPUS];
135910 +
135911 +/* "raw" gets the cpu-local struct whether it's a redirect or not. */
135912 +static inline struct qman_portal *get_raw_affine_portal(void)
135913 +{
135914 + return &get_cpu_var(qman_affine_portal);
135915 +}
135916 +/* For ops that can redirect, this obtains the portal to use */
135917 +#ifdef CONFIG_FSL_DPA_PORTAL_SHARE
135918 +static inline struct qman_portal *get_affine_portal(void)
135919 +{
135920 + struct qman_portal *p = get_raw_affine_portal();
135921 + if (p->sharing_redirect)
135922 + return p->sharing_redirect;
135923 + return p;
135924 +}
135925 +#else
135926 +#define get_affine_portal() get_raw_affine_portal()
135927 +#endif
135928 +/* For every "get", there must be a "put" */
135929 +static inline void put_affine_portal(void)
135930 +{
135931 + put_cpu_var(qman_affine_portal);
135932 +}
135933 +/* Exception: poll functions assume the caller is cpu-affine and in no risk of
135934 + * re-entrance, which are the two reasons we usually use the get/put_cpu_var()
135935 + * semantic - ie. to disable pre-emption. Some use-cases expect the execution
135936 + * context to remain as non-atomic during poll-triggered callbacks as it was
135937 + * when the poll API was first called (eg. NAPI), so we go out of our way in
135938 + * this case to not disable pre-emption. */
135939 +static inline struct qman_portal *get_poll_portal(void)
135940 +{
135941 + return &get_cpu_var(qman_affine_portal);
135942 +}
135943 +#define put_poll_portal()
135944 +
135945 +/* This gives a FQID->FQ lookup to cover the fact that we can't directly demux
135946 + * retirement notifications (the fact they are sometimes h/w-consumed means that
135947 + * contextB isn't always a s/w demux - and as we can't know which case it is
135948 + * when looking at the notification, we have to use the slow lookup for all of
135949 + * them). NB, it's possible to have multiple FQ objects refer to the same FQID
135950 + * (though at most one of them should be the consumer), so this table isn't for
135951 + * all FQs - FQs are added when retirement commands are issued, and removed when
135952 + * they complete, which also massively reduces the size of this table. */
135953 +IMPLEMENT_DPA_RBTREE(fqtree, struct qman_fq, node, fqid);
135954 +
135955 +/* This is what everything can wait on, even if it migrates to a different cpu
135956 + * to the one whose affine portal it is waiting on. */
135957 +static DECLARE_WAIT_QUEUE_HEAD(affine_queue);
135958 +
135959 +static inline int table_push_fq(struct qman_portal *p, struct qman_fq *fq)
135960 +{
135961 + int ret = fqtree_push(&p->retire_table, fq);
135962 + if (ret)
135963 + pr_err("ERROR: double FQ-retirement %d\n", fq->fqid);
135964 + return ret;
135965 +}
135966 +
135967 +static inline void table_del_fq(struct qman_portal *p, struct qman_fq *fq)
135968 +{
135969 + fqtree_del(&p->retire_table, fq);
135970 +}
135971 +
135972 +static inline struct qman_fq *table_find_fq(struct qman_portal *p, u32 fqid)
135973 +{
135974 + return fqtree_find(&p->retire_table, fqid);
135975 +}
135976 +
135977 +#ifdef CONFIG_FSL_QMAN_FQ_LOOKUP
135978 +static void **qman_fq_lookup_table;
135979 +static size_t qman_fq_lookup_table_size;
135980 +
135981 +int qman_setup_fq_lookup_table(size_t num_entries)
135982 +{
135983 + num_entries++;
135984 + /* Allocate 1 more entry since the first entry is not used */
135985 + qman_fq_lookup_table = vzalloc((num_entries * sizeof(void *)));
135986 + if (!qman_fq_lookup_table) {
135987 + pr_err("QMan: Could not allocate fq lookup table\n");
135988 + return -ENOMEM;
135989 + }
135990 + qman_fq_lookup_table_size = num_entries;
135991 + pr_info("QMan: Allocated lookup table at %p, entry count %lu\n",
135992 + qman_fq_lookup_table,
135993 + (unsigned long)qman_fq_lookup_table_size);
135994 + return 0;
135995 +}
135996 +
135997 +/* global structure that maintains fq object mapping */
135998 +static DEFINE_SPINLOCK(fq_hash_table_lock);
135999 +
136000 +static int find_empty_fq_table_entry(u32 *entry, struct qman_fq *fq)
136001 +{
136002 + u32 i;
136003 +
136004 + spin_lock(&fq_hash_table_lock);
136005 + /* Can't use index zero because this has special meaning
136006 + * in context_b field. */
136007 + for (i = 1; i < qman_fq_lookup_table_size; i++) {
136008 + if (qman_fq_lookup_table[i] == NULL) {
136009 + *entry = i;
136010 + qman_fq_lookup_table[i] = fq;
136011 + spin_unlock(&fq_hash_table_lock);
136012 + return 0;
136013 + }
136014 + }
136015 + spin_unlock(&fq_hash_table_lock);
136016 + return -ENOMEM;
136017 +}
136018 +
136019 +static void clear_fq_table_entry(u32 entry)
136020 +{
136021 + spin_lock(&fq_hash_table_lock);
136022 + BUG_ON(entry >= qman_fq_lookup_table_size);
136023 + qman_fq_lookup_table[entry] = NULL;
136024 + spin_unlock(&fq_hash_table_lock);
136025 +}
136026 +
136027 +static inline struct qman_fq *get_fq_table_entry(u32 entry)
136028 +{
136029 + BUG_ON(entry >= qman_fq_lookup_table_size);
136030 + return qman_fq_lookup_table[entry];
136031 +}
136032 +#endif
136033 +
136034 +static inline void cpu_to_hw_fqd(struct qm_fqd *fqd)
136035 +{
136036 + /* Byteswap the FQD to HW format */
136037 + fqd->fq_ctrl = cpu_to_be16(fqd->fq_ctrl);
136038 + fqd->dest_wq = cpu_to_be16(fqd->dest_wq);
136039 + fqd->ics_cred = cpu_to_be16(fqd->ics_cred);
136040 + fqd->context_b = cpu_to_be32(fqd->context_b);
136041 + fqd->context_a.opaque = cpu_to_be64(fqd->context_a.opaque);
136042 +}
136043 +
136044 +static inline void hw_fqd_to_cpu(struct qm_fqd *fqd)
136045 +{
136046 + /* Byteswap the FQD to CPU format */
136047 + fqd->fq_ctrl = be16_to_cpu(fqd->fq_ctrl);
136048 + fqd->dest_wq = be16_to_cpu(fqd->dest_wq);
136049 + fqd->ics_cred = be16_to_cpu(fqd->ics_cred);
136050 + fqd->context_b = be32_to_cpu(fqd->context_b);
136051 + fqd->context_a.opaque = be64_to_cpu(fqd->context_a.opaque);
136052 +}
136053 +
136054 +/* Swap a 40 bit address */
136055 +static inline u64 cpu_to_be40(u64 in)
136056 +{
136057 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
136058 + return in;
136059 +#else
136060 + u64 out = 0;
136061 + u8 *p = (u8 *) &out;
136062 + p[0] = in >> 32;
136063 + p[1] = in >> 24;
136064 + p[2] = in >> 16;
136065 + p[3] = in >> 8;
136066 + p[4] = in >> 0;
136067 + return out;
136068 +#endif
136069 +}
136070 +static inline u64 be40_to_cpu(u64 in)
136071 +{
136072 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
136073 + return in;
136074 +#else
136075 + u64 out = 0;
136076 + u8 *pout = (u8 *) &out;
136077 + u8 *pin = (u8 *) &in;
136078 + pout[0] = pin[4];
136079 + pout[1] = pin[3];
136080 + pout[2] = pin[2];
136081 + pout[3] = pin[1];
136082 + pout[4] = pin[0];
136083 + return out;
136084 +#endif
136085 +}
136086 +
136087 +/* Swap a 24 bit value */
136088 +static inline u32 cpu_to_be24(u32 in)
136089 +{
136090 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
136091 + return in;
136092 +#else
136093 + u32 out = 0;
136094 + u8 *p = (u8 *) &out;
136095 + p[0] = in >> 16;
136096 + p[1] = in >> 8;
136097 + p[2] = in >> 0;
136098 + return out;
136099 +#endif
136100 +}
136101 +
136102 +static inline u32 be24_to_cpu(u32 in)
136103 +{
136104 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
136105 + return in;
136106 +#else
136107 + u32 out = 0;
136108 + u8 *pout = (u8 *) &out;
136109 + u8 *pin = (u8 *) &in;
136110 + pout[0] = pin[2];
136111 + pout[1] = pin[1];
136112 + pout[2] = pin[0];
136113 + return out;
136114 +#endif
136115 +}
136116 +
136117 +static inline u64 be48_to_cpu(u64 in)
136118 +{
136119 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
136120 + return in;
136121 +#else
136122 + u64 out = 0;
136123 + u8 *pout = (u8 *) &out;
136124 + u8 *pin = (u8 *) &in;
136125 +
136126 + pout[0] = pin[5];
136127 + pout[1] = pin[4];
136128 + pout[2] = pin[3];
136129 + pout[3] = pin[2];
136130 + pout[4] = pin[1];
136131 + pout[5] = pin[0];
136132 + return out;
136133 +#endif
136134 +}
136135 +static inline void cpu_to_hw_fd(struct qm_fd *fd)
136136 +{
136137 + fd->opaque_addr = cpu_to_be64(fd->opaque_addr);
136138 + fd->status = cpu_to_be32(fd->status);
136139 + fd->opaque = cpu_to_be32(fd->opaque);
136140 +}
136141 +
136142 +static inline void hw_fd_to_cpu(struct qm_fd *fd)
136143 +{
136144 + fd->opaque_addr = be64_to_cpu(fd->opaque_addr);
136145 + fd->status = be32_to_cpu(fd->status);
136146 + fd->opaque = be32_to_cpu(fd->opaque);
136147 +}
136148 +
136149 +static inline void hw_cq_query_to_cpu(struct qm_mcr_ceetm_cq_query *cq_query)
136150 +{
136151 + cq_query->ccgid = be16_to_cpu(cq_query->ccgid);
136152 + cq_query->state = be16_to_cpu(cq_query->state);
136153 + cq_query->pfdr_hptr = be24_to_cpu(cq_query->pfdr_hptr);
136154 + cq_query->pfdr_tptr = be24_to_cpu(cq_query->pfdr_tptr);
136155 + cq_query->od1_xsfdr = be16_to_cpu(cq_query->od1_xsfdr);
136156 + cq_query->od2_xsfdr = be16_to_cpu(cq_query->od2_xsfdr);
136157 + cq_query->od3_xsfdr = be16_to_cpu(cq_query->od3_xsfdr);
136158 + cq_query->od4_xsfdr = be16_to_cpu(cq_query->od4_xsfdr);
136159 + cq_query->od5_xsfdr = be16_to_cpu(cq_query->od5_xsfdr);
136160 + cq_query->od6_xsfdr = be16_to_cpu(cq_query->od6_xsfdr);
136161 + cq_query->ra1_xsfdr = be16_to_cpu(cq_query->ra1_xsfdr);
136162 + cq_query->ra2_xsfdr = be16_to_cpu(cq_query->ra2_xsfdr);
136163 + cq_query->frm_cnt = be24_to_cpu(cq_query->frm_cnt);
136164 +}
136165 +
136166 +static inline void hw_ccgr_query_to_cpu(struct qm_mcr_ceetm_ccgr_query *ccgr_q)
136167 +{
136168 + int i;
136169 +
136170 + ccgr_q->cm_query.cs_thres.hword =
136171 + be16_to_cpu(ccgr_q->cm_query.cs_thres.hword);
136172 + ccgr_q->cm_query.cs_thres_x.hword =
136173 + be16_to_cpu(ccgr_q->cm_query.cs_thres_x.hword);
136174 + ccgr_q->cm_query.td_thres.hword =
136175 + be16_to_cpu(ccgr_q->cm_query.td_thres.hword);
136176 + ccgr_q->cm_query.wr_parm_g.word =
136177 + be32_to_cpu(ccgr_q->cm_query.wr_parm_g.word);
136178 + ccgr_q->cm_query.wr_parm_y.word =
136179 + be32_to_cpu(ccgr_q->cm_query.wr_parm_y.word);
136180 + ccgr_q->cm_query.wr_parm_r.word =
136181 + be32_to_cpu(ccgr_q->cm_query.wr_parm_r.word);
136182 + ccgr_q->cm_query.cscn_targ_dcp =
136183 + be16_to_cpu(ccgr_q->cm_query.cscn_targ_dcp);
136184 + ccgr_q->cm_query.i_cnt = be40_to_cpu(ccgr_q->cm_query.i_cnt);
136185 + ccgr_q->cm_query.a_cnt = be40_to_cpu(ccgr_q->cm_query.a_cnt);
136186 + for (i = 0; i < ARRAY_SIZE(ccgr_q->cm_query.cscn_targ_swp); i++)
136187 + ccgr_q->cm_query.cscn_targ_swp[i] =
136188 + be32_to_cpu(ccgr_q->cm_query.cscn_targ_swp[i]);
136189 +}
136190 +
136191 +/* In the case that slow- and fast-path handling are both done by qman_poll()
136192 + * (ie. because there is no interrupt handling), we ought to balance how often
136193 + * we do the fast-path poll versus the slow-path poll. We'll use two decrementer
136194 + * sources, so we call the fast poll 'n' times before calling the slow poll
136195 + * once. The idle decrementer constant is used when the last slow-poll detected
136196 + * no work to do, and the busy decrementer constant when the last slow-poll had
136197 + * work to do. */
136198 +#define SLOW_POLL_IDLE 1000
136199 +#define SLOW_POLL_BUSY 10
136200 +static u32 __poll_portal_slow(struct qman_portal *p, u32 is);
136201 +static inline unsigned int __poll_portal_fast(struct qman_portal *p,
136202 + unsigned int poll_limit);
136203 +
136204 +/* Portal interrupt handler */
136205 +static irqreturn_t portal_isr(__always_unused int irq, void *ptr)
136206 +{
136207 + struct qman_portal *p = ptr;
136208 + /*
136209 + * The CSCI/CCSCI source is cleared inside __poll_portal_slow(), because
136210 + * it could race against a Query Congestion State command also given
136211 + * as part of the handling of this interrupt source. We mustn't
136212 + * clear it a second time in this top-level function.
136213 + */
136214 + u32 clear = QM_DQAVAIL_MASK | (p->irq_sources &
136215 + ~(QM_PIRQ_CSCI | QM_PIRQ_CCSCI));
136216 + u32 is = qm_isr_status_read(&p->p) & p->irq_sources;
136217 + /* DQRR-handling if it's interrupt-driven */
136218 + if (is & QM_PIRQ_DQRI)
136219 + __poll_portal_fast(p, CONFIG_FSL_QMAN_POLL_LIMIT);
136220 + /* Handling of anything else that's interrupt-driven */
136221 + clear |= __poll_portal_slow(p, is);
136222 + qm_isr_status_clear(&p->p, clear);
136223 + return IRQ_HANDLED;
136224 +}
136225 +
136226 +/* This inner version is used privately by qman_create_affine_portal(), as well
136227 + * as by the exported qman_stop_dequeues(). */
136228 +static inline void qman_stop_dequeues_ex(struct qman_portal *p)
136229 +{
136230 + unsigned long irqflags __maybe_unused;
136231 + PORTAL_IRQ_LOCK(p, irqflags);
136232 + if (!(p->dqrr_disable_ref++))
136233 + qm_dqrr_set_maxfill(&p->p, 0);
136234 + PORTAL_IRQ_UNLOCK(p, irqflags);
136235 +}
136236 +
136237 +static int drain_mr_fqrni(struct qm_portal *p)
136238 +{
136239 + const struct qm_mr_entry *msg;
136240 +loop:
136241 + msg = qm_mr_current(p);
136242 + if (!msg) {
136243 + /* if MR was full and h/w had other FQRNI entries to produce, we
136244 + * need to allow it time to produce those entries once the
136245 + * existing entries are consumed. A worst-case situation
136246 + * (fully-loaded system) means h/w sequencers may have to do 3-4
136247 + * other things before servicing the portal's MR pump, each of
136248 + * which (if slow) may take ~50 qman cycles (which is ~200
136249 + * processor cycles). So rounding up and then multiplying this
136250 + * worst-case estimate by a factor of 10, just to be
136251 + * ultra-paranoid, goes as high as 10,000 cycles. NB, we consume
136252 + * one entry at a time, so h/w has an opportunity to produce new
136253 + * entries well before the ring has been fully consumed, so
136254 + * we're being *really* paranoid here. */
136255 + u64 now, then = mfatb();
136256 + do {
136257 + now = mfatb();
136258 + } while ((then + 10000) > now);
136259 + msg = qm_mr_current(p);
136260 + if (!msg)
136261 + return 0;
136262 + }
136263 + if ((msg->verb & QM_MR_VERB_TYPE_MASK) != QM_MR_VERB_FQRNI) {
136264 + /* We aren't draining anything but FQRNIs */
136265 + pr_err("QMan found verb 0x%x in MR\n", msg->verb);
136266 + return -1;
136267 + }
136268 + qm_mr_next(p);
136269 + qm_mr_cci_consume(p, 1);
136270 + goto loop;
136271 +}
136272 +
136273 +#ifdef CONFIG_SUSPEND
136274 +static int _qman_portal_suspend_noirq(struct device *dev)
136275 +{
136276 + struct qman_portal *p = (struct qman_portal *)dev->platform_data;
136277 +#ifdef CONFIG_PM_DEBUG
136278 + struct platform_device *pdev = to_platform_device(dev);
136279 +#endif
136280 +
136281 + p->save_isdr = qm_isr_disable_read(&p->p);
136282 + qm_isr_disable_write(&p->p, 0xffffffff);
136283 + qm_isr_status_clear(&p->p, 0xffffffff);
136284 +#ifdef CONFIG_PM_DEBUG
136285 + pr_info("Suspend for %s\n", pdev->name);
136286 +#endif
136287 + return 0;
136288 +}
136289 +
136290 +static int _qman_portal_resume_noirq(struct device *dev)
136291 +{
136292 + struct qman_portal *p = (struct qman_portal *)dev->platform_data;
136293 +
136294 + /* restore isdr */
136295 + qm_isr_disable_write(&p->p, p->save_isdr);
136296 + return 0;
136297 +}
136298 +#else
136299 +#define _qman_portal_suspend_noirq NULL
136300 +#define _qman_portal_resume_noirq NULL
136301 +#endif
136302 +
136303 +struct dev_pm_domain qman_portal_device_pm_domain = {
136304 + .ops = {
136305 + USE_PLATFORM_PM_SLEEP_OPS
136306 + .suspend_noirq = _qman_portal_suspend_noirq,
136307 + .resume_noirq = _qman_portal_resume_noirq,
136308 + }
136309 +};
136310 +
136311 +struct qman_portal *qman_create_portal(
136312 + struct qman_portal *portal,
136313 + const struct qm_portal_config *config,
136314 + const struct qman_cgrs *cgrs)
136315 +{
136316 + struct qm_portal *__p;
136317 + char buf[16];
136318 + int ret;
136319 + u32 isdr;
136320 +
136321 + if (!portal) {
136322 + portal = kmalloc(sizeof(*portal), GFP_KERNEL);
136323 + if (!portal)
136324 + return portal;
136325 + portal->alloced = 1;
136326 + } else
136327 + portal->alloced = 0;
136328 +
136329 + __p = &portal->p;
136330 +
136331 +#if (defined CONFIG_PPC || defined CONFIG_PPC64) && defined CONFIG_FSL_PAMU
136332 + /* PAMU is required for stashing */
136333 + portal->use_eqcr_ci_stashing = ((qman_ip_rev >= QMAN_REV30) ?
136334 + 1 : 0);
136335 +#elif defined(CONFIG_ARM) || defined(CONFIG_ARM64)
136336 + portal->use_eqcr_ci_stashing = 1;
136337 +#else
136338 + portal->use_eqcr_ci_stashing = 0;
136339 +#endif
136340 +
136341 + /* prep the low-level portal struct with the mapped addresses from the
136342 + * config, everything that follows depends on it and "config" is more
136343 + * for (de)reference... */
136344 + __p->addr.addr_ce = config->addr_virt[DPA_PORTAL_CE];
136345 + __p->addr.addr_ci = config->addr_virt[DPA_PORTAL_CI];
136346 + /*
136347 + * If CI-stashing is used, the current defaults use a threshold of 3,
136348 + * and stash with high-than-DQRR priority.
136349 + */
136350 + if (qm_eqcr_init(__p, qm_eqcr_pvb,
136351 + portal->use_eqcr_ci_stashing ? 3 : 0, 1)) {
136352 + pr_err("Qman EQCR initialisation failed\n");
136353 + goto fail_eqcr;
136354 + }
136355 + if (qm_dqrr_init(__p, config, qm_dqrr_dpush, qm_dqrr_pvb,
136356 + qm_dqrr_cdc, DQRR_MAXFILL)) {
136357 + pr_err("Qman DQRR initialisation failed\n");
136358 + goto fail_dqrr;
136359 + }
136360 + if (qm_mr_init(__p, qm_mr_pvb, qm_mr_cci)) {
136361 + pr_err("Qman MR initialisation failed\n");
136362 + goto fail_mr;
136363 + }
136364 + if (qm_mc_init(__p)) {
136365 + pr_err("Qman MC initialisation failed\n");
136366 + goto fail_mc;
136367 + }
136368 + if (qm_isr_init(__p)) {
136369 + pr_err("Qman ISR initialisation failed\n");
136370 + goto fail_isr;
136371 + }
136372 + /* static interrupt-gating controls */
136373 + qm_dqrr_set_ithresh(__p, CONFIG_FSL_QMAN_PIRQ_DQRR_ITHRESH);
136374 + qm_mr_set_ithresh(__p, CONFIG_FSL_QMAN_PIRQ_MR_ITHRESH);
136375 + qm_isr_set_iperiod(__p, CONFIG_FSL_QMAN_PIRQ_IPERIOD);
136376 + portal->cgrs = kmalloc(2 * sizeof(*cgrs), GFP_KERNEL);
136377 + if (!portal->cgrs)
136378 + goto fail_cgrs;
136379 + /* initial snapshot is no-depletion */
136380 + qman_cgrs_init(&portal->cgrs[1]);
136381 + if (cgrs)
136382 + portal->cgrs[0] = *cgrs;
136383 + else
136384 + /* if the given mask is NULL, assume all CGRs can be seen */
136385 + qman_cgrs_fill(&portal->cgrs[0]);
136386 + INIT_LIST_HEAD(&portal->cgr_cbs);
136387 + spin_lock_init(&portal->cgr_lock);
136388 + if (num_ceetms) {
136389 + for (ret = 0; ret < num_ceetms; ret++) {
136390 + portal->ccgrs[ret] = kmalloc(2 *
136391 + sizeof(struct qman_ccgrs), GFP_KERNEL);
136392 + if (!portal->ccgrs[ret])
136393 + goto fail_ccgrs;
136394 + qman_ccgrs_init(&portal->ccgrs[ret][1]);
136395 + qman_ccgrs_fill(&portal->ccgrs[ret][0]);
136396 + INIT_LIST_HEAD(&portal->ccgr_cbs[ret]);
136397 + }
136398 + }
136399 + spin_lock_init(&portal->ccgr_lock);
136400 + portal->bits = 0;
136401 + portal->slowpoll = 0;
136402 +#ifdef CONFIG_FSL_DPA_CAN_WAIT_SYNC
136403 + portal->eqci_owned = NULL;
136404 +#endif
136405 +#ifdef CONFIG_FSL_DPA_PORTAL_SHARE
136406 + raw_spin_lock_init(&portal->sharing_lock);
136407 + portal->is_shared = config->public_cfg.is_shared;
136408 + portal->sharing_redirect = NULL;
136409 +#endif
136410 + portal->sdqcr = QM_SDQCR_SOURCE_CHANNELS | QM_SDQCR_COUNT_UPTO3 |
136411 + QM_SDQCR_DEDICATED_PRECEDENCE | QM_SDQCR_TYPE_PRIO_QOS |
136412 + QM_SDQCR_TOKEN_SET(0xab) | QM_SDQCR_CHANNELS_DEDICATED;
136413 + portal->dqrr_disable_ref = 0;
136414 + portal->cb_dc_ern = NULL;
136415 + sprintf(buf, "qportal-%d", config->public_cfg.channel);
136416 + portal->pdev = platform_device_alloc(buf, -1);
136417 + if (!portal->pdev) {
136418 + pr_err("qman_portal - platform_device_alloc() failed\n");
136419 + goto fail_devalloc;
136420 + }
136421 +#if defined(CONFIG_ARM) || defined(CONFIG_ARM64)
136422 + portal->pdev->dev.coherent_dma_mask = DMA_BIT_MASK(40);
136423 + portal->pdev->dev.dma_mask = &portal->pdev->dev.coherent_dma_mask;
136424 +#else
136425 + if (dma_set_mask(&portal->pdev->dev, DMA_BIT_MASK(40))) {
136426 + pr_err("qman_portal - dma_set_mask() failed\n");
136427 + goto fail_devadd;
136428 + }
136429 +#endif
136430 + portal->pdev->dev.pm_domain = &qman_portal_device_pm_domain;
136431 + portal->pdev->dev.platform_data = portal;
136432 + ret = platform_device_add(portal->pdev);
136433 + if (ret) {
136434 + pr_err("qman_portal - platform_device_add() failed\n");
136435 + goto fail_devadd;
136436 + }
136437 + dpa_rbtree_init(&portal->retire_table);
136438 + isdr = 0xffffffff;
136439 + qm_isr_disable_write(__p, isdr);
136440 + portal->irq_sources = 0;
136441 + qm_isr_enable_write(__p, portal->irq_sources);
136442 + qm_isr_status_clear(__p, 0xffffffff);
136443 + snprintf(portal->irqname, MAX_IRQNAME, IRQNAME, config->public_cfg.cpu);
136444 + if (request_irq(config->public_cfg.irq, portal_isr, 0, portal->irqname,
136445 + portal)) {
136446 + pr_err("request_irq() failed\n");
136447 + goto fail_irq;
136448 + }
136449 + if ((config->public_cfg.cpu != -1) &&
136450 + irq_can_set_affinity(config->public_cfg.irq) &&
136451 + irq_set_affinity(config->public_cfg.irq,
136452 + cpumask_of(config->public_cfg.cpu))) {
136453 + pr_err("irq_set_affinity() failed\n");
136454 + goto fail_affinity;
136455 + }
136456 +
136457 + /* Need EQCR to be empty before continuing */
136458 + isdr ^= QM_PIRQ_EQCI;
136459 + qm_isr_disable_write(__p, isdr);
136460 + ret = qm_eqcr_get_fill(__p);
136461 + if (ret) {
136462 + pr_err("Qman EQCR unclean\n");
136463 + goto fail_eqcr_empty;
136464 + }
136465 + isdr ^= (QM_PIRQ_DQRI | QM_PIRQ_MRI);
136466 + qm_isr_disable_write(__p, isdr);
136467 + if (qm_dqrr_current(__p) != NULL) {
136468 + pr_err("Qman DQRR unclean\n");
136469 + qm_dqrr_cdc_consume_n(__p, 0xffff);
136470 + }
136471 + if (qm_mr_current(__p) != NULL) {
136472 + /* special handling, drain just in case it's a few FQRNIs */
136473 + if (drain_mr_fqrni(__p)) {
136474 + const struct qm_mr_entry *e = qm_mr_current(__p);
136475 + /*
136476 + * Message ring cannot be empty no need to check
136477 + * qm_mr_current returned successfully
136478 + */
136479 + pr_err("Qman MR unclean, MR VERB 0x%x, rc 0x%x\n, addr 0x%x",
136480 + e->verb, e->ern.rc, e->ern.fd.addr_lo);
136481 + goto fail_dqrr_mr_empty;
136482 + }
136483 + }
136484 + /* Success */
136485 + portal->config = config;
136486 + qm_isr_disable_write(__p, 0);
136487 + qm_isr_uninhibit(__p);
136488 + /* Write a sane SDQCR */
136489 + qm_dqrr_sdqcr_set(__p, portal->sdqcr);
136490 + return portal;
136491 +fail_dqrr_mr_empty:
136492 +fail_eqcr_empty:
136493 +fail_affinity:
136494 + free_irq(config->public_cfg.irq, portal);
136495 +fail_irq:
136496 + platform_device_del(portal->pdev);
136497 +fail_devadd:
136498 + platform_device_put(portal->pdev);
136499 +fail_devalloc:
136500 + if (num_ceetms)
136501 + for (ret = 0; ret < num_ceetms; ret++)
136502 + kfree(portal->ccgrs[ret]);
136503 +fail_ccgrs:
136504 + kfree(portal->cgrs);
136505 +fail_cgrs:
136506 + qm_isr_finish(__p);
136507 +fail_isr:
136508 + qm_mc_finish(__p);
136509 +fail_mc:
136510 + qm_mr_finish(__p);
136511 +fail_mr:
136512 + qm_dqrr_finish(__p);
136513 +fail_dqrr:
136514 + qm_eqcr_finish(__p);
136515 +fail_eqcr:
136516 + if (portal->alloced)
136517 + kfree(portal);
136518 + return NULL;
136519 +}
136520 +
136521 +struct qman_portal *qman_create_affine_portal(
136522 + const struct qm_portal_config *config,
136523 + const struct qman_cgrs *cgrs)
136524 +{
136525 + struct qman_portal *res;
136526 + struct qman_portal *portal;
136527 +
136528 + portal = &per_cpu(qman_affine_portal, config->public_cfg.cpu);
136529 + res = qman_create_portal(portal, config, cgrs);
136530 + if (res) {
136531 + spin_lock(&affine_mask_lock);
136532 + cpumask_set_cpu(config->public_cfg.cpu, &affine_mask);
136533 + affine_channels[config->public_cfg.cpu] =
136534 + config->public_cfg.channel;
136535 + affine_portals[config->public_cfg.cpu] = portal;
136536 + spin_unlock(&affine_mask_lock);
136537 + }
136538 + return res;
136539 +}
136540 +
136541 +/* These checks are BUG_ON()s because the driver is already supposed to avoid
136542 + * these cases. */
136543 +struct qman_portal *qman_create_affine_slave(struct qman_portal *redirect,
136544 + int cpu)
136545 +{
136546 +#ifdef CONFIG_FSL_DPA_PORTAL_SHARE
136547 + struct qman_portal *p;
136548 + p = &per_cpu(qman_affine_portal, cpu);
136549 + /* Check that we don't already have our own portal */
136550 + BUG_ON(p->config);
136551 + /* Check that we aren't already slaving to another portal */
136552 + BUG_ON(p->is_shared);
136553 + /* Check that 'redirect' is prepared to have us */
136554 + BUG_ON(!redirect->config->public_cfg.is_shared);
136555 + /* These are the only elements to initialise when redirecting */
136556 + p->irq_sources = 0;
136557 + p->sharing_redirect = redirect;
136558 + affine_portals[cpu] = p;
136559 + return p;
136560 +#else
136561 + BUG();
136562 + return NULL;
136563 +#endif
136564 +}
136565 +
136566 +void qman_destroy_portal(struct qman_portal *qm)
136567 +{
136568 + const struct qm_portal_config *pcfg;
136569 + int i;
136570 +
136571 + /* Stop dequeues on the portal */
136572 + qm_dqrr_sdqcr_set(&qm->p, 0);
136573 +
136574 + /* NB we do this to "quiesce" EQCR. If we add enqueue-completions or
136575 + * something related to QM_PIRQ_EQCI, this may need fixing.
136576 + * Also, due to the prefetching model used for CI updates in the enqueue
136577 + * path, this update will only invalidate the CI cacheline *after*
136578 + * working on it, so we need to call this twice to ensure a full update
136579 + * irrespective of where the enqueue processing was at when the teardown
136580 + * began. */
136581 + qm_eqcr_cce_update(&qm->p);
136582 + qm_eqcr_cce_update(&qm->p);
136583 + pcfg = qm->config;
136584 +
136585 + free_irq(pcfg->public_cfg.irq, qm);
136586 +
136587 + kfree(qm->cgrs);
136588 + if (num_ceetms)
136589 + for (i = 0; i < num_ceetms; i++)
136590 + kfree(qm->ccgrs[i]);
136591 + qm_isr_finish(&qm->p);
136592 + qm_mc_finish(&qm->p);
136593 + qm_mr_finish(&qm->p);
136594 + qm_dqrr_finish(&qm->p);
136595 + qm_eqcr_finish(&qm->p);
136596 +
136597 + platform_device_del(qm->pdev);
136598 + platform_device_put(qm->pdev);
136599 +
136600 + qm->config = NULL;
136601 + if (qm->alloced)
136602 + kfree(qm);
136603 +}
136604 +
136605 +const struct qm_portal_config *qman_destroy_affine_portal(void)
136606 +{
136607 + /* We don't want to redirect if we're a slave, use "raw" */
136608 + struct qman_portal *qm = get_raw_affine_portal();
136609 + const struct qm_portal_config *pcfg;
136610 + int cpu;
136611 +#ifdef CONFIG_FSL_DPA_PORTAL_SHARE
136612 + if (qm->sharing_redirect) {
136613 + qm->sharing_redirect = NULL;
136614 + put_affine_portal();
136615 + return NULL;
136616 + }
136617 + qm->is_shared = 0;
136618 +#endif
136619 + pcfg = qm->config;
136620 + cpu = pcfg->public_cfg.cpu;
136621 +
136622 + qman_destroy_portal(qm);
136623 +
136624 + spin_lock(&affine_mask_lock);
136625 + cpumask_clear_cpu(cpu, &affine_mask);
136626 + spin_unlock(&affine_mask_lock);
136627 + put_affine_portal();
136628 + return pcfg;
136629 +}
136630 +
136631 +const struct qman_portal_config *qman_p_get_portal_config(struct qman_portal *p)
136632 +{
136633 + return &p->config->public_cfg;
136634 +}
136635 +EXPORT_SYMBOL(qman_p_get_portal_config);
136636 +
136637 +const struct qman_portal_config *qman_get_portal_config(void)
136638 +{
136639 + struct qman_portal *p = get_affine_portal();
136640 + const struct qman_portal_config *ret = qman_p_get_portal_config(p);
136641 + put_affine_portal();
136642 + return ret;
136643 +}
136644 +EXPORT_SYMBOL(qman_get_portal_config);
136645 +
136646 +/* Inline helper to reduce nesting in __poll_portal_slow() */
136647 +static inline void fq_state_change(struct qman_portal *p, struct qman_fq *fq,
136648 + const struct qm_mr_entry *msg, u8 verb)
136649 +{
136650 + FQLOCK(fq);
136651 + switch (verb) {
136652 + case QM_MR_VERB_FQRL:
136653 + DPA_ASSERT(fq_isset(fq, QMAN_FQ_STATE_ORL));
136654 + fq_clear(fq, QMAN_FQ_STATE_ORL);
136655 + table_del_fq(p, fq);
136656 + break;
136657 + case QM_MR_VERB_FQRN:
136658 + DPA_ASSERT((fq->state == qman_fq_state_parked) ||
136659 + (fq->state == qman_fq_state_sched));
136660 + DPA_ASSERT(fq_isset(fq, QMAN_FQ_STATE_CHANGING));
136661 + fq_clear(fq, QMAN_FQ_STATE_CHANGING);
136662 + if (msg->fq.fqs & QM_MR_FQS_NOTEMPTY)
136663 + fq_set(fq, QMAN_FQ_STATE_NE);
136664 + if (msg->fq.fqs & QM_MR_FQS_ORLPRESENT)
136665 + fq_set(fq, QMAN_FQ_STATE_ORL);
136666 + else
136667 + table_del_fq(p, fq);
136668 + fq->state = qman_fq_state_retired;
136669 + break;
136670 + case QM_MR_VERB_FQPN:
136671 + DPA_ASSERT(fq->state == qman_fq_state_sched);
136672 + DPA_ASSERT(fq_isclear(fq, QMAN_FQ_STATE_CHANGING));
136673 + fq->state = qman_fq_state_parked;
136674 + }
136675 + FQUNLOCK(fq);
136676 +}
136677 +
136678 +static u32 __poll_portal_slow(struct qman_portal *p, u32 is)
136679 +{
136680 + const struct qm_mr_entry *msg;
136681 + struct qm_mr_entry swapped_msg;
136682 + int k;
136683 +
136684 + if (is & QM_PIRQ_CSCI) {
136685 + struct qman_cgrs rr, c;
136686 + struct qm_mc_result *mcr;
136687 + struct qman_cgr *cgr;
136688 + unsigned long irqflags __maybe_unused;
136689 +
136690 + spin_lock_irqsave(&p->cgr_lock, irqflags);
136691 + /*
136692 + * The CSCI bit must be cleared _before_ issuing the
136693 + * Query Congestion State command, to ensure that a long
136694 + * CGR State Change callback cannot miss an intervening
136695 + * state change.
136696 + */
136697 + qm_isr_status_clear(&p->p, QM_PIRQ_CSCI);
136698 + qm_mc_start(&p->p);
136699 + qm_mc_commit(&p->p, QM_MCC_VERB_QUERYCONGESTION);
136700 + while (!(mcr = qm_mc_result(&p->p)))
136701 + cpu_relax();
136702 + for (k = 0; k < 8; k++)
136703 + mcr->querycongestion.state.__state[k] = be32_to_cpu(
136704 + mcr->querycongestion.state.__state[k]);
136705 + /* mask out the ones I'm not interested in */
136706 + qman_cgrs_and(&rr, (const struct qman_cgrs *)
136707 + &mcr->querycongestion.state, &p->cgrs[0]);
136708 + /* check previous snapshot for delta, enter/exit congestion */
136709 + qman_cgrs_xor(&c, &rr, &p->cgrs[1]);
136710 + /* update snapshot */
136711 + qman_cgrs_cp(&p->cgrs[1], &rr);
136712 + /* Invoke callback */
136713 + list_for_each_entry(cgr, &p->cgr_cbs, node)
136714 + if (cgr->cb && qman_cgrs_get(&c, cgr->cgrid))
136715 + cgr->cb(p, cgr, qman_cgrs_get(&rr, cgr->cgrid));
136716 + spin_unlock_irqrestore(&p->cgr_lock, irqflags);
136717 + }
136718 + if (is & QM_PIRQ_CCSCI) {
136719 + struct qman_ccgrs rr, c, congestion_result;
136720 + struct qm_mc_result *mcr;
136721 + struct qm_mc_command *mcc;
136722 + struct qm_ceetm_ccg *ccg;
136723 + unsigned long irqflags __maybe_unused;
136724 + int i, j;
136725 +
136726 + spin_lock_irqsave(&p->ccgr_lock, irqflags);
136727 + /*
136728 + * The CCSCI bit must be cleared _before_ issuing the
136729 + * Query Congestion State command, to ensure that a long
136730 + * CCGR State Change callback cannot miss an intervening
136731 + * state change.
136732 + */
136733 + qm_isr_status_clear(&p->p, QM_PIRQ_CCSCI);
136734 +
136735 + for (i = 0; i < num_ceetms; i++) {
136736 + for (j = 0; j < 2; j++) {
136737 + mcc = qm_mc_start(&p->p);
136738 + mcc->ccgr_query.ccgrid = cpu_to_be16(
136739 + CEETM_QUERY_CONGESTION_STATE | j);
136740 + mcc->ccgr_query.dcpid = i;
136741 + qm_mc_commit(&p->p, QM_CEETM_VERB_CCGR_QUERY);
136742 + while (!(mcr = qm_mc_result(&p->p)))
136743 + cpu_relax();
136744 + for (k = 0; k < 8; k++)
136745 + mcr->ccgr_query.congestion_state.state.
136746 + __state[k] = be32_to_cpu(
136747 + mcr->ccgr_query.
136748 + congestion_state.state.
136749 + __state[k]);
136750 + congestion_result.q[j] =
136751 + mcr->ccgr_query.congestion_state.state;
136752 + }
136753 + /* mask out the ones I'm not interested in */
136754 + qman_ccgrs_and(&rr, &congestion_result,
136755 + &p->ccgrs[i][0]);
136756 + /*
136757 + * check previous snapshot for delta, enter/exit
136758 + * congestion.
136759 + */
136760 + qman_ccgrs_xor(&c, &rr, &p->ccgrs[i][1]);
136761 + /* update snapshot */
136762 + qman_ccgrs_cp(&p->ccgrs[i][1], &rr);
136763 + /* Invoke callback */
136764 + list_for_each_entry(ccg, &p->ccgr_cbs[i], cb_node)
136765 + if (ccg->cb && qman_ccgrs_get(&c,
136766 + (ccg->parent->idx << 4) | ccg->idx))
136767 + ccg->cb(ccg, ccg->cb_ctx,
136768 + qman_ccgrs_get(&rr,
136769 + (ccg->parent->idx << 4)
136770 + | ccg->idx));
136771 + }
136772 + spin_unlock_irqrestore(&p->ccgr_lock, irqflags);
136773 + }
136774 +
136775 +#ifdef CONFIG_FSL_DPA_CAN_WAIT_SYNC
136776 + if (is & QM_PIRQ_EQCI) {
136777 + unsigned long irqflags;
136778 + PORTAL_IRQ_LOCK(p, irqflags);
136779 + p->eqci_owned = NULL;
136780 + PORTAL_IRQ_UNLOCK(p, irqflags);
136781 + wake_up(&affine_queue);
136782 + }
136783 +#endif
136784 +
136785 + if (is & QM_PIRQ_EQRI) {
136786 + unsigned long irqflags __maybe_unused;
136787 + PORTAL_IRQ_LOCK(p, irqflags);
136788 + qm_eqcr_cce_update(&p->p);
136789 + qm_eqcr_set_ithresh(&p->p, 0);
136790 + PORTAL_IRQ_UNLOCK(p, irqflags);
136791 + wake_up(&affine_queue);
136792 + }
136793 +
136794 + if (is & QM_PIRQ_MRI) {
136795 + struct qman_fq *fq;
136796 + u8 verb, num = 0;
136797 +mr_loop:
136798 + qm_mr_pvb_update(&p->p);
136799 + msg = qm_mr_current(&p->p);
136800 + if (!msg)
136801 + goto mr_done;
136802 + swapped_msg = *msg;
136803 + hw_fd_to_cpu(&swapped_msg.ern.fd);
136804 + verb = msg->verb & QM_MR_VERB_TYPE_MASK;
136805 + /* The message is a software ERN iff the 0x20 bit is set */
136806 + if (verb & 0x20) {
136807 + switch (verb) {
136808 + case QM_MR_VERB_FQRNI:
136809 + /* nada, we drop FQRNIs on the floor */
136810 + break;
136811 + case QM_MR_VERB_FQRN:
136812 + case QM_MR_VERB_FQRL:
136813 + /* Lookup in the retirement table */
136814 + fq = table_find_fq(p, be32_to_cpu(msg->fq.fqid));
136815 + BUG_ON(!fq);
136816 + fq_state_change(p, fq, &swapped_msg, verb);
136817 + if (fq->cb.fqs)
136818 + fq->cb.fqs(p, fq, &swapped_msg);
136819 + break;
136820 + case QM_MR_VERB_FQPN:
136821 + /* Parked */
136822 +#ifdef CONFIG_FSL_QMAN_FQ_LOOKUP
136823 + fq = get_fq_table_entry(
136824 + be32_to_cpu(msg->fq.contextB));
136825 +#else
136826 + fq = (void *)(uintptr_t)
136827 + be32_to_cpu(msg->fq.contextB);
136828 +#endif
136829 + fq_state_change(p, fq, msg, verb);
136830 + if (fq->cb.fqs)
136831 + fq->cb.fqs(p, fq, &swapped_msg);
136832 + break;
136833 + case QM_MR_VERB_DC_ERN:
136834 + /* DCP ERN */
136835 + if (p->cb_dc_ern)
136836 + p->cb_dc_ern(p, msg);
136837 + else if (cb_dc_ern)
136838 + cb_dc_ern(p, msg);
136839 + else {
136840 + static int warn_once;
136841 + if (!warn_once) {
136842 + pr_crit("Leaking DCP ERNs!\n");
136843 + warn_once = 1;
136844 + }
136845 + }
136846 + break;
136847 + default:
136848 + pr_crit("Invalid MR verb 0x%02x\n", verb);
136849 + }
136850 + } else {
136851 + /* Its a software ERN */
136852 +#ifdef CONFIG_FSL_QMAN_FQ_LOOKUP
136853 + fq = get_fq_table_entry(be32_to_cpu(msg->ern.tag));
136854 +#else
136855 + fq = (void *)(uintptr_t)be32_to_cpu(msg->ern.tag);
136856 +#endif
136857 + fq->cb.ern(p, fq, &swapped_msg);
136858 + }
136859 + num++;
136860 + qm_mr_next(&p->p);
136861 + goto mr_loop;
136862 +mr_done:
136863 + qm_mr_cci_consume(&p->p, num);
136864 + }
136865 + /*
136866 + * QM_PIRQ_CSCI/CCSCI has already been cleared, as part of its specific
136867 + * processing. If that interrupt source has meanwhile been re-asserted,
136868 + * we mustn't clear it here (or in the top-level interrupt handler).
136869 + */
136870 + return is & (QM_PIRQ_EQCI | QM_PIRQ_EQRI | QM_PIRQ_MRI);
136871 +}
136872 +
136873 +/* remove some slowish-path stuff from the "fast path" and make sure it isn't
136874 + * inlined. */
136875 +static noinline void clear_vdqcr(struct qman_portal *p, struct qman_fq *fq)
136876 +{
136877 + p->vdqcr_owned = NULL;
136878 + FQLOCK(fq);
136879 + fq_clear(fq, QMAN_FQ_STATE_VDQCR);
136880 + FQUNLOCK(fq);
136881 + wake_up(&affine_queue);
136882 +}
136883 +
136884 +/* Copy a DQRR entry ensuring reads reach QBMan in order */
136885 +static inline void safe_copy_dqrr(struct qm_dqrr_entry *dst,
136886 + const struct qm_dqrr_entry *src)
136887 +{
136888 + int i = 0;
136889 + const u64 *s64 = (u64*)src;
136890 + u64 *d64 = (u64*)dst;
136891 +
136892 + /* DQRR only has 32 bytes of valid data so only need to
136893 + * copy 4 - 64 bit values */
136894 + *d64 = *s64;
136895 +#if defined(CONFIG_ARM) || defined(CONFIG_ARM64)
136896 + {
136897 + u32 res, zero = 0;
136898 + /* Create a dependancy after copying first bytes ensures no wrap
136899 + transaction generated to QBMan */
136900 + /* Logical AND the value pointed to by s64 with 0x0 and
136901 + store the result in res */
136902 + asm volatile("and %[result], %[in1], %[in2]"
136903 + : [result] "=r" (res)
136904 + : [in1] "r" (zero), [in2] "r" (*s64)
136905 + : "memory");
136906 + /* Add res to s64 - this creates a dependancy on the result of
136907 + reading the value of s64 before the next read. The side
136908 + effect of this is that the core must stall until the first
136909 + aligned read is complete therefore preventing a WRAP
136910 + transaction to be seen by the QBMan */
136911 + asm volatile("add %[result], %[in1], %[in2]"
136912 + : [result] "=r" (s64)
136913 + : [in1] "r" (res), [in2] "r" (s64)
136914 + : "memory");
136915 + }
136916 +#endif
136917 + /* Copy the last 3 64 bit parts */
136918 + d64++; s64++;
136919 + for (;i<3; i++)
136920 + *d64++ = *s64++;
136921 +}
136922 +
136923 +/* Look: no locks, no irq_save()s, no preempt_disable()s! :-) The only states
136924 + * that would conflict with other things if they ran at the same time on the
136925 + * same cpu are;
136926 + *
136927 + * (i) setting/clearing vdqcr_owned, and
136928 + * (ii) clearing the NE (Not Empty) flag.
136929 + *
136930 + * Both are safe. Because;
136931 + *
136932 + * (i) this clearing can only occur after qman_volatile_dequeue() has set the
136933 + * vdqcr_owned field (which it does before setting VDQCR), and
136934 + * qman_volatile_dequeue() blocks interrupts and preemption while this is
136935 + * done so that we can't interfere.
136936 + * (ii) the NE flag is only cleared after qman_retire_fq() has set it, and as
136937 + * with (i) that API prevents us from interfering until it's safe.
136938 + *
136939 + * The good thing is that qman_volatile_dequeue() and qman_retire_fq() run far
136940 + * less frequently (ie. per-FQ) than __poll_portal_fast() does, so the nett
136941 + * advantage comes from this function not having to "lock" anything at all.
136942 + *
136943 + * Note also that the callbacks are invoked at points which are safe against the
136944 + * above potential conflicts, but that this function itself is not re-entrant
136945 + * (this is because the function tracks one end of each FIFO in the portal and
136946 + * we do *not* want to lock that). So the consequence is that it is safe for
136947 + * user callbacks to call into any Qman API *except* qman_poll() (as that's the
136948 + * sole API that could be invoking the callback through this function).
136949 + */
136950 +static inline unsigned int __poll_portal_fast(struct qman_portal *p,
136951 + unsigned int poll_limit)
136952 +{
136953 + const struct qm_dqrr_entry *dq;
136954 + struct qman_fq *fq;
136955 + enum qman_cb_dqrr_result res;
136956 + unsigned int limit = 0;
136957 +#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
136958 + struct qm_dqrr_entry *shadow;
136959 + const struct qm_dqrr_entry *orig_dq;
136960 +#endif
136961 +loop:
136962 + qm_dqrr_pvb_update(&p->p);
136963 + dq = qm_dqrr_current(&p->p);
136964 + if (!dq)
136965 + goto done;
136966 +#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
136967 + /* If running on an LE system the fields of the
136968 + dequeue entry must be swapped. Because the
136969 + QMan HW will ignore writes the DQRR entry is
136970 + copied and the index stored within the copy */
136971 + shadow = &p->shadow_dqrr[DQRR_PTR2IDX(dq)];
136972 + /* Use safe copy here to avoid WRAP transaction */
136973 + safe_copy_dqrr(shadow, dq);
136974 + orig_dq = dq;
136975 + dq = shadow;
136976 + shadow->fqid = be32_to_cpu(shadow->fqid);
136977 + shadow->contextB = be32_to_cpu(shadow->contextB);
136978 + shadow->seqnum = be16_to_cpu(shadow->seqnum);
136979 + hw_fd_to_cpu(&shadow->fd);
136980 +#endif
136981 + if (dq->stat & QM_DQRR_STAT_UNSCHEDULED) {
136982 + /* VDQCR: don't trust contextB as the FQ may have been
136983 + * configured for h/w consumption and we're draining it
136984 + * post-retirement. */
136985 + fq = p->vdqcr_owned;
136986 + /* We only set QMAN_FQ_STATE_NE when retiring, so we only need
136987 + * to check for clearing it when doing volatile dequeues. It's
136988 + * one less thing to check in the critical path (SDQCR). */
136989 + if (dq->stat & QM_DQRR_STAT_FQ_EMPTY)
136990 + fq_clear(fq, QMAN_FQ_STATE_NE);
136991 + /* this is duplicated from the SDQCR code, but we have stuff to
136992 + * do before *and* after this callback, and we don't want
136993 + * multiple if()s in the critical path (SDQCR). */
136994 + res = fq->cb.dqrr(p, fq, dq);
136995 + if (res == qman_cb_dqrr_stop)
136996 + goto done;
136997 + /* Check for VDQCR completion */
136998 + if (dq->stat & QM_DQRR_STAT_DQCR_EXPIRED)
136999 + clear_vdqcr(p, fq);
137000 + } else {
137001 + /* SDQCR: contextB points to the FQ */
137002 +#ifdef CONFIG_FSL_QMAN_FQ_LOOKUP
137003 + fq = get_fq_table_entry(dq->contextB);
137004 +#else
137005 + fq = (void *)(uintptr_t)dq->contextB;
137006 +#endif
137007 + /* Now let the callback do its stuff */
137008 + res = fq->cb.dqrr(p, fq, dq);
137009 +
137010 + /* The callback can request that we exit without consuming this
137011 + * entry nor advancing; */
137012 + if (res == qman_cb_dqrr_stop)
137013 + goto done;
137014 + }
137015 + /* Interpret 'dq' from a driver perspective. */
137016 + /* Parking isn't possible unless HELDACTIVE was set. NB,
137017 + * FORCEELIGIBLE implies HELDACTIVE, so we only need to
137018 + * check for HELDACTIVE to cover both. */
137019 + DPA_ASSERT((dq->stat & QM_DQRR_STAT_FQ_HELDACTIVE) ||
137020 + (res != qman_cb_dqrr_park));
137021 +#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
137022 + if (res != qman_cb_dqrr_defer)
137023 + qm_dqrr_cdc_consume_1ptr(&p->p, orig_dq,
137024 + (res == qman_cb_dqrr_park));
137025 +#else
137026 + /* Defer just means "skip it, I'll consume it myself later on" */
137027 + if (res != qman_cb_dqrr_defer)
137028 + qm_dqrr_cdc_consume_1ptr(&p->p, dq, (res == qman_cb_dqrr_park));
137029 +#endif
137030 + /* Move forward */
137031 + qm_dqrr_next(&p->p);
137032 + /* Entry processed and consumed, increment our counter. The callback can
137033 + * request that we exit after consuming the entry, and we also exit if
137034 + * we reach our processing limit, so loop back only if neither of these
137035 + * conditions is met. */
137036 + if ((++limit < poll_limit) && (res != qman_cb_dqrr_consume_stop))
137037 + goto loop;
137038 +done:
137039 + return limit;
137040 +}
137041 +
137042 +u32 qman_irqsource_get(void)
137043 +{
137044 + /* "irqsource" and "poll" APIs mustn't redirect when sharing, they
137045 + * should shut the user out if they are not the primary CPU hosting the
137046 + * portal. That's why we use the "raw" interface. */
137047 + struct qman_portal *p = get_raw_affine_portal();
137048 + u32 ret = p->irq_sources & QM_PIRQ_VISIBLE;
137049 + put_affine_portal();
137050 + return ret;
137051 +}
137052 +EXPORT_SYMBOL(qman_irqsource_get);
137053 +
137054 +int qman_p_irqsource_add(struct qman_portal *p, u32 bits __maybe_unused)
137055 +{
137056 + __maybe_unused unsigned long irqflags;
137057 +#ifdef CONFIG_FSL_DPA_PORTAL_SHARE
137058 + if (p->sharing_redirect)
137059 + return -EINVAL;
137060 + else
137061 +#endif
137062 + {
137063 + bits = bits & QM_PIRQ_VISIBLE;
137064 + PORTAL_IRQ_LOCK(p, irqflags);
137065 +
137066 + /* Clear any previously remaining interrupt conditions in
137067 + * QCSP_ISR. This prevents raising a false interrupt when
137068 + * interrupt conditions are enabled in QCSP_IER.
137069 + */
137070 + qm_isr_status_clear(&p->p, bits);
137071 + set_bits(bits, &p->irq_sources);
137072 + qm_isr_enable_write(&p->p, p->irq_sources);
137073 + PORTAL_IRQ_UNLOCK(p, irqflags);
137074 + }
137075 + return 0;
137076 +}
137077 +EXPORT_SYMBOL(qman_p_irqsource_add);
137078 +
137079 +int qman_irqsource_add(u32 bits __maybe_unused)
137080 +{
137081 + struct qman_portal *p = get_raw_affine_portal();
137082 + int ret;
137083 + ret = qman_p_irqsource_add(p, bits);
137084 + put_affine_portal();
137085 + return ret;
137086 +}
137087 +EXPORT_SYMBOL(qman_irqsource_add);
137088 +
137089 +int qman_p_irqsource_remove(struct qman_portal *p, u32 bits)
137090 +{
137091 + __maybe_unused unsigned long irqflags;
137092 + u32 ier;
137093 +#ifdef CONFIG_FSL_DPA_PORTAL_SHARE
137094 + if (p->sharing_redirect) {
137095 + put_affine_portal();
137096 + return -EINVAL;
137097 + }
137098 +#endif
137099 + /* Our interrupt handler only processes+clears status register bits that
137100 + * are in p->irq_sources. As we're trimming that mask, if one of them
137101 + * were to assert in the status register just before we remove it from
137102 + * the enable register, there would be an interrupt-storm when we
137103 + * release the IRQ lock. So we wait for the enable register update to
137104 + * take effect in h/w (by reading it back) and then clear all other bits
137105 + * in the status register. Ie. we clear them from ISR once it's certain
137106 + * IER won't allow them to reassert. */
137107 + PORTAL_IRQ_LOCK(p, irqflags);
137108 + bits &= QM_PIRQ_VISIBLE;
137109 + clear_bits(bits, &p->irq_sources);
137110 + qm_isr_enable_write(&p->p, p->irq_sources);
137111 +
137112 + ier = qm_isr_enable_read(&p->p);
137113 + /* Using "~ier" (rather than "bits" or "~p->irq_sources") creates a
137114 + * data-dependency, ie. to protect against re-ordering. */
137115 + qm_isr_status_clear(&p->p, ~ier);
137116 + PORTAL_IRQ_UNLOCK(p, irqflags);
137117 + return 0;
137118 +}
137119 +EXPORT_SYMBOL(qman_p_irqsource_remove);
137120 +
137121 +int qman_irqsource_remove(u32 bits)
137122 +{
137123 + struct qman_portal *p = get_raw_affine_portal();
137124 + int ret;
137125 + ret = qman_p_irqsource_remove(p, bits);
137126 + put_affine_portal();
137127 + return ret;
137128 +}
137129 +EXPORT_SYMBOL(qman_irqsource_remove);
137130 +
137131 +const cpumask_t *qman_affine_cpus(void)
137132 +{
137133 + return &affine_mask;
137134 +}
137135 +EXPORT_SYMBOL(qman_affine_cpus);
137136 +
137137 +u16 qman_affine_channel(int cpu)
137138 +{
137139 + if (cpu < 0) {
137140 + struct qman_portal *portal = get_raw_affine_portal();
137141 +#ifdef CONFIG_FSL_DPA_PORTAL_SHARE
137142 + BUG_ON(portal->sharing_redirect);
137143 +#endif
137144 + cpu = portal->config->public_cfg.cpu;
137145 + put_affine_portal();
137146 + }
137147 + BUG_ON(!cpumask_test_cpu(cpu, &affine_mask));
137148 + return affine_channels[cpu];
137149 +}
137150 +EXPORT_SYMBOL(qman_affine_channel);
137151 +
137152 +void *qman_get_affine_portal(int cpu)
137153 +{
137154 + return affine_portals[cpu];
137155 +}
137156 +EXPORT_SYMBOL(qman_get_affine_portal);
137157 +
137158 +int qman_p_poll_dqrr(struct qman_portal *p, unsigned int limit)
137159 +{
137160 + int ret;
137161 +
137162 +#ifdef CONFIG_FSL_DPA_PORTAL_SHARE
137163 + if (unlikely(p->sharing_redirect))
137164 + ret = -EINVAL;
137165 + else
137166 +#endif
137167 + {
137168 + BUG_ON(p->irq_sources & QM_PIRQ_DQRI);
137169 + ret = __poll_portal_fast(p, limit);
137170 + }
137171 + return ret;
137172 +}
137173 +EXPORT_SYMBOL(qman_p_poll_dqrr);
137174 +
137175 +int qman_poll_dqrr(unsigned int limit)
137176 +{
137177 + struct qman_portal *p = get_poll_portal();
137178 + int ret;
137179 + ret = qman_p_poll_dqrr(p, limit);
137180 + put_poll_portal();
137181 + return ret;
137182 +}
137183 +EXPORT_SYMBOL(qman_poll_dqrr);
137184 +
137185 +u32 qman_p_poll_slow(struct qman_portal *p)
137186 +{
137187 + u32 ret;
137188 +#ifdef CONFIG_FSL_DPA_PORTAL_SHARE
137189 + if (unlikely(p->sharing_redirect))
137190 + ret = (u32)-1;
137191 + else
137192 +#endif
137193 + {
137194 + u32 is = qm_isr_status_read(&p->p) & ~p->irq_sources;
137195 + ret = __poll_portal_slow(p, is);
137196 + qm_isr_status_clear(&p->p, ret);
137197 + }
137198 + return ret;
137199 +}
137200 +EXPORT_SYMBOL(qman_p_poll_slow);
137201 +
137202 +u32 qman_poll_slow(void)
137203 +{
137204 + struct qman_portal *p = get_poll_portal();
137205 + u32 ret;
137206 + ret = qman_p_poll_slow(p);
137207 + put_poll_portal();
137208 + return ret;
137209 +}
137210 +EXPORT_SYMBOL(qman_poll_slow);
137211 +
137212 +/* Legacy wrapper */
137213 +void qman_p_poll(struct qman_portal *p)
137214 +{
137215 +#ifdef CONFIG_FSL_DPA_PORTAL_SHARE
137216 + if (unlikely(p->sharing_redirect))
137217 + return;
137218 +#endif
137219 + if ((~p->irq_sources) & QM_PIRQ_SLOW) {
137220 + if (!(p->slowpoll--)) {
137221 + u32 is = qm_isr_status_read(&p->p) & ~p->irq_sources;
137222 + u32 active = __poll_portal_slow(p, is);
137223 + if (active) {
137224 + qm_isr_status_clear(&p->p, active);
137225 + p->slowpoll = SLOW_POLL_BUSY;
137226 + } else
137227 + p->slowpoll = SLOW_POLL_IDLE;
137228 + }
137229 + }
137230 + if ((~p->irq_sources) & QM_PIRQ_DQRI)
137231 + __poll_portal_fast(p, CONFIG_FSL_QMAN_POLL_LIMIT);
137232 +}
137233 +EXPORT_SYMBOL(qman_p_poll);
137234 +
137235 +void qman_poll(void)
137236 +{
137237 + struct qman_portal *p = get_poll_portal();
137238 + qman_p_poll(p);
137239 + put_poll_portal();
137240 +}
137241 +EXPORT_SYMBOL(qman_poll);
137242 +
137243 +void qman_p_stop_dequeues(struct qman_portal *p)
137244 +{
137245 + qman_stop_dequeues_ex(p);
137246 +}
137247 +EXPORT_SYMBOL(qman_p_stop_dequeues);
137248 +
137249 +void qman_stop_dequeues(void)
137250 +{
137251 + struct qman_portal *p = get_affine_portal();
137252 + qman_p_stop_dequeues(p);
137253 + put_affine_portal();
137254 +}
137255 +EXPORT_SYMBOL(qman_stop_dequeues);
137256 +
137257 +void qman_p_start_dequeues(struct qman_portal *p)
137258 +{
137259 + unsigned long irqflags __maybe_unused;
137260 + PORTAL_IRQ_LOCK(p, irqflags);
137261 + DPA_ASSERT(p->dqrr_disable_ref > 0);
137262 + if (!(--p->dqrr_disable_ref))
137263 + qm_dqrr_set_maxfill(&p->p, DQRR_MAXFILL);
137264 + PORTAL_IRQ_UNLOCK(p, irqflags);
137265 +}
137266 +EXPORT_SYMBOL(qman_p_start_dequeues);
137267 +
137268 +void qman_start_dequeues(void)
137269 +{
137270 + struct qman_portal *p = get_affine_portal();
137271 + qman_p_start_dequeues(p);
137272 + put_affine_portal();
137273 +}
137274 +EXPORT_SYMBOL(qman_start_dequeues);
137275 +
137276 +void qman_p_static_dequeue_add(struct qman_portal *p, u32 pools)
137277 +{
137278 + unsigned long irqflags __maybe_unused;
137279 + PORTAL_IRQ_LOCK(p, irqflags);
137280 + pools &= p->config->public_cfg.pools;
137281 + p->sdqcr |= pools;
137282 + qm_dqrr_sdqcr_set(&p->p, p->sdqcr);
137283 + PORTAL_IRQ_UNLOCK(p, irqflags);
137284 +}
137285 +EXPORT_SYMBOL(qman_p_static_dequeue_add);
137286 +
137287 +void qman_static_dequeue_add(u32 pools)
137288 +{
137289 + struct qman_portal *p = get_affine_portal();
137290 + qman_p_static_dequeue_add(p, pools);
137291 + put_affine_portal();
137292 +}
137293 +EXPORT_SYMBOL(qman_static_dequeue_add);
137294 +
137295 +void qman_p_static_dequeue_del(struct qman_portal *p, u32 pools)
137296 +{
137297 + unsigned long irqflags __maybe_unused;
137298 + PORTAL_IRQ_LOCK(p, irqflags);
137299 + pools &= p->config->public_cfg.pools;
137300 + p->sdqcr &= ~pools;
137301 + qm_dqrr_sdqcr_set(&p->p, p->sdqcr);
137302 + PORTAL_IRQ_UNLOCK(p, irqflags);
137303 +}
137304 +EXPORT_SYMBOL(qman_p_static_dequeue_del);
137305 +
137306 +void qman_static_dequeue_del(u32 pools)
137307 +{
137308 + struct qman_portal *p = get_affine_portal();
137309 + qman_p_static_dequeue_del(p, pools);
137310 + put_affine_portal();
137311 +}
137312 +EXPORT_SYMBOL(qman_static_dequeue_del);
137313 +
137314 +u32 qman_p_static_dequeue_get(struct qman_portal *p)
137315 +{
137316 + return p->sdqcr;
137317 +}
137318 +EXPORT_SYMBOL(qman_p_static_dequeue_get);
137319 +
137320 +u32 qman_static_dequeue_get(void)
137321 +{
137322 + struct qman_portal *p = get_affine_portal();
137323 + u32 ret = qman_p_static_dequeue_get(p);
137324 + put_affine_portal();
137325 + return ret;
137326 +}
137327 +EXPORT_SYMBOL(qman_static_dequeue_get);
137328 +
137329 +void qman_p_dca(struct qman_portal *p, struct qm_dqrr_entry *dq,
137330 + int park_request)
137331 +{
137332 + qm_dqrr_cdc_consume_1ptr(&p->p, dq, park_request);
137333 +}
137334 +EXPORT_SYMBOL(qman_p_dca);
137335 +
137336 +void qman_dca(struct qm_dqrr_entry *dq, int park_request)
137337 +{
137338 + struct qman_portal *p = get_affine_portal();
137339 + qman_p_dca(p, dq, park_request);
137340 + put_affine_portal();
137341 +}
137342 +EXPORT_SYMBOL(qman_dca);
137343 +
137344 +/*******************/
137345 +/* Frame queue API */
137346 +/*******************/
137347 +
137348 +static const char *mcr_result_str(u8 result)
137349 +{
137350 + switch (result) {
137351 + case QM_MCR_RESULT_NULL:
137352 + return "QM_MCR_RESULT_NULL";
137353 + case QM_MCR_RESULT_OK:
137354 + return "QM_MCR_RESULT_OK";
137355 + case QM_MCR_RESULT_ERR_FQID:
137356 + return "QM_MCR_RESULT_ERR_FQID";
137357 + case QM_MCR_RESULT_ERR_FQSTATE:
137358 + return "QM_MCR_RESULT_ERR_FQSTATE";
137359 + case QM_MCR_RESULT_ERR_NOTEMPTY:
137360 + return "QM_MCR_RESULT_ERR_NOTEMPTY";
137361 + case QM_MCR_RESULT_PENDING:
137362 + return "QM_MCR_RESULT_PENDING";
137363 + case QM_MCR_RESULT_ERR_BADCOMMAND:
137364 + return "QM_MCR_RESULT_ERR_BADCOMMAND";
137365 + }
137366 + return "<unknown MCR result>";
137367 +}
137368 +
137369 +int qman_create_fq(u32 fqid, u32 flags, struct qman_fq *fq)
137370 +{
137371 + struct qm_fqd fqd;
137372 + struct qm_mcr_queryfq_np np;
137373 + struct qm_mc_command *mcc;
137374 + struct qm_mc_result *mcr;
137375 + struct qman_portal *p;
137376 + unsigned long irqflags __maybe_unused;
137377 +
137378 + if (flags & QMAN_FQ_FLAG_DYNAMIC_FQID) {
137379 + int ret = qman_alloc_fqid(&fqid);
137380 + if (ret)
137381 + return ret;
137382 + }
137383 + spin_lock_init(&fq->fqlock);
137384 + fq->fqid = fqid;
137385 + fq->flags = flags;
137386 + fq->state = qman_fq_state_oos;
137387 + fq->cgr_groupid = 0;
137388 +#ifdef CONFIG_FSL_QMAN_FQ_LOOKUP
137389 + if (unlikely(find_empty_fq_table_entry(&fq->key, fq)))
137390 + return -ENOMEM;
137391 +#endif
137392 + if (!(flags & QMAN_FQ_FLAG_AS_IS) || (flags & QMAN_FQ_FLAG_NO_MODIFY))
137393 + return 0;
137394 + /* Everything else is AS_IS support */
137395 + p = get_affine_portal();
137396 + PORTAL_IRQ_LOCK(p, irqflags);
137397 + mcc = qm_mc_start(&p->p);
137398 + mcc->queryfq.fqid = cpu_to_be32(fqid);
137399 + qm_mc_commit(&p->p, QM_MCC_VERB_QUERYFQ);
137400 + while (!(mcr = qm_mc_result(&p->p)))
137401 + cpu_relax();
137402 + DPA_ASSERT((mcr->verb & QM_MCR_VERB_MASK) == QM_MCC_VERB_QUERYFQ);
137403 + if (mcr->result != QM_MCR_RESULT_OK) {
137404 + pr_err("QUERYFQ failed: %s\n", mcr_result_str(mcr->result));
137405 + goto err;
137406 + }
137407 + fqd = mcr->queryfq.fqd;
137408 + hw_fqd_to_cpu(&fqd);
137409 + mcc = qm_mc_start(&p->p);
137410 + mcc->queryfq_np.fqid = cpu_to_be32(fqid);
137411 + qm_mc_commit(&p->p, QM_MCC_VERB_QUERYFQ_NP);
137412 + while (!(mcr = qm_mc_result(&p->p)))
137413 + cpu_relax();
137414 + DPA_ASSERT((mcr->verb & QM_MCR_VERB_MASK) == QM_MCC_VERB_QUERYFQ_NP);
137415 + if (mcr->result != QM_MCR_RESULT_OK) {
137416 + pr_err("QUERYFQ_NP failed: %s\n", mcr_result_str(mcr->result));
137417 + goto err;
137418 + }
137419 + np = mcr->queryfq_np;
137420 + /* Phew, have queryfq and queryfq_np results, stitch together
137421 + * the FQ object from those. */
137422 + fq->cgr_groupid = fqd.cgid;
137423 + switch (np.state & QM_MCR_NP_STATE_MASK) {
137424 + case QM_MCR_NP_STATE_OOS:
137425 + break;
137426 + case QM_MCR_NP_STATE_RETIRED:
137427 + fq->state = qman_fq_state_retired;
137428 + if (np.frm_cnt)
137429 + fq_set(fq, QMAN_FQ_STATE_NE);
137430 + break;
137431 + case QM_MCR_NP_STATE_TEN_SCHED:
137432 + case QM_MCR_NP_STATE_TRU_SCHED:
137433 + case QM_MCR_NP_STATE_ACTIVE:
137434 + fq->state = qman_fq_state_sched;
137435 + if (np.state & QM_MCR_NP_STATE_R)
137436 + fq_set(fq, QMAN_FQ_STATE_CHANGING);
137437 + break;
137438 + case QM_MCR_NP_STATE_PARKED:
137439 + fq->state = qman_fq_state_parked;
137440 + break;
137441 + default:
137442 + DPA_ASSERT(NULL == "invalid FQ state");
137443 + }
137444 + if (fqd.fq_ctrl & QM_FQCTRL_CGE)
137445 + fq->state |= QMAN_FQ_STATE_CGR_EN;
137446 + PORTAL_IRQ_UNLOCK(p, irqflags);
137447 + put_affine_portal();
137448 + return 0;
137449 +err:
137450 + PORTAL_IRQ_UNLOCK(p, irqflags);
137451 + put_affine_portal();
137452 + if (flags & QMAN_FQ_FLAG_DYNAMIC_FQID)
137453 + qman_release_fqid(fqid);
137454 + return -EIO;
137455 +}
137456 +EXPORT_SYMBOL(qman_create_fq);
137457 +
137458 +void qman_destroy_fq(struct qman_fq *fq, u32 flags __maybe_unused)
137459 +{
137460 +
137461 + /* We don't need to lock the FQ as it is a pre-condition that the FQ be
137462 + * quiesced. Instead, run some checks. */
137463 + switch (fq->state) {
137464 + case qman_fq_state_parked:
137465 + DPA_ASSERT(flags & QMAN_FQ_DESTROY_PARKED);
137466 + case qman_fq_state_oos:
137467 + if (fq_isset(fq, QMAN_FQ_FLAG_DYNAMIC_FQID))
137468 + qman_release_fqid(fq->fqid);
137469 +#ifdef CONFIG_FSL_QMAN_FQ_LOOKUP
137470 + clear_fq_table_entry(fq->key);
137471 +#endif
137472 + return;
137473 + default:
137474 + break;
137475 + }
137476 + DPA_ASSERT(NULL == "qman_free_fq() on unquiesced FQ!");
137477 +}
137478 +EXPORT_SYMBOL(qman_destroy_fq);
137479 +
137480 +u32 qman_fq_fqid(struct qman_fq *fq)
137481 +{
137482 + return fq->fqid;
137483 +}
137484 +EXPORT_SYMBOL(qman_fq_fqid);
137485 +
137486 +void qman_fq_state(struct qman_fq *fq, enum qman_fq_state *state, u32 *flags)
137487 +{
137488 + if (state)
137489 + *state = fq->state;
137490 + if (flags)
137491 + *flags = fq->flags;
137492 +}
137493 +EXPORT_SYMBOL(qman_fq_state);
137494 +
137495 +int qman_init_fq(struct qman_fq *fq, u32 flags, struct qm_mcc_initfq *opts)
137496 +{
137497 + struct qm_mc_command *mcc;
137498 + struct qm_mc_result *mcr;
137499 + struct qman_portal *p;
137500 + unsigned long irqflags __maybe_unused;
137501 + u8 res, myverb = (flags & QMAN_INITFQ_FLAG_SCHED) ?
137502 + QM_MCC_VERB_INITFQ_SCHED : QM_MCC_VERB_INITFQ_PARKED;
137503 +
137504 + if ((fq->state != qman_fq_state_oos) &&
137505 + (fq->state != qman_fq_state_parked))
137506 + return -EINVAL;
137507 +#ifdef CONFIG_FSL_DPA_CHECKING
137508 + if (unlikely(fq_isset(fq, QMAN_FQ_FLAG_NO_MODIFY)))
137509 + return -EINVAL;
137510 +#endif
137511 + if (opts && (opts->we_mask & QM_INITFQ_WE_OAC)) {
137512 + /* And can't be set at the same time as TDTHRESH */
137513 + if (opts->we_mask & QM_INITFQ_WE_TDTHRESH)
137514 + return -EINVAL;
137515 + }
137516 + /* Issue an INITFQ_[PARKED|SCHED] management command */
137517 + p = get_affine_portal();
137518 + PORTAL_IRQ_LOCK(p, irqflags);
137519 + FQLOCK(fq);
137520 + if (unlikely((fq_isset(fq, QMAN_FQ_STATE_CHANGING)) ||
137521 + ((fq->state != qman_fq_state_oos) &&
137522 + (fq->state != qman_fq_state_parked)))) {
137523 + FQUNLOCK(fq);
137524 + PORTAL_IRQ_UNLOCK(p, irqflags);
137525 + put_affine_portal();
137526 + return -EBUSY;
137527 + }
137528 + mcc = qm_mc_start(&p->p);
137529 + if (opts)
137530 + mcc->initfq = *opts;
137531 + mcc->initfq.fqid = cpu_to_be32(fq->fqid);
137532 + mcc->initfq.count = 0;
137533 +
137534 + /* If the FQ does *not* have the TO_DCPORTAL flag, contextB is set as a
137535 + * demux pointer. Otherwise, the caller-provided value is allowed to
137536 + * stand, don't overwrite it. */
137537 + if (fq_isclear(fq, QMAN_FQ_FLAG_TO_DCPORTAL)) {
137538 + dma_addr_t phys_fq;
137539 + mcc->initfq.we_mask |= QM_INITFQ_WE_CONTEXTB;
137540 +#ifdef CONFIG_FSL_QMAN_FQ_LOOKUP
137541 + mcc->initfq.fqd.context_b = fq->key;
137542 +#else
137543 + mcc->initfq.fqd.context_b = (u32)(uintptr_t)fq;
137544 +#endif
137545 + /* and the physical address - NB, if the user wasn't trying to
137546 + * set CONTEXTA, clear the stashing settings. */
137547 + if (!(mcc->initfq.we_mask & QM_INITFQ_WE_CONTEXTA)) {
137548 + mcc->initfq.we_mask |= QM_INITFQ_WE_CONTEXTA;
137549 + memset(&mcc->initfq.fqd.context_a, 0,
137550 + sizeof(mcc->initfq.fqd.context_a));
137551 + } else {
137552 + phys_fq = dma_map_single(&p->pdev->dev, fq, sizeof(*fq),
137553 + DMA_TO_DEVICE);
137554 + qm_fqd_stashing_set64(&mcc->initfq.fqd, phys_fq);
137555 + }
137556 + }
137557 + if (flags & QMAN_INITFQ_FLAG_LOCAL) {
137558 + mcc->initfq.fqd.dest.channel = p->config->public_cfg.channel;
137559 + if (!(mcc->initfq.we_mask & QM_INITFQ_WE_DESTWQ)) {
137560 + mcc->initfq.we_mask |= QM_INITFQ_WE_DESTWQ;
137561 + mcc->initfq.fqd.dest.wq = 4;
137562 + }
137563 + }
137564 + mcc->initfq.we_mask = cpu_to_be16(mcc->initfq.we_mask);
137565 + cpu_to_hw_fqd(&mcc->initfq.fqd);
137566 + qm_mc_commit(&p->p, myverb);
137567 + while (!(mcr = qm_mc_result(&p->p)))
137568 + cpu_relax();
137569 + DPA_ASSERT((mcr->verb & QM_MCR_VERB_MASK) == myverb);
137570 + res = mcr->result;
137571 + if (res != QM_MCR_RESULT_OK) {
137572 + FQUNLOCK(fq);
137573 + PORTAL_IRQ_UNLOCK(p, irqflags);
137574 + put_affine_portal();
137575 + return -EIO;
137576 + }
137577 + if (opts) {
137578 + if (opts->we_mask & QM_INITFQ_WE_FQCTRL) {
137579 + if (opts->fqd.fq_ctrl & QM_FQCTRL_CGE)
137580 + fq_set(fq, QMAN_FQ_STATE_CGR_EN);
137581 + else
137582 + fq_clear(fq, QMAN_FQ_STATE_CGR_EN);
137583 + }
137584 + if (opts->we_mask & QM_INITFQ_WE_CGID)
137585 + fq->cgr_groupid = opts->fqd.cgid;
137586 + }
137587 + fq->state = (flags & QMAN_INITFQ_FLAG_SCHED) ?
137588 + qman_fq_state_sched : qman_fq_state_parked;
137589 + FQUNLOCK(fq);
137590 + PORTAL_IRQ_UNLOCK(p, irqflags);
137591 + put_affine_portal();
137592 + return 0;
137593 +}
137594 +EXPORT_SYMBOL(qman_init_fq);
137595 +
137596 +int qman_schedule_fq(struct qman_fq *fq)
137597 +{
137598 + struct qm_mc_command *mcc;
137599 + struct qm_mc_result *mcr;
137600 + struct qman_portal *p;
137601 + unsigned long irqflags __maybe_unused;
137602 + int ret = 0;
137603 + u8 res;
137604 +
137605 + if (fq->state != qman_fq_state_parked)
137606 + return -EINVAL;
137607 +#ifdef CONFIG_FSL_DPA_CHECKING
137608 + if (unlikely(fq_isset(fq, QMAN_FQ_FLAG_NO_MODIFY)))
137609 + return -EINVAL;
137610 +#endif
137611 + /* Issue a ALTERFQ_SCHED management command */
137612 + p = get_affine_portal();
137613 + PORTAL_IRQ_LOCK(p, irqflags);
137614 + FQLOCK(fq);
137615 + if (unlikely((fq_isset(fq, QMAN_FQ_STATE_CHANGING)) ||
137616 + (fq->state != qman_fq_state_parked))) {
137617 + ret = -EBUSY;
137618 + goto out;
137619 + }
137620 + mcc = qm_mc_start(&p->p);
137621 + mcc->alterfq.fqid = cpu_to_be32(fq->fqid);
137622 + qm_mc_commit(&p->p, QM_MCC_VERB_ALTER_SCHED);
137623 + while (!(mcr = qm_mc_result(&p->p)))
137624 + cpu_relax();
137625 + DPA_ASSERT((mcr->verb & QM_MCR_VERB_MASK) == QM_MCR_VERB_ALTER_SCHED);
137626 + res = mcr->result;
137627 + if (res != QM_MCR_RESULT_OK) {
137628 + ret = -EIO;
137629 + goto out;
137630 + }
137631 + fq->state = qman_fq_state_sched;
137632 +out:
137633 + FQUNLOCK(fq);
137634 + PORTAL_IRQ_UNLOCK(p, irqflags);
137635 + put_affine_portal();
137636 + return ret;
137637 +}
137638 +EXPORT_SYMBOL(qman_schedule_fq);
137639 +
137640 +int qman_retire_fq(struct qman_fq *fq, u32 *flags)
137641 +{
137642 + struct qm_mc_command *mcc;
137643 + struct qm_mc_result *mcr;
137644 + struct qman_portal *p;
137645 + unsigned long irqflags __maybe_unused;
137646 + int rval;
137647 + u8 res;
137648 +
137649 + if ((fq->state != qman_fq_state_parked) &&
137650 + (fq->state != qman_fq_state_sched))
137651 + return -EINVAL;
137652 +#ifdef CONFIG_FSL_DPA_CHECKING
137653 + if (unlikely(fq_isset(fq, QMAN_FQ_FLAG_NO_MODIFY)))
137654 + return -EINVAL;
137655 +#endif
137656 + p = get_affine_portal();
137657 + PORTAL_IRQ_LOCK(p, irqflags);
137658 + FQLOCK(fq);
137659 + if (unlikely((fq_isset(fq, QMAN_FQ_STATE_CHANGING)) ||
137660 + (fq->state == qman_fq_state_retired) ||
137661 + (fq->state == qman_fq_state_oos))) {
137662 + rval = -EBUSY;
137663 + goto out;
137664 + }
137665 + rval = table_push_fq(p, fq);
137666 + if (rval)
137667 + goto out;
137668 + mcc = qm_mc_start(&p->p);
137669 + mcc->alterfq.fqid = cpu_to_be32(fq->fqid);
137670 + qm_mc_commit(&p->p, QM_MCC_VERB_ALTER_RETIRE);
137671 + while (!(mcr = qm_mc_result(&p->p)))
137672 + cpu_relax();
137673 + DPA_ASSERT((mcr->verb & QM_MCR_VERB_MASK) == QM_MCR_VERB_ALTER_RETIRE);
137674 + res = mcr->result;
137675 + /* "Elegant" would be to treat OK/PENDING the same way; set CHANGING,
137676 + * and defer the flags until FQRNI or FQRN (respectively) show up. But
137677 + * "Friendly" is to process OK immediately, and not set CHANGING. We do
137678 + * friendly, otherwise the caller doesn't necessarily have a fully
137679 + * "retired" FQ on return even if the retirement was immediate. However
137680 + * this does mean some code duplication between here and
137681 + * fq_state_change(). */
137682 + if (likely(res == QM_MCR_RESULT_OK)) {
137683 + rval = 0;
137684 + /* Process 'fq' right away, we'll ignore FQRNI */
137685 + if (mcr->alterfq.fqs & QM_MCR_FQS_NOTEMPTY)
137686 + fq_set(fq, QMAN_FQ_STATE_NE);
137687 + if (mcr->alterfq.fqs & QM_MCR_FQS_ORLPRESENT)
137688 + fq_set(fq, QMAN_FQ_STATE_ORL);
137689 + else
137690 + table_del_fq(p, fq);
137691 + if (flags)
137692 + *flags = fq->flags;
137693 + fq->state = qman_fq_state_retired;
137694 + if (fq->cb.fqs) {
137695 + /* Another issue with supporting "immediate" retirement
137696 + * is that we're forced to drop FQRNIs, because by the
137697 + * time they're seen it may already be "too late" (the
137698 + * fq may have been OOS'd and free()'d already). But if
137699 + * the upper layer wants a callback whether it's
137700 + * immediate or not, we have to fake a "MR" entry to
137701 + * look like an FQRNI... */
137702 + struct qm_mr_entry msg;
137703 + msg.verb = QM_MR_VERB_FQRNI;
137704 + msg.fq.fqs = mcr->alterfq.fqs;
137705 + msg.fq.fqid = fq->fqid;
137706 +#ifdef CONFIG_FSL_QMAN_FQ_LOOKUP
137707 + msg.fq.contextB = fq->key;
137708 +#else
137709 + msg.fq.contextB = (u32)(uintptr_t)fq;
137710 +#endif
137711 + fq->cb.fqs(p, fq, &msg);
137712 + }
137713 + } else if (res == QM_MCR_RESULT_PENDING) {
137714 + rval = 1;
137715 + fq_set(fq, QMAN_FQ_STATE_CHANGING);
137716 + } else {
137717 + rval = -EIO;
137718 + table_del_fq(p, fq);
137719 + }
137720 +out:
137721 + FQUNLOCK(fq);
137722 + PORTAL_IRQ_UNLOCK(p, irqflags);
137723 + put_affine_portal();
137724 + return rval;
137725 +}
137726 +EXPORT_SYMBOL(qman_retire_fq);
137727 +
137728 +int qman_oos_fq(struct qman_fq *fq)
137729 +{
137730 + struct qm_mc_command *mcc;
137731 + struct qm_mc_result *mcr;
137732 + struct qman_portal *p;
137733 + unsigned long irqflags __maybe_unused;
137734 + int ret = 0;
137735 + u8 res;
137736 +
137737 + if (fq->state != qman_fq_state_retired)
137738 + return -EINVAL;
137739 +#ifdef CONFIG_FSL_DPA_CHECKING
137740 + if (unlikely(fq_isset(fq, QMAN_FQ_FLAG_NO_MODIFY)))
137741 + return -EINVAL;
137742 +#endif
137743 + p = get_affine_portal();
137744 + PORTAL_IRQ_LOCK(p, irqflags);
137745 + FQLOCK(fq);
137746 + if (unlikely((fq_isset(fq, QMAN_FQ_STATE_BLOCKOOS)) ||
137747 + (fq->state != qman_fq_state_retired))) {
137748 + ret = -EBUSY;
137749 + goto out;
137750 + }
137751 + mcc = qm_mc_start(&p->p);
137752 + mcc->alterfq.fqid = cpu_to_be32(fq->fqid);
137753 + qm_mc_commit(&p->p, QM_MCC_VERB_ALTER_OOS);
137754 + while (!(mcr = qm_mc_result(&p->p)))
137755 + cpu_relax();
137756 + DPA_ASSERT((mcr->verb & QM_MCR_VERB_MASK) == QM_MCR_VERB_ALTER_OOS);
137757 + res = mcr->result;
137758 + if (res != QM_MCR_RESULT_OK) {
137759 + ret = -EIO;
137760 + goto out;
137761 + }
137762 + fq->state = qman_fq_state_oos;
137763 +out:
137764 + FQUNLOCK(fq);
137765 + PORTAL_IRQ_UNLOCK(p, irqflags);
137766 + put_affine_portal();
137767 + return ret;
137768 +}
137769 +EXPORT_SYMBOL(qman_oos_fq);
137770 +
137771 +int qman_fq_flow_control(struct qman_fq *fq, int xon)
137772 +{
137773 + struct qm_mc_command *mcc;
137774 + struct qm_mc_result *mcr;
137775 + struct qman_portal *p;
137776 + unsigned long irqflags __maybe_unused;
137777 + int ret = 0;
137778 + u8 res;
137779 + u8 myverb;
137780 +
137781 + if ((fq->state == qman_fq_state_oos) ||
137782 + (fq->state == qman_fq_state_retired) ||
137783 + (fq->state == qman_fq_state_parked))
137784 + return -EINVAL;
137785 +
137786 +#ifdef CONFIG_FSL_DPA_CHECKING
137787 + if (unlikely(fq_isset(fq, QMAN_FQ_FLAG_NO_MODIFY)))
137788 + return -EINVAL;
137789 +#endif
137790 + /* Issue a ALTER_FQXON or ALTER_FQXOFF management command */
137791 + p = get_affine_portal();
137792 + PORTAL_IRQ_LOCK(p, irqflags);
137793 + FQLOCK(fq);
137794 + if (unlikely((fq_isset(fq, QMAN_FQ_STATE_CHANGING)) ||
137795 + (fq->state == qman_fq_state_parked) ||
137796 + (fq->state == qman_fq_state_oos) ||
137797 + (fq->state == qman_fq_state_retired))) {
137798 + ret = -EBUSY;
137799 + goto out;
137800 + }
137801 + mcc = qm_mc_start(&p->p);
137802 + mcc->alterfq.fqid = fq->fqid;
137803 + mcc->alterfq.count = 0;
137804 + myverb = xon ? QM_MCC_VERB_ALTER_FQXON : QM_MCC_VERB_ALTER_FQXOFF;
137805 +
137806 + qm_mc_commit(&p->p, myverb);
137807 + while (!(mcr = qm_mc_result(&p->p)))
137808 + cpu_relax();
137809 + DPA_ASSERT((mcr->verb & QM_MCR_VERB_MASK) == myverb);
137810 +
137811 + res = mcr->result;
137812 + if (res != QM_MCR_RESULT_OK) {
137813 + ret = -EIO;
137814 + goto out;
137815 + }
137816 +out:
137817 + FQUNLOCK(fq);
137818 + PORTAL_IRQ_UNLOCK(p, irqflags);
137819 + put_affine_portal();
137820 + return ret;
137821 +}
137822 +EXPORT_SYMBOL(qman_fq_flow_control);
137823 +
137824 +int qman_query_fq(struct qman_fq *fq, struct qm_fqd *fqd)
137825 +{
137826 + struct qm_mc_command *mcc;
137827 + struct qm_mc_result *mcr;
137828 + struct qman_portal *p = get_affine_portal();
137829 + unsigned long irqflags __maybe_unused;
137830 + u8 res;
137831 +
137832 + PORTAL_IRQ_LOCK(p, irqflags);
137833 + mcc = qm_mc_start(&p->p);
137834 + mcc->queryfq.fqid = cpu_to_be32(fq->fqid);
137835 + qm_mc_commit(&p->p, QM_MCC_VERB_QUERYFQ);
137836 + while (!(mcr = qm_mc_result(&p->p)))
137837 + cpu_relax();
137838 + DPA_ASSERT((mcr->verb & QM_MCR_VERB_MASK) == QM_MCR_VERB_QUERYFQ);
137839 + res = mcr->result;
137840 + if (res == QM_MCR_RESULT_OK)
137841 + *fqd = mcr->queryfq.fqd;
137842 + hw_fqd_to_cpu(fqd);
137843 + PORTAL_IRQ_UNLOCK(p, irqflags);
137844 + put_affine_portal();
137845 + if (res != QM_MCR_RESULT_OK)
137846 + return -EIO;
137847 + return 0;
137848 +}
137849 +EXPORT_SYMBOL(qman_query_fq);
137850 +
137851 +int qman_query_fq_np(struct qman_fq *fq, struct qm_mcr_queryfq_np *np)
137852 +{
137853 + struct qm_mc_command *mcc;
137854 + struct qm_mc_result *mcr;
137855 + struct qman_portal *p = get_affine_portal();
137856 + unsigned long irqflags __maybe_unused;
137857 + u8 res;
137858 +
137859 + PORTAL_IRQ_LOCK(p, irqflags);
137860 + mcc = qm_mc_start(&p->p);
137861 + mcc->queryfq.fqid = cpu_to_be32(fq->fqid);
137862 + qm_mc_commit(&p->p, QM_MCC_VERB_QUERYFQ_NP);
137863 + while (!(mcr = qm_mc_result(&p->p)))
137864 + cpu_relax();
137865 + DPA_ASSERT((mcr->verb & QM_MCR_VERB_MASK) == QM_MCR_VERB_QUERYFQ_NP);
137866 + res = mcr->result;
137867 + if (res == QM_MCR_RESULT_OK) {
137868 + *np = mcr->queryfq_np;
137869 + np->fqd_link = be24_to_cpu(np->fqd_link);
137870 + np->odp_seq = be16_to_cpu(np->odp_seq);
137871 + np->orp_nesn = be16_to_cpu(np->orp_nesn);
137872 + np->orp_ea_hseq = be16_to_cpu(np->orp_ea_hseq);
137873 + np->orp_ea_tseq = be16_to_cpu(np->orp_ea_tseq);
137874 + np->orp_ea_hptr = be24_to_cpu(np->orp_ea_hptr);
137875 + np->orp_ea_tptr = be24_to_cpu(np->orp_ea_tptr);
137876 + np->pfdr_hptr = be24_to_cpu(np->pfdr_hptr);
137877 + np->pfdr_tptr = be24_to_cpu(np->pfdr_tptr);
137878 + np->ics_surp = be16_to_cpu(np->ics_surp);
137879 + np->byte_cnt = be32_to_cpu(np->byte_cnt);
137880 + np->frm_cnt = be24_to_cpu(np->frm_cnt);
137881 + np->ra1_sfdr = be16_to_cpu(np->ra1_sfdr);
137882 + np->ra2_sfdr = be16_to_cpu(np->ra2_sfdr);
137883 + np->od1_sfdr = be16_to_cpu(np->od1_sfdr);
137884 + np->od2_sfdr = be16_to_cpu(np->od2_sfdr);
137885 + np->od3_sfdr = be16_to_cpu(np->od3_sfdr);
137886 + }
137887 + PORTAL_IRQ_UNLOCK(p, irqflags);
137888 + put_affine_portal();
137889 + if (res == QM_MCR_RESULT_ERR_FQID)
137890 + return -ERANGE;
137891 + else if (res != QM_MCR_RESULT_OK)
137892 + return -EIO;
137893 + return 0;
137894 +}
137895 +EXPORT_SYMBOL(qman_query_fq_np);
137896 +
137897 +int qman_query_wq(u8 query_dedicated, struct qm_mcr_querywq *wq)
137898 +{
137899 + struct qm_mc_command *mcc;
137900 + struct qm_mc_result *mcr;
137901 + struct qman_portal *p = get_affine_portal();
137902 + unsigned long irqflags __maybe_unused;
137903 + u8 res, myverb;
137904 +
137905 + PORTAL_IRQ_LOCK(p, irqflags);
137906 + myverb = (query_dedicated) ? QM_MCR_VERB_QUERYWQ_DEDICATED :
137907 + QM_MCR_VERB_QUERYWQ;
137908 + mcc = qm_mc_start(&p->p);
137909 + mcc->querywq.channel.id = cpu_to_be16(wq->channel.id);
137910 + qm_mc_commit(&p->p, myverb);
137911 + while (!(mcr = qm_mc_result(&p->p)))
137912 + cpu_relax();
137913 + DPA_ASSERT((mcr->verb & QM_MCR_VERB_MASK) == myverb);
137914 + res = mcr->result;
137915 + if (res == QM_MCR_RESULT_OK) {
137916 + int i, array_len;
137917 + wq->channel.id = be16_to_cpu(mcr->querywq.channel.id);
137918 + array_len = ARRAY_SIZE(mcr->querywq.wq_len);
137919 + for (i = 0; i < array_len; i++)
137920 + wq->wq_len[i] = be32_to_cpu(mcr->querywq.wq_len[i]);
137921 + }
137922 + PORTAL_IRQ_UNLOCK(p, irqflags);
137923 + put_affine_portal();
137924 + if (res != QM_MCR_RESULT_OK) {
137925 + pr_err("QUERYWQ failed: %s\n", mcr_result_str(res));
137926 + return -EIO;
137927 + }
137928 + return 0;
137929 +}
137930 +EXPORT_SYMBOL(qman_query_wq);
137931 +
137932 +int qman_testwrite_cgr(struct qman_cgr *cgr, u64 i_bcnt,
137933 + struct qm_mcr_cgrtestwrite *result)
137934 +{
137935 + struct qm_mc_command *mcc;
137936 + struct qm_mc_result *mcr;
137937 + struct qman_portal *p = get_affine_portal();
137938 + unsigned long irqflags __maybe_unused;
137939 + u8 res;
137940 +
137941 + PORTAL_IRQ_LOCK(p, irqflags);
137942 + mcc = qm_mc_start(&p->p);
137943 + mcc->cgrtestwrite.cgid = cgr->cgrid;
137944 + mcc->cgrtestwrite.i_bcnt_hi = (u8)(i_bcnt >> 32);
137945 + mcc->cgrtestwrite.i_bcnt_lo = (u32)i_bcnt;
137946 + qm_mc_commit(&p->p, QM_MCC_VERB_CGRTESTWRITE);
137947 + while (!(mcr = qm_mc_result(&p->p)))
137948 + cpu_relax();
137949 + DPA_ASSERT((mcr->verb & QM_MCR_VERB_MASK) == QM_MCC_VERB_CGRTESTWRITE);
137950 + res = mcr->result;
137951 + if (res == QM_MCR_RESULT_OK)
137952 + *result = mcr->cgrtestwrite;
137953 + PORTAL_IRQ_UNLOCK(p, irqflags);
137954 + put_affine_portal();
137955 + if (res != QM_MCR_RESULT_OK) {
137956 + pr_err("CGR TEST WRITE failed: %s\n", mcr_result_str(res));
137957 + return -EIO;
137958 + }
137959 + return 0;
137960 +}
137961 +EXPORT_SYMBOL(qman_testwrite_cgr);
137962 +
137963 +int qman_query_cgr(struct qman_cgr *cgr, struct qm_mcr_querycgr *cgrd)
137964 +{
137965 + struct qm_mc_command *mcc;
137966 + struct qm_mc_result *mcr;
137967 + struct qman_portal *p = get_affine_portal();
137968 + unsigned long irqflags __maybe_unused;
137969 + u8 res;
137970 + int i;
137971 +
137972 + PORTAL_IRQ_LOCK(p, irqflags);
137973 + mcc = qm_mc_start(&p->p);
137974 + mcc->querycgr.cgid = cgr->cgrid;
137975 + qm_mc_commit(&p->p, QM_MCC_VERB_QUERYCGR);
137976 + while (!(mcr = qm_mc_result(&p->p)))
137977 + cpu_relax();
137978 + DPA_ASSERT((mcr->verb & QM_MCR_VERB_MASK) == QM_MCC_VERB_QUERYCGR);
137979 + res = mcr->result;
137980 + if (res == QM_MCR_RESULT_OK)
137981 + *cgrd = mcr->querycgr;
137982 + PORTAL_IRQ_UNLOCK(p, irqflags);
137983 + put_affine_portal();
137984 + if (res != QM_MCR_RESULT_OK) {
137985 + pr_err("QUERY_CGR failed: %s\n", mcr_result_str(res));
137986 + return -EIO;
137987 + }
137988 + cgrd->cgr.wr_parm_g.word =
137989 + be32_to_cpu(cgrd->cgr.wr_parm_g.word);
137990 + cgrd->cgr.wr_parm_y.word =
137991 + be32_to_cpu(cgrd->cgr.wr_parm_y.word);
137992 + cgrd->cgr.wr_parm_r.word =
137993 + be32_to_cpu(cgrd->cgr.wr_parm_r.word);
137994 + cgrd->cgr.cscn_targ = be32_to_cpu(cgrd->cgr.cscn_targ);
137995 + cgrd->cgr.__cs_thres = be16_to_cpu(cgrd->cgr.__cs_thres);
137996 + for (i = 0; i < ARRAY_SIZE(cgrd->cscn_targ_swp); i++)
137997 + be32_to_cpus(&cgrd->cscn_targ_swp[i]);
137998 + return 0;
137999 +}
138000 +EXPORT_SYMBOL(qman_query_cgr);
138001 +
138002 +int qman_query_congestion(struct qm_mcr_querycongestion *congestion)
138003 +{
138004 + struct qm_mc_result *mcr;
138005 + struct qman_portal *p = get_affine_portal();
138006 + unsigned long irqflags __maybe_unused;
138007 + u8 res;
138008 + int i;
138009 +
138010 + PORTAL_IRQ_LOCK(p, irqflags);
138011 + qm_mc_start(&p->p);
138012 + qm_mc_commit(&p->p, QM_MCC_VERB_QUERYCONGESTION);
138013 + while (!(mcr = qm_mc_result(&p->p)))
138014 + cpu_relax();
138015 + DPA_ASSERT((mcr->verb & QM_MCR_VERB_MASK) ==
138016 + QM_MCC_VERB_QUERYCONGESTION);
138017 + res = mcr->result;
138018 + if (res == QM_MCR_RESULT_OK)
138019 + memcpy_fromio(congestion, &mcr->querycongestion,
138020 + sizeof(*congestion));
138021 + PORTAL_IRQ_UNLOCK(p, irqflags);
138022 + put_affine_portal();
138023 + if (res != QM_MCR_RESULT_OK) {
138024 + pr_err("QUERY_CONGESTION failed: %s\n", mcr_result_str(res));
138025 + return -EIO;
138026 + }
138027 +
138028 + for (i = 0; i < ARRAY_SIZE(congestion->state.__state); i++)
138029 + be32_to_cpus(&congestion->state.__state[i]);
138030 + return 0;
138031 +}
138032 +EXPORT_SYMBOL(qman_query_congestion);
138033 +
138034 +/* internal function used as a wait_event() expression */
138035 +static int set_p_vdqcr(struct qman_portal *p, struct qman_fq *fq, u32 vdqcr)
138036 +{
138037 + unsigned long irqflags __maybe_unused;
138038 + int ret = -EBUSY;
138039 + PORTAL_IRQ_LOCK(p, irqflags);
138040 + if (!p->vdqcr_owned) {
138041 + FQLOCK(fq);
138042 + if (fq_isset(fq, QMAN_FQ_STATE_VDQCR))
138043 + goto escape;
138044 + fq_set(fq, QMAN_FQ_STATE_VDQCR);
138045 + FQUNLOCK(fq);
138046 + p->vdqcr_owned = fq;
138047 + ret = 0;
138048 + }
138049 +escape:
138050 + PORTAL_IRQ_UNLOCK(p, irqflags);
138051 + if (!ret)
138052 + qm_dqrr_vdqcr_set(&p->p, vdqcr);
138053 + return ret;
138054 +}
138055 +
138056 +static int set_vdqcr(struct qman_portal **p, struct qman_fq *fq, u32 vdqcr)
138057 +{
138058 + int ret;
138059 + *p = get_affine_portal();
138060 + ret = set_p_vdqcr(*p, fq, vdqcr);
138061 + put_affine_portal();
138062 + return ret;
138063 +}
138064 +
138065 +#ifdef CONFIG_FSL_DPA_CAN_WAIT
138066 +static int wait_p_vdqcr_start(struct qman_portal *p, struct qman_fq *fq,
138067 + u32 vdqcr, u32 flags)
138068 +{
138069 + int ret = 0;
138070 + if (flags & QMAN_VOLATILE_FLAG_WAIT_INT)
138071 + ret = wait_event_interruptible(affine_queue,
138072 + !(ret = set_p_vdqcr(p, fq, vdqcr)));
138073 + else
138074 + wait_event(affine_queue, !(ret = set_p_vdqcr(p, fq, vdqcr)));
138075 + return ret;
138076 +}
138077 +
138078 +static int wait_vdqcr_start(struct qman_portal **p, struct qman_fq *fq,
138079 + u32 vdqcr, u32 flags)
138080 +{
138081 + int ret = 0;
138082 + if (flags & QMAN_VOLATILE_FLAG_WAIT_INT)
138083 + ret = wait_event_interruptible(affine_queue,
138084 + !(ret = set_vdqcr(p, fq, vdqcr)));
138085 + else
138086 + wait_event(affine_queue, !(ret = set_vdqcr(p, fq, vdqcr)));
138087 + return ret;
138088 +}
138089 +#endif
138090 +
138091 +int qman_p_volatile_dequeue(struct qman_portal *p, struct qman_fq *fq,
138092 + u32 flags __maybe_unused, u32 vdqcr)
138093 +{
138094 + int ret;
138095 +
138096 + if ((fq->state != qman_fq_state_parked) &&
138097 + (fq->state != qman_fq_state_retired))
138098 + return -EINVAL;
138099 + if (vdqcr & QM_VDQCR_FQID_MASK)
138100 + return -EINVAL;
138101 + if (fq_isset(fq, QMAN_FQ_STATE_VDQCR))
138102 + return -EBUSY;
138103 + vdqcr = (vdqcr & ~QM_VDQCR_FQID_MASK) | fq->fqid;
138104 +#ifdef CONFIG_FSL_DPA_CAN_WAIT
138105 + if (flags & QMAN_VOLATILE_FLAG_WAIT)
138106 + ret = wait_p_vdqcr_start(p, fq, vdqcr, flags);
138107 + else
138108 +#endif
138109 + ret = set_p_vdqcr(p, fq, vdqcr);
138110 + if (ret)
138111 + return ret;
138112 + /* VDQCR is set */
138113 +#ifdef CONFIG_FSL_DPA_CAN_WAIT
138114 + if (flags & QMAN_VOLATILE_FLAG_FINISH) {
138115 + if (flags & QMAN_VOLATILE_FLAG_WAIT_INT)
138116 + /* NB: don't propagate any error - the caller wouldn't
138117 + * know whether the VDQCR was issued or not. A signal
138118 + * could arrive after returning anyway, so the caller
138119 + * can check signal_pending() if that's an issue. */
138120 + wait_event_interruptible(affine_queue,
138121 + !fq_isset(fq, QMAN_FQ_STATE_VDQCR));
138122 + else
138123 + wait_event(affine_queue,
138124 + !fq_isset(fq, QMAN_FQ_STATE_VDQCR));
138125 + }
138126 +#endif
138127 + return 0;
138128 +}
138129 +EXPORT_SYMBOL(qman_p_volatile_dequeue);
138130 +
138131 +int qman_volatile_dequeue(struct qman_fq *fq, u32 flags __maybe_unused,
138132 + u32 vdqcr)
138133 +{
138134 + struct qman_portal *p;
138135 + int ret;
138136 +
138137 + if ((fq->state != qman_fq_state_parked) &&
138138 + (fq->state != qman_fq_state_retired))
138139 + return -EINVAL;
138140 + if (vdqcr & QM_VDQCR_FQID_MASK)
138141 + return -EINVAL;
138142 + if (fq_isset(fq, QMAN_FQ_STATE_VDQCR))
138143 + return -EBUSY;
138144 + vdqcr = (vdqcr & ~QM_VDQCR_FQID_MASK) | fq->fqid;
138145 +#ifdef CONFIG_FSL_DPA_CAN_WAIT
138146 + if (flags & QMAN_VOLATILE_FLAG_WAIT)
138147 + ret = wait_vdqcr_start(&p, fq, vdqcr, flags);
138148 + else
138149 +#endif
138150 + ret = set_vdqcr(&p, fq, vdqcr);
138151 + if (ret)
138152 + return ret;
138153 + /* VDQCR is set */
138154 +#ifdef CONFIG_FSL_DPA_CAN_WAIT
138155 + if (flags & QMAN_VOLATILE_FLAG_FINISH) {
138156 + if (flags & QMAN_VOLATILE_FLAG_WAIT_INT)
138157 + /* NB: don't propagate any error - the caller wouldn't
138158 + * know whether the VDQCR was issued or not. A signal
138159 + * could arrive after returning anyway, so the caller
138160 + * can check signal_pending() if that's an issue. */
138161 + wait_event_interruptible(affine_queue,
138162 + !fq_isset(fq, QMAN_FQ_STATE_VDQCR));
138163 + else
138164 + wait_event(affine_queue,
138165 + !fq_isset(fq, QMAN_FQ_STATE_VDQCR));
138166 + }
138167 +#endif
138168 + return 0;
138169 +}
138170 +EXPORT_SYMBOL(qman_volatile_dequeue);
138171 +
138172 +static noinline void update_eqcr_ci(struct qman_portal *p, u8 avail)
138173 +{
138174 + if (avail)
138175 + qm_eqcr_cce_prefetch(&p->p);
138176 + else
138177 + qm_eqcr_cce_update(&p->p);
138178 +}
138179 +
138180 +int qman_eqcr_is_empty(void)
138181 +{
138182 + unsigned long irqflags __maybe_unused;
138183 + struct qman_portal *p = get_affine_portal();
138184 + u8 avail;
138185 +
138186 + PORTAL_IRQ_LOCK(p, irqflags);
138187 + update_eqcr_ci(p, 0);
138188 + avail = qm_eqcr_get_fill(&p->p);
138189 + PORTAL_IRQ_UNLOCK(p, irqflags);
138190 + put_affine_portal();
138191 + return avail == 0;
138192 +}
138193 +EXPORT_SYMBOL(qman_eqcr_is_empty);
138194 +
138195 +void qman_set_dc_ern(qman_cb_dc_ern handler, int affine)
138196 +{
138197 + if (affine) {
138198 + unsigned long irqflags __maybe_unused;
138199 + struct qman_portal *p = get_affine_portal();
138200 + PORTAL_IRQ_LOCK(p, irqflags);
138201 + p->cb_dc_ern = handler;
138202 + PORTAL_IRQ_UNLOCK(p, irqflags);
138203 + put_affine_portal();
138204 + } else
138205 + cb_dc_ern = handler;
138206 +}
138207 +EXPORT_SYMBOL(qman_set_dc_ern);
138208 +
138209 +static inline struct qm_eqcr_entry *try_p_eq_start(struct qman_portal *p,
138210 + unsigned long *irqflags __maybe_unused,
138211 + struct qman_fq *fq,
138212 + const struct qm_fd *fd,
138213 + u32 flags)
138214 +{
138215 + struct qm_eqcr_entry *eq;
138216 + u8 avail;
138217 + PORTAL_IRQ_LOCK(p, (*irqflags));
138218 +#ifdef CONFIG_FSL_DPA_CAN_WAIT_SYNC
138219 + if (unlikely((flags & QMAN_ENQUEUE_FLAG_WAIT) &&
138220 + (flags & QMAN_ENQUEUE_FLAG_WAIT_SYNC))) {
138221 + if (p->eqci_owned) {
138222 + PORTAL_IRQ_UNLOCK(p, (*irqflags));
138223 + return NULL;
138224 + }
138225 + p->eqci_owned = fq;
138226 + }
138227 +#endif
138228 + if (p->use_eqcr_ci_stashing) {
138229 + /*
138230 + * The stashing case is easy, only update if we need to in
138231 + * order to try and liberate ring entries.
138232 + */
138233 + eq = qm_eqcr_start_stash(&p->p);
138234 + } else {
138235 + /*
138236 + * The non-stashing case is harder, need to prefetch ahead of
138237 + * time.
138238 + */
138239 + avail = qm_eqcr_get_avail(&p->p);
138240 + if (avail < 2)
138241 + update_eqcr_ci(p, avail);
138242 + eq = qm_eqcr_start_no_stash(&p->p);
138243 + }
138244 +
138245 + if (unlikely(!eq)) {
138246 +#ifdef CONFIG_FSL_DPA_CAN_WAIT_SYNC
138247 + if (unlikely((flags & QMAN_ENQUEUE_FLAG_WAIT) &&
138248 + (flags & QMAN_ENQUEUE_FLAG_WAIT_SYNC)))
138249 + p->eqci_owned = NULL;
138250 +#endif
138251 + PORTAL_IRQ_UNLOCK(p, (*irqflags));
138252 + return NULL;
138253 + }
138254 + if (flags & QMAN_ENQUEUE_FLAG_DCA)
138255 + eq->dca = QM_EQCR_DCA_ENABLE |
138256 + ((flags & QMAN_ENQUEUE_FLAG_DCA_PARK) ?
138257 + QM_EQCR_DCA_PARK : 0) |
138258 + ((flags >> 8) & QM_EQCR_DCA_IDXMASK);
138259 + eq->fqid = cpu_to_be32(fq->fqid);
138260 +#ifdef CONFIG_FSL_QMAN_FQ_LOOKUP
138261 + eq->tag = cpu_to_be32(fq->key);
138262 +#else
138263 + eq->tag = cpu_to_be32((u32)(uintptr_t)fq);
138264 +#endif
138265 + eq->fd = *fd;
138266 + cpu_to_hw_fd(&eq->fd);
138267 + return eq;
138268 +}
138269 +
138270 +static inline struct qm_eqcr_entry *try_eq_start(struct qman_portal **p,
138271 + unsigned long *irqflags __maybe_unused,
138272 + struct qman_fq *fq,
138273 + const struct qm_fd *fd,
138274 + u32 flags)
138275 +{
138276 + struct qm_eqcr_entry *eq;
138277 + *p = get_affine_portal();
138278 + eq = try_p_eq_start(*p, irqflags, fq, fd, flags);
138279 + if (!eq)
138280 + put_affine_portal();
138281 + return eq;
138282 +}
138283 +
138284 +#ifdef CONFIG_FSL_DPA_CAN_WAIT
138285 +static noinline struct qm_eqcr_entry *__wait_eq_start(struct qman_portal **p,
138286 + unsigned long *irqflags __maybe_unused,
138287 + struct qman_fq *fq,
138288 + const struct qm_fd *fd,
138289 + u32 flags)
138290 +{
138291 + struct qm_eqcr_entry *eq = try_eq_start(p, irqflags, fq, fd, flags);
138292 + if (!eq)
138293 + qm_eqcr_set_ithresh(&(*p)->p, EQCR_ITHRESH);
138294 + return eq;
138295 +}
138296 +static noinline struct qm_eqcr_entry *wait_eq_start(struct qman_portal **p,
138297 + unsigned long *irqflags __maybe_unused,
138298 + struct qman_fq *fq,
138299 + const struct qm_fd *fd,
138300 + u32 flags)
138301 +{
138302 + struct qm_eqcr_entry *eq;
138303 + if (flags & QMAN_ENQUEUE_FLAG_WAIT_INT)
138304 + /* NB: return NULL if signal occurs before completion. Signal
138305 + * can occur during return. Caller must check for signal */
138306 + wait_event_interruptible(affine_queue,
138307 + (eq = __wait_eq_start(p, irqflags, fq, fd, flags)));
138308 + else
138309 + wait_event(affine_queue,
138310 + (eq = __wait_eq_start(p, irqflags, fq, fd, flags)));
138311 + return eq;
138312 +}
138313 +static noinline struct qm_eqcr_entry *__wait_p_eq_start(struct qman_portal *p,
138314 + unsigned long *irqflags __maybe_unused,
138315 + struct qman_fq *fq,
138316 + const struct qm_fd *fd,
138317 + u32 flags)
138318 +{
138319 + struct qm_eqcr_entry *eq = try_p_eq_start(p, irqflags, fq, fd, flags);
138320 + if (!eq)
138321 + qm_eqcr_set_ithresh(&p->p, EQCR_ITHRESH);
138322 + return eq;
138323 +}
138324 +static noinline struct qm_eqcr_entry *wait_p_eq_start(struct qman_portal *p,
138325 + unsigned long *irqflags __maybe_unused,
138326 + struct qman_fq *fq,
138327 + const struct qm_fd *fd,
138328 + u32 flags)
138329 +{
138330 + struct qm_eqcr_entry *eq;
138331 + if (flags & QMAN_ENQUEUE_FLAG_WAIT_INT)
138332 + /* NB: return NULL if signal occurs before completion. Signal
138333 + * can occur during return. Caller must check for signal */
138334 + wait_event_interruptible(affine_queue,
138335 + (eq = __wait_p_eq_start(p, irqflags, fq, fd, flags)));
138336 + else
138337 + wait_event(affine_queue,
138338 + (eq = __wait_p_eq_start(p, irqflags, fq, fd, flags)));
138339 + return eq;
138340 +}
138341 +#endif
138342 +
138343 +int qman_p_enqueue(struct qman_portal *p, struct qman_fq *fq,
138344 + const struct qm_fd *fd, u32 flags)
138345 +{
138346 + struct qm_eqcr_entry *eq;
138347 + unsigned long irqflags __maybe_unused;
138348 +
138349 +#ifdef CONFIG_FSL_DPA_CAN_WAIT
138350 + if (flags & QMAN_ENQUEUE_FLAG_WAIT)
138351 + eq = wait_p_eq_start(p, &irqflags, fq, fd, flags);
138352 + else
138353 +#endif
138354 + eq = try_p_eq_start(p, &irqflags, fq, fd, flags);
138355 + if (!eq)
138356 + return -EBUSY;
138357 + /* Note: QM_EQCR_VERB_INTERRUPT == QMAN_ENQUEUE_FLAG_WAIT_SYNC */
138358 + qm_eqcr_pvb_commit(&p->p, QM_EQCR_VERB_CMD_ENQUEUE |
138359 + (flags & (QM_EQCR_VERB_COLOUR_MASK | QM_EQCR_VERB_INTERRUPT)));
138360 + /* Factor the below out, it's used from qman_enqueue_orp() too */
138361 + PORTAL_IRQ_UNLOCK(p, irqflags);
138362 +#ifdef CONFIG_FSL_DPA_CAN_WAIT_SYNC
138363 + if (unlikely((flags & QMAN_ENQUEUE_FLAG_WAIT) &&
138364 + (flags & QMAN_ENQUEUE_FLAG_WAIT_SYNC))) {
138365 + if (flags & QMAN_ENQUEUE_FLAG_WAIT_INT)
138366 + /* NB: return success even if signal occurs before
138367 + * condition is true. pvb_commit guarantees success */
138368 + wait_event_interruptible(affine_queue,
138369 + (p->eqci_owned != fq));
138370 + else
138371 + wait_event(affine_queue, (p->eqci_owned != fq));
138372 + }
138373 +#endif
138374 + return 0;
138375 +}
138376 +EXPORT_SYMBOL(qman_p_enqueue);
138377 +
138378 +int qman_enqueue(struct qman_fq *fq, const struct qm_fd *fd, u32 flags)
138379 +{
138380 + struct qman_portal *p;
138381 + struct qm_eqcr_entry *eq;
138382 + unsigned long irqflags __maybe_unused;
138383 +
138384 +#ifdef CONFIG_FSL_DPA_CAN_WAIT
138385 + if (flags & QMAN_ENQUEUE_FLAG_WAIT)
138386 + eq = wait_eq_start(&p, &irqflags, fq, fd, flags);
138387 + else
138388 +#endif
138389 + eq = try_eq_start(&p, &irqflags, fq, fd, flags);
138390 + if (!eq)
138391 + return -EBUSY;
138392 + /* Note: QM_EQCR_VERB_INTERRUPT == QMAN_ENQUEUE_FLAG_WAIT_SYNC */
138393 + qm_eqcr_pvb_commit(&p->p, QM_EQCR_VERB_CMD_ENQUEUE |
138394 + (flags & (QM_EQCR_VERB_COLOUR_MASK | QM_EQCR_VERB_INTERRUPT)));
138395 + /* Factor the below out, it's used from qman_enqueue_orp() too */
138396 + PORTAL_IRQ_UNLOCK(p, irqflags);
138397 + put_affine_portal();
138398 +#ifdef CONFIG_FSL_DPA_CAN_WAIT_SYNC
138399 + if (unlikely((flags & QMAN_ENQUEUE_FLAG_WAIT) &&
138400 + (flags & QMAN_ENQUEUE_FLAG_WAIT_SYNC))) {
138401 + if (flags & QMAN_ENQUEUE_FLAG_WAIT_INT)
138402 + /* NB: return success even if signal occurs before
138403 + * condition is true. pvb_commit guarantees success */
138404 + wait_event_interruptible(affine_queue,
138405 + (p->eqci_owned != fq));
138406 + else
138407 + wait_event(affine_queue, (p->eqci_owned != fq));
138408 + }
138409 +#endif
138410 + return 0;
138411 +}
138412 +EXPORT_SYMBOL(qman_enqueue);
138413 +
138414 +int qman_p_enqueue_orp(struct qman_portal *p, struct qman_fq *fq,
138415 + const struct qm_fd *fd, u32 flags,
138416 + struct qman_fq *orp, u16 orp_seqnum)
138417 +{
138418 + struct qm_eqcr_entry *eq;
138419 + unsigned long irqflags __maybe_unused;
138420 +
138421 +#ifdef CONFIG_FSL_DPA_CAN_WAIT
138422 + if (flags & QMAN_ENQUEUE_FLAG_WAIT)
138423 + eq = wait_p_eq_start(p, &irqflags, fq, fd, flags);
138424 + else
138425 +#endif
138426 + eq = try_p_eq_start(p, &irqflags, fq, fd, flags);
138427 + if (!eq)
138428 + return -EBUSY;
138429 + /* Process ORP-specifics here */
138430 + if (flags & QMAN_ENQUEUE_FLAG_NLIS)
138431 + orp_seqnum |= QM_EQCR_SEQNUM_NLIS;
138432 + else {
138433 + orp_seqnum &= ~QM_EQCR_SEQNUM_NLIS;
138434 + if (flags & QMAN_ENQUEUE_FLAG_NESN)
138435 + orp_seqnum |= QM_EQCR_SEQNUM_NESN;
138436 + else
138437 + /* No need to check 4 QMAN_ENQUEUE_FLAG_HOLE */
138438 + orp_seqnum &= ~QM_EQCR_SEQNUM_NESN;
138439 + }
138440 + eq->seqnum = cpu_to_be16(orp_seqnum);
138441 + eq->orp = cpu_to_be32(orp->fqid);
138442 + /* Note: QM_EQCR_VERB_INTERRUPT == QMAN_ENQUEUE_FLAG_WAIT_SYNC */
138443 + qm_eqcr_pvb_commit(&p->p, QM_EQCR_VERB_ORP |
138444 + ((flags & (QMAN_ENQUEUE_FLAG_HOLE | QMAN_ENQUEUE_FLAG_NESN)) ?
138445 + 0 : QM_EQCR_VERB_CMD_ENQUEUE) |
138446 + (flags & (QM_EQCR_VERB_COLOUR_MASK | QM_EQCR_VERB_INTERRUPT)));
138447 + PORTAL_IRQ_UNLOCK(p, irqflags);
138448 +#ifdef CONFIG_FSL_DPA_CAN_WAIT_SYNC
138449 + if (unlikely((flags & QMAN_ENQUEUE_FLAG_WAIT) &&
138450 + (flags & QMAN_ENQUEUE_FLAG_WAIT_SYNC))) {
138451 + if (flags & QMAN_ENQUEUE_FLAG_WAIT_INT)
138452 + /* NB: return success even if signal occurs before
138453 + * condition is true. pvb_commit guarantees success */
138454 + wait_event_interruptible(affine_queue,
138455 + (p->eqci_owned != fq));
138456 + else
138457 + wait_event(affine_queue, (p->eqci_owned != fq));
138458 + }
138459 +#endif
138460 + return 0;
138461 +}
138462 +EXPORT_SYMBOL(qman_p_enqueue_orp);
138463 +
138464 +int qman_enqueue_orp(struct qman_fq *fq, const struct qm_fd *fd, u32 flags,
138465 + struct qman_fq *orp, u16 orp_seqnum)
138466 +{
138467 + struct qman_portal *p;
138468 + struct qm_eqcr_entry *eq;
138469 + unsigned long irqflags __maybe_unused;
138470 +
138471 +#ifdef CONFIG_FSL_DPA_CAN_WAIT
138472 + if (flags & QMAN_ENQUEUE_FLAG_WAIT)
138473 + eq = wait_eq_start(&p, &irqflags, fq, fd, flags);
138474 + else
138475 +#endif
138476 + eq = try_eq_start(&p, &irqflags, fq, fd, flags);
138477 + if (!eq)
138478 + return -EBUSY;
138479 + /* Process ORP-specifics here */
138480 + if (flags & QMAN_ENQUEUE_FLAG_NLIS)
138481 + orp_seqnum |= QM_EQCR_SEQNUM_NLIS;
138482 + else {
138483 + orp_seqnum &= ~QM_EQCR_SEQNUM_NLIS;
138484 + if (flags & QMAN_ENQUEUE_FLAG_NESN)
138485 + orp_seqnum |= QM_EQCR_SEQNUM_NESN;
138486 + else
138487 + /* No need to check 4 QMAN_ENQUEUE_FLAG_HOLE */
138488 + orp_seqnum &= ~QM_EQCR_SEQNUM_NESN;
138489 + }
138490 + eq->seqnum = cpu_to_be16(orp_seqnum);
138491 + eq->orp = cpu_to_be32(orp->fqid);
138492 + /* Note: QM_EQCR_VERB_INTERRUPT == QMAN_ENQUEUE_FLAG_WAIT_SYNC */
138493 + qm_eqcr_pvb_commit(&p->p, QM_EQCR_VERB_ORP |
138494 + ((flags & (QMAN_ENQUEUE_FLAG_HOLE | QMAN_ENQUEUE_FLAG_NESN)) ?
138495 + 0 : QM_EQCR_VERB_CMD_ENQUEUE) |
138496 + (flags & (QM_EQCR_VERB_COLOUR_MASK | QM_EQCR_VERB_INTERRUPT)));
138497 + PORTAL_IRQ_UNLOCK(p, irqflags);
138498 + put_affine_portal();
138499 +#ifdef CONFIG_FSL_DPA_CAN_WAIT_SYNC
138500 + if (unlikely((flags & QMAN_ENQUEUE_FLAG_WAIT) &&
138501 + (flags & QMAN_ENQUEUE_FLAG_WAIT_SYNC))) {
138502 + if (flags & QMAN_ENQUEUE_FLAG_WAIT_INT)
138503 + /* NB: return success even if signal occurs before
138504 + * condition is true. pvb_commit guarantees success */
138505 + wait_event_interruptible(affine_queue,
138506 + (p->eqci_owned != fq));
138507 + else
138508 + wait_event(affine_queue, (p->eqci_owned != fq));
138509 + }
138510 +#endif
138511 + return 0;
138512 +}
138513 +EXPORT_SYMBOL(qman_enqueue_orp);
138514 +
138515 +int qman_p_enqueue_precommit(struct qman_portal *p, struct qman_fq *fq,
138516 + const struct qm_fd *fd, u32 flags,
138517 + qman_cb_precommit cb, void *cb_arg)
138518 +{
138519 + struct qm_eqcr_entry *eq;
138520 + unsigned long irqflags __maybe_unused;
138521 +
138522 +#ifdef CONFIG_FSL_DPA_CAN_WAIT
138523 + if (flags & QMAN_ENQUEUE_FLAG_WAIT)
138524 + eq = wait_p_eq_start(p, &irqflags, fq, fd, flags);
138525 + else
138526 +#endif
138527 + eq = try_p_eq_start(p, &irqflags, fq, fd, flags);
138528 + if (!eq)
138529 + return -EBUSY;
138530 + /* invoke user supplied callback function before writing commit verb */
138531 + if (cb(cb_arg)) {
138532 + PORTAL_IRQ_UNLOCK(p, irqflags);
138533 + return -EINVAL;
138534 + }
138535 + /* Note: QM_EQCR_VERB_INTERRUPT == QMAN_ENQUEUE_FLAG_WAIT_SYNC */
138536 + qm_eqcr_pvb_commit(&p->p, QM_EQCR_VERB_CMD_ENQUEUE |
138537 + (flags & (QM_EQCR_VERB_COLOUR_MASK | QM_EQCR_VERB_INTERRUPT)));
138538 + /* Factor the below out, it's used from qman_enqueue_orp() too */
138539 + PORTAL_IRQ_UNLOCK(p, irqflags);
138540 +#ifdef CONFIG_FSL_DPA_CAN_WAIT_SYNC
138541 + if (unlikely((flags & QMAN_ENQUEUE_FLAG_WAIT) &&
138542 + (flags & QMAN_ENQUEUE_FLAG_WAIT_SYNC))) {
138543 + if (flags & QMAN_ENQUEUE_FLAG_WAIT_INT)
138544 + /* NB: return success even if signal occurs before
138545 + * condition is true. pvb_commit guarantees success */
138546 + wait_event_interruptible(affine_queue,
138547 + (p->eqci_owned != fq));
138548 + else
138549 + wait_event(affine_queue, (p->eqci_owned != fq));
138550 + }
138551 +#endif
138552 + return 0;
138553 +}
138554 +EXPORT_SYMBOL(qman_p_enqueue_precommit);
138555 +
138556 +int qman_enqueue_precommit(struct qman_fq *fq, const struct qm_fd *fd,
138557 + u32 flags, qman_cb_precommit cb, void *cb_arg)
138558 +{
138559 + struct qman_portal *p;
138560 + struct qm_eqcr_entry *eq;
138561 + unsigned long irqflags __maybe_unused;
138562 +
138563 +#ifdef CONFIG_FSL_DPA_CAN_WAIT
138564 + if (flags & QMAN_ENQUEUE_FLAG_WAIT)
138565 + eq = wait_eq_start(&p, &irqflags, fq, fd, flags);
138566 + else
138567 +#endif
138568 + eq = try_eq_start(&p, &irqflags, fq, fd, flags);
138569 + if (!eq)
138570 + return -EBUSY;
138571 + /* invoke user supplied callback function before writing commit verb */
138572 + if (cb(cb_arg)) {
138573 + PORTAL_IRQ_UNLOCK(p, irqflags);
138574 + put_affine_portal();
138575 + return -EINVAL;
138576 + }
138577 + /* Note: QM_EQCR_VERB_INTERRUPT == QMAN_ENQUEUE_FLAG_WAIT_SYNC */
138578 + qm_eqcr_pvb_commit(&p->p, QM_EQCR_VERB_CMD_ENQUEUE |
138579 + (flags & (QM_EQCR_VERB_COLOUR_MASK | QM_EQCR_VERB_INTERRUPT)));
138580 + /* Factor the below out, it's used from qman_enqueue_orp() too */
138581 + PORTAL_IRQ_UNLOCK(p, irqflags);
138582 + put_affine_portal();
138583 +#ifdef CONFIG_FSL_DPA_CAN_WAIT_SYNC
138584 + if (unlikely((flags & QMAN_ENQUEUE_FLAG_WAIT) &&
138585 + (flags & QMAN_ENQUEUE_FLAG_WAIT_SYNC))) {
138586 + if (flags & QMAN_ENQUEUE_FLAG_WAIT_INT)
138587 + /* NB: return success even if signal occurs before
138588 + * condition is true. pvb_commit guarantees success */
138589 + wait_event_interruptible(affine_queue,
138590 + (p->eqci_owned != fq));
138591 + else
138592 + wait_event(affine_queue, (p->eqci_owned != fq));
138593 + }
138594 +#endif
138595 + return 0;
138596 +}
138597 +EXPORT_SYMBOL(qman_enqueue_precommit);
138598 +
138599 +int qman_modify_cgr(struct qman_cgr *cgr, u32 flags,
138600 + struct qm_mcc_initcgr *opts)
138601 +{
138602 + struct qm_mc_command *mcc;
138603 + struct qm_mc_result *mcr;
138604 + struct qman_portal *p = get_affine_portal();
138605 + unsigned long irqflags __maybe_unused;
138606 + u8 res;
138607 + u8 verb = QM_MCC_VERB_MODIFYCGR;
138608 +
138609 + PORTAL_IRQ_LOCK(p, irqflags);
138610 + mcc = qm_mc_start(&p->p);
138611 + if (opts)
138612 + mcc->initcgr = *opts;
138613 + mcc->initcgr.we_mask = cpu_to_be16(mcc->initcgr.we_mask);
138614 + mcc->initcgr.cgr.wr_parm_g.word =
138615 + cpu_to_be32(mcc->initcgr.cgr.wr_parm_g.word);
138616 + mcc->initcgr.cgr.wr_parm_y.word =
138617 + cpu_to_be32(mcc->initcgr.cgr.wr_parm_y.word);
138618 + mcc->initcgr.cgr.wr_parm_r.word =
138619 + cpu_to_be32(mcc->initcgr.cgr.wr_parm_r.word);
138620 + mcc->initcgr.cgr.cscn_targ = cpu_to_be32(mcc->initcgr.cgr.cscn_targ);
138621 + mcc->initcgr.cgr.__cs_thres = cpu_to_be16(mcc->initcgr.cgr.__cs_thres);
138622 +
138623 + mcc->initcgr.cgid = cgr->cgrid;
138624 + if (flags & QMAN_CGR_FLAG_USE_INIT)
138625 + verb = QM_MCC_VERB_INITCGR;
138626 + qm_mc_commit(&p->p, verb);
138627 + while (!(mcr = qm_mc_result(&p->p)))
138628 + cpu_relax();
138629 + DPA_ASSERT((mcr->verb & QM_MCR_VERB_MASK) == verb);
138630 + res = mcr->result;
138631 + PORTAL_IRQ_UNLOCK(p, irqflags);
138632 + put_affine_portal();
138633 + return (res == QM_MCR_RESULT_OK) ? 0 : -EIO;
138634 +}
138635 +EXPORT_SYMBOL(qman_modify_cgr);
138636 +
138637 +#define TARG_MASK(n) (0x80000000 >> (n->config->public_cfg.channel - \
138638 + QM_CHANNEL_SWPORTAL0))
138639 +#define TARG_DCP_MASK(n) (0x80000000 >> (10 + n))
138640 +#define PORTAL_IDX(n) (n->config->public_cfg.channel - QM_CHANNEL_SWPORTAL0)
138641 +
138642 +static u8 qman_cgr_cpus[__CGR_NUM];
138643 +
138644 +int qman_create_cgr(struct qman_cgr *cgr, u32 flags,
138645 + struct qm_mcc_initcgr *opts)
138646 +{
138647 + unsigned long irqflags __maybe_unused;
138648 + struct qm_mcr_querycgr cgr_state;
138649 + struct qm_mcc_initcgr local_opts;
138650 + int ret;
138651 + struct qman_portal *p;
138652 +
138653 + /* We have to check that the provided CGRID is within the limits of the
138654 + * data-structures, for obvious reasons. However we'll let h/w take
138655 + * care of determining whether it's within the limits of what exists on
138656 + * the SoC. */
138657 + if (cgr->cgrid >= __CGR_NUM)
138658 + return -EINVAL;
138659 +
138660 + preempt_disable();
138661 + p = get_affine_portal();
138662 + qman_cgr_cpus[cgr->cgrid] = smp_processor_id();
138663 + preempt_enable();
138664 +
138665 + memset(&local_opts, 0, sizeof(struct qm_mcc_initcgr));
138666 + cgr->chan = p->config->public_cfg.channel;
138667 + spin_lock_irqsave(&p->cgr_lock, irqflags);
138668 +
138669 + /* if no opts specified, just add it to the list */
138670 + if (!opts)
138671 + goto add_list;
138672 +
138673 + ret = qman_query_cgr(cgr, &cgr_state);
138674 + if (ret)
138675 + goto release_lock;
138676 + if (opts)
138677 + local_opts = *opts;
138678 + if ((qman_ip_rev & 0xFF00) >= QMAN_REV30)
138679 + local_opts.cgr.cscn_targ_upd_ctrl =
138680 + QM_CGR_TARG_UDP_CTRL_WRITE_BIT | PORTAL_IDX(p);
138681 + else
138682 + /* Overwrite TARG */
138683 + local_opts.cgr.cscn_targ = cgr_state.cgr.cscn_targ |
138684 + TARG_MASK(p);
138685 + local_opts.we_mask |= QM_CGR_WE_CSCN_TARG;
138686 +
138687 + /* send init if flags indicate so */
138688 + if (opts && (flags & QMAN_CGR_FLAG_USE_INIT))
138689 + ret = qman_modify_cgr(cgr, QMAN_CGR_FLAG_USE_INIT, &local_opts);
138690 + else
138691 + ret = qman_modify_cgr(cgr, 0, &local_opts);
138692 + if (ret)
138693 + goto release_lock;
138694 +add_list:
138695 + list_add(&cgr->node, &p->cgr_cbs);
138696 +
138697 + /* Determine if newly added object requires its callback to be called */
138698 + ret = qman_query_cgr(cgr, &cgr_state);
138699 + if (ret) {
138700 + /* we can't go back, so proceed and return success, but screen
138701 + * and wail to the log file */
138702 + pr_crit("CGR HW state partially modified\n");
138703 + ret = 0;
138704 + goto release_lock;
138705 + }
138706 + if (cgr->cb && cgr_state.cgr.cscn_en && qman_cgrs_get(&p->cgrs[1],
138707 + cgr->cgrid))
138708 + cgr->cb(p, cgr, 1);
138709 +release_lock:
138710 + spin_unlock_irqrestore(&p->cgr_lock, irqflags);
138711 + put_affine_portal();
138712 + return ret;
138713 +}
138714 +EXPORT_SYMBOL(qman_create_cgr);
138715 +
138716 +int qman_create_cgr_to_dcp(struct qman_cgr *cgr, u32 flags, u16 dcp_portal,
138717 + struct qm_mcc_initcgr *opts)
138718 +{
138719 + unsigned long irqflags __maybe_unused;
138720 + struct qm_mcc_initcgr local_opts;
138721 + struct qm_mcr_querycgr cgr_state;
138722 + int ret;
138723 +
138724 + if ((qman_ip_rev & 0xFF00) < QMAN_REV30) {
138725 + pr_warn("This QMan version doesn't support to send CSCN to DCP portal\n");
138726 + return -EINVAL;
138727 + }
138728 + /* We have to check that the provided CGRID is within the limits of the
138729 + * data-structures, for obvious reasons. However we'll let h/w take
138730 + * care of determining whether it's within the limits of what exists on
138731 + * the SoC.
138732 + */
138733 + if (cgr->cgrid >= __CGR_NUM)
138734 + return -EINVAL;
138735 +
138736 + ret = qman_query_cgr(cgr, &cgr_state);
138737 + if (ret)
138738 + return ret;
138739 +
138740 + memset(&local_opts, 0, sizeof(struct qm_mcc_initcgr));
138741 + if (opts)
138742 + local_opts = *opts;
138743 +
138744 + if ((qman_ip_rev & 0xFF00) >= QMAN_REV30)
138745 + local_opts.cgr.cscn_targ_upd_ctrl =
138746 + QM_CGR_TARG_UDP_CTRL_WRITE_BIT |
138747 + QM_CGR_TARG_UDP_CTRL_DCP | dcp_portal;
138748 + else
138749 + local_opts.cgr.cscn_targ = cgr_state.cgr.cscn_targ |
138750 + TARG_DCP_MASK(dcp_portal);
138751 + local_opts.we_mask |= QM_CGR_WE_CSCN_TARG;
138752 +
138753 + /* send init if flags indicate so */
138754 + if (opts && (flags & QMAN_CGR_FLAG_USE_INIT))
138755 + ret = qman_modify_cgr(cgr, QMAN_CGR_FLAG_USE_INIT,
138756 + &local_opts);
138757 + else
138758 + ret = qman_modify_cgr(cgr, 0, &local_opts);
138759 +
138760 + return ret;
138761 +}
138762 +EXPORT_SYMBOL(qman_create_cgr_to_dcp);
138763 +
138764 +int qman_delete_cgr(struct qman_cgr *cgr)
138765 +{
138766 + unsigned long irqflags __maybe_unused;
138767 + struct qm_mcr_querycgr cgr_state;
138768 + struct qm_mcc_initcgr local_opts;
138769 + int ret = 0;
138770 + struct qman_cgr *i;
138771 + struct qman_portal *p = get_affine_portal();
138772 +
138773 + if (cgr->chan != p->config->public_cfg.channel) {
138774 + pr_crit("Attempting to delete cgr from different portal "
138775 + "than it was create: create 0x%x, delete 0x%x\n",
138776 + cgr->chan, p->config->public_cfg.channel);
138777 + ret = -EINVAL;
138778 + goto put_portal;
138779 + }
138780 + memset(&local_opts, 0, sizeof(struct qm_mcc_initcgr));
138781 + spin_lock_irqsave(&p->cgr_lock, irqflags);
138782 + list_del(&cgr->node);
138783 + /*
138784 + * If there are no other CGR objects for this CGRID in the list, update
138785 + * CSCN_TARG accordingly
138786 + */
138787 + list_for_each_entry(i, &p->cgr_cbs, node)
138788 + if ((i->cgrid == cgr->cgrid) && i->cb)
138789 + goto release_lock;
138790 + ret = qman_query_cgr(cgr, &cgr_state);
138791 + if (ret) {
138792 + /* add back to the list */
138793 + list_add(&cgr->node, &p->cgr_cbs);
138794 + goto release_lock;
138795 + }
138796 + /* Overwrite TARG */
138797 + local_opts.we_mask = QM_CGR_WE_CSCN_TARG;
138798 + if ((qman_ip_rev & 0xFF00) >= QMAN_REV30)
138799 + local_opts.cgr.cscn_targ_upd_ctrl = PORTAL_IDX(p);
138800 + else
138801 + local_opts.cgr.cscn_targ = cgr_state.cgr.cscn_targ &
138802 + ~(TARG_MASK(p));
138803 + ret = qman_modify_cgr(cgr, 0, &local_opts);
138804 + if (ret)
138805 + /* add back to the list */
138806 + list_add(&cgr->node, &p->cgr_cbs);
138807 +release_lock:
138808 + spin_unlock_irqrestore(&p->cgr_lock, irqflags);
138809 +put_portal:
138810 + put_affine_portal();
138811 + return ret;
138812 +}
138813 +EXPORT_SYMBOL(qman_delete_cgr);
138814 +
138815 +struct cgr_comp {
138816 + struct qman_cgr *cgr;
138817 + struct completion completion;
138818 +};
138819 +
138820 +static int qman_delete_cgr_thread(void *p)
138821 +{
138822 + struct cgr_comp *cgr_comp = (struct cgr_comp *)p;
138823 + int res;
138824 +
138825 + res = qman_delete_cgr((struct qman_cgr *)cgr_comp->cgr);
138826 + complete(&cgr_comp->completion);
138827 +
138828 + return res;
138829 +}
138830 +
138831 +void qman_delete_cgr_safe(struct qman_cgr *cgr)
138832 +{
138833 + struct task_struct *thread;
138834 + struct cgr_comp cgr_comp;
138835 +
138836 + preempt_disable();
138837 + if (qman_cgr_cpus[cgr->cgrid] != smp_processor_id()) {
138838 + init_completion(&cgr_comp.completion);
138839 + cgr_comp.cgr = cgr;
138840 + thread = kthread_create(qman_delete_cgr_thread, &cgr_comp,
138841 + "cgr_del");
138842 +
138843 + if (likely(!IS_ERR(thread))) {
138844 + kthread_bind(thread, qman_cgr_cpus[cgr->cgrid]);
138845 + wake_up_process(thread);
138846 + wait_for_completion(&cgr_comp.completion);
138847 + preempt_enable();
138848 + return;
138849 + }
138850 + }
138851 + qman_delete_cgr(cgr);
138852 + preempt_enable();
138853 +}
138854 +EXPORT_SYMBOL(qman_delete_cgr_safe);
138855 +
138856 +int qm_get_clock(u64 *clock_hz)
138857 +{
138858 + if (!qman_clk) {
138859 + pr_warn("Qman clock speed is unknown\n");
138860 + return -EINVAL;
138861 + }
138862 + *clock_hz = (u64)qman_clk;
138863 + return 0;
138864 +}
138865 +EXPORT_SYMBOL(qm_get_clock);
138866 +
138867 +int qm_set_clock(u64 clock_hz)
138868 +{
138869 + if (qman_clk)
138870 + return -1;
138871 + qman_clk = (u32)clock_hz;
138872 + return 0;
138873 +}
138874 +EXPORT_SYMBOL(qm_set_clock);
138875 +
138876 +/* CEETM management command */
138877 +static int qman_ceetm_configure_lfqmt(struct qm_mcc_ceetm_lfqmt_config *opts)
138878 +{
138879 + struct qm_mc_command *mcc;
138880 + struct qm_mc_result *mcr;
138881 + struct qman_portal *p;
138882 + unsigned long irqflags __maybe_unused;
138883 + u8 res;
138884 +
138885 + p = get_affine_portal();
138886 + PORTAL_IRQ_LOCK(p, irqflags);
138887 +
138888 + mcc = qm_mc_start(&p->p);
138889 + mcc->lfqmt_config = *opts;
138890 + qm_mc_commit(&p->p, QM_CEETM_VERB_LFQMT_CONFIG);
138891 + while (!(mcr = qm_mc_result(&p->p)))
138892 + cpu_relax();
138893 + DPA_ASSERT((mcr->verb & QM_MCR_VERB_MASK) ==
138894 + QM_CEETM_VERB_LFQMT_CONFIG);
138895 + PORTAL_IRQ_UNLOCK(p, irqflags);
138896 + put_affine_portal();
138897 +
138898 + res = mcr->result;
138899 + if (res != QM_MCR_RESULT_OK) {
138900 + pr_err("CEETM: CONFIGURE LFQMT failed\n");
138901 + return -EIO;
138902 + }
138903 + return 0;
138904 +}
138905 +
138906 +int qman_ceetm_query_lfqmt(int lfqid,
138907 + struct qm_mcr_ceetm_lfqmt_query *lfqmt_query)
138908 +{
138909 + struct qm_mc_command *mcc;
138910 + struct qm_mc_result *mcr;
138911 + struct qman_portal *p;
138912 + unsigned long irqflags __maybe_unused;
138913 + u8 res;
138914 +
138915 + p = get_affine_portal();
138916 + PORTAL_IRQ_LOCK(p, irqflags);
138917 +
138918 + mcc = qm_mc_start(&p->p);
138919 + mcc->lfqmt_query.lfqid = lfqid;
138920 + qm_mc_commit(&p->p, QM_CEETM_VERB_LFQMT_QUERY);
138921 + while (!(mcr = qm_mc_result(&p->p)))
138922 + cpu_relax();
138923 + DPA_ASSERT((mcr->verb & QM_MCR_VERB_MASK) == QM_CEETM_VERB_LFQMT_QUERY);
138924 + res = mcr->result;
138925 + if (res == QM_MCR_RESULT_OK)
138926 + *lfqmt_query = mcr->lfqmt_query;
138927 +
138928 + PORTAL_IRQ_UNLOCK(p, irqflags);
138929 + put_affine_portal();
138930 + if (res != QM_MCR_RESULT_OK) {
138931 + pr_err("CEETM: QUERY LFQMT failed\n");
138932 + return -EIO;
138933 + }
138934 + return 0;
138935 +}
138936 +EXPORT_SYMBOL(qman_ceetm_query_lfqmt);
138937 +
138938 +static int qman_ceetm_configure_cq(struct qm_mcc_ceetm_cq_config *opts)
138939 +{
138940 + struct qm_mc_command *mcc;
138941 + struct qm_mc_result *mcr;
138942 + struct qman_portal *p;
138943 + unsigned long irqflags __maybe_unused;
138944 + u8 res;
138945 +
138946 + p = get_affine_portal();
138947 + PORTAL_IRQ_LOCK(p, irqflags);
138948 +
138949 + mcc = qm_mc_start(&p->p);
138950 + mcc->cq_config = *opts;
138951 + qm_mc_commit(&p->p, QM_CEETM_VERB_CQ_CONFIG);
138952 + while (!(mcr = qm_mc_result(&p->p)))
138953 + cpu_relax();
138954 + res = mcr->result;
138955 + DPA_ASSERT((mcr->verb & QM_MCR_VERB_MASK) == QM_CEETM_VERB_CQ_CONFIG);
138956 +
138957 + PORTAL_IRQ_UNLOCK(p, irqflags);
138958 + put_affine_portal();
138959 +
138960 + if (res != QM_MCR_RESULT_OK) {
138961 + pr_err("CEETM: CONFIGURE CQ failed\n");
138962 + return -EIO;
138963 + }
138964 + return 0;
138965 +}
138966 +
138967 +int qman_ceetm_query_cq(unsigned int cqid, unsigned int dcpid,
138968 + struct qm_mcr_ceetm_cq_query *cq_query)
138969 +{
138970 + struct qm_mc_command *mcc;
138971 + struct qm_mc_result *mcr;
138972 + struct qman_portal *p;
138973 + unsigned long irqflags __maybe_unused;
138974 + u8 res;
138975 +
138976 + p = get_affine_portal();
138977 + PORTAL_IRQ_LOCK(p, irqflags);
138978 +
138979 + mcc = qm_mc_start(&p->p);
138980 + mcc->cq_query.cqid = cpu_to_be16(cqid);
138981 + mcc->cq_query.dcpid = dcpid;
138982 + qm_mc_commit(&p->p, QM_CEETM_VERB_CQ_QUERY);
138983 + while (!(mcr = qm_mc_result(&p->p)))
138984 + cpu_relax();
138985 + DPA_ASSERT((mcr->verb & QM_MCR_VERB_MASK) == QM_CEETM_VERB_CQ_QUERY);
138986 + res = mcr->result;
138987 + if (res == QM_MCR_RESULT_OK) {
138988 + *cq_query = mcr->cq_query;
138989 + hw_cq_query_to_cpu(cq_query);
138990 + }
138991 +
138992 + PORTAL_IRQ_UNLOCK(p, irqflags);
138993 + put_affine_portal();
138994 +
138995 + if (res != QM_MCR_RESULT_OK) {
138996 + pr_err("CEETM: QUERY CQ failed\n");
138997 + return -EIO;
138998 + }
138999 +
139000 + return 0;
139001 +}
139002 +EXPORT_SYMBOL(qman_ceetm_query_cq);
139003 +
139004 +static int qman_ceetm_configure_dct(struct qm_mcc_ceetm_dct_config *opts)
139005 +{
139006 + struct qm_mc_command *mcc;
139007 + struct qm_mc_result *mcr;
139008 + struct qman_portal *p;
139009 + unsigned long irqflags __maybe_unused;
139010 + u8 res;
139011 +
139012 + p = get_affine_portal();
139013 + PORTAL_IRQ_LOCK(p, irqflags);
139014 +
139015 + mcc = qm_mc_start(&p->p);
139016 + mcc->dct_config = *opts;
139017 + qm_mc_commit(&p->p, QM_CEETM_VERB_DCT_CONFIG);
139018 + while (!(mcr = qm_mc_result(&p->p)))
139019 + cpu_relax();
139020 + DPA_ASSERT((mcr->verb & QM_MCR_VERB_MASK) == QM_CEETM_VERB_DCT_CONFIG);
139021 + res = mcr->result;
139022 +
139023 + PORTAL_IRQ_UNLOCK(p, irqflags);
139024 + put_affine_portal();
139025 +
139026 + if (res != QM_MCR_RESULT_OK) {
139027 + pr_err("CEETM: CONFIGURE DCT failed\n");
139028 + return -EIO;
139029 + }
139030 + return 0;
139031 +}
139032 +
139033 +static int qman_ceetm_query_dct(struct qm_mcc_ceetm_dct_query *opts,
139034 + struct qm_mcr_ceetm_dct_query *dct_query)
139035 +{
139036 + struct qm_mc_command *mcc;
139037 + struct qm_mc_result *mcr;
139038 + struct qman_portal *p = get_affine_portal();
139039 + unsigned long irqflags __maybe_unused;
139040 + u8 res;
139041 +
139042 + PORTAL_IRQ_LOCK(p, irqflags);
139043 +
139044 + mcc = qm_mc_start(&p->p);
139045 + mcc->dct_query = *opts;
139046 + qm_mc_commit(&p->p, QM_CEETM_VERB_DCT_QUERY);
139047 + while (!(mcr = qm_mc_result(&p->p)))
139048 + cpu_relax();
139049 + DPA_ASSERT((mcr->verb & QM_MCR_VERB_MASK) == QM_CEETM_VERB_DCT_QUERY);
139050 + res = mcr->result;
139051 +
139052 + PORTAL_IRQ_UNLOCK(p, irqflags);
139053 + put_affine_portal();
139054 +
139055 + if (res != QM_MCR_RESULT_OK) {
139056 + pr_err("CEETM: QUERY DCT failed\n");
139057 + return -EIO;
139058 + }
139059 +
139060 + *dct_query = mcr->dct_query;
139061 + return 0;
139062 +}
139063 +
139064 +static int qman_ceetm_configure_class_scheduler(
139065 + struct qm_mcc_ceetm_class_scheduler_config *opts)
139066 +{
139067 + struct qm_mc_command *mcc;
139068 + struct qm_mc_result *mcr;
139069 + struct qman_portal *p;
139070 + unsigned long irqflags __maybe_unused;
139071 + u8 res;
139072 +
139073 + p = get_affine_portal();
139074 + PORTAL_IRQ_LOCK(p, irqflags);
139075 +
139076 + mcc = qm_mc_start(&p->p);
139077 + mcc->csch_config = *opts;
139078 + qm_mc_commit(&p->p, QM_CEETM_VERB_CLASS_SCHEDULER_CONFIG);
139079 + while (!(mcr = qm_mc_result(&p->p)))
139080 + cpu_relax();
139081 + DPA_ASSERT((mcr->verb & QM_MCR_VERB_MASK) ==
139082 + QM_CEETM_VERB_CLASS_SCHEDULER_CONFIG);
139083 + res = mcr->result;
139084 +
139085 + PORTAL_IRQ_UNLOCK(p, irqflags);
139086 + put_affine_portal();
139087 +
139088 + if (res != QM_MCR_RESULT_OK) {
139089 + pr_err("CEETM: CONFIGURE CLASS SCHEDULER failed\n");
139090 + return -EIO;
139091 + }
139092 + return 0;
139093 +}
139094 +
139095 +static int qman_ceetm_query_class_scheduler(struct qm_ceetm_channel *channel,
139096 + struct qm_mcr_ceetm_class_scheduler_query *query)
139097 +{
139098 + struct qm_mc_command *mcc;
139099 + struct qm_mc_result *mcr;
139100 + struct qman_portal *p;
139101 + unsigned long irqflags __maybe_unused;
139102 + u8 res;
139103 +
139104 + p = get_affine_portal();
139105 + PORTAL_IRQ_LOCK(p, irqflags);
139106 +
139107 + mcc = qm_mc_start(&p->p);
139108 + mcc->csch_query.cqcid = cpu_to_be16(channel->idx);
139109 + mcc->csch_query.dcpid = channel->dcp_idx;
139110 + qm_mc_commit(&p->p, QM_CEETM_VERB_CLASS_SCHEDULER_QUERY);
139111 + while (!(mcr = qm_mc_result(&p->p)))
139112 + cpu_relax();
139113 + DPA_ASSERT((mcr->verb & QM_MCR_VERB_MASK) ==
139114 + QM_CEETM_VERB_CLASS_SCHEDULER_QUERY);
139115 + res = mcr->result;
139116 +
139117 + PORTAL_IRQ_UNLOCK(p, irqflags);
139118 + put_affine_portal();
139119 +
139120 + if (res != QM_MCR_RESULT_OK) {
139121 + pr_err("CEETM: QUERY CLASS SCHEDULER failed\n");
139122 + return -EIO;
139123 + }
139124 + *query = mcr->csch_query;
139125 + return 0;
139126 +}
139127 +
139128 +static int qman_ceetm_configure_mapping_shaper_tcfc(
139129 + struct qm_mcc_ceetm_mapping_shaper_tcfc_config *opts)
139130 +{
139131 + struct qm_mc_command *mcc;
139132 + struct qm_mc_result *mcr;
139133 + struct qman_portal *p;
139134 + unsigned long irqflags __maybe_unused;
139135 + u8 res;
139136 +
139137 + p = get_affine_portal();
139138 + PORTAL_IRQ_LOCK(p, irqflags);
139139 +
139140 + mcc = qm_mc_start(&p->p);
139141 + mcc->mst_config = *opts;
139142 + qm_mc_commit(&p->p, QM_CEETM_VERB_MAPPING_SHAPER_TCFC_CONFIG);
139143 + while (!(mcr = qm_mc_result(&p->p)))
139144 + cpu_relax();
139145 + DPA_ASSERT((mcr->verb & QM_MCR_VERB_MASK) ==
139146 + QM_CEETM_VERB_MAPPING_SHAPER_TCFC_CONFIG);
139147 + res = mcr->result;
139148 +
139149 + PORTAL_IRQ_UNLOCK(p, irqflags);
139150 + put_affine_portal();
139151 +
139152 + if (res != QM_MCR_RESULT_OK) {
139153 + pr_err("CEETM: CONFIGURE CHANNEL MAPPING failed\n");
139154 + return -EIO;
139155 + }
139156 + return 0;
139157 +}
139158 +
139159 +static int qman_ceetm_query_mapping_shaper_tcfc(
139160 + struct qm_mcc_ceetm_mapping_shaper_tcfc_query *opts,
139161 + struct qm_mcr_ceetm_mapping_shaper_tcfc_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->mst_query = *opts;
139174 + qm_mc_commit(&p->p, QM_CEETM_VERB_MAPPING_SHAPER_TCFC_QUERY);
139175 + while (!(mcr = qm_mc_result(&p->p)))
139176 + cpu_relax();
139177 + DPA_ASSERT((mcr->verb & QM_MCR_VERB_MASK) ==
139178 + QM_CEETM_VERB_MAPPING_SHAPER_TCFC_QUERY);
139179 + res = mcr->result;
139180 +
139181 + PORTAL_IRQ_UNLOCK(p, irqflags);
139182 + put_affine_portal();
139183 +
139184 + if (res != QM_MCR_RESULT_OK) {
139185 + pr_err("CEETM: QUERY CHANNEL MAPPING failed\n");
139186 + return -EIO;
139187 + }
139188 +
139189 + *response = mcr->mst_query;
139190 + return 0;
139191 +}
139192 +
139193 +static int qman_ceetm_configure_ccgr(struct qm_mcc_ceetm_ccgr_config *opts)
139194 +{
139195 + struct qm_mc_command *mcc;
139196 + struct qm_mc_result *mcr;
139197 + struct qman_portal *p;
139198 + unsigned long irqflags __maybe_unused;
139199 + u8 res;
139200 +
139201 + p = get_affine_portal();
139202 + PORTAL_IRQ_LOCK(p, irqflags);
139203 +
139204 + mcc = qm_mc_start(&p->p);
139205 + mcc->ccgr_config = *opts;
139206 +
139207 + qm_mc_commit(&p->p, QM_CEETM_VERB_CCGR_CONFIG);
139208 + while (!(mcr = qm_mc_result(&p->p)))
139209 + cpu_relax();
139210 + DPA_ASSERT((mcr->verb & QM_MCR_VERB_MASK) == QM_CEETM_VERB_CCGR_CONFIG);
139211 +
139212 + PORTAL_IRQ_UNLOCK(p, irqflags);
139213 + put_affine_portal();
139214 +
139215 + res = mcr->result;
139216 + if (res != QM_MCR_RESULT_OK) {
139217 + pr_err("CEETM: CONFIGURE CCGR failed\n");
139218 + return -EIO;
139219 + }
139220 + return 0;
139221 +}
139222 +
139223 +int qman_ceetm_query_ccgr(struct qm_mcc_ceetm_ccgr_query *ccgr_query,
139224 + struct qm_mcr_ceetm_ccgr_query *response)
139225 +{
139226 + struct qm_mc_command *mcc;
139227 + struct qm_mc_result *mcr;
139228 + struct qman_portal *p;
139229 + unsigned long irqflags __maybe_unused;
139230 + u8 res;
139231 +
139232 + p = get_affine_portal();
139233 + PORTAL_IRQ_LOCK(p, irqflags);
139234 +
139235 + mcc = qm_mc_start(&p->p);
139236 + mcc->ccgr_query.ccgrid = cpu_to_be16(ccgr_query->ccgrid);
139237 + mcc->ccgr_query.dcpid = ccgr_query->dcpid;
139238 + qm_mc_commit(&p->p, QM_CEETM_VERB_CCGR_QUERY);
139239 +
139240 + while (!(mcr = qm_mc_result(&p->p)))
139241 + cpu_relax();
139242 + DPA_ASSERT((mcr->verb & QM_MCR_VERB_MASK) == QM_CEETM_VERB_CCGR_QUERY);
139243 + res = mcr->result;
139244 + if (res == QM_MCR_RESULT_OK) {
139245 + *response = mcr->ccgr_query;
139246 + hw_ccgr_query_to_cpu(response);
139247 + }
139248 +
139249 + PORTAL_IRQ_UNLOCK(p, irqflags);
139250 + put_affine_portal();
139251 + if (res != QM_MCR_RESULT_OK) {
139252 + pr_err("CEETM: QUERY CCGR failed\n");
139253 + return -EIO;
139254 + }
139255 + return 0;
139256 +}
139257 +EXPORT_SYMBOL(qman_ceetm_query_ccgr);
139258 +
139259 +static int qman_ceetm_cq_peek_pop_xsfdrread(struct qm_ceetm_cq *cq,
139260 + u8 command_type, u16 xsfdr,
139261 + struct qm_mcr_ceetm_cq_peek_pop_xsfdrread *cq_ppxr)
139262 +{
139263 + struct qm_mc_command *mcc;
139264 + struct qm_mc_result *mcr;
139265 + struct qman_portal *p;
139266 + unsigned long irqflags __maybe_unused;
139267 + u8 res;
139268 +
139269 + p = get_affine_portal();
139270 + PORTAL_IRQ_LOCK(p, irqflags);
139271 +
139272 + mcc = qm_mc_start(&p->p);
139273 + switch (command_type) {
139274 + case 0:
139275 + case 1:
139276 + mcc->cq_ppxr.cqid = (cq->parent->idx << 4) | cq->idx;
139277 + break;
139278 + case 2:
139279 + mcc->cq_ppxr.xsfdr = xsfdr;
139280 + break;
139281 + default:
139282 + break;
139283 + }
139284 + mcc->cq_ppxr.ct = command_type;
139285 + mcc->cq_ppxr.dcpid = cq->parent->dcp_idx;
139286 + qm_mc_commit(&p->p, QM_CEETM_VERB_CQ_PEEK_POP_XFDRREAD);
139287 + while (!(mcr = qm_mc_result(&p->p)))
139288 + cpu_relax();
139289 + DPA_ASSERT((mcr->verb & QM_MCR_VERB_MASK) ==
139290 + QM_CEETM_VERB_CQ_PEEK_POP_XFDRREAD);
139291 +
139292 + PORTAL_IRQ_UNLOCK(p, irqflags);
139293 + put_affine_portal();
139294 +
139295 + res = mcr->result;
139296 + if (res != QM_MCR_RESULT_OK) {
139297 + pr_err("CEETM: CQ PEEK/POP/XSFDR READ failed\n");
139298 + return -EIO;
139299 + }
139300 + *cq_ppxr = mcr->cq_ppxr;
139301 + return 0;
139302 +}
139303 +
139304 +static int qman_ceetm_query_statistics(u16 cid,
139305 + enum qm_dc_portal dcp_idx,
139306 + u16 command_type,
139307 + struct qm_mcr_ceetm_statistics_query *query_result)
139308 +{
139309 + struct qm_mc_command *mcc;
139310 + struct qm_mc_result *mcr;
139311 + struct qman_portal *p;
139312 + unsigned long irqflags __maybe_unused;
139313 + u8 res;
139314 +
139315 + p = get_affine_portal();
139316 + PORTAL_IRQ_LOCK(p, irqflags);
139317 +
139318 + mcc = qm_mc_start(&p->p);
139319 + mcc->stats_query_write.cid = cid;
139320 + mcc->stats_query_write.dcpid = dcp_idx;
139321 + mcc->stats_query_write.ct = command_type;
139322 + qm_mc_commit(&p->p, QM_CEETM_VERB_STATISTICS_QUERY_WRITE);
139323 +
139324 + while (!(mcr = qm_mc_result(&p->p)))
139325 + cpu_relax();
139326 + DPA_ASSERT((mcr->verb & QM_MCR_VERB_MASK) ==
139327 + QM_CEETM_VERB_STATISTICS_QUERY_WRITE);
139328 +
139329 + PORTAL_IRQ_UNLOCK(p, irqflags);
139330 + put_affine_portal();
139331 +
139332 + res = mcr->result;
139333 + if (res != QM_MCR_RESULT_OK) {
139334 + pr_err("CEETM: STATISTICS QUERY failed\n");
139335 + return -EIO;
139336 + }
139337 + *query_result = mcr->stats_query;
139338 + return 0;
139339 +}
139340 +
139341 +int qman_ceetm_query_write_statistics(u16 cid, enum qm_dc_portal dcp_idx,
139342 + u16 command_type, u64 frame_count,
139343 + u64 byte_count)
139344 +{
139345 + struct qm_mc_command *mcc;
139346 + struct qm_mc_result *mcr;
139347 + struct qman_portal *p;
139348 + unsigned long irqflags __maybe_unused;
139349 + u8 res;
139350 +
139351 + p = get_affine_portal();
139352 + PORTAL_IRQ_LOCK(p, irqflags);
139353 +
139354 + mcc = qm_mc_start(&p->p);
139355 + mcc->stats_query_write.cid = cid;
139356 + mcc->stats_query_write.dcpid = dcp_idx;
139357 + mcc->stats_query_write.ct = command_type;
139358 + mcc->stats_query_write.frm_cnt = frame_count;
139359 + mcc->stats_query_write.byte_cnt = byte_count;
139360 + qm_mc_commit(&p->p, QM_CEETM_VERB_STATISTICS_QUERY_WRITE);
139361 +
139362 + while (!(mcr = qm_mc_result(&p->p)))
139363 + cpu_relax();
139364 + DPA_ASSERT((mcr->verb & QM_MCR_VERB_MASK) ==
139365 + QM_CEETM_VERB_STATISTICS_QUERY_WRITE);
139366 +
139367 + PORTAL_IRQ_UNLOCK(p, irqflags);
139368 + put_affine_portal();
139369 +
139370 + res = mcr->result;
139371 + if (res != QM_MCR_RESULT_OK) {
139372 + pr_err("CEETM: STATISTICS WRITE failed\n");
139373 + return -EIO;
139374 + }
139375 + return 0;
139376 +}
139377 +EXPORT_SYMBOL(qman_ceetm_query_write_statistics);
139378 +
139379 +int qman_ceetm_bps2tokenrate(u64 bps, struct qm_ceetm_rate *token_rate,
139380 + int rounding)
139381 +{
139382 + u16 pres;
139383 + u64 temp;
139384 + u64 qman_freq;
139385 + int ret;
139386 +
139387 + /* Read PRES from CEET_CFG_PRES register */
139388 + ret = qman_ceetm_get_prescaler(&pres);
139389 + if (ret)
139390 + return -EINVAL;
139391 +
139392 + ret = qm_get_clock(&qman_freq);
139393 + if (ret)
139394 + return -EINVAL;
139395 +
139396 + /* token-rate = bytes-per-second * update-reference-period
139397 + *
139398 + * Where token-rate is N/8192 for a integer N, and
139399 + * update-reference-period is (2^22)/(PRES*QHz), where PRES
139400 + * is the prescalar value and QHz is the QMan clock frequency.
139401 + * So:
139402 + *
139403 + * token-rate = (byte-per-second*2^22)/PRES*QHZ)
139404 + *
139405 + * Converting to bits-per-second gives;
139406 + *
139407 + * token-rate = (bps*2^19) / (PRES*QHZ)
139408 + * N = (bps*2^32) / (PRES*QHz)
139409 + *
139410 + * And to avoid 64-bit overflow if 'bps' is larger than 4Gbps
139411 + * (yet minimise rounding error if 'bps' is small), we reorganise
139412 + * the formula to use two 16-bit shifts rather than 1 32-bit shift.
139413 + * N = (((bps*2^16)/PRES)*2^16)/QHz
139414 + */
139415 + temp = ROUNDING((bps << 16), pres, rounding);
139416 + temp = ROUNDING((temp << 16), qman_freq, rounding);
139417 + token_rate->whole = temp >> 13;
139418 + token_rate->fraction = temp & (((u64)1 << 13) - 1);
139419 + return 0;
139420 +}
139421 +EXPORT_SYMBOL(qman_ceetm_bps2tokenrate);
139422 +
139423 +int qman_ceetm_tokenrate2bps(const struct qm_ceetm_rate *token_rate, u64 *bps,
139424 + int rounding)
139425 +{
139426 + u16 pres;
139427 + u64 temp;
139428 + u64 qman_freq;
139429 + int ret;
139430 +
139431 + /* Read PRES from CEET_CFG_PRES register */
139432 + ret = qman_ceetm_get_prescaler(&pres);
139433 + if (ret)
139434 + return -EINVAL;
139435 +
139436 + ret = qm_get_clock(&qman_freq);
139437 + if (ret)
139438 + return -EINVAL;
139439 +
139440 + /* bytes-per-second = token-rate / update-reference-period
139441 + *
139442 + * where "token-rate" is N/8192 for an integer N, and
139443 + * "update-reference-period" is (2^22)/(PRES*QHz), where PRES is
139444 + * the prescalar value and QHz is the QMan clock frequency. So;
139445 + *
139446 + * bytes-per-second = (N/8192) / (4194304/PRES*QHz)
139447 + * = N*PRES*QHz / (4194304*8192)
139448 + * = N*PRES*QHz / (2^35)
139449 + *
139450 + * Converting to bits-per-second gives;
139451 + *
139452 + * bps = N*PRES*QHZ / (2^32)
139453 + *
139454 + * Note, the numerator has a maximum width of 72 bits! So to
139455 + * avoid 64-bit overflow errors, we calculate PRES*QHZ (maximum
139456 + * width 48 bits) divided by 2^9 (reducing to maximum 39 bits), before
139457 + * multiplying by N (goes to maximum of 63 bits).
139458 + *
139459 + * temp = PRES*QHZ / (2^16)
139460 + * kbps = temp*N / (2^16)
139461 + */
139462 + temp = ROUNDING(qman_freq * pres, (u64)1 << 16 , rounding);
139463 + temp *= ((token_rate->whole << 13) + token_rate->fraction);
139464 + *bps = ROUNDING(temp, (u64)(1) << 16, rounding);
139465 + return 0;
139466 +}
139467 +EXPORT_SYMBOL(qman_ceetm_tokenrate2bps);
139468 +
139469 +int qman_ceetm_sp_claim(struct qm_ceetm_sp **sp, enum qm_dc_portal dcp_idx,
139470 + unsigned int sp_idx)
139471 +{
139472 + struct qm_ceetm_sp *p;
139473 +
139474 + DPA_ASSERT((dcp_idx == qm_dc_portal_fman0) ||
139475 + (dcp_idx == qm_dc_portal_fman1));
139476 +
139477 + if ((sp_idx < qman_ceetms[dcp_idx].sp_range[0]) ||
139478 + (sp_idx >= (qman_ceetms[dcp_idx].sp_range[0] +
139479 + qman_ceetms[dcp_idx].sp_range[1]))) {
139480 + pr_err("Sub-portal index doesn't exist\n");
139481 + return -EINVAL;
139482 + }
139483 +
139484 + list_for_each_entry(p, &qman_ceetms[dcp_idx].sub_portals, node) {
139485 + if ((p->idx == sp_idx) && (p->is_claimed == 0)) {
139486 + p->is_claimed = 1;
139487 + *sp = p;
139488 + return 0;
139489 + }
139490 + }
139491 + pr_err("The sub-portal#%d is not available!\n", sp_idx);
139492 + return -ENODEV;
139493 +}
139494 +EXPORT_SYMBOL(qman_ceetm_sp_claim);
139495 +
139496 +int qman_ceetm_sp_release(struct qm_ceetm_sp *sp)
139497 +{
139498 + struct qm_ceetm_sp *p;
139499 +
139500 + if (sp->lni && sp->lni->is_claimed == 1) {
139501 + pr_err("The dependency of sub-portal has not been released!\n");
139502 + return -EBUSY;
139503 + }
139504 +
139505 + list_for_each_entry(p, &qman_ceetms[sp->dcp_idx].sub_portals, node) {
139506 + if (p->idx == sp->idx) {
139507 + p->is_claimed = 0;
139508 + p->lni = NULL;
139509 + }
139510 + }
139511 + /* Disable CEETM mode of this sub-portal */
139512 + qman_sp_disable_ceetm_mode(sp->dcp_idx, sp->idx);
139513 +
139514 + return 0;
139515 +}
139516 +EXPORT_SYMBOL(qman_ceetm_sp_release);
139517 +
139518 +int qman_ceetm_lni_claim(struct qm_ceetm_lni **lni, enum qm_dc_portal dcp_idx,
139519 + unsigned int lni_idx)
139520 +{
139521 + struct qm_ceetm_lni *p;
139522 +
139523 + if ((lni_idx < qman_ceetms[dcp_idx].lni_range[0]) ||
139524 + (lni_idx >= (qman_ceetms[dcp_idx].lni_range[0] +
139525 + qman_ceetms[dcp_idx].lni_range[1]))) {
139526 + pr_err("The lni index is out of range\n");
139527 + return -EINVAL;
139528 + }
139529 +
139530 + list_for_each_entry(p, &qman_ceetms[dcp_idx].lnis, node) {
139531 + if ((p->idx == lni_idx) && (p->is_claimed == 0)) {
139532 + *lni = p;
139533 + p->is_claimed = 1;
139534 + return 0;
139535 + }
139536 + }
139537 +
139538 + pr_err("The LNI#%d is not available!\n", lni_idx);
139539 + return -EINVAL;
139540 +}
139541 +EXPORT_SYMBOL(qman_ceetm_lni_claim);
139542 +
139543 +int qman_ceetm_lni_release(struct qm_ceetm_lni *lni)
139544 +{
139545 + struct qm_ceetm_lni *p;
139546 + struct qm_mcc_ceetm_mapping_shaper_tcfc_config config_opts;
139547 +
139548 + if (!list_empty(&lni->channels)) {
139549 + pr_err("The LNI dependencies are not released!\n");
139550 + return -EBUSY;
139551 + }
139552 +
139553 + list_for_each_entry(p, &qman_ceetms[lni->dcp_idx].lnis, node) {
139554 + if (p->idx == lni->idx) {
139555 + p->shaper_enable = 0;
139556 + p->shaper_couple = 0;
139557 + p->cr_token_rate.whole = 0;
139558 + p->cr_token_rate.fraction = 0;
139559 + p->er_token_rate.whole = 0;
139560 + p->er_token_rate.fraction = 0;
139561 + p->cr_token_bucket_limit = 0;
139562 + p->er_token_bucket_limit = 0;
139563 + p->is_claimed = 0;
139564 + }
139565 + }
139566 + config_opts.cid = cpu_to_be16(CEETM_COMMAND_LNI_SHAPER | lni->idx);
139567 + config_opts.dcpid = lni->dcp_idx;
139568 + memset(&config_opts.shaper_config, 0,
139569 + sizeof(config_opts.shaper_config));
139570 + return qman_ceetm_configure_mapping_shaper_tcfc(&config_opts);
139571 +}
139572 +EXPORT_SYMBOL(qman_ceetm_lni_release);
139573 +
139574 +int qman_ceetm_sp_set_lni(struct qm_ceetm_sp *sp, struct qm_ceetm_lni *lni)
139575 +{
139576 + struct qm_mcc_ceetm_mapping_shaper_tcfc_config config_opts;
139577 +
139578 + config_opts.cid = cpu_to_be16(CEETM_COMMAND_SP_MAPPING | sp->idx);
139579 + config_opts.dcpid = sp->dcp_idx;
139580 + config_opts.sp_mapping.map_lni_id = lni->idx;
139581 + sp->lni = lni;
139582 +
139583 + if (qman_ceetm_configure_mapping_shaper_tcfc(&config_opts))
139584 + return -EINVAL;
139585 +
139586 + /* Enable CEETM mode for this sub-portal */
139587 + return qman_sp_enable_ceetm_mode(sp->dcp_idx, sp->idx);
139588 +}
139589 +EXPORT_SYMBOL(qman_ceetm_sp_set_lni);
139590 +
139591 +int qman_ceetm_sp_get_lni(struct qm_ceetm_sp *sp, unsigned int *lni_idx)
139592 +{
139593 + struct qm_mcc_ceetm_mapping_shaper_tcfc_query query_opts;
139594 + struct qm_mcr_ceetm_mapping_shaper_tcfc_query query_result;
139595 +
139596 + query_opts.cid = cpu_to_be16(CEETM_COMMAND_SP_MAPPING | sp->idx);
139597 + query_opts.dcpid = sp->dcp_idx;
139598 + if (qman_ceetm_query_mapping_shaper_tcfc(&query_opts, &query_result)) {
139599 + pr_err("Can't get SP <-> LNI mapping\n");
139600 + return -EINVAL;
139601 + }
139602 + *lni_idx = query_result.sp_mapping_query.map_lni_id;
139603 + sp->lni->idx = query_result.sp_mapping_query.map_lni_id;
139604 + return 0;
139605 +}
139606 +EXPORT_SYMBOL(qman_ceetm_sp_get_lni);
139607 +
139608 +int qman_ceetm_lni_enable_shaper(struct qm_ceetm_lni *lni, int coupled,
139609 + int oal)
139610 +{
139611 + struct qm_mcc_ceetm_mapping_shaper_tcfc_config config_opts;
139612 +
139613 + if (lni->shaper_enable) {
139614 + pr_err("The shaper has already been enabled\n");
139615 + return -EINVAL;
139616 + }
139617 + lni->shaper_enable = 1;
139618 + lni->shaper_couple = coupled;
139619 + lni->oal = oal;
139620 +
139621 + config_opts.cid = cpu_to_be16(CEETM_COMMAND_LNI_SHAPER | lni->idx);
139622 + config_opts.dcpid = lni->dcp_idx;
139623 + config_opts.shaper_config.cpl = coupled;
139624 + config_opts.shaper_config.oal = oal;
139625 + config_opts.shaper_config.crtcr = cpu_to_be24((lni->cr_token_rate.whole
139626 + << 13) | lni->cr_token_rate.fraction);
139627 + config_opts.shaper_config.ertcr = cpu_to_be24((lni->er_token_rate.whole
139628 + << 13) | lni->er_token_rate.fraction);
139629 + config_opts.shaper_config.crtbl =
139630 + cpu_to_be16(lni->cr_token_bucket_limit);
139631 + config_opts.shaper_config.ertbl =
139632 + cpu_to_be16(lni->er_token_bucket_limit);
139633 + config_opts.shaper_config.mps = 60;
139634 +
139635 + return qman_ceetm_configure_mapping_shaper_tcfc(&config_opts);
139636 +}
139637 +EXPORT_SYMBOL(qman_ceetm_lni_enable_shaper);
139638 +
139639 +int qman_ceetm_lni_disable_shaper(struct qm_ceetm_lni *lni)
139640 +{
139641 + struct qm_mcc_ceetm_mapping_shaper_tcfc_config config_opts;
139642 +
139643 + if (!lni->shaper_enable) {
139644 + pr_err("The shaper has been disabled\n");
139645 + return -EINVAL;
139646 + }
139647 +
139648 + config_opts.cid = cpu_to_be16(CEETM_COMMAND_LNI_SHAPER | lni->idx);
139649 + config_opts.dcpid = lni->dcp_idx;
139650 + config_opts.shaper_config.cpl = lni->shaper_couple;
139651 + config_opts.shaper_config.oal = lni->oal;
139652 + config_opts.shaper_config.crtbl =
139653 + cpu_to_be16(lni->cr_token_bucket_limit);
139654 + config_opts.shaper_config.ertbl =
139655 + cpu_to_be16(lni->er_token_bucket_limit);
139656 + /* Set CR/ER rate with all 1's to configure an infinite rate, thus
139657 + * disable the shaping.
139658 + */
139659 + config_opts.shaper_config.crtcr = 0xFFFFFF;
139660 + config_opts.shaper_config.ertcr = 0xFFFFFF;
139661 + config_opts.shaper_config.mps = 60;
139662 + lni->shaper_enable = 0;
139663 + return qman_ceetm_configure_mapping_shaper_tcfc(&config_opts);
139664 +}
139665 +EXPORT_SYMBOL(qman_ceetm_lni_disable_shaper);
139666 +
139667 +int qman_ceetm_lni_is_shaper_enabled(struct qm_ceetm_lni *lni)
139668 +{
139669 + return lni->shaper_enable;
139670 +}
139671 +EXPORT_SYMBOL(qman_ceetm_lni_is_shaper_enabled);
139672 +
139673 +int qman_ceetm_lni_set_commit_rate(struct qm_ceetm_lni *lni,
139674 + const struct qm_ceetm_rate *token_rate,
139675 + u16 token_limit)
139676 +{
139677 + struct qm_mcc_ceetm_mapping_shaper_tcfc_config config_opts;
139678 + struct qm_mcc_ceetm_mapping_shaper_tcfc_query query_opts;
139679 + struct qm_mcr_ceetm_mapping_shaper_tcfc_query query_result;
139680 + int ret;
139681 +
139682 + lni->cr_token_rate.whole = token_rate->whole;
139683 + lni->cr_token_rate.fraction = token_rate->fraction;
139684 + lni->cr_token_bucket_limit = token_limit;
139685 + if (!lni->shaper_enable)
139686 + return 0;
139687 + query_opts.cid = cpu_to_be16(CEETM_COMMAND_LNI_SHAPER | lni->idx);
139688 + query_opts.dcpid = lni->dcp_idx;
139689 + ret = qman_ceetm_query_mapping_shaper_tcfc(&query_opts,
139690 + &query_result);
139691 + if (ret) {
139692 + pr_err("Fail to get current LNI shaper setting\n");
139693 + return -EINVAL;
139694 + }
139695 +
139696 + config_opts.cid = cpu_to_be16(CEETM_COMMAND_LNI_SHAPER | lni->idx);
139697 + config_opts.dcpid = lni->dcp_idx;
139698 + config_opts.shaper_config.crtcr = cpu_to_be24((token_rate->whole << 13)
139699 + | (token_rate->fraction));
139700 + config_opts.shaper_config.crtbl = cpu_to_be16(token_limit);
139701 + config_opts.shaper_config.cpl = query_result.shaper_query.cpl;
139702 + config_opts.shaper_config.oal = query_result.shaper_query.oal;
139703 + config_opts.shaper_config.ertcr = query_result.shaper_query.ertcr;
139704 + config_opts.shaper_config.ertbl = query_result.shaper_query.ertbl;
139705 + config_opts.shaper_config.mps = query_result.shaper_query.mps;
139706 + return qman_ceetm_configure_mapping_shaper_tcfc(&config_opts);
139707 +}
139708 +EXPORT_SYMBOL(qman_ceetm_lni_set_commit_rate);
139709 +
139710 +int qman_ceetm_lni_set_commit_rate_bps(struct qm_ceetm_lni *lni,
139711 + u64 bps,
139712 + u16 token_limit)
139713 +{
139714 + struct qm_ceetm_rate token_rate;
139715 + int ret;
139716 +
139717 + ret = qman_ceetm_bps2tokenrate(bps, &token_rate, 0);
139718 + if (ret) {
139719 + pr_err("Can not convert bps to token rate\n");
139720 + return -EINVAL;
139721 + }
139722 +
139723 + return qman_ceetm_lni_set_commit_rate(lni, &token_rate, token_limit);
139724 +}
139725 +EXPORT_SYMBOL(qman_ceetm_lni_set_commit_rate_bps);
139726 +
139727 +int qman_ceetm_lni_get_commit_rate(struct qm_ceetm_lni *lni,
139728 + struct qm_ceetm_rate *token_rate,
139729 + u16 *token_limit)
139730 +{
139731 + struct qm_mcc_ceetm_mapping_shaper_tcfc_query query_opts;
139732 + struct qm_mcr_ceetm_mapping_shaper_tcfc_query query_result;
139733 + int ret;
139734 +
139735 + query_opts.cid = cpu_to_be16(CEETM_COMMAND_LNI_SHAPER | lni->idx);
139736 + query_opts.dcpid = lni->dcp_idx;
139737 +
139738 + ret = qman_ceetm_query_mapping_shaper_tcfc(&query_opts, &query_result);
139739 + if (ret) {
139740 + pr_err("The LNI CR rate or limit is not set\n");
139741 + return -EINVAL;
139742 + }
139743 + token_rate->whole = be24_to_cpu(query_result.shaper_query.crtcr) >> 13;
139744 + token_rate->fraction = be24_to_cpu(query_result.shaper_query.crtcr) &
139745 + 0x1FFF;
139746 + *token_limit = be16_to_cpu(query_result.shaper_query.crtbl);
139747 + return 0;
139748 +}
139749 +EXPORT_SYMBOL(qman_ceetm_lni_get_commit_rate);
139750 +
139751 +int qman_ceetm_lni_get_commit_rate_bps(struct qm_ceetm_lni *lni,
139752 + u64 *bps, u16 *token_limit)
139753 +{
139754 + struct qm_ceetm_rate token_rate;
139755 + int ret;
139756 +
139757 + ret = qman_ceetm_lni_get_commit_rate(lni, &token_rate, token_limit);
139758 + if (ret) {
139759 + pr_err("The LNI CR rate or limit is not available\n");
139760 + return -EINVAL;
139761 + }
139762 +
139763 + return qman_ceetm_tokenrate2bps(&token_rate, bps, 0);
139764 +}
139765 +EXPORT_SYMBOL(qman_ceetm_lni_get_commit_rate_bps);
139766 +
139767 +int qman_ceetm_lni_set_excess_rate(struct qm_ceetm_lni *lni,
139768 + const struct qm_ceetm_rate *token_rate,
139769 + u16 token_limit)
139770 +{
139771 + struct qm_mcc_ceetm_mapping_shaper_tcfc_config config_opts;
139772 + struct qm_mcc_ceetm_mapping_shaper_tcfc_query query_opts;
139773 + struct qm_mcr_ceetm_mapping_shaper_tcfc_query query_result;
139774 + int ret;
139775 +
139776 + lni->er_token_rate.whole = token_rate->whole;
139777 + lni->er_token_rate.fraction = token_rate->fraction;
139778 + lni->er_token_bucket_limit = token_limit;
139779 + if (!lni->shaper_enable)
139780 + return 0;
139781 +
139782 + query_opts.cid = cpu_to_be16(CEETM_COMMAND_LNI_SHAPER | lni->idx);
139783 + query_opts.dcpid = lni->dcp_idx;
139784 + ret = qman_ceetm_query_mapping_shaper_tcfc(&query_opts,
139785 + &query_result);
139786 + if (ret) {
139787 + pr_err("Fail to get current LNI shaper setting\n");
139788 + return -EINVAL;
139789 + }
139790 +
139791 + config_opts.cid = cpu_to_be16(CEETM_COMMAND_LNI_SHAPER | lni->idx);
139792 + config_opts.dcpid = lni->dcp_idx;
139793 + config_opts.shaper_config.ertcr = cpu_to_be24(
139794 + (token_rate->whole << 13) | (token_rate->fraction));
139795 + config_opts.shaper_config.ertbl = cpu_to_be16(token_limit);
139796 + config_opts.shaper_config.cpl = query_result.shaper_query.cpl;
139797 + config_opts.shaper_config.oal = query_result.shaper_query.oal;
139798 + config_opts.shaper_config.crtcr = query_result.shaper_query.crtcr;
139799 + config_opts.shaper_config.crtbl = query_result.shaper_query.crtbl;
139800 + config_opts.shaper_config.mps = query_result.shaper_query.mps;
139801 + return qman_ceetm_configure_mapping_shaper_tcfc(&config_opts);
139802 +}
139803 +EXPORT_SYMBOL(qman_ceetm_lni_set_excess_rate);
139804 +
139805 +int qman_ceetm_lni_set_excess_rate_bps(struct qm_ceetm_lni *lni,
139806 + u64 bps,
139807 + u16 token_limit)
139808 +{
139809 + struct qm_ceetm_rate token_rate;
139810 + int ret;
139811 +
139812 + ret = qman_ceetm_bps2tokenrate(bps, &token_rate, 0);
139813 + if (ret) {
139814 + pr_err("Can not convert bps to token rate\n");
139815 + return -EINVAL;
139816 + }
139817 + return qman_ceetm_lni_set_excess_rate(lni, &token_rate, token_limit);
139818 +}
139819 +EXPORT_SYMBOL(qman_ceetm_lni_set_excess_rate_bps);
139820 +
139821 +int qman_ceetm_lni_get_excess_rate(struct qm_ceetm_lni *lni,
139822 + struct qm_ceetm_rate *token_rate,
139823 + u16 *token_limit)
139824 +{
139825 + struct qm_mcc_ceetm_mapping_shaper_tcfc_query query_opts;
139826 + struct qm_mcr_ceetm_mapping_shaper_tcfc_query query_result;
139827 + int ret;
139828 +
139829 + query_opts.cid = cpu_to_be16(CEETM_COMMAND_LNI_SHAPER | lni->idx);
139830 + query_opts.dcpid = lni->dcp_idx;
139831 + ret = qman_ceetm_query_mapping_shaper_tcfc(&query_opts, &query_result);
139832 + if (ret) {
139833 + pr_err("The LNI ER rate or limit is not set\n");
139834 + return -EINVAL;
139835 + }
139836 + token_rate->whole = be24_to_cpu(query_result.shaper_query.ertcr) >> 13;
139837 + token_rate->fraction = be24_to_cpu(query_result.shaper_query.ertcr) &
139838 + 0x1FFF;
139839 + *token_limit = be16_to_cpu(query_result.shaper_query.ertbl);
139840 + return 0;
139841 +}
139842 +EXPORT_SYMBOL(qman_ceetm_lni_get_excess_rate);
139843 +
139844 +int qman_ceetm_lni_get_excess_rate_bps(struct qm_ceetm_lni *lni,
139845 + u64 *bps, u16 *token_limit)
139846 +{
139847 + struct qm_ceetm_rate token_rate;
139848 + int ret;
139849 +
139850 + ret = qman_ceetm_lni_get_excess_rate(lni, &token_rate, token_limit);
139851 + if (ret) {
139852 + pr_err("The LNI ER rate or limit is not available\n");
139853 + return -EINVAL;
139854 + }
139855 +
139856 + return qman_ceetm_tokenrate2bps(&token_rate, bps, 0);
139857 +}
139858 +EXPORT_SYMBOL(qman_ceetm_lni_get_excess_rate_bps);
139859 +
139860 +#define QMAN_CEETM_LNITCFCC_CQ_LEVEL_SHIFT(n) ((15 - n) * 4)
139861 +#define QMAN_CEETM_LNITCFCC_ENABLE 0x8
139862 +int qman_ceetm_lni_set_tcfcc(struct qm_ceetm_lni *lni,
139863 + unsigned int cq_level,
139864 + int traffic_class)
139865 +{
139866 + struct qm_mcc_ceetm_mapping_shaper_tcfc_config config_opts;
139867 + struct qm_mcc_ceetm_mapping_shaper_tcfc_query query_opts;
139868 + struct qm_mcr_ceetm_mapping_shaper_tcfc_query query_result;
139869 + u64 lnitcfcc;
139870 +
139871 + if ((cq_level > 15) | (traffic_class > 7)) {
139872 + pr_err("The CQ or traffic class id is out of range\n");
139873 + return -EINVAL;
139874 + }
139875 +
139876 + query_opts.cid = cpu_to_be16(CEETM_COMMAND_TCFC | lni->idx);
139877 + query_opts.dcpid = lni->dcp_idx;
139878 + if (qman_ceetm_query_mapping_shaper_tcfc(&query_opts, &query_result)) {
139879 + pr_err("Fail to query tcfcc\n");
139880 + return -EINVAL;
139881 + }
139882 +
139883 + lnitcfcc = be64_to_cpu(query_result.tcfc_query.lnitcfcc);
139884 + if (traffic_class == -1) {
139885 + /* disable tcfc for this CQ */
139886 + lnitcfcc &= ~((u64)QMAN_CEETM_LNITCFCC_ENABLE <<
139887 + QMAN_CEETM_LNITCFCC_CQ_LEVEL_SHIFT(cq_level));
139888 + } else {
139889 + lnitcfcc &= ~((u64)0xF <<
139890 + QMAN_CEETM_LNITCFCC_CQ_LEVEL_SHIFT(cq_level));
139891 + lnitcfcc |= ((u64)(QMAN_CEETM_LNITCFCC_ENABLE |
139892 + traffic_class)) <<
139893 + QMAN_CEETM_LNITCFCC_CQ_LEVEL_SHIFT(cq_level);
139894 + }
139895 + config_opts.tcfc_config.lnitcfcc = cpu_to_be64(lnitcfcc);
139896 + config_opts.cid = cpu_to_be16(CEETM_COMMAND_TCFC | lni->idx);
139897 + config_opts.dcpid = lni->dcp_idx;
139898 + return qman_ceetm_configure_mapping_shaper_tcfc(&config_opts);
139899 +}
139900 +EXPORT_SYMBOL(qman_ceetm_lni_set_tcfcc);
139901 +
139902 +#define QMAN_CEETM_LNITCFCC_TC_MASK 0x7
139903 +int qman_ceetm_lni_get_tcfcc(struct qm_ceetm_lni *lni, unsigned int cq_level,
139904 + int *traffic_class)
139905 +{
139906 + struct qm_mcc_ceetm_mapping_shaper_tcfc_query query_opts;
139907 + struct qm_mcr_ceetm_mapping_shaper_tcfc_query query_result;
139908 + int ret;
139909 + u8 lnitcfcc;
139910 +
139911 + if (cq_level > 15) {
139912 + pr_err("the CQ level is out of range\n");
139913 + return -EINVAL;
139914 + }
139915 +
139916 + query_opts.cid = cpu_to_be16(CEETM_COMMAND_TCFC | lni->idx);
139917 + query_opts.dcpid = lni->dcp_idx;
139918 + ret = qman_ceetm_query_mapping_shaper_tcfc(&query_opts, &query_result);
139919 + if (ret)
139920 + return ret;
139921 + lnitcfcc = (u8)be64_to_cpu((query_result.tcfc_query.lnitcfcc) >>
139922 + QMAN_CEETM_LNITCFCC_CQ_LEVEL_SHIFT(cq_level));
139923 + if (lnitcfcc & QMAN_CEETM_LNITCFCC_ENABLE)
139924 + *traffic_class = lnitcfcc & QMAN_CEETM_LNITCFCC_TC_MASK;
139925 + else
139926 + *traffic_class = -1;
139927 + return 0;
139928 +}
139929 +EXPORT_SYMBOL(qman_ceetm_lni_get_tcfcc);
139930 +
139931 +int qman_ceetm_channel_claim(struct qm_ceetm_channel **channel,
139932 + struct qm_ceetm_lni *lni)
139933 +{
139934 + struct qm_ceetm_channel *p;
139935 + u32 channel_idx;
139936 + int ret = 0;
139937 + struct qm_mcc_ceetm_mapping_shaper_tcfc_config config_opts;
139938 +
139939 + if (lni->dcp_idx == qm_dc_portal_fman0) {
139940 + ret = qman_alloc_ceetm0_channel(&channel_idx);
139941 + } else if (lni->dcp_idx == qm_dc_portal_fman1) {
139942 + ret = qman_alloc_ceetm1_channel(&channel_idx);
139943 + } else {
139944 + pr_err("dcp_idx %u does not correspond to a known fman in this driver\n",
139945 + lni->dcp_idx);
139946 + return -EINVAL;
139947 + }
139948 +
139949 + if (ret) {
139950 + pr_err("The is no channel available for LNI#%d\n", lni->idx);
139951 + return -ENODEV;
139952 + }
139953 +
139954 + p = kzalloc(sizeof(*p), GFP_KERNEL);
139955 + if (!p)
139956 + return -ENOMEM;
139957 + p->idx = channel_idx;
139958 + p->dcp_idx = lni->dcp_idx;
139959 + p->lni_idx = lni->idx;
139960 + list_add_tail(&p->node, &lni->channels);
139961 + INIT_LIST_HEAD(&p->class_queues);
139962 + INIT_LIST_HEAD(&p->ccgs);
139963 + config_opts.cid = cpu_to_be16(CEETM_COMMAND_CHANNEL_MAPPING |
139964 + channel_idx);
139965 + config_opts.dcpid = lni->dcp_idx;
139966 + config_opts.channel_mapping.map_lni_id = lni->idx;
139967 + config_opts.channel_mapping.map_shaped = 0;
139968 + if (qman_ceetm_configure_mapping_shaper_tcfc(&config_opts)) {
139969 + pr_err("Can't map channel#%d for LNI#%d\n",
139970 + channel_idx, lni->idx);
139971 + return -EINVAL;
139972 + }
139973 + *channel = p;
139974 + return 0;
139975 +}
139976 +EXPORT_SYMBOL(qman_ceetm_channel_claim);
139977 +
139978 +int qman_ceetm_channel_release(struct qm_ceetm_channel *channel)
139979 +{
139980 + struct qm_mcc_ceetm_mapping_shaper_tcfc_config config_opts;
139981 + if (!list_empty(&channel->class_queues)) {
139982 + pr_err("CEETM channel#%d has class queue unreleased!\n",
139983 + channel->idx);
139984 + return -EBUSY;
139985 + }
139986 + if (!list_empty(&channel->ccgs)) {
139987 + pr_err("CEETM channel#%d has ccg unreleased!\n",
139988 + channel->idx);
139989 + return -EBUSY;
139990 + }
139991 +
139992 + /* channel->dcp_idx corresponds to known fman validation */
139993 + if ((channel->dcp_idx != qm_dc_portal_fman0) &&
139994 + (channel->dcp_idx != qm_dc_portal_fman1)) {
139995 + pr_err("dcp_idx %u does not correspond to a known fman in this driver\n",
139996 + channel->dcp_idx);
139997 + return -EINVAL;
139998 + }
139999 +
140000 + config_opts.cid = cpu_to_be16(CEETM_COMMAND_CHANNEL_SHAPER |
140001 + channel->idx);
140002 + config_opts.dcpid = channel->dcp_idx;
140003 + memset(&config_opts.shaper_config, 0,
140004 + sizeof(config_opts.shaper_config));
140005 + if (qman_ceetm_configure_mapping_shaper_tcfc(&config_opts)) {
140006 + pr_err("Can't reset channel shapping parameters\n");
140007 + return -EINVAL;
140008 + }
140009 +
140010 + if (channel->dcp_idx == qm_dc_portal_fman0) {
140011 + qman_release_ceetm0_channelid(channel->idx);
140012 + } else if (channel->dcp_idx == qm_dc_portal_fman1) {
140013 + qman_release_ceetm1_channelid(channel->idx);
140014 + } else {
140015 + pr_err("dcp_idx %u does not correspond to a known fman in this driver\n",
140016 + channel->dcp_idx);
140017 + return -EINVAL;
140018 + }
140019 + list_del(&channel->node);
140020 + kfree(channel);
140021 +
140022 + return 0;
140023 +}
140024 +EXPORT_SYMBOL(qman_ceetm_channel_release);
140025 +
140026 +int qman_ceetm_channel_enable_shaper(struct qm_ceetm_channel *channel,
140027 + int coupled)
140028 +{
140029 + struct qm_mcc_ceetm_mapping_shaper_tcfc_query query_opts;
140030 + struct qm_mcr_ceetm_mapping_shaper_tcfc_query query_result;
140031 + struct qm_mcc_ceetm_mapping_shaper_tcfc_config config_opts;
140032 +
140033 + if (channel->shaper_enable == 1) {
140034 + pr_err("This channel shaper has been enabled!\n");
140035 + return -EINVAL;
140036 + }
140037 +
140038 + channel->shaper_enable = 1;
140039 + channel->shaper_couple = coupled;
140040 +
140041 + query_opts.cid = cpu_to_be16(CEETM_COMMAND_CHANNEL_MAPPING |
140042 + channel->idx);
140043 + query_opts.dcpid = channel->dcp_idx;
140044 +
140045 + if (qman_ceetm_query_mapping_shaper_tcfc(&query_opts, &query_result)) {
140046 + pr_err("Can't query channel mapping\n");
140047 + return -EINVAL;
140048 + }
140049 +
140050 + config_opts.cid = cpu_to_be16(CEETM_COMMAND_CHANNEL_MAPPING |
140051 + channel->idx);
140052 + config_opts.dcpid = channel->dcp_idx;
140053 + config_opts.channel_mapping.map_lni_id =
140054 + query_result.channel_mapping_query.map_lni_id;
140055 + config_opts.channel_mapping.map_shaped = 1;
140056 + if (qman_ceetm_configure_mapping_shaper_tcfc(&config_opts)) {
140057 + pr_err("Can't enable shaper for channel #%d\n", channel->idx);
140058 + return -EINVAL;
140059 + }
140060 +
140061 + config_opts.cid = cpu_to_be16(CEETM_COMMAND_CHANNEL_SHAPER |
140062 + channel->idx);
140063 + config_opts.shaper_config.cpl = coupled;
140064 + config_opts.shaper_config.crtcr =
140065 + cpu_to_be24((channel->cr_token_rate.whole
140066 + << 13) |
140067 + channel->cr_token_rate.fraction);
140068 + config_opts.shaper_config.ertcr =
140069 + cpu_to_be24(channel->er_token_rate.whole
140070 + << 13 |
140071 + channel->er_token_rate.fraction);
140072 + config_opts.shaper_config.crtbl =
140073 + cpu_to_be16(channel->cr_token_bucket_limit);
140074 + config_opts.shaper_config.ertbl =
140075 + cpu_to_be16(channel->er_token_bucket_limit);
140076 +
140077 + return qman_ceetm_configure_mapping_shaper_tcfc(&config_opts);
140078 +}
140079 +EXPORT_SYMBOL(qman_ceetm_channel_enable_shaper);
140080 +
140081 +int qman_ceetm_channel_disable_shaper(struct qm_ceetm_channel *channel)
140082 +{
140083 + struct qm_mcc_ceetm_mapping_shaper_tcfc_query query_opts;
140084 + struct qm_mcr_ceetm_mapping_shaper_tcfc_query query_result;
140085 + struct qm_mcc_ceetm_mapping_shaper_tcfc_config config_opts;
140086 +
140087 +
140088 + query_opts.cid = cpu_to_be16(CEETM_COMMAND_CHANNEL_MAPPING |
140089 + channel->idx);
140090 + query_opts.dcpid = channel->dcp_idx;
140091 +
140092 + if (qman_ceetm_query_mapping_shaper_tcfc(&query_opts, &query_result)) {
140093 + pr_err("Can't query channel mapping\n");
140094 + return -EINVAL;
140095 + }
140096 +
140097 + config_opts.cid = cpu_to_be16(CEETM_COMMAND_CHANNEL_MAPPING |
140098 + channel->idx);
140099 + config_opts.dcpid = channel->dcp_idx;
140100 + config_opts.channel_mapping.map_shaped = 0;
140101 + config_opts.channel_mapping.map_lni_id =
140102 + query_result.channel_mapping_query.map_lni_id;
140103 +
140104 + return qman_ceetm_configure_mapping_shaper_tcfc(&config_opts);
140105 +}
140106 +EXPORT_SYMBOL(qman_ceetm_channel_disable_shaper);
140107 +
140108 +int qman_ceetm_channel_is_shaper_enabled(struct qm_ceetm_channel *channel)
140109 +{
140110 + struct qm_mcc_ceetm_mapping_shaper_tcfc_query query_opts;
140111 + struct qm_mcr_ceetm_mapping_shaper_tcfc_query query_result;
140112 +
140113 + query_opts.cid = cpu_to_be16(CEETM_COMMAND_CHANNEL_MAPPING |
140114 + channel->idx);
140115 + query_opts.dcpid = channel->dcp_idx;
140116 +
140117 + if (qman_ceetm_query_mapping_shaper_tcfc(&query_opts, &query_result)) {
140118 + pr_err("Can't query channel mapping\n");
140119 + return -EINVAL;
140120 + }
140121 +
140122 + return query_result.channel_mapping_query.map_shaped;
140123 +}
140124 +EXPORT_SYMBOL(qman_ceetm_channel_is_shaper_enabled);
140125 +
140126 +int qman_ceetm_channel_set_commit_rate(struct qm_ceetm_channel *channel,
140127 + const struct qm_ceetm_rate *token_rate,
140128 + u16 token_limit)
140129 +{
140130 + struct qm_mcc_ceetm_mapping_shaper_tcfc_config config_opts;
140131 + struct qm_mcc_ceetm_mapping_shaper_tcfc_query query_opts;
140132 + struct qm_mcr_ceetm_mapping_shaper_tcfc_query query_result;
140133 + int ret;
140134 +
140135 + query_opts.cid = cpu_to_be16(CEETM_COMMAND_CHANNEL_SHAPER |
140136 + channel->idx);
140137 + query_opts.dcpid = channel->dcp_idx;
140138 +
140139 + ret = qman_ceetm_query_mapping_shaper_tcfc(&query_opts, &query_result);
140140 + if (ret) {
140141 + pr_err("Fail to get the current channel shaper setting\n");
140142 + return -EINVAL;
140143 + }
140144 +
140145 + channel->cr_token_rate.whole = token_rate->whole;
140146 + channel->cr_token_rate.fraction = token_rate->fraction;
140147 + channel->cr_token_bucket_limit = token_limit;
140148 + config_opts.cid = cpu_to_be16(CEETM_COMMAND_CHANNEL_SHAPER |
140149 + channel->idx);
140150 + config_opts.dcpid = channel->dcp_idx;
140151 + config_opts.shaper_config.crtcr = cpu_to_be24((token_rate->whole
140152 + << 13) | (token_rate->fraction));
140153 + config_opts.shaper_config.crtbl = cpu_to_be16(token_limit);
140154 + config_opts.shaper_config.cpl = query_result.shaper_query.cpl;
140155 + config_opts.shaper_config.ertcr = query_result.shaper_query.ertcr;
140156 + config_opts.shaper_config.ertbl = query_result.shaper_query.ertbl;
140157 + return qman_ceetm_configure_mapping_shaper_tcfc(&config_opts);
140158 +}
140159 +EXPORT_SYMBOL(qman_ceetm_channel_set_commit_rate);
140160 +
140161 +int qman_ceetm_channel_set_commit_rate_bps(struct qm_ceetm_channel *channel,
140162 + u64 bps, u16 token_limit)
140163 +{
140164 + struct qm_ceetm_rate token_rate;
140165 + int ret;
140166 +
140167 + ret = qman_ceetm_bps2tokenrate(bps, &token_rate, 0);
140168 + if (ret) {
140169 + pr_err("Can not convert bps to token rate\n");
140170 + return -EINVAL;
140171 + }
140172 + return qman_ceetm_channel_set_commit_rate(channel, &token_rate,
140173 + token_limit);
140174 +}
140175 +EXPORT_SYMBOL(qman_ceetm_channel_set_commit_rate_bps);
140176 +
140177 +int qman_ceetm_channel_get_commit_rate(struct qm_ceetm_channel *channel,
140178 + struct qm_ceetm_rate *token_rate,
140179 + u16 *token_limit)
140180 +{
140181 + struct qm_mcc_ceetm_mapping_shaper_tcfc_query query_opts;
140182 + struct qm_mcr_ceetm_mapping_shaper_tcfc_query query_result;
140183 + int ret;
140184 +
140185 + query_opts.cid = cpu_to_be16(CEETM_COMMAND_CHANNEL_SHAPER |
140186 + channel->idx);
140187 + query_opts.dcpid = channel->dcp_idx;
140188 +
140189 + ret = qman_ceetm_query_mapping_shaper_tcfc(&query_opts, &query_result);
140190 + if (ret | !query_result.shaper_query.crtcr |
140191 + !query_result.shaper_query.crtbl) {
140192 + pr_err("The channel commit rate or limit is not set\n");
140193 + return -EINVAL;
140194 + }
140195 + token_rate->whole = be24_to_cpu(query_result.shaper_query.crtcr) >> 13;
140196 + token_rate->fraction = be24_to_cpu(query_result.shaper_query.crtcr) &
140197 + 0x1FFF;
140198 + *token_limit = be16_to_cpu(query_result.shaper_query.crtbl);
140199 + return 0;
140200 +}
140201 +EXPORT_SYMBOL(qman_ceetm_channel_get_commit_rate);
140202 +
140203 +int qman_ceetm_channel_get_commit_rate_bps(struct qm_ceetm_channel *channel,
140204 + u64 *bps, u16 *token_limit)
140205 +{
140206 + struct qm_ceetm_rate token_rate;
140207 + int ret;
140208 +
140209 + ret = qman_ceetm_channel_get_commit_rate(channel, &token_rate,
140210 + token_limit);
140211 + if (ret) {
140212 + pr_err("The channel CR rate or limit is not available\n");
140213 + return -EINVAL;
140214 + }
140215 +
140216 + return qman_ceetm_tokenrate2bps(&token_rate, bps, 0);
140217 +}
140218 +EXPORT_SYMBOL(qman_ceetm_channel_get_commit_rate_bps);
140219 +
140220 +int qman_ceetm_channel_set_excess_rate(struct qm_ceetm_channel *channel,
140221 + const struct qm_ceetm_rate *token_rate,
140222 + u16 token_limit)
140223 +{
140224 + struct qm_mcc_ceetm_mapping_shaper_tcfc_config config_opts;
140225 + struct qm_mcc_ceetm_mapping_shaper_tcfc_query query_opts;
140226 + struct qm_mcr_ceetm_mapping_shaper_tcfc_query query_result;
140227 + int ret;
140228 +
140229 + query_opts.cid = cpu_to_be16(CEETM_COMMAND_CHANNEL_SHAPER |
140230 + channel->idx);
140231 + query_opts.dcpid = channel->dcp_idx;
140232 + ret = qman_ceetm_query_mapping_shaper_tcfc(&query_opts, &query_result);
140233 + if (ret) {
140234 + pr_err("Fail to get the current channel shaper setting\n");
140235 + return -EINVAL;
140236 + }
140237 +
140238 + channel->er_token_rate.whole = token_rate->whole;
140239 + channel->er_token_rate.fraction = token_rate->fraction;
140240 + channel->er_token_bucket_limit = token_limit;
140241 + config_opts.cid = cpu_to_be16(CEETM_COMMAND_CHANNEL_SHAPER |
140242 + channel->idx);
140243 + config_opts.dcpid = channel->dcp_idx;
140244 + config_opts.shaper_config.ertcr = cpu_to_be24(
140245 + (token_rate->whole << 13) | (token_rate->fraction));
140246 + config_opts.shaper_config.ertbl = cpu_to_be16(token_limit);
140247 + config_opts.shaper_config.cpl = query_result.shaper_query.cpl;
140248 + config_opts.shaper_config.crtcr = query_result.shaper_query.crtcr;
140249 + config_opts.shaper_config.crtbl = query_result.shaper_query.crtbl;
140250 + return qman_ceetm_configure_mapping_shaper_tcfc(&config_opts);
140251 +}
140252 +EXPORT_SYMBOL(qman_ceetm_channel_set_excess_rate);
140253 +
140254 +int qman_ceetm_channel_set_excess_rate_bps(struct qm_ceetm_channel *channel,
140255 + u64 bps, u16 token_limit)
140256 +{
140257 + struct qm_ceetm_rate token_rate;
140258 + int ret;
140259 +
140260 + ret = qman_ceetm_bps2tokenrate(bps, &token_rate, 0);
140261 + if (ret) {
140262 + pr_err("Can not convert bps to token rate\n");
140263 + return -EINVAL;
140264 + }
140265 + return qman_ceetm_channel_set_excess_rate(channel, &token_rate,
140266 + token_limit);
140267 +}
140268 +EXPORT_SYMBOL(qman_ceetm_channel_set_excess_rate_bps);
140269 +
140270 +int qman_ceetm_channel_get_excess_rate(struct qm_ceetm_channel *channel,
140271 + struct qm_ceetm_rate *token_rate,
140272 + u16 *token_limit)
140273 +{
140274 + struct qm_mcc_ceetm_mapping_shaper_tcfc_query query_opts;
140275 + struct qm_mcr_ceetm_mapping_shaper_tcfc_query query_result;
140276 + int ret;
140277 +
140278 + query_opts.cid = cpu_to_be16(CEETM_COMMAND_CHANNEL_SHAPER |
140279 + channel->idx);
140280 + query_opts.dcpid = channel->dcp_idx;
140281 + ret = qman_ceetm_query_mapping_shaper_tcfc(&query_opts, &query_result);
140282 + if (ret | !query_result.shaper_query.ertcr |
140283 + !query_result.shaper_query.ertbl) {
140284 + pr_err("The channel excess rate or limit is not set\n");
140285 + return -EINVAL;
140286 + }
140287 + token_rate->whole = be24_to_cpu(query_result.shaper_query.ertcr) >> 13;
140288 + token_rate->fraction = be24_to_cpu(query_result.shaper_query.ertcr) &
140289 + 0x1FFF;
140290 + *token_limit = be16_to_cpu(query_result.shaper_query.ertbl);
140291 + return 0;
140292 +}
140293 +EXPORT_SYMBOL(qman_ceetm_channel_get_excess_rate);
140294 +
140295 +int qman_ceetm_channel_get_excess_rate_bps(struct qm_ceetm_channel *channel,
140296 + u64 *bps, u16 *token_limit)
140297 +{
140298 + struct qm_ceetm_rate token_rate;
140299 + int ret;
140300 +
140301 + ret = qman_ceetm_channel_get_excess_rate(channel, &token_rate,
140302 + token_limit);
140303 + if (ret) {
140304 + pr_err("The channel ER rate or limit is not available\n");
140305 + return -EINVAL;
140306 + }
140307 +
140308 + return qman_ceetm_tokenrate2bps(&token_rate, bps, 0);
140309 +}
140310 +EXPORT_SYMBOL(qman_ceetm_channel_get_excess_rate_bps);
140311 +
140312 +int qman_ceetm_channel_set_weight(struct qm_ceetm_channel *channel,
140313 + u16 token_limit)
140314 +{
140315 + struct qm_mcc_ceetm_mapping_shaper_tcfc_config config_opts;
140316 +
140317 + if (channel->shaper_enable) {
140318 + pr_err("This channel is a shaped one\n");
140319 + return -EINVAL;
140320 + }
140321 +
140322 + channel->cr_token_bucket_limit = token_limit;
140323 + config_opts.cid = cpu_to_be16(CEETM_COMMAND_CHANNEL_SHAPER |
140324 + channel->idx);
140325 + config_opts.dcpid = channel->dcp_idx;
140326 + config_opts.shaper_config.crtbl = cpu_to_be16(token_limit);
140327 + return qman_ceetm_configure_mapping_shaper_tcfc(&config_opts);
140328 +}
140329 +EXPORT_SYMBOL(qman_ceetm_channel_set_weight);
140330 +
140331 +int qman_ceetm_channel_get_weight(struct qm_ceetm_channel *channel,
140332 + u16 *token_limit)
140333 +{
140334 + struct qm_mcc_ceetm_mapping_shaper_tcfc_query query_opts;
140335 + struct qm_mcr_ceetm_mapping_shaper_tcfc_query query_result;
140336 + int ret;
140337 +
140338 + query_opts.cid = cpu_to_be16(CEETM_COMMAND_CHANNEL_SHAPER |
140339 + channel->idx);
140340 + query_opts.dcpid = channel->dcp_idx;
140341 + ret = qman_ceetm_query_mapping_shaper_tcfc(&query_opts, &query_result);
140342 + if (ret | !query_result.shaper_query.crtbl) {
140343 + pr_err("This unshaped channel's uFQ wight is unavailable\n");
140344 + return -EINVAL;
140345 + }
140346 + *token_limit = be16_to_cpu(query_result.shaper_query.crtbl);
140347 + return 0;
140348 +}
140349 +EXPORT_SYMBOL(qman_ceetm_channel_get_weight);
140350 +
140351 +int qman_ceetm_channel_set_group(struct qm_ceetm_channel *channel, int group_b,
140352 + unsigned int prio_a, unsigned int prio_b)
140353 +{
140354 + struct qm_mcc_ceetm_class_scheduler_config config_opts;
140355 + struct qm_mcr_ceetm_class_scheduler_query query_result;
140356 + int i;
140357 +
140358 + if (prio_a > 7) {
140359 + pr_err("The priority of group A is out of range\n");
140360 + return -EINVAL;
140361 + }
140362 + if (group_b && (prio_b > 7)) {
140363 + pr_err("The priority of group B is out of range\n");
140364 + return -EINVAL;
140365 + }
140366 +
140367 + if (qman_ceetm_query_class_scheduler(channel, &query_result)) {
140368 + pr_err("Can't query channel#%d's scheduler!\n", channel->idx);
140369 + return -EINVAL;
140370 + }
140371 +
140372 + config_opts.cqcid = cpu_to_be16(channel->idx);
140373 + config_opts.dcpid = channel->dcp_idx;
140374 + config_opts.gpc_combine_flag = !group_b;
140375 + config_opts.gpc_prio_a = prio_a;
140376 + config_opts.gpc_prio_b = prio_b;
140377 +
140378 + for (i = 0; i < 8; i++)
140379 + config_opts.w[i] = query_result.w[i];
140380 + config_opts.crem = query_result.crem;
140381 + config_opts.erem = query_result.erem;
140382 +
140383 + return qman_ceetm_configure_class_scheduler(&config_opts);
140384 +}
140385 +EXPORT_SYMBOL(qman_ceetm_channel_set_group);
140386 +
140387 +int qman_ceetm_channel_get_group(struct qm_ceetm_channel *channel, int *group_b,
140388 + unsigned int *prio_a, unsigned int *prio_b)
140389 +{
140390 + struct qm_mcr_ceetm_class_scheduler_query query_result;
140391 +
140392 + if (qman_ceetm_query_class_scheduler(channel, &query_result)) {
140393 + pr_err("Can't query channel#%d's scheduler!\n", channel->idx);
140394 + return -EINVAL;
140395 + }
140396 + *group_b = !query_result.gpc_combine_flag;
140397 + *prio_a = query_result.gpc_prio_a;
140398 + *prio_b = query_result.gpc_prio_b;
140399 +
140400 + return 0;
140401 +}
140402 +EXPORT_SYMBOL(qman_ceetm_channel_get_group);
140403 +
140404 +#define GROUP_A_ELIGIBILITY_SET (1 << 8)
140405 +#define GROUP_B_ELIGIBILITY_SET (1 << 9)
140406 +#define CQ_ELIGIBILITY_SET(n) (1 << (7 - n))
140407 +int qman_ceetm_channel_set_group_cr_eligibility(struct qm_ceetm_channel
140408 + *channel, int group_b, int cre)
140409 +{
140410 + struct qm_mcc_ceetm_class_scheduler_config csch_config;
140411 + struct qm_mcr_ceetm_class_scheduler_query csch_query;
140412 + int i;
140413 +
140414 + if (qman_ceetm_query_class_scheduler(channel, &csch_query)) {
140415 + pr_err("Cannot get the channel %d scheduler setting.\n",
140416 + channel->idx);
140417 + return -EINVAL;
140418 + }
140419 + csch_config.cqcid = cpu_to_be16(channel->idx);
140420 + csch_config.dcpid = channel->dcp_idx;
140421 + csch_config.gpc_combine_flag = csch_query.gpc_combine_flag;
140422 + csch_config.gpc_prio_a = csch_query.gpc_prio_a;
140423 + csch_config.gpc_prio_b = csch_query.gpc_prio_b;
140424 +
140425 + for (i = 0; i < 8; i++)
140426 + csch_config.w[i] = csch_query.w[i];
140427 + csch_config.erem = csch_query.erem;
140428 + if (group_b)
140429 + csch_config.crem = (be16_to_cpu(csch_query.crem)
140430 + & ~GROUP_B_ELIGIBILITY_SET)
140431 + | (cre ? GROUP_B_ELIGIBILITY_SET : 0);
140432 + else
140433 + csch_config.crem = (be16_to_cpu(csch_query.crem)
140434 + & ~GROUP_A_ELIGIBILITY_SET)
140435 + | (cre ? GROUP_A_ELIGIBILITY_SET : 0);
140436 +
140437 + csch_config.crem = cpu_to_be16(csch_config.crem);
140438 +
140439 + if (qman_ceetm_configure_class_scheduler(&csch_config)) {
140440 + pr_err("Cannot config channel %d's scheduler with "
140441 + "group_%c's cr eligibility\n", channel->idx,
140442 + group_b ? 'b' : 'a');
140443 + return -EINVAL;
140444 + }
140445 +
140446 + return 0;
140447 +}
140448 +EXPORT_SYMBOL(qman_ceetm_channel_set_group_cr_eligibility);
140449 +
140450 +int qman_ceetm_channel_set_group_er_eligibility(struct qm_ceetm_channel
140451 + *channel, int group_b, int ere)
140452 +{
140453 + struct qm_mcc_ceetm_class_scheduler_config csch_config;
140454 + struct qm_mcr_ceetm_class_scheduler_query csch_query;
140455 + int i;
140456 +
140457 + if (qman_ceetm_query_class_scheduler(channel, &csch_query)) {
140458 + pr_err("Cannot get the channel %d scheduler setting.\n",
140459 + channel->idx);
140460 + return -EINVAL;
140461 + }
140462 + csch_config.cqcid = cpu_to_be16(channel->idx);
140463 + csch_config.dcpid = channel->dcp_idx;
140464 + csch_config.gpc_combine_flag = csch_query.gpc_combine_flag;
140465 + csch_config.gpc_prio_a = csch_query.gpc_prio_a;
140466 + csch_config.gpc_prio_b = csch_query.gpc_prio_b;
140467 +
140468 + for (i = 0; i < 8; i++)
140469 + csch_config.w[i] = csch_query.w[i];
140470 + csch_config.crem = csch_query.crem;
140471 + if (group_b)
140472 + csch_config.erem = (be16_to_cpu(csch_query.erem)
140473 + & ~GROUP_B_ELIGIBILITY_SET)
140474 + | (ere ? GROUP_B_ELIGIBILITY_SET : 0);
140475 + else
140476 + csch_config.erem = (be16_to_cpu(csch_query.erem)
140477 + & ~GROUP_A_ELIGIBILITY_SET)
140478 + | (ere ? GROUP_A_ELIGIBILITY_SET : 0);
140479 +
140480 + csch_config.erem = cpu_to_be16(csch_config.erem);
140481 +
140482 + if (qman_ceetm_configure_class_scheduler(&csch_config)) {
140483 + pr_err("Cannot config channel %d's scheduler with "
140484 + "group_%c's er eligibility\n", channel->idx,
140485 + group_b ? 'b' : 'a');
140486 + return -EINVAL;
140487 + }
140488 +
140489 + return 0;
140490 +}
140491 +EXPORT_SYMBOL(qman_ceetm_channel_set_group_er_eligibility);
140492 +
140493 +int qman_ceetm_channel_set_cq_cr_eligibility(struct qm_ceetm_channel *channel,
140494 + unsigned int idx, int cre)
140495 +{
140496 + struct qm_mcc_ceetm_class_scheduler_config csch_config;
140497 + struct qm_mcr_ceetm_class_scheduler_query csch_query;
140498 + int i;
140499 +
140500 + if (idx > 7) {
140501 + pr_err("CQ index is out of range\n");
140502 + return -EINVAL;
140503 + }
140504 + if (qman_ceetm_query_class_scheduler(channel, &csch_query)) {
140505 + pr_err("Cannot get the channel %d scheduler setting.\n",
140506 + channel->idx);
140507 + return -EINVAL;
140508 + }
140509 + csch_config.cqcid = cpu_to_be16(channel->idx);
140510 + csch_config.dcpid = channel->dcp_idx;
140511 + csch_config.gpc_combine_flag = csch_query.gpc_combine_flag;
140512 + csch_config.gpc_prio_a = csch_query.gpc_prio_a;
140513 + csch_config.gpc_prio_b = csch_query.gpc_prio_b;
140514 + for (i = 0; i < 8; i++)
140515 + csch_config.w[i] = csch_query.w[i];
140516 + csch_config.erem = csch_query.erem;
140517 + csch_config.crem = (be16_to_cpu(csch_query.crem)
140518 + & ~CQ_ELIGIBILITY_SET(idx)) |
140519 + (cre ? CQ_ELIGIBILITY_SET(idx) : 0);
140520 + csch_config.crem = cpu_to_be16(csch_config.crem);
140521 + if (qman_ceetm_configure_class_scheduler(&csch_config)) {
140522 + pr_err("Cannot config channel scheduler to set "
140523 + "cr eligibility mask for CQ#%d\n", idx);
140524 + return -EINVAL;
140525 + }
140526 +
140527 + return 0;
140528 +}
140529 +EXPORT_SYMBOL(qman_ceetm_channel_set_cq_cr_eligibility);
140530 +
140531 +int qman_ceetm_channel_set_cq_er_eligibility(struct qm_ceetm_channel *channel,
140532 + unsigned int idx, int ere)
140533 +{
140534 + struct qm_mcc_ceetm_class_scheduler_config csch_config;
140535 + struct qm_mcr_ceetm_class_scheduler_query csch_query;
140536 + int i;
140537 +
140538 + if (idx > 7) {
140539 + pr_err("CQ index is out of range\n");
140540 + return -EINVAL;
140541 + }
140542 + if (qman_ceetm_query_class_scheduler(channel, &csch_query)) {
140543 + pr_err("Cannot get the channel %d scheduler setting.\n",
140544 + channel->idx);
140545 + return -EINVAL;
140546 + }
140547 + csch_config.cqcid = cpu_to_be16(channel->idx);
140548 + csch_config.dcpid = channel->dcp_idx;
140549 + csch_config.gpc_combine_flag = csch_query.gpc_combine_flag;
140550 + csch_config.gpc_prio_a = csch_query.gpc_prio_a;
140551 + csch_config.gpc_prio_b = csch_query.gpc_prio_b;
140552 + for (i = 0; i < 8; i++)
140553 + csch_config.w[i] = csch_query.w[i];
140554 + csch_config.crem = csch_query.crem;
140555 + csch_config.erem = (be16_to_cpu(csch_query.erem)
140556 + & ~CQ_ELIGIBILITY_SET(idx)) |
140557 + (ere ? CQ_ELIGIBILITY_SET(idx) : 0);
140558 + csch_config.erem = cpu_to_be16(csch_config.erem);
140559 + if (qman_ceetm_configure_class_scheduler(&csch_config)) {
140560 + pr_err("Cannot config channel scheduler to set "
140561 + "er eligibility mask for CQ#%d\n", idx);
140562 + return -EINVAL;
140563 + }
140564 + return 0;
140565 +}
140566 +EXPORT_SYMBOL(qman_ceetm_channel_set_cq_er_eligibility);
140567 +
140568 +int qman_ceetm_cq_claim(struct qm_ceetm_cq **cq,
140569 + struct qm_ceetm_channel *channel, unsigned int idx,
140570 + struct qm_ceetm_ccg *ccg)
140571 +{
140572 + struct qm_ceetm_cq *p;
140573 + struct qm_mcc_ceetm_cq_config cq_config;
140574 +
140575 + if (idx > 7) {
140576 + pr_err("The independent class queue id is out of range\n");
140577 + return -EINVAL;
140578 + }
140579 +
140580 + list_for_each_entry(p, &channel->class_queues, node) {
140581 + if (p->idx == idx) {
140582 + pr_err("The CQ#%d has been claimed!\n", idx);
140583 + return -EINVAL;
140584 + }
140585 + }
140586 +
140587 + p = kmalloc(sizeof(*p), GFP_KERNEL);
140588 + if (!p) {
140589 + pr_err("Can't allocate memory for CQ#%d!\n", idx);
140590 + return -ENOMEM;
140591 + }
140592 +
140593 + list_add_tail(&p->node, &channel->class_queues);
140594 + p->idx = idx;
140595 + p->is_claimed = 1;
140596 + p->parent = channel;
140597 + INIT_LIST_HEAD(&p->bound_lfqids);
140598 +
140599 + if (ccg) {
140600 + cq_config.cqid = cpu_to_be16((channel->idx << 4) | idx);
140601 + cq_config.dcpid = channel->dcp_idx;
140602 + cq_config.ccgid = cpu_to_be16(ccg->idx);
140603 + if (qman_ceetm_configure_cq(&cq_config)) {
140604 + pr_err("Can't configure the CQ#%d with CCGRID#%d\n",
140605 + idx, ccg->idx);
140606 + list_del(&p->node);
140607 + kfree(p);
140608 + return -EINVAL;
140609 + }
140610 + }
140611 +
140612 + *cq = p;
140613 + return 0;
140614 +}
140615 +EXPORT_SYMBOL(qman_ceetm_cq_claim);
140616 +
140617 +int qman_ceetm_cq_claim_A(struct qm_ceetm_cq **cq,
140618 + struct qm_ceetm_channel *channel, unsigned int idx,
140619 + struct qm_ceetm_ccg *ccg)
140620 +{
140621 + struct qm_ceetm_cq *p;
140622 + struct qm_mcc_ceetm_cq_config cq_config;
140623 +
140624 + if ((idx < 8) || (idx > 15)) {
140625 + pr_err("This grouped class queue id is out of range\n");
140626 + return -EINVAL;
140627 + }
140628 +
140629 + list_for_each_entry(p, &channel->class_queues, node) {
140630 + if (p->idx == idx) {
140631 + pr_err("The CQ#%d has been claimed!\n", idx);
140632 + return -EINVAL;
140633 + }
140634 + }
140635 +
140636 + p = kmalloc(sizeof(*p), GFP_KERNEL);
140637 + if (!p) {
140638 + pr_err("Can't allocate memory for CQ#%d!\n", idx);
140639 + return -ENOMEM;
140640 + }
140641 +
140642 + list_add_tail(&p->node, &channel->class_queues);
140643 + p->idx = idx;
140644 + p->is_claimed = 1;
140645 + p->parent = channel;
140646 + INIT_LIST_HEAD(&p->bound_lfqids);
140647 +
140648 + if (ccg) {
140649 + cq_config.cqid = cpu_to_be16((channel->idx << 4) | idx);
140650 + cq_config.dcpid = channel->dcp_idx;
140651 + cq_config.ccgid = cpu_to_be16(ccg->idx);
140652 + if (qman_ceetm_configure_cq(&cq_config)) {
140653 + pr_err("Can't configure the CQ#%d with CCGRID#%d\n",
140654 + idx, ccg->idx);
140655 + list_del(&p->node);
140656 + kfree(p);
140657 + return -EINVAL;
140658 + }
140659 + }
140660 + *cq = p;
140661 + return 0;
140662 +}
140663 +EXPORT_SYMBOL(qman_ceetm_cq_claim_A);
140664 +
140665 +int qman_ceetm_cq_claim_B(struct qm_ceetm_cq **cq,
140666 + struct qm_ceetm_channel *channel, unsigned int idx,
140667 + struct qm_ceetm_ccg *ccg)
140668 +{
140669 + struct qm_ceetm_cq *p;
140670 + struct qm_mcc_ceetm_cq_config cq_config;
140671 +
140672 + if ((idx < 12) || (idx > 15)) {
140673 + pr_err("This grouped class queue id is out of range\n");
140674 + return -EINVAL;
140675 + }
140676 +
140677 + list_for_each_entry(p, &channel->class_queues, node) {
140678 + if (p->idx == idx) {
140679 + pr_err("The CQ#%d has been claimed!\n", idx);
140680 + return -EINVAL;
140681 + }
140682 + }
140683 +
140684 + p = kmalloc(sizeof(*p), GFP_KERNEL);
140685 + if (!p) {
140686 + pr_err("Can't allocate memory for CQ#%d!\n", idx);
140687 + return -ENOMEM;
140688 + }
140689 +
140690 + list_add_tail(&p->node, &channel->class_queues);
140691 + p->idx = idx;
140692 + p->is_claimed = 1;
140693 + p->parent = channel;
140694 + INIT_LIST_HEAD(&p->bound_lfqids);
140695 +
140696 + if (ccg) {
140697 + cq_config.cqid = cpu_to_be16((channel->idx << 4) | idx);
140698 + cq_config.dcpid = channel->dcp_idx;
140699 + cq_config.ccgid = cpu_to_be16(ccg->idx);
140700 + if (qman_ceetm_configure_cq(&cq_config)) {
140701 + pr_err("Can't configure the CQ#%d with CCGRID#%d\n",
140702 + idx, ccg->idx);
140703 + list_del(&p->node);
140704 + kfree(p);
140705 + return -EINVAL;
140706 + }
140707 + }
140708 + *cq = p;
140709 + return 0;
140710 +}
140711 +EXPORT_SYMBOL(qman_ceetm_cq_claim_B);
140712 +
140713 +int qman_ceetm_cq_release(struct qm_ceetm_cq *cq)
140714 +{
140715 + if (!list_empty(&cq->bound_lfqids)) {
140716 + pr_err("The CQ#%d has unreleased LFQID\n", cq->idx);
140717 + return -EBUSY;
140718 + }
140719 + list_del(&cq->node);
140720 + qman_ceetm_drain_cq(cq);
140721 + kfree(cq);
140722 + return 0;
140723 +}
140724 +EXPORT_SYMBOL(qman_ceetm_cq_release);
140725 +
140726 +int qman_ceetm_set_queue_weight(struct qm_ceetm_cq *cq,
140727 + struct qm_ceetm_weight_code *weight_code)
140728 +{
140729 + struct qm_mcc_ceetm_class_scheduler_config config_opts;
140730 + struct qm_mcr_ceetm_class_scheduler_query query_result;
140731 + int i;
140732 +
140733 + if (cq->idx < 8) {
140734 + pr_err("Can not set weight for ungrouped class queue\n");
140735 + return -EINVAL;
140736 + }
140737 +
140738 + if (qman_ceetm_query_class_scheduler(cq->parent, &query_result)) {
140739 + pr_err("Can't query channel#%d's scheduler!\n",
140740 + cq->parent->idx);
140741 + return -EINVAL;
140742 + }
140743 +
140744 + config_opts.cqcid = cpu_to_be16(cq->parent->idx);
140745 + config_opts.dcpid = cq->parent->dcp_idx;
140746 + config_opts.crem = query_result.crem;
140747 + config_opts.erem = query_result.erem;
140748 + config_opts.gpc_combine_flag = query_result.gpc_combine_flag;
140749 + config_opts.gpc_prio_a = query_result.gpc_prio_a;
140750 + config_opts.gpc_prio_b = query_result.gpc_prio_b;
140751 +
140752 + for (i = 0; i < 8; i++)
140753 + config_opts.w[i] = query_result.w[i];
140754 + config_opts.w[cq->idx - 8] = ((weight_code->y << 3) |
140755 + (weight_code->x & 0x7));
140756 + return qman_ceetm_configure_class_scheduler(&config_opts);
140757 +}
140758 +EXPORT_SYMBOL(qman_ceetm_set_queue_weight);
140759 +
140760 +int qman_ceetm_get_queue_weight(struct qm_ceetm_cq *cq,
140761 + struct qm_ceetm_weight_code *weight_code)
140762 +{
140763 + struct qm_mcr_ceetm_class_scheduler_query query_result;
140764 +
140765 + if (cq->idx < 8) {
140766 + pr_err("Can not get weight for ungrouped class queue\n");
140767 + return -EINVAL;
140768 + }
140769 +
140770 + if (qman_ceetm_query_class_scheduler(cq->parent,
140771 + &query_result)) {
140772 + pr_err("Can't get the weight code for CQ#%d!\n", cq->idx);
140773 + return -EINVAL;
140774 + }
140775 + weight_code->y = query_result.w[cq->idx - 8] >> 3;
140776 + weight_code->x = query_result.w[cq->idx - 8] & 0x7;
140777 +
140778 + return 0;
140779 +}
140780 +EXPORT_SYMBOL(qman_ceetm_get_queue_weight);
140781 +
140782 +/* The WBFS code is represent as {x,y}, the effect wieght can be calculated as:
140783 + * effective weight = 2^x / (1 - (y/64))
140784 + * = 2^(x+6) / (64 - y)
140785 + */
140786 +static void reduce_fraction(u32 *n, u32 *d)
140787 +{
140788 + u32 factor = 2;
140789 + u32 lesser = (*n < *d) ? *n : *d;
140790 + /* If factor exceeds the square-root of the lesser of *n and *d,
140791 + * then there's no point continuing. Proof: if there was a factor
140792 + * bigger than the square root, that would imply there exists
140793 + * another factor smaller than the square-root with which it
140794 + * multiplies to give 'lesser' - but that's a contradiction
140795 + * because the other factor would have already been found and
140796 + * divided out.
140797 + */
140798 + while ((factor * factor) <= lesser) {
140799 + /* If 'factor' is a factor of *n and *d, divide them both
140800 + * by 'factor' as many times as possible.
140801 + */
140802 + while (!(*n % factor) && !(*d % factor)) {
140803 + *n /= factor;
140804 + *d /= factor;
140805 + lesser /= factor;
140806 + }
140807 + if (factor == 2)
140808 + factor = 3;
140809 + else
140810 + factor += 2;
140811 + }
140812 +}
140813 +
140814 +int qman_ceetm_wbfs2ratio(struct qm_ceetm_weight_code *weight_code,
140815 + u32 *numerator,
140816 + u32 *denominator)
140817 +{
140818 + *numerator = (u32) 1 << (weight_code->x + 6);
140819 + *denominator = 64 - weight_code->y;
140820 + reduce_fraction(numerator, denominator);
140821 + return 0;
140822 +}
140823 +EXPORT_SYMBOL(qman_ceetm_wbfs2ratio);
140824 +
140825 +/* For a given x, the weight is between 2^x (inclusive) and 2^(x+1) (exclusive).
140826 + * So find 'x' by range, and then estimate 'y' using:
140827 + * 64 - y = 2^(x + 6) / weight
140828 + * = 2^(x + 6) / (n/d)
140829 + * = d * 2^(x+6) / n
140830 + * y = 64 - (d * 2^(x+6) / n)
140831 + */
140832 +int qman_ceetm_ratio2wbfs(u32 numerator,
140833 + u32 denominator,
140834 + struct qm_ceetm_weight_code *weight_code,
140835 + int rounding)
140836 +{
140837 + unsigned int y, x = 0;
140838 + /* search incrementing 'x' until:
140839 + * weight < 2^(x+1)
140840 + * n/d < 2^(x+1)
140841 + * n < d * 2^(x+1)
140842 + */
140843 + while ((x < 8) && (numerator >= (denominator << (x + 1))))
140844 + x++;
140845 + if (x >= 8)
140846 + return -ERANGE;
140847 + /* because of the subtraction, use '-rounding' */
140848 + y = 64 - ROUNDING(denominator << (x + 6), numerator, -rounding);
140849 + if (y >= 32)
140850 + return -ERANGE;
140851 + weight_code->x = x;
140852 + weight_code->y = y;
140853 + return 0;
140854 +}
140855 +EXPORT_SYMBOL(qman_ceetm_ratio2wbfs);
140856 +
140857 +int qman_ceetm_set_queue_weight_in_ratio(struct qm_ceetm_cq *cq, u32 ratio)
140858 +{
140859 + struct qm_ceetm_weight_code weight_code;
140860 +
140861 + if (qman_ceetm_ratio2wbfs(ratio, 100, &weight_code, 0)) {
140862 + pr_err("Cannot get wbfs code for cq %x\n", cq->idx);
140863 + return -EINVAL;
140864 + }
140865 + return qman_ceetm_set_queue_weight(cq, &weight_code);
140866 +}
140867 +EXPORT_SYMBOL(qman_ceetm_set_queue_weight_in_ratio);
140868 +
140869 +int qman_ceetm_get_queue_weight_in_ratio(struct qm_ceetm_cq *cq, u32 *ratio)
140870 +{
140871 + struct qm_ceetm_weight_code weight_code;
140872 + u32 n, d;
140873 +
140874 + if (qman_ceetm_get_queue_weight(cq, &weight_code)) {
140875 + pr_err("Cannot query the weight code for cq%x\n", cq->idx);
140876 + return -EINVAL;
140877 + }
140878 +
140879 + if (qman_ceetm_wbfs2ratio(&weight_code, &n, &d)) {
140880 + pr_err("Cannot get the ratio with wbfs code\n");
140881 + return -EINVAL;
140882 + }
140883 +
140884 + *ratio = (n * 100) / d;
140885 + return 0;
140886 +}
140887 +EXPORT_SYMBOL(qman_ceetm_get_queue_weight_in_ratio);
140888 +
140889 +int qman_ceetm_cq_get_dequeue_statistics(struct qm_ceetm_cq *cq, u32 flags,
140890 + u64 *frame_count, u64 *byte_count)
140891 +{
140892 + struct qm_mcr_ceetm_statistics_query result;
140893 + u16 cid, command_type;
140894 + enum qm_dc_portal dcp_idx;
140895 + int ret;
140896 +
140897 + cid = cpu_to_be16((cq->parent->idx << 4) | cq->idx);
140898 + dcp_idx = cq->parent->dcp_idx;
140899 + if (flags == QMAN_CEETM_FLAG_CLEAR_STATISTICS_COUNTER)
140900 + command_type = CEETM_QUERY_DEQUEUE_CLEAR_STATISTICS;
140901 + else
140902 + command_type = CEETM_QUERY_DEQUEUE_STATISTICS;
140903 +
140904 + ret = qman_ceetm_query_statistics(cid, dcp_idx, command_type, &result);
140905 + if (ret) {
140906 + pr_err("Can't query the statistics of CQ#%d!\n", cq->idx);
140907 + return -EINVAL;
140908 + }
140909 +
140910 + *frame_count = be40_to_cpu(result.frm_cnt);
140911 + *byte_count = be48_to_cpu(result.byte_cnt);
140912 + return 0;
140913 +}
140914 +EXPORT_SYMBOL(qman_ceetm_cq_get_dequeue_statistics);
140915 +
140916 +int qman_ceetm_drain_cq(struct qm_ceetm_cq *cq)
140917 +{
140918 + struct qm_mcr_ceetm_cq_peek_pop_xsfdrread ppxr;
140919 + int ret;
140920 +
140921 + do {
140922 + ret = qman_ceetm_cq_peek_pop_xsfdrread(cq, 1, 0, &ppxr);
140923 + if (ret) {
140924 + pr_err("Failed to pop frame from CQ\n");
140925 + return -EINVAL;
140926 + }
140927 + } while (!(ppxr.stat & 0x2));
140928 +
140929 + return 0;
140930 +}
140931 +EXPORT_SYMBOL(qman_ceetm_drain_cq);
140932 +
140933 +#define CEETM_LFQMT_LFQID_MSB 0xF00000
140934 +#define CEETM_LFQMT_LFQID_LSB 0x000FFF
140935 +int qman_ceetm_lfq_claim(struct qm_ceetm_lfq **lfq,
140936 + struct qm_ceetm_cq *cq)
140937 +{
140938 + struct qm_ceetm_lfq *p;
140939 + u32 lfqid;
140940 + int ret = 0;
140941 + struct qm_mcc_ceetm_lfqmt_config lfqmt_config;
140942 +
140943 + if (cq->parent->dcp_idx == qm_dc_portal_fman0) {
140944 + ret = qman_alloc_ceetm0_lfqid(&lfqid);
140945 + } else if (cq->parent->dcp_idx == qm_dc_portal_fman1) {
140946 + ret = qman_alloc_ceetm1_lfqid(&lfqid);
140947 + } else {
140948 + pr_err("dcp_idx %u does not correspond to a known fman in this driver\n",
140949 + cq->parent->dcp_idx);
140950 + return -EINVAL;
140951 + }
140952 +
140953 + if (ret) {
140954 + pr_err("There is no lfqid avalaible for CQ#%d!\n", cq->idx);
140955 + return -ENODEV;
140956 + }
140957 + p = kmalloc(sizeof(*p), GFP_KERNEL);
140958 + if (!p)
140959 + return -ENOMEM;
140960 + p->idx = lfqid;
140961 + p->dctidx = (u16)(lfqid & CEETM_LFQMT_LFQID_LSB);
140962 + p->parent = cq->parent;
140963 + list_add_tail(&p->node, &cq->bound_lfqids);
140964 +
140965 + lfqmt_config.lfqid = cpu_to_be24(CEETM_LFQMT_LFQID_MSB |
140966 + (cq->parent->dcp_idx << 16) |
140967 + (lfqid & CEETM_LFQMT_LFQID_LSB));
140968 + lfqmt_config.cqid = cpu_to_be16((cq->parent->idx << 4) | (cq->idx));
140969 + lfqmt_config.dctidx = cpu_to_be16(p->dctidx);
140970 + if (qman_ceetm_configure_lfqmt(&lfqmt_config)) {
140971 + pr_err("Can't configure LFQMT for LFQID#%d @ CQ#%d\n",
140972 + lfqid, cq->idx);
140973 + list_del(&p->node);
140974 + kfree(p);
140975 + return -EINVAL;
140976 + }
140977 + *lfq = p;
140978 + return 0;
140979 +}
140980 +EXPORT_SYMBOL(qman_ceetm_lfq_claim);
140981 +
140982 +int qman_ceetm_lfq_release(struct qm_ceetm_lfq *lfq)
140983 +{
140984 + if (lfq->parent->dcp_idx == qm_dc_portal_fman0) {
140985 + qman_release_ceetm0_lfqid(lfq->idx);
140986 + } else if (lfq->parent->dcp_idx == qm_dc_portal_fman1) {
140987 + qman_release_ceetm1_lfqid(lfq->idx);
140988 + } else {
140989 + pr_err("dcp_idx %u does not correspond to a known fman in this driver\n",
140990 + lfq->parent->dcp_idx);
140991 + return -EINVAL;
140992 + }
140993 + list_del(&lfq->node);
140994 + kfree(lfq);
140995 + return 0;
140996 +}
140997 +EXPORT_SYMBOL(qman_ceetm_lfq_release);
140998 +
140999 +int qman_ceetm_lfq_set_context(struct qm_ceetm_lfq *lfq, u64 context_a,
141000 + u32 context_b)
141001 +{
141002 + struct qm_mcc_ceetm_dct_config dct_config;
141003 + lfq->context_a = context_a;
141004 + lfq->context_b = context_b;
141005 + dct_config.dctidx = cpu_to_be16((u16)lfq->dctidx);
141006 + dct_config.dcpid = lfq->parent->dcp_idx;
141007 + dct_config.context_b = cpu_to_be32(context_b);
141008 + dct_config.context_a = cpu_to_be64(context_a);
141009 +
141010 + return qman_ceetm_configure_dct(&dct_config);
141011 +}
141012 +EXPORT_SYMBOL(qman_ceetm_lfq_set_context);
141013 +
141014 +int qman_ceetm_lfq_get_context(struct qm_ceetm_lfq *lfq, u64 *context_a,
141015 + u32 *context_b)
141016 +{
141017 + struct qm_mcc_ceetm_dct_query dct_query;
141018 + struct qm_mcr_ceetm_dct_query query_result;
141019 +
141020 + dct_query.dctidx = cpu_to_be16(lfq->dctidx);
141021 + dct_query.dcpid = lfq->parent->dcp_idx;
141022 + if (qman_ceetm_query_dct(&dct_query, &query_result)) {
141023 + pr_err("Can't query LFQID#%d's context!\n", lfq->idx);
141024 + return -EINVAL;
141025 + }
141026 + *context_a = be64_to_cpu(query_result.context_a);
141027 + *context_b = be32_to_cpu(query_result.context_b);
141028 + return 0;
141029 +}
141030 +EXPORT_SYMBOL(qman_ceetm_lfq_get_context);
141031 +
141032 +int qman_ceetm_create_fq(struct qm_ceetm_lfq *lfq, struct qman_fq *fq)
141033 +{
141034 + spin_lock_init(&fq->fqlock);
141035 + fq->fqid = lfq->idx;
141036 + fq->flags = QMAN_FQ_FLAG_NO_MODIFY;
141037 + if (lfq->ern)
141038 + fq->cb.ern = lfq->ern;
141039 +#ifdef CONFIG_FSL_QMAN_FQ_LOOKUP
141040 + if (unlikely(find_empty_fq_table_entry(&fq->key, fq)))
141041 + return -ENOMEM;
141042 +#endif
141043 + return 0;
141044 +}
141045 +EXPORT_SYMBOL(qman_ceetm_create_fq);
141046 +
141047 +#define MAX_CCG_IDX 0x000F
141048 +int qman_ceetm_ccg_claim(struct qm_ceetm_ccg **ccg,
141049 + struct qm_ceetm_channel *channel,
141050 + unsigned int idx,
141051 + void (*cscn)(struct qm_ceetm_ccg *,
141052 + void *cb_ctx,
141053 + int congested),
141054 + void *cb_ctx)
141055 +{
141056 + struct qm_ceetm_ccg *p;
141057 +
141058 + if (idx > MAX_CCG_IDX) {
141059 + pr_err("The given ccg index is out of range\n");
141060 + return -EINVAL;
141061 + }
141062 +
141063 + list_for_each_entry(p, &channel->ccgs, node) {
141064 + if (p->idx == idx) {
141065 + pr_err("The CCG#%d has been claimed\n", idx);
141066 + return -EINVAL;
141067 + }
141068 + }
141069 +
141070 + p = kmalloc(sizeof(*p), GFP_KERNEL);
141071 + if (!p) {
141072 + pr_err("Can't allocate memory for CCG#%d!\n", idx);
141073 + return -ENOMEM;
141074 + }
141075 +
141076 + list_add_tail(&p->node, &channel->ccgs);
141077 +
141078 + p->idx = idx;
141079 + p->parent = channel;
141080 + p->cb = cscn;
141081 + p->cb_ctx = cb_ctx;
141082 + INIT_LIST_HEAD(&p->cb_node);
141083 +
141084 + *ccg = p;
141085 + return 0;
141086 +}
141087 +EXPORT_SYMBOL(qman_ceetm_ccg_claim);
141088 +
141089 +int qman_ceetm_ccg_release(struct qm_ceetm_ccg *ccg)
141090 +{
141091 + unsigned long irqflags __maybe_unused;
141092 + struct qm_mcc_ceetm_ccgr_config config_opts;
141093 + int ret = 0;
141094 + struct qman_portal *p = get_affine_portal();
141095 +
141096 + memset(&config_opts, 0, sizeof(struct qm_mcc_ceetm_ccgr_config));
141097 + spin_lock_irqsave(&p->ccgr_lock, irqflags);
141098 + if (!list_empty(&ccg->cb_node))
141099 + list_del(&ccg->cb_node);
141100 + config_opts.ccgrid = cpu_to_be16(CEETM_CCGR_CM_CONFIGURE |
141101 + (ccg->parent->idx << 4) | ccg->idx);
141102 + config_opts.dcpid = ccg->parent->dcp_idx;
141103 + config_opts.we_mask = cpu_to_be16(QM_CCGR_WE_CSCN_TUPD);
141104 + config_opts.cm_config.cscn_tupd = cpu_to_be16(PORTAL_IDX(p));
141105 + ret = qman_ceetm_configure_ccgr(&config_opts);
141106 + spin_unlock_irqrestore(&p->ccgr_lock, irqflags);
141107 + put_affine_portal();
141108 +
141109 + list_del(&ccg->node);
141110 + kfree(ccg);
141111 + return ret;
141112 +}
141113 +EXPORT_SYMBOL(qman_ceetm_ccg_release);
141114 +
141115 +int qman_ceetm_ccg_set(struct qm_ceetm_ccg *ccg, u16 we_mask,
141116 + const struct qm_ceetm_ccg_params *params)
141117 +{
141118 + struct qm_mcc_ceetm_ccgr_config config_opts;
141119 + unsigned long irqflags __maybe_unused;
141120 + int ret;
141121 + struct qman_portal *p;
141122 +
141123 + if (((ccg->parent->idx << 4) | ccg->idx) >= (2 * __CGR_NUM))
141124 + return -EINVAL;
141125 +
141126 + p = get_affine_portal();
141127 +
141128 + memset(&config_opts, 0, sizeof(struct qm_mcc_ceetm_ccgr_config));
141129 + spin_lock_irqsave(&p->ccgr_lock, irqflags);
141130 +
141131 + config_opts.ccgrid = cpu_to_be16(CEETM_CCGR_CM_CONFIGURE |
141132 + (ccg->parent->idx << 4) | ccg->idx);
141133 + config_opts.dcpid = ccg->parent->dcp_idx;
141134 + config_opts.we_mask = we_mask;
141135 + if (we_mask & QM_CCGR_WE_CSCN_EN) {
141136 + config_opts.we_mask |= QM_CCGR_WE_CSCN_TUPD;
141137 + config_opts.cm_config.cscn_tupd = cpu_to_be16(
141138 + QM_CGR_TARG_UDP_CTRL_WRITE_BIT | PORTAL_IDX(p));
141139 + }
141140 + config_opts.we_mask = cpu_to_be16(config_opts.we_mask);
141141 + config_opts.cm_config.ctl_wr_en_g = params->wr_en_g;
141142 + config_opts.cm_config.ctl_wr_en_y = params->wr_en_y;
141143 + config_opts.cm_config.ctl_wr_en_r = params->wr_en_r;
141144 + config_opts.cm_config.ctl_td_en = params->td_en;
141145 + config_opts.cm_config.ctl_td_mode = params->td_mode;
141146 + config_opts.cm_config.ctl_cscn_en = params->cscn_en;
141147 + config_opts.cm_config.ctl_mode = params->mode;
141148 + config_opts.cm_config.oal = params->oal;
141149 + config_opts.cm_config.cs_thres.hword =
141150 + cpu_to_be16(params->cs_thres_in.hword);
141151 + config_opts.cm_config.cs_thres_x.hword =
141152 + cpu_to_be16(params->cs_thres_out.hword);
141153 + config_opts.cm_config.td_thres.hword =
141154 + cpu_to_be16(params->td_thres.hword);
141155 + config_opts.cm_config.wr_parm_g.word =
141156 + cpu_to_be32(params->wr_parm_g.word);
141157 + config_opts.cm_config.wr_parm_y.word =
141158 + cpu_to_be32(params->wr_parm_y.word);
141159 + config_opts.cm_config.wr_parm_r.word =
141160 + cpu_to_be32(params->wr_parm_r.word);
141161 + ret = qman_ceetm_configure_ccgr(&config_opts);
141162 + if (ret) {
141163 + pr_err("Configure CCGR CM failed!\n");
141164 + goto release_lock;
141165 + }
141166 +
141167 + if (we_mask & QM_CCGR_WE_CSCN_EN)
141168 + if (list_empty(&ccg->cb_node))
141169 + list_add(&ccg->cb_node,
141170 + &p->ccgr_cbs[ccg->parent->dcp_idx]);
141171 +release_lock:
141172 + spin_unlock_irqrestore(&p->ccgr_lock, irqflags);
141173 + put_affine_portal();
141174 + return ret;
141175 +}
141176 +EXPORT_SYMBOL(qman_ceetm_ccg_set);
141177 +
141178 +#define CEETM_CCGR_CTL_MASK 0x01
141179 +int qman_ceetm_ccg_get(struct qm_ceetm_ccg *ccg,
141180 + struct qm_ceetm_ccg_params *params)
141181 +{
141182 + struct qm_mcc_ceetm_ccgr_query query_opts;
141183 + struct qm_mcr_ceetm_ccgr_query query_result;
141184 +
141185 + query_opts.ccgrid = cpu_to_be16(CEETM_CCGR_CM_QUERY |
141186 + (ccg->parent->idx << 4) | ccg->idx);
141187 + query_opts.dcpid = ccg->parent->dcp_idx;
141188 +
141189 + if (qman_ceetm_query_ccgr(&query_opts, &query_result)) {
141190 + pr_err("Can't query CCGR#%d\n", ccg->idx);
141191 + return -EINVAL;
141192 + }
141193 +
141194 + params->wr_parm_r.word = query_result.cm_query.wr_parm_r.word;
141195 + params->wr_parm_y.word = query_result.cm_query.wr_parm_y.word;
141196 + params->wr_parm_g.word = query_result.cm_query.wr_parm_g.word;
141197 + params->td_thres.hword = query_result.cm_query.td_thres.hword;
141198 + params->cs_thres_out.hword = query_result.cm_query.cs_thres_x.hword;
141199 + params->cs_thres_in.hword = query_result.cm_query.cs_thres.hword;
141200 + params->oal = query_result.cm_query.oal;
141201 + params->wr_en_g = query_result.cm_query.ctl_wr_en_g;
141202 + params->wr_en_y = query_result.cm_query.ctl_wr_en_y;
141203 + params->wr_en_r = query_result.cm_query.ctl_wr_en_r;
141204 + params->td_en = query_result.cm_query.ctl_td_en;
141205 + params->td_mode = query_result.cm_query.ctl_td_mode;
141206 + params->cscn_en = query_result.cm_query.ctl_cscn_en;
141207 + params->mode = query_result.cm_query.ctl_mode;
141208 +
141209 + return 0;
141210 +}
141211 +EXPORT_SYMBOL(qman_ceetm_ccg_get);
141212 +
141213 +int qman_ceetm_ccg_get_reject_statistics(struct qm_ceetm_ccg *ccg, u32 flags,
141214 + u64 *frame_count, u64 *byte_count)
141215 +{
141216 + struct qm_mcr_ceetm_statistics_query result;
141217 + u16 cid, command_type;
141218 + enum qm_dc_portal dcp_idx;
141219 + int ret;
141220 +
141221 + cid = cpu_to_be16((ccg->parent->idx << 4) | ccg->idx);
141222 + dcp_idx = ccg->parent->dcp_idx;
141223 + if (flags == QMAN_CEETM_FLAG_CLEAR_STATISTICS_COUNTER)
141224 + command_type = CEETM_QUERY_REJECT_CLEAR_STATISTICS;
141225 + else
141226 + command_type = CEETM_QUERY_REJECT_STATISTICS;
141227 +
141228 + ret = qman_ceetm_query_statistics(cid, dcp_idx, command_type, &result);
141229 + if (ret) {
141230 + pr_err("Can't query the statistics of CCG#%d!\n", ccg->idx);
141231 + return -EINVAL;
141232 + }
141233 +
141234 + *frame_count = be40_to_cpu(result.frm_cnt);
141235 + *byte_count = be48_to_cpu(result.byte_cnt);
141236 + return 0;
141237 +}
141238 +EXPORT_SYMBOL(qman_ceetm_ccg_get_reject_statistics);
141239 +
141240 +int qman_ceetm_cscn_swp_get(struct qm_ceetm_ccg *ccg,
141241 + u16 swp_idx,
141242 + unsigned int *cscn_enabled)
141243 +{
141244 + struct qm_mcc_ceetm_ccgr_query query_opts;
141245 + struct qm_mcr_ceetm_ccgr_query query_result;
141246 + int i;
141247 +
141248 + DPA_ASSERT(swp_idx < 127);
141249 + query_opts.ccgrid = cpu_to_be16(CEETM_CCGR_CM_QUERY |
141250 + (ccg->parent->idx << 4) | ccg->idx);
141251 + query_opts.dcpid = ccg->parent->dcp_idx;
141252 +
141253 + if (qman_ceetm_query_ccgr(&query_opts, &query_result)) {
141254 + pr_err("Can't query CCGR#%d\n", ccg->idx);
141255 + return -EINVAL;
141256 + }
141257 +
141258 + i = swp_idx / 32;
141259 + i = 3 - i;
141260 + *cscn_enabled = query_result.cm_query.cscn_targ_swp[i] >>
141261 + (31 - swp_idx % 32);
141262 +
141263 + return 0;
141264 +}
141265 +EXPORT_SYMBOL(qman_ceetm_cscn_swp_get);
141266 +
141267 +int qman_ceetm_cscn_dcp_set(struct qm_ceetm_ccg *ccg,
141268 + u16 dcp_idx,
141269 + u8 vcgid,
141270 + unsigned int cscn_enabled,
141271 + u16 we_mask,
141272 + const struct qm_ceetm_ccg_params *params)
141273 +{
141274 + struct qm_mcc_ceetm_ccgr_config config_opts;
141275 + int ret;
141276 +
141277 + config_opts.ccgrid = cpu_to_be16(CEETM_CCGR_CM_CONFIGURE |
141278 + (ccg->parent->idx << 4) | ccg->idx);
141279 + config_opts.dcpid = ccg->parent->dcp_idx;
141280 + config_opts.we_mask = cpu_to_be16(we_mask | QM_CCGR_WE_CSCN_TUPD |
141281 + QM_CCGR_WE_CDV);
141282 + config_opts.cm_config.cdv = vcgid;
141283 + config_opts.cm_config.cscn_tupd = cpu_to_be16((cscn_enabled << 15) |
141284 + QM_CGR_TARG_UDP_CTRL_DCP | dcp_idx);
141285 + config_opts.cm_config.ctl_wr_en_g = params->wr_en_g;
141286 + config_opts.cm_config.ctl_wr_en_y = params->wr_en_y;
141287 + config_opts.cm_config.ctl_wr_en_r = params->wr_en_r;
141288 + config_opts.cm_config.ctl_td_en = params->td_en;
141289 + config_opts.cm_config.ctl_td_mode = params->td_mode;
141290 + config_opts.cm_config.ctl_cscn_en = params->cscn_en;
141291 + config_opts.cm_config.ctl_mode = params->mode;
141292 + config_opts.cm_config.cs_thres.hword =
141293 + cpu_to_be16(params->cs_thres_in.hword);
141294 + config_opts.cm_config.cs_thres_x.hword =
141295 + cpu_to_be16(params->cs_thres_out.hword);
141296 + config_opts.cm_config.td_thres.hword =
141297 + cpu_to_be16(params->td_thres.hword);
141298 + config_opts.cm_config.wr_parm_g.word =
141299 + cpu_to_be32(params->wr_parm_g.word);
141300 + config_opts.cm_config.wr_parm_y.word =
141301 + cpu_to_be32(params->wr_parm_y.word);
141302 + config_opts.cm_config.wr_parm_r.word =
141303 + cpu_to_be32(params->wr_parm_r.word);
141304 +
141305 + ret = qman_ceetm_configure_ccgr(&config_opts);
141306 + if (ret) {
141307 + pr_err("Configure CSCN_TARG_DCP failed!\n");
141308 + return -EINVAL;
141309 + }
141310 + return 0;
141311 +}
141312 +EXPORT_SYMBOL(qman_ceetm_cscn_dcp_set);
141313 +
141314 +int qman_ceetm_cscn_dcp_get(struct qm_ceetm_ccg *ccg,
141315 + u16 dcp_idx,
141316 + u8 *vcgid,
141317 + unsigned int *cscn_enabled)
141318 +{
141319 + struct qm_mcc_ceetm_ccgr_query query_opts;
141320 + struct qm_mcr_ceetm_ccgr_query query_result;
141321 +
141322 + query_opts.ccgrid = cpu_to_be16(CEETM_CCGR_CM_QUERY |
141323 + (ccg->parent->idx << 4) | ccg->idx);
141324 + query_opts.dcpid = ccg->parent->dcp_idx;
141325 +
141326 + if (qman_ceetm_query_ccgr(&query_opts, &query_result)) {
141327 + pr_err("Can't query CCGR#%d\n", ccg->idx);
141328 + return -EINVAL;
141329 + }
141330 +
141331 + *vcgid = query_result.cm_query.cdv;
141332 + *cscn_enabled = (query_result.cm_query.cscn_targ_dcp >> dcp_idx) & 0x1;
141333 + return 0;
141334 +}
141335 +EXPORT_SYMBOL(qman_ceetm_cscn_dcp_get);
141336 +
141337 +int qman_ceetm_querycongestion(struct __qm_mcr_querycongestion *ccg_state,
141338 + unsigned int dcp_idx)
141339 +{
141340 + struct qm_mc_command *mcc;
141341 + struct qm_mc_result *mcr;
141342 + struct qman_portal *p;
141343 + unsigned long irqflags __maybe_unused;
141344 + u8 res;
141345 + int i, j;
141346 +
141347 + p = get_affine_portal();
141348 + PORTAL_IRQ_LOCK(p, irqflags);
141349 +
141350 + mcc = qm_mc_start(&p->p);
141351 + for (i = 0; i < 2; i++) {
141352 + mcc->ccgr_query.ccgrid =
141353 + cpu_to_be16(CEETM_QUERY_CONGESTION_STATE | i);
141354 + mcc->ccgr_query.dcpid = dcp_idx;
141355 + qm_mc_commit(&p->p, QM_CEETM_VERB_CCGR_QUERY);
141356 +
141357 + while (!(mcr = qm_mc_result(&p->p)))
141358 + cpu_relax();
141359 + DPA_ASSERT((mcr->verb & QM_MCR_VERB_MASK) ==
141360 + QM_CEETM_VERB_CCGR_QUERY);
141361 + res = mcr->result;
141362 + if (res == QM_MCR_RESULT_OK) {
141363 + for (j = 0; j < 8; j++)
141364 + mcr->ccgr_query.congestion_state.state.
141365 + __state[j] = be32_to_cpu(mcr->ccgr_query.
141366 + congestion_state.state.__state[j]);
141367 + *(ccg_state + i) =
141368 + mcr->ccgr_query.congestion_state.state;
141369 + } else {
141370 + pr_err("QUERY CEETM CONGESTION STATE failed\n");
141371 + PORTAL_IRQ_UNLOCK(p, irqflags);
141372 + return -EIO;
141373 + }
141374 + }
141375 + PORTAL_IRQ_UNLOCK(p, irqflags);
141376 + put_affine_portal();
141377 + return 0;
141378 +}
141379 +
141380 +int qman_set_wpm(int wpm_enable)
141381 +{
141382 + return qm_set_wpm(wpm_enable);
141383 +}
141384 +EXPORT_SYMBOL(qman_set_wpm);
141385 +
141386 +int qman_get_wpm(int *wpm_enable)
141387 +{
141388 + return qm_get_wpm(wpm_enable);
141389 +}
141390 +EXPORT_SYMBOL(qman_get_wpm);
141391 +
141392 +int qman_shutdown_fq(u32 fqid)
141393 +{
141394 + struct qman_portal *p;
141395 + unsigned long irqflags __maybe_unused;
141396 + int ret;
141397 + struct qm_portal *low_p;
141398 + p = get_affine_portal();
141399 + PORTAL_IRQ_LOCK(p, irqflags);
141400 + low_p = &p->p;
141401 + ret = qm_shutdown_fq(&low_p, 1, fqid);
141402 + PORTAL_IRQ_UNLOCK(p, irqflags);
141403 + put_affine_portal();
141404 + return ret;
141405 +}
141406 +
141407 +const struct qm_portal_config *qman_get_qm_portal_config(
141408 + struct qman_portal *portal)
141409 +{
141410 + return portal->sharing_redirect ? NULL : portal->config;
141411 +}
141412 --- /dev/null
141413 +++ b/drivers/staging/fsl_qbman/qman_low.h
141414 @@ -0,0 +1,1442 @@
141415 +/* Copyright 2008-2011 Freescale Semiconductor, Inc.
141416 + *
141417 + * Redistribution and use in source and binary forms, with or without
141418 + * modification, are permitted provided that the following conditions are met:
141419 + * * Redistributions of source code must retain the above copyright
141420 + * notice, this list of conditions and the following disclaimer.
141421 + * * Redistributions in binary form must reproduce the above copyright
141422 + * notice, this list of conditions and the following disclaimer in the
141423 + * documentation and/or other materials provided with the distribution.
141424 + * * Neither the name of Freescale Semiconductor nor the
141425 + * names of its contributors may be used to endorse or promote products
141426 + * derived from this software without specific prior written permission.
141427 + *
141428 + *
141429 + * ALTERNATIVELY, this software may be distributed under the terms of the
141430 + * GNU General Public License ("GPL") as published by the Free Software
141431 + * Foundation, either version 2 of that License or (at your option) any
141432 + * later version.
141433 + *
141434 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
141435 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
141436 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
141437 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
141438 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
141439 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
141440 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
141441 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
141442 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
141443 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
141444 + */
141445 +
141446 +#include "qman_private.h"
141447 +
141448 +/***************************/
141449 +/* Portal register assists */
141450 +/***************************/
141451 +
141452 +/* Cache-inhibited register offsets */
141453 +#if defined(CONFIG_PPC32) || defined(CONFIG_PPC64)
141454 +
141455 +#define QM_REG_EQCR_PI_CINH 0x0000
141456 +#define QM_REG_EQCR_CI_CINH 0x0004
141457 +#define QM_REG_EQCR_ITR 0x0008
141458 +#define QM_REG_DQRR_PI_CINH 0x0040
141459 +#define QM_REG_DQRR_CI_CINH 0x0044
141460 +#define QM_REG_DQRR_ITR 0x0048
141461 +#define QM_REG_DQRR_DCAP 0x0050
141462 +#define QM_REG_DQRR_SDQCR 0x0054
141463 +#define QM_REG_DQRR_VDQCR 0x0058
141464 +#define QM_REG_DQRR_PDQCR 0x005c
141465 +#define QM_REG_MR_PI_CINH 0x0080
141466 +#define QM_REG_MR_CI_CINH 0x0084
141467 +#define QM_REG_MR_ITR 0x0088
141468 +#define QM_REG_CFG 0x0100
141469 +#define QM_REG_ISR 0x0e00
141470 +#define QM_REG_IIR 0x0e0c
141471 +#define QM_REG_ITPR 0x0e14
141472 +
141473 +/* Cache-enabled register offsets */
141474 +#define QM_CL_EQCR 0x0000
141475 +#define QM_CL_DQRR 0x1000
141476 +#define QM_CL_MR 0x2000
141477 +#define QM_CL_EQCR_PI_CENA 0x3000
141478 +#define QM_CL_EQCR_CI_CENA 0x3100
141479 +#define QM_CL_DQRR_PI_CENA 0x3200
141480 +#define QM_CL_DQRR_CI_CENA 0x3300
141481 +#define QM_CL_MR_PI_CENA 0x3400
141482 +#define QM_CL_MR_CI_CENA 0x3500
141483 +#define QM_CL_CR 0x3800
141484 +#define QM_CL_RR0 0x3900
141485 +#define QM_CL_RR1 0x3940
141486 +
141487 +#endif
141488 +
141489 +#if defined(CONFIG_ARM) || defined(CONFIG_ARM64)
141490 +
141491 +#define QM_REG_EQCR_PI_CINH 0x3000
141492 +#define QM_REG_EQCR_CI_CINH 0x3040
141493 +#define QM_REG_EQCR_ITR 0x3080
141494 +#define QM_REG_DQRR_PI_CINH 0x3100
141495 +#define QM_REG_DQRR_CI_CINH 0x3140
141496 +#define QM_REG_DQRR_ITR 0x3180
141497 +#define QM_REG_DQRR_DCAP 0x31C0
141498 +#define QM_REG_DQRR_SDQCR 0x3200
141499 +#define QM_REG_DQRR_VDQCR 0x3240
141500 +#define QM_REG_DQRR_PDQCR 0x3280
141501 +#define QM_REG_MR_PI_CINH 0x3300
141502 +#define QM_REG_MR_CI_CINH 0x3340
141503 +#define QM_REG_MR_ITR 0x3380
141504 +#define QM_REG_CFG 0x3500
141505 +#define QM_REG_ISR 0x3600
141506 +#define QM_REG_IIR 0x36C0
141507 +#define QM_REG_ITPR 0x3740
141508 +
141509 +/* Cache-enabled register offsets */
141510 +#define QM_CL_EQCR 0x0000
141511 +#define QM_CL_DQRR 0x1000
141512 +#define QM_CL_MR 0x2000
141513 +#define QM_CL_EQCR_PI_CENA 0x3000
141514 +#define QM_CL_EQCR_CI_CENA 0x3040
141515 +#define QM_CL_DQRR_PI_CENA 0x3100
141516 +#define QM_CL_DQRR_CI_CENA 0x3140
141517 +#define QM_CL_MR_PI_CENA 0x3300
141518 +#define QM_CL_MR_CI_CENA 0x3340
141519 +#define QM_CL_CR 0x3800
141520 +#define QM_CL_RR0 0x3900
141521 +#define QM_CL_RR1 0x3940
141522 +
141523 +#endif
141524 +
141525 +
141526 +/* BTW, the drivers (and h/w programming model) already obtain the required
141527 + * synchronisation for portal accesses via lwsync(), hwsync(), and
141528 + * data-dependencies. Use of barrier()s or other order-preserving primitives
141529 + * simply degrade performance. Hence the use of the __raw_*() interfaces, which
141530 + * simply ensure that the compiler treats the portal registers as volatile (ie.
141531 + * non-coherent). */
141532 +
141533 +/* Cache-inhibited register access. */
141534 +#define __qm_in(qm, o) be32_to_cpu(__raw_readl((qm)->addr_ci + (o)))
141535 +#define __qm_out(qm, o, val) __raw_writel((cpu_to_be32(val)), \
141536 + (qm)->addr_ci + (o));
141537 +#define qm_in(reg) __qm_in(&portal->addr, QM_REG_##reg)
141538 +#define qm_out(reg, val) __qm_out(&portal->addr, QM_REG_##reg, val)
141539 +
141540 +/* Cache-enabled (index) register access */
141541 +#define __qm_cl_touch_ro(qm, o) dcbt_ro((qm)->addr_ce + (o))
141542 +#define __qm_cl_touch_rw(qm, o) dcbt_rw((qm)->addr_ce + (o))
141543 +#define __qm_cl_in(qm, o) be32_to_cpu(__raw_readl((qm)->addr_ce + (o)))
141544 +#define __qm_cl_out(qm, o, val) \
141545 + do { \
141546 + u32 *__tmpclout = (qm)->addr_ce + (o); \
141547 + __raw_writel(cpu_to_be32(val), __tmpclout); \
141548 + dcbf(__tmpclout); \
141549 + } while (0)
141550 +#define __qm_cl_invalidate(qm, o) dcbi((qm)->addr_ce + (o))
141551 +#define qm_cl_touch_ro(reg) __qm_cl_touch_ro(&portal->addr, QM_CL_##reg##_CENA)
141552 +#define qm_cl_touch_rw(reg) __qm_cl_touch_rw(&portal->addr, QM_CL_##reg##_CENA)
141553 +#define qm_cl_in(reg) __qm_cl_in(&portal->addr, QM_CL_##reg##_CENA)
141554 +#define qm_cl_out(reg, val) __qm_cl_out(&portal->addr, QM_CL_##reg##_CENA, val)
141555 +#define qm_cl_invalidate(reg)\
141556 + __qm_cl_invalidate(&portal->addr, QM_CL_##reg##_CENA)
141557 +
141558 +/* Cache-enabled ring access */
141559 +#define qm_cl(base, idx) ((void *)base + ((idx) << 6))
141560 +
141561 +/* Cyclic helper for rings. FIXME: once we are able to do fine-grain perf
141562 + * analysis, look at using the "extra" bit in the ring index registers to avoid
141563 + * cyclic issues. */
141564 +static inline u8 qm_cyc_diff(u8 ringsize, u8 first, u8 last)
141565 +{
141566 + /* 'first' is included, 'last' is excluded */
141567 + if (first <= last)
141568 + return last - first;
141569 + return ringsize + last - first;
141570 +}
141571 +
141572 +/* Portal modes.
141573 + * Enum types;
141574 + * pmode == production mode
141575 + * cmode == consumption mode,
141576 + * dmode == h/w dequeue mode.
141577 + * Enum values use 3 letter codes. First letter matches the portal mode,
141578 + * remaining two letters indicate;
141579 + * ci == cache-inhibited portal register
141580 + * ce == cache-enabled portal register
141581 + * vb == in-band valid-bit (cache-enabled)
141582 + * dc == DCA (Discrete Consumption Acknowledgement), DQRR-only
141583 + * As for "enum qm_dqrr_dmode", it should be self-explanatory.
141584 + */
141585 +enum qm_eqcr_pmode { /* matches QCSP_CFG::EPM */
141586 + qm_eqcr_pci = 0, /* PI index, cache-inhibited */
141587 + qm_eqcr_pce = 1, /* PI index, cache-enabled */
141588 + qm_eqcr_pvb = 2 /* valid-bit */
141589 +};
141590 +enum qm_dqrr_dmode { /* matches QCSP_CFG::DP */
141591 + qm_dqrr_dpush = 0, /* SDQCR + VDQCR */
141592 + qm_dqrr_dpull = 1 /* PDQCR */
141593 +};
141594 +enum qm_dqrr_pmode { /* s/w-only */
141595 + qm_dqrr_pci, /* reads DQRR_PI_CINH */
141596 + qm_dqrr_pce, /* reads DQRR_PI_CENA */
141597 + qm_dqrr_pvb /* reads valid-bit */
141598 +};
141599 +enum qm_dqrr_cmode { /* matches QCSP_CFG::DCM */
141600 + qm_dqrr_cci = 0, /* CI index, cache-inhibited */
141601 + qm_dqrr_cce = 1, /* CI index, cache-enabled */
141602 + qm_dqrr_cdc = 2 /* Discrete Consumption Acknowledgement */
141603 +};
141604 +enum qm_mr_pmode { /* s/w-only */
141605 + qm_mr_pci, /* reads MR_PI_CINH */
141606 + qm_mr_pce, /* reads MR_PI_CENA */
141607 + qm_mr_pvb /* reads valid-bit */
141608 +};
141609 +enum qm_mr_cmode { /* matches QCSP_CFG::MM */
141610 + qm_mr_cci = 0, /* CI index, cache-inhibited */
141611 + qm_mr_cce = 1 /* CI index, cache-enabled */
141612 +};
141613 +
141614 +
141615 +/* ------------------------- */
141616 +/* --- Portal structures --- */
141617 +
141618 +#define QM_EQCR_SIZE 8
141619 +#define QM_DQRR_SIZE 16
141620 +#define QM_MR_SIZE 8
141621 +
141622 +struct qm_eqcr {
141623 + struct qm_eqcr_entry *ring, *cursor;
141624 + u8 ci, available, ithresh, vbit;
141625 +#ifdef CONFIG_FSL_DPA_CHECKING
141626 + u32 busy;
141627 + enum qm_eqcr_pmode pmode;
141628 +#endif
141629 +};
141630 +
141631 +struct qm_dqrr {
141632 + const struct qm_dqrr_entry *ring, *cursor;
141633 + u8 pi, ci, fill, ithresh, vbit;
141634 +#ifdef CONFIG_FSL_DPA_CHECKING
141635 + enum qm_dqrr_dmode dmode;
141636 + enum qm_dqrr_pmode pmode;
141637 + enum qm_dqrr_cmode cmode;
141638 +#endif
141639 +};
141640 +
141641 +struct qm_mr {
141642 + const struct qm_mr_entry *ring, *cursor;
141643 + u8 pi, ci, fill, ithresh, vbit;
141644 +#ifdef CONFIG_FSL_DPA_CHECKING
141645 + enum qm_mr_pmode pmode;
141646 + enum qm_mr_cmode cmode;
141647 +#endif
141648 +};
141649 +
141650 +struct qm_mc {
141651 + struct qm_mc_command *cr;
141652 + struct qm_mc_result *rr;
141653 + u8 rridx, vbit;
141654 +#ifdef CONFIG_FSL_DPA_CHECKING
141655 + enum {
141656 + /* Can be _mc_start()ed */
141657 + qman_mc_idle,
141658 + /* Can be _mc_commit()ed or _mc_abort()ed */
141659 + qman_mc_user,
141660 + /* Can only be _mc_retry()ed */
141661 + qman_mc_hw
141662 + } state;
141663 +#endif
141664 +};
141665 +
141666 +#define QM_PORTAL_ALIGNMENT ____cacheline_aligned
141667 +
141668 +struct qm_addr {
141669 + void __iomem *addr_ce; /* cache-enabled */
141670 + void __iomem *addr_ci; /* cache-inhibited */
141671 +};
141672 +
141673 +struct qm_portal {
141674 + /* In the non-CONFIG_FSL_DPA_CHECKING case, the following stuff up to
141675 + * and including 'mc' fits within a cacheline (yay!). The 'config' part
141676 + * is setup-only, so isn't a cause for a concern. In other words, don't
141677 + * rearrange this structure on a whim, there be dragons ... */
141678 + struct qm_addr addr;
141679 + struct qm_eqcr eqcr;
141680 + struct qm_dqrr dqrr;
141681 + struct qm_mr mr;
141682 + struct qm_mc mc;
141683 +} QM_PORTAL_ALIGNMENT;
141684 +
141685 +
141686 +/* ---------------- */
141687 +/* --- EQCR API --- */
141688 +
141689 +/* Bit-wise logic to wrap a ring pointer by clearing the "carry bit" */
141690 +#define EQCR_CARRYCLEAR(p) \
141691 + (void *)((unsigned long)(p) & (~(unsigned long)(QM_EQCR_SIZE << 6)))
141692 +
141693 +/* Bit-wise logic to convert a ring pointer to a ring index */
141694 +static inline u8 EQCR_PTR2IDX(struct qm_eqcr_entry *e)
141695 +{
141696 + return ((uintptr_t)e >> 6) & (QM_EQCR_SIZE - 1);
141697 +}
141698 +
141699 +/* Increment the 'cursor' ring pointer, taking 'vbit' into account */
141700 +static inline void EQCR_INC(struct qm_eqcr *eqcr)
141701 +{
141702 + /* NB: this is odd-looking, but experiments show that it generates fast
141703 + * code with essentially no branching overheads. We increment to the
141704 + * next EQCR pointer and handle overflow and 'vbit'. */
141705 + struct qm_eqcr_entry *partial = eqcr->cursor + 1;
141706 + eqcr->cursor = EQCR_CARRYCLEAR(partial);
141707 + if (partial != eqcr->cursor)
141708 + eqcr->vbit ^= QM_EQCR_VERB_VBIT;
141709 +}
141710 +
141711 +static inline int qm_eqcr_init(struct qm_portal *portal,
141712 + enum qm_eqcr_pmode pmode,
141713 + unsigned int eq_stash_thresh,
141714 + int eq_stash_prio)
141715 +{
141716 + /* This use of 'register', as well as all other occurrences, is because
141717 + * it has been observed to generate much faster code with gcc than is
141718 + * otherwise the case. */
141719 + register struct qm_eqcr *eqcr = &portal->eqcr;
141720 + u32 cfg;
141721 + u8 pi;
141722 +
141723 + eqcr->ring = portal->addr.addr_ce + QM_CL_EQCR;
141724 + eqcr->ci = qm_in(EQCR_CI_CINH) & (QM_EQCR_SIZE - 1);
141725 + qm_cl_invalidate(EQCR_CI);
141726 + pi = qm_in(EQCR_PI_CINH) & (QM_EQCR_SIZE - 1);
141727 + eqcr->cursor = eqcr->ring + pi;
141728 + eqcr->vbit = (qm_in(EQCR_PI_CINH) & QM_EQCR_SIZE) ?
141729 + QM_EQCR_VERB_VBIT : 0;
141730 + eqcr->available = QM_EQCR_SIZE - 1 -
141731 + qm_cyc_diff(QM_EQCR_SIZE, eqcr->ci, pi);
141732 + eqcr->ithresh = qm_in(EQCR_ITR);
141733 +#ifdef CONFIG_FSL_DPA_CHECKING
141734 + eqcr->busy = 0;
141735 + eqcr->pmode = pmode;
141736 +#endif
141737 + cfg = (qm_in(CFG) & 0x00ffffff) |
141738 + (eq_stash_thresh << 28) | /* QCSP_CFG: EST */
141739 + (eq_stash_prio << 26) | /* QCSP_CFG: EP */
141740 + ((pmode & 0x3) << 24); /* QCSP_CFG::EPM */
141741 + qm_out(CFG, cfg);
141742 + return 0;
141743 +}
141744 +
141745 +static inline unsigned int qm_eqcr_get_ci_stashing(struct qm_portal *portal)
141746 +{
141747 + return (qm_in(CFG) >> 28) & 0x7;
141748 +}
141749 +
141750 +static inline void qm_eqcr_finish(struct qm_portal *portal)
141751 +{
141752 + register struct qm_eqcr *eqcr = &portal->eqcr;
141753 + u8 pi, ci;
141754 + u32 cfg;
141755 +
141756 + /*
141757 + * Disable EQCI stashing because the QMan only
141758 + * presents the value it previously stashed to
141759 + * maintain coherency. Setting the stash threshold
141760 + * to 1 then 0 ensures that QMan has resyncronized
141761 + * its internal copy so that the portal is clean
141762 + * when it is reinitialized in the future
141763 + */
141764 + cfg = (qm_in(CFG) & 0x0fffffff) |
141765 + (1 << 28); /* QCSP_CFG: EST */
141766 + qm_out(CFG, cfg);
141767 + cfg &= 0x0fffffff; /* stash threshold = 0 */
141768 + qm_out(CFG, cfg);
141769 +
141770 + pi = qm_in(EQCR_PI_CINH) & (QM_EQCR_SIZE - 1);
141771 + ci = qm_in(EQCR_CI_CINH) & (QM_EQCR_SIZE - 1);
141772 +
141773 + /* Refresh EQCR CI cache value */
141774 + qm_cl_invalidate(EQCR_CI);
141775 + eqcr->ci = qm_cl_in(EQCR_CI) & (QM_EQCR_SIZE - 1);
141776 +
141777 + DPA_ASSERT(!eqcr->busy);
141778 + if (pi != EQCR_PTR2IDX(eqcr->cursor))
141779 + pr_crit("losing uncommited EQCR entries\n");
141780 + if (ci != eqcr->ci)
141781 + pr_crit("missing existing EQCR completions\n");
141782 + if (eqcr->ci != EQCR_PTR2IDX(eqcr->cursor))
141783 + pr_crit("EQCR destroyed unquiesced\n");
141784 +}
141785 +
141786 +static inline struct qm_eqcr_entry *qm_eqcr_start_no_stash(struct qm_portal
141787 + *portal)
141788 +{
141789 + register struct qm_eqcr *eqcr = &portal->eqcr;
141790 + DPA_ASSERT(!eqcr->busy);
141791 + if (!eqcr->available)
141792 + return NULL;
141793 +
141794 +
141795 +#ifdef CONFIG_FSL_DPA_CHECKING
141796 + eqcr->busy = 1;
141797 +#endif
141798 +#if defined(CONFIG_PPC32) || defined(CONFIG_PPC64)
141799 + dcbz_64(eqcr->cursor);
141800 +#endif
141801 + return eqcr->cursor;
141802 +}
141803 +
141804 +static inline struct qm_eqcr_entry *qm_eqcr_start_stash(struct qm_portal
141805 + *portal)
141806 +{
141807 + register struct qm_eqcr *eqcr = &portal->eqcr;
141808 + u8 diff, old_ci;
141809 +
141810 + DPA_ASSERT(!eqcr->busy);
141811 + if (!eqcr->available) {
141812 + old_ci = eqcr->ci;
141813 + eqcr->ci = qm_cl_in(EQCR_CI) & (QM_EQCR_SIZE - 1);
141814 + diff = qm_cyc_diff(QM_EQCR_SIZE, old_ci, eqcr->ci);
141815 + eqcr->available += diff;
141816 + if (!diff)
141817 + return NULL;
141818 + }
141819 +#ifdef CONFIG_FSL_DPA_CHECKING
141820 + eqcr->busy = 1;
141821 +#endif
141822 +#if defined(CONFIG_PPC32) || defined(CONFIG_PPC64)
141823 + dcbz_64(eqcr->cursor);
141824 +#endif
141825 + return eqcr->cursor;
141826 +}
141827 +
141828 +static inline void qm_eqcr_abort(struct qm_portal *portal)
141829 +{
141830 + __maybe_unused register struct qm_eqcr *eqcr = &portal->eqcr;
141831 + DPA_ASSERT(eqcr->busy);
141832 +#ifdef CONFIG_FSL_DPA_CHECKING
141833 + eqcr->busy = 0;
141834 +#endif
141835 +}
141836 +
141837 +static inline struct qm_eqcr_entry *qm_eqcr_pend_and_next(
141838 + struct qm_portal *portal, u8 myverb)
141839 +{
141840 + register struct qm_eqcr *eqcr = &portal->eqcr;
141841 + DPA_ASSERT(eqcr->busy);
141842 + DPA_ASSERT(eqcr->pmode != qm_eqcr_pvb);
141843 + if (eqcr->available == 1)
141844 + return NULL;
141845 + eqcr->cursor->__dont_write_directly__verb = myverb | eqcr->vbit;
141846 + dcbf(eqcr->cursor);
141847 + EQCR_INC(eqcr);
141848 + eqcr->available--;
141849 +#if defined(CONFIG_PPC32) || defined(CONFIG_PPC64)
141850 + dcbz_64(eqcr->cursor);
141851 +#endif
141852 + return eqcr->cursor;
141853 +}
141854 +
141855 +#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
141856 +#define EQCR_COMMIT_CHECKS(eqcr) \
141857 +do { \
141858 + DPA_ASSERT(eqcr->busy); \
141859 + DPA_ASSERT(eqcr->cursor->orp == (eqcr->cursor->orp & 0xffffff00)); \
141860 + DPA_ASSERT(eqcr->cursor->fqid == (eqcr->cursor->fqid & 0xffffff00)); \
141861 +} while (0)
141862 +#else
141863 +#define EQCR_COMMIT_CHECKS(eqcr) \
141864 +do { \
141865 + DPA_ASSERT(eqcr->busy); \
141866 + DPA_ASSERT(eqcr->cursor->orp == (eqcr->cursor->orp & \
141867 + cpu_to_be32(0x00ffffff))); \
141868 + DPA_ASSERT(eqcr->cursor->fqid == (eqcr->cursor->fqid & \
141869 + cpu_to_be32(0x00ffffff))); \
141870 +} while (0)
141871 +#endif
141872 +
141873 +static inline void qm_eqcr_pci_commit(struct qm_portal *portal, u8 myverb)
141874 +{
141875 + register struct qm_eqcr *eqcr = &portal->eqcr;
141876 + EQCR_COMMIT_CHECKS(eqcr);
141877 + DPA_ASSERT(eqcr->pmode == qm_eqcr_pci);
141878 + eqcr->cursor->__dont_write_directly__verb = myverb | eqcr->vbit;
141879 + EQCR_INC(eqcr);
141880 + eqcr->available--;
141881 + dcbf(eqcr->cursor);
141882 + hwsync();
141883 + qm_out(EQCR_PI_CINH, EQCR_PTR2IDX(eqcr->cursor));
141884 +#ifdef CONFIG_FSL_DPA_CHECKING
141885 + eqcr->busy = 0;
141886 +#endif
141887 +}
141888 +
141889 +static inline void qm_eqcr_pce_prefetch(struct qm_portal *portal)
141890 +{
141891 + __maybe_unused register struct qm_eqcr *eqcr = &portal->eqcr;
141892 + DPA_ASSERT(eqcr->pmode == qm_eqcr_pce);
141893 + qm_cl_invalidate(EQCR_PI);
141894 + qm_cl_touch_rw(EQCR_PI);
141895 +}
141896 +
141897 +static inline void qm_eqcr_pce_commit(struct qm_portal *portal, u8 myverb)
141898 +{
141899 + register struct qm_eqcr *eqcr = &portal->eqcr;
141900 + EQCR_COMMIT_CHECKS(eqcr);
141901 + DPA_ASSERT(eqcr->pmode == qm_eqcr_pce);
141902 + eqcr->cursor->__dont_write_directly__verb = myverb | eqcr->vbit;
141903 + EQCR_INC(eqcr);
141904 + eqcr->available--;
141905 + dcbf(eqcr->cursor);
141906 + lwsync();
141907 + qm_cl_out(EQCR_PI, EQCR_PTR2IDX(eqcr->cursor));
141908 +#ifdef CONFIG_FSL_DPA_CHECKING
141909 + eqcr->busy = 0;
141910 +#endif
141911 +}
141912 +
141913 +static inline void qm_eqcr_pvb_commit(struct qm_portal *portal, u8 myverb)
141914 +{
141915 + register struct qm_eqcr *eqcr = &portal->eqcr;
141916 + struct qm_eqcr_entry *eqcursor;
141917 + EQCR_COMMIT_CHECKS(eqcr);
141918 + DPA_ASSERT(eqcr->pmode == qm_eqcr_pvb);
141919 + lwsync();
141920 + eqcursor = eqcr->cursor;
141921 + eqcursor->__dont_write_directly__verb = myverb | eqcr->vbit;
141922 + dcbf(eqcursor);
141923 + EQCR_INC(eqcr);
141924 + eqcr->available--;
141925 +#ifdef CONFIG_FSL_DPA_CHECKING
141926 + eqcr->busy = 0;
141927 +#endif
141928 +}
141929 +
141930 +static inline u8 qm_eqcr_cci_update(struct qm_portal *portal)
141931 +{
141932 + register struct qm_eqcr *eqcr = &portal->eqcr;
141933 + u8 diff, old_ci = eqcr->ci;
141934 + eqcr->ci = qm_in(EQCR_CI_CINH) & (QM_EQCR_SIZE - 1);
141935 + diff = qm_cyc_diff(QM_EQCR_SIZE, old_ci, eqcr->ci);
141936 + eqcr->available += diff;
141937 + return diff;
141938 +}
141939 +
141940 +static inline void qm_eqcr_cce_prefetch(struct qm_portal *portal)
141941 +{
141942 + __maybe_unused register struct qm_eqcr *eqcr = &portal->eqcr;
141943 + qm_cl_touch_ro(EQCR_CI);
141944 +}
141945 +
141946 +static inline u8 qm_eqcr_cce_update(struct qm_portal *portal)
141947 +{
141948 + register struct qm_eqcr *eqcr = &portal->eqcr;
141949 + u8 diff, old_ci = eqcr->ci;
141950 + eqcr->ci = qm_cl_in(EQCR_CI) & (QM_EQCR_SIZE - 1);
141951 + qm_cl_invalidate(EQCR_CI);
141952 + diff = qm_cyc_diff(QM_EQCR_SIZE, old_ci, eqcr->ci);
141953 + eqcr->available += diff;
141954 + return diff;
141955 +}
141956 +
141957 +static inline u8 qm_eqcr_get_ithresh(struct qm_portal *portal)
141958 +{
141959 + register struct qm_eqcr *eqcr = &portal->eqcr;
141960 + return eqcr->ithresh;
141961 +}
141962 +
141963 +static inline void qm_eqcr_set_ithresh(struct qm_portal *portal, u8 ithresh)
141964 +{
141965 + register struct qm_eqcr *eqcr = &portal->eqcr;
141966 + eqcr->ithresh = ithresh;
141967 + qm_out(EQCR_ITR, ithresh);
141968 +}
141969 +
141970 +static inline u8 qm_eqcr_get_avail(struct qm_portal *portal)
141971 +{
141972 + register struct qm_eqcr *eqcr = &portal->eqcr;
141973 + return eqcr->available;
141974 +}
141975 +
141976 +static inline u8 qm_eqcr_get_fill(struct qm_portal *portal)
141977 +{
141978 + register struct qm_eqcr *eqcr = &portal->eqcr;
141979 + return QM_EQCR_SIZE - 1 - eqcr->available;
141980 +}
141981 +
141982 +
141983 +/* ---------------- */
141984 +/* --- DQRR API --- */
141985 +
141986 +/* FIXME: many possible improvements;
141987 + * - look at changing the API to use pointer rather than index parameters now
141988 + * that 'cursor' is a pointer,
141989 + * - consider moving other parameters to pointer if it could help (ci)
141990 + */
141991 +
141992 +#define DQRR_CARRYCLEAR(p) \
141993 + (void *)((unsigned long)(p) & (~(unsigned long)(QM_DQRR_SIZE << 6)))
141994 +
141995 +static inline u8 DQRR_PTR2IDX(const struct qm_dqrr_entry *e)
141996 +{
141997 + return ((uintptr_t)e >> 6) & (QM_DQRR_SIZE - 1);
141998 +}
141999 +
142000 +static inline const struct qm_dqrr_entry *DQRR_INC(
142001 + const struct qm_dqrr_entry *e)
142002 +{
142003 + return DQRR_CARRYCLEAR(e + 1);
142004 +}
142005 +
142006 +static inline void qm_dqrr_set_maxfill(struct qm_portal *portal, u8 mf)
142007 +{
142008 + qm_out(CFG, (qm_in(CFG) & 0xff0fffff) |
142009 + ((mf & (QM_DQRR_SIZE - 1)) << 20));
142010 +}
142011 +
142012 +static inline void qm_dqrr_cci_consume(struct qm_portal *portal, u8 num)
142013 +{
142014 + register struct qm_dqrr *dqrr = &portal->dqrr;
142015 + DPA_ASSERT(dqrr->cmode == qm_dqrr_cci);
142016 + dqrr->ci = (dqrr->ci + num) & (QM_DQRR_SIZE - 1);
142017 + qm_out(DQRR_CI_CINH, dqrr->ci);
142018 +}
142019 +
142020 +static inline void qm_dqrr_cce_consume(struct qm_portal *portal, u8 num)
142021 +{
142022 + register struct qm_dqrr *dqrr = &portal->dqrr;
142023 + DPA_ASSERT(dqrr->cmode == qm_dqrr_cce);
142024 + dqrr->ci = (dqrr->ci + num) & (QM_DQRR_SIZE - 1);
142025 + qm_cl_out(DQRR_CI, dqrr->ci);
142026 +}
142027 +
142028 +static inline void qm_dqrr_cdc_consume_n(struct qm_portal *portal, u16 bitmask)
142029 +{
142030 + __maybe_unused register struct qm_dqrr *dqrr = &portal->dqrr;
142031 + DPA_ASSERT(dqrr->cmode == qm_dqrr_cdc);
142032 + qm_out(DQRR_DCAP, (1 << 8) | /* DQRR_DCAP::S */
142033 + ((u32)bitmask << 16)); /* DQRR_DCAP::DCAP_CI */
142034 + dqrr->ci = qm_in(DQRR_CI_CINH) & (QM_DQRR_SIZE - 1);
142035 + dqrr->fill = qm_cyc_diff(QM_DQRR_SIZE, dqrr->ci, dqrr->pi);
142036 +}
142037 +
142038 +static inline int qm_dqrr_init(struct qm_portal *portal,
142039 + const struct qm_portal_config *config,
142040 + enum qm_dqrr_dmode dmode,
142041 + __maybe_unused enum qm_dqrr_pmode pmode,
142042 + enum qm_dqrr_cmode cmode, u8 max_fill)
142043 +{
142044 + register struct qm_dqrr *dqrr = &portal->dqrr;
142045 + u32 cfg;
142046 +
142047 + /* Make sure the DQRR will be idle when we enable */
142048 + qm_out(DQRR_SDQCR, 0);
142049 + qm_out(DQRR_VDQCR, 0);
142050 + qm_out(DQRR_PDQCR, 0);
142051 + dqrr->ring = portal->addr.addr_ce + QM_CL_DQRR;
142052 + dqrr->pi = qm_in(DQRR_PI_CINH) & (QM_DQRR_SIZE - 1);
142053 + dqrr->ci = qm_in(DQRR_CI_CINH) & (QM_DQRR_SIZE - 1);
142054 + dqrr->cursor = dqrr->ring + dqrr->ci;
142055 + dqrr->fill = qm_cyc_diff(QM_DQRR_SIZE, dqrr->ci, dqrr->pi);
142056 + dqrr->vbit = (qm_in(DQRR_PI_CINH) & QM_DQRR_SIZE) ?
142057 + QM_DQRR_VERB_VBIT : 0;
142058 + dqrr->ithresh = qm_in(DQRR_ITR);
142059 +
142060 + /* Free up pending DQRR entries if any as per current DCM */
142061 + if (dqrr->fill) {
142062 + enum qm_dqrr_cmode dcm = (qm_in(CFG) >> 16) & 3;
142063 +
142064 +#ifdef CONFIG_FSL_DPA_CHECKING
142065 + dqrr->cmode = dcm;
142066 +#endif
142067 + switch (dcm) {
142068 + case qm_dqrr_cci:
142069 + qm_dqrr_cci_consume(portal, dqrr->fill);
142070 + break;
142071 + case qm_dqrr_cce:
142072 + qm_dqrr_cce_consume(portal, dqrr->fill);
142073 + break;
142074 + case qm_dqrr_cdc:
142075 + qm_dqrr_cdc_consume_n(portal, (QM_DQRR_SIZE - 1));
142076 + break;
142077 + default:
142078 + DPA_ASSERT(0);
142079 + }
142080 + }
142081 +
142082 +#ifdef CONFIG_FSL_DPA_CHECKING
142083 + dqrr->dmode = dmode;
142084 + dqrr->pmode = pmode;
142085 + dqrr->cmode = cmode;
142086 +#endif
142087 + /* Invalidate every ring entry before beginning */
142088 + for (cfg = 0; cfg < QM_DQRR_SIZE; cfg++)
142089 + dcbi(qm_cl(dqrr->ring, cfg));
142090 + cfg = (qm_in(CFG) & 0xff000f00) |
142091 + ((max_fill & (QM_DQRR_SIZE - 1)) << 20) | /* DQRR_MF */
142092 + ((dmode & 1) << 18) | /* DP */
142093 + ((cmode & 3) << 16) | /* DCM */
142094 + 0xa0 | /* RE+SE */
142095 + (0 ? 0x40 : 0) | /* Ignore RP */
142096 + (0 ? 0x10 : 0); /* Ignore SP */
142097 + qm_out(CFG, cfg);
142098 + qm_dqrr_set_maxfill(portal, max_fill);
142099 + return 0;
142100 +}
142101 +
142102 +static inline void qm_dqrr_finish(struct qm_portal *portal)
142103 +{
142104 + __maybe_unused register struct qm_dqrr *dqrr = &portal->dqrr;
142105 +#ifdef CONFIG_FSL_DPA_CHECKING
142106 + if ((dqrr->cmode != qm_dqrr_cdc) &&
142107 + (dqrr->ci != DQRR_PTR2IDX(dqrr->cursor)))
142108 + pr_crit("Ignoring completed DQRR entries\n");
142109 +#endif
142110 +}
142111 +
142112 +static inline const struct qm_dqrr_entry *qm_dqrr_current(
142113 + struct qm_portal *portal)
142114 +{
142115 + register struct qm_dqrr *dqrr = &portal->dqrr;
142116 + if (!dqrr->fill)
142117 + return NULL;
142118 + return dqrr->cursor;
142119 +}
142120 +
142121 +static inline u8 qm_dqrr_cursor(struct qm_portal *portal)
142122 +{
142123 + register struct qm_dqrr *dqrr = &portal->dqrr;
142124 + return DQRR_PTR2IDX(dqrr->cursor);
142125 +}
142126 +
142127 +static inline u8 qm_dqrr_next(struct qm_portal *portal)
142128 +{
142129 + register struct qm_dqrr *dqrr = &portal->dqrr;
142130 + DPA_ASSERT(dqrr->fill);
142131 + dqrr->cursor = DQRR_INC(dqrr->cursor);
142132 + return --dqrr->fill;
142133 +}
142134 +
142135 +static inline u8 qm_dqrr_pci_update(struct qm_portal *portal)
142136 +{
142137 + register struct qm_dqrr *dqrr = &portal->dqrr;
142138 + u8 diff, old_pi = dqrr->pi;
142139 + DPA_ASSERT(dqrr->pmode == qm_dqrr_pci);
142140 + dqrr->pi = qm_in(DQRR_PI_CINH) & (QM_DQRR_SIZE - 1);
142141 + diff = qm_cyc_diff(QM_DQRR_SIZE, old_pi, dqrr->pi);
142142 + dqrr->fill += diff;
142143 + return diff;
142144 +}
142145 +
142146 +static inline void qm_dqrr_pce_prefetch(struct qm_portal *portal)
142147 +{
142148 + __maybe_unused register struct qm_dqrr *dqrr = &portal->dqrr;
142149 + DPA_ASSERT(dqrr->pmode == qm_dqrr_pce);
142150 + qm_cl_invalidate(DQRR_PI);
142151 + qm_cl_touch_ro(DQRR_PI);
142152 +}
142153 +
142154 +static inline u8 qm_dqrr_pce_update(struct qm_portal *portal)
142155 +{
142156 + register struct qm_dqrr *dqrr = &portal->dqrr;
142157 + u8 diff, old_pi = dqrr->pi;
142158 + DPA_ASSERT(dqrr->pmode == qm_dqrr_pce);
142159 + dqrr->pi = qm_cl_in(DQRR_PI) & (QM_DQRR_SIZE - 1);
142160 + diff = qm_cyc_diff(QM_DQRR_SIZE, old_pi, dqrr->pi);
142161 + dqrr->fill += diff;
142162 + return diff;
142163 +}
142164 +
142165 +static inline void qm_dqrr_pvb_update(struct qm_portal *portal)
142166 +{
142167 + register struct qm_dqrr *dqrr = &portal->dqrr;
142168 + const struct qm_dqrr_entry *res = qm_cl(dqrr->ring, dqrr->pi);
142169 + DPA_ASSERT(dqrr->pmode == qm_dqrr_pvb);
142170 +#if (defined CONFIG_PPC || defined CONFIG_PPC64) && !defined CONFIG_FSL_PAMU
142171 + /*
142172 + * On PowerPC platforms if PAMU is not available we need to
142173 + * manually invalidate the cache. When PAMU is available the
142174 + * cache is updated by stashing operations generated by QMan
142175 + */
142176 + dcbi(res);
142177 + dcbt_ro(res);
142178 +#endif
142179 +
142180 + /* when accessing 'verb', use __raw_readb() to ensure that compiler
142181 + * inlining doesn't try to optimise out "excess reads". */
142182 + if ((__raw_readb(&res->verb) & QM_DQRR_VERB_VBIT) == dqrr->vbit) {
142183 + dqrr->pi = (dqrr->pi + 1) & (QM_DQRR_SIZE - 1);
142184 + if (!dqrr->pi)
142185 + dqrr->vbit ^= QM_DQRR_VERB_VBIT;
142186 + dqrr->fill++;
142187 + }
142188 +}
142189 +
142190 +
142191 +static inline void qm_dqrr_cci_consume_to_current(struct qm_portal *portal)
142192 +{
142193 + register struct qm_dqrr *dqrr = &portal->dqrr;
142194 + DPA_ASSERT(dqrr->cmode == qm_dqrr_cci);
142195 + dqrr->ci = DQRR_PTR2IDX(dqrr->cursor);
142196 + qm_out(DQRR_CI_CINH, dqrr->ci);
142197 +}
142198 +
142199 +static inline void qm_dqrr_cce_prefetch(struct qm_portal *portal)
142200 +{
142201 + __maybe_unused register struct qm_dqrr *dqrr = &portal->dqrr;
142202 + DPA_ASSERT(dqrr->cmode == qm_dqrr_cce);
142203 + qm_cl_invalidate(DQRR_CI);
142204 + qm_cl_touch_rw(DQRR_CI);
142205 +}
142206 +
142207 +static inline void qm_dqrr_cce_consume_to_current(struct qm_portal *portal)
142208 +{
142209 + register struct qm_dqrr *dqrr = &portal->dqrr;
142210 + DPA_ASSERT(dqrr->cmode == qm_dqrr_cce);
142211 + dqrr->ci = DQRR_PTR2IDX(dqrr->cursor);
142212 + qm_cl_out(DQRR_CI, dqrr->ci);
142213 +}
142214 +
142215 +static inline void qm_dqrr_cdc_consume_1(struct qm_portal *portal, u8 idx,
142216 + int park)
142217 +{
142218 + __maybe_unused register struct qm_dqrr *dqrr = &portal->dqrr;
142219 + DPA_ASSERT(dqrr->cmode == qm_dqrr_cdc);
142220 + DPA_ASSERT(idx < QM_DQRR_SIZE);
142221 + qm_out(DQRR_DCAP, (0 << 8) | /* S */
142222 + ((park ? 1 : 0) << 6) | /* PK */
142223 + idx); /* DCAP_CI */
142224 +}
142225 +
142226 +static inline void qm_dqrr_cdc_consume_1ptr(struct qm_portal *portal,
142227 + const struct qm_dqrr_entry *dq,
142228 + int park)
142229 +{
142230 + __maybe_unused register struct qm_dqrr *dqrr = &portal->dqrr;
142231 + u8 idx = DQRR_PTR2IDX(dq);
142232 + DPA_ASSERT(dqrr->cmode == qm_dqrr_cdc);
142233 + DPA_ASSERT((dqrr->ring + idx) == dq);
142234 + DPA_ASSERT(idx < QM_DQRR_SIZE);
142235 + qm_out(DQRR_DCAP, (0 << 8) | /* DQRR_DCAP::S */
142236 + ((park ? 1 : 0) << 6) | /* DQRR_DCAP::PK */
142237 + idx); /* DQRR_DCAP::DCAP_CI */
142238 +}
142239 +
142240 +static inline u8 qm_dqrr_cdc_cci(struct qm_portal *portal)
142241 +{
142242 + __maybe_unused register struct qm_dqrr *dqrr = &portal->dqrr;
142243 + DPA_ASSERT(dqrr->cmode == qm_dqrr_cdc);
142244 + return qm_in(DQRR_CI_CINH) & (QM_DQRR_SIZE - 1);
142245 +}
142246 +
142247 +static inline void qm_dqrr_cdc_cce_prefetch(struct qm_portal *portal)
142248 +{
142249 + __maybe_unused register struct qm_dqrr *dqrr = &portal->dqrr;
142250 + DPA_ASSERT(dqrr->cmode == qm_dqrr_cdc);
142251 + qm_cl_invalidate(DQRR_CI);
142252 + qm_cl_touch_ro(DQRR_CI);
142253 +}
142254 +
142255 +static inline u8 qm_dqrr_cdc_cce(struct qm_portal *portal)
142256 +{
142257 + __maybe_unused register struct qm_dqrr *dqrr = &portal->dqrr;
142258 + DPA_ASSERT(dqrr->cmode == qm_dqrr_cdc);
142259 + return qm_cl_in(DQRR_CI) & (QM_DQRR_SIZE - 1);
142260 +}
142261 +
142262 +static inline u8 qm_dqrr_get_ci(struct qm_portal *portal)
142263 +{
142264 + register struct qm_dqrr *dqrr = &portal->dqrr;
142265 + DPA_ASSERT(dqrr->cmode != qm_dqrr_cdc);
142266 + return dqrr->ci;
142267 +}
142268 +
142269 +static inline void qm_dqrr_park(struct qm_portal *portal, u8 idx)
142270 +{
142271 + __maybe_unused register struct qm_dqrr *dqrr = &portal->dqrr;
142272 + DPA_ASSERT(dqrr->cmode != qm_dqrr_cdc);
142273 + qm_out(DQRR_DCAP, (0 << 8) | /* S */
142274 + (1 << 6) | /* PK */
142275 + (idx & (QM_DQRR_SIZE - 1))); /* DCAP_CI */
142276 +}
142277 +
142278 +static inline void qm_dqrr_park_current(struct qm_portal *portal)
142279 +{
142280 + register struct qm_dqrr *dqrr = &portal->dqrr;
142281 + DPA_ASSERT(dqrr->cmode != qm_dqrr_cdc);
142282 + qm_out(DQRR_DCAP, (0 << 8) | /* S */
142283 + (1 << 6) | /* PK */
142284 + DQRR_PTR2IDX(dqrr->cursor)); /* DCAP_CI */
142285 +}
142286 +
142287 +static inline void qm_dqrr_sdqcr_set(struct qm_portal *portal, u32 sdqcr)
142288 +{
142289 + qm_out(DQRR_SDQCR, sdqcr);
142290 +}
142291 +
142292 +static inline u32 qm_dqrr_sdqcr_get(struct qm_portal *portal)
142293 +{
142294 + return qm_in(DQRR_SDQCR);
142295 +}
142296 +
142297 +static inline void qm_dqrr_vdqcr_set(struct qm_portal *portal, u32 vdqcr)
142298 +{
142299 + qm_out(DQRR_VDQCR, vdqcr);
142300 +}
142301 +
142302 +static inline u32 qm_dqrr_vdqcr_get(struct qm_portal *portal)
142303 +{
142304 + return qm_in(DQRR_VDQCR);
142305 +}
142306 +
142307 +static inline void qm_dqrr_pdqcr_set(struct qm_portal *portal, u32 pdqcr)
142308 +{
142309 + qm_out(DQRR_PDQCR, pdqcr);
142310 +}
142311 +
142312 +static inline u32 qm_dqrr_pdqcr_get(struct qm_portal *portal)
142313 +{
142314 + return qm_in(DQRR_PDQCR);
142315 +}
142316 +
142317 +static inline u8 qm_dqrr_get_ithresh(struct qm_portal *portal)
142318 +{
142319 + register struct qm_dqrr *dqrr = &portal->dqrr;
142320 + return dqrr->ithresh;
142321 +}
142322 +
142323 +static inline void qm_dqrr_set_ithresh(struct qm_portal *portal, u8 ithresh)
142324 +{
142325 + qm_out(DQRR_ITR, ithresh);
142326 +}
142327 +
142328 +static inline u8 qm_dqrr_get_maxfill(struct qm_portal *portal)
142329 +{
142330 + return (qm_in(CFG) & 0x00f00000) >> 20;
142331 +}
142332 +
142333 +
142334 +/* -------------- */
142335 +/* --- MR API --- */
142336 +
142337 +#define MR_CARRYCLEAR(p) \
142338 + (void *)((unsigned long)(p) & (~(unsigned long)(QM_MR_SIZE << 6)))
142339 +
142340 +static inline u8 MR_PTR2IDX(const struct qm_mr_entry *e)
142341 +{
142342 + return ((uintptr_t)e >> 6) & (QM_MR_SIZE - 1);
142343 +}
142344 +
142345 +static inline const struct qm_mr_entry *MR_INC(const struct qm_mr_entry *e)
142346 +{
142347 + return MR_CARRYCLEAR(e + 1);
142348 +}
142349 +
142350 +static inline int qm_mr_init(struct qm_portal *portal, enum qm_mr_pmode pmode,
142351 + enum qm_mr_cmode cmode)
142352 +{
142353 + register struct qm_mr *mr = &portal->mr;
142354 + u32 cfg;
142355 +
142356 + mr->ring = portal->addr.addr_ce + QM_CL_MR;
142357 + mr->pi = qm_in(MR_PI_CINH) & (QM_MR_SIZE - 1);
142358 + mr->ci = qm_in(MR_CI_CINH) & (QM_MR_SIZE - 1);
142359 + mr->cursor = mr->ring + mr->ci;
142360 + mr->fill = qm_cyc_diff(QM_MR_SIZE, mr->ci, mr->pi);
142361 + mr->vbit = (qm_in(MR_PI_CINH) & QM_MR_SIZE) ? QM_MR_VERB_VBIT : 0;
142362 + mr->ithresh = qm_in(MR_ITR);
142363 +#ifdef CONFIG_FSL_DPA_CHECKING
142364 + mr->pmode = pmode;
142365 + mr->cmode = cmode;
142366 +#endif
142367 + cfg = (qm_in(CFG) & 0xfffff0ff) |
142368 + ((cmode & 1) << 8); /* QCSP_CFG:MM */
142369 + qm_out(CFG, cfg);
142370 + return 0;
142371 +}
142372 +
142373 +static inline void qm_mr_finish(struct qm_portal *portal)
142374 +{
142375 + register struct qm_mr *mr = &portal->mr;
142376 + if (mr->ci != MR_PTR2IDX(mr->cursor))
142377 + pr_crit("Ignoring completed MR entries\n");
142378 +}
142379 +
142380 +static inline const struct qm_mr_entry *qm_mr_current(struct qm_portal *portal)
142381 +{
142382 + register struct qm_mr *mr = &portal->mr;
142383 + if (!mr->fill)
142384 + return NULL;
142385 + return mr->cursor;
142386 +}
142387 +
142388 +static inline u8 qm_mr_cursor(struct qm_portal *portal)
142389 +{
142390 + register struct qm_mr *mr = &portal->mr;
142391 + return MR_PTR2IDX(mr->cursor);
142392 +}
142393 +
142394 +static inline u8 qm_mr_next(struct qm_portal *portal)
142395 +{
142396 + register struct qm_mr *mr = &portal->mr;
142397 + DPA_ASSERT(mr->fill);
142398 + mr->cursor = MR_INC(mr->cursor);
142399 + return --mr->fill;
142400 +}
142401 +
142402 +static inline u8 qm_mr_pci_update(struct qm_portal *portal)
142403 +{
142404 + register struct qm_mr *mr = &portal->mr;
142405 + u8 diff, old_pi = mr->pi;
142406 + DPA_ASSERT(mr->pmode == qm_mr_pci);
142407 + mr->pi = qm_in(MR_PI_CINH);
142408 + diff = qm_cyc_diff(QM_MR_SIZE, old_pi, mr->pi);
142409 + mr->fill += diff;
142410 + return diff;
142411 +}
142412 +
142413 +static inline void qm_mr_pce_prefetch(struct qm_portal *portal)
142414 +{
142415 + __maybe_unused register struct qm_mr *mr = &portal->mr;
142416 + DPA_ASSERT(mr->pmode == qm_mr_pce);
142417 + qm_cl_invalidate(MR_PI);
142418 + qm_cl_touch_ro(MR_PI);
142419 +}
142420 +
142421 +static inline u8 qm_mr_pce_update(struct qm_portal *portal)
142422 +{
142423 + register struct qm_mr *mr = &portal->mr;
142424 + u8 diff, old_pi = mr->pi;
142425 + DPA_ASSERT(mr->pmode == qm_mr_pce);
142426 + mr->pi = qm_cl_in(MR_PI) & (QM_MR_SIZE - 1);
142427 + diff = qm_cyc_diff(QM_MR_SIZE, old_pi, mr->pi);
142428 + mr->fill += diff;
142429 + return diff;
142430 +}
142431 +
142432 +static inline void qm_mr_pvb_update(struct qm_portal *portal)
142433 +{
142434 + register struct qm_mr *mr = &portal->mr;
142435 + const struct qm_mr_entry *res = qm_cl(mr->ring, mr->pi);
142436 + DPA_ASSERT(mr->pmode == qm_mr_pvb);
142437 + /* when accessing 'verb', use __raw_readb() to ensure that compiler
142438 + * inlining doesn't try to optimise out "excess reads". */
142439 + if ((__raw_readb(&res->verb) & QM_MR_VERB_VBIT) == mr->vbit) {
142440 + mr->pi = (mr->pi + 1) & (QM_MR_SIZE - 1);
142441 + if (!mr->pi)
142442 + mr->vbit ^= QM_MR_VERB_VBIT;
142443 + mr->fill++;
142444 + res = MR_INC(res);
142445 + }
142446 + dcbit_ro(res);
142447 +}
142448 +
142449 +static inline void qm_mr_cci_consume(struct qm_portal *portal, u8 num)
142450 +{
142451 + register struct qm_mr *mr = &portal->mr;
142452 + DPA_ASSERT(mr->cmode == qm_mr_cci);
142453 + mr->ci = (mr->ci + num) & (QM_MR_SIZE - 1);
142454 + qm_out(MR_CI_CINH, mr->ci);
142455 +}
142456 +
142457 +static inline void qm_mr_cci_consume_to_current(struct qm_portal *portal)
142458 +{
142459 + register struct qm_mr *mr = &portal->mr;
142460 + DPA_ASSERT(mr->cmode == qm_mr_cci);
142461 + mr->ci = MR_PTR2IDX(mr->cursor);
142462 + qm_out(MR_CI_CINH, mr->ci);
142463 +}
142464 +
142465 +static inline void qm_mr_cce_prefetch(struct qm_portal *portal)
142466 +{
142467 + __maybe_unused register struct qm_mr *mr = &portal->mr;
142468 + DPA_ASSERT(mr->cmode == qm_mr_cce);
142469 + qm_cl_invalidate(MR_CI);
142470 + qm_cl_touch_rw(MR_CI);
142471 +}
142472 +
142473 +static inline void qm_mr_cce_consume(struct qm_portal *portal, u8 num)
142474 +{
142475 + register struct qm_mr *mr = &portal->mr;
142476 + DPA_ASSERT(mr->cmode == qm_mr_cce);
142477 + mr->ci = (mr->ci + num) & (QM_MR_SIZE - 1);
142478 + qm_cl_out(MR_CI, mr->ci);
142479 +}
142480 +
142481 +static inline void qm_mr_cce_consume_to_current(struct qm_portal *portal)
142482 +{
142483 + register struct qm_mr *mr = &portal->mr;
142484 + DPA_ASSERT(mr->cmode == qm_mr_cce);
142485 + mr->ci = MR_PTR2IDX(mr->cursor);
142486 + qm_cl_out(MR_CI, mr->ci);
142487 +}
142488 +
142489 +static inline u8 qm_mr_get_ci(struct qm_portal *portal)
142490 +{
142491 + register struct qm_mr *mr = &portal->mr;
142492 + return mr->ci;
142493 +}
142494 +
142495 +static inline u8 qm_mr_get_ithresh(struct qm_portal *portal)
142496 +{
142497 + register struct qm_mr *mr = &portal->mr;
142498 + return mr->ithresh;
142499 +}
142500 +
142501 +static inline void qm_mr_set_ithresh(struct qm_portal *portal, u8 ithresh)
142502 +{
142503 + qm_out(MR_ITR, ithresh);
142504 +}
142505 +
142506 +
142507 +/* ------------------------------ */
142508 +/* --- Management command API --- */
142509 +
142510 +static inline int qm_mc_init(struct qm_portal *portal)
142511 +{
142512 + u8 rr0, rr1;
142513 + register struct qm_mc *mc = &portal->mc;
142514 +
142515 + mc->cr = portal->addr.addr_ce + QM_CL_CR;
142516 + mc->rr = portal->addr.addr_ce + QM_CL_RR0;
142517 +
142518 + /*
142519 + * The expected valid bit polarity for the next CR command is 0
142520 + * if RR1 contains a valid response, and is 1 if RR0 contains a
142521 + * valid response. If both RR contain all 0, this indicates either
142522 + * that no command has been executed since reset (in which case the
142523 + * expected valid bit polarity is 1)
142524 + */
142525 + rr0 = __raw_readb(&mc->rr->verb);
142526 + rr1 = __raw_readb(&(mc->rr+1)->verb);
142527 + if ((rr0 == 0 && rr1 == 0) || rr0 != 0)
142528 + mc->rridx = 1;
142529 + else
142530 + mc->rridx = 0;
142531 +
142532 + mc->vbit = mc->rridx ? QM_MCC_VERB_VBIT : 0;
142533 +#ifdef CONFIG_FSL_DPA_CHECKING
142534 + mc->state = qman_mc_idle;
142535 +#endif
142536 + return 0;
142537 +}
142538 +
142539 +static inline void qm_mc_finish(struct qm_portal *portal)
142540 +{
142541 + __maybe_unused register struct qm_mc *mc = &portal->mc;
142542 + DPA_ASSERT(mc->state == qman_mc_idle);
142543 +#ifdef CONFIG_FSL_DPA_CHECKING
142544 + if (mc->state != qman_mc_idle)
142545 + pr_crit("Losing incomplete MC command\n");
142546 +#endif
142547 +}
142548 +
142549 +static inline struct qm_mc_command *qm_mc_start(struct qm_portal *portal)
142550 +{
142551 + register struct qm_mc *mc = &portal->mc;
142552 + DPA_ASSERT(mc->state == qman_mc_idle);
142553 +#ifdef CONFIG_FSL_DPA_CHECKING
142554 + mc->state = qman_mc_user;
142555 +#endif
142556 +#if defined(CONFIG_PPC32) || defined(CONFIG_PPC64)
142557 + dcbz_64(mc->cr);
142558 +#endif
142559 + return mc->cr;
142560 +}
142561 +
142562 +static inline void qm_mc_abort(struct qm_portal *portal)
142563 +{
142564 + __maybe_unused register struct qm_mc *mc = &portal->mc;
142565 + DPA_ASSERT(mc->state == qman_mc_user);
142566 +#ifdef CONFIG_FSL_DPA_CHECKING
142567 + mc->state = qman_mc_idle;
142568 +#endif
142569 +}
142570 +
142571 +static inline void qm_mc_commit(struct qm_portal *portal, u8 myverb)
142572 +{
142573 + register struct qm_mc *mc = &portal->mc;
142574 + struct qm_mc_result *rr = mc->rr + mc->rridx;
142575 + DPA_ASSERT(mc->state == qman_mc_user);
142576 + lwsync();
142577 + mc->cr->__dont_write_directly__verb = myverb | mc->vbit;
142578 + dcbf(mc->cr);
142579 + dcbit_ro(rr);
142580 +#ifdef CONFIG_FSL_DPA_CHECKING
142581 + mc->state = qman_mc_hw;
142582 +#endif
142583 +}
142584 +
142585 +static inline struct qm_mc_result *qm_mc_result(struct qm_portal *portal)
142586 +{
142587 + register struct qm_mc *mc = &portal->mc;
142588 + struct qm_mc_result *rr = mc->rr + mc->rridx;
142589 + DPA_ASSERT(mc->state == qman_mc_hw);
142590 + /* The inactive response register's verb byte always returns zero until
142591 + * its command is submitted and completed. This includes the valid-bit,
142592 + * in case you were wondering... */
142593 + if (!__raw_readb(&rr->verb)) {
142594 + dcbit_ro(rr);
142595 + return NULL;
142596 + }
142597 + mc->rridx ^= 1;
142598 + mc->vbit ^= QM_MCC_VERB_VBIT;
142599 +#ifdef CONFIG_FSL_DPA_CHECKING
142600 + mc->state = qman_mc_idle;
142601 +#endif
142602 + return rr;
142603 +}
142604 +
142605 +
142606 +/* ------------------------------------- */
142607 +/* --- Portal interrupt register API --- */
142608 +
142609 +static inline int qm_isr_init(__always_unused struct qm_portal *portal)
142610 +{
142611 + return 0;
142612 +}
142613 +
142614 +static inline void qm_isr_finish(__always_unused struct qm_portal *portal)
142615 +{
142616 +}
142617 +
142618 +static inline void qm_isr_set_iperiod(struct qm_portal *portal, u16 iperiod)
142619 +{
142620 + qm_out(ITPR, iperiod);
142621 +}
142622 +
142623 +static inline u32 __qm_isr_read(struct qm_portal *portal, enum qm_isr_reg n)
142624 +{
142625 +#if defined(CONFIG_ARM) || defined(CONFIG_ARM64)
142626 + return __qm_in(&portal->addr, QM_REG_ISR + (n << 6));
142627 +#else
142628 + return __qm_in(&portal->addr, QM_REG_ISR + (n << 2));
142629 +#endif
142630 +}
142631 +
142632 +static inline void __qm_isr_write(struct qm_portal *portal, enum qm_isr_reg n,
142633 + u32 val)
142634 +{
142635 +#if defined(CONFIG_ARM) || defined(CONFIG_ARM64)
142636 + __qm_out(&portal->addr, QM_REG_ISR + (n << 6), val);
142637 +#else
142638 + __qm_out(&portal->addr, QM_REG_ISR + (n << 2), val);
142639 +#endif
142640 +}
142641 +
142642 +/* Cleanup FQs */
142643 +static inline int qm_shutdown_fq(struct qm_portal **portal, int portal_count,
142644 + u32 fqid)
142645 +{
142646 +
142647 + struct qm_mc_command *mcc;
142648 + struct qm_mc_result *mcr;
142649 + u8 state;
142650 + int orl_empty, fq_empty, i, drain = 0;
142651 + u32 result;
142652 + u32 channel, wq;
142653 + u16 dest_wq;
142654 +
142655 + /* Determine the state of the FQID */
142656 + mcc = qm_mc_start(portal[0]);
142657 + mcc->queryfq_np.fqid = cpu_to_be32(fqid);
142658 + qm_mc_commit(portal[0], QM_MCC_VERB_QUERYFQ_NP);
142659 + while (!(mcr = qm_mc_result(portal[0])))
142660 + cpu_relax();
142661 + DPA_ASSERT((mcr->verb & QM_MCR_VERB_MASK) == QM_MCR_VERB_QUERYFQ_NP);
142662 + state = mcr->queryfq_np.state & QM_MCR_NP_STATE_MASK;
142663 + if (state == QM_MCR_NP_STATE_OOS)
142664 + return 0; /* Already OOS, no need to do anymore checks */
142665 +
142666 + /* Query which channel the FQ is using */
142667 + mcc = qm_mc_start(portal[0]);
142668 + mcc->queryfq.fqid = cpu_to_be32(fqid);
142669 + qm_mc_commit(portal[0], QM_MCC_VERB_QUERYFQ);
142670 + while (!(mcr = qm_mc_result(portal[0])))
142671 + cpu_relax();
142672 + DPA_ASSERT((mcr->verb & QM_MCR_VERB_MASK) == QM_MCR_VERB_QUERYFQ);
142673 +
142674 + /* Need to store these since the MCR gets reused */
142675 + dest_wq = be16_to_cpu(mcr->queryfq.fqd.dest_wq);
142676 + wq = dest_wq & 0x7;
142677 + channel = dest_wq>>3;
142678 +
142679 + switch (state) {
142680 + case QM_MCR_NP_STATE_TEN_SCHED:
142681 + case QM_MCR_NP_STATE_TRU_SCHED:
142682 + case QM_MCR_NP_STATE_ACTIVE:
142683 + case QM_MCR_NP_STATE_PARKED:
142684 + orl_empty = 0;
142685 + mcc = qm_mc_start(portal[0]);
142686 + mcc->alterfq.fqid = cpu_to_be32(fqid);
142687 + qm_mc_commit(portal[0], QM_MCC_VERB_ALTER_RETIRE);
142688 + while (!(mcr = qm_mc_result(portal[0])))
142689 + cpu_relax();
142690 + DPA_ASSERT((mcr->verb & QM_MCR_VERB_MASK) ==
142691 + QM_MCR_VERB_ALTER_RETIRE);
142692 + result = mcr->result; /* Make a copy as we reuse MCR below */
142693 +
142694 + if (result == QM_MCR_RESULT_PENDING) {
142695 + /* Need to wait for the FQRN in the message ring, which
142696 + will only occur once the FQ has been drained. In
142697 + order for the FQ to drain the portal needs to be set
142698 + to dequeue from the channel the FQ is scheduled on */
142699 + const struct qm_mr_entry *msg;
142700 + const struct qm_dqrr_entry *dqrr = NULL;
142701 + int found_fqrn = 0;
142702 + u16 dequeue_wq = 0;
142703 +
142704 + /* Flag that we need to drain FQ */
142705 + drain = 1;
142706 +
142707 + if (channel >= qm_channel_pool1 &&
142708 + channel < (qm_channel_pool1 + 15)) {
142709 + /* Pool channel, enable the bit in the portal */
142710 + dequeue_wq = (channel -
142711 + qm_channel_pool1 + 1)<<4 | wq;
142712 + } else if (channel < qm_channel_pool1) {
142713 + /* Dedicated channel */
142714 + dequeue_wq = wq;
142715 + } else {
142716 + pr_info("Cannot recover FQ 0x%x, it is "
142717 + "scheduled on channel 0x%x",
142718 + fqid, channel);
142719 + return -EBUSY;
142720 + }
142721 + /* Set the sdqcr to drain this channel */
142722 + if (channel < qm_channel_pool1)
142723 + for (i = 0; i < portal_count; i++)
142724 + qm_dqrr_sdqcr_set(portal[i],
142725 + QM_SDQCR_TYPE_ACTIVE |
142726 + QM_SDQCR_CHANNELS_DEDICATED);
142727 + else
142728 + for (i = 0; i < portal_count; i++)
142729 + qm_dqrr_sdqcr_set(
142730 + portal[i],
142731 + QM_SDQCR_TYPE_ACTIVE |
142732 + QM_SDQCR_CHANNELS_POOL_CONV
142733 + (channel));
142734 + while (!found_fqrn) {
142735 + /* Keep draining DQRR while checking the MR*/
142736 + for (i = 0; i < portal_count; i++) {
142737 + qm_dqrr_pvb_update(portal[i]);
142738 + dqrr = qm_dqrr_current(portal[i]);
142739 + while (dqrr) {
142740 + qm_dqrr_cdc_consume_1ptr(
142741 + portal[i], dqrr, 0);
142742 + qm_dqrr_pvb_update(portal[i]);
142743 + qm_dqrr_next(portal[i]);
142744 + dqrr = qm_dqrr_current(
142745 + portal[i]);
142746 + }
142747 + /* Process message ring too */
142748 + qm_mr_pvb_update(portal[i]);
142749 + msg = qm_mr_current(portal[i]);
142750 + while (msg) {
142751 + if ((msg->verb &
142752 + QM_MR_VERB_TYPE_MASK)
142753 + == QM_MR_VERB_FQRN)
142754 + found_fqrn = 1;
142755 + qm_mr_next(portal[i]);
142756 + qm_mr_cci_consume_to_current(
142757 + portal[i]);
142758 + qm_mr_pvb_update(portal[i]);
142759 + msg = qm_mr_current(portal[i]);
142760 + }
142761 + cpu_relax();
142762 + }
142763 + }
142764 + }
142765 + if (result != QM_MCR_RESULT_OK &&
142766 + result != QM_MCR_RESULT_PENDING) {
142767 + /* error */
142768 + pr_err("qman_retire_fq failed on FQ 0x%x, result=0x%x\n",
142769 + fqid, result);
142770 + return -1;
142771 + }
142772 + if (!(mcr->alterfq.fqs & QM_MCR_FQS_ORLPRESENT)) {
142773 + /* ORL had no entries, no need to wait until the
142774 + ERNs come in */
142775 + orl_empty = 1;
142776 + }
142777 + /* Retirement succeeded, check to see if FQ needs
142778 + to be drained */
142779 + if (drain || mcr->alterfq.fqs & QM_MCR_FQS_NOTEMPTY) {
142780 + /* FQ is Not Empty, drain using volatile DQ commands */
142781 + fq_empty = 0;
142782 + do {
142783 + const struct qm_dqrr_entry *dqrr = NULL;
142784 + u32 vdqcr = fqid | QM_VDQCR_NUMFRAMES_SET(3);
142785 + qm_dqrr_vdqcr_set(portal[0], vdqcr);
142786 +
142787 + /* Wait for a dequeue to occur */
142788 + while (dqrr == NULL) {
142789 + qm_dqrr_pvb_update(portal[0]);
142790 + dqrr = qm_dqrr_current(portal[0]);
142791 + if (!dqrr)
142792 + cpu_relax();
142793 + }
142794 + /* Process the dequeues, making sure to
142795 + empty the ring completely */
142796 + while (dqrr) {
142797 + if (be32_to_cpu(dqrr->fqid) == fqid &&
142798 + dqrr->stat & QM_DQRR_STAT_FQ_EMPTY)
142799 + fq_empty = 1;
142800 + qm_dqrr_cdc_consume_1ptr(portal[0],
142801 + dqrr, 0);
142802 + qm_dqrr_pvb_update(portal[0]);
142803 + qm_dqrr_next(portal[0]);
142804 + dqrr = qm_dqrr_current(portal[0]);
142805 + }
142806 + } while (fq_empty == 0);
142807 + }
142808 + for (i = 0; i < portal_count; i++)
142809 + qm_dqrr_sdqcr_set(portal[i], 0);
142810 +
142811 + /* Wait for the ORL to have been completely drained */
142812 + while (orl_empty == 0) {
142813 + const struct qm_mr_entry *msg;
142814 + qm_mr_pvb_update(portal[0]);
142815 + msg = qm_mr_current(portal[0]);
142816 + while (msg) {
142817 + if ((msg->verb & QM_MR_VERB_TYPE_MASK) ==
142818 + QM_MR_VERB_FQRL)
142819 + orl_empty = 1;
142820 + qm_mr_next(portal[0]);
142821 + qm_mr_cci_consume_to_current(portal[0]);
142822 + qm_mr_pvb_update(portal[0]);
142823 + msg = qm_mr_current(portal[0]);
142824 + }
142825 + cpu_relax();
142826 + }
142827 + mcc = qm_mc_start(portal[0]);
142828 + mcc->alterfq.fqid = cpu_to_be32(fqid);
142829 + qm_mc_commit(portal[0], QM_MCC_VERB_ALTER_OOS);
142830 + while (!(mcr = qm_mc_result(portal[0])))
142831 + cpu_relax();
142832 + DPA_ASSERT((mcr->verb & QM_MCR_VERB_MASK) ==
142833 + QM_MCR_VERB_ALTER_OOS);
142834 + if (mcr->result != QM_MCR_RESULT_OK) {
142835 + pr_err("OOS after drain Failed on FQID 0x%x, result 0x%x\n",
142836 + fqid, mcr->result);
142837 + return -1;
142838 + }
142839 + return 0;
142840 + case QM_MCR_NP_STATE_RETIRED:
142841 + /* Send OOS Command */
142842 + mcc = qm_mc_start(portal[0]);
142843 + mcc->alterfq.fqid = cpu_to_be32(fqid);
142844 + qm_mc_commit(portal[0], QM_MCC_VERB_ALTER_OOS);
142845 + while (!(mcr = qm_mc_result(portal[0])))
142846 + cpu_relax();
142847 + DPA_ASSERT((mcr->verb & QM_MCR_VERB_MASK) ==
142848 + QM_MCR_VERB_ALTER_OOS);
142849 + if (mcr->result) {
142850 + pr_err("OOS Failed on FQID 0x%x\n", fqid);
142851 + return -1;
142852 + }
142853 + return 0;
142854 + }
142855 + return -1;
142856 +}
142857 --- /dev/null
142858 +++ b/drivers/staging/fsl_qbman/qman_private.h
142859 @@ -0,0 +1,398 @@
142860 +/* Copyright 2008-2012 Freescale Semiconductor, Inc.
142861 + *
142862 + * Redistribution and use in source and binary forms, with or without
142863 + * modification, are permitted provided that the following conditions are met:
142864 + * * Redistributions of source code must retain the above copyright
142865 + * notice, this list of conditions and the following disclaimer.
142866 + * * Redistributions in binary form must reproduce the above copyright
142867 + * notice, this list of conditions and the following disclaimer in the
142868 + * documentation and/or other materials provided with the distribution.
142869 + * * Neither the name of Freescale Semiconductor nor the
142870 + * names of its contributors may be used to endorse or promote products
142871 + * derived from this software without specific prior written permission.
142872 + *
142873 + *
142874 + * ALTERNATIVELY, this software may be distributed under the terms of the
142875 + * GNU General Public License ("GPL") as published by the Free Software
142876 + * Foundation, either version 2 of that License or (at your option) any
142877 + * later version.
142878 + *
142879 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
142880 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
142881 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
142882 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
142883 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
142884 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
142885 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
142886 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
142887 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
142888 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
142889 + */
142890 +
142891 +#include "dpa_sys.h"
142892 +#include <linux/fsl_qman.h>
142893 +#include <linux/iommu.h>
142894 +
142895 +#if defined(CONFIG_FSL_PAMU)
142896 +#include <asm/fsl_pamu_stash.h>
142897 +#endif
142898 +
142899 +#if !defined(CONFIG_FSL_QMAN_FQ_LOOKUP) && defined(CONFIG_PPC64)
142900 +#error "_PPC64 requires _FSL_QMAN_FQ_LOOKUP"
142901 +#endif
142902 +
142903 +#define QBMAN_ANY_PORTAL_IDX 0xffffffff
142904 + /* ----------------- */
142905 + /* Congestion Groups */
142906 + /* ----------------- */
142907 +/* This wrapper represents a bit-array for the state of the 256 Qman congestion
142908 + * groups. Is also used as a *mask* for congestion groups, eg. so we ignore
142909 + * those that don't concern us. We harness the structure and accessor details
142910 + * already used in the management command to query congestion groups. */
142911 +struct qman_cgrs {
142912 + struct __qm_mcr_querycongestion q;
142913 +};
142914 +static inline void qman_cgrs_init(struct qman_cgrs *c)
142915 +{
142916 + memset(c, 0, sizeof(*c));
142917 +}
142918 +static inline void qman_cgrs_fill(struct qman_cgrs *c)
142919 +{
142920 + memset(c, 0xff, sizeof(*c));
142921 +}
142922 +static inline int qman_cgrs_get(struct qman_cgrs *c, int num)
142923 +{
142924 + return QM_MCR_QUERYCONGESTION(&c->q, num);
142925 +}
142926 +static inline void qman_cgrs_set(struct qman_cgrs *c, int num)
142927 +{
142928 + c->q.__state[__CGR_WORD(num)] |= (0x80000000 >> __CGR_SHIFT(num));
142929 +}
142930 +static inline void qman_cgrs_unset(struct qman_cgrs *c, int num)
142931 +{
142932 + c->q.__state[__CGR_WORD(num)] &= ~(0x80000000 >> __CGR_SHIFT(num));
142933 +}
142934 +static inline int qman_cgrs_next(struct qman_cgrs *c, int num)
142935 +{
142936 + while ((++num < __CGR_NUM) && !qman_cgrs_get(c, num))
142937 + ;
142938 + return num;
142939 +}
142940 +static inline void qman_cgrs_cp(struct qman_cgrs *dest,
142941 + const struct qman_cgrs *src)
142942 +{
142943 + *dest = *src;
142944 +}
142945 +static inline void qman_cgrs_and(struct qman_cgrs *dest,
142946 + const struct qman_cgrs *a, const struct qman_cgrs *b)
142947 +{
142948 + int ret;
142949 + u32 *_d = dest->q.__state;
142950 + const u32 *_a = a->q.__state;
142951 + const u32 *_b = b->q.__state;
142952 + for (ret = 0; ret < 8; ret++)
142953 + *(_d++) = *(_a++) & *(_b++);
142954 +}
142955 +static inline void qman_cgrs_xor(struct qman_cgrs *dest,
142956 + const struct qman_cgrs *a, const struct qman_cgrs *b)
142957 +{
142958 + int ret;
142959 + u32 *_d = dest->q.__state;
142960 + const u32 *_a = a->q.__state;
142961 + const u32 *_b = b->q.__state;
142962 + for (ret = 0; ret < 8; ret++)
142963 + *(_d++) = *(_a++) ^ *(_b++);
142964 +}
142965 +
142966 + /* ----------------------- */
142967 + /* CEETM Congestion Groups */
142968 + /* ----------------------- */
142969 +/* This wrapper represents a bit-array for the state of the 512 Qman CEETM
142970 + * congestion groups.
142971 + */
142972 +struct qman_ccgrs {
142973 + struct __qm_mcr_querycongestion q[2];
142974 +};
142975 +static inline void qman_ccgrs_init(struct qman_ccgrs *c)
142976 +{
142977 + memset(c, 0, sizeof(*c));
142978 +}
142979 +static inline void qman_ccgrs_fill(struct qman_ccgrs *c)
142980 +{
142981 + memset(c, 0xff, sizeof(*c));
142982 +}
142983 +static inline int qman_ccgrs_get(struct qman_ccgrs *c, int num)
142984 +{
142985 + if (num < __CGR_NUM)
142986 + return QM_MCR_QUERYCONGESTION(&c->q[0], num);
142987 + else
142988 + return QM_MCR_QUERYCONGESTION(&c->q[1], (num - __CGR_NUM));
142989 +}
142990 +static inline int qman_ccgrs_next(struct qman_ccgrs *c, int num)
142991 +{
142992 + while ((++num < __CGR_NUM) && !qman_ccgrs_get(c, num))
142993 + ;
142994 + return num;
142995 +}
142996 +static inline void qman_ccgrs_cp(struct qman_ccgrs *dest,
142997 + const struct qman_ccgrs *src)
142998 +{
142999 + *dest = *src;
143000 +}
143001 +static inline void qman_ccgrs_and(struct qman_ccgrs *dest,
143002 + const struct qman_ccgrs *a, const struct qman_ccgrs *b)
143003 +{
143004 + int ret, i;
143005 + u32 *_d;
143006 + const u32 *_a, *_b;
143007 + for (i = 0; i < 2; i++) {
143008 + _d = dest->q[i].__state;
143009 + _a = a->q[i].__state;
143010 + _b = b->q[i].__state;
143011 + for (ret = 0; ret < 8; ret++)
143012 + *(_d++) = *(_a++) & *(_b++);
143013 + }
143014 +}
143015 +static inline void qman_ccgrs_xor(struct qman_ccgrs *dest,
143016 + const struct qman_ccgrs *a, const struct qman_ccgrs *b)
143017 +{
143018 + int ret, i;
143019 + u32 *_d;
143020 + const u32 *_a, *_b;
143021 + for (i = 0; i < 2; i++) {
143022 + _d = dest->q[i].__state;
143023 + _a = a->q[i].__state;
143024 + _b = b->q[i].__state;
143025 + for (ret = 0; ret < 8; ret++)
143026 + *(_d++) = *(_a++) ^ *(_b++);
143027 + }
143028 +}
143029 +
143030 +/* used by CCSR and portal interrupt code */
143031 +enum qm_isr_reg {
143032 + qm_isr_status = 0,
143033 + qm_isr_enable = 1,
143034 + qm_isr_disable = 2,
143035 + qm_isr_inhibit = 3
143036 +};
143037 +
143038 +struct qm_portal_config {
143039 + /* Corenet portal addresses;
143040 + * [0]==cache-enabled, [1]==cache-inhibited. */
143041 + __iomem void *addr_virt[2];
143042 + struct resource addr_phys[2];
143043 + struct device dev;
143044 + struct iommu_domain *iommu_domain;
143045 + /* Allow these to be joined in lists */
143046 + struct list_head list;
143047 + /* User-visible portal configuration settings */
143048 + struct qman_portal_config public_cfg;
143049 + /* power management saved data */
143050 + u32 saved_isdr;
143051 +};
143052 +
143053 +/* Revision info (for errata and feature handling) */
143054 +#define QMAN_REV11 0x0101
143055 +#define QMAN_REV12 0x0102
143056 +#define QMAN_REV20 0x0200
143057 +#define QMAN_REV30 0x0300
143058 +#define QMAN_REV31 0x0301
143059 +#define QMAN_REV32 0x0302
143060 +
143061 +/* QMan REV_2 register contains the Cfg option */
143062 +#define QMAN_REV_CFG_0 0x0
143063 +#define QMAN_REV_CFG_1 0x1
143064 +#define QMAN_REV_CFG_2 0x2
143065 +#define QMAN_REV_CFG_3 0x3
143066 +
143067 +extern u16 qman_ip_rev; /* 0 if uninitialised, otherwise QMAN_REVx */
143068 +extern u8 qman_ip_cfg;
143069 +extern u32 qman_clk;
143070 +extern u16 qman_portal_max;
143071 +
143072 +#ifdef CONFIG_FSL_QMAN_CONFIG
143073 +/* Hooks from qman_driver.c to qman_config.c */
143074 +int qman_init_ccsr(struct device_node *node);
143075 +void qman_liodn_fixup(u16 channel);
143076 +int qman_set_sdest(u16 channel, unsigned int cpu_idx);
143077 +size_t get_qman_fqd_size(void);
143078 +#else
143079 +static inline size_t get_qman_fqd_size(void)
143080 +{
143081 + return (PAGE_SIZE << CONFIG_FSL_QMAN_FQD_SZ);
143082 +}
143083 +#endif
143084 +
143085 +int qm_set_wpm(int wpm);
143086 +int qm_get_wpm(int *wpm);
143087 +
143088 +/* Hooks from qman_driver.c in to qman_high.c */
143089 +struct qman_portal *qman_create_portal(
143090 + struct qman_portal *portal,
143091 + const struct qm_portal_config *config,
143092 + const struct qman_cgrs *cgrs);
143093 +
143094 +struct qman_portal *qman_create_affine_portal(
143095 + const struct qm_portal_config *config,
143096 + const struct qman_cgrs *cgrs);
143097 +struct qman_portal *qman_create_affine_slave(struct qman_portal *redirect,
143098 + int cpu);
143099 +const struct qm_portal_config *qman_destroy_affine_portal(void);
143100 +void qman_destroy_portal(struct qman_portal *qm);
143101 +
143102 +/* Hooks from fsl_usdpaa.c to qman_driver.c */
143103 +struct qm_portal_config *qm_get_unused_portal(void);
143104 +struct qm_portal_config *qm_get_unused_portal_idx(uint32_t idx);
143105 +
143106 +void qm_put_unused_portal(struct qm_portal_config *pcfg);
143107 +void qm_set_liodns(struct qm_portal_config *pcfg);
143108 +
143109 +/* This CGR feature is supported by h/w and required by unit-tests and the
143110 + * debugfs hooks, so is implemented in the driver. However it allows an explicit
143111 + * corruption of h/w fields by s/w that are usually incorruptible (because the
143112 + * counters are usually maintained entirely within h/w). As such, we declare
143113 + * this API internally. */
143114 +int qman_testwrite_cgr(struct qman_cgr *cgr, u64 i_bcnt,
143115 + struct qm_mcr_cgrtestwrite *result);
143116 +
143117 +#ifdef CONFIG_FSL_QMAN_FQ_LOOKUP
143118 +/* If the fq object pointer is greater than the size of context_b field,
143119 + * than a lookup table is required. */
143120 +int qman_setup_fq_lookup_table(size_t num_entries);
143121 +#endif
143122 +
143123 +
143124 +/*************************************************/
143125 +/* QMan s/w corenet portal, low-level i/face */
143126 +/*************************************************/
143127 +
143128 +/* Note: most functions are only used by the high-level interface, so are
143129 + * inlined from qman_low.h. The stuff below is for use by other parts of the
143130 + * driver. */
143131 +
143132 +/* For qm_dqrr_sdqcr_set(); Choose one SOURCE. Choose one COUNT. Choose one
143133 + * dequeue TYPE. Choose TOKEN (8-bit).
143134 + * If SOURCE == CHANNELS,
143135 + * Choose CHANNELS_DEDICATED and/or CHANNELS_POOL(n).
143136 + * You can choose DEDICATED_PRECEDENCE if the portal channel should have
143137 + * priority.
143138 + * If SOURCE == SPECIFICWQ,
143139 + * Either select the work-queue ID with SPECIFICWQ_WQ(), or select the
143140 + * channel (SPECIFICWQ_DEDICATED or SPECIFICWQ_POOL()) and specify the
143141 + * work-queue priority (0-7) with SPECIFICWQ_WQ() - either way, you get the
143142 + * same value.
143143 + */
143144 +#define QM_SDQCR_SOURCE_CHANNELS 0x0
143145 +#define QM_SDQCR_SOURCE_SPECIFICWQ 0x40000000
143146 +#define QM_SDQCR_COUNT_EXACT1 0x0
143147 +#define QM_SDQCR_COUNT_UPTO3 0x20000000
143148 +#define QM_SDQCR_DEDICATED_PRECEDENCE 0x10000000
143149 +#define QM_SDQCR_TYPE_MASK 0x03000000
143150 +#define QM_SDQCR_TYPE_NULL 0x0
143151 +#define QM_SDQCR_TYPE_PRIO_QOS 0x01000000
143152 +#define QM_SDQCR_TYPE_ACTIVE_QOS 0x02000000
143153 +#define QM_SDQCR_TYPE_ACTIVE 0x03000000
143154 +#define QM_SDQCR_TOKEN_MASK 0x00ff0000
143155 +#define QM_SDQCR_TOKEN_SET(v) (((v) & 0xff) << 16)
143156 +#define QM_SDQCR_TOKEN_GET(v) (((v) >> 16) & 0xff)
143157 +#define QM_SDQCR_CHANNELS_DEDICATED 0x00008000
143158 +#define QM_SDQCR_SPECIFICWQ_MASK 0x000000f7
143159 +#define QM_SDQCR_SPECIFICWQ_DEDICATED 0x00000000
143160 +#define QM_SDQCR_SPECIFICWQ_POOL(n) ((n) << 4)
143161 +#define QM_SDQCR_SPECIFICWQ_WQ(n) (n)
143162 +
143163 +/* For qm_dqrr_vdqcr_set(): use FQID(n) to fill in the frame queue ID */
143164 +#define QM_VDQCR_FQID_MASK 0x00ffffff
143165 +#define QM_VDQCR_FQID(n) ((n) & QM_VDQCR_FQID_MASK)
143166 +
143167 +/* For qm_dqrr_pdqcr_set(); Choose one MODE. Choose one COUNT.
143168 + * If MODE==SCHEDULED
143169 + * Choose SCHEDULED_CHANNELS or SCHEDULED_SPECIFICWQ. Choose one dequeue TYPE.
143170 + * If CHANNELS,
143171 + * Choose CHANNELS_DEDICATED and/or CHANNELS_POOL() channels.
143172 + * You can choose DEDICATED_PRECEDENCE if the portal channel should have
143173 + * priority.
143174 + * If SPECIFICWQ,
143175 + * Either select the work-queue ID with SPECIFICWQ_WQ(), or select the
143176 + * channel (SPECIFICWQ_DEDICATED or SPECIFICWQ_POOL()) and specify the
143177 + * work-queue priority (0-7) with SPECIFICWQ_WQ() - either way, you get the
143178 + * same value.
143179 + * If MODE==UNSCHEDULED
143180 + * Choose FQID().
143181 + */
143182 +#define QM_PDQCR_MODE_SCHEDULED 0x0
143183 +#define QM_PDQCR_MODE_UNSCHEDULED 0x80000000
143184 +#define QM_PDQCR_SCHEDULED_CHANNELS 0x0
143185 +#define QM_PDQCR_SCHEDULED_SPECIFICWQ 0x40000000
143186 +#define QM_PDQCR_COUNT_EXACT1 0x0
143187 +#define QM_PDQCR_COUNT_UPTO3 0x20000000
143188 +#define QM_PDQCR_DEDICATED_PRECEDENCE 0x10000000
143189 +#define QM_PDQCR_TYPE_MASK 0x03000000
143190 +#define QM_PDQCR_TYPE_NULL 0x0
143191 +#define QM_PDQCR_TYPE_PRIO_QOS 0x01000000
143192 +#define QM_PDQCR_TYPE_ACTIVE_QOS 0x02000000
143193 +#define QM_PDQCR_TYPE_ACTIVE 0x03000000
143194 +#define QM_PDQCR_CHANNELS_DEDICATED 0x00008000
143195 +#define QM_PDQCR_CHANNELS_POOL(n) (0x00008000 >> (n))
143196 +#define QM_PDQCR_SPECIFICWQ_MASK 0x000000f7
143197 +#define QM_PDQCR_SPECIFICWQ_DEDICATED 0x00000000
143198 +#define QM_PDQCR_SPECIFICWQ_POOL(n) ((n) << 4)
143199 +#define QM_PDQCR_SPECIFICWQ_WQ(n) (n)
143200 +#define QM_PDQCR_FQID(n) ((n) & 0xffffff)
143201 +
143202 +/* Used by all portal interrupt registers except 'inhibit'
143203 + * Channels with frame availability
143204 + */
143205 +#define QM_PIRQ_DQAVAIL 0x0000ffff
143206 +
143207 +/* The DQAVAIL interrupt fields break down into these bits; */
143208 +#define QM_DQAVAIL_PORTAL 0x8000 /* Portal channel */
143209 +#define QM_DQAVAIL_POOL(n) (0x8000 >> (n)) /* Pool channel, n==[1..15] */
143210 +#define QM_DQAVAIL_MASK 0xffff
143211 +/* This mask contains all the "irqsource" bits visible to API users */
143212 +#define QM_PIRQ_VISIBLE (QM_PIRQ_SLOW | QM_PIRQ_DQRI)
143213 +
143214 +/* These are qm_<reg>_<verb>(). So for example, qm_disable_write() means "write
143215 + * the disable register" rather than "disable the ability to write". */
143216 +#define qm_isr_status_read(qm) __qm_isr_read(qm, qm_isr_status)
143217 +#define qm_isr_status_clear(qm, m) __qm_isr_write(qm, qm_isr_status, m)
143218 +#define qm_isr_enable_read(qm) __qm_isr_read(qm, qm_isr_enable)
143219 +#define qm_isr_enable_write(qm, v) __qm_isr_write(qm, qm_isr_enable, v)
143220 +#define qm_isr_disable_read(qm) __qm_isr_read(qm, qm_isr_disable)
143221 +#define qm_isr_disable_write(qm, v) __qm_isr_write(qm, qm_isr_disable, v)
143222 +/* TODO: unfortunate name-clash here, reword? */
143223 +#define qm_isr_inhibit(qm) __qm_isr_write(qm, qm_isr_inhibit, 1)
143224 +#define qm_isr_uninhibit(qm) __qm_isr_write(qm, qm_isr_inhibit, 0)
143225 +
143226 +#ifdef CONFIG_FSL_QMAN_CONFIG
143227 +int qman_have_ccsr(void);
143228 +#else
143229 +#define qman_have_ccsr 0
143230 +#endif
143231 +
143232 +__init int qman_init(void);
143233 +__init int qman_resource_init(void);
143234 +
143235 +/* CEETM related */
143236 +#define QMAN_CEETM_MAX 2
143237 +extern u8 num_ceetms;
143238 +extern struct qm_ceetm qman_ceetms[QMAN_CEETM_MAX];
143239 +int qman_sp_enable_ceetm_mode(enum qm_dc_portal portal, u16 sub_portal);
143240 +int qman_sp_disable_ceetm_mode(enum qm_dc_portal portal, u16 sub_portal);
143241 +int qman_ceetm_set_prescaler(enum qm_dc_portal portal);
143242 +int qman_ceetm_get_prescaler(u16 *pres);
143243 +int qman_ceetm_query_cq(unsigned int cqid, unsigned int dcpid,
143244 + struct qm_mcr_ceetm_cq_query *cq_query);
143245 +int qman_ceetm_query_ccgr(struct qm_mcc_ceetm_ccgr_query *ccgr_query,
143246 + struct qm_mcr_ceetm_ccgr_query *response);
143247 +int qman_ceetm_get_xsfdr(enum qm_dc_portal portal, unsigned int *num);
143248 +
143249 +extern void *affine_portals[NR_CPUS];
143250 +const struct qm_portal_config *qman_get_qm_portal_config(
143251 + struct qman_portal *portal);
143252 +
143253 +/* power management */
143254 +#ifdef CONFIG_SUSPEND
143255 +void suspend_unused_qportal(void);
143256 +void resume_unused_qportal(void);
143257 +#endif
143258 --- /dev/null
143259 +++ b/drivers/staging/fsl_qbman/qman_test.c
143260 @@ -0,0 +1,57 @@
143261 +/* Copyright 2008-2011 Freescale Semiconductor, Inc.
143262 + *
143263 + * Redistribution and use in source and binary forms, with or without
143264 + * modification, are permitted provided that the following conditions are met:
143265 + * * Redistributions of source code must retain the above copyright
143266 + * notice, this list of conditions and the following disclaimer.
143267 + * * Redistributions in binary form must reproduce the above copyright
143268 + * notice, this list of conditions and the following disclaimer in the
143269 + * documentation and/or other materials provided with the distribution.
143270 + * * Neither the name of Freescale Semiconductor nor the
143271 + * names of its contributors may be used to endorse or promote products
143272 + * derived from this software without specific prior written permission.
143273 + *
143274 + *
143275 + * ALTERNATIVELY, this software may be distributed under the terms of the
143276 + * GNU General Public License ("GPL") as published by the Free Software
143277 + * Foundation, either version 2 of that License or (at your option) any
143278 + * later version.
143279 + *
143280 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
143281 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
143282 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
143283 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
143284 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
143285 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
143286 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
143287 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
143288 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
143289 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
143290 + */
143291 +
143292 +#include "qman_test.h"
143293 +
143294 +MODULE_AUTHOR("Geoff Thorpe");
143295 +MODULE_LICENSE("Dual BSD/GPL");
143296 +MODULE_DESCRIPTION("Qman testing");
143297 +
143298 +static int test_init(void)
143299 +{
143300 + int loop = 1;
143301 + while (loop--) {
143302 +#ifdef CONFIG_FSL_QMAN_TEST_STASH_POTATO
143303 + qman_test_hotpotato();
143304 +#endif
143305 +#ifdef CONFIG_FSL_QMAN_TEST_HIGH
143306 + qman_test_high();
143307 +#endif
143308 + }
143309 + return 0;
143310 +}
143311 +
143312 +static void test_exit(void)
143313 +{
143314 +}
143315 +
143316 +module_init(test_init);
143317 +module_exit(test_exit);
143318 --- /dev/null
143319 +++ b/drivers/staging/fsl_qbman/qman_test.h
143320 @@ -0,0 +1,45 @@
143321 +/* Copyright 2008-2011 Freescale Semiconductor, Inc.
143322 + *
143323 + * Redistribution and use in source and binary forms, with or without
143324 + * modification, are permitted provided that the following conditions are met:
143325 + * * Redistributions of source code must retain the above copyright
143326 + * notice, this list of conditions and the following disclaimer.
143327 + * * Redistributions in binary form must reproduce the above copyright
143328 + * notice, this list of conditions and the following disclaimer in the
143329 + * documentation and/or other materials provided with the distribution.
143330 + * * Neither the name of Freescale Semiconductor nor the
143331 + * names of its contributors may be used to endorse or promote products
143332 + * derived from this software without specific prior written permission.
143333 + *
143334 + *
143335 + * ALTERNATIVELY, this software may be distributed under the terms of the
143336 + * GNU General Public License ("GPL") as published by the Free Software
143337 + * Foundation, either version 2 of that License or (at your option) any
143338 + * later version.
143339 + *
143340 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
143341 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
143342 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
143343 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
143344 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
143345 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
143346 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
143347 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
143348 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
143349 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
143350 + */
143351 +
143352 +#include <linux/kernel.h>
143353 +#include <linux/errno.h>
143354 +#include <linux/io.h>
143355 +#include <linux/slab.h>
143356 +#include <linux/module.h>
143357 +#include <linux/interrupt.h>
143358 +#include <linux/delay.h>
143359 +#include <linux/sched.h>
143360 +
143361 +#include <linux/fsl_qman.h>
143362 +
143363 +void qman_test_hotpotato(void);
143364 +void qman_test_high(void);
143365 +
143366 --- /dev/null
143367 +++ b/drivers/staging/fsl_qbman/qman_test_high.c
143368 @@ -0,0 +1,216 @@
143369 +/* Copyright 2008-2011 Freescale Semiconductor, Inc.
143370 + *
143371 + * Redistribution and use in source and binary forms, with or without
143372 + * modification, are permitted provided that the following conditions are met:
143373 + * * Redistributions of source code must retain the above copyright
143374 + * notice, this list of conditions and the following disclaimer.
143375 + * * Redistributions in binary form must reproduce the above copyright
143376 + * notice, this list of conditions and the following disclaimer in the
143377 + * documentation and/or other materials provided with the distribution.
143378 + * * Neither the name of Freescale Semiconductor nor the
143379 + * names of its contributors may be used to endorse or promote products
143380 + * derived from this software without specific prior written permission.
143381 + *
143382 + *
143383 + * ALTERNATIVELY, this software may be distributed under the terms of the
143384 + * GNU General Public License ("GPL") as published by the Free Software
143385 + * Foundation, either version 2 of that License or (at your option) any
143386 + * later version.
143387 + *
143388 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
143389 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
143390 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
143391 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
143392 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
143393 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
143394 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
143395 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
143396 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
143397 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
143398 + */
143399 +
143400 +#include "qman_test.h"
143401 +
143402 +/*************/
143403 +/* constants */
143404 +/*************/
143405 +
143406 +#define CGR_ID 27
143407 +#define POOL_ID 2
143408 +#define FQ_FLAGS QMAN_FQ_FLAG_DYNAMIC_FQID
143409 +#define NUM_ENQUEUES 10
143410 +#define NUM_PARTIAL 4
143411 +#define PORTAL_SDQCR (QM_SDQCR_SOURCE_CHANNELS | \
143412 + QM_SDQCR_TYPE_PRIO_QOS | \
143413 + QM_SDQCR_TOKEN_SET(0x98) | \
143414 + QM_SDQCR_CHANNELS_DEDICATED | \
143415 + QM_SDQCR_CHANNELS_POOL(POOL_ID))
143416 +#define PORTAL_OPAQUE ((void *)0xf00dbeef)
143417 +#define VDQCR_FLAGS (QMAN_VOLATILE_FLAG_WAIT | QMAN_VOLATILE_FLAG_FINISH)
143418 +
143419 +/*************************************/
143420 +/* Predeclarations (eg. for fq_base) */
143421 +/*************************************/
143422 +
143423 +static enum qman_cb_dqrr_result cb_dqrr(struct qman_portal *,
143424 + struct qman_fq *,
143425 + const struct qm_dqrr_entry *);
143426 +static void cb_ern(struct qman_portal *, struct qman_fq *,
143427 + const struct qm_mr_entry *);
143428 +static void cb_fqs(struct qman_portal *, struct qman_fq *,
143429 + const struct qm_mr_entry *);
143430 +
143431 +/***************/
143432 +/* global vars */
143433 +/***************/
143434 +
143435 +static struct qm_fd fd, fd_dq;
143436 +static struct qman_fq fq_base = {
143437 + .cb.dqrr = cb_dqrr,
143438 + .cb.ern = cb_ern,
143439 + .cb.fqs = cb_fqs
143440 +};
143441 +static DECLARE_WAIT_QUEUE_HEAD(waitqueue);
143442 +static int retire_complete, sdqcr_complete;
143443 +
143444 +/**********************/
143445 +/* internal functions */
143446 +/**********************/
143447 +
143448 +/* Helpers for initialising and "incrementing" a frame descriptor */
143449 +static void fd_init(struct qm_fd *__fd)
143450 +{
143451 + qm_fd_addr_set64(__fd, 0xabdeadbeefLLU);
143452 + __fd->format = qm_fd_contig_big;
143453 + __fd->length29 = 0x0000ffff;
143454 + __fd->cmd = 0xfeedf00d;
143455 +}
143456 +
143457 +static void fd_inc(struct qm_fd *__fd)
143458 +{
143459 + u64 t = qm_fd_addr_get64(__fd);
143460 + int z = t >> 40;
143461 + t <<= 1;
143462 + if (z)
143463 + t |= 1;
143464 + qm_fd_addr_set64(__fd, t);
143465 + __fd->length29--;
143466 + __fd->cmd++;
143467 +}
143468 +
143469 +/* The only part of the 'fd' we can't memcmp() is the ppid */
143470 +static int fd_cmp(const struct qm_fd *a, const struct qm_fd *b)
143471 +{
143472 + int r = (qm_fd_addr_get64(a) == qm_fd_addr_get64(b)) ? 0 : -1;
143473 + if (!r)
143474 + r = a->format - b->format;
143475 + if (!r)
143476 + r = a->opaque - b->opaque;
143477 + if (!r)
143478 + r = a->cmd - b->cmd;
143479 + return r;
143480 +}
143481 +
143482 +/********/
143483 +/* test */
143484 +/********/
143485 +
143486 +static void do_enqueues(struct qman_fq *fq)
143487 +{
143488 + unsigned int loop;
143489 + for (loop = 0; loop < NUM_ENQUEUES; loop++) {
143490 + if (qman_enqueue(fq, &fd, QMAN_ENQUEUE_FLAG_WAIT |
143491 + (((loop + 1) == NUM_ENQUEUES) ?
143492 + QMAN_ENQUEUE_FLAG_WAIT_SYNC : 0)))
143493 + panic("qman_enqueue() failed\n");
143494 + fd_inc(&fd);
143495 + }
143496 +}
143497 +
143498 +void qman_test_high(void)
143499 +{
143500 + unsigned int flags;
143501 + int res;
143502 + struct qman_fq *fq = &fq_base;
143503 +
143504 + pr_info("qman_test_high starting\n");
143505 + fd_init(&fd);
143506 + fd_init(&fd_dq);
143507 +
143508 + /* Initialise (parked) FQ */
143509 + if (qman_create_fq(0, FQ_FLAGS, fq))
143510 + panic("qman_create_fq() failed\n");
143511 + if (qman_init_fq(fq, QMAN_INITFQ_FLAG_LOCAL, NULL))
143512 + panic("qman_init_fq() failed\n");
143513 +
143514 + /* Do enqueues + VDQCR, twice. (Parked FQ) */
143515 + do_enqueues(fq);
143516 + pr_info("VDQCR (till-empty);\n");
143517 + if (qman_volatile_dequeue(fq, VDQCR_FLAGS,
143518 + QM_VDQCR_NUMFRAMES_TILLEMPTY))
143519 + panic("qman_volatile_dequeue() failed\n");
143520 + do_enqueues(fq);
143521 + pr_info("VDQCR (%d of %d);\n", NUM_PARTIAL, NUM_ENQUEUES);
143522 + if (qman_volatile_dequeue(fq, VDQCR_FLAGS,
143523 + QM_VDQCR_NUMFRAMES_SET(NUM_PARTIAL)))
143524 + panic("qman_volatile_dequeue() failed\n");
143525 + pr_info("VDQCR (%d of %d);\n", NUM_ENQUEUES - NUM_PARTIAL,
143526 + NUM_ENQUEUES);
143527 + if (qman_volatile_dequeue(fq, VDQCR_FLAGS,
143528 + QM_VDQCR_NUMFRAMES_SET(NUM_ENQUEUES - NUM_PARTIAL)))
143529 + panic("qman_volatile_dequeue() failed\n");
143530 +
143531 + do_enqueues(fq);
143532 + pr_info("scheduled dequeue (till-empty)\n");
143533 + if (qman_schedule_fq(fq))
143534 + panic("qman_schedule_fq() failed\n");
143535 + wait_event(waitqueue, sdqcr_complete);
143536 +
143537 + /* Retire and OOS the FQ */
143538 + res = qman_retire_fq(fq, &flags);
143539 + if (res < 0)
143540 + panic("qman_retire_fq() failed\n");
143541 + wait_event(waitqueue, retire_complete);
143542 + if (flags & QMAN_FQ_STATE_BLOCKOOS)
143543 + panic("leaking frames\n");
143544 + if (qman_oos_fq(fq))
143545 + panic("qman_oos_fq() failed\n");
143546 + qman_destroy_fq(fq, 0);
143547 + pr_info("qman_test_high finished\n");
143548 +}
143549 +
143550 +static enum qman_cb_dqrr_result cb_dqrr(struct qman_portal *p,
143551 + struct qman_fq *fq,
143552 + const struct qm_dqrr_entry *dq)
143553 +{
143554 + if (fd_cmp(&fd_dq, &dq->fd)) {
143555 + pr_err("BADNESS: dequeued frame doesn't match;\n");
143556 + pr_err("Expected 0x%llx, got 0x%llx\n",
143557 + (unsigned long long)fd_dq.length29,
143558 + (unsigned long long)dq->fd.length29);
143559 + BUG();
143560 + }
143561 + fd_inc(&fd_dq);
143562 + if (!(dq->stat & QM_DQRR_STAT_UNSCHEDULED) && !fd_cmp(&fd_dq, &fd)) {
143563 + sdqcr_complete = 1;
143564 + wake_up(&waitqueue);
143565 + }
143566 + return qman_cb_dqrr_consume;
143567 +}
143568 +
143569 +static void cb_ern(struct qman_portal *p, struct qman_fq *fq,
143570 + const struct qm_mr_entry *msg)
143571 +{
143572 + panic("cb_ern() unimplemented");
143573 +}
143574 +
143575 +static void cb_fqs(struct qman_portal *p, struct qman_fq *fq,
143576 + const struct qm_mr_entry *msg)
143577 +{
143578 + u8 verb = (msg->verb & QM_MR_VERB_TYPE_MASK);
143579 + if ((verb != QM_MR_VERB_FQRN) && (verb != QM_MR_VERB_FQRNI))
143580 + panic("unexpected FQS message");
143581 + pr_info("Retirement message received\n");
143582 + retire_complete = 1;
143583 + wake_up(&waitqueue);
143584 +}
143585 --- /dev/null
143586 +++ b/drivers/staging/fsl_qbman/qman_test_hotpotato.c
143587 @@ -0,0 +1,502 @@
143588 +/* Copyright 2009-2012 Freescale Semiconductor, Inc.
143589 + *
143590 + * Redistribution and use in source and binary forms, with or without
143591 + * modification, are permitted provided that the following conditions are met:
143592 + * * Redistributions of source code must retain the above copyright
143593 + * notice, this list of conditions and the following disclaimer.
143594 + * * Redistributions in binary form must reproduce the above copyright
143595 + * notice, this list of conditions and the following disclaimer in the
143596 + * documentation and/or other materials provided with the distribution.
143597 + * * Neither the name of Freescale Semiconductor nor the
143598 + * names of its contributors may be used to endorse or promote products
143599 + * derived from this software without specific prior written permission.
143600 + *
143601 + *
143602 + * ALTERNATIVELY, this software may be distributed under the terms of the
143603 + * GNU General Public License ("GPL") as published by the Free Software
143604 + * Foundation, either version 2 of that License or (at your option) any
143605 + * later version.
143606 + *
143607 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
143608 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
143609 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
143610 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
143611 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
143612 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
143613 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
143614 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
143615 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
143616 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
143617 + */
143618 +
143619 +#include <linux/kthread.h>
143620 +#include <linux/platform_device.h>
143621 +#include <linux/dma-mapping.h>
143622 +#include "qman_test.h"
143623 +
143624 +/* Algorithm:
143625 + *
143626 + * Each cpu will have HP_PER_CPU "handlers" set up, each of which incorporates
143627 + * an rx/tx pair of FQ objects (both of which are stashed on dequeue). The
143628 + * organisation of FQIDs is such that the HP_PER_CPU*NUM_CPUS handlers will
143629 + * shuttle a "hot potato" frame around them such that every forwarding action
143630 + * moves it from one cpu to another. (The use of more than one handler per cpu
143631 + * is to allow enough handlers/FQs to truly test the significance of caching -
143632 + * ie. when cache-expiries are occurring.)
143633 + *
143634 + * The "hot potato" frame content will be HP_NUM_WORDS*4 bytes in size, and the
143635 + * first and last words of the frame data will undergo a transformation step on
143636 + * each forwarding action. To achieve this, each handler will be assigned a
143637 + * 32-bit "mixer", that is produced using a 32-bit LFSR. When a frame is
143638 + * received by a handler, the mixer of the expected sender is XOR'd into all
143639 + * words of the entire frame, which is then validated against the original
143640 + * values. Then, before forwarding, the entire frame is XOR'd with the mixer of
143641 + * the current handler. Apart from validating that the frame is taking the
143642 + * expected path, this also provides some quasi-realistic overheads to each
143643 + * forwarding action - dereferencing *all* the frame data, computation, and
143644 + * conditional branching. There is a "special" handler designated to act as the
143645 + * instigator of the test by creating an enqueuing the "hot potato" frame, and
143646 + * to determine when the test has completed by counting HP_LOOPS iterations.
143647 + *
143648 + * Init phases:
143649 + *
143650 + * 1. prepare each cpu's 'hp_cpu' struct using on_each_cpu(,,1) and link them
143651 + * into 'hp_cpu_list'. Specifically, set processor_id, allocate HP_PER_CPU
143652 + * handlers and link-list them (but do no other handler setup).
143653 + *
143654 + * 2. scan over 'hp_cpu_list' HP_PER_CPU times, the first time sets each
143655 + * hp_cpu's 'iterator' to point to its first handler. With each loop,
143656 + * allocate rx/tx FQIDs and mixer values to the hp_cpu's iterator handler
143657 + * and advance the iterator for the next loop. This includes a final fixup,
143658 + * which connects the last handler to the first (and which is why phase 2
143659 + * and 3 are separate).
143660 + *
143661 + * 3. scan over 'hp_cpu_list' HP_PER_CPU times, the first time sets each
143662 + * hp_cpu's 'iterator' to point to its first handler. With each loop,
143663 + * initialise FQ objects and advance the iterator for the next loop.
143664 + * Moreover, do this initialisation on the cpu it applies to so that Rx FQ
143665 + * initialisation targets the correct cpu.
143666 + */
143667 +
143668 +/* helper to run something on all cpus (can't use on_each_cpu(), as that invokes
143669 + * the fn from irq context, which is too restrictive). */
143670 +struct bstrap {
143671 + void (*fn)(void);
143672 + atomic_t started;
143673 +};
143674 +static int bstrap_fn(void *__bstrap)
143675 +{
143676 + struct bstrap *bstrap = __bstrap;
143677 + atomic_inc(&bstrap->started);
143678 + bstrap->fn();
143679 + while (!kthread_should_stop())
143680 + msleep(1);
143681 + return 0;
143682 +}
143683 +static int on_all_cpus(void (*fn)(void))
143684 +{
143685 + int cpu;
143686 + for_each_cpu(cpu, cpu_online_mask) {
143687 + struct bstrap bstrap = {
143688 + .fn = fn,
143689 + .started = ATOMIC_INIT(0)
143690 + };
143691 + struct task_struct *k = kthread_create(bstrap_fn, &bstrap,
143692 + "hotpotato%d", cpu);
143693 + int ret;
143694 + if (IS_ERR(k))
143695 + return -ENOMEM;
143696 + kthread_bind(k, cpu);
143697 + wake_up_process(k);
143698 + /* If we call kthread_stop() before the "wake up" has had an
143699 + * effect, then the thread may exit with -EINTR without ever
143700 + * running the function. So poll until it's started before
143701 + * requesting it to stop. */
143702 + while (!atomic_read(&bstrap.started))
143703 + msleep(10);
143704 + ret = kthread_stop(k);
143705 + if (ret)
143706 + return ret;
143707 + }
143708 + return 0;
143709 +}
143710 +
143711 +struct hp_handler {
143712 +
143713 + /* The following data is stashed when 'rx' is dequeued; */
143714 + /* -------------- */
143715 + /* The Rx FQ, dequeues of which will stash the entire hp_handler */
143716 + struct qman_fq rx;
143717 + /* The Tx FQ we should forward to */
143718 + struct qman_fq tx;
143719 + /* The value we XOR post-dequeue, prior to validating */
143720 + u32 rx_mixer;
143721 + /* The value we XOR pre-enqueue, after validating */
143722 + u32 tx_mixer;
143723 + /* what the hotpotato address should be on dequeue */
143724 + dma_addr_t addr;
143725 + u32 *frame_ptr;
143726 +
143727 + /* The following data isn't (necessarily) stashed on dequeue; */
143728 + /* -------------- */
143729 + u32 fqid_rx, fqid_tx;
143730 + /* list node for linking us into 'hp_cpu' */
143731 + struct list_head node;
143732 + /* Just to check ... */
143733 + unsigned int processor_id;
143734 +} ____cacheline_aligned;
143735 +
143736 +struct hp_cpu {
143737 + /* identify the cpu we run on; */
143738 + unsigned int processor_id;
143739 + /* root node for the per-cpu list of handlers */
143740 + struct list_head handlers;
143741 + /* list node for linking us into 'hp_cpu_list' */
143742 + struct list_head node;
143743 + /* when repeatedly scanning 'hp_list', each time linking the n'th
143744 + * handlers together, this is used as per-cpu iterator state */
143745 + struct hp_handler *iterator;
143746 +};
143747 +
143748 +/* Each cpu has one of these */
143749 +static DEFINE_PER_CPU(struct hp_cpu, hp_cpus);
143750 +
143751 +/* links together the hp_cpu structs, in first-come first-serve order. */
143752 +static LIST_HEAD(hp_cpu_list);
143753 +static spinlock_t hp_lock = __SPIN_LOCK_UNLOCKED(hp_lock);
143754 +
143755 +static unsigned int hp_cpu_list_length;
143756 +
143757 +/* the "special" handler, that starts and terminates the test. */
143758 +static struct hp_handler *special_handler;
143759 +static int loop_counter;
143760 +
143761 +/* handlers are allocated out of this, so they're properly aligned. */
143762 +static struct kmem_cache *hp_handler_slab;
143763 +
143764 +/* this is the frame data */
143765 +static void *__frame_ptr;
143766 +static u32 *frame_ptr;
143767 +static dma_addr_t frame_dma;
143768 +
143769 +/* the main function waits on this */
143770 +static DECLARE_WAIT_QUEUE_HEAD(queue);
143771 +
143772 +#define HP_PER_CPU 2
143773 +#define HP_LOOPS 8
143774 +/* 80 bytes, like a small ethernet frame, and bleeds into a second cacheline */
143775 +#define HP_NUM_WORDS 80
143776 +/* First word of the LFSR-based frame data */
143777 +#define HP_FIRST_WORD 0xabbaf00d
143778 +
143779 +static inline u32 do_lfsr(u32 prev)
143780 +{
143781 + return (prev >> 1) ^ (-(prev & 1u) & 0xd0000001u);
143782 +}
143783 +
143784 +static void allocate_frame_data(void)
143785 +{
143786 + u32 lfsr = HP_FIRST_WORD;
143787 + int loop;
143788 + struct platform_device *pdev = platform_device_alloc("foobar", -1);
143789 + if (!pdev)
143790 + panic("platform_device_alloc() failed");
143791 + if (platform_device_add(pdev))
143792 + panic("platform_device_add() failed");
143793 + __frame_ptr = kmalloc(4 * HP_NUM_WORDS, GFP_KERNEL);
143794 + if (!__frame_ptr)
143795 + panic("kmalloc() failed");
143796 + frame_ptr = (void *)(((unsigned long)__frame_ptr + 63) &
143797 + ~(unsigned long)63);
143798 + for (loop = 0; loop < HP_NUM_WORDS; loop++) {
143799 + frame_ptr[loop] = lfsr;
143800 + lfsr = do_lfsr(lfsr);
143801 + }
143802 + frame_dma = dma_map_single(&pdev->dev, frame_ptr, 4 * HP_NUM_WORDS,
143803 + DMA_BIDIRECTIONAL);
143804 + platform_device_del(pdev);
143805 + platform_device_put(pdev);
143806 +}
143807 +
143808 +static void deallocate_frame_data(void)
143809 +{
143810 + kfree(__frame_ptr);
143811 +}
143812 +
143813 +static inline void process_frame_data(struct hp_handler *handler,
143814 + const struct qm_fd *fd)
143815 +{
143816 + u32 *p = handler->frame_ptr;
143817 + u32 lfsr = HP_FIRST_WORD;
143818 + int loop;
143819 + if (qm_fd_addr_get64(fd) != (handler->addr & 0xffffffffff)) {
143820 + pr_err("Got 0x%llx expected 0x%llx\n",
143821 + qm_fd_addr_get64(fd), handler->addr);
143822 + panic("bad frame address");
143823 + }
143824 + for (loop = 0; loop < HP_NUM_WORDS; loop++, p++) {
143825 + *p ^= handler->rx_mixer;
143826 + if (*p != lfsr)
143827 + panic("corrupt frame data");
143828 + *p ^= handler->tx_mixer;
143829 + lfsr = do_lfsr(lfsr);
143830 + }
143831 +}
143832 +
143833 +static enum qman_cb_dqrr_result normal_dqrr(struct qman_portal *portal,
143834 + struct qman_fq *fq,
143835 + const struct qm_dqrr_entry *dqrr)
143836 +{
143837 + struct hp_handler *handler = (struct hp_handler *)fq;
143838 +
143839 + process_frame_data(handler, &dqrr->fd);
143840 + if (qman_enqueue(&handler->tx, &dqrr->fd, 0))
143841 + panic("qman_enqueue() failed");
143842 + return qman_cb_dqrr_consume;
143843 +}
143844 +
143845 +static enum qman_cb_dqrr_result special_dqrr(struct qman_portal *portal,
143846 + struct qman_fq *fq,
143847 + const struct qm_dqrr_entry *dqrr)
143848 +{
143849 + struct hp_handler *handler = (struct hp_handler *)fq;
143850 +
143851 + process_frame_data(handler, &dqrr->fd);
143852 + if (++loop_counter < HP_LOOPS) {
143853 + if (qman_enqueue(&handler->tx, &dqrr->fd, 0))
143854 + panic("qman_enqueue() failed");
143855 + } else {
143856 + pr_info("Received final (%dth) frame\n", loop_counter);
143857 + wake_up(&queue);
143858 + }
143859 + return qman_cb_dqrr_consume;
143860 +}
143861 +
143862 +static void create_per_cpu_handlers(void)
143863 +{
143864 + struct hp_handler *handler;
143865 + int loop;
143866 + struct hp_cpu *hp_cpu = &get_cpu_var(hp_cpus);
143867 +
143868 + hp_cpu->processor_id = smp_processor_id();
143869 + spin_lock(&hp_lock);
143870 + list_add_tail(&hp_cpu->node, &hp_cpu_list);
143871 + hp_cpu_list_length++;
143872 + spin_unlock(&hp_lock);
143873 + INIT_LIST_HEAD(&hp_cpu->handlers);
143874 + for (loop = 0; loop < HP_PER_CPU; loop++) {
143875 + handler = kmem_cache_alloc(hp_handler_slab, GFP_KERNEL);
143876 + if (!handler)
143877 + panic("kmem_cache_alloc() failed");
143878 + handler->processor_id = hp_cpu->processor_id;
143879 + handler->addr = frame_dma;
143880 + handler->frame_ptr = frame_ptr;
143881 + list_add_tail(&handler->node, &hp_cpu->handlers);
143882 + }
143883 + put_cpu_var(hp_cpus);
143884 +}
143885 +
143886 +static void destroy_per_cpu_handlers(void)
143887 +{
143888 + struct list_head *loop, *tmp;
143889 + struct hp_cpu *hp_cpu = &get_cpu_var(hp_cpus);
143890 +
143891 + spin_lock(&hp_lock);
143892 + list_del(&hp_cpu->node);
143893 + spin_unlock(&hp_lock);
143894 + list_for_each_safe(loop, tmp, &hp_cpu->handlers) {
143895 + u32 flags;
143896 + struct hp_handler *handler = list_entry(loop, struct hp_handler,
143897 + node);
143898 + if (qman_retire_fq(&handler->rx, &flags))
143899 + panic("qman_retire_fq(rx) failed");
143900 + BUG_ON(flags & QMAN_FQ_STATE_BLOCKOOS);
143901 + if (qman_oos_fq(&handler->rx))
143902 + panic("qman_oos_fq(rx) failed");
143903 + qman_destroy_fq(&handler->rx, 0);
143904 + qman_destroy_fq(&handler->tx, 0);
143905 + qman_release_fqid(handler->fqid_rx);
143906 + list_del(&handler->node);
143907 + kmem_cache_free(hp_handler_slab, handler);
143908 + }
143909 + put_cpu_var(hp_cpus);
143910 +}
143911 +
143912 +static inline u8 num_cachelines(u32 offset)
143913 +{
143914 + u8 res = (offset + (L1_CACHE_BYTES - 1))
143915 + / (L1_CACHE_BYTES);
143916 + if (res > 3)
143917 + return 3;
143918 + return res;
143919 +}
143920 +#define STASH_DATA_CL \
143921 + num_cachelines(HP_NUM_WORDS * 4)
143922 +#define STASH_CTX_CL \
143923 + num_cachelines(offsetof(struct hp_handler, fqid_rx))
143924 +
143925 +static void init_handler(void *__handler)
143926 +{
143927 + struct qm_mcc_initfq opts;
143928 + struct hp_handler *handler = __handler;
143929 + BUG_ON(handler->processor_id != smp_processor_id());
143930 + /* Set up rx */
143931 + memset(&handler->rx, 0, sizeof(handler->rx));
143932 + if (handler == special_handler)
143933 + handler->rx.cb.dqrr = special_dqrr;
143934 + else
143935 + handler->rx.cb.dqrr = normal_dqrr;
143936 + if (qman_create_fq(handler->fqid_rx, 0, &handler->rx))
143937 + panic("qman_create_fq(rx) failed");
143938 + memset(&opts, 0, sizeof(opts));
143939 + opts.we_mask = QM_INITFQ_WE_FQCTRL | QM_INITFQ_WE_CONTEXTA;
143940 + opts.fqd.fq_ctrl = QM_FQCTRL_CTXASTASHING;
143941 + opts.fqd.context_a.stashing.data_cl = STASH_DATA_CL;
143942 + opts.fqd.context_a.stashing.context_cl = STASH_CTX_CL;
143943 + if (qman_init_fq(&handler->rx, QMAN_INITFQ_FLAG_SCHED |
143944 + QMAN_INITFQ_FLAG_LOCAL, &opts))
143945 + panic("qman_init_fq(rx) failed");
143946 + /* Set up tx */
143947 + memset(&handler->tx, 0, sizeof(handler->tx));
143948 + if (qman_create_fq(handler->fqid_tx, QMAN_FQ_FLAG_NO_MODIFY,
143949 + &handler->tx))
143950 + panic("qman_create_fq(tx) failed");
143951 +}
143952 +
143953 +static void init_phase2(void)
143954 +{
143955 + int loop;
143956 + u32 fqid = 0;
143957 + u32 lfsr = 0xdeadbeef;
143958 + struct hp_cpu *hp_cpu;
143959 + struct hp_handler *handler;
143960 +
143961 + for (loop = 0; loop < HP_PER_CPU; loop++) {
143962 + list_for_each_entry(hp_cpu, &hp_cpu_list, node) {
143963 + int ret;
143964 + if (!loop)
143965 + hp_cpu->iterator = list_first_entry(
143966 + &hp_cpu->handlers,
143967 + struct hp_handler, node);
143968 + else
143969 + hp_cpu->iterator = list_entry(
143970 + hp_cpu->iterator->node.next,
143971 + struct hp_handler, node);
143972 + /* Rx FQID is the previous handler's Tx FQID */
143973 + hp_cpu->iterator->fqid_rx = fqid;
143974 + /* Allocate new FQID for Tx */
143975 + ret = qman_alloc_fqid(&fqid);
143976 + if (ret)
143977 + panic("qman_alloc_fqid() failed");
143978 + hp_cpu->iterator->fqid_tx = fqid;
143979 + /* Rx mixer is the previous handler's Tx mixer */
143980 + hp_cpu->iterator->rx_mixer = lfsr;
143981 + /* Get new mixer for Tx */
143982 + lfsr = do_lfsr(lfsr);
143983 + hp_cpu->iterator->tx_mixer = lfsr;
143984 + }
143985 + }
143986 + /* Fix up the first handler (fqid_rx==0, rx_mixer=0xdeadbeef) */
143987 + hp_cpu = list_first_entry(&hp_cpu_list, struct hp_cpu, node);
143988 + handler = list_first_entry(&hp_cpu->handlers, struct hp_handler, node);
143989 + BUG_ON((handler->fqid_rx != 0) || (handler->rx_mixer != 0xdeadbeef));
143990 + handler->fqid_rx = fqid;
143991 + handler->rx_mixer = lfsr;
143992 + /* and tag it as our "special" handler */
143993 + special_handler = handler;
143994 +}
143995 +
143996 +static void init_phase3(void)
143997 +{
143998 + int loop;
143999 + struct hp_cpu *hp_cpu;
144000 +
144001 + for (loop = 0; loop < HP_PER_CPU; loop++) {
144002 + list_for_each_entry(hp_cpu, &hp_cpu_list, node) {
144003 + if (!loop)
144004 + hp_cpu->iterator = list_first_entry(
144005 + &hp_cpu->handlers,
144006 + struct hp_handler, node);
144007 + else
144008 + hp_cpu->iterator = list_entry(
144009 + hp_cpu->iterator->node.next,
144010 + struct hp_handler, node);
144011 + preempt_disable();
144012 + if (hp_cpu->processor_id == smp_processor_id())
144013 + init_handler(hp_cpu->iterator);
144014 + else
144015 + smp_call_function_single(hp_cpu->processor_id,
144016 + init_handler, hp_cpu->iterator, 1);
144017 + preempt_enable();
144018 + }
144019 + }
144020 +}
144021 +
144022 +static void send_first_frame(void *ignore)
144023 +{
144024 + u32 *p = special_handler->frame_ptr;
144025 + u32 lfsr = HP_FIRST_WORD;
144026 + int loop;
144027 + struct qm_fd fd;
144028 +
144029 + BUG_ON(special_handler->processor_id != smp_processor_id());
144030 + memset(&fd, 0, sizeof(fd));
144031 + qm_fd_addr_set64(&fd, special_handler->addr);
144032 + fd.format = qm_fd_contig_big;
144033 + fd.length29 = HP_NUM_WORDS * 4;
144034 + for (loop = 0; loop < HP_NUM_WORDS; loop++, p++) {
144035 + if (*p != lfsr)
144036 + panic("corrupt frame data");
144037 + *p ^= special_handler->tx_mixer;
144038 + lfsr = do_lfsr(lfsr);
144039 + }
144040 + pr_info("Sending first frame\n");
144041 + if (qman_enqueue(&special_handler->tx, &fd, 0))
144042 + panic("qman_enqueue() failed");
144043 +}
144044 +
144045 +void qman_test_hotpotato(void)
144046 +{
144047 + if (cpumask_weight(cpu_online_mask) < 2) {
144048 + pr_info("qman_test_hotpotato, skip - only 1 CPU\n");
144049 + return;
144050 + }
144051 +
144052 + pr_info("qman_test_hotpotato starting\n");
144053 +
144054 + hp_cpu_list_length = 0;
144055 + loop_counter = 0;
144056 + hp_handler_slab = kmem_cache_create("hp_handler_slab",
144057 + sizeof(struct hp_handler), L1_CACHE_BYTES,
144058 + SLAB_HWCACHE_ALIGN, NULL);
144059 + if (!hp_handler_slab)
144060 + panic("kmem_cache_create() failed");
144061 +
144062 + allocate_frame_data();
144063 +
144064 + /* Init phase 1 */
144065 + pr_info("Creating %d handlers per cpu...\n", HP_PER_CPU);
144066 + if (on_all_cpus(create_per_cpu_handlers))
144067 + panic("on_each_cpu() failed");
144068 + pr_info("Number of cpus: %d, total of %d handlers\n",
144069 + hp_cpu_list_length, hp_cpu_list_length * HP_PER_CPU);
144070 +
144071 + init_phase2();
144072 +
144073 + init_phase3();
144074 +
144075 + preempt_disable();
144076 + if (special_handler->processor_id == smp_processor_id())
144077 + send_first_frame(NULL);
144078 + else
144079 + smp_call_function_single(special_handler->processor_id,
144080 + send_first_frame, NULL, 1);
144081 + preempt_enable();
144082 +
144083 + wait_event(queue, loop_counter == HP_LOOPS);
144084 + deallocate_frame_data();
144085 + if (on_all_cpus(destroy_per_cpu_handlers))
144086 + panic("on_each_cpu() failed");
144087 + kmem_cache_destroy(hp_handler_slab);
144088 + pr_info("qman_test_hotpotato finished\n");
144089 +}
144090 --- /dev/null
144091 +++ b/drivers/staging/fsl_qbman/qman_utility.c
144092 @@ -0,0 +1,129 @@
144093 +/* Copyright 2008-2011 Freescale Semiconductor, Inc.
144094 + *
144095 + * Redistribution and use in source and binary forms, with or without
144096 + * modification, are permitted provided that the following conditions are met:
144097 + * * Redistributions of source code must retain the above copyright
144098 + * notice, this list of conditions and the following disclaimer.
144099 + * * Redistributions in binary form must reproduce the above copyright
144100 + * notice, this list of conditions and the following disclaimer in the
144101 + * documentation and/or other materials provided with the distribution.
144102 + * * Neither the name of Freescale Semiconductor nor the
144103 + * names of its contributors may be used to endorse or promote products
144104 + * derived from this software without specific prior written permission.
144105 + *
144106 + *
144107 + * ALTERNATIVELY, this software may be distributed under the terms of the
144108 + * GNU General Public License ("GPL") as published by the Free Software
144109 + * Foundation, either version 2 of that License or (at your option) any
144110 + * later version.
144111 + *
144112 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
144113 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
144114 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
144115 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
144116 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
144117 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
144118 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
144119 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
144120 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
144121 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
144122 + */
144123 +
144124 +#include "qman_private.h"
144125 +
144126 +/* ----------------- */
144127 +/* --- FQID Pool --- */
144128 +
144129 +struct qman_fqid_pool {
144130 + /* Base and size of the FQID range */
144131 + u32 fqid_base;
144132 + u32 total;
144133 + /* Number of FQIDs currently "allocated" */
144134 + u32 used;
144135 + /* Allocation optimisation. When 'used<total', it is the index of an
144136 + * available FQID. Otherwise there are no available FQIDs, and this
144137 + * will be set when the next deallocation occurs. */
144138 + u32 next;
144139 + /* A bit-field representation of the FQID range. */
144140 + unsigned long *bits;
144141 +};
144142 +
144143 +#define QLONG_BYTES sizeof(unsigned long)
144144 +#define QLONG_BITS (QLONG_BYTES * 8)
144145 +/* Number of 'longs' required for the given number of bits */
144146 +#define QNUM_LONGS(b) (((b) + QLONG_BITS - 1) / QLONG_BITS)
144147 +/* Shorthand for the number of bytes of same (kmalloc, memset, etc) */
144148 +#define QNUM_BYTES(b) (QNUM_LONGS(b) * QLONG_BYTES)
144149 +/* And in bits */
144150 +#define QNUM_BITS(b) (QNUM_LONGS(b) * QLONG_BITS)
144151 +
144152 +struct qman_fqid_pool *qman_fqid_pool_create(u32 fqid_start, u32 num)
144153 +{
144154 + struct qman_fqid_pool *pool = kmalloc(sizeof(*pool), GFP_KERNEL);
144155 + unsigned int i;
144156 +
144157 + BUG_ON(!num);
144158 + if (!pool)
144159 + return NULL;
144160 + pool->fqid_base = fqid_start;
144161 + pool->total = num;
144162 + pool->used = 0;
144163 + pool->next = 0;
144164 + pool->bits = kzalloc(QNUM_BYTES(num), GFP_KERNEL);
144165 + if (!pool->bits) {
144166 + kfree(pool);
144167 + return NULL;
144168 + }
144169 + /* If num is not an even multiple of QLONG_BITS (or even 8, for
144170 + * byte-oriented searching) then we fill the trailing bits with 1, to
144171 + * make them look allocated (permanently). */
144172 + for (i = num + 1; i < QNUM_BITS(num); i++)
144173 + set_bit(i, pool->bits);
144174 + return pool;
144175 +}
144176 +EXPORT_SYMBOL(qman_fqid_pool_create);
144177 +
144178 +int qman_fqid_pool_destroy(struct qman_fqid_pool *pool)
144179 +{
144180 + int ret = pool->used;
144181 + kfree(pool->bits);
144182 + kfree(pool);
144183 + return ret;
144184 +}
144185 +EXPORT_SYMBOL(qman_fqid_pool_destroy);
144186 +
144187 +int qman_fqid_pool_alloc(struct qman_fqid_pool *pool, u32 *fqid)
144188 +{
144189 + int ret;
144190 + if (pool->used == pool->total)
144191 + return -ENOMEM;
144192 + *fqid = pool->fqid_base + pool->next;
144193 + ret = test_and_set_bit(pool->next, pool->bits);
144194 + BUG_ON(ret);
144195 + if (++pool->used == pool->total)
144196 + return 0;
144197 + pool->next = find_next_zero_bit(pool->bits, pool->total, pool->next);
144198 + if (pool->next >= pool->total)
144199 + pool->next = find_first_zero_bit(pool->bits, pool->total);
144200 + BUG_ON(pool->next >= pool->total);
144201 + return 0;
144202 +}
144203 +EXPORT_SYMBOL(qman_fqid_pool_alloc);
144204 +
144205 +void qman_fqid_pool_free(struct qman_fqid_pool *pool, u32 fqid)
144206 +{
144207 + int ret;
144208 +
144209 + fqid -= pool->fqid_base;
144210 + ret = test_and_clear_bit(fqid, pool->bits);
144211 + BUG_ON(!ret);
144212 + if (pool->used-- == pool->total)
144213 + pool->next = fqid;
144214 +}
144215 +EXPORT_SYMBOL(qman_fqid_pool_free);
144216 +
144217 +u32 qman_fqid_pool_used(struct qman_fqid_pool *pool)
144218 +{
144219 + return pool->used;
144220 +}
144221 +EXPORT_SYMBOL(qman_fqid_pool_used);
144222 --- /dev/null
144223 +++ b/include/linux/fsl_bman.h
144224 @@ -0,0 +1,532 @@
144225 +/* Copyright 2008-2012 Freescale Semiconductor, Inc.
144226 + *
144227 + * Redistribution and use in source and binary forms, with or without
144228 + * modification, are permitted provided that the following conditions are met:
144229 + * * Redistributions of source code must retain the above copyright
144230 + * notice, this list of conditions and the following disclaimer.
144231 + * * Redistributions in binary form must reproduce the above copyright
144232 + * notice, this list of conditions and the following disclaimer in the
144233 + * documentation and/or other materials provided with the distribution.
144234 + * * Neither the name of Freescale Semiconductor nor the
144235 + * names of its contributors may be used to endorse or promote products
144236 + * derived from this software without specific prior written permission.
144237 + *
144238 + *
144239 + * ALTERNATIVELY, this software may be distributed under the terms of the
144240 + * GNU General Public License ("GPL") as published by the Free Software
144241 + * Foundation, either version 2 of that License or (at your option) any
144242 + * later version.
144243 + *
144244 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
144245 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
144246 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
144247 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
144248 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
144249 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
144250 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
144251 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
144252 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
144253 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
144254 + */
144255 +
144256 +#ifndef FSL_BMAN_H
144257 +#define FSL_BMAN_H
144258 +
144259 +#ifdef __cplusplus
144260 +extern "C" {
144261 +#endif
144262 +
144263 +/* Last updated for v00.79 of the BG */
144264 +
144265 +/* Portal processing (interrupt) sources */
144266 +#define BM_PIRQ_RCRI 0x00000002 /* RCR Ring (below threshold) */
144267 +#define BM_PIRQ_BSCN 0x00000001 /* Buffer depletion State Change */
144268 +
144269 +/* This wrapper represents a bit-array for the depletion state of the 64 Bman
144270 + * buffer pools. */
144271 +struct bman_depletion {
144272 + u32 __state[2];
144273 +};
144274 +#define BMAN_DEPLETION_EMPTY { { 0x00000000, 0x00000000 } }
144275 +#define BMAN_DEPLETION_FULL { { 0xffffffff, 0xffffffff } }
144276 +#define __bmdep_word(x) ((x) >> 5)
144277 +#define __bmdep_shift(x) ((x) & 0x1f)
144278 +#define __bmdep_bit(x) (0x80000000 >> __bmdep_shift(x))
144279 +static inline void bman_depletion_init(struct bman_depletion *c)
144280 +{
144281 + c->__state[0] = c->__state[1] = 0;
144282 +}
144283 +static inline void bman_depletion_fill(struct bman_depletion *c)
144284 +{
144285 + c->__state[0] = c->__state[1] = ~0;
144286 +}
144287 +static inline int bman_depletion_get(const struct bman_depletion *c, u8 bpid)
144288 +{
144289 + return c->__state[__bmdep_word(bpid)] & __bmdep_bit(bpid);
144290 +}
144291 +static inline void bman_depletion_set(struct bman_depletion *c, u8 bpid)
144292 +{
144293 + c->__state[__bmdep_word(bpid)] |= __bmdep_bit(bpid);
144294 +}
144295 +static inline void bman_depletion_unset(struct bman_depletion *c, u8 bpid)
144296 +{
144297 + c->__state[__bmdep_word(bpid)] &= ~__bmdep_bit(bpid);
144298 +}
144299 +
144300 +/* ------------------------------------------------------- */
144301 +/* --- Bman data structures (and associated constants) --- */
144302 +
144303 +/* Represents s/w corenet portal mapped data structures */
144304 +struct bm_rcr_entry; /* RCR (Release Command Ring) entries */
144305 +struct bm_mc_command; /* MC (Management Command) command */
144306 +struct bm_mc_result; /* MC result */
144307 +
144308 +/* Code-reduction, define a wrapper for 48-bit buffers. In cases where a buffer
144309 + * pool id specific to this buffer is needed (BM_RCR_VERB_CMD_BPID_MULTI,
144310 + * BM_MCC_VERB_ACQUIRE), the 'bpid' field is used. */
144311 +struct bm_buffer {
144312 + union {
144313 + struct {
144314 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
144315 + u8 __reserved1;
144316 + u8 bpid;
144317 + u16 hi; /* High 16-bits of 48-bit address */
144318 + u32 lo; /* Low 32-bits of 48-bit address */
144319 +#else
144320 + u32 lo;
144321 + u16 hi;
144322 + u8 bpid;
144323 + u8 __reserved;
144324 +#endif
144325 + };
144326 + struct {
144327 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
144328 + u64 __notaddress:16;
144329 + u64 addr:48;
144330 +#else
144331 + u64 addr:48;
144332 + u64 __notaddress:16;
144333 +#endif
144334 + };
144335 + u64 opaque;
144336 + };
144337 +} __aligned(8);
144338 +static inline u64 bm_buffer_get64(const struct bm_buffer *buf)
144339 +{
144340 + return buf->addr;
144341 +}
144342 +static inline dma_addr_t bm_buf_addr(const struct bm_buffer *buf)
144343 +{
144344 + return (dma_addr_t)buf->addr;
144345 +}
144346 +/* Macro, so we compile better if 'v' isn't always 64-bit */
144347 +#define bm_buffer_set64(buf, v) \
144348 + do { \
144349 + struct bm_buffer *__buf931 = (buf); \
144350 + __buf931->hi = upper_32_bits(v); \
144351 + __buf931->lo = lower_32_bits(v); \
144352 + } while (0)
144353 +
144354 +/* See 1.5.3.5.4: "Release Command" */
144355 +struct bm_rcr_entry {
144356 + union {
144357 + struct {
144358 + u8 __dont_write_directly__verb;
144359 + u8 bpid; /* used with BM_RCR_VERB_CMD_BPID_SINGLE */
144360 + u8 __reserved1[62];
144361 + };
144362 + struct bm_buffer bufs[8];
144363 + };
144364 +} __packed;
144365 +#define BM_RCR_VERB_VBIT 0x80
144366 +#define BM_RCR_VERB_CMD_MASK 0x70 /* one of two values; */
144367 +#define BM_RCR_VERB_CMD_BPID_SINGLE 0x20
144368 +#define BM_RCR_VERB_CMD_BPID_MULTI 0x30
144369 +#define BM_RCR_VERB_BUFCOUNT_MASK 0x0f /* values 1..8 */
144370 +
144371 +/* See 1.5.3.1: "Acquire Command" */
144372 +/* See 1.5.3.2: "Query Command" */
144373 +struct bm_mcc_acquire {
144374 + u8 bpid;
144375 + u8 __reserved1[62];
144376 +} __packed;
144377 +struct bm_mcc_query {
144378 + u8 __reserved2[63];
144379 +} __packed;
144380 +struct bm_mc_command {
144381 + u8 __dont_write_directly__verb;
144382 + union {
144383 + struct bm_mcc_acquire acquire;
144384 + struct bm_mcc_query query;
144385 + };
144386 +} __packed;
144387 +#define BM_MCC_VERB_VBIT 0x80
144388 +#define BM_MCC_VERB_CMD_MASK 0x70 /* where the verb contains; */
144389 +#define BM_MCC_VERB_CMD_ACQUIRE 0x10
144390 +#define BM_MCC_VERB_CMD_QUERY 0x40
144391 +#define BM_MCC_VERB_ACQUIRE_BUFCOUNT 0x0f /* values 1..8 go here */
144392 +
144393 +/* See 1.5.3.3: "Acquire Response" */
144394 +/* See 1.5.3.4: "Query Response" */
144395 +struct bm_pool_state {
144396 + u8 __reserved1[32];
144397 + /* "availability state" and "depletion state" */
144398 + struct {
144399 + u8 __reserved1[8];
144400 + /* Access using bman_depletion_***() */
144401 + struct bman_depletion state;
144402 + } as, ds;
144403 +};
144404 +struct bm_mc_result {
144405 + union {
144406 + struct {
144407 + u8 verb;
144408 + u8 __reserved1[63];
144409 + };
144410 + union {
144411 + struct {
144412 + u8 __reserved1;
144413 + u8 bpid;
144414 + u8 __reserved2[62];
144415 + };
144416 + struct bm_buffer bufs[8];
144417 + } acquire;
144418 + struct bm_pool_state query;
144419 + };
144420 +} __packed;
144421 +#define BM_MCR_VERB_VBIT 0x80
144422 +#define BM_MCR_VERB_CMD_MASK BM_MCC_VERB_CMD_MASK
144423 +#define BM_MCR_VERB_CMD_ACQUIRE BM_MCC_VERB_CMD_ACQUIRE
144424 +#define BM_MCR_VERB_CMD_QUERY BM_MCC_VERB_CMD_QUERY
144425 +#define BM_MCR_VERB_CMD_ERR_INVALID 0x60
144426 +#define BM_MCR_VERB_CMD_ERR_ECC 0x70
144427 +#define BM_MCR_VERB_ACQUIRE_BUFCOUNT BM_MCC_VERB_ACQUIRE_BUFCOUNT /* 0..8 */
144428 +/* Determine the "availability state" of pool 'p' from a query result 'r' */
144429 +#define BM_MCR_QUERY_AVAILABILITY(r, p) \
144430 + bman_depletion_get(&r->query.as.state, p)
144431 +/* Determine the "depletion state" of pool 'p' from a query result 'r' */
144432 +#define BM_MCR_QUERY_DEPLETION(r, p) \
144433 + bman_depletion_get(&r->query.ds.state, p)
144434 +
144435 +/*******************************************************************/
144436 +/* Managed (aka "shared" or "mux/demux") portal, high-level i/face */
144437 +/*******************************************************************/
144438 +
144439 + /* Portal and Buffer Pools */
144440 + /* ----------------------- */
144441 +/* Represents a managed portal */
144442 +struct bman_portal;
144443 +
144444 +/* This object type represents Bman buffer pools. */
144445 +struct bman_pool;
144446 +
144447 +struct bman_portal_config {
144448 + /* This is used for any "core-affine" portals, ie. default portals
144449 + * associated to the corresponding cpu. -1 implies that there is no core
144450 + * affinity configured. */
144451 + int cpu;
144452 + /* portal interrupt line */
144453 + int irq;
144454 + /* the unique index of this portal */
144455 + u32 index;
144456 + /* Is this portal shared? (If so, it has coarser locking and demuxes
144457 + * processing on behalf of other CPUs.) */
144458 + int is_shared;
144459 + /* These are the buffer pool IDs that may be used via this portal. */
144460 + struct bman_depletion mask;
144461 +};
144462 +
144463 +/* This callback type is used when handling pool depletion entry/exit. The
144464 + * 'cb_ctx' value is the opaque value associated with the pool object in
144465 + * bman_new_pool(). 'depleted' is non-zero on depletion-entry, and zero on
144466 + * depletion-exit. */
144467 +typedef void (*bman_cb_depletion)(struct bman_portal *bm,
144468 + struct bman_pool *pool, void *cb_ctx, int depleted);
144469 +
144470 +/* This struct specifies parameters for a bman_pool object. */
144471 +struct bman_pool_params {
144472 + /* index of the buffer pool to encapsulate (0-63), ignored if
144473 + * BMAN_POOL_FLAG_DYNAMIC_BPID is set. */
144474 + u32 bpid;
144475 + /* bit-mask of BMAN_POOL_FLAG_*** options */
144476 + u32 flags;
144477 + /* depletion-entry/exit callback, if BMAN_POOL_FLAG_DEPLETION is set */
144478 + bman_cb_depletion cb;
144479 + /* opaque user value passed as a parameter to 'cb' */
144480 + void *cb_ctx;
144481 + /* depletion-entry/exit thresholds, if BMAN_POOL_FLAG_THRESH is set. NB:
144482 + * this is only allowed if BMAN_POOL_FLAG_DYNAMIC_BPID is used *and*
144483 + * when run in the control plane (which controls Bman CCSR). This array
144484 + * matches the definition of bm_pool_set(). */
144485 + u32 thresholds[4];
144486 +};
144487 +
144488 +/* Flags to bman_new_pool() */
144489 +#define BMAN_POOL_FLAG_NO_RELEASE 0x00000001 /* can't release to pool */
144490 +#define BMAN_POOL_FLAG_ONLY_RELEASE 0x00000002 /* can only release to pool */
144491 +#define BMAN_POOL_FLAG_DEPLETION 0x00000004 /* track depletion entry/exit */
144492 +#define BMAN_POOL_FLAG_DYNAMIC_BPID 0x00000008 /* (de)allocate bpid */
144493 +#define BMAN_POOL_FLAG_THRESH 0x00000010 /* set depletion thresholds */
144494 +#define BMAN_POOL_FLAG_STOCKPILE 0x00000020 /* stockpile to reduce hw ops */
144495 +
144496 +/* Flags to bman_release() */
144497 +#ifdef CONFIG_FSL_DPA_CAN_WAIT
144498 +#define BMAN_RELEASE_FLAG_WAIT 0x00000001 /* wait if RCR is full */
144499 +#define BMAN_RELEASE_FLAG_WAIT_INT 0x00000002 /* if we wait, interruptible? */
144500 +#ifdef CONFIG_FSL_DPA_CAN_WAIT_SYNC
144501 +#define BMAN_RELEASE_FLAG_WAIT_SYNC 0x00000004 /* if wait, until consumed? */
144502 +#endif
144503 +#endif
144504 +#define BMAN_RELEASE_FLAG_NOW 0x00000008 /* issue immediate release */
144505 +
144506 +/* Flags to bman_acquire() */
144507 +#define BMAN_ACQUIRE_FLAG_STOCKPILE 0x00000001 /* no hw op, stockpile only */
144508 +
144509 + /* Portal Management */
144510 + /* ----------------- */
144511 +/**
144512 + * bman_get_portal_config - get portal configuration settings
144513 + *
144514 + * This returns a read-only view of the current cpu's affine portal settings.
144515 + */
144516 +const struct bman_portal_config *bman_get_portal_config(void);
144517 +
144518 +/**
144519 + * bman_irqsource_get - return the portal work that is interrupt-driven
144520 + *
144521 + * Returns a bitmask of BM_PIRQ_**I processing sources that are currently
144522 + * enabled for interrupt handling on the current cpu's affine portal. These
144523 + * sources will trigger the portal interrupt and the interrupt handler (or a
144524 + * tasklet/bottom-half it defers to) will perform the corresponding processing
144525 + * work. The bman_poll_***() functions will only process sources that are not in
144526 + * this bitmask. If the current CPU is sharing a portal hosted on another CPU,
144527 + * this always returns zero.
144528 + */
144529 +u32 bman_irqsource_get(void);
144530 +
144531 +/**
144532 + * bman_irqsource_add - add processing sources to be interrupt-driven
144533 + * @bits: bitmask of BM_PIRQ_**I processing sources
144534 + *
144535 + * Adds processing sources that should be interrupt-driven (rather than
144536 + * processed via bman_poll_***() functions). Returns zero for success, or
144537 + * -EINVAL if the current CPU is sharing a portal hosted on another CPU. */
144538 +int bman_irqsource_add(u32 bits);
144539 +
144540 +/**
144541 + * bman_irqsource_remove - remove processing sources from being interrupt-driven
144542 + * @bits: bitmask of BM_PIRQ_**I processing sources
144543 + *
144544 + * Removes processing sources from being interrupt-driven, so that they will
144545 + * instead be processed via bman_poll_***() functions. Returns zero for success,
144546 + * or -EINVAL if the current CPU is sharing a portal hosted on another CPU. */
144547 +int bman_irqsource_remove(u32 bits);
144548 +
144549 +/**
144550 + * bman_affine_cpus - return a mask of cpus that have affine portals
144551 + */
144552 +const cpumask_t *bman_affine_cpus(void);
144553 +
144554 +/**
144555 + * bman_poll_slow - process anything that isn't interrupt-driven.
144556 + *
144557 + * This function does any portal processing that isn't interrupt-driven. If the
144558 + * current CPU is sharing a portal hosted on another CPU, this function will
144559 + * return -EINVAL, otherwise the return value is a bitmask of BM_PIRQ_* sources
144560 + * indicating what interrupt sources were actually processed by the call.
144561 + *
144562 + * NB, unlike the legacy wrapper bman_poll(), this function will
144563 + * deterministically check for the presence of portal processing work and do it,
144564 + * which implies some latency even if there's nothing to do. The bman_poll()
144565 + * wrapper on the other hand (like the qman_poll() wrapper) attenuates this by
144566 + * checking for (and doing) portal processing infrequently. Ie. such that
144567 + * qman_poll() and bman_poll() can be called from core-processing loops. Use
144568 + * bman_poll_slow() when you yourself are deciding when to incur the overhead of
144569 + * processing.
144570 + */
144571 +u32 bman_poll_slow(void);
144572 +
144573 +/**
144574 + * bman_poll - process anything that isn't interrupt-driven.
144575 + *
144576 + * Dispatcher logic on a cpu can use this to trigger any maintenance of the
144577 + * affine portal. This function does whatever processing is not triggered by
144578 + * interrupts. This is a legacy wrapper that can be used in core-processing
144579 + * loops but mitigates the performance overhead of portal processing by
144580 + * adaptively bypassing true portal processing most of the time. (Processing is
144581 + * done once every 10 calls if the previous processing revealed that work needed
144582 + * to be done, or once very 1000 calls if the previous processing revealed no
144583 + * work needed doing.) If you wish to control this yourself, call
144584 + * bman_poll_slow() instead, which always checks for portal processing work.
144585 + */
144586 +void bman_poll(void);
144587 +
144588 +/**
144589 + * bman_rcr_is_empty - Determine if portal's RCR is empty
144590 + *
144591 + * For use in situations where a cpu-affine caller needs to determine when all
144592 + * releases for the local portal have been processed by Bman but can't use the
144593 + * BMAN_RELEASE_FLAG_WAIT_SYNC flag to do this from the final bman_release().
144594 + * The function forces tracking of RCR consumption (which normally doesn't
144595 + * happen until release processing needs to find space to put new release
144596 + * commands), and returns zero if the ring still has unprocessed entries,
144597 + * non-zero if it is empty.
144598 + */
144599 +int bman_rcr_is_empty(void);
144600 +
144601 +/**
144602 + * bman_alloc_bpid_range - Allocate a contiguous range of BPIDs
144603 + * @result: is set by the API to the base BPID of the allocated range
144604 + * @count: the number of BPIDs required
144605 + * @align: required alignment of the allocated range
144606 + * @partial: non-zero if the API can return fewer than @count BPIDs
144607 + *
144608 + * Returns the number of buffer pools allocated, or a negative error code. If
144609 + * @partial is non zero, the allocation request may return a smaller range of
144610 + * BPs than requested (though alignment will be as requested). If @partial is
144611 + * zero, the return value will either be 'count' or negative.
144612 + */
144613 +int bman_alloc_bpid_range(u32 *result, u32 count, u32 align, int partial);
144614 +static inline int bman_alloc_bpid(u32 *result)
144615 +{
144616 + int ret = bman_alloc_bpid_range(result, 1, 0, 0);
144617 + return (ret > 0) ? 0 : ret;
144618 +}
144619 +
144620 +/**
144621 + * bman_release_bpid_range - Release the specified range of buffer pool IDs
144622 + * @bpid: the base BPID of the range to deallocate
144623 + * @count: the number of BPIDs in the range
144624 + *
144625 + * This function can also be used to seed the allocator with ranges of BPIDs
144626 + * that it can subsequently allocate from.
144627 + */
144628 +void bman_release_bpid_range(u32 bpid, unsigned int count);
144629 +static inline void bman_release_bpid(u32 bpid)
144630 +{
144631 + bman_release_bpid_range(bpid, 1);
144632 +}
144633 +
144634 +int bman_reserve_bpid_range(u32 bpid, unsigned int count);
144635 +static inline int bman_reserve_bpid(u32 bpid)
144636 +{
144637 + return bman_reserve_bpid_range(bpid, 1);
144638 +}
144639 +
144640 +void bman_seed_bpid_range(u32 bpid, unsigned int count);
144641 +
144642 +
144643 +int bman_shutdown_pool(u32 bpid);
144644 +
144645 + /* Pool management */
144646 + /* --------------- */
144647 +/**
144648 + * bman_new_pool - Allocates a Buffer Pool object
144649 + * @params: parameters specifying the buffer pool ID and behaviour
144650 + *
144651 + * Creates a pool object for the given @params. A portal and the depletion
144652 + * callback field of @params are only used if the BMAN_POOL_FLAG_DEPLETION flag
144653 + * is set. NB, the fields from @params are copied into the new pool object, so
144654 + * the structure provided by the caller can be released or reused after the
144655 + * function returns.
144656 + */
144657 +struct bman_pool *bman_new_pool(const struct bman_pool_params *params);
144658 +
144659 +/**
144660 + * bman_free_pool - Deallocates a Buffer Pool object
144661 + * @pool: the pool object to release
144662 + *
144663 + */
144664 +void bman_free_pool(struct bman_pool *pool);
144665 +
144666 +/**
144667 + * bman_get_params - Returns a pool object's parameters.
144668 + * @pool: the pool object
144669 + *
144670 + * The returned pointer refers to state within the pool object so must not be
144671 + * modified and can no longer be read once the pool object is destroyed.
144672 + */
144673 +const struct bman_pool_params *bman_get_params(const struct bman_pool *pool);
144674 +
144675 +/**
144676 + * bman_release - Release buffer(s) to the buffer pool
144677 + * @pool: the buffer pool object to release to
144678 + * @bufs: an array of buffers to release
144679 + * @num: the number of buffers in @bufs (1-8)
144680 + * @flags: bit-mask of BMAN_RELEASE_FLAG_*** options
144681 + *
144682 + * Adds the given buffers to RCR entries. If the portal @p was created with the
144683 + * "COMPACT" flag, then it will be using a compaction algorithm to improve
144684 + * utilisation of RCR. As such, these buffers may join an existing ring entry
144685 + * and/or it may not be issued right away so as to allow future releases to join
144686 + * the same ring entry. Use the BMAN_RELEASE_FLAG_NOW flag to override this
144687 + * behaviour by committing the RCR entry (or entries) right away. If the RCR
144688 + * ring is full, the function will return -EBUSY unless BMAN_RELEASE_FLAG_WAIT
144689 + * is selected, in which case it will sleep waiting for space to become
144690 + * available in RCR. If the function receives a signal before such time (and
144691 + * BMAN_RELEASE_FLAG_WAIT_INT is set), the function returns -EINTR. Otherwise,
144692 + * it returns zero.
144693 + */
144694 +int bman_release(struct bman_pool *pool, const struct bm_buffer *bufs, u8 num,
144695 + u32 flags);
144696 +
144697 +/**
144698 + * bman_acquire - Acquire buffer(s) from a buffer pool
144699 + * @pool: the buffer pool object to acquire from
144700 + * @bufs: array for storing the acquired buffers
144701 + * @num: the number of buffers desired (@bufs is at least this big)
144702 + *
144703 + * Issues an "Acquire" command via the portal's management command interface.
144704 + * The return value will be the number of buffers obtained from the pool, or a
144705 + * negative error code if a h/w error or pool starvation was encountered. In
144706 + * the latter case, the content of @bufs is undefined.
144707 + */
144708 +int bman_acquire(struct bman_pool *pool, struct bm_buffer *bufs, u8 num,
144709 + u32 flags);
144710 +
144711 +/**
144712 + * bman_flush_stockpile - Flush stockpile buffer(s) to the buffer pool
144713 + * @pool: the buffer pool object the stockpile belongs
144714 + * @flags: bit-mask of BMAN_RELEASE_FLAG_*** options
144715 + *
144716 + * Adds stockpile buffers to RCR entries until the stockpile is empty.
144717 + * The return value will be a negative error code if a h/w error occurred.
144718 + * If BMAN_RELEASE_FLAG_NOW flag is passed and RCR ring is full,
144719 + * -EAGAIN will be returned.
144720 + */
144721 +int bman_flush_stockpile(struct bman_pool *pool, u32 flags);
144722 +
144723 +/**
144724 + * bman_query_pools - Query all buffer pool states
144725 + * @state: storage for the queried availability and depletion states
144726 + */
144727 +int bman_query_pools(struct bm_pool_state *state);
144728 +
144729 +#ifdef CONFIG_FSL_BMAN_CONFIG
144730 +/**
144731 + * bman_query_free_buffers - Query how many free buffers are in buffer pool
144732 + * @pool: the buffer pool object to query
144733 + *
144734 + * Return the number of the free buffers
144735 + */
144736 +u32 bman_query_free_buffers(struct bman_pool *pool);
144737 +
144738 +/**
144739 + * bman_update_pool_thresholds - Change the buffer pool's depletion thresholds
144740 + * @pool: the buffer pool object to which the thresholds will be set
144741 + * @thresholds: the new thresholds
144742 + */
144743 +int bman_update_pool_thresholds(struct bman_pool *pool, const u32 *thresholds);
144744 +#endif
144745 +
144746 +/**
144747 + * The below bman_p_***() variant might be called in a situation that the cpu
144748 + * which the portal affine to is not online yet.
144749 + * @bman_portal specifies which portal the API will use.
144750 +*/
144751 +int bman_p_irqsource_add(struct bman_portal *p, __maybe_unused u32 bits);
144752 +#ifdef __cplusplus
144753 +}
144754 +#endif
144755 +
144756 +#endif /* FSL_BMAN_H */
144757 --- /dev/null
144758 +++ b/include/linux/fsl_qman.h
144759 @@ -0,0 +1,3888 @@
144760 +/* Copyright 2008-2012 Freescale Semiconductor, Inc.
144761 + *
144762 + * Redistribution and use in source and binary forms, with or without
144763 + * modification, are permitted provided that the following conditions are met:
144764 + * * Redistributions of source code must retain the above copyright
144765 + * notice, this list of conditions and the following disclaimer.
144766 + * * Redistributions in binary form must reproduce the above copyright
144767 + * notice, this list of conditions and the following disclaimer in the
144768 + * documentation and/or other materials provided with the distribution.
144769 + * * Neither the name of Freescale Semiconductor nor the
144770 + * names of its contributors may be used to endorse or promote products
144771 + * derived from this software without specific prior written permission.
144772 + *
144773 + *
144774 + * ALTERNATIVELY, this software may be distributed under the terms of the
144775 + * GNU General Public License ("GPL") as published by the Free Software
144776 + * Foundation, either version 2 of that License or (at your option) any
144777 + * later version.
144778 + *
144779 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
144780 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
144781 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
144782 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
144783 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
144784 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
144785 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
144786 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
144787 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
144788 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
144789 + */
144790 +
144791 +#ifndef FSL_QMAN_H
144792 +#define FSL_QMAN_H
144793 +
144794 +#ifdef __cplusplus
144795 +extern "C" {
144796 +#endif
144797 +
144798 +/* Last updated for v00.800 of the BG */
144799 +
144800 +/* Hardware constants */
144801 +#define QM_CHANNEL_SWPORTAL0 0
144802 +#define QMAN_CHANNEL_POOL1 0x21
144803 +#define QMAN_CHANNEL_CAAM 0x80
144804 +#define QMAN_CHANNEL_PME 0xa0
144805 +#define QMAN_CHANNEL_POOL1_REV3 0x401
144806 +#define QMAN_CHANNEL_CAAM_REV3 0x840
144807 +#define QMAN_CHANNEL_PME_REV3 0x860
144808 +#define QMAN_CHANNEL_DCE 0x8a0
144809 +#define QMAN_CHANNEL_DCE_QMANREV312 0x880
144810 +extern u16 qm_channel_pool1;
144811 +extern u16 qm_channel_caam;
144812 +extern u16 qm_channel_pme;
144813 +extern u16 qm_channel_dce;
144814 +enum qm_dc_portal {
144815 + qm_dc_portal_fman0 = 0,
144816 + qm_dc_portal_fman1 = 1,
144817 + qm_dc_portal_caam = 2,
144818 + qm_dc_portal_pme = 3,
144819 + qm_dc_portal_rman = 4,
144820 + qm_dc_portal_dce = 5
144821 +};
144822 +
144823 +/* Portal processing (interrupt) sources */
144824 +#define QM_PIRQ_CCSCI 0x00200000 /* CEETM Congestion State Change */
144825 +#define QM_PIRQ_CSCI 0x00100000 /* Congestion State Change */
144826 +#define QM_PIRQ_EQCI 0x00080000 /* Enqueue Command Committed */
144827 +#define QM_PIRQ_EQRI 0x00040000 /* EQCR Ring (below threshold) */
144828 +#define QM_PIRQ_DQRI 0x00020000 /* DQRR Ring (non-empty) */
144829 +#define QM_PIRQ_MRI 0x00010000 /* MR Ring (non-empty) */
144830 +/* This mask contains all the interrupt sources that need handling except DQRI,
144831 + * ie. that if present should trigger slow-path processing. */
144832 +#define QM_PIRQ_SLOW (QM_PIRQ_CSCI | QM_PIRQ_EQCI | QM_PIRQ_EQRI | \
144833 + QM_PIRQ_MRI | QM_PIRQ_CCSCI)
144834 +
144835 +/* --- Clock speed --- */
144836 +/* A qman driver instance may or may not know the current qman clock speed.
144837 + * However, certain CEETM calculations may not be possible if this is not known.
144838 + * The 'set' function will only succeed (return zero) if the driver did not
144839 + * already know the clock speed. Likewise, the 'get' function will only succeed
144840 + * if the driver does know the clock speed (either because it knew when booting,
144841 + * or was told via 'set'). In cases where software is running on a driver
144842 + * instance that does not know the clock speed (eg. on a hypervised data-plane),
144843 + * and the user can obtain the current qman clock speed by other means (eg. from
144844 + * a message sent from the control-plane), then the 'set' function can be used
144845 + * to enable rate-calculations in a driver where it would otherwise not be
144846 + * possible. */
144847 +int qm_get_clock(u64 *clock_hz);
144848 +int qm_set_clock(u64 clock_hz);
144849 +
144850 +/* For qman_static_dequeue_*** APIs */
144851 +#define QM_SDQCR_CHANNELS_POOL_MASK 0x00007fff
144852 +/* for n in [1,15] */
144853 +#define QM_SDQCR_CHANNELS_POOL(n) (0x00008000 >> (n))
144854 +/* for conversion from n of qm_channel */
144855 +static inline u32 QM_SDQCR_CHANNELS_POOL_CONV(u16 channel)
144856 +{
144857 + return QM_SDQCR_CHANNELS_POOL(channel + 1 - qm_channel_pool1);
144858 +}
144859 +
144860 +/* For qman_volatile_dequeue(); Choose one PRECEDENCE. EXACT is optional. Use
144861 + * NUMFRAMES(n) (6-bit) or NUMFRAMES_TILLEMPTY to fill in the frame-count. Use
144862 + * FQID(n) to fill in the frame queue ID. */
144863 +#define QM_VDQCR_PRECEDENCE_VDQCR 0x0
144864 +#define QM_VDQCR_PRECEDENCE_SDQCR 0x80000000
144865 +#define QM_VDQCR_EXACT 0x40000000
144866 +#define QM_VDQCR_NUMFRAMES_MASK 0x3f000000
144867 +#define QM_VDQCR_NUMFRAMES_SET(n) (((n) & 0x3f) << 24)
144868 +#define QM_VDQCR_NUMFRAMES_GET(n) (((n) >> 24) & 0x3f)
144869 +#define QM_VDQCR_NUMFRAMES_TILLEMPTY QM_VDQCR_NUMFRAMES_SET(0)
144870 +
144871 +
144872 +/* ------------------------------------------------------- */
144873 +/* --- Qman data structures (and associated constants) --- */
144874 +
144875 +/* Represents s/w corenet portal mapped data structures */
144876 +struct qm_eqcr_entry; /* EQCR (EnQueue Command Ring) entries */
144877 +struct qm_dqrr_entry; /* DQRR (DeQueue Response Ring) entries */
144878 +struct qm_mr_entry; /* MR (Message Ring) entries */
144879 +struct qm_mc_command; /* MC (Management Command) command */
144880 +struct qm_mc_result; /* MC result */
144881 +
144882 +/* See David Lapp's "Frame formats" document, "dpateam", Jan 07, 2008 */
144883 +#define QM_FD_FORMAT_SG 0x4
144884 +#define QM_FD_FORMAT_LONG 0x2
144885 +#define QM_FD_FORMAT_COMPOUND 0x1
144886 +enum qm_fd_format {
144887 + /* 'contig' implies a contiguous buffer, whereas 'sg' implies a
144888 + * scatter-gather table. 'big' implies a 29-bit length with no offset
144889 + * field, otherwise length is 20-bit and offset is 9-bit. 'compound'
144890 + * implies a s/g-like table, where each entry itself represents a frame
144891 + * (contiguous or scatter-gather) and the 29-bit "length" is
144892 + * interpreted purely for congestion calculations, ie. a "congestion
144893 + * weight". */
144894 + qm_fd_contig = 0,
144895 + qm_fd_contig_big = QM_FD_FORMAT_LONG,
144896 + qm_fd_sg = QM_FD_FORMAT_SG,
144897 + qm_fd_sg_big = QM_FD_FORMAT_SG | QM_FD_FORMAT_LONG,
144898 + qm_fd_compound = QM_FD_FORMAT_COMPOUND
144899 +};
144900 +
144901 +/* Capitalised versions are un-typed but can be used in static expressions */
144902 +#define QM_FD_CONTIG 0
144903 +#define QM_FD_CONTIG_BIG QM_FD_FORMAT_LONG
144904 +#define QM_FD_SG QM_FD_FORMAT_SG
144905 +#define QM_FD_SG_BIG (QM_FD_FORMAT_SG | QM_FD_FORMAT_LONG)
144906 +#define QM_FD_COMPOUND QM_FD_FORMAT_COMPOUND
144907 +
144908 +/* See 1.5.1.1: "Frame Descriptor (FD)" */
144909 +struct qm_fd {
144910 + union {
144911 + struct {
144912 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
144913 + u8 dd:2; /* dynamic debug */
144914 + u8 liodn_offset:6;
144915 + u8 bpid:8; /* Buffer Pool ID */
144916 + u8 eliodn_offset:4;
144917 + u8 __reserved:4;
144918 + u8 addr_hi; /* high 8-bits of 40-bit address */
144919 + u32 addr_lo; /* low 32-bits of 40-bit address */
144920 +#else
144921 + u32 addr_lo; /* low 32-bits of 40-bit address */
144922 + u8 addr_hi; /* high 8-bits of 40-bit address */
144923 + u8 __reserved:4;
144924 + u8 eliodn_offset:4;
144925 + u8 bpid:8; /* Buffer Pool ID */
144926 + u8 liodn_offset:6;
144927 + u8 dd:2; /* dynamic debug */
144928 +#endif
144929 + };
144930 + struct {
144931 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
144932 + u64 __notaddress:24;
144933 + u64 addr:40;
144934 +#else
144935 + u64 addr:40;
144936 + u64 __notaddress:24;
144937 +#endif
144938 + };
144939 + u64 opaque_addr;
144940 + };
144941 + /* The 'format' field indicates the interpretation of the remaining 29
144942 + * bits of the 32-bit word. For packing reasons, it is duplicated in the
144943 + * other union elements. Note, union'd structs are difficult to use with
144944 + * static initialisation under gcc, in which case use the "opaque" form
144945 + * with one of the macros. */
144946 + union {
144947 + /* For easier/faster copying of this part of the fd (eg. from a
144948 + * DQRR entry to an EQCR entry) copy 'opaque' */
144949 + u32 opaque;
144950 + /* If 'format' is _contig or _sg, 20b length and 9b offset */
144951 + struct {
144952 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
144953 + enum qm_fd_format format:3;
144954 + u16 offset:9;
144955 + u32 length20:20;
144956 +#else
144957 + u32 length20:20;
144958 + u16 offset:9;
144959 + enum qm_fd_format format:3;
144960 +#endif
144961 + };
144962 + /* If 'format' is _contig_big or _sg_big, 29b length */
144963 + struct {
144964 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
144965 + enum qm_fd_format _format1:3;
144966 + u32 length29:29;
144967 +#else
144968 + u32 length29:29;
144969 + enum qm_fd_format _format1:3;
144970 +#endif
144971 + };
144972 + /* If 'format' is _compound, 29b "congestion weight" */
144973 + struct {
144974 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
144975 + enum qm_fd_format _format2:3;
144976 + u32 cong_weight:29;
144977 +#else
144978 + u32 cong_weight:29;
144979 + enum qm_fd_format _format2:3;
144980 +#endif
144981 + };
144982 + };
144983 + union {
144984 + u32 cmd;
144985 + u32 status;
144986 + };
144987 +} __aligned(8);
144988 +#define QM_FD_DD_NULL 0x00
144989 +#define QM_FD_PID_MASK 0x3f
144990 +static inline u64 qm_fd_addr_get64(const struct qm_fd *fd)
144991 +{
144992 + return fd->addr;
144993 +}
144994 +
144995 +static inline dma_addr_t qm_fd_addr(const struct qm_fd *fd)
144996 +{
144997 + return (dma_addr_t)fd->addr;
144998 +}
144999 +/* Macro, so we compile better if 'v' isn't always 64-bit */
145000 +#define qm_fd_addr_set64(fd, v) \
145001 + do { \
145002 + struct qm_fd *__fd931 = (fd); \
145003 + __fd931->addr = v; \
145004 + } while (0)
145005 +
145006 +/* For static initialisation of FDs (which is complicated by the use of unions
145007 + * in "struct qm_fd"), use the following macros. Note that;
145008 + * - 'dd', 'pid' and 'bpid' are ignored because there's no static initialisation
145009 + * use-case),
145010 + * - use capitalised QM_FD_*** formats for static initialisation.
145011 + */
145012 +#define QM_FD_FMT_20(cmd, addr_hi, addr_lo, fmt, off, len) \
145013 + { 0, 0, 0, 0, 0, addr_hi, addr_lo, \
145014 + { (((fmt)&0x7) << 29) | (((off)&0x1ff) << 20) | ((len)&0xfffff) }, \
145015 + { cmd } }
145016 +#define QM_FD_FMT_29(cmd, addr_hi, addr_lo, fmt, len) \
145017 + { 0, 0, 0, 0, 0, addr_hi, addr_lo, \
145018 + { (((fmt)&0x7) << 29) | ((len)&0x1fffffff) }, \
145019 + { cmd } }
145020 +
145021 +/* See 2.2.1.3 Multi-Core Datapath Acceleration Architecture */
145022 +#define QM_SG_OFFSET_MASK 0x1FFF
145023 +struct qm_sg_entry {
145024 + union {
145025 + struct {
145026 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
145027 + u8 __reserved1[3];
145028 + u8 addr_hi; /* high 8-bits of 40-bit address */
145029 + u32 addr_lo; /* low 32-bits of 40-bit address */
145030 +#else
145031 + u32 addr_lo; /* low 32-bits of 40-bit address */
145032 + u8 addr_hi; /* high 8-bits of 40-bit address */
145033 + u8 __reserved1[3];
145034 +#endif
145035 + };
145036 + struct {
145037 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
145038 + u64 __notaddress:24;
145039 + u64 addr:40;
145040 +#else
145041 + u64 addr:40;
145042 + u64 __notaddress:24;
145043 +#endif
145044 + };
145045 + u64 opaque;
145046 + };
145047 + union {
145048 + struct {
145049 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
145050 + u32 extension:1; /* Extension bit */
145051 + u32 final:1; /* Final bit */
145052 + u32 length:30;
145053 +#else
145054 + u32 length:30;
145055 + u32 final:1; /* Final bit */
145056 + u32 extension:1; /* Extension bit */
145057 +#endif
145058 + };
145059 + u32 sgt_efl;
145060 + };
145061 + u8 __reserved2;
145062 + u8 bpid;
145063 + union {
145064 + struct {
145065 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
145066 + u16 __reserved3:3;
145067 + u16 offset:13;
145068 +#else
145069 + u16 offset:13;
145070 + u16 __reserved3:3;
145071 +#endif
145072 + };
145073 + u16 opaque_offset;
145074 + };
145075 +} __packed;
145076 +union qm_sg_efl {
145077 + struct {
145078 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
145079 + u32 extension:1; /* Extension bit */
145080 + u32 final:1; /* Final bit */
145081 + u32 length:30;
145082 +#else
145083 + u32 length:30;
145084 + u32 final:1; /* Final bit */
145085 + u32 extension:1; /* Extension bit */
145086 +#endif
145087 + };
145088 + u32 efl;
145089 +};
145090 +static inline dma_addr_t qm_sg_addr(const struct qm_sg_entry *sg)
145091 +{
145092 + return (dma_addr_t)be64_to_cpu(sg->opaque) & 0xffffffffffULL;
145093 +}
145094 +static inline u8 qm_sg_entry_get_ext(const struct qm_sg_entry *sg)
145095 +{
145096 + union qm_sg_efl u;
145097 +
145098 + u.efl = be32_to_cpu(sg->sgt_efl);
145099 + return u.extension;
145100 +}
145101 +static inline u8 qm_sg_entry_get_final(const struct qm_sg_entry *sg)
145102 +{
145103 + union qm_sg_efl u;
145104 +
145105 + u.efl = be32_to_cpu(sg->sgt_efl);
145106 + return u.final;
145107 +}
145108 +static inline u32 qm_sg_entry_get_len(const struct qm_sg_entry *sg)
145109 +{
145110 + union qm_sg_efl u;
145111 +
145112 + u.efl = be32_to_cpu(sg->sgt_efl);
145113 + return u.length;
145114 +}
145115 +static inline u8 qm_sg_entry_get_bpid(const struct qm_sg_entry *sg)
145116 +{
145117 + return sg->bpid;
145118 +}
145119 +static inline u16 qm_sg_entry_get_offset(const struct qm_sg_entry *sg)
145120 +{
145121 + u32 opaque_offset = be16_to_cpu(sg->opaque_offset);
145122 +
145123 + return opaque_offset & 0x1fff;
145124 +}
145125 +
145126 +/* Macro, so we compile better if 'v' isn't always 64-bit */
145127 +#define qm_sg_entry_set64(sg, v) \
145128 + do { \
145129 + struct qm_sg_entry *__sg931 = (sg); \
145130 + __sg931->opaque = cpu_to_be64(v); \
145131 + } while (0)
145132 +#define qm_sg_entry_set_ext(sg, v) \
145133 + do { \
145134 + union qm_sg_efl __u932; \
145135 + __u932.efl = be32_to_cpu((sg)->sgt_efl); \
145136 + __u932.extension = v; \
145137 + (sg)->sgt_efl = cpu_to_be32(__u932.efl); \
145138 + } while (0)
145139 +#define qm_sg_entry_set_final(sg, v) \
145140 + do { \
145141 + union qm_sg_efl __u933; \
145142 + __u933.efl = be32_to_cpu((sg)->sgt_efl); \
145143 + __u933.final = v; \
145144 + (sg)->sgt_efl = cpu_to_be32(__u933.efl); \
145145 + } while (0)
145146 +#define qm_sg_entry_set_len(sg, v) \
145147 + do { \
145148 + union qm_sg_efl __u934; \
145149 + __u934.efl = be32_to_cpu((sg)->sgt_efl); \
145150 + __u934.length = v; \
145151 + (sg)->sgt_efl = cpu_to_be32(__u934.efl); \
145152 + } while (0)
145153 +#define qm_sg_entry_set_bpid(sg, v) \
145154 + do { \
145155 + struct qm_sg_entry *__u935 = (sg); \
145156 + __u935->bpid = v; \
145157 + } while (0)
145158 +#define qm_sg_entry_set_offset(sg, v) \
145159 + do { \
145160 + struct qm_sg_entry *__u936 = (sg); \
145161 + __u936->opaque_offset = cpu_to_be16(v); \
145162 + } while (0)
145163 +
145164 +/* See 1.5.8.1: "Enqueue Command" */
145165 +struct qm_eqcr_entry {
145166 + u8 __dont_write_directly__verb;
145167 + u8 dca;
145168 + u16 seqnum;
145169 + u32 orp; /* 24-bit */
145170 + u32 fqid; /* 24-bit */
145171 + u32 tag;
145172 + struct qm_fd fd;
145173 + u8 __reserved3[32];
145174 +} __packed;
145175 +#define QM_EQCR_VERB_VBIT 0x80
145176 +#define QM_EQCR_VERB_CMD_MASK 0x61 /* but only one value; */
145177 +#define QM_EQCR_VERB_CMD_ENQUEUE 0x01
145178 +#define QM_EQCR_VERB_COLOUR_MASK 0x18 /* 4 possible values; */
145179 +#define QM_EQCR_VERB_COLOUR_GREEN 0x00
145180 +#define QM_EQCR_VERB_COLOUR_YELLOW 0x08
145181 +#define QM_EQCR_VERB_COLOUR_RED 0x10
145182 +#define QM_EQCR_VERB_COLOUR_OVERRIDE 0x18
145183 +#define QM_EQCR_VERB_INTERRUPT 0x04 /* on command consumption */
145184 +#define QM_EQCR_VERB_ORP 0x02 /* enable order restoration */
145185 +#define QM_EQCR_DCA_ENABLE 0x80
145186 +#define QM_EQCR_DCA_PARK 0x40
145187 +#define QM_EQCR_DCA_IDXMASK 0x0f /* "DQRR::idx" goes here */
145188 +#define QM_EQCR_SEQNUM_NESN 0x8000 /* Advance NESN */
145189 +#define QM_EQCR_SEQNUM_NLIS 0x4000 /* More fragments to come */
145190 +#define QM_EQCR_SEQNUM_SEQMASK 0x3fff /* sequence number goes here */
145191 +#define QM_EQCR_FQID_NULL 0 /* eg. for an ORP seqnum hole */
145192 +
145193 +/* See 1.5.8.2: "Frame Dequeue Response" */
145194 +struct qm_dqrr_entry {
145195 + u8 verb;
145196 + u8 stat;
145197 + u16 seqnum; /* 15-bit */
145198 + u8 tok;
145199 + u8 __reserved2[3];
145200 + u32 fqid; /* 24-bit */
145201 + u32 contextB;
145202 + struct qm_fd fd;
145203 + u8 __reserved4[32];
145204 +};
145205 +#define QM_DQRR_VERB_VBIT 0x80
145206 +#define QM_DQRR_VERB_MASK 0x7f /* where the verb contains; */
145207 +#define QM_DQRR_VERB_FRAME_DEQUEUE 0x60 /* "this format" */
145208 +#define QM_DQRR_STAT_FQ_EMPTY 0x80 /* FQ empty */
145209 +#define QM_DQRR_STAT_FQ_HELDACTIVE 0x40 /* FQ held active */
145210 +#define QM_DQRR_STAT_FQ_FORCEELIGIBLE 0x20 /* FQ was force-eligible'd */
145211 +#define QM_DQRR_STAT_FD_VALID 0x10 /* has a non-NULL FD */
145212 +#define QM_DQRR_STAT_UNSCHEDULED 0x02 /* Unscheduled dequeue */
145213 +#define QM_DQRR_STAT_DQCR_EXPIRED 0x01 /* VDQCR or PDQCR expired*/
145214 +
145215 +/* See 1.5.8.3: "ERN Message Response" */
145216 +/* See 1.5.8.4: "FQ State Change Notification" */
145217 +struct qm_mr_entry {
145218 + u8 verb;
145219 + union {
145220 + struct {
145221 + u8 dca;
145222 + u16 seqnum;
145223 + u8 rc; /* Rejection Code */
145224 + u32 orp:24;
145225 + u32 fqid; /* 24-bit */
145226 + u32 tag;
145227 + struct qm_fd fd;
145228 + } __packed ern;
145229 + struct {
145230 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
145231 + u8 colour:2; /* See QM_MR_DCERN_COLOUR_* */
145232 + u8 __reserved1:3;
145233 + enum qm_dc_portal portal:3;
145234 +#else
145235 + enum qm_dc_portal portal:3;
145236 + u8 __reserved1:3;
145237 + u8 colour:2; /* See QM_MR_DCERN_COLOUR_* */
145238 +#endif
145239 + u16 __reserved2;
145240 + u8 rc; /* Rejection Code */
145241 + u32 __reserved3:24;
145242 + u32 fqid; /* 24-bit */
145243 + u32 tag;
145244 + struct qm_fd fd;
145245 + } __packed dcern;
145246 + struct {
145247 + u8 fqs; /* Frame Queue Status */
145248 + u8 __reserved1[6];
145249 + u32 fqid; /* 24-bit */
145250 + u32 contextB;
145251 + u8 __reserved2[16];
145252 + } __packed fq; /* FQRN/FQRNI/FQRL/FQPN */
145253 + };
145254 + u8 __reserved2[32];
145255 +} __packed;
145256 +#define QM_MR_VERB_VBIT 0x80
145257 +/* The "ern" VERB bits match QM_EQCR_VERB_*** so aren't reproduced here. ERNs
145258 + * originating from direct-connect portals ("dcern") use 0x20 as a verb which
145259 + * would be invalid as a s/w enqueue verb. A s/w ERN can be distinguished from
145260 + * the other MR types by noting if the 0x20 bit is unset. */
145261 +#define QM_MR_VERB_TYPE_MASK 0x27
145262 +#define QM_MR_VERB_DC_ERN 0x20
145263 +#define QM_MR_VERB_FQRN 0x21
145264 +#define QM_MR_VERB_FQRNI 0x22
145265 +#define QM_MR_VERB_FQRL 0x23
145266 +#define QM_MR_VERB_FQPN 0x24
145267 +#define QM_MR_RC_MASK 0xf0 /* contains one of; */
145268 +#define QM_MR_RC_CGR_TAILDROP 0x00
145269 +#define QM_MR_RC_WRED 0x10
145270 +#define QM_MR_RC_ERROR 0x20
145271 +#define QM_MR_RC_ORPWINDOW_EARLY 0x30
145272 +#define QM_MR_RC_ORPWINDOW_LATE 0x40
145273 +#define QM_MR_RC_FQ_TAILDROP 0x50
145274 +#define QM_MR_RC_ORPWINDOW_RETIRED 0x60
145275 +#define QM_MR_RC_ORP_ZERO 0x70
145276 +#define QM_MR_FQS_ORLPRESENT 0x02 /* ORL fragments to come */
145277 +#define QM_MR_FQS_NOTEMPTY 0x01 /* FQ has enqueued frames */
145278 +#define QM_MR_DCERN_COLOUR_GREEN 0x00
145279 +#define QM_MR_DCERN_COLOUR_YELLOW 0x01
145280 +#define QM_MR_DCERN_COLOUR_RED 0x02
145281 +#define QM_MR_DCERN_COLOUR_OVERRIDE 0x03
145282 +
145283 +/* An identical structure of FQD fields is present in the "Init FQ" command and
145284 + * the "Query FQ" result, it's suctioned out into the "struct qm_fqd" type.
145285 + * Within that, the 'stashing' and 'taildrop' pieces are also factored out, the
145286 + * latter has two inlines to assist with converting to/from the mant+exp
145287 + * representation. */
145288 +struct qm_fqd_stashing {
145289 + /* See QM_STASHING_EXCL_<...> */
145290 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
145291 + u8 exclusive;
145292 + u8 __reserved1:2;
145293 + /* Numbers of cachelines */
145294 + u8 annotation_cl:2;
145295 + u8 data_cl:2;
145296 + u8 context_cl:2;
145297 +#else
145298 + u8 context_cl:2;
145299 + u8 data_cl:2;
145300 + u8 annotation_cl:2;
145301 + u8 __reserved1:2;
145302 + u8 exclusive;
145303 +#endif
145304 +} __packed;
145305 +struct qm_fqd_taildrop {
145306 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
145307 + u16 __reserved1:3;
145308 + u16 mant:8;
145309 + u16 exp:5;
145310 +#else
145311 + u16 exp:5;
145312 + u16 mant:8;
145313 + u16 __reserved1:3;
145314 +#endif
145315 +} __packed;
145316 +struct qm_fqd_oac {
145317 + /* See QM_OAC_<...> */
145318 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
145319 + u8 oac:2; /* "Overhead Accounting Control" */
145320 + u8 __reserved1:6;
145321 +#else
145322 + u8 __reserved1:6;
145323 + u8 oac:2; /* "Overhead Accounting Control" */
145324 +#endif
145325 + /* Two's-complement value (-128 to +127) */
145326 + signed char oal; /* "Overhead Accounting Length" */
145327 +} __packed;
145328 +struct qm_fqd {
145329 + union {
145330 + u8 orpc;
145331 + struct {
145332 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
145333 + u8 __reserved1:2;
145334 + u8 orprws:3;
145335 + u8 oa:1;
145336 + u8 olws:2;
145337 +#else
145338 + u8 olws:2;
145339 + u8 oa:1;
145340 + u8 orprws:3;
145341 + u8 __reserved1:2;
145342 +#endif
145343 + } __packed;
145344 + };
145345 + u8 cgid;
145346 + u16 fq_ctrl; /* See QM_FQCTRL_<...> */
145347 + union {
145348 + u16 dest_wq;
145349 + struct {
145350 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
145351 + u16 channel:13; /* qm_channel */
145352 + u16 wq:3;
145353 +#else
145354 + u16 wq:3;
145355 + u16 channel:13; /* qm_channel */
145356 +#endif
145357 + } __packed dest;
145358 + };
145359 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
145360 + u16 __reserved2:1;
145361 + u16 ics_cred:15;
145362 +#else
145363 + u16 __reserved2:1;
145364 + u16 ics_cred:15;
145365 +#endif
145366 + /* For "Initialize Frame Queue" commands, the write-enable mask
145367 + * determines whether 'td' or 'oac_init' is observed. For query
145368 + * commands, this field is always 'td', and 'oac_query' (below) reflects
145369 + * the Overhead ACcounting values. */
145370 + union {
145371 + struct qm_fqd_taildrop td;
145372 + struct qm_fqd_oac oac_init;
145373 + };
145374 + u32 context_b;
145375 + union {
145376 + /* Treat it as 64-bit opaque */
145377 + u64 opaque;
145378 + struct {
145379 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
145380 + u32 hi;
145381 + u32 lo;
145382 +#else
145383 + u32 lo;
145384 + u32 hi;
145385 +#endif
145386 + };
145387 + /* Treat it as s/w portal stashing config */
145388 + /* See 1.5.6.7.1: "FQD Context_A field used for [...] */
145389 + struct {
145390 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
145391 + struct qm_fqd_stashing stashing;
145392 + /* 48-bit address of FQ context to
145393 + * stash, must be cacheline-aligned */
145394 + u16 context_hi;
145395 + u32 context_lo;
145396 +#else
145397 + u32 context_lo;
145398 + u16 context_hi;
145399 + struct qm_fqd_stashing stashing;
145400 +#endif
145401 + } __packed;
145402 + } context_a;
145403 + struct qm_fqd_oac oac_query;
145404 +} __packed;
145405 +/* 64-bit converters for context_hi/lo */
145406 +static inline u64 qm_fqd_stashing_get64(const struct qm_fqd *fqd)
145407 +{
145408 + return ((u64)fqd->context_a.context_hi << 32) |
145409 + (u64)fqd->context_a.context_lo;
145410 +}
145411 +static inline dma_addr_t qm_fqd_stashing_addr(const struct qm_fqd *fqd)
145412 +{
145413 + return (dma_addr_t)qm_fqd_stashing_get64(fqd);
145414 +}
145415 +static inline u64 qm_fqd_context_a_get64(const struct qm_fqd *fqd)
145416 +{
145417 + return ((u64)fqd->context_a.hi << 32) |
145418 + (u64)fqd->context_a.lo;
145419 +}
145420 +/* Macro, so we compile better when 'v' isn't necessarily 64-bit */
145421 +#define qm_fqd_stashing_set64(fqd, v) \
145422 + do { \
145423 + struct qm_fqd *__fqd931 = (fqd); \
145424 + __fqd931->context_a.context_hi = upper_32_bits(v); \
145425 + __fqd931->context_a.context_lo = lower_32_bits(v); \
145426 + } while (0)
145427 +#define qm_fqd_context_a_set64(fqd, v) \
145428 + do { \
145429 + struct qm_fqd *__fqd931 = (fqd); \
145430 + __fqd931->context_a.hi = upper_32_bits(v); \
145431 + __fqd931->context_a.lo = lower_32_bits(v); \
145432 + } while (0)
145433 +/* convert a threshold value into mant+exp representation */
145434 +static inline int qm_fqd_taildrop_set(struct qm_fqd_taildrop *td, u32 val,
145435 + int roundup)
145436 +{
145437 + u32 e = 0;
145438 + int oddbit = 0;
145439 + if (val > 0xe0000000)
145440 + return -ERANGE;
145441 + while (val > 0xff) {
145442 + oddbit = val & 1;
145443 + val >>= 1;
145444 + e++;
145445 + if (roundup && oddbit)
145446 + val++;
145447 + }
145448 + td->exp = e;
145449 + td->mant = val;
145450 + return 0;
145451 +}
145452 +/* and the other direction */
145453 +static inline u32 qm_fqd_taildrop_get(const struct qm_fqd_taildrop *td)
145454 +{
145455 + return (u32)td->mant << td->exp;
145456 +}
145457 +
145458 +/* See 1.5.2.2: "Frame Queue Descriptor (FQD)" */
145459 +/* Frame Queue Descriptor (FQD) field 'fq_ctrl' uses these constants */
145460 +#define QM_FQCTRL_MASK 0x07ff /* 'fq_ctrl' flags; */
145461 +#define QM_FQCTRL_CGE 0x0400 /* Congestion Group Enable */
145462 +#define QM_FQCTRL_TDE 0x0200 /* Tail-Drop Enable */
145463 +#define QM_FQCTRL_ORP 0x0100 /* ORP Enable */
145464 +#define QM_FQCTRL_CTXASTASHING 0x0080 /* Context-A stashing */
145465 +#define QM_FQCTRL_CPCSTASH 0x0040 /* CPC Stash Enable */
145466 +#define QM_FQCTRL_FORCESFDR 0x0008 /* High-priority SFDRs */
145467 +#define QM_FQCTRL_AVOIDBLOCK 0x0004 /* Don't block active */
145468 +#define QM_FQCTRL_HOLDACTIVE 0x0002 /* Hold active in portal */
145469 +#define QM_FQCTRL_PREFERINCACHE 0x0001 /* Aggressively cache FQD */
145470 +#define QM_FQCTRL_LOCKINCACHE QM_FQCTRL_PREFERINCACHE /* older naming */
145471 +
145472 +/* See 1.5.6.7.1: "FQD Context_A field used for [...] */
145473 +/* Frame Queue Descriptor (FQD) field 'CONTEXT_A' uses these constants */
145474 +#define QM_STASHING_EXCL_ANNOTATION 0x04
145475 +#define QM_STASHING_EXCL_DATA 0x02
145476 +#define QM_STASHING_EXCL_CTX 0x01
145477 +
145478 +/* See 1.5.5.3: "Intra Class Scheduling" */
145479 +/* FQD field 'OAC' (Overhead ACcounting) uses these constants */
145480 +#define QM_OAC_ICS 0x2 /* Accounting for Intra-Class Scheduling */
145481 +#define QM_OAC_CG 0x1 /* Accounting for Congestion Groups */
145482 +
145483 +/* See 1.5.8.4: "FQ State Change Notification" */
145484 +/* This struct represents the 32-bit "WR_PARM_[GYR]" parameters in CGR fields
145485 + * and associated commands/responses. The WRED parameters are calculated from
145486 + * these fields as follows;
145487 + * MaxTH = MA * (2 ^ Mn)
145488 + * Slope = SA / (2 ^ Sn)
145489 + * MaxP = 4 * (Pn + 1)
145490 + */
145491 +struct qm_cgr_wr_parm {
145492 + union {
145493 + u32 word;
145494 + struct {
145495 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
145496 + u32 MA:8;
145497 + u32 Mn:5;
145498 + u32 SA:7; /* must be between 64-127 */
145499 + u32 Sn:6;
145500 + u32 Pn:6;
145501 +#else
145502 + u32 Pn:6;
145503 + u32 Sn:6;
145504 + u32 SA:7; /* must be between 64-127 */
145505 + u32 Mn:5;
145506 + u32 MA:8;
145507 +#endif
145508 + } __packed;
145509 + };
145510 +} __packed;
145511 +/* This struct represents the 13-bit "CS_THRES" CGR field. In the corresponding
145512 + * management commands, this is padded to a 16-bit structure field, so that's
145513 + * how we represent it here. The congestion state threshold is calculated from
145514 + * these fields as follows;
145515 + * CS threshold = TA * (2 ^ Tn)
145516 + */
145517 +struct qm_cgr_cs_thres {
145518 + union {
145519 + u16 hword;
145520 + struct {
145521 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
145522 + u16 __reserved:3;
145523 + u16 TA:8;
145524 + u16 Tn:5;
145525 +#else
145526 + u16 Tn:5;
145527 + u16 TA:8;
145528 + u16 __reserved:3;
145529 +#endif
145530 + } __packed;
145531 + };
145532 +} __packed;
145533 +/* This identical structure of CGR fields is present in the "Init/Modify CGR"
145534 + * commands and the "Query CGR" result. It's suctioned out here into its own
145535 + * struct. */
145536 +struct __qm_mc_cgr {
145537 + struct qm_cgr_wr_parm wr_parm_g;
145538 + struct qm_cgr_wr_parm wr_parm_y;
145539 + struct qm_cgr_wr_parm wr_parm_r;
145540 + u8 wr_en_g; /* boolean, use QM_CGR_EN */
145541 + u8 wr_en_y; /* boolean, use QM_CGR_EN */
145542 + u8 wr_en_r; /* boolean, use QM_CGR_EN */
145543 + u8 cscn_en; /* boolean, use QM_CGR_EN */
145544 + union {
145545 + struct {
145546 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
145547 + u16 cscn_targ_upd_ctrl; /* use QM_CSCN_TARG_UDP_ */
145548 + u16 cscn_targ_dcp_low; /* CSCN_TARG_DCP low-16bits */
145549 +#else
145550 + u16 cscn_targ_dcp_low; /* CSCN_TARG_DCP low-16bits */
145551 + u16 cscn_targ_upd_ctrl; /* use QM_CSCN_TARG_UDP_ */
145552 +#endif
145553 + };
145554 + u32 cscn_targ; /* use QM_CGR_TARG_* */
145555 + };
145556 + u8 cstd_en; /* boolean, use QM_CGR_EN */
145557 + u8 cs; /* boolean, only used in query response */
145558 + union {
145559 + /* use qm_cgr_cs_thres_set64() */
145560 + struct qm_cgr_cs_thres cs_thres;
145561 + u16 __cs_thres;
145562 + };
145563 + u8 mode; /* QMAN_CGR_MODE_FRAME not supported in rev1.0 */
145564 +} __packed;
145565 +#define QM_CGR_EN 0x01 /* For wr_en_*, cscn_en, cstd_en */
145566 +#define QM_CGR_TARG_UDP_CTRL_WRITE_BIT 0x8000 /* value written to portal bit*/
145567 +#define QM_CGR_TARG_UDP_CTRL_DCP 0x4000 /* 0: SWP, 1: DCP */
145568 +#define QM_CGR_TARG_PORTAL(n) (0x80000000 >> (n)) /* s/w portal, 0-9 */
145569 +#define QM_CGR_TARG_FMAN0 0x00200000 /* direct-connect portal: fman0 */
145570 +#define QM_CGR_TARG_FMAN1 0x00100000 /* : fman1 */
145571 +/* Convert CGR thresholds to/from "cs_thres" format */
145572 +static inline u64 qm_cgr_cs_thres_get64(const struct qm_cgr_cs_thres *th)
145573 +{
145574 + return (u64)th->TA << th->Tn;
145575 +}
145576 +static inline int qm_cgr_cs_thres_set64(struct qm_cgr_cs_thres *th, u64 val,
145577 + int roundup)
145578 +{
145579 + u32 e = 0;
145580 + int oddbit = 0;
145581 + while (val > 0xff) {
145582 + oddbit = val & 1;
145583 + val >>= 1;
145584 + e++;
145585 + if (roundup && oddbit)
145586 + val++;
145587 + }
145588 + th->Tn = e;
145589 + th->TA = val;
145590 + return 0;
145591 +}
145592 +
145593 +/* See 1.5.8.5.1: "Initialize FQ" */
145594 +/* See 1.5.8.5.2: "Query FQ" */
145595 +/* See 1.5.8.5.3: "Query FQ Non-Programmable Fields" */
145596 +/* See 1.5.8.5.4: "Alter FQ State Commands " */
145597 +/* See 1.5.8.6.1: "Initialize/Modify CGR" */
145598 +/* See 1.5.8.6.2: "CGR Test Write" */
145599 +/* See 1.5.8.6.3: "Query CGR" */
145600 +/* See 1.5.8.6.4: "Query Congestion Group State" */
145601 +struct qm_mcc_initfq {
145602 + u8 __reserved1;
145603 + u16 we_mask; /* Write Enable Mask */
145604 + u32 fqid; /* 24-bit */
145605 + u16 count; /* Initialises 'count+1' FQDs */
145606 + struct qm_fqd fqd; /* the FQD fields go here */
145607 + u8 __reserved3[30];
145608 +} __packed;
145609 +struct qm_mcc_queryfq {
145610 + u8 __reserved1[3];
145611 + u32 fqid; /* 24-bit */
145612 + u8 __reserved2[56];
145613 +} __packed;
145614 +struct qm_mcc_queryfq_np {
145615 + u8 __reserved1[3];
145616 + u32 fqid; /* 24-bit */
145617 + u8 __reserved2[56];
145618 +} __packed;
145619 +struct qm_mcc_alterfq {
145620 + u8 __reserved1[3];
145621 + u32 fqid; /* 24-bit */
145622 + u8 __reserved2;
145623 + u8 count; /* number of consecutive FQID */
145624 + u8 __reserved3[10];
145625 + u32 context_b; /* frame queue context b */
145626 + u8 __reserved4[40];
145627 +} __packed;
145628 +struct qm_mcc_initcgr {
145629 + u8 __reserved1;
145630 + u16 we_mask; /* Write Enable Mask */
145631 + struct __qm_mc_cgr cgr; /* CGR fields */
145632 + u8 __reserved2[2];
145633 + u8 cgid;
145634 + u8 __reserved4[32];
145635 +} __packed;
145636 +struct qm_mcc_cgrtestwrite {
145637 + u8 __reserved1[2];
145638 + u8 i_bcnt_hi:8;/* high 8-bits of 40-bit "Instant" */
145639 + u32 i_bcnt_lo; /* low 32-bits of 40-bit */
145640 + u8 __reserved2[23];
145641 + u8 cgid;
145642 + u8 __reserved3[32];
145643 +} __packed;
145644 +struct qm_mcc_querycgr {
145645 + u8 __reserved1[30];
145646 + u8 cgid;
145647 + u8 __reserved2[32];
145648 +} __packed;
145649 +struct qm_mcc_querycongestion {
145650 + u8 __reserved[63];
145651 +} __packed;
145652 +struct qm_mcc_querywq {
145653 + u8 __reserved;
145654 + /* select channel if verb != QUERYWQ_DEDICATED */
145655 + union {
145656 + u16 channel_wq; /* ignores wq (3 lsbits) */
145657 + struct {
145658 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
145659 + u16 id:13; /* qm_channel */
145660 + u16 __reserved1:3;
145661 +#else
145662 + u16 __reserved1:3;
145663 + u16 id:13; /* qm_channel */
145664 +#endif
145665 + } __packed channel;
145666 + };
145667 + u8 __reserved2[60];
145668 +} __packed;
145669 +
145670 +struct qm_mcc_ceetm_lfqmt_config {
145671 + u8 __reserved1[4];
145672 + u32 lfqid:24;
145673 + u8 __reserved2[2];
145674 + u16 cqid;
145675 + u8 __reserved3[2];
145676 + u16 dctidx;
145677 + u8 __reserved4[48];
145678 +} __packed;
145679 +
145680 +struct qm_mcc_ceetm_lfqmt_query {
145681 + u8 __reserved1[4];
145682 + u32 lfqid:24;
145683 + u8 __reserved2[56];
145684 +} __packed;
145685 +
145686 +struct qm_mcc_ceetm_cq_config {
145687 + u8 __reserved1;
145688 + u16 cqid;
145689 + u8 dcpid;
145690 + u8 __reserved2;
145691 + u16 ccgid;
145692 + u8 __reserved3[56];
145693 +} __packed;
145694 +
145695 +struct qm_mcc_ceetm_cq_query {
145696 + u8 __reserved1;
145697 + u16 cqid;
145698 + u8 dcpid;
145699 + u8 __reserved2[59];
145700 +} __packed;
145701 +
145702 +struct qm_mcc_ceetm_dct_config {
145703 + u8 __reserved1;
145704 + u16 dctidx;
145705 + u8 dcpid;
145706 + u8 __reserved2[15];
145707 + u32 context_b;
145708 + u64 context_a;
145709 + u8 __reserved3[32];
145710 +} __packed;
145711 +
145712 +struct qm_mcc_ceetm_dct_query {
145713 + u8 __reserved1;
145714 + u16 dctidx;
145715 + u8 dcpid;
145716 + u8 __reserved2[59];
145717 +} __packed;
145718 +
145719 +struct qm_mcc_ceetm_class_scheduler_config {
145720 + u8 __reserved1;
145721 + u16 cqcid;
145722 + u8 dcpid;
145723 + u8 __reserved2[6];
145724 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
145725 + u8 gpc_reserved:1;
145726 + u8 gpc_combine_flag:1;
145727 + u8 gpc_prio_b:3;
145728 + u8 gpc_prio_a:3;
145729 +#else
145730 + u8 gpc_prio_a:3;
145731 + u8 gpc_prio_b:3;
145732 + u8 gpc_combine_flag:1;
145733 + u8 gpc_reserved:1;
145734 +#endif
145735 + u16 crem;
145736 + u16 erem;
145737 + u8 w[8];
145738 + u8 __reserved3[40];
145739 +} __packed;
145740 +
145741 +struct qm_mcc_ceetm_class_scheduler_query {
145742 + u8 __reserved1;
145743 + u16 cqcid;
145744 + u8 dcpid;
145745 + u8 __reserved2[59];
145746 +} __packed;
145747 +
145748 +#define CEETM_COMMAND_CHANNEL_MAPPING (0 << 12)
145749 +#define CEETM_COMMAND_SP_MAPPING (1 << 12)
145750 +#define CEETM_COMMAND_CHANNEL_SHAPER (2 << 12)
145751 +#define CEETM_COMMAND_LNI_SHAPER (3 << 12)
145752 +#define CEETM_COMMAND_TCFC (4 << 12)
145753 +
145754 +#define CEETM_CCGRID_MASK 0x01FF
145755 +#define CEETM_CCGR_CM_CONFIGURE (0 << 14)
145756 +#define CEETM_CCGR_DN_CONFIGURE (1 << 14)
145757 +#define CEETM_CCGR_TEST_WRITE (2 << 14)
145758 +#define CEETM_CCGR_CM_QUERY (0 << 14)
145759 +#define CEETM_CCGR_DN_QUERY (1 << 14)
145760 +#define CEETM_CCGR_DN_QUERY_FLUSH (2 << 14)
145761 +#define CEETM_QUERY_CONGESTION_STATE (3 << 14)
145762 +
145763 +struct qm_mcc_ceetm_mapping_shaper_tcfc_config {
145764 + u8 __reserved1;
145765 + u16 cid;
145766 + u8 dcpid;
145767 + union {
145768 + struct {
145769 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
145770 + u8 map_shaped:1;
145771 + u8 map_reserved:4;
145772 + u8 map_lni_id:3;
145773 +#else
145774 + u8 map_lni_id:3;
145775 + u8 map_reserved:4;
145776 + u8 map_shaped:1;
145777 +#endif
145778 + u8 __reserved2[58];
145779 + } __packed channel_mapping;
145780 + struct {
145781 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
145782 + u8 map_reserved:5;
145783 + u8 map_lni_id:3;
145784 +#else
145785 + u8 map_lni_id:3;
145786 + u8 map_reserved:5;
145787 +#endif
145788 + u8 __reserved2[58];
145789 + } __packed sp_mapping;
145790 + struct {
145791 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
145792 + u8 cpl:1;
145793 + u8 cpl_reserved:2;
145794 + u8 oal:5;
145795 +#else
145796 + u8 oal:5;
145797 + u8 cpl_reserved:2;
145798 + u8 cpl:1;
145799 +#endif
145800 + u32 crtcr:24;
145801 + u32 ertcr:24;
145802 + u16 crtbl;
145803 + u16 ertbl;
145804 + u8 mps; /* This will be hardcoded by driver with 60 */
145805 + u8 __reserved2[47];
145806 + } __packed shaper_config;
145807 + struct {
145808 + u8 __reserved2[11];
145809 + u64 lnitcfcc;
145810 + u8 __reserved3[40];
145811 + } __packed tcfc_config;
145812 + };
145813 +} __packed;
145814 +
145815 +struct qm_mcc_ceetm_mapping_shaper_tcfc_query {
145816 + u8 __reserved1;
145817 + u16 cid;
145818 + u8 dcpid;
145819 + u8 __reserved2[59];
145820 +} __packed;
145821 +
145822 +struct qm_mcc_ceetm_ccgr_config {
145823 + u8 __reserved1;
145824 + u16 ccgrid;
145825 + u8 dcpid;
145826 + u8 __reserved2;
145827 + u16 we_mask;
145828 + union {
145829 + struct {
145830 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
145831 + u8 ctl_reserved:1;
145832 + u8 ctl_wr_en_g:1;
145833 + u8 ctl_wr_en_y:1;
145834 + u8 ctl_wr_en_r:1;
145835 + u8 ctl_td_en:1;
145836 + u8 ctl_td_mode:1;
145837 + u8 ctl_cscn_en:1;
145838 + u8 ctl_mode:1;
145839 +#else
145840 + u8 ctl_mode:1;
145841 + u8 ctl_cscn_en:1;
145842 + u8 ctl_td_mode:1;
145843 + u8 ctl_td_en:1;
145844 + u8 ctl_wr_en_r:1;
145845 + u8 ctl_wr_en_y:1;
145846 + u8 ctl_wr_en_g:1;
145847 + u8 ctl_reserved:1;
145848 +#endif
145849 + u8 cdv;
145850 + u16 cscn_tupd;
145851 + u8 oal;
145852 + u8 __reserved3;
145853 + struct qm_cgr_cs_thres cs_thres;
145854 + struct qm_cgr_cs_thres cs_thres_x;
145855 + struct qm_cgr_cs_thres td_thres;
145856 + struct qm_cgr_wr_parm wr_parm_g;
145857 + struct qm_cgr_wr_parm wr_parm_y;
145858 + struct qm_cgr_wr_parm wr_parm_r;
145859 + } __packed cm_config;
145860 + struct {
145861 + u8 dnc;
145862 + u8 dn0;
145863 + u8 dn1;
145864 + u64 dnba:40;
145865 + u8 __reserved3[2];
145866 + u16 dnth_0;
145867 + u8 __reserved4[2];
145868 + u16 dnth_1;
145869 + u8 __reserved5[8];
145870 + } __packed dn_config;
145871 + struct {
145872 + u8 __reserved3[3];
145873 + u64 i_cnt:40;
145874 + u8 __reserved4[16];
145875 + } __packed test_write;
145876 + };
145877 + u8 __reserved5[32];
145878 +} __packed;
145879 +
145880 +struct qm_mcc_ceetm_ccgr_query {
145881 + u8 __reserved1;
145882 + u16 ccgrid;
145883 + u8 dcpid;
145884 + u8 __reserved2[59];
145885 +} __packed;
145886 +
145887 +struct qm_mcc_ceetm_cq_peek_pop_xsfdrread {
145888 + u8 __reserved1;
145889 + u16 cqid;
145890 + u8 dcpid;
145891 + u8 ct;
145892 + u16 xsfdr;
145893 + u8 __reserved2[56];
145894 +} __packed;
145895 +
145896 +#define CEETM_QUERY_DEQUEUE_STATISTICS 0x00
145897 +#define CEETM_QUERY_DEQUEUE_CLEAR_STATISTICS 0x01
145898 +#define CEETM_WRITE_DEQUEUE_STATISTICS 0x02
145899 +#define CEETM_QUERY_REJECT_STATISTICS 0x03
145900 +#define CEETM_QUERY_REJECT_CLEAR_STATISTICS 0x04
145901 +#define CEETM_WRITE_REJECT_STATISTICS 0x05
145902 +struct qm_mcc_ceetm_statistics_query_write {
145903 + u8 __reserved1;
145904 + u16 cid;
145905 + u8 dcpid;
145906 + u8 ct;
145907 + u8 __reserved2[13];
145908 + u64 frm_cnt:40;
145909 + u8 __reserved3[2];
145910 + u64 byte_cnt:48;
145911 + u8 __reserved[32];
145912 +} __packed;
145913 +
145914 +struct qm_mc_command {
145915 + u8 __dont_write_directly__verb;
145916 + union {
145917 + struct qm_mcc_initfq initfq;
145918 + struct qm_mcc_queryfq queryfq;
145919 + struct qm_mcc_queryfq_np queryfq_np;
145920 + struct qm_mcc_alterfq alterfq;
145921 + struct qm_mcc_initcgr initcgr;
145922 + struct qm_mcc_cgrtestwrite cgrtestwrite;
145923 + struct qm_mcc_querycgr querycgr;
145924 + struct qm_mcc_querycongestion querycongestion;
145925 + struct qm_mcc_querywq querywq;
145926 + struct qm_mcc_ceetm_lfqmt_config lfqmt_config;
145927 + struct qm_mcc_ceetm_lfqmt_query lfqmt_query;
145928 + struct qm_mcc_ceetm_cq_config cq_config;
145929 + struct qm_mcc_ceetm_cq_query cq_query;
145930 + struct qm_mcc_ceetm_dct_config dct_config;
145931 + struct qm_mcc_ceetm_dct_query dct_query;
145932 + struct qm_mcc_ceetm_class_scheduler_config csch_config;
145933 + struct qm_mcc_ceetm_class_scheduler_query csch_query;
145934 + struct qm_mcc_ceetm_mapping_shaper_tcfc_config mst_config;
145935 + struct qm_mcc_ceetm_mapping_shaper_tcfc_query mst_query;
145936 + struct qm_mcc_ceetm_ccgr_config ccgr_config;
145937 + struct qm_mcc_ceetm_ccgr_query ccgr_query;
145938 + struct qm_mcc_ceetm_cq_peek_pop_xsfdrread cq_ppxr;
145939 + struct qm_mcc_ceetm_statistics_query_write stats_query_write;
145940 + };
145941 +} __packed;
145942 +#define QM_MCC_VERB_VBIT 0x80
145943 +#define QM_MCC_VERB_MASK 0x7f /* where the verb contains; */
145944 +#define QM_MCC_VERB_INITFQ_PARKED 0x40
145945 +#define QM_MCC_VERB_INITFQ_SCHED 0x41
145946 +#define QM_MCC_VERB_QUERYFQ 0x44
145947 +#define QM_MCC_VERB_QUERYFQ_NP 0x45 /* "non-programmable" fields */
145948 +#define QM_MCC_VERB_QUERYWQ 0x46
145949 +#define QM_MCC_VERB_QUERYWQ_DEDICATED 0x47
145950 +#define QM_MCC_VERB_ALTER_SCHED 0x48 /* Schedule FQ */
145951 +#define QM_MCC_VERB_ALTER_FE 0x49 /* Force Eligible FQ */
145952 +#define QM_MCC_VERB_ALTER_RETIRE 0x4a /* Retire FQ */
145953 +#define QM_MCC_VERB_ALTER_OOS 0x4b /* Take FQ out of service */
145954 +#define QM_MCC_VERB_ALTER_FQXON 0x4d /* FQ XON */
145955 +#define QM_MCC_VERB_ALTER_FQXOFF 0x4e /* FQ XOFF */
145956 +#define QM_MCC_VERB_INITCGR 0x50
145957 +#define QM_MCC_VERB_MODIFYCGR 0x51
145958 +#define QM_MCC_VERB_CGRTESTWRITE 0x52
145959 +#define QM_MCC_VERB_QUERYCGR 0x58
145960 +#define QM_MCC_VERB_QUERYCONGESTION 0x59
145961 +/* INITFQ-specific flags */
145962 +#define QM_INITFQ_WE_MASK 0x01ff /* 'Write Enable' flags; */
145963 +#define QM_INITFQ_WE_OAC 0x0100
145964 +#define QM_INITFQ_WE_ORPC 0x0080
145965 +#define QM_INITFQ_WE_CGID 0x0040
145966 +#define QM_INITFQ_WE_FQCTRL 0x0020
145967 +#define QM_INITFQ_WE_DESTWQ 0x0010
145968 +#define QM_INITFQ_WE_ICSCRED 0x0008
145969 +#define QM_INITFQ_WE_TDTHRESH 0x0004
145970 +#define QM_INITFQ_WE_CONTEXTB 0x0002
145971 +#define QM_INITFQ_WE_CONTEXTA 0x0001
145972 +/* INITCGR/MODIFYCGR-specific flags */
145973 +#define QM_CGR_WE_MASK 0x07ff /* 'Write Enable Mask'; */
145974 +#define QM_CGR_WE_WR_PARM_G 0x0400
145975 +#define QM_CGR_WE_WR_PARM_Y 0x0200
145976 +#define QM_CGR_WE_WR_PARM_R 0x0100
145977 +#define QM_CGR_WE_WR_EN_G 0x0080
145978 +#define QM_CGR_WE_WR_EN_Y 0x0040
145979 +#define QM_CGR_WE_WR_EN_R 0x0020
145980 +#define QM_CGR_WE_CSCN_EN 0x0010
145981 +#define QM_CGR_WE_CSCN_TARG 0x0008
145982 +#define QM_CGR_WE_CSTD_EN 0x0004
145983 +#define QM_CGR_WE_CS_THRES 0x0002
145984 +#define QM_CGR_WE_MODE 0x0001
145985 +
145986 +/* See 1.5.9.7 CEETM Management Commands */
145987 +#define QM_CEETM_VERB_LFQMT_CONFIG 0x70
145988 +#define QM_CEETM_VERB_LFQMT_QUERY 0x71
145989 +#define QM_CEETM_VERB_CQ_CONFIG 0x72
145990 +#define QM_CEETM_VERB_CQ_QUERY 0x73
145991 +#define QM_CEETM_VERB_DCT_CONFIG 0x74
145992 +#define QM_CEETM_VERB_DCT_QUERY 0x75
145993 +#define QM_CEETM_VERB_CLASS_SCHEDULER_CONFIG 0x76
145994 +#define QM_CEETM_VERB_CLASS_SCHEDULER_QUERY 0x77
145995 +#define QM_CEETM_VERB_MAPPING_SHAPER_TCFC_CONFIG 0x78
145996 +#define QM_CEETM_VERB_MAPPING_SHAPER_TCFC_QUERY 0x79
145997 +#define QM_CEETM_VERB_CCGR_CONFIG 0x7A
145998 +#define QM_CEETM_VERB_CCGR_QUERY 0x7B
145999 +#define QM_CEETM_VERB_CQ_PEEK_POP_XFDRREAD 0x7C
146000 +#define QM_CEETM_VERB_STATISTICS_QUERY_WRITE 0x7D
146001 +
146002 +/* See 1.5.8.5.1: "Initialize FQ" */
146003 +/* See 1.5.8.5.2: "Query FQ" */
146004 +/* See 1.5.8.5.3: "Query FQ Non-Programmable Fields" */
146005 +/* See 1.5.8.5.4: "Alter FQ State Commands " */
146006 +/* See 1.5.8.6.1: "Initialize/Modify CGR" */
146007 +/* See 1.5.8.6.2: "CGR Test Write" */
146008 +/* See 1.5.8.6.3: "Query CGR" */
146009 +/* See 1.5.8.6.4: "Query Congestion Group State" */
146010 +struct qm_mcr_initfq {
146011 + u8 __reserved1[62];
146012 +} __packed;
146013 +struct qm_mcr_queryfq {
146014 + u8 __reserved1[8];
146015 + struct qm_fqd fqd; /* the FQD fields are here */
146016 + u8 __reserved2[30];
146017 +} __packed;
146018 +struct qm_mcr_queryfq_np {
146019 + u8 __reserved1;
146020 + u8 state; /* QM_MCR_NP_STATE_*** */
146021 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
146022 + u8 __reserved2;
146023 + u32 fqd_link:24;
146024 + u16 __reserved3:2;
146025 + u16 odp_seq:14;
146026 + u16 __reserved4:2;
146027 + u16 orp_nesn:14;
146028 + u16 __reserved5:1;
146029 + u16 orp_ea_hseq:15;
146030 + u16 __reserved6:1;
146031 + u16 orp_ea_tseq:15;
146032 + u8 __reserved7;
146033 + u32 orp_ea_hptr:24;
146034 + u8 __reserved8;
146035 + u32 orp_ea_tptr:24;
146036 + u8 __reserved9;
146037 + u32 pfdr_hptr:24;
146038 + u8 __reserved10;
146039 + u32 pfdr_tptr:24;
146040 + u8 __reserved11[5];
146041 + u8 __reserved12:7;
146042 + u8 is:1;
146043 + u16 ics_surp;
146044 + u32 byte_cnt;
146045 + u8 __reserved13;
146046 + u32 frm_cnt:24;
146047 + u32 __reserved14;
146048 + u16 ra1_sfdr; /* QM_MCR_NP_RA1_*** */
146049 + u16 ra2_sfdr; /* QM_MCR_NP_RA2_*** */
146050 + u16 __reserved15;
146051 + u16 od1_sfdr; /* QM_MCR_NP_OD1_*** */
146052 + u16 od2_sfdr; /* QM_MCR_NP_OD2_*** */
146053 + u16 od3_sfdr; /* QM_MCR_NP_OD3_*** */
146054 +#else
146055 + u8 __reserved2;
146056 + u32 fqd_link:24;
146057 +
146058 + u16 odp_seq:14;
146059 + u16 __reserved3:2;
146060 +
146061 + u16 orp_nesn:14;
146062 + u16 __reserved4:2;
146063 +
146064 + u16 orp_ea_hseq:15;
146065 + u16 __reserved5:1;
146066 +
146067 + u16 orp_ea_tseq:15;
146068 + u16 __reserved6:1;
146069 +
146070 + u8 __reserved7;
146071 + u32 orp_ea_hptr:24;
146072 +
146073 + u8 __reserved8;
146074 + u32 orp_ea_tptr:24;
146075 +
146076 + u8 __reserved9;
146077 + u32 pfdr_hptr:24;
146078 +
146079 + u8 __reserved10;
146080 + u32 pfdr_tptr:24;
146081 +
146082 + u8 __reserved11[5];
146083 + u8 is:1;
146084 + u8 __reserved12:7;
146085 + u16 ics_surp;
146086 + u32 byte_cnt;
146087 + u8 __reserved13;
146088 + u32 frm_cnt:24;
146089 + u32 __reserved14;
146090 + u16 ra1_sfdr; /* QM_MCR_NP_RA1_*** */
146091 + u16 ra2_sfdr; /* QM_MCR_NP_RA2_*** */
146092 + u16 __reserved15;
146093 + u16 od1_sfdr; /* QM_MCR_NP_OD1_*** */
146094 + u16 od2_sfdr; /* QM_MCR_NP_OD2_*** */
146095 + u16 od3_sfdr; /* QM_MCR_NP_OD3_*** */
146096 +#endif
146097 +} __packed;
146098 +
146099 +
146100 +struct qm_mcr_alterfq {
146101 + u8 fqs; /* Frame Queue Status */
146102 + u8 __reserved1[61];
146103 +} __packed;
146104 +struct qm_mcr_initcgr {
146105 + u8 __reserved1[62];
146106 +} __packed;
146107 +struct qm_mcr_cgrtestwrite {
146108 + u16 __reserved1;
146109 + struct __qm_mc_cgr cgr; /* CGR fields */
146110 + u8 __reserved2[3];
146111 + u32 __reserved3:24;
146112 + u32 i_bcnt_hi:8;/* high 8-bits of 40-bit "Instant" */
146113 + u32 i_bcnt_lo; /* low 32-bits of 40-bit */
146114 + u32 __reserved4:24;
146115 + u32 a_bcnt_hi:8;/* high 8-bits of 40-bit "Average" */
146116 + u32 a_bcnt_lo; /* low 32-bits of 40-bit */
146117 + u16 lgt; /* Last Group Tick */
146118 + u16 wr_prob_g;
146119 + u16 wr_prob_y;
146120 + u16 wr_prob_r;
146121 + u8 __reserved5[8];
146122 +} __packed;
146123 +struct qm_mcr_querycgr {
146124 + u16 __reserved1;
146125 + struct __qm_mc_cgr cgr; /* CGR fields */
146126 + u8 __reserved2[3];
146127 + union {
146128 + struct {
146129 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
146130 + u32 __reserved3:24;
146131 + u32 i_bcnt_hi:8;/* high 8-bits of 40-bit "Instant" */
146132 + u32 i_bcnt_lo; /* low 32-bits of 40-bit */
146133 +#else
146134 + u32 i_bcnt_lo; /* low 32-bits of 40-bit */
146135 + u32 i_bcnt_hi:8;/* high 8-bits of 40-bit "Instant" */
146136 + u32 __reserved3:24;
146137 +#endif
146138 + };
146139 + u64 i_bcnt;
146140 + };
146141 + union {
146142 + struct {
146143 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
146144 + u32 __reserved4:24;
146145 + u32 a_bcnt_hi:8;/* high 8-bits of 40-bit "Average" */
146146 + u32 a_bcnt_lo; /* low 32-bits of 40-bit */
146147 +#else
146148 + u32 a_bcnt_lo; /* low 32-bits of 40-bit */
146149 + u32 a_bcnt_hi:8;/* high 8-bits of 40-bit "Average" */
146150 + u32 __reserved4:24;
146151 +#endif
146152 + };
146153 + u64 a_bcnt;
146154 + };
146155 + union {
146156 + u32 cscn_targ_swp[4];
146157 + u8 __reserved5[16];
146158 + };
146159 +} __packed;
146160 +static inline u64 qm_mcr_querycgr_i_get64(const struct qm_mcr_querycgr *q)
146161 +{
146162 + return be64_to_cpu(q->i_bcnt);
146163 +}
146164 +static inline u64 qm_mcr_querycgr_a_get64(const struct qm_mcr_querycgr *q)
146165 +{
146166 + return be64_to_cpu(q->a_bcnt);
146167 +}
146168 +static inline u64 qm_mcr_cgrtestwrite_i_get64(
146169 + const struct qm_mcr_cgrtestwrite *q)
146170 +{
146171 + return be64_to_cpu(((u64)q->i_bcnt_hi << 32) | (u64)q->i_bcnt_lo);
146172 +}
146173 +static inline u64 qm_mcr_cgrtestwrite_a_get64(
146174 + const struct qm_mcr_cgrtestwrite *q)
146175 +{
146176 + return be64_to_cpu(((u64)q->a_bcnt_hi << 32) | (u64)q->a_bcnt_lo);
146177 +}
146178 +/* Macro, so we compile better if 'v' isn't always 64-bit */
146179 +#define qm_mcr_querycgr_i_set64(q, v) \
146180 + do { \
146181 + struct qm_mcr_querycgr *__q931 = (fd); \
146182 + __q931->i_bcnt_hi = upper_32_bits(v); \
146183 + __q931->i_bcnt_lo = lower_32_bits(v); \
146184 + } while (0)
146185 +#define qm_mcr_querycgr_a_set64(q, v) \
146186 + do { \
146187 + struct qm_mcr_querycgr *__q931 = (fd); \
146188 + __q931->a_bcnt_hi = upper_32_bits(v); \
146189 + __q931->a_bcnt_lo = lower_32_bits(v); \
146190 + } while (0)
146191 +struct __qm_mcr_querycongestion {
146192 + u32 __state[8];
146193 +};
146194 +struct qm_mcr_querycongestion {
146195 + u8 __reserved[30];
146196 + /* Access this struct using QM_MCR_QUERYCONGESTION() */
146197 + struct __qm_mcr_querycongestion state;
146198 +} __packed;
146199 +struct qm_mcr_querywq {
146200 + union {
146201 + u16 channel_wq; /* ignores wq (3 lsbits) */
146202 + struct {
146203 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
146204 + u16 id:13; /* qm_channel */
146205 + u16 __reserved:3;
146206 +#else
146207 + u16 __reserved:3;
146208 + u16 id:13; /* qm_channel */
146209 +#endif
146210 + } __packed channel;
146211 + };
146212 + u8 __reserved[28];
146213 + u32 wq_len[8];
146214 +} __packed;
146215 +
146216 +/* QMAN CEETM Management Command Response */
146217 +struct qm_mcr_ceetm_lfqmt_config {
146218 + u8 __reserved1[62];
146219 +} __packed;
146220 +struct qm_mcr_ceetm_lfqmt_query {
146221 + u8 __reserved1[8];
146222 + u16 cqid;
146223 + u8 __reserved2[2];
146224 + u16 dctidx;
146225 + u8 __reserved3[2];
146226 + u16 ccgid;
146227 + u8 __reserved4[44];
146228 +} __packed;
146229 +
146230 +struct qm_mcr_ceetm_cq_config {
146231 + u8 __reserved1[62];
146232 +} __packed;
146233 +
146234 +struct qm_mcr_ceetm_cq_query {
146235 + u8 __reserved1[4];
146236 + u16 ccgid;
146237 + u16 state;
146238 + u32 pfdr_hptr:24;
146239 + u32 pfdr_tptr:24;
146240 + u16 od1_xsfdr;
146241 + u16 od2_xsfdr;
146242 + u16 od3_xsfdr;
146243 + u16 od4_xsfdr;
146244 + u16 od5_xsfdr;
146245 + u16 od6_xsfdr;
146246 + u16 ra1_xsfdr;
146247 + u16 ra2_xsfdr;
146248 + u8 __reserved2;
146249 + u32 frm_cnt:24;
146250 + u8 __reserved333[28];
146251 +} __packed;
146252 +
146253 +struct qm_mcr_ceetm_dct_config {
146254 + u8 __reserved1[62];
146255 +} __packed;
146256 +
146257 +struct qm_mcr_ceetm_dct_query {
146258 + u8 __reserved1[18];
146259 + u32 context_b;
146260 + u64 context_a;
146261 + u8 __reserved2[32];
146262 +} __packed;
146263 +
146264 +struct qm_mcr_ceetm_class_scheduler_config {
146265 + u8 __reserved1[62];
146266 +} __packed;
146267 +
146268 +struct qm_mcr_ceetm_class_scheduler_query {
146269 + u8 __reserved1[9];
146270 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
146271 + u8 gpc_reserved:1;
146272 + u8 gpc_combine_flag:1;
146273 + u8 gpc_prio_b:3;
146274 + u8 gpc_prio_a:3;
146275 +#else
146276 + u8 gpc_prio_a:3;
146277 + u8 gpc_prio_b:3;
146278 + u8 gpc_combine_flag:1;
146279 + u8 gpc_reserved:1;
146280 +#endif
146281 + u16 crem;
146282 + u16 erem;
146283 + u8 w[8];
146284 + u8 __reserved2[5];
146285 + u32 wbfslist:24;
146286 + u32 d8;
146287 + u32 d9;
146288 + u32 d10;
146289 + u32 d11;
146290 + u32 d12;
146291 + u32 d13;
146292 + u32 d14;
146293 + u32 d15;
146294 +} __packed;
146295 +
146296 +struct qm_mcr_ceetm_mapping_shaper_tcfc_config {
146297 + u16 cid;
146298 + u8 __reserved2[60];
146299 +} __packed;
146300 +
146301 +struct qm_mcr_ceetm_mapping_shaper_tcfc_query {
146302 + u16 cid;
146303 + u8 __reserved1;
146304 + union {
146305 + struct {
146306 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
146307 + u8 map_shaped:1;
146308 + u8 map_reserved:4;
146309 + u8 map_lni_id:3;
146310 +#else
146311 + u8 map_lni_id:3;
146312 + u8 map_reserved:4;
146313 + u8 map_shaped:1;
146314 +#endif
146315 + u8 __reserved2[58];
146316 + } __packed channel_mapping_query;
146317 + struct {
146318 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
146319 + u8 map_reserved:5;
146320 + u8 map_lni_id:3;
146321 +#else
146322 + u8 map_lni_id:3;
146323 + u8 map_reserved:5;
146324 +#endif
146325 + u8 __reserved2[58];
146326 + } __packed sp_mapping_query;
146327 + struct {
146328 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
146329 + u8 cpl:1;
146330 + u8 cpl_reserved:2;
146331 + u8 oal:5;
146332 +#else
146333 + u8 oal:5;
146334 + u8 cpl_reserved:2;
146335 + u8 cpl:1;
146336 +#endif
146337 + u32 crtcr:24;
146338 + u32 ertcr:24;
146339 + u16 crtbl;
146340 + u16 ertbl;
146341 + u8 mps;
146342 + u8 __reserved2[15];
146343 + u32 crat;
146344 + u32 erat;
146345 + u8 __reserved3[24];
146346 + } __packed shaper_query;
146347 + struct {
146348 + u8 __reserved1[11];
146349 + u64 lnitcfcc;
146350 + u8 __reserved3[40];
146351 + } __packed tcfc_query;
146352 + };
146353 +} __packed;
146354 +
146355 +struct qm_mcr_ceetm_ccgr_config {
146356 + u8 __reserved1[46];
146357 + union {
146358 + u8 __reserved2[8];
146359 + struct {
146360 + u16 timestamp;
146361 + u16 wr_porb_g;
146362 + u16 wr_prob_y;
146363 + u16 wr_prob_r;
146364 + } __packed test_write;
146365 + };
146366 + u8 __reserved3[8];
146367 +} __packed;
146368 +
146369 +struct qm_mcr_ceetm_ccgr_query {
146370 + u8 __reserved1[6];
146371 + union {
146372 + struct {
146373 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
146374 + u8 ctl_reserved:1;
146375 + u8 ctl_wr_en_g:1;
146376 + u8 ctl_wr_en_y:1;
146377 + u8 ctl_wr_en_r:1;
146378 + u8 ctl_td_en:1;
146379 + u8 ctl_td_mode:1;
146380 + u8 ctl_cscn_en:1;
146381 + u8 ctl_mode:1;
146382 +#else
146383 + u8 ctl_mode:1;
146384 + u8 ctl_cscn_en:1;
146385 + u8 ctl_td_mode:1;
146386 + u8 ctl_td_en:1;
146387 + u8 ctl_wr_en_r:1;
146388 + u8 ctl_wr_en_y:1;
146389 + u8 ctl_wr_en_g:1;
146390 + u8 ctl_reserved:1;
146391 +#endif
146392 + u8 cdv;
146393 + u8 __reserved2[2];
146394 + u8 oal;
146395 + u8 __reserved3;
146396 + struct qm_cgr_cs_thres cs_thres;
146397 + struct qm_cgr_cs_thres cs_thres_x;
146398 + struct qm_cgr_cs_thres td_thres;
146399 + struct qm_cgr_wr_parm wr_parm_g;
146400 + struct qm_cgr_wr_parm wr_parm_y;
146401 + struct qm_cgr_wr_parm wr_parm_r;
146402 + u16 cscn_targ_dcp;
146403 + u8 dcp_lsn;
146404 + u64 i_cnt:40;
146405 + u8 __reserved4[3];
146406 + u64 a_cnt:40;
146407 + u32 cscn_targ_swp[4];
146408 + } __packed cm_query;
146409 + struct {
146410 + u8 dnc;
146411 + u8 dn0;
146412 + u8 dn1;
146413 + u64 dnba:40;
146414 + u8 __reserved2[2];
146415 + u16 dnth_0;
146416 + u8 __reserved3[2];
146417 + u16 dnth_1;
146418 + u8 __reserved4[10];
146419 + u16 dnacc_0;
146420 + u8 __reserved5[2];
146421 + u16 dnacc_1;
146422 + u8 __reserved6[24];
146423 + } __packed dn_query;
146424 + struct {
146425 + u8 __reserved2[24];
146426 + struct __qm_mcr_querycongestion state;
146427 + } __packed congestion_state;
146428 +
146429 + };
146430 +} __packed;
146431 +
146432 +struct qm_mcr_ceetm_cq_peek_pop_xsfdrread {
146433 + u8 stat;
146434 + u8 __reserved1[11];
146435 + u16 dctidx;
146436 + struct qm_fd fd;
146437 + u8 __reserved2[32];
146438 +} __packed;
146439 +
146440 +struct qm_mcr_ceetm_statistics_query {
146441 + u8 __reserved1[17];
146442 + u64 frm_cnt:40;
146443 + u8 __reserved2[2];
146444 + u64 byte_cnt:48;
146445 + u8 __reserved3[32];
146446 +} __packed;
146447 +
146448 +struct qm_mc_result {
146449 + u8 verb;
146450 + u8 result;
146451 + union {
146452 + struct qm_mcr_initfq initfq;
146453 + struct qm_mcr_queryfq queryfq;
146454 + struct qm_mcr_queryfq_np queryfq_np;
146455 + struct qm_mcr_alterfq alterfq;
146456 + struct qm_mcr_initcgr initcgr;
146457 + struct qm_mcr_cgrtestwrite cgrtestwrite;
146458 + struct qm_mcr_querycgr querycgr;
146459 + struct qm_mcr_querycongestion querycongestion;
146460 + struct qm_mcr_querywq querywq;
146461 + struct qm_mcr_ceetm_lfqmt_config lfqmt_config;
146462 + struct qm_mcr_ceetm_lfqmt_query lfqmt_query;
146463 + struct qm_mcr_ceetm_cq_config cq_config;
146464 + struct qm_mcr_ceetm_cq_query cq_query;
146465 + struct qm_mcr_ceetm_dct_config dct_config;
146466 + struct qm_mcr_ceetm_dct_query dct_query;
146467 + struct qm_mcr_ceetm_class_scheduler_config csch_config;
146468 + struct qm_mcr_ceetm_class_scheduler_query csch_query;
146469 + struct qm_mcr_ceetm_mapping_shaper_tcfc_config mst_config;
146470 + struct qm_mcr_ceetm_mapping_shaper_tcfc_query mst_query;
146471 + struct qm_mcr_ceetm_ccgr_config ccgr_config;
146472 + struct qm_mcr_ceetm_ccgr_query ccgr_query;
146473 + struct qm_mcr_ceetm_cq_peek_pop_xsfdrread cq_ppxr;
146474 + struct qm_mcr_ceetm_statistics_query stats_query;
146475 + };
146476 +} __packed;
146477 +
146478 +#define QM_MCR_VERB_RRID 0x80
146479 +#define QM_MCR_VERB_MASK QM_MCC_VERB_MASK
146480 +#define QM_MCR_VERB_INITFQ_PARKED QM_MCC_VERB_INITFQ_PARKED
146481 +#define QM_MCR_VERB_INITFQ_SCHED QM_MCC_VERB_INITFQ_SCHED
146482 +#define QM_MCR_VERB_QUERYFQ QM_MCC_VERB_QUERYFQ
146483 +#define QM_MCR_VERB_QUERYFQ_NP QM_MCC_VERB_QUERYFQ_NP
146484 +#define QM_MCR_VERB_QUERYWQ QM_MCC_VERB_QUERYWQ
146485 +#define QM_MCR_VERB_QUERYWQ_DEDICATED QM_MCC_VERB_QUERYWQ_DEDICATED
146486 +#define QM_MCR_VERB_ALTER_SCHED QM_MCC_VERB_ALTER_SCHED
146487 +#define QM_MCR_VERB_ALTER_FE QM_MCC_VERB_ALTER_FE
146488 +#define QM_MCR_VERB_ALTER_RETIRE QM_MCC_VERB_ALTER_RETIRE
146489 +#define QM_MCR_VERB_ALTER_OOS QM_MCC_VERB_ALTER_OOS
146490 +#define QM_MCR_RESULT_NULL 0x00
146491 +#define QM_MCR_RESULT_OK 0xf0
146492 +#define QM_MCR_RESULT_ERR_FQID 0xf1
146493 +#define QM_MCR_RESULT_ERR_FQSTATE 0xf2
146494 +#define QM_MCR_RESULT_ERR_NOTEMPTY 0xf3 /* OOS fails if FQ is !empty */
146495 +#define QM_MCR_RESULT_ERR_BADCHANNEL 0xf4
146496 +#define QM_MCR_RESULT_PENDING 0xf8
146497 +#define QM_MCR_RESULT_ERR_BADCOMMAND 0xff
146498 +#define QM_MCR_NP_STATE_FE 0x10
146499 +#define QM_MCR_NP_STATE_R 0x08
146500 +#define QM_MCR_NP_STATE_MASK 0x07 /* Reads FQD::STATE; */
146501 +#define QM_MCR_NP_STATE_OOS 0x00
146502 +#define QM_MCR_NP_STATE_RETIRED 0x01
146503 +#define QM_MCR_NP_STATE_TEN_SCHED 0x02
146504 +#define QM_MCR_NP_STATE_TRU_SCHED 0x03
146505 +#define QM_MCR_NP_STATE_PARKED 0x04
146506 +#define QM_MCR_NP_STATE_ACTIVE 0x05
146507 +#define QM_MCR_NP_PTR_MASK 0x07ff /* for RA[12] & OD[123] */
146508 +#define QM_MCR_NP_RA1_NRA(v) (((v) >> 14) & 0x3) /* FQD::NRA */
146509 +#define QM_MCR_NP_RA2_IT(v) (((v) >> 14) & 0x1) /* FQD::IT */
146510 +#define QM_MCR_NP_OD1_NOD(v) (((v) >> 14) & 0x3) /* FQD::NOD */
146511 +#define QM_MCR_NP_OD3_NPC(v) (((v) >> 14) & 0x3) /* FQD::NPC */
146512 +#define QM_MCR_FQS_ORLPRESENT 0x02 /* ORL fragments to come */
146513 +#define QM_MCR_FQS_NOTEMPTY 0x01 /* FQ has enqueued frames */
146514 +/* This extracts the state for congestion group 'n' from a query response.
146515 + * Eg.
146516 + * u8 cgr = [...];
146517 + * struct qm_mc_result *res = [...];
146518 + * printf("congestion group %d congestion state: %d\n", cgr,
146519 + * QM_MCR_QUERYCONGESTION(&res->querycongestion.state, cgr));
146520 + */
146521 +#define __CGR_WORD(num) (num >> 5)
146522 +#define __CGR_SHIFT(num) (num & 0x1f)
146523 +#define __CGR_NUM (sizeof(struct __qm_mcr_querycongestion) << 3)
146524 +static inline int QM_MCR_QUERYCONGESTION(struct __qm_mcr_querycongestion *p,
146525 + u8 cgr)
146526 +{
146527 + return p->__state[__CGR_WORD(cgr)] & (0x80000000 >> __CGR_SHIFT(cgr));
146528 +}
146529 +
146530 +
146531 +/*********************/
146532 +/* Utility interface */
146533 +/*********************/
146534 +
146535 +/* Represents an allocator over a range of FQIDs. NB, accesses are not locked,
146536 + * spinlock them yourself if needed. */
146537 +struct qman_fqid_pool;
146538 +
146539 +/* Create/destroy a FQID pool, num must be a multiple of 32. NB, _destroy()
146540 + * always succeeds, but returns non-zero if there were "leaked" FQID
146541 + * allocations. */
146542 +struct qman_fqid_pool *qman_fqid_pool_create(u32 fqid_start, u32 num);
146543 +int qman_fqid_pool_destroy(struct qman_fqid_pool *pool);
146544 +/* Alloc/free a FQID from the range. _alloc() returns zero for success. */
146545 +int qman_fqid_pool_alloc(struct qman_fqid_pool *pool, u32 *fqid);
146546 +void qman_fqid_pool_free(struct qman_fqid_pool *pool, u32 fqid);
146547 +u32 qman_fqid_pool_used(struct qman_fqid_pool *pool);
146548 +
146549 +/*******************************************************************/
146550 +/* Managed (aka "shared" or "mux/demux") portal, high-level i/face */
146551 +/*******************************************************************/
146552 +
146553 + /* Portal and Frame Queues */
146554 + /* ----------------------- */
146555 +/* Represents a managed portal */
146556 +struct qman_portal;
146557 +
146558 +/* This object type represents Qman frame queue descriptors (FQD), it is
146559 + * cacheline-aligned, and initialised by qman_create_fq(). The structure is
146560 + * defined further down. */
146561 +struct qman_fq;
146562 +
146563 +/* This object type represents a Qman congestion group, it is defined further
146564 + * down. */
146565 +struct qman_cgr;
146566 +
146567 +struct qman_portal_config {
146568 + /* If the caller enables DQRR stashing (and thus wishes to operate the
146569 + * portal from only one cpu), this is the logical CPU that the portal
146570 + * will stash to. Whether stashing is enabled or not, this setting is
146571 + * also used for any "core-affine" portals, ie. default portals
146572 + * associated to the corresponding cpu. -1 implies that there is no core
146573 + * affinity configured. */
146574 + int cpu;
146575 + /* portal interrupt line */
146576 + int irq;
146577 + /* the unique index of this portal */
146578 + u32 index;
146579 + /* Is this portal shared? (If so, it has coarser locking and demuxes
146580 + * processing on behalf of other CPUs.) */
146581 + int is_shared;
146582 + /* The portal's dedicated channel id, use this value for initialising
146583 + * frame queues to target this portal when scheduled. */
146584 + u16 channel;
146585 + /* A mask of which pool channels this portal has dequeue access to
146586 + * (using QM_SDQCR_CHANNELS_POOL(n) for the bitmask) */
146587 + u32 pools;
146588 +};
146589 +
146590 +/* This enum, and the callback type that returns it, are used when handling
146591 + * dequeued frames via DQRR. Note that for "null" callbacks registered with the
146592 + * portal object (for handling dequeues that do not demux because contextB is
146593 + * NULL), the return value *MUST* be qman_cb_dqrr_consume. */
146594 +enum qman_cb_dqrr_result {
146595 + /* DQRR entry can be consumed */
146596 + qman_cb_dqrr_consume,
146597 + /* Like _consume, but requests parking - FQ must be held-active */
146598 + qman_cb_dqrr_park,
146599 + /* Does not consume, for DCA mode only. This allows out-of-order
146600 + * consumes by explicit calls to qman_dca() and/or the use of implicit
146601 + * DCA via EQCR entries. */
146602 + qman_cb_dqrr_defer,
146603 + /* Stop processing without consuming this ring entry. Exits the current
146604 + * qman_poll_dqrr() or interrupt-handling, as appropriate. If within an
146605 + * interrupt handler, the callback would typically call
146606 + * qman_irqsource_remove(QM_PIRQ_DQRI) before returning this value,
146607 + * otherwise the interrupt will reassert immediately. */
146608 + qman_cb_dqrr_stop,
146609 + /* Like qman_cb_dqrr_stop, but consumes the current entry. */
146610 + qman_cb_dqrr_consume_stop
146611 +};
146612 +typedef enum qman_cb_dqrr_result (*qman_cb_dqrr)(struct qman_portal *qm,
146613 + struct qman_fq *fq,
146614 + const struct qm_dqrr_entry *dqrr);
146615 +
146616 +/* This callback type is used when handling ERNs, FQRNs and FQRLs via MR. They
146617 + * are always consumed after the callback returns. */
146618 +typedef void (*qman_cb_mr)(struct qman_portal *qm, struct qman_fq *fq,
146619 + const struct qm_mr_entry *msg);
146620 +
146621 +/* This callback type is used when handling DCP ERNs */
146622 +typedef void (*qman_cb_dc_ern)(struct qman_portal *qm,
146623 + const struct qm_mr_entry *msg);
146624 +
146625 +/* s/w-visible states. Ie. tentatively scheduled + truly scheduled + active +
146626 + * held-active + held-suspended are just "sched". Things like "retired" will not
146627 + * be assumed until it is complete (ie. QMAN_FQ_STATE_CHANGING is set until
146628 + * then, to indicate it's completing and to gate attempts to retry the retire
146629 + * command). Note, park commands do not set QMAN_FQ_STATE_CHANGING because it's
146630 + * technically impossible in the case of enqueue DCAs (which refer to DQRR ring
146631 + * index rather than the FQ that ring entry corresponds to), so repeated park
146632 + * commands are allowed (if you're silly enough to try) but won't change FQ
146633 + * state, and the resulting park notifications move FQs from "sched" to
146634 + * "parked". */
146635 +enum qman_fq_state {
146636 + qman_fq_state_oos,
146637 + qman_fq_state_parked,
146638 + qman_fq_state_sched,
146639 + qman_fq_state_retired
146640 +};
146641 +
146642 +/* Frame queue objects (struct qman_fq) are stored within memory passed to
146643 + * qman_create_fq(), as this allows stashing of caller-provided demux callback
146644 + * pointers at no extra cost to stashing of (driver-internal) FQ state. If the
146645 + * caller wishes to add per-FQ state and have it benefit from dequeue-stashing,
146646 + * they should;
146647 + *
146648 + * (a) extend the qman_fq structure with their state; eg.
146649 + *
146650 + * // myfq is allocated and driver_fq callbacks filled in;
146651 + * struct my_fq {
146652 + * struct qman_fq base;
146653 + * int an_extra_field;
146654 + * [ ... add other fields to be associated with each FQ ...]
146655 + * } *myfq = some_my_fq_allocator();
146656 + * struct qman_fq *fq = qman_create_fq(fqid, flags, &myfq->base);
146657 + *
146658 + * // in a dequeue callback, access extra fields from 'fq' via a cast;
146659 + * struct my_fq *myfq = (struct my_fq *)fq;
146660 + * do_something_with(myfq->an_extra_field);
146661 + * [...]
146662 + *
146663 + * (b) when and if configuring the FQ for context stashing, specify how ever
146664 + * many cachelines are required to stash 'struct my_fq', to accelerate not
146665 + * only the Qman driver but the callback as well.
146666 + */
146667 +
146668 +struct qman_fq_cb {
146669 + qman_cb_dqrr dqrr; /* for dequeued frames */
146670 + qman_cb_mr ern; /* for s/w ERNs */
146671 + qman_cb_mr fqs; /* frame-queue state changes*/
146672 +};
146673 +
146674 +struct qman_fq {
146675 + /* Caller of qman_create_fq() provides these demux callbacks */
146676 + struct qman_fq_cb cb;
146677 + /* These are internal to the driver, don't touch. In particular, they
146678 + * may change, be removed, or extended (so you shouldn't rely on
146679 + * sizeof(qman_fq) being a constant). */
146680 + spinlock_t fqlock;
146681 + u32 fqid;
146682 + volatile unsigned long flags;
146683 + enum qman_fq_state state;
146684 + int cgr_groupid;
146685 + struct rb_node node;
146686 +#ifdef CONFIG_FSL_QMAN_FQ_LOOKUP
146687 + u32 key;
146688 +#endif
146689 +};
146690 +
146691 +/* This callback type is used when handling congestion group entry/exit.
146692 + * 'congested' is non-zero on congestion-entry, and zero on congestion-exit. */
146693 +typedef void (*qman_cb_cgr)(struct qman_portal *qm,
146694 + struct qman_cgr *cgr, int congested);
146695 +
146696 +struct qman_cgr {
146697 + /* Set these prior to qman_create_cgr() */
146698 + u32 cgrid; /* 0..255, but u32 to allow specials like -1, 256, etc.*/
146699 + qman_cb_cgr cb;
146700 + /* These are private to the driver */
146701 + u16 chan; /* portal channel this object is created on */
146702 + struct list_head node;
146703 +};
146704 +
146705 +/* Flags to qman_create_fq() */
146706 +#define QMAN_FQ_FLAG_NO_ENQUEUE 0x00000001 /* can't enqueue */
146707 +#define QMAN_FQ_FLAG_NO_MODIFY 0x00000002 /* can only enqueue */
146708 +#define QMAN_FQ_FLAG_TO_DCPORTAL 0x00000004 /* consumed by CAAM/PME/Fman */
146709 +#define QMAN_FQ_FLAG_LOCKED 0x00000008 /* multi-core locking */
146710 +#define QMAN_FQ_FLAG_AS_IS 0x00000010 /* query h/w state */
146711 +#define QMAN_FQ_FLAG_DYNAMIC_FQID 0x00000020 /* (de)allocate fqid */
146712 +
146713 +/* Flags to qman_destroy_fq() */
146714 +#define QMAN_FQ_DESTROY_PARKED 0x00000001 /* FQ can be parked or OOS */
146715 +
146716 +/* Flags from qman_fq_state() */
146717 +#define QMAN_FQ_STATE_CHANGING 0x80000000 /* 'state' is changing */
146718 +#define QMAN_FQ_STATE_NE 0x40000000 /* retired FQ isn't empty */
146719 +#define QMAN_FQ_STATE_ORL 0x20000000 /* retired FQ has ORL */
146720 +#define QMAN_FQ_STATE_BLOCKOOS 0xe0000000 /* if any are set, no OOS */
146721 +#define QMAN_FQ_STATE_CGR_EN 0x10000000 /* CGR enabled */
146722 +#define QMAN_FQ_STATE_VDQCR 0x08000000 /* being volatile dequeued */
146723 +
146724 +/* Flags to qman_init_fq() */
146725 +#define QMAN_INITFQ_FLAG_SCHED 0x00000001 /* schedule rather than park */
146726 +#define QMAN_INITFQ_FLAG_LOCAL 0x00000004 /* set dest portal */
146727 +
146728 +/* Flags to qman_volatile_dequeue() */
146729 +#ifdef CONFIG_FSL_DPA_CAN_WAIT
146730 +#define QMAN_VOLATILE_FLAG_WAIT 0x00000001 /* wait if VDQCR is in use */
146731 +#define QMAN_VOLATILE_FLAG_WAIT_INT 0x00000002 /* if wait, interruptible? */
146732 +#define QMAN_VOLATILE_FLAG_FINISH 0x00000004 /* wait till VDQCR completes */
146733 +#endif
146734 +
146735 +/* Flags to qman_enqueue(). NB, the strange numbering is to align with hardware,
146736 + * bit-wise. (NB: the PME API is sensitive to these precise numberings too, so
146737 + * any change here should be audited in PME.) */
146738 +#ifdef CONFIG_FSL_DPA_CAN_WAIT
146739 +#define QMAN_ENQUEUE_FLAG_WAIT 0x00010000 /* wait if EQCR is full */
146740 +#define QMAN_ENQUEUE_FLAG_WAIT_INT 0x00020000 /* if wait, interruptible? */
146741 +#ifdef CONFIG_FSL_DPA_CAN_WAIT_SYNC
146742 +#define QMAN_ENQUEUE_FLAG_WAIT_SYNC 0x00000004 /* if wait, until consumed? */
146743 +#endif
146744 +#endif
146745 +#define QMAN_ENQUEUE_FLAG_WATCH_CGR 0x00080000 /* watch congestion state */
146746 +#define QMAN_ENQUEUE_FLAG_DCA 0x00008000 /* perform enqueue-DCA */
146747 +#define QMAN_ENQUEUE_FLAG_DCA_PARK 0x00004000 /* If DCA, requests park */
146748 +#define QMAN_ENQUEUE_FLAG_DCA_PTR(p) /* If DCA, p is DQRR entry */ \
146749 + (((u32)(p) << 2) & 0x00000f00)
146750 +#define QMAN_ENQUEUE_FLAG_C_GREEN 0x00000000 /* choose one C_*** flag */
146751 +#define QMAN_ENQUEUE_FLAG_C_YELLOW 0x00000008
146752 +#define QMAN_ENQUEUE_FLAG_C_RED 0x00000010
146753 +#define QMAN_ENQUEUE_FLAG_C_OVERRIDE 0x00000018
146754 +/* For the ORP-specific qman_enqueue_orp() variant;
146755 + * - this flag indicates "Not Last In Sequence", ie. all but the final fragment
146756 + * of a frame. */
146757 +#define QMAN_ENQUEUE_FLAG_NLIS 0x01000000
146758 +/* - this flag performs no enqueue but fills in an ORP sequence number that
146759 + * would otherwise block it (eg. if a frame has been dropped). */
146760 +#define QMAN_ENQUEUE_FLAG_HOLE 0x02000000
146761 +/* - this flag performs no enqueue but advances NESN to the given sequence
146762 + * number. */
146763 +#define QMAN_ENQUEUE_FLAG_NESN 0x04000000
146764 +
146765 +/* Flags to qman_modify_cgr() */
146766 +#define QMAN_CGR_FLAG_USE_INIT 0x00000001
146767 +#define QMAN_CGR_MODE_FRAME 0x00000001
146768 +
146769 + /* Portal Management */
146770 + /* ----------------- */
146771 +/**
146772 + * qman_get_portal_config - get portal configuration settings
146773 + *
146774 + * This returns a read-only view of the current cpu's affine portal settings.
146775 + */
146776 +const struct qman_portal_config *qman_get_portal_config(void);
146777 +
146778 +/**
146779 + * qman_irqsource_get - return the portal work that is interrupt-driven
146780 + *
146781 + * Returns a bitmask of QM_PIRQ_**I processing sources that are currently
146782 + * enabled for interrupt handling on the current cpu's affine portal. These
146783 + * sources will trigger the portal interrupt and the interrupt handler (or a
146784 + * tasklet/bottom-half it defers to) will perform the corresponding processing
146785 + * work. The qman_poll_***() functions will only process sources that are not in
146786 + * this bitmask. If the current CPU is sharing a portal hosted on another CPU,
146787 + * this always returns zero.
146788 + */
146789 +u32 qman_irqsource_get(void);
146790 +
146791 +/**
146792 + * qman_irqsource_add - add processing sources to be interrupt-driven
146793 + * @bits: bitmask of QM_PIRQ_**I processing sources
146794 + *
146795 + * Adds processing sources that should be interrupt-driven (rather than
146796 + * processed via qman_poll_***() functions). Returns zero for success, or
146797 + * -EINVAL if the current CPU is sharing a portal hosted on another CPU.
146798 + */
146799 +int qman_irqsource_add(u32 bits);
146800 +
146801 +/**
146802 + * qman_irqsource_remove - remove processing sources from being interrupt-driven
146803 + * @bits: bitmask of QM_PIRQ_**I processing sources
146804 + *
146805 + * Removes processing sources from being interrupt-driven, so that they will
146806 + * instead be processed via qman_poll_***() functions. Returns zero for success,
146807 + * or -EINVAL if the current CPU is sharing a portal hosted on another CPU.
146808 + */
146809 +int qman_irqsource_remove(u32 bits);
146810 +
146811 +/**
146812 + * qman_affine_cpus - return a mask of cpus that have affine portals
146813 + */
146814 +const cpumask_t *qman_affine_cpus(void);
146815 +
146816 +/**
146817 + * qman_affine_channel - return the channel ID of an portal
146818 + * @cpu: the cpu whose affine portal is the subject of the query
146819 + *
146820 + * If @cpu is -1, the affine portal for the current CPU will be used. It is a
146821 + * bug to call this function for any value of @cpu (other than -1) that is not a
146822 + * member of the mask returned from qman_affine_cpus().
146823 + */
146824 +u16 qman_affine_channel(int cpu);
146825 +
146826 +/**
146827 + * qman_get_affine_portal - return the portal pointer affine to cpu
146828 + * @cpu: the cpu whose affine portal is the subject of the query
146829 + *
146830 + */
146831 +void *qman_get_affine_portal(int cpu);
146832 +
146833 +/**
146834 + * qman_poll_dqrr - process DQRR (fast-path) entries
146835 + * @limit: the maximum number of DQRR entries to process
146836 + *
146837 + * Use of this function requires that DQRR processing not be interrupt-driven.
146838 + * Ie. the value returned by qman_irqsource_get() should not include
146839 + * QM_PIRQ_DQRI. If the current CPU is sharing a portal hosted on another CPU,
146840 + * this function will return -EINVAL, otherwise the return value is >=0 and
146841 + * represents the number of DQRR entries processed.
146842 + */
146843 +int qman_poll_dqrr(unsigned int limit);
146844 +
146845 +/**
146846 + * qman_poll_slow - process anything (except DQRR) that isn't interrupt-driven.
146847 + *
146848 + * This function does any portal processing that isn't interrupt-driven. If the
146849 + * current CPU is sharing a portal hosted on another CPU, this function will
146850 + * return (u32)-1, otherwise the return value is a bitmask of QM_PIRQ_* sources
146851 + * indicating what interrupt sources were actually processed by the call.
146852 + */
146853 +u32 qman_poll_slow(void);
146854 +
146855 +/**
146856 + * qman_poll - legacy wrapper for qman_poll_dqrr() and qman_poll_slow()
146857 + *
146858 + * Dispatcher logic on a cpu can use this to trigger any maintenance of the
146859 + * affine portal. There are two classes of portal processing in question;
146860 + * fast-path (which involves demuxing dequeue ring (DQRR) entries and tracking
146861 + * enqueue ring (EQCR) consumption), and slow-path (which involves EQCR
146862 + * thresholds, congestion state changes, etc). This function does whatever
146863 + * processing is not triggered by interrupts.
146864 + *
146865 + * Note, if DQRR and some slow-path processing are poll-driven (rather than
146866 + * interrupt-driven) then this function uses a heuristic to determine how often
146867 + * to run slow-path processing - as slow-path processing introduces at least a
146868 + * minimum latency each time it is run, whereas fast-path (DQRR) processing is
146869 + * close to zero-cost if there is no work to be done. Applications can tune this
146870 + * behaviour themselves by using qman_poll_dqrr() and qman_poll_slow() directly
146871 + * rather than going via this wrapper.
146872 + */
146873 +void qman_poll(void);
146874 +
146875 +/**
146876 + * qman_stop_dequeues - Stop h/w dequeuing to the s/w portal
146877 + *
146878 + * Disables DQRR processing of the portal. This is reference-counted, so
146879 + * qman_start_dequeues() must be called as many times as qman_stop_dequeues() to
146880 + * truly re-enable dequeuing.
146881 + */
146882 +void qman_stop_dequeues(void);
146883 +
146884 +/**
146885 + * qman_start_dequeues - (Re)start h/w dequeuing to the s/w portal
146886 + *
146887 + * Enables DQRR processing of the portal. This is reference-counted, so
146888 + * qman_start_dequeues() must be called as many times as qman_stop_dequeues() to
146889 + * truly re-enable dequeuing.
146890 + */
146891 +void qman_start_dequeues(void);
146892 +
146893 +/**
146894 + * qman_static_dequeue_add - Add pool channels to the portal SDQCR
146895 + * @pools: bit-mask of pool channels, using QM_SDQCR_CHANNELS_POOL(n)
146896 + *
146897 + * Adds a set of pool channels to the portal's static dequeue command register
146898 + * (SDQCR). The requested pools are limited to those the portal has dequeue
146899 + * access to.
146900 + */
146901 +void qman_static_dequeue_add(u32 pools);
146902 +
146903 +/**
146904 + * qman_static_dequeue_del - Remove pool channels from the portal SDQCR
146905 + * @pools: bit-mask of pool channels, using QM_SDQCR_CHANNELS_POOL(n)
146906 + *
146907 + * Removes a set of pool channels from the portal's static dequeue command
146908 + * register (SDQCR). The requested pools are limited to those the portal has
146909 + * dequeue access to.
146910 + */
146911 +void qman_static_dequeue_del(u32 pools);
146912 +
146913 +/**
146914 + * qman_static_dequeue_get - return the portal's current SDQCR
146915 + *
146916 + * Returns the portal's current static dequeue command register (SDQCR). The
146917 + * entire register is returned, so if only the currently-enabled pool channels
146918 + * are desired, mask the return value with QM_SDQCR_CHANNELS_POOL_MASK.
146919 + */
146920 +u32 qman_static_dequeue_get(void);
146921 +
146922 +/**
146923 + * qman_dca - Perform a Discrete Consumption Acknowledgement
146924 + * @dq: the DQRR entry to be consumed
146925 + * @park_request: indicates whether the held-active @fq should be parked
146926 + *
146927 + * Only allowed in DCA-mode portals, for DQRR entries whose handler callback had
146928 + * previously returned 'qman_cb_dqrr_defer'. NB, as with the other APIs, this
146929 + * does not take a 'portal' argument but implies the core affine portal from the
146930 + * cpu that is currently executing the function. For reasons of locking, this
146931 + * function must be called from the same CPU as that which processed the DQRR
146932 + * entry in the first place.
146933 + */
146934 +void qman_dca(struct qm_dqrr_entry *dq, int park_request);
146935 +
146936 +/**
146937 + * qman_eqcr_is_empty - Determine if portal's EQCR is empty
146938 + *
146939 + * For use in situations where a cpu-affine caller needs to determine when all
146940 + * enqueues for the local portal have been processed by Qman but can't use the
146941 + * QMAN_ENQUEUE_FLAG_WAIT_SYNC flag to do this from the final qman_enqueue().
146942 + * The function forces tracking of EQCR consumption (which normally doesn't
146943 + * happen until enqueue processing needs to find space to put new enqueue
146944 + * commands), and returns zero if the ring still has unprocessed entries,
146945 + * non-zero if it is empty.
146946 + */
146947 +int qman_eqcr_is_empty(void);
146948 +
146949 +/**
146950 + * qman_set_dc_ern - Set the handler for DCP enqueue rejection notifications
146951 + * @handler: callback for processing DCP ERNs
146952 + * @affine: whether this handler is specific to the locally affine portal
146953 + *
146954 + * If a hardware block's interface to Qman (ie. its direct-connect portal, or
146955 + * DCP) is configured not to receive enqueue rejections, then any enqueues
146956 + * through that DCP that are rejected will be sent to a given software portal.
146957 + * If @affine is non-zero, then this handler will only be used for DCP ERNs
146958 + * received on the portal affine to the current CPU. If multiple CPUs share a
146959 + * portal and they all call this function, they will be setting the handler for
146960 + * the same portal! If @affine is zero, then this handler will be global to all
146961 + * portals handled by this instance of the driver. Only those portals that do
146962 + * not have their own affine handler will use the global handler.
146963 + */
146964 +void qman_set_dc_ern(qman_cb_dc_ern handler, int affine);
146965 +
146966 + /* FQ management */
146967 + /* ------------- */
146968 +/**
146969 + * qman_create_fq - Allocates a FQ
146970 + * @fqid: the index of the FQD to encapsulate, must be "Out of Service"
146971 + * @flags: bit-mask of QMAN_FQ_FLAG_*** options
146972 + * @fq: memory for storing the 'fq', with callbacks filled in
146973 + *
146974 + * Creates a frame queue object for the given @fqid, unless the
146975 + * QMAN_FQ_FLAG_DYNAMIC_FQID flag is set in @flags, in which case a FQID is
146976 + * dynamically allocated (or the function fails if none are available). Once
146977 + * created, the caller should not touch the memory at 'fq' except as extended to
146978 + * adjacent memory for user-defined fields (see the definition of "struct
146979 + * qman_fq" for more info). NO_MODIFY is only intended for enqueuing to
146980 + * pre-existing frame-queues that aren't to be otherwise interfered with, it
146981 + * prevents all other modifications to the frame queue. The TO_DCPORTAL flag
146982 + * causes the driver to honour any contextB modifications requested in the
146983 + * qm_init_fq() API, as this indicates the frame queue will be consumed by a
146984 + * direct-connect portal (PME, CAAM, or Fman). When frame queues are consumed by
146985 + * software portals, the contextB field is controlled by the driver and can't be
146986 + * modified by the caller. If the AS_IS flag is specified, management commands
146987 + * will be used on portal @p to query state for frame queue @fqid and construct
146988 + * a frame queue object based on that, rather than assuming/requiring that it be
146989 + * Out of Service.
146990 + */
146991 +int qman_create_fq(u32 fqid, u32 flags, struct qman_fq *fq);
146992 +
146993 +/**
146994 + * qman_destroy_fq - Deallocates a FQ
146995 + * @fq: the frame queue object to release
146996 + * @flags: bit-mask of QMAN_FQ_FREE_*** options
146997 + *
146998 + * The memory for this frame queue object ('fq' provided in qman_create_fq()) is
146999 + * not deallocated but the caller regains ownership, to do with as desired. The
147000 + * FQ must be in the 'out-of-service' state unless the QMAN_FQ_FREE_PARKED flag
147001 + * is specified, in which case it may also be in the 'parked' state.
147002 + */
147003 +void qman_destroy_fq(struct qman_fq *fq, u32 flags);
147004 +
147005 +/**
147006 + * qman_fq_fqid - Queries the frame queue ID of a FQ object
147007 + * @fq: the frame queue object to query
147008 + */
147009 +u32 qman_fq_fqid(struct qman_fq *fq);
147010 +
147011 +/**
147012 + * qman_fq_state - Queries the state of a FQ object
147013 + * @fq: the frame queue object to query
147014 + * @state: pointer to state enum to return the FQ scheduling state
147015 + * @flags: pointer to state flags to receive QMAN_FQ_STATE_*** bitmask
147016 + *
147017 + * Queries the state of the FQ object, without performing any h/w commands.
147018 + * This captures the state, as seen by the driver, at the time the function
147019 + * executes.
147020 + */
147021 +void qman_fq_state(struct qman_fq *fq, enum qman_fq_state *state, u32 *flags);
147022 +
147023 +/**
147024 + * qman_init_fq - Initialises FQ fields, leaves the FQ "parked" or "scheduled"
147025 + * @fq: the frame queue object to modify, must be 'parked' or new.
147026 + * @flags: bit-mask of QMAN_INITFQ_FLAG_*** options
147027 + * @opts: the FQ-modification settings, as defined in the low-level API
147028 + *
147029 + * The @opts parameter comes from the low-level portal API. Select
147030 + * QMAN_INITFQ_FLAG_SCHED in @flags to cause the frame queue to be scheduled
147031 + * rather than parked. NB, @opts can be NULL.
147032 + *
147033 + * Note that some fields and options within @opts may be ignored or overwritten
147034 + * by the driver;
147035 + * 1. the 'count' and 'fqid' fields are always ignored (this operation only
147036 + * affects one frame queue: @fq).
147037 + * 2. the QM_INITFQ_WE_CONTEXTB option of the 'we_mask' field and the associated
147038 + * 'fqd' structure's 'context_b' field are sometimes overwritten;
147039 + * - if @fq was not created with QMAN_FQ_FLAG_TO_DCPORTAL, then context_b is
147040 + * initialised to a value used by the driver for demux.
147041 + * - if context_b is initialised for demux, so is context_a in case stashing
147042 + * is requested (see item 4).
147043 + * (So caller control of context_b is only possible for TO_DCPORTAL frame queue
147044 + * objects.)
147045 + * 3. if @flags contains QMAN_INITFQ_FLAG_LOCAL, the 'fqd' structure's
147046 + * 'dest::channel' field will be overwritten to match the portal used to issue
147047 + * the command. If the WE_DESTWQ write-enable bit had already been set by the
147048 + * caller, the channel workqueue will be left as-is, otherwise the write-enable
147049 + * bit is set and the workqueue is set to a default of 4. If the "LOCAL" flag
147050 + * isn't set, the destination channel/workqueue fields and the write-enable bit
147051 + * are left as-is.
147052 + * 4. if the driver overwrites context_a/b for demux, then if
147053 + * QM_INITFQ_WE_CONTEXTA is set, the driver will only overwrite
147054 + * context_a.address fields and will leave the stashing fields provided by the
147055 + * user alone, otherwise it will zero out the context_a.stashing fields.
147056 + */
147057 +int qman_init_fq(struct qman_fq *fq, u32 flags, struct qm_mcc_initfq *opts);
147058 +
147059 +/**
147060 + * qman_schedule_fq - Schedules a FQ
147061 + * @fq: the frame queue object to schedule, must be 'parked'
147062 + *
147063 + * Schedules the frame queue, which must be Parked, which takes it to
147064 + * Tentatively-Scheduled or Truly-Scheduled depending on its fill-level.
147065 + */
147066 +int qman_schedule_fq(struct qman_fq *fq);
147067 +
147068 +/**
147069 + * qman_retire_fq - Retires a FQ
147070 + * @fq: the frame queue object to retire
147071 + * @flags: FQ flags (as per qman_fq_state) if retirement completes immediately
147072 + *
147073 + * Retires the frame queue. This returns zero if it succeeds immediately, +1 if
147074 + * the retirement was started asynchronously, otherwise it returns negative for
147075 + * failure. When this function returns zero, @flags is set to indicate whether
147076 + * the retired FQ is empty and/or whether it has any ORL fragments (to show up
147077 + * as ERNs). Otherwise the corresponding flags will be known when a subsequent
147078 + * FQRN message shows up on the portal's message ring.
147079 + *
147080 + * NB, if the retirement is asynchronous (the FQ was in the Truly Scheduled or
147081 + * Active state), the completion will be via the message ring as a FQRN - but
147082 + * the corresponding callback may occur before this function returns!! Ie. the
147083 + * caller should be prepared to accept the callback as the function is called,
147084 + * not only once it has returned.
147085 + */
147086 +int qman_retire_fq(struct qman_fq *fq, u32 *flags);
147087 +
147088 +/**
147089 + * qman_oos_fq - Puts a FQ "out of service"
147090 + * @fq: the frame queue object to be put out-of-service, must be 'retired'
147091 + *
147092 + * The frame queue must be retired and empty, and if any order restoration list
147093 + * was released as ERNs at the time of retirement, they must all be consumed.
147094 + */
147095 +int qman_oos_fq(struct qman_fq *fq);
147096 +
147097 +/**
147098 + * qman_fq_flow_control - Set the XON/XOFF state of a FQ
147099 + * @fq: the frame queue object to be set to XON/XOFF state, must not be 'oos',
147100 + * or 'retired' or 'parked' state
147101 + * @xon: boolean to set fq in XON or XOFF state
147102 + *
147103 + * The frame should be in Tentatively Scheduled state or Truly Schedule sate,
147104 + * otherwise the IFSI interrupt will be asserted.
147105 + */
147106 +int qman_fq_flow_control(struct qman_fq *fq, int xon);
147107 +
147108 +/**
147109 + * qman_query_fq - Queries FQD fields (via h/w query command)
147110 + * @fq: the frame queue object to be queried
147111 + * @fqd: storage for the queried FQD fields
147112 + */
147113 +int qman_query_fq(struct qman_fq *fq, struct qm_fqd *fqd);
147114 +
147115 +/**
147116 + * qman_query_fq_np - Queries non-programmable FQD fields
147117 + * @fq: the frame queue object to be queried
147118 + * @np: storage for the queried FQD fields
147119 + */
147120 +int qman_query_fq_np(struct qman_fq *fq, struct qm_mcr_queryfq_np *np);
147121 +
147122 +/**
147123 + * qman_query_wq - Queries work queue lengths
147124 + * @query_dedicated: If non-zero, query length of WQs in the channel dedicated
147125 + * to this software portal. Otherwise, query length of WQs in a
147126 + * channel specified in wq.
147127 + * @wq: storage for the queried WQs lengths. Also specified the channel to
147128 + * to query if query_dedicated is zero.
147129 + */
147130 +int qman_query_wq(u8 query_dedicated, struct qm_mcr_querywq *wq);
147131 +
147132 +/**
147133 + * qman_volatile_dequeue - Issue a volatile dequeue command
147134 + * @fq: the frame queue object to dequeue from
147135 + * @flags: a bit-mask of QMAN_VOLATILE_FLAG_*** options
147136 + * @vdqcr: bit mask of QM_VDQCR_*** options, as per qm_dqrr_vdqcr_set()
147137 + *
147138 + * Attempts to lock access to the portal's VDQCR volatile dequeue functionality.
147139 + * The function will block and sleep if QMAN_VOLATILE_FLAG_WAIT is specified and
147140 + * the VDQCR is already in use, otherwise returns non-zero for failure. If
147141 + * QMAN_VOLATILE_FLAG_FINISH is specified, the function will only return once
147142 + * the VDQCR command has finished executing (ie. once the callback for the last
147143 + * DQRR entry resulting from the VDQCR command has been called). If not using
147144 + * the FINISH flag, completion can be determined either by detecting the
147145 + * presence of the QM_DQRR_STAT_UNSCHEDULED and QM_DQRR_STAT_DQCR_EXPIRED bits
147146 + * in the "stat" field of the "struct qm_dqrr_entry" passed to the FQ's dequeue
147147 + * callback, or by waiting for the QMAN_FQ_STATE_VDQCR bit to disappear from the
147148 + * "flags" retrieved from qman_fq_state().
147149 + */
147150 +int qman_volatile_dequeue(struct qman_fq *fq, u32 flags, u32 vdqcr);
147151 +
147152 +/**
147153 + * qman_enqueue - Enqueue a frame to a frame queue
147154 + * @fq: the frame queue object to enqueue to
147155 + * @fd: a descriptor of the frame to be enqueued
147156 + * @flags: bit-mask of QMAN_ENQUEUE_FLAG_*** options
147157 + *
147158 + * Fills an entry in the EQCR of portal @qm to enqueue the frame described by
147159 + * @fd. The descriptor details are copied from @fd to the EQCR entry, the 'pid'
147160 + * field is ignored. The return value is non-zero on error, such as ring full
147161 + * (and FLAG_WAIT not specified), congestion avoidance (FLAG_WATCH_CGR
147162 + * specified), etc. If the ring is full and FLAG_WAIT is specified, this
147163 + * function will block. If FLAG_INTERRUPT is set, the EQCI bit of the portal
147164 + * interrupt will assert when Qman consumes the EQCR entry (subject to "status
147165 + * disable", "enable", and "inhibit" registers). If FLAG_DCA is set, Qman will
147166 + * perform an implied "discrete consumption acknowledgement" on the dequeue
147167 + * ring's (DQRR) entry, at the ring index specified by the FLAG_DCA_IDX(x)
147168 + * macro. (As an alternative to issuing explicit DCA actions on DQRR entries,
147169 + * this implicit DCA can delay the release of a "held active" frame queue
147170 + * corresponding to a DQRR entry until Qman consumes the EQCR entry - providing
147171 + * order-preservation semantics in packet-forwarding scenarios.) If FLAG_DCA is
147172 + * set, then FLAG_DCA_PARK can also be set to imply that the DQRR consumption
147173 + * acknowledgement should "park request" the "held active" frame queue. Ie.
147174 + * when the portal eventually releases that frame queue, it will be left in the
147175 + * Parked state rather than Tentatively Scheduled or Truly Scheduled. If the
147176 + * portal is watching congestion groups, the QMAN_ENQUEUE_FLAG_WATCH_CGR flag
147177 + * is requested, and the FQ is a member of a congestion group, then this
147178 + * function returns -EAGAIN if the congestion group is currently congested.
147179 + * Note, this does not eliminate ERNs, as the async interface means we can be
147180 + * sending enqueue commands to an un-congested FQ that becomes congested before
147181 + * the enqueue commands are processed, but it does minimise needless thrashing
147182 + * of an already busy hardware resource by throttling many of the to-be-dropped
147183 + * enqueues "at the source".
147184 + */
147185 +int qman_enqueue(struct qman_fq *fq, const struct qm_fd *fd, u32 flags);
147186 +
147187 +typedef int (*qman_cb_precommit) (void *arg);
147188 +/**
147189 + * qman_enqueue_precommit - Enqueue a frame to a frame queue and call cb
147190 + * @fq: the frame queue object to enqueue to
147191 + * @fd: a descriptor of the frame to be enqueued
147192 + * @flags: bit-mask of QMAN_ENQUEUE_FLAG_*** options
147193 + * @cb: user supplied callback function to invoke before writing commit verb.
147194 + * @cb_arg: callback function argument
147195 + *
147196 + * This is similar to qman_enqueue except that it will invoke a user supplied
147197 + * callback function just before writng the commit verb. This is useful
147198 + * when the user want to do something *just before* enqueuing the request and
147199 + * the enqueue can't fail.
147200 + */
147201 +int qman_enqueue_precommit(struct qman_fq *fq, const struct qm_fd *fd,
147202 + u32 flags, qman_cb_precommit cb, void *cb_arg);
147203 +
147204 +/**
147205 + * qman_enqueue_orp - Enqueue a frame to a frame queue using an ORP
147206 + * @fq: the frame queue object to enqueue to
147207 + * @fd: a descriptor of the frame to be enqueued
147208 + * @flags: bit-mask of QMAN_ENQUEUE_FLAG_*** options
147209 + * @orp: the frame queue object used as an order restoration point.
147210 + * @orp_seqnum: the sequence number of this frame in the order restoration path
147211 + *
147212 + * Similar to qman_enqueue(), but with the addition of an Order Restoration
147213 + * Point (@orp) and corresponding sequence number (@orp_seqnum) for this
147214 + * enqueue operation to employ order restoration. Each frame queue object acts
147215 + * as an Order Definition Point (ODP) by providing each frame dequeued from it
147216 + * with an incrementing sequence number, this value is generally ignored unless
147217 + * that sequence of dequeued frames will need order restoration later. Each
147218 + * frame queue object also encapsulates an Order Restoration Point (ORP), which
147219 + * is a re-assembly context for re-ordering frames relative to their sequence
147220 + * numbers as they are enqueued. The ORP does not have to be within the frame
147221 + * queue that receives the enqueued frame, in fact it is usually the frame
147222 + * queue from which the frames were originally dequeued. For the purposes of
147223 + * order restoration, multiple frames (or "fragments") can be enqueued for a
147224 + * single sequence number by setting the QMAN_ENQUEUE_FLAG_NLIS flag for all
147225 + * enqueues except the final fragment of a given sequence number. Ordering
147226 + * between sequence numbers is guaranteed, even if fragments of different
147227 + * sequence numbers are interlaced with one another. Fragments of the same
147228 + * sequence number will retain the order in which they are enqueued. If no
147229 + * enqueue is to performed, QMAN_ENQUEUE_FLAG_HOLE indicates that the given
147230 + * sequence number is to be "skipped" by the ORP logic (eg. if a frame has been
147231 + * dropped from a sequence), or QMAN_ENQUEUE_FLAG_NESN indicates that the given
147232 + * sequence number should become the ORP's "Next Expected Sequence Number".
147233 + *
147234 + * Side note: a frame queue object can be used purely as an ORP, without
147235 + * carrying any frames at all. Care should be taken not to deallocate a frame
147236 + * queue object that is being actively used as an ORP, as a future allocation
147237 + * of the frame queue object may start using the internal ORP before the
147238 + * previous use has finished.
147239 + */
147240 +int qman_enqueue_orp(struct qman_fq *fq, const struct qm_fd *fd, u32 flags,
147241 + struct qman_fq *orp, u16 orp_seqnum);
147242 +
147243 +/**
147244 + * qman_alloc_fqid_range - Allocate a contiguous range of FQIDs
147245 + * @result: is set by the API to the base FQID of the allocated range
147246 + * @count: the number of FQIDs required
147247 + * @align: required alignment of the allocated range
147248 + * @partial: non-zero if the API can return fewer than @count FQIDs
147249 + *
147250 + * Returns the number of frame queues allocated, or a negative error code. If
147251 + * @partial is non zero, the allocation request may return a smaller range of
147252 + * FQs than requested (though alignment will be as requested). If @partial is
147253 + * zero, the return value will either be 'count' or negative.
147254 + */
147255 +int qman_alloc_fqid_range(u32 *result, u32 count, u32 align, int partial);
147256 +static inline int qman_alloc_fqid(u32 *result)
147257 +{
147258 + int ret = qman_alloc_fqid_range(result, 1, 0, 0);
147259 + return (ret > 0) ? 0 : ret;
147260 +}
147261 +
147262 +/**
147263 + * qman_release_fqid_range - Release the specified range of frame queue IDs
147264 + * @fqid: the base FQID of the range to deallocate
147265 + * @count: the number of FQIDs in the range
147266 + *
147267 + * This function can also be used to seed the allocator with ranges of FQIDs
147268 + * that it can subsequently allocate from.
147269 + */
147270 +void qman_release_fqid_range(u32 fqid, unsigned int count);
147271 +static inline void qman_release_fqid(u32 fqid)
147272 +{
147273 + qman_release_fqid_range(fqid, 1);
147274 +}
147275 +
147276 +void qman_seed_fqid_range(u32 fqid, unsigned int count);
147277 +
147278 +
147279 +int qman_shutdown_fq(u32 fqid);
147280 +
147281 +/**
147282 + * qman_reserve_fqid_range - Reserve the specified range of frame queue IDs
147283 + * @fqid: the base FQID of the range to deallocate
147284 + * @count: the number of FQIDs in the range
147285 + */
147286 +int qman_reserve_fqid_range(u32 fqid, unsigned int count);
147287 +static inline int qman_reserve_fqid(u32 fqid)
147288 +{
147289 + return qman_reserve_fqid_range(fqid, 1);
147290 +}
147291 +
147292 + /* Pool-channel management */
147293 + /* ----------------------- */
147294 +/**
147295 + * qman_alloc_pool_range - Allocate a contiguous range of pool-channel IDs
147296 + * @result: is set by the API to the base pool-channel ID of the allocated range
147297 + * @count: the number of pool-channel IDs required
147298 + * @align: required alignment of the allocated range
147299 + * @partial: non-zero if the API can return fewer than @count
147300 + *
147301 + * Returns the number of pool-channel IDs allocated, or a negative error code.
147302 + * If @partial is non zero, the allocation request may return a smaller range of
147303 + * than requested (though alignment will be as requested). If @partial is zero,
147304 + * the return value will either be 'count' or negative.
147305 + */
147306 +int qman_alloc_pool_range(u32 *result, u32 count, u32 align, int partial);
147307 +static inline int qman_alloc_pool(u32 *result)
147308 +{
147309 + int ret = qman_alloc_pool_range(result, 1, 0, 0);
147310 + return (ret > 0) ? 0 : ret;
147311 +}
147312 +
147313 +/**
147314 + * qman_release_pool_range - Release the specified range of pool-channel IDs
147315 + * @id: the base pool-channel ID of the range to deallocate
147316 + * @count: the number of pool-channel IDs in the range
147317 + */
147318 +void qman_release_pool_range(u32 id, unsigned int count);
147319 +static inline void qman_release_pool(u32 id)
147320 +{
147321 + qman_release_pool_range(id, 1);
147322 +}
147323 +
147324 +/**
147325 + * qman_reserve_pool_range - Reserve the specified range of pool-channel IDs
147326 + * @id: the base pool-channel ID of the range to reserve
147327 + * @count: the number of pool-channel IDs in the range
147328 + */
147329 +int qman_reserve_pool_range(u32 id, unsigned int count);
147330 +static inline int qman_reserve_pool(u32 id)
147331 +{
147332 + return qman_reserve_pool_range(id, 1);
147333 +}
147334 +
147335 +void qman_seed_pool_range(u32 id, unsigned int count);
147336 +
147337 + /* CGR management */
147338 + /* -------------- */
147339 +/**
147340 + * qman_create_cgr - Register a congestion group object
147341 + * @cgr: the 'cgr' object, with fields filled in
147342 + * @flags: QMAN_CGR_FLAG_* values
147343 + * @opts: optional state of CGR settings
147344 + *
147345 + * Registers this object to receiving congestion entry/exit callbacks on the
147346 + * portal affine to the cpu portal on which this API is executed. If opts is
147347 + * NULL then only the callback (cgr->cb) function is registered. If @flags
147348 + * contains QMAN_CGR_FLAG_USE_INIT, then an init hw command (which will reset
147349 + * any unspecified parameters) will be used rather than a modify hw hardware
147350 + * (which only modifies the specified parameters).
147351 + */
147352 +int qman_create_cgr(struct qman_cgr *cgr, u32 flags,
147353 + struct qm_mcc_initcgr *opts);
147354 +
147355 +/**
147356 + * qman_create_cgr_to_dcp - Register a congestion group object to DCP portal
147357 + * @cgr: the 'cgr' object, with fields filled in
147358 + * @flags: QMAN_CGR_FLAG_* values
147359 + * @dcp_portal: the DCP portal to which the cgr object is registered.
147360 + * @opts: optional state of CGR settings
147361 + *
147362 + */
147363 +int qman_create_cgr_to_dcp(struct qman_cgr *cgr, u32 flags, u16 dcp_portal,
147364 + struct qm_mcc_initcgr *opts);
147365 +
147366 +/**
147367 + * qman_delete_cgr - Deregisters a congestion group object
147368 + * @cgr: the 'cgr' object to deregister
147369 + *
147370 + * "Unplugs" this CGR object from the portal affine to the cpu on which this API
147371 + * is executed. This must be excuted on the same affine portal on which it was
147372 + * created.
147373 + */
147374 +int qman_delete_cgr(struct qman_cgr *cgr);
147375 +
147376 +/**
147377 + * qman_delete_cgr_safe - Deregisters a congestion group object from any CPU
147378 + * @cgr: the 'cgr' object to deregister
147379 + *
147380 + * This will select the proper CPU and run there qman_delete_cgr().
147381 + */
147382 +void qman_delete_cgr_safe(struct qman_cgr *cgr);
147383 +
147384 +/**
147385 + * qman_modify_cgr - Modify CGR fields
147386 + * @cgr: the 'cgr' object to modify
147387 + * @flags: QMAN_CGR_FLAG_* values
147388 + * @opts: the CGR-modification settings
147389 + *
147390 + * The @opts parameter comes from the low-level portal API, and can be NULL.
147391 + * Note that some fields and options within @opts may be ignored or overwritten
147392 + * by the driver, in particular the 'cgrid' field is ignored (this operation
147393 + * only affects the given CGR object). If @flags contains
147394 + * QMAN_CGR_FLAG_USE_INIT, then an init hw command (which will reset any
147395 + * unspecified parameters) will be used rather than a modify hw hardware (which
147396 + * only modifies the specified parameters).
147397 + */
147398 +int qman_modify_cgr(struct qman_cgr *cgr, u32 flags,
147399 + struct qm_mcc_initcgr *opts);
147400 +
147401 +/**
147402 +* qman_query_cgr - Queries CGR fields
147403 +* @cgr: the 'cgr' object to query
147404 +* @result: storage for the queried congestion group record
147405 +*/
147406 +int qman_query_cgr(struct qman_cgr *cgr, struct qm_mcr_querycgr *result);
147407 +
147408 +/**
147409 + * qman_query_congestion - Queries the state of all congestion groups
147410 + * @congestion: storage for the queried state of all congestion groups
147411 + */
147412 +int qman_query_congestion(struct qm_mcr_querycongestion *congestion);
147413 +
147414 +/**
147415 + * qman_alloc_cgrid_range - Allocate a contiguous range of CGR IDs
147416 + * @result: is set by the API to the base CGR ID of the allocated range
147417 + * @count: the number of CGR IDs required
147418 + * @align: required alignment of the allocated range
147419 + * @partial: non-zero if the API can return fewer than @count
147420 + *
147421 + * Returns the number of CGR IDs allocated, or a negative error code.
147422 + * If @partial is non zero, the allocation request may return a smaller range of
147423 + * than requested (though alignment will be as requested). If @partial is zero,
147424 + * the return value will either be 'count' or negative.
147425 + */
147426 +int qman_alloc_cgrid_range(u32 *result, u32 count, u32 align, int partial);
147427 +static inline int qman_alloc_cgrid(u32 *result)
147428 +{
147429 + int ret = qman_alloc_cgrid_range(result, 1, 0, 0);
147430 + return (ret > 0) ? 0 : ret;
147431 +}
147432 +
147433 +/**
147434 + * qman_release_cgrid_range - Release the specified range of CGR IDs
147435 + * @id: the base CGR ID of the range to deallocate
147436 + * @count: the number of CGR IDs in the range
147437 + */
147438 +void qman_release_cgrid_range(u32 id, unsigned int count);
147439 +static inline void qman_release_cgrid(u32 id)
147440 +{
147441 + qman_release_cgrid_range(id, 1);
147442 +}
147443 +
147444 +/**
147445 + * qman_reserve_cgrid_range - Reserve the specified range of CGR ID
147446 + * @id: the base CGR ID of the range to reserve
147447 + * @count: the number of CGR IDs in the range
147448 + */
147449 +int qman_reserve_cgrid_range(u32 id, unsigned int count);
147450 +static inline int qman_reserve_cgrid(u32 id)
147451 +{
147452 + return qman_reserve_cgrid_range(id, 1);
147453 +}
147454 +
147455 +void qman_seed_cgrid_range(u32 id, unsigned int count);
147456 +
147457 +
147458 + /* Helpers */
147459 + /* ------- */
147460 +/**
147461 + * qman_poll_fq_for_init - Check if an FQ has been initialised from OOS
147462 + * @fqid: the FQID that will be initialised by other s/w
147463 + *
147464 + * In many situations, a FQID is provided for communication between s/w
147465 + * entities, and whilst the consumer is responsible for initialising and
147466 + * scheduling the FQ, the producer(s) generally create a wrapper FQ object using
147467 + * and only call qman_enqueue() (no FQ initialisation, scheduling, etc). Ie;
147468 + * qman_create_fq(..., QMAN_FQ_FLAG_NO_MODIFY, ...);
147469 + * However, data can not be enqueued to the FQ until it is initialised out of
147470 + * the OOS state - this function polls for that condition. It is particularly
147471 + * useful for users of IPC functions - each endpoint's Rx FQ is the other
147472 + * endpoint's Tx FQ, so each side can initialise and schedule their Rx FQ object
147473 + * and then use this API on the (NO_MODIFY) Tx FQ object in order to
147474 + * synchronise. The function returns zero for success, +1 if the FQ is still in
147475 + * the OOS state, or negative if there was an error.
147476 + */
147477 +static inline int qman_poll_fq_for_init(struct qman_fq *fq)
147478 +{
147479 + struct qm_mcr_queryfq_np np;
147480 + int err;
147481 + err = qman_query_fq_np(fq, &np);
147482 + if (err)
147483 + return err;
147484 + if ((np.state & QM_MCR_NP_STATE_MASK) == QM_MCR_NP_STATE_OOS)
147485 + return 1;
147486 + return 0;
147487 +}
147488 +
147489 + /* -------------- */
147490 + /* CEETM :: types */
147491 + /* -------------- */
147492 +/**
147493 + * Token Rate Structure
147494 + * Shaping rates are based on a "credit" system and a pre-configured h/w
147495 + * internal timer. The following type represents a shaper "rate" parameter as a
147496 + * fractional number of "tokens". Here's how it works. This (fractional) number
147497 + * of tokens is added to the shaper's "credit" every time the h/w timer elapses
147498 + * (up to a limit which is set by another shaper parameter). Every time a frame
147499 + * is enqueued through a shaper, the shaper deducts as many tokens as there are
147500 + * bytes of data in the enqueued frame. A shaper will not allow itself to
147501 + * enqueue any frames if its token count is negative. As such;
147502 + *
147503 + * The rate at which data is enqueued is limited by the
147504 + * rate at which tokens are added.
147505 + *
147506 + * Therefore if the user knows the period between these h/w timer updates in
147507 + * seconds, they can calculate the maximum traffic rate of the shaper (in
147508 + * bytes-per-second) from the token rate. And vice versa, they can calculate
147509 + * the token rate to use in order to achieve a given traffic rate.
147510 + */
147511 +struct qm_ceetm_rate {
147512 + /* The token rate is; whole + (fraction/8192) */
147513 + u32 whole:11; /* 0..2047 */
147514 + u32 fraction:13; /* 0..8191 */
147515 +};
147516 +
147517 +struct qm_ceetm_weight_code {
147518 + /* The weight code is; 5 msbits + 3 lsbits */
147519 + u8 y:5;
147520 + u8 x:3;
147521 +};
147522 +
147523 +struct qm_ceetm {
147524 + unsigned int idx;
147525 + struct list_head sub_portals;
147526 + struct list_head lnis;
147527 + unsigned int sp_range[2];
147528 + unsigned int lni_range[2];
147529 +};
147530 +
147531 +struct qm_ceetm_sp {
147532 + struct list_head node;
147533 + unsigned int idx;
147534 + unsigned int dcp_idx;
147535 + int is_claimed;
147536 + struct qm_ceetm_lni *lni;
147537 +};
147538 +
147539 +/* Logical Network Interface */
147540 +struct qm_ceetm_lni {
147541 + struct list_head node;
147542 + unsigned int idx;
147543 + unsigned int dcp_idx;
147544 + int is_claimed;
147545 + struct qm_ceetm_sp *sp;
147546 + struct list_head channels;
147547 + int shaper_enable;
147548 + int shaper_couple;
147549 + int oal;
147550 + struct qm_ceetm_rate cr_token_rate;
147551 + struct qm_ceetm_rate er_token_rate;
147552 + u16 cr_token_bucket_limit;
147553 + u16 er_token_bucket_limit;
147554 +};
147555 +
147556 +/* Class Queue Channel */
147557 +struct qm_ceetm_channel {
147558 + struct list_head node;
147559 + unsigned int idx;
147560 + unsigned int lni_idx;
147561 + unsigned int dcp_idx;
147562 + struct list_head class_queues;
147563 + struct list_head ccgs;
147564 + u8 shaper_enable;
147565 + u8 shaper_couple;
147566 + struct qm_ceetm_rate cr_token_rate;
147567 + struct qm_ceetm_rate er_token_rate;
147568 + u16 cr_token_bucket_limit;
147569 + u16 er_token_bucket_limit;
147570 +};
147571 +
147572 +struct qm_ceetm_ccg;
147573 +
147574 +/* This callback type is used when handling congestion entry/exit. The
147575 + * 'cb_ctx' value is the opaque value associated with ccg object.
147576 + * 'congested' is non-zero on congestion-entry, and zero on congestion-exit.
147577 + */
147578 +typedef void (*qman_cb_ccgr)(struct qm_ceetm_ccg *ccg, void *cb_ctx,
147579 + int congested);
147580 +
147581 +/* Class Congestion Group */
147582 +struct qm_ceetm_ccg {
147583 + struct qm_ceetm_channel *parent;
147584 + struct list_head node;
147585 + struct list_head cb_node;
147586 + qman_cb_ccgr cb;
147587 + void *cb_ctx;
147588 + unsigned int idx;
147589 +};
147590 +
147591 +/* Class Queue */
147592 +struct qm_ceetm_cq {
147593 + struct qm_ceetm_channel *parent;
147594 + struct qm_ceetm_ccg *ccg;
147595 + struct list_head node;
147596 + unsigned int idx;
147597 + int is_claimed;
147598 + struct list_head bound_lfqids;
147599 + struct list_head binding_node;
147600 +};
147601 +
147602 +/* Logical Frame Queue */
147603 +struct qm_ceetm_lfq {
147604 + struct qm_ceetm_channel *parent;
147605 + struct list_head node;
147606 + unsigned int idx;
147607 + unsigned int dctidx;
147608 + u64 context_a;
147609 + u32 context_b;
147610 + qman_cb_mr ern;
147611 +};
147612 +
147613 +/**
147614 + * qman_ceetm_bps2tokenrate - Given a desired rate 'bps' measured in bps
147615 + * (ie. bits-per-second), compute the 'token_rate' fraction that best
147616 + * approximates that rate.
147617 + * @bps: the desired shaper rate in bps.
147618 + * @token_rate: the output token rate computed with the given kbps.
147619 + * @rounding: dictates how to round if an exact conversion is not possible; if
147620 + * it is negative then 'token_rate' will round down to the highest value that
147621 + * does not exceed the desired rate, if it is positive then 'token_rate' will
147622 + * round up to the lowest value that is greater than or equal to the desired
147623 + * rate, and if it is zero then it will round to the nearest approximation,
147624 + * whether that be up or down.
147625 + *
147626 + * Return 0 for success, or -EINVAL if prescaler or qman clock is not available.
147627 + */
147628 +int qman_ceetm_bps2tokenrate(u64 bps,
147629 + struct qm_ceetm_rate *token_rate,
147630 + int rounding);
147631 +
147632 +/**
147633 + * qman_ceetm_tokenrate2bps - Given a 'token_rate', compute the
147634 + * corresponding number of 'bps'.
147635 + * @token_rate: the input desired token_rate fraction.
147636 + * @bps: the output shaper rate in bps computed with the give token rate.
147637 + * @rounding: has the same semantics as the previous function.
147638 + *
147639 + * Return 0 for success, or -EINVAL if prescaler or qman clock is not available.
147640 + */
147641 +int qman_ceetm_tokenrate2bps(const struct qm_ceetm_rate *token_rate,
147642 + u64 *bps,
147643 + int rounding);
147644 +
147645 +int qman_alloc_ceetm0_channel_range(u32 *result, u32 count, u32 align,
147646 + int partial);
147647 +static inline int qman_alloc_ceetm0_channel(u32 *result)
147648 +{
147649 + int ret = qman_alloc_ceetm0_channel_range(result, 1, 0, 0);
147650 + return (ret > 0) ? 0 : ret;
147651 +}
147652 +void qman_release_ceetm0_channel_range(u32 channelid, u32 count);
147653 +static inline void qman_release_ceetm0_channelid(u32 channelid)
147654 +{
147655 + qman_release_ceetm0_channel_range(channelid, 1);
147656 +}
147657 +
147658 +int qman_reserve_ceetm0_channel_range(u32 channelid, u32 count);
147659 +static inline int qman_reserve_ceetm0_channelid(u32 channelid)
147660 +{
147661 + return qman_reserve_ceetm0_channel_range(channelid, 1);
147662 +}
147663 +
147664 +void qman_seed_ceetm0_channel_range(u32 channelid, u32 count);
147665 +
147666 +
147667 +int qman_alloc_ceetm1_channel_range(u32 *result, u32 count, u32 align,
147668 + int partial);
147669 +static inline int qman_alloc_ceetm1_channel(u32 *result)
147670 +{
147671 + int ret = qman_alloc_ceetm1_channel_range(result, 1, 0, 0);
147672 + return (ret > 0) ? 0 : ret;
147673 +}
147674 +void qman_release_ceetm1_channel_range(u32 channelid, u32 count);
147675 +static inline void qman_release_ceetm1_channelid(u32 channelid)
147676 +{
147677 + qman_release_ceetm1_channel_range(channelid, 1);
147678 +}
147679 +int qman_reserve_ceetm1_channel_range(u32 channelid, u32 count);
147680 +static inline int qman_reserve_ceetm1_channelid(u32 channelid)
147681 +{
147682 + return qman_reserve_ceetm1_channel_range(channelid, 1);
147683 +}
147684 +
147685 +void qman_seed_ceetm1_channel_range(u32 channelid, u32 count);
147686 +
147687 +
147688 +int qman_alloc_ceetm0_lfqid_range(u32 *result, u32 count, u32 align,
147689 + int partial);
147690 +static inline int qman_alloc_ceetm0_lfqid(u32 *result)
147691 +{
147692 + int ret = qman_alloc_ceetm0_lfqid_range(result, 1, 0, 0);
147693 + return (ret > 0) ? 0 : ret;
147694 +}
147695 +void qman_release_ceetm0_lfqid_range(u32 lfqid, u32 count);
147696 +static inline void qman_release_ceetm0_lfqid(u32 lfqid)
147697 +{
147698 + qman_release_ceetm0_lfqid_range(lfqid, 1);
147699 +}
147700 +int qman_reserve_ceetm0_lfqid_range(u32 lfqid, u32 count);
147701 +static inline int qman_reserve_ceetm0_lfqid(u32 lfqid)
147702 +{
147703 + return qman_reserve_ceetm0_lfqid_range(lfqid, 1);
147704 +}
147705 +
147706 +void qman_seed_ceetm0_lfqid_range(u32 lfqid, u32 count);
147707 +
147708 +
147709 +int qman_alloc_ceetm1_lfqid_range(u32 *result, u32 count, u32 align,
147710 + int partial);
147711 +static inline int qman_alloc_ceetm1_lfqid(u32 *result)
147712 +{
147713 + int ret = qman_alloc_ceetm1_lfqid_range(result, 1, 0, 0);
147714 + return (ret > 0) ? 0 : ret;
147715 +}
147716 +void qman_release_ceetm1_lfqid_range(u32 lfqid, u32 count);
147717 +static inline void qman_release_ceetm1_lfqid(u32 lfqid)
147718 +{
147719 + qman_release_ceetm1_lfqid_range(lfqid, 1);
147720 +}
147721 +int qman_reserve_ceetm1_lfqid_range(u32 lfqid, u32 count);
147722 +static inline int qman_reserve_ceetm1_lfqid(u32 lfqid)
147723 +{
147724 + return qman_reserve_ceetm1_lfqid_range(lfqid, 1);
147725 +}
147726 +
147727 +void qman_seed_ceetm1_lfqid_range(u32 lfqid, u32 count);
147728 +
147729 +
147730 + /* ----------------------------- */
147731 + /* CEETM :: sub-portals */
147732 + /* ----------------------------- */
147733 +
147734 +/**
147735 + * qman_ceetm_sp_claim - Claims the given sub-portal, provided it is available
147736 + * to us and configured for traffic-management.
147737 + * @sp: the returned sub-portal object, if successful.
147738 + * @dcp_id: specifies the desired Fman block (and thus the relevant CEETM
147739 + * instance),
147740 + * @sp_idx" is the desired sub-portal index from 0 to 15.
147741 + *
147742 + * Returns zero for success, or -ENODEV if the sub-portal is in use, or -EINVAL
147743 + * if the sp_idx is out of range.
147744 + *
147745 + * Note that if there are multiple driver domains (eg. a linux kernel versus
147746 + * user-space drivers in USDPAA, or multiple guests running under a hypervisor)
147747 + * then a sub-portal may be accessible by more than one instance of a qman
147748 + * driver and so it may be claimed multiple times. If this is the case, it is
147749 + * up to the system architect to prevent conflicting configuration actions
147750 + * coming from the different driver domains. The qman drivers do not have any
147751 + * behind-the-scenes coordination to prevent this from happening.
147752 + */
147753 +int qman_ceetm_sp_claim(struct qm_ceetm_sp **sp,
147754 + enum qm_dc_portal dcp_idx,
147755 + unsigned int sp_idx);
147756 +
147757 +/**
147758 + * qman_ceetm_sp_release - Releases a previously claimed sub-portal.
147759 + * @sp: the sub-portal to be released.
147760 + *
147761 + * Returns 0 for success, or -EBUSY for failure if the dependencies are not
147762 + * released.
147763 + */
147764 +int qman_ceetm_sp_release(struct qm_ceetm_sp *sp);
147765 +
147766 + /* ----------------------------------- */
147767 + /* CEETM :: logical network interfaces */
147768 + /* ----------------------------------- */
147769 +
147770 +/**
147771 + * qman_ceetm_lni_claim - Claims an unclaimed LNI.
147772 + * @lni: the returned LNI object, if successful.
147773 + * @dcp_id: specifies the desired Fman block (and thus the relevant CEETM
147774 + * instance)
147775 + * @lni_idx: is the desired LNI index.
147776 + *
147777 + * Returns zero for success, or -EINVAL on failure, which will happen if the LNI
147778 + * is not available or has already been claimed (and not yet successfully
147779 + * released), or lni_dix is out of range.
147780 + *
147781 + * Note that there may be multiple driver domains (or instances) that need to
147782 + * transmit out the same LNI, so this claim is only guaranteeing exclusivity
147783 + * within the domain of the driver being called. See qman_ceetm_sp_claim() and
147784 + * qman_ceetm_sp_get_lni() for more information.
147785 + */
147786 +int qman_ceetm_lni_claim(struct qm_ceetm_lni **lni,
147787 + enum qm_dc_portal dcp_id,
147788 + unsigned int lni_idx);
147789 +
147790 +/**
147791 + * qman_ceetm_lni_releaes - Releases a previously claimed LNI.
147792 + * @lni: the lni needs to be released.
147793 + *
147794 + * This will only succeed if all dependent objects have been released.
147795 + * Returns zero for success, or -EBUSY if the dependencies are not released.
147796 + */
147797 +int qman_ceetm_lni_release(struct qm_ceetm_lni *lni);
147798 +
147799 +/**
147800 + * qman_ceetm_sp_set_lni
147801 + * qman_ceetm_sp_get_lni - Set/get the LNI that the sub-portal is currently
147802 + * mapped to.
147803 + * @sp: the given sub-portal.
147804 + * @lni(in "set"function): the LNI object which the sp will be mappaed to.
147805 + * @lni_idx(in "get" function): the LNI index which the sp is mapped to.
147806 + *
147807 + * Returns zero for success, or -EINVAL for the "set" function when this sp-lni
147808 + * mapping has been set, or configure mapping command returns error, and
147809 + * -EINVAL for "get" function when this sp-lni mapping is not set or the query
147810 + * mapping command returns error.
147811 + *
147812 + * This may be useful in situations where multiple driver domains have access
147813 + * to the same sub-portals in order to all be able to transmit out the same
147814 + * physical interface (perhaps they're on different IP addresses or VPNs, so
147815 + * Fman is splitting Rx traffic and here we need to converge Tx traffic). In
147816 + * that case, a control-plane is likely to use qman_ceetm_lni_claim() followed
147817 + * by qman_ceetm_sp_set_lni() to configure the sub-portal, and other domains
147818 + * are likely to use qman_ceetm_sp_get_lni() followed by qman_ceetm_lni_claim()
147819 + * in order to determine the LNI that the control-plane had assigned. This is
147820 + * why the "get" returns an index, whereas the "set" takes an (already claimed)
147821 + * LNI object.
147822 + */
147823 +int qman_ceetm_sp_set_lni(struct qm_ceetm_sp *sp,
147824 + struct qm_ceetm_lni *lni);
147825 +int qman_ceetm_sp_get_lni(struct qm_ceetm_sp *sp,
147826 + unsigned int *lni_idx);
147827 +
147828 +/**
147829 + * qman_ceetm_lni_enable_shaper
147830 + * qman_ceetm_lni_disable_shaper - Enables/disables shaping on the LNI.
147831 + * @lni: the given LNI.
147832 + * @coupled: indicates whether CR and ER are coupled.
147833 + * @oal: the overhead accounting length which is added to the actual length of
147834 + * each frame when performing shaper calculations.
147835 + *
147836 + * When the number of (unused) committed-rate tokens reach the committed-rate
147837 + * token limit, 'coupled' indicates whether surplus tokens should be added to
147838 + * the excess-rate token count (up to the excess-rate token limit).
147839 + * When LNI is claimed, the shaper is disabled by default. The enable function
147840 + * will turn on this shaper for this lni.
147841 + * Whenever a claimed LNI is first enabled for shaping, its committed and
147842 + * excess token rates and limits are zero, so will need to be changed to do
147843 + * anything useful. The shaper can subsequently be enabled/disabled without
147844 + * resetting the shaping parameters, but the shaping parameters will be reset
147845 + * when the LNI is released.
147846 + *
147847 + * Returns zero for success, or errno for "enable" function in the cases as:
147848 + * a) -EINVAL if the shaper is already enabled,
147849 + * b) -EIO if the configure shaper command returns error.
147850 + * For "disable" function, returns:
147851 + * a) -EINVAL if the shaper is has already disabled.
147852 + * b) -EIO if calling configure shaper command returns error.
147853 + */
147854 +int qman_ceetm_lni_enable_shaper(struct qm_ceetm_lni *lni, int coupled,
147855 + int oal);
147856 +int qman_ceetm_lni_disable_shaper(struct qm_ceetm_lni *lni);
147857 +
147858 +/**
147859 + * qman_ceetm_lni_is_shaper_enabled - Check LNI shaper status
147860 + * @lni: the give LNI
147861 + */
147862 +int qman_ceetm_lni_is_shaper_enabled(struct qm_ceetm_lni *lni);
147863 +
147864 +/**
147865 + * qman_ceetm_lni_set_commit_rate
147866 + * qman_ceetm_lni_get_commit_rate
147867 + * qman_ceetm_lni_set_excess_rate
147868 + * qman_ceetm_lni_get_excess_rate - Set/get the shaper CR/ER token rate and
147869 + * token limit for the given LNI.
147870 + * @lni: the given LNI.
147871 + * @token_rate: the desired token rate for "set" fuction, or the token rate of
147872 + * the LNI queried by "get" function.
147873 + * @token_limit: the desired token bucket limit for "set" function, or the token
147874 + * limit of the given LNI queried by "get" function.
147875 + *
147876 + * Returns zero for success. The "set" function returns -EINVAL if the given
147877 + * LNI is unshapped or -EIO if the configure shaper command returns error.
147878 + * The "get" function returns -EINVAL if the token rate or the token limit is
147879 + * not set or the query command returns error.
147880 + */
147881 +int qman_ceetm_lni_set_commit_rate(struct qm_ceetm_lni *lni,
147882 + const struct qm_ceetm_rate *token_rate,
147883 + u16 token_limit);
147884 +int qman_ceetm_lni_get_commit_rate(struct qm_ceetm_lni *lni,
147885 + struct qm_ceetm_rate *token_rate,
147886 + u16 *token_limit);
147887 +int qman_ceetm_lni_set_excess_rate(struct qm_ceetm_lni *lni,
147888 + const struct qm_ceetm_rate *token_rate,
147889 + u16 token_limit);
147890 +int qman_ceetm_lni_get_excess_rate(struct qm_ceetm_lni *lni,
147891 + struct qm_ceetm_rate *token_rate,
147892 + u16 *token_limit);
147893 +/**
147894 + * qman_ceetm_lni_set_commit_rate_bps
147895 + * qman_ceetm_lni_get_commit_rate_bps
147896 + * qman_ceetm_lni_set_excess_rate_bps
147897 + * qman_ceetm_lni_get_excess_rate_bps - Set/get the shaper CR/ER rate
147898 + * and token limit for the given LNI.
147899 + * @lni: the given LNI.
147900 + * @bps: the desired shaping rate in bps for "set" fuction, or the shaping rate
147901 + * of the LNI queried by "get" function.
147902 + * @token_limit: the desired token bucket limit for "set" function, or the token
147903 + * limit of the given LNI queried by "get" function.
147904 + *
147905 + * Returns zero for success. The "set" function returns -EINVAL if the given
147906 + * LNI is unshapped or -EIO if the configure shaper command returns error.
147907 + * The "get" function returns -EINVAL if the token rate or the token limit is
147908 + * not set or the query command returns error.
147909 + */
147910 +int qman_ceetm_lni_set_commit_rate_bps(struct qm_ceetm_lni *lni,
147911 + u64 bps,
147912 + u16 token_limit);
147913 +int qman_ceetm_lni_get_commit_rate_bps(struct qm_ceetm_lni *lni,
147914 + u64 *bps, u16 *token_limit);
147915 +int qman_ceetm_lni_set_excess_rate_bps(struct qm_ceetm_lni *lni,
147916 + u64 bps,
147917 + u16 token_limit);
147918 +int qman_ceetm_lni_get_excess_rate_bps(struct qm_ceetm_lni *lni,
147919 + u64 *bps, u16 *token_limit);
147920 +
147921 +/**
147922 + * qman_ceetm_lni_set_tcfcc
147923 + * qman_ceetm_lni_get_tcfcc - Configure/query "Traffic Class Flow Control".
147924 + * @lni: the given LNI.
147925 + * @cq_level: is between 0 and 15, representing individual class queue levels
147926 + * (CQ0 to CQ7 for every channel) and grouped class queue levels (CQ8 to CQ15
147927 + * for every channel).
147928 + * @traffic_class: is between 0 and 7 when associating a given class queue level
147929 + * to a traffic class, or -1 when disabling traffic class flow control for this
147930 + * class queue level.
147931 + *
147932 + * Return zero for success, or -EINVAL if the cq_level or traffic_class is out
147933 + * of range as indicated above, or -EIO if the configure/query tcfcc command
147934 + * returns error.
147935 + *
147936 + * Refer to the section of QMan CEETM traffic class flow control in the
147937 + * Reference Manual.
147938 + */
147939 +int qman_ceetm_lni_set_tcfcc(struct qm_ceetm_lni *lni,
147940 + unsigned int cq_level,
147941 + int traffic_class);
147942 +int qman_ceetm_lni_get_tcfcc(struct qm_ceetm_lni *lni,
147943 + unsigned int cq_level,
147944 + int *traffic_class);
147945 +
147946 + /* ----------------------------- */
147947 + /* CEETM :: class queue channels */
147948 + /* ----------------------------- */
147949 +
147950 +/**
147951 + * qman_ceetm_channel_claim - Claims an unclaimed CQ channel that is mapped to
147952 + * the given LNI.
147953 + * @channel: the returned class queue channel object, if successful.
147954 + * @lni: the LNI that the channel belongs to.
147955 + *
147956 + * Channels are always initially "unshaped".
147957 + *
147958 + * Return zero for success, or -ENODEV if there is no channel available(all 32
147959 + * channels are claimed) or -EINVAL if the channel mapping command returns
147960 + * error.
147961 + */
147962 +int qman_ceetm_channel_claim(struct qm_ceetm_channel **channel,
147963 + struct qm_ceetm_lni *lni);
147964 +
147965 +/**
147966 + * qman_ceetm_channel_release - Releases a previously claimed CQ channel.
147967 + * @channel: the channel needs to be released.
147968 + *
147969 + * Returns zero for success, or -EBUSY if the dependencies are still in use.
147970 + *
147971 + * Note any shaping of the channel will be cleared to leave it in an unshaped
147972 + * state.
147973 + */
147974 +int qman_ceetm_channel_release(struct qm_ceetm_channel *channel);
147975 +
147976 +/**
147977 + * qman_ceetm_channel_enable_shaper
147978 + * qman_ceetm_channel_disable_shaper - Enables/disables shaping on the channel.
147979 + * @channel: the given channel.
147980 + * @coupled: indicates whether surplus CR tokens should be added to the
147981 + * excess-rate token count (up to the excess-rate token limit) when the number
147982 + * of (unused) committed-rate tokens reach the committed_rate token limit.
147983 + *
147984 + * Whenever a claimed channel is first enabled for shaping, its committed and
147985 + * excess token rates and limits are zero, so will need to be changed to do
147986 + * anything useful. The shaper can subsequently be enabled/disabled without
147987 + * resetting the shaping parameters, but the shaping parameters will be reset
147988 + * when the channel is released.
147989 + *
147990 + * Return 0 for success, or -EINVAL for failure, in the case that the channel
147991 + * shaper has been enabled/disabled or the management command returns error.
147992 + */
147993 +int qman_ceetm_channel_enable_shaper(struct qm_ceetm_channel *channel,
147994 + int coupled);
147995 +int qman_ceetm_channel_disable_shaper(struct qm_ceetm_channel *channel);
147996 +
147997 +/**
147998 + * qman_ceetm_channel_is_shaper_enabled - Check channel shaper status.
147999 + * @channel: the give channel.
148000 + */
148001 +int qman_ceetm_channel_is_shaper_enabled(struct qm_ceetm_channel *channel);
148002 +
148003 +/**
148004 + * qman_ceetm_channel_set_commit_rate
148005 + * qman_ceetm_channel_get_commit_rate
148006 + * qman_ceetm_channel_set_excess_rate
148007 + * qman_ceetm_channel_get_excess_rate - Set/get channel CR/ER shaper parameters.
148008 + * @channel: the given channel.
148009 + * @token_rate: the desired token rate for "set" function, or the queried token
148010 + * rate for "get" function.
148011 + * @token_limit: the desired token limit for "set" function, or the queried
148012 + * token limit for "get" function.
148013 + *
148014 + * Return zero for success. The "set" function returns -EINVAL if the channel
148015 + * is unshaped, or -EIO if the configure shapper command returns error. The
148016 + * "get" function returns -EINVAL if token rate of token limit is not set, or
148017 + * the query shaper command returns error.
148018 + */
148019 +int qman_ceetm_channel_set_commit_rate(struct qm_ceetm_channel *channel,
148020 + const struct qm_ceetm_rate *token_rate,
148021 + u16 token_limit);
148022 +int qman_ceetm_channel_get_commit_rate(struct qm_ceetm_channel *channel,
148023 + struct qm_ceetm_rate *token_rate,
148024 + u16 *token_limit);
148025 +int qman_ceetm_channel_set_excess_rate(struct qm_ceetm_channel *channel,
148026 + const struct qm_ceetm_rate *token_rate,
148027 + u16 token_limit);
148028 +int qman_ceetm_channel_get_excess_rate(struct qm_ceetm_channel *channel,
148029 + struct qm_ceetm_rate *token_rate,
148030 + u16 *token_limit);
148031 +/**
148032 + * qman_ceetm_channel_set_commit_rate_bps
148033 + * qman_ceetm_channel_get_commit_rate_bps
148034 + * qman_ceetm_channel_set_excess_rate_bps
148035 + * qman_ceetm_channel_get_excess_rate_bps - Set/get channel CR/ER shaper
148036 + * parameters.
148037 + * @channel: the given channel.
148038 + * @token_rate: the desired shaper rate in bps for "set" function, or the
148039 + * shaper rate in bps for "get" function.
148040 + * @token_limit: the desired token limit for "set" function, or the queried
148041 + * token limit for "get" function.
148042 + *
148043 + * Return zero for success. The "set" function returns -EINVAL if the channel
148044 + * is unshaped, or -EIO if the configure shapper command returns error. The
148045 + * "get" function returns -EINVAL if token rate of token limit is not set, or
148046 + * the query shaper command returns error.
148047 + */
148048 +int qman_ceetm_channel_set_commit_rate_bps(struct qm_ceetm_channel *channel,
148049 + u64 bps, u16 token_limit);
148050 +int qman_ceetm_channel_get_commit_rate_bps(struct qm_ceetm_channel *channel,
148051 + u64 *bps, u16 *token_limit);
148052 +int qman_ceetm_channel_set_excess_rate_bps(struct qm_ceetm_channel *channel,
148053 + u64 bps, u16 token_limit);
148054 +int qman_ceetm_channel_get_excess_rate_bps(struct qm_ceetm_channel *channel,
148055 + u64 *bps, u16 *token_limit);
148056 +
148057 +/**
148058 + * qman_ceetm_channel_set_weight
148059 + * qman_ceetm_channel_get_weight - Set/get the weight for unshaped channel
148060 + * @channel: the given channel.
148061 + * @token_limit: the desired token limit as the weight of the unshaped channel
148062 + * for "set" function, or the queried token limit for "get" function.
148063 + *
148064 + * The algorithm of unshaped fair queuing (uFQ) is used for unshaped channel.
148065 + * It allows the unshaped channels to be included in the CR time eligible list,
148066 + * and thus use the configured CR token limit value as their fair queuing
148067 + * weight.
148068 + *
148069 + * Return zero for success, or -EINVAL if the channel is a shaped channel or
148070 + * the management command returns error.
148071 + */
148072 +int qman_ceetm_channel_set_weight(struct qm_ceetm_channel *channel,
148073 + u16 token_limit);
148074 +int qman_ceetm_channel_get_weight(struct qm_ceetm_channel *channel,
148075 + u16 *token_limit);
148076 +
148077 +/**
148078 + * qman_ceetm_channel_set_group
148079 + * qman_ceetm_channel_get_group - Set/get the grouping of the class scheduler.
148080 + * @channel: the given channel.
148081 + * @group_b: indicates whether there is group B in this channel.
148082 + * @prio_a: the priority of group A.
148083 + * @prio_b: the priority of group B.
148084 + *
148085 + * There are 8 individual class queues (CQ0-CQ7), and 8 grouped class queues
148086 + * (CQ8-CQ15). If 'group_b' is zero, then all the grouped class queues are in
148087 + * group A, otherwise they are split into group A (CQ8-11) and group B
148088 + * (CQ12-C15). The individual class queues and the group(s) are in strict
148089 + * priority order relative to each other. Within the group(s), the scheduling
148090 + * is not strict priority order, but the result of scheduling within a group
148091 + * is in strict priority order relative to the other class queues in the
148092 + * channel. 'prio_a' and 'prio_b' control the priority order of the groups
148093 + * relative to the individual class queues, and take values from 0-7. Eg. if
148094 + * 'group_b' is non-zero, 'prio_a' is 2 and 'prio_b' is 6, then the strict
148095 + * priority order would be;
148096 + * CQ0, CQ1, CQ2, GROUPA, CQ3, CQ4, CQ5, CQ6, GROUPB, CQ7
148097 + *
148098 + * Return 0 for success. For "set" function, returns -EINVAL if prio_a or
148099 + * prio_b are out of the range 0 - 7 (priority of group A or group B can not
148100 + * be 0, CQ0 is always the highest class queue in this channel.), or -EIO if
148101 + * the configure scheduler command returns error. For "get" function, return
148102 + * -EINVAL if the query scheduler command returns error.
148103 + */
148104 +int qman_ceetm_channel_set_group(struct qm_ceetm_channel *channel,
148105 + int group_b,
148106 + unsigned int prio_a,
148107 + unsigned int prio_b);
148108 +int qman_ceetm_channel_get_group(struct qm_ceetm_channel *channel,
148109 + int *group_b,
148110 + unsigned int *prio_a,
148111 + unsigned int *prio_b);
148112 +
148113 +/**
148114 + * qman_ceetm_channel_set_group_cr_eligibility
148115 + * qman_ceetm_channel_set_group_er_eligibility - Set channel group eligibility
148116 + * @channel: the given channel object
148117 + * @group_b: indicates whether there is group B in this channel.
148118 + * @cre: the commit rate eligibility, 1 for enable, 0 for disable.
148119 + *
148120 + * Return zero for success, or -EINVAL if eligibility setting fails.
148121 +*/
148122 +int qman_ceetm_channel_set_group_cr_eligibility(struct qm_ceetm_channel
148123 + *channel, int group_b, int cre);
148124 +int qman_ceetm_channel_set_group_er_eligibility(struct qm_ceetm_channel
148125 + *channel, int group_b, int ere);
148126 +
148127 +/**
148128 + * qman_ceetm_channel_set_cq_cr_eligibility
148129 + * qman_ceetm_channel_set_cq_er_eligibility - Set channel cq eligibility
148130 + * @channel: the given channel object
148131 + * @idx: is from 0 to 7 (representing CQ0 to CQ7).
148132 + * @cre: the commit rate eligibility, 1 for enable, 0 for disable.
148133 + *
148134 + * Return zero for success, or -EINVAL if eligibility setting fails.
148135 +*/
148136 +int qman_ceetm_channel_set_cq_cr_eligibility(struct qm_ceetm_channel *channel,
148137 + unsigned int idx, int cre);
148138 +int qman_ceetm_channel_set_cq_er_eligibility(struct qm_ceetm_channel *channel,
148139 + unsigned int idx, int ere);
148140 +
148141 + /* --------------------- */
148142 + /* CEETM :: class queues */
148143 + /* --------------------- */
148144 +
148145 +/**
148146 + * qman_ceetm_cq_claim - Claims an individual class queue.
148147 + * @cq: the returned class queue object, if successful.
148148 + * @channel: the class queue channel.
148149 + * @idx: is from 0 to 7 (representing CQ0 to CQ7).
148150 + * @ccg: represents the class congestion group that this class queue should be
148151 + * subscribed to, or NULL if no congestion group membership is desired.
148152 + *
148153 + * Returns zero for success, or -EINVAL if @idx is out of range 0 - 7 or
148154 + * if this class queue has been claimed, or configure class queue command
148155 + * returns error, or returns -ENOMEM if allocating CQ memory fails.
148156 + */
148157 +int qman_ceetm_cq_claim(struct qm_ceetm_cq **cq,
148158 + struct qm_ceetm_channel *channel,
148159 + unsigned int idx,
148160 + struct qm_ceetm_ccg *ccg);
148161 +
148162 +/**
148163 + * qman_ceetm_cq_claim_A - Claims a class queue group A.
148164 + * @cq: the returned class queue object, if successful.
148165 + * @channel: the class queue channel.
148166 + * @idx: is from 8 to 15 if only group A exits, otherwise, it is from 8 to 11.
148167 + * @ccg: represents the class congestion group that this class queue should be
148168 + * subscribed to, or NULL if no congestion group membership is desired.
148169 + *
148170 + * Return zero for success, or -EINVAL if @idx is out the range or if
148171 + * this class queue has been claimed or configure class queue command returns
148172 + * error, or returns -ENOMEM if allocating CQ memory fails.
148173 + */
148174 +int qman_ceetm_cq_claim_A(struct qm_ceetm_cq **cq,
148175 + struct qm_ceetm_channel *channel,
148176 + unsigned int idx,
148177 + struct qm_ceetm_ccg *ccg);
148178 +
148179 +/**
148180 + * qman_ceetm_cq_claim_B - Claims a class queue group B.
148181 + * @cq: the returned class queue object, if successful.
148182 + * @channel: the class queue channel.
148183 + * @idx: is from 0 to 3 (CQ12 to CQ15).
148184 + * @ccg: represents the class congestion group that this class queue should be
148185 + * subscribed to, or NULL if no congestion group membership is desired.
148186 + *
148187 + * Return zero for success, or -EINVAL if @idx is out the range or if
148188 + * this class queue has been claimed or configure class queue command returns
148189 + * error, or returns -ENOMEM if allocating CQ memory fails.
148190 + */
148191 +int qman_ceetm_cq_claim_B(struct qm_ceetm_cq **cq,
148192 + struct qm_ceetm_channel *channel,
148193 + unsigned int idx,
148194 + struct qm_ceetm_ccg *ccg);
148195 +
148196 +/**
148197 + * qman_ceetm_cq_release - Releases a previously claimed class queue.
148198 + * @cq: The class queue to be released.
148199 + *
148200 + * Return zero for success, or -EBUSY if the dependent objects (eg. logical
148201 + * FQIDs) have not been released.
148202 + */
148203 +int qman_ceetm_cq_release(struct qm_ceetm_cq *cq);
148204 +
148205 +/**
148206 + * qman_ceetm_set_queue_weight
148207 + * qman_ceetm_get_queue_weight - Configure/query the weight of a grouped class
148208 + * queue.
148209 + * @cq: the given class queue.
148210 + * @weight_code: the desired weight code to set for the given class queue for
148211 + * "set" function or the queired weight code for "get" function.
148212 + *
148213 + * Grouped class queues have a default weight code of zero, which corresponds to
148214 + * a scheduler weighting of 1. This function can be used to modify a grouped
148215 + * class queue to another weight, (Use the helpers qman_ceetm_wbfs2ratio()
148216 + * and qman_ceetm_ratio2wbfs() to convert between these 'weight_code' values
148217 + * and the corresponding sharing weight.)
148218 + *
148219 + * Returns zero for success, or -EIO if the configure weight command returns
148220 + * error for "set" function, or -EINVAL if the query command returns
148221 + * error for "get" function.
148222 + * See section "CEETM Weighted Scheduling among Grouped Classes" in Reference
148223 + * Manual for weight and weight code.
148224 + */
148225 +int qman_ceetm_set_queue_weight(struct qm_ceetm_cq *cq,
148226 + struct qm_ceetm_weight_code *weight_code);
148227 +int qman_ceetm_get_queue_weight(struct qm_ceetm_cq *cq,
148228 + struct qm_ceetm_weight_code *weight_code);
148229 +
148230 +/**
148231 + * qman_ceetm_set_queue_weight_in_ratio
148232 + * qman_ceetm_get_queue_weight_in_ratio - Configure/query the weight of a
148233 + * grouped class queue.
148234 + * @cq: the given class queue.
148235 + * @ratio: the weight in ratio. It should be the real ratio number multiplied
148236 + * by 100 to get rid of fraction.
148237 + *
148238 + * Returns zero for success, or -EIO if the configure weight command returns
148239 + * error for "set" function, or -EINVAL if the query command returns
148240 + * error for "get" function.
148241 + */
148242 +int qman_ceetm_set_queue_weight_in_ratio(struct qm_ceetm_cq *cq, u32 ratio);
148243 +int qman_ceetm_get_queue_weight_in_ratio(struct qm_ceetm_cq *cq, u32 *ratio);
148244 +
148245 +/* Weights are encoded using a pseudo-exponential scheme. The weight codes 0,
148246 + * 32, 64, [...] correspond to weights of 1, 2, 4, [...]. The weights
148247 + * corresponding to intermediate weight codes are calculated using linear
148248 + * interpolation on the inverted values. Or put another way, the inverse weights
148249 + * for each 32nd weight code are 1, 1/2, 1/4, [...], and so the intervals
148250 + * between these are divided linearly into 32 intermediate values, the inverses
148251 + * of which form the remaining weight codes.
148252 + *
148253 + * The Weighted Bandwidth Fair Scheduling (WBFS) algorithm provides a form of
148254 + * scheduling within a group of class queues (group A or B). Weights are used to
148255 + * normalise the class queues to an underlying BFS algorithm where all class
148256 + * queues are assumed to require "equal bandwidth". So the weights referred to
148257 + * by the weight codes act as divisors on the size of frames being enqueued. Ie.
148258 + * one class queue in a group is assigned a weight of 2 whilst the other class
148259 + * queues in the group keep the default weight of 1, then the WBFS scheduler
148260 + * will effectively treat all frames enqueued on the weight-2 class queue as
148261 + * having half the number of bytes they really have. Ie. if all other things are
148262 + * equal, that class queue would get twice as much bytes-per-second bandwidth as
148263 + * the others. So weights should be chosen to provide bandwidth ratios between
148264 + * members of the same class queue group. These weights have no bearing on
148265 + * behaviour outside that group's WBFS mechanism though.
148266 + */
148267 +
148268 +/**
148269 + * qman_ceetm_wbfs2ratio - Given a weight code ('wbfs'), an accurate fractional
148270 + * representation of the corresponding weight is given (in order to not lose
148271 + * any precision).
148272 + * @weight_code: The given weight code in WBFS.
148273 + * @numerator: the numerator part of the weight computed by the weight code.
148274 + * @denominator: the denominator part of the weight computed by the weight code
148275 + *
148276 + * Returns zero for success or -EINVAL if the given weight code is illegal.
148277 + */
148278 +int qman_ceetm_wbfs2ratio(struct qm_ceetm_weight_code *weight_code,
148279 + u32 *numerator,
148280 + u32 *denominator);
148281 +/**
148282 + * qman_ceetm_ratio2wbfs - Given a weight, find the nearest possible weight code
148283 + * If the user needs to know how close this is, convert the resulting weight
148284 + * code back to a weight and compare.
148285 + * @numerator: numerator part of the given weight.
148286 + * @denominator: denominator part of the given weight.
148287 + * @weight_code: the weight code computed from the given weight.
148288 + *
148289 + * Returns zero for success, or -ERANGE if "numerator/denominator" is outside
148290 + * the range of weights.
148291 + */
148292 +int qman_ceetm_ratio2wbfs(u32 numerator,
148293 + u32 denominator,
148294 + struct qm_ceetm_weight_code *weight_code,
148295 + int rounding);
148296 +
148297 +#define QMAN_CEETM_FLAG_CLEAR_STATISTICS_COUNTER 0x1
148298 +/**
148299 + * qman_ceetm_cq_get_dequeue_statistics - Get the statistics provided by CEETM
148300 + * CQ counters.
148301 + * @cq: the given CQ object.
148302 + * @flags: indicates whether the statistics counter will be cleared after query.
148303 + * @frame_count: The number of the frames that have been counted since the
148304 + * counter was cleared last time.
148305 + * @byte_count: the number of bytes in all frames that have been counted.
148306 + *
148307 + * Return zero for success or -EINVAL if query statistics command returns error.
148308 + *
148309 + */
148310 +int qman_ceetm_cq_get_dequeue_statistics(struct qm_ceetm_cq *cq, u32 flags,
148311 + u64 *frame_count, u64 *byte_count);
148312 +
148313 +/**
148314 + * qman_ceetm_drain_cq - drain the CQ till it is empty.
148315 + * @cq: the give CQ object.
148316 + * Return 0 for success or -EINVAL for unsuccessful command to empty CQ.
148317 + */
148318 +int qman_ceetm_drain_cq(struct qm_ceetm_cq *cq);
148319 +
148320 + /* ---------------------- */
148321 + /* CEETM :: logical FQIDs */
148322 + /* ---------------------- */
148323 +/**
148324 + * qman_ceetm_lfq_claim - Claims an unused logical FQID, associates it with
148325 + * the given class queue.
148326 + * @lfq: the returned lfq object, if successful.
148327 + * @cq: the class queue which needs to claim a LFQID.
148328 + *
148329 + * Return zero for success, or -ENODEV if no LFQID is available or -ENOMEM if
148330 + * allocating memory for lfq fails, or -EINVAL if configuring LFQMT fails.
148331 + */
148332 +int qman_ceetm_lfq_claim(struct qm_ceetm_lfq **lfq,
148333 + struct qm_ceetm_cq *cq);
148334 +
148335 +/**
148336 + * qman_ceetm_lfq_release - Releases a previously claimed logical FQID.
148337 + * @lfq: the lfq to be released.
148338 + *
148339 + * Return zero for success.
148340 + */
148341 +int qman_ceetm_lfq_release(struct qm_ceetm_lfq *lfq);
148342 +
148343 +/**
148344 + * qman_ceetm_lfq_set_context
148345 + * qman_ceetm_lfq_get_context - Set/get the context_a/context_b pair to the
148346 + * "dequeue context table" associated with the logical FQID.
148347 + * @lfq: the given logical FQ object.
148348 + * @context_a: contextA of the dequeue context.
148349 + * @context_b: contextB of the dequeue context.
148350 + *
148351 + * Returns zero for success, or -EINVAL if there is error to set/get the
148352 + * context pair.
148353 + */
148354 +int qman_ceetm_lfq_set_context(struct qm_ceetm_lfq *lfq,
148355 + u64 context_a,
148356 + u32 context_b);
148357 +int qman_ceetm_lfq_get_context(struct qm_ceetm_lfq *lfq,
148358 + u64 *context_a,
148359 + u32 *context_b);
148360 +
148361 +/**
148362 + * qman_ceetm_create_fq - Initialise a FQ object for the LFQ.
148363 + * @lfq: the given logic fq.
148364 + * @fq: the fq object created for the given logic fq.
148365 + *
148366 + * The FQ object can be used in qman_enqueue() and qman_enqueue_orp() APIs to
148367 + * target a logical FQID (and the class queue it is associated with).
148368 + * Note that this FQ object can only be used for enqueues, and
148369 + * in the case of qman_enqueue_orp() it can not be used as the 'orp' parameter,
148370 + * only as 'fq'. This FQ object can not (and shouldn't) be destroyed, it is only
148371 + * valid as long as the underlying 'lfq' remains claimed. It is the user's
148372 + * responsibility to ensure that the underlying 'lfq' is not released until any
148373 + * enqueues to this FQ object have completed. The only field the user needs to
148374 + * fill in is fq->cb.ern, as that enqueue rejection handler is the callback that
148375 + * could conceivably be called on this FQ object. This API can be called
148376 + * multiple times to create multiple FQ objects referring to the same logical
148377 + * FQID, and any enqueue rejections will respect the callback of the object that
148378 + * issued the enqueue (and will identify the object via the parameter passed to
148379 + * the callback too). There is no 'flags' parameter to this API as there is for
148380 + * qman_create_fq() - the created FQ object behaves as though qman_create_fq()
148381 + * had been called with the single flag QMAN_FQ_FLAG_NO_MODIFY.
148382 + *
148383 + * Returns 0 for success.
148384 + */
148385 +int qman_ceetm_create_fq(struct qm_ceetm_lfq *lfq, struct qman_fq *fq);
148386 +
148387 + /* -------------------------------- */
148388 + /* CEETM :: class congestion groups */
148389 + /* -------------------------------- */
148390 +
148391 +/**
148392 + * qman_ceetm_ccg_claim - Claims an unused CCG.
148393 + * @ccg: the returned CCG object, if successful.
148394 + * @channel: the given class queue channel
148395 + * @cscn: the callback function of this CCG.
148396 + * @cb_ctx: the corresponding context to be used used if state change
148397 + * notifications are later enabled for this CCG.
148398 + *
148399 + * The congestion group is local to the given class queue channel, so only
148400 + * class queues within the channel can be associated with that congestion group.
148401 + * The association of class queues to congestion groups occurs when the class
148402 + * queues are claimed, see qman_ceetm_cq_claim() and related functions.
148403 + * Congestion groups are in a "zero" state when initially claimed, and they are
148404 + * returned to that state when released.
148405 + *
148406 + * Return zero for success, or -EINVAL if no CCG in the channel is available.
148407 + */
148408 +int qman_ceetm_ccg_claim(struct qm_ceetm_ccg **ccg,
148409 + struct qm_ceetm_channel *channel,
148410 + unsigned int idx,
148411 + void (*cscn)(struct qm_ceetm_ccg *,
148412 + void *cb_ctx,
148413 + int congested),
148414 + void *cb_ctx);
148415 +
148416 +/**
148417 + * qman_ceetm_ccg_release - Releases a previously claimed CCG.
148418 + * @ccg: the given ccg.
148419 + *
148420 + * Returns zero for success, or -EBUSY if the given ccg's dependent objects
148421 + * (class queues that are associated with the CCG) have not been released.
148422 + */
148423 +int qman_ceetm_ccg_release(struct qm_ceetm_ccg *ccg);
148424 +
148425 +/* This struct is used to specify attributes for a CCG. The 'we_mask' field
148426 + * controls which CCG attributes are to be updated, and the remainder specify
148427 + * the values for those attributes. A CCG counts either frames or the bytes
148428 + * within those frames, but not both ('mode'). A CCG can optionally cause
148429 + * enqueues to be rejected, due to tail-drop or WRED, or both (they are
148430 + * independent options, 'td_en' and 'wr_en_g,wr_en_y,wr_en_r'). Tail-drop can be
148431 + * level-triggered due to a single threshold ('td_thres') or edge-triggered due
148432 + * to a "congestion state", but not both ('td_mode'). Congestion state has
148433 + * distinct entry and exit thresholds ('cs_thres_in' and 'cs_thres_out'), and
148434 + * notifications can be sent to software the CCG goes in to and out of this
148435 + * congested state ('cscn_en'). */
148436 +struct qm_ceetm_ccg_params {
148437 + /* Boolean fields together in a single bitfield struct */
148438 + struct {
148439 + /* Whether to count bytes or frames. 1==frames */
148440 + u8 mode:1;
148441 + /* En/disable tail-drop. 1==enable */
148442 + u8 td_en:1;
148443 + /* Tail-drop on congestion-state or threshold. 1=threshold */
148444 + u8 td_mode:1;
148445 + /* Generate congestion state change notifications. 1==enable */
148446 + u8 cscn_en:1;
148447 + /* Enable WRED rejections (per colour). 1==enable */
148448 + u8 wr_en_g:1;
148449 + u8 wr_en_y:1;
148450 + u8 wr_en_r:1;
148451 + } __packed;
148452 + /* Tail-drop threshold. See qm_cgr_thres_[gs]et64(). */
148453 + struct qm_cgr_cs_thres td_thres;
148454 + /* Congestion state thresholds, for entry and exit. */
148455 + struct qm_cgr_cs_thres cs_thres_in;
148456 + struct qm_cgr_cs_thres cs_thres_out;
148457 + /* Overhead accounting length. Per-packet "tax", from -128 to +127 */
148458 + signed char oal;
148459 + /* Congestion state change notification for DCP portal, virtual CCGID*/
148460 + /* WRED parameters. */
148461 + struct qm_cgr_wr_parm wr_parm_g;
148462 + struct qm_cgr_wr_parm wr_parm_y;
148463 + struct qm_cgr_wr_parm wr_parm_r;
148464 +};
148465 +/* Bits used in 'we_mask' to qman_ceetm_ccg_set(), controls which attributes of
148466 + * the CCGR are to be updated. */
148467 +#define QM_CCGR_WE_MODE 0x0001 /* mode (bytes/frames) */
148468 +#define QM_CCGR_WE_CS_THRES_IN 0x0002 /* congestion state entry threshold */
148469 +#define QM_CCGR_WE_TD_EN 0x0004 /* congestion state tail-drop enable */
148470 +#define QM_CCGR_WE_CSCN_TUPD 0x0008 /* CSCN target update */
148471 +#define QM_CCGR_WE_CSCN_EN 0x0010 /* congestion notification enable */
148472 +#define QM_CCGR_WE_WR_EN_R 0x0020 /* WRED enable - red */
148473 +#define QM_CCGR_WE_WR_EN_Y 0x0040 /* WRED enable - yellow */
148474 +#define QM_CCGR_WE_WR_EN_G 0x0080 /* WRED enable - green */
148475 +#define QM_CCGR_WE_WR_PARM_R 0x0100 /* WRED parameters - red */
148476 +#define QM_CCGR_WE_WR_PARM_Y 0x0200 /* WRED parameters - yellow */
148477 +#define QM_CCGR_WE_WR_PARM_G 0x0400 /* WRED parameters - green */
148478 +#define QM_CCGR_WE_OAL 0x0800 /* overhead accounting length */
148479 +#define QM_CCGR_WE_CS_THRES_OUT 0x1000 /* congestion state exit threshold */
148480 +#define QM_CCGR_WE_TD_THRES 0x2000 /* tail-drop threshold */
148481 +#define QM_CCGR_WE_TD_MODE 0x4000 /* tail-drop mode (state/threshold) */
148482 +#define QM_CCGR_WE_CDV 0x8000 /* cdv */
148483 +
148484 +/**
148485 + * qman_ceetm_ccg_set
148486 + * qman_ceetm_ccg_get - Configure/query a subset of CCG attributes.
148487 + * @ccg: the given CCG object.
148488 + * @we_mask: the write enable mask.
148489 + * @params: the parameters setting for this ccg
148490 + *
148491 + * Return 0 for success, or -EIO if configure ccg command returns error for
148492 + * "set" function, or -EINVAL if query ccg command returns error for "get"
148493 + * function.
148494 + */
148495 +int qman_ceetm_ccg_set(struct qm_ceetm_ccg *ccg,
148496 + u16 we_mask,
148497 + const struct qm_ceetm_ccg_params *params);
148498 +int qman_ceetm_ccg_get(struct qm_ceetm_ccg *ccg,
148499 + struct qm_ceetm_ccg_params *params);
148500 +
148501 +/** qman_ceetm_cscn_swp_set - Add or remove a software portal from the target
148502 + * mask.
148503 + * qman_ceetm_cscn_swp_get - Query whether a given software portal index is
148504 + * in the cscn target mask.
148505 + * @ccg: the give CCG object.
148506 + * @swp_idx: the index of the software portal.
148507 + * @cscn_enabled: 1: Set the swp to be cscn target. 0: remove the swp from
148508 + * the target mask.
148509 + * @we_mask: the write enable mask.
148510 + * @params: the parameters setting for this ccg
148511 + *
148512 + * Return 0 for success, or -EINVAL if command in set/get function fails.
148513 + */
148514 +int qman_ceetm_cscn_swp_set(struct qm_ceetm_ccg *ccg,
148515 + u16 swp_idx,
148516 + unsigned int cscn_enabled,
148517 + u16 we_mask,
148518 + const struct qm_ceetm_ccg_params *params);
148519 +int qman_ceetm_cscn_swp_get(struct qm_ceetm_ccg *ccg,
148520 + u16 swp_idx,
148521 + unsigned int *cscn_enabled);
148522 +
148523 +/** qman_ceetm_cscn_dcp_set - Add or remove a direct connect portal from the\
148524 + * target mask.
148525 + * qman_ceetm_cscn_dcp_get - Query whether a given direct connect portal index
148526 + * is in the cscn target mask.
148527 + * @ccg: the give CCG object.
148528 + * @dcp_idx: the index of the direct connect portal.
148529 + * @vcgid: congestion state change notification for dcp portal, virtual CGID.
148530 + * @cscn_enabled: 1: Set the dcp to be cscn target. 0: remove the dcp from
148531 + * the target mask.
148532 + * @we_mask: the write enable mask.
148533 + * @params: the parameters setting for this ccg
148534 + *
148535 + * Return 0 for success, or -EINVAL if command in set/get function fails.
148536 + */
148537 +int qman_ceetm_cscn_dcp_set(struct qm_ceetm_ccg *ccg,
148538 + u16 dcp_idx,
148539 + u8 vcgid,
148540 + unsigned int cscn_enabled,
148541 + u16 we_mask,
148542 + const struct qm_ceetm_ccg_params *params);
148543 +int qman_ceetm_cscn_dcp_get(struct qm_ceetm_ccg *ccg,
148544 + u16 dcp_idx,
148545 + u8 *vcgid,
148546 + unsigned int *cscn_enabled);
148547 +
148548 +/**
148549 + * qman_ceetm_ccg_get_reject_statistics - Get the statistics provided by
148550 + * CEETM CCG counters.
148551 + * @ccg: the given CCG object.
148552 + * @flags: indicates whether the statistics counter will be cleared after query.
148553 + * @frame_count: The number of the frames that have been counted since the
148554 + * counter was cleared last time.
148555 + * @byte_count: the number of bytes in all frames that have been counted.
148556 + *
148557 + * Return zero for success or -EINVAL if query statistics command returns error.
148558 + *
148559 + */
148560 +int qman_ceetm_ccg_get_reject_statistics(struct qm_ceetm_ccg *ccg, u32 flags,
148561 + u64 *frame_count, u64 *byte_count);
148562 +
148563 +/**
148564 + * qman_ceetm_query_lfqmt - Query the logical frame queue mapping table
148565 + * @lfqid: Logical Frame Queue ID
148566 + * @lfqmt_query: Results of the query command
148567 + *
148568 + * Returns zero for success or -EIO if the query command returns error.
148569 + *
148570 + */
148571 +int qman_ceetm_query_lfqmt(int lfqid,
148572 + struct qm_mcr_ceetm_lfqmt_query *lfqmt_query);
148573 +
148574 +/**
148575 + * qman_ceetm_query_write_statistics - Query (and optionally write) statistics
148576 + * @cid: Target ID (CQID or CCGRID)
148577 + * @dcp_idx: CEETM portal ID
148578 + * @command_type: One of the following:
148579 + * 0 = Query dequeue statistics. CID carries the CQID to be queried.
148580 + * 1 = Query and clear dequeue statistics. CID carries the CQID to be queried
148581 + * 2 = Write dequeue statistics. CID carries the CQID to be written.
148582 + * 3 = Query reject statistics. CID carries the CCGRID to be queried.
148583 + * 4 = Query and clear reject statistics. CID carries the CCGRID to be queried
148584 + * 5 = Write reject statistics. CID carries the CCGRID to be written
148585 + * @frame_count: Frame count value to be written if this is a write command
148586 + * @byte_count: Bytes count value to be written if this is a write command
148587 + *
148588 + * Returns zero for success or -EIO if the query command returns error.
148589 + */
148590 +int qman_ceetm_query_write_statistics(u16 cid, enum qm_dc_portal dcp_idx,
148591 + u16 command_type, u64 frame_count,
148592 + u64 byte_count);
148593 +
148594 +/**
148595 + * qman_set_wpm - Set waterfall power management
148596 + *
148597 + * @wpm_enable: boolean, 1 = enable wpm, 0 = disable wpm.
148598 + *
148599 + * Return 0 for success, return -ENODEV if QMan misc_cfg register is not
148600 + * accessible.
148601 + */
148602 +int qman_set_wpm(int wpm_enable);
148603 +
148604 +/**
148605 + * qman_get_wpm - Query the waterfall power management setting
148606 + *
148607 + * @wpm_enable: boolean, 1 = enable wpm, 0 = disable wpm.
148608 + *
148609 + * Return 0 for success, return -ENODEV if QMan misc_cfg register is not
148610 + * accessible.
148611 + */
148612 +int qman_get_wpm(int *wpm_enable);
148613 +
148614 +/* The below qman_p_***() variants might be called in a migration situation
148615 + * (e.g. cpu hotplug). They are used to continue accessing the portal that
148616 + * execution was affine to prior to migration.
148617 + * @qman_portal specifies which portal the APIs will use.
148618 +*/
148619 +const struct qman_portal_config *qman_p_get_portal_config(struct qman_portal
148620 + *p);
148621 +int qman_p_irqsource_add(struct qman_portal *p, u32 bits);
148622 +int qman_p_irqsource_remove(struct qman_portal *p, u32 bits);
148623 +int qman_p_poll_dqrr(struct qman_portal *p, unsigned int limit);
148624 +u32 qman_p_poll_slow(struct qman_portal *p);
148625 +void qman_p_poll(struct qman_portal *p);
148626 +void qman_p_stop_dequeues(struct qman_portal *p);
148627 +void qman_p_start_dequeues(struct qman_portal *p);
148628 +void qman_p_static_dequeue_add(struct qman_portal *p, u32 pools);
148629 +void qman_p_static_dequeue_del(struct qman_portal *p, u32 pools);
148630 +u32 qman_p_static_dequeue_get(struct qman_portal *p);
148631 +void qman_p_dca(struct qman_portal *p, struct qm_dqrr_entry *dq,
148632 + int park_request);
148633 +int qman_p_volatile_dequeue(struct qman_portal *p, struct qman_fq *fq,
148634 + u32 flags __maybe_unused, u32 vdqcr);
148635 +int qman_p_enqueue(struct qman_portal *p, struct qman_fq *fq,
148636 + const struct qm_fd *fd, u32 flags);
148637 +int qman_p_enqueue_orp(struct qman_portal *p, struct qman_fq *fq,
148638 + const struct qm_fd *fd, u32 flags,
148639 + struct qman_fq *orp, u16 orp_seqnum);
148640 +int qman_p_enqueue_precommit(struct qman_portal *p, struct qman_fq *fq,
148641 + const struct qm_fd *fd, u32 flags,
148642 + qman_cb_precommit cb, void *cb_arg);
148643 +#ifdef __cplusplus
148644 +}
148645 +#endif
148646 +
148647 +#endif /* FSL_QMAN_H */
148648 --- /dev/null
148649 +++ b/include/linux/fsl_usdpaa.h
148650 @@ -0,0 +1,372 @@
148651 +/* Copyright 2011-2012 Freescale Semiconductor, Inc.
148652 + *
148653 + * This file is licensed under the terms of the GNU General Public License
148654 + * version 2. This program is licensed "as is" without any warranty of any
148655 + * kind, whether express or implied.
148656 + */
148657 +
148658 +#ifndef FSL_USDPAA_H
148659 +#define FSL_USDPAA_H
148660 +
148661 +#ifdef __cplusplus
148662 +extern "C" {
148663 +#endif
148664 +
148665 +#include <linux/uaccess.h>
148666 +#include <linux/ioctl.h>
148667 +#include <linux/fsl_qman.h> /* For "enum qm_channel" */
148668 +#include <linux/compat.h>
148669 +
148670 +#ifdef CONFIG_FSL_USDPAA
148671 +
148672 +/******************************/
148673 +/* Allocation of resource IDs */
148674 +/******************************/
148675 +
148676 +/* This enum is used to distinguish between the type of underlying object being
148677 + * manipulated. */
148678 +enum usdpaa_id_type {
148679 + usdpaa_id_fqid,
148680 + usdpaa_id_bpid,
148681 + usdpaa_id_qpool,
148682 + usdpaa_id_cgrid,
148683 + usdpaa_id_ceetm0_lfqid,
148684 + usdpaa_id_ceetm0_channelid,
148685 + usdpaa_id_ceetm1_lfqid,
148686 + usdpaa_id_ceetm1_channelid,
148687 + usdpaa_id_max /* <-- not a valid type, represents the number of types */
148688 +};
148689 +#define USDPAA_IOCTL_MAGIC 'u'
148690 +struct usdpaa_ioctl_id_alloc {
148691 + uint32_t base; /* Return value, the start of the allocated range */
148692 + enum usdpaa_id_type id_type; /* what kind of resource(s) to allocate */
148693 + uint32_t num; /* how many IDs to allocate (and return value) */
148694 + uint32_t align; /* must be a power of 2, 0 is treated like 1 */
148695 + int partial; /* whether to allow less than 'num' */
148696 +};
148697 +struct usdpaa_ioctl_id_release {
148698 + /* Input; */
148699 + enum usdpaa_id_type id_type;
148700 + uint32_t base;
148701 + uint32_t num;
148702 +};
148703 +struct usdpaa_ioctl_id_reserve {
148704 + enum usdpaa_id_type id_type;
148705 + uint32_t base;
148706 + uint32_t num;
148707 +};
148708 +
148709 +
148710 +/* ioctl() commands */
148711 +#define USDPAA_IOCTL_ID_ALLOC \
148712 + _IOWR(USDPAA_IOCTL_MAGIC, 0x01, struct usdpaa_ioctl_id_alloc)
148713 +#define USDPAA_IOCTL_ID_RELEASE \
148714 + _IOW(USDPAA_IOCTL_MAGIC, 0x02, struct usdpaa_ioctl_id_release)
148715 +#define USDPAA_IOCTL_ID_RESERVE \
148716 + _IOW(USDPAA_IOCTL_MAGIC, 0x0A, struct usdpaa_ioctl_id_reserve)
148717 +
148718 +/**********************/
148719 +/* Mapping DMA memory */
148720 +/**********************/
148721 +
148722 +/* Maximum length for a map name, including NULL-terminator */
148723 +#define USDPAA_DMA_NAME_MAX 16
148724 +/* Flags for requesting DMA maps. Maps are private+unnamed or sharable+named.
148725 + * For a sharable and named map, specify _SHARED (whether creating one or
148726 + * binding to an existing one). If _SHARED is specified and _CREATE is not, then
148727 + * the mapping must already exist. If _SHARED and _CREATE are specified and the
148728 + * mapping doesn't already exist, it will be created. If _SHARED and _CREATE are
148729 + * specified and the mapping already exists, the mapping will fail unless _LAZY
148730 + * is specified. When mapping to a pre-existing sharable map, the length must be
148731 + * an exact match. Lengths must be a power-of-4 multiple of page size.
148732 + *
148733 + * Note that this does not actually map the memory to user-space, that is done
148734 + * by a subsequent mmap() using the page offset returned from this ioctl(). The
148735 + * ioctl() is what gives the process permission to do this, and a page-offset
148736 + * with which to do so.
148737 + */
148738 +#define USDPAA_DMA_FLAG_SHARE 0x01
148739 +#define USDPAA_DMA_FLAG_CREATE 0x02
148740 +#define USDPAA_DMA_FLAG_LAZY 0x04
148741 +#define USDPAA_DMA_FLAG_RDONLY 0x08
148742 +struct usdpaa_ioctl_dma_map {
148743 + /* Output parameters - virtual and physical addresses */
148744 + void *ptr;
148745 + uint64_t phys_addr;
148746 + /* Input parameter, the length of the region to be created (or if
148747 + * mapping an existing region, this must match it). Must be a power-of-4
148748 + * multiple of page size. */
148749 + uint64_t len;
148750 + /* Input parameter, the USDPAA_DMA_FLAG_* settings. */
148751 + uint32_t flags;
148752 + /* If _FLAG_SHARE is specified, the name of the region to be created (or
148753 + * of the existing mapping to use). */
148754 + char name[USDPAA_DMA_NAME_MAX];
148755 + /* If this ioctl() creates the mapping, this is an input parameter
148756 + * stating whether the region supports locking. If mapping an existing
148757 + * region, this is a return value indicating the same thing. */
148758 + int has_locking;
148759 + /* In the case of a successful map with _CREATE and _LAZY, this return
148760 + * value indicates whether we created the mapped region or whether it
148761 + * already existed. */
148762 + int did_create;
148763 +};
148764 +
148765 +#ifdef CONFIG_COMPAT
148766 +struct usdpaa_ioctl_dma_map_compat {
148767 + /* Output parameters - virtual and physical addresses */
148768 + compat_uptr_t ptr;
148769 + uint64_t phys_addr;
148770 + /* Input parameter, the length of the region to be created (or if
148771 + * mapping an existing region, this must match it). Must be a power-of-4
148772 + * multiple of page size. */
148773 + uint64_t len;
148774 + /* Input parameter, the USDPAA_DMA_FLAG_* settings. */
148775 + uint32_t flags;
148776 + /* If _FLAG_SHARE is specified, the name of the region to be created (or
148777 + * of the existing mapping to use). */
148778 + char name[USDPAA_DMA_NAME_MAX];
148779 + /* If this ioctl() creates the mapping, this is an input parameter
148780 + * stating whether the region supports locking. If mapping an existing
148781 + * region, this is a return value indicating the same thing. */
148782 + int has_locking;
148783 + /* In the case of a successful map with _CREATE and _LAZY, this return
148784 + * value indicates whether we created the mapped region or whether it
148785 + * already existed. */
148786 + int did_create;
148787 +};
148788 +
148789 +#define USDPAA_IOCTL_DMA_MAP_COMPAT \
148790 + _IOWR(USDPAA_IOCTL_MAGIC, 0x03, struct usdpaa_ioctl_dma_map_compat)
148791 +#endif
148792 +
148793 +
148794 +#define USDPAA_IOCTL_DMA_MAP \
148795 + _IOWR(USDPAA_IOCTL_MAGIC, 0x03, struct usdpaa_ioctl_dma_map)
148796 +/* munmap() does not remove the DMA map, just the user-space mapping to it.
148797 + * This ioctl will do both (though you can munmap() before calling the ioctl
148798 + * too). */
148799 +#define USDPAA_IOCTL_DMA_UNMAP \
148800 + _IOW(USDPAA_IOCTL_MAGIC, 0x04, unsigned char)
148801 +/* We implement a cross-process locking scheme per DMA map. Call this ioctl()
148802 + * with a mmap()'d address, and the process will (interruptible) sleep if the
148803 + * lock is already held by another process. Process destruction will
148804 + * automatically clean up any held locks. */
148805 +#define USDPAA_IOCTL_DMA_LOCK \
148806 + _IOW(USDPAA_IOCTL_MAGIC, 0x05, unsigned char)
148807 +#define USDPAA_IOCTL_DMA_UNLOCK \
148808 + _IOW(USDPAA_IOCTL_MAGIC, 0x06, unsigned char)
148809 +
148810 +/***************************************/
148811 +/* Mapping and using QMan/BMan portals */
148812 +/***************************************/
148813 +enum usdpaa_portal_type {
148814 + usdpaa_portal_qman,
148815 + usdpaa_portal_bman,
148816 +};
148817 +
148818 +#define QBMAN_ANY_PORTAL_IDX 0xffffffff
148819 +
148820 +struct usdpaa_ioctl_portal_map {
148821 + /* Input parameter, is a qman or bman portal required. */
148822 +
148823 + enum usdpaa_portal_type type;
148824 + /* Specifes a specific portal index to map or QBMAN_ANY_PORTAL_IDX
148825 + for don't care. The portal index will be populated by the
148826 + driver when the ioctl() successfully completes */
148827 + uint32_t index;
148828 +
148829 + /* Return value if the map succeeds, this gives the mapped
148830 + * cache-inhibited (cinh) and cache-enabled (cena) addresses. */
148831 + struct usdpaa_portal_map {
148832 + void *cinh;
148833 + void *cena;
148834 + } addr;
148835 + /* Qman-specific return values */
148836 + uint16_t channel;
148837 + uint32_t pools;
148838 +};
148839 +
148840 +#ifdef CONFIG_COMPAT
148841 +struct compat_usdpaa_ioctl_portal_map {
148842 + /* Input parameter, is a qman or bman portal required. */
148843 + enum usdpaa_portal_type type;
148844 + /* Specifes a specific portal index to map or QBMAN_ANY_PORTAL_IDX
148845 + for don't care. The portal index will be populated by the
148846 + driver when the ioctl() successfully completes */
148847 + uint32_t index;
148848 + /* Return value if the map succeeds, this gives the mapped
148849 + * cache-inhibited (cinh) and cache-enabled (cena) addresses. */
148850 + struct usdpaa_portal_map_compat {
148851 + compat_uptr_t cinh;
148852 + compat_uptr_t cena;
148853 + } addr;
148854 + /* Qman-specific return values */
148855 + uint16_t channel;
148856 + uint32_t pools;
148857 +};
148858 +#define USDPAA_IOCTL_PORTAL_MAP_COMPAT \
148859 + _IOWR(USDPAA_IOCTL_MAGIC, 0x07, struct compat_usdpaa_ioctl_portal_map)
148860 +#define USDPAA_IOCTL_PORTAL_UNMAP_COMPAT \
148861 + _IOW(USDPAA_IOCTL_MAGIC, 0x08, struct usdpaa_portal_map_compat)
148862 +#endif
148863 +
148864 +#define USDPAA_IOCTL_PORTAL_MAP \
148865 + _IOWR(USDPAA_IOCTL_MAGIC, 0x07, struct usdpaa_ioctl_portal_map)
148866 +#define USDPAA_IOCTL_PORTAL_UNMAP \
148867 + _IOW(USDPAA_IOCTL_MAGIC, 0x08, struct usdpaa_portal_map)
148868 +
148869 +struct usdpaa_ioctl_irq_map {
148870 + enum usdpaa_portal_type type; /* Type of portal to map */
148871 + int fd; /* File descriptor that contains the portal */
148872 + void *portal_cinh; /* Cache inhibited area to identify the portal */
148873 +};
148874 +
148875 +#define USDPAA_IOCTL_PORTAL_IRQ_MAP \
148876 + _IOW(USDPAA_IOCTL_MAGIC, 0x09, struct usdpaa_ioctl_irq_map)
148877 +
148878 +#ifdef CONFIG_COMPAT
148879 +
148880 +struct compat_ioctl_irq_map {
148881 + enum usdpaa_portal_type type; /* Type of portal to map */
148882 + compat_int_t fd; /* File descriptor that contains the portal */
148883 + compat_uptr_t portal_cinh; /* Used identify the portal */};
148884 +
148885 +#define USDPAA_IOCTL_PORTAL_IRQ_MAP_COMPAT \
148886 + _IOW(USDPAA_IOCTL_MAGIC, 0x09, struct compat_ioctl_irq_map)
148887 +#endif
148888 +
148889 +/* ioctl to query the amount of DMA memory used in the system */
148890 +struct usdpaa_ioctl_dma_used {
148891 + uint64_t free_bytes;
148892 + uint64_t total_bytes;
148893 +};
148894 +#define USDPAA_IOCTL_DMA_USED \
148895 + _IOR(USDPAA_IOCTL_MAGIC, 0x0B, struct usdpaa_ioctl_dma_used)
148896 +
148897 +/* ioctl to allocate a raw portal */
148898 +struct usdpaa_ioctl_raw_portal {
148899 + /* inputs */
148900 + enum usdpaa_portal_type type; /* Type of portal to allocate */
148901 +
148902 + /* set to non zero to turn on stashing */
148903 + uint8_t enable_stash;
148904 + /* Stashing attributes for the portal */
148905 + uint32_t cpu;
148906 + uint32_t cache;
148907 + uint32_t window;
148908 +
148909 + /* Specifies the stash request queue this portal should use */
148910 + uint8_t sdest;
148911 +
148912 + /* Specifes a specific portal index to map or QBMAN_ANY_PORTAL_IDX
148913 + * for don't care. The portal index will be populated by the
148914 + * driver when the ioctl() successfully completes */
148915 + uint32_t index;
148916 +
148917 + /* outputs */
148918 + uint64_t cinh;
148919 + uint64_t cena;
148920 +};
148921 +
148922 +#define USDPAA_IOCTL_ALLOC_RAW_PORTAL \
148923 + _IOWR(USDPAA_IOCTL_MAGIC, 0x0C, struct usdpaa_ioctl_raw_portal)
148924 +
148925 +#define USDPAA_IOCTL_FREE_RAW_PORTAL \
148926 + _IOR(USDPAA_IOCTL_MAGIC, 0x0D, struct usdpaa_ioctl_raw_portal)
148927 +
148928 +#ifdef CONFIG_COMPAT
148929 +
148930 +struct compat_ioctl_raw_portal {
148931 + /* inputs */
148932 + enum usdpaa_portal_type type; /* Type of portal to allocate */
148933 +
148934 + /* set to non zero to turn on stashing */
148935 + uint8_t enable_stash;
148936 + /* Stashing attributes for the portal */
148937 + uint32_t cpu;
148938 + uint32_t cache;
148939 + uint32_t window;
148940 + /* Specifies the stash request queue this portal should use */
148941 + uint8_t sdest;
148942 +
148943 + /* Specifes a specific portal index to map or QBMAN_ANY_PORTAL_IDX
148944 + * for don't care. The portal index will be populated by the
148945 + * driver when the ioctl() successfully completes */
148946 + uint32_t index;
148947 +
148948 + /* outputs */
148949 + uint64_t cinh;
148950 + uint64_t cena;
148951 +};
148952 +
148953 +#define USDPAA_IOCTL_ALLOC_RAW_PORTAL_COMPAT \
148954 + _IOWR(USDPAA_IOCTL_MAGIC, 0x0C, struct compat_ioctl_raw_portal)
148955 +
148956 +#define USDPAA_IOCTL_FREE_RAW_PORTAL_COMPAT \
148957 + _IOR(USDPAA_IOCTL_MAGIC, 0x0D, struct compat_ioctl_raw_portal)
148958 +
148959 +#endif
148960 +
148961 +#ifdef __KERNEL__
148962 +
148963 +/* Early-boot hook */
148964 +int __init fsl_usdpaa_init_early(void);
148965 +
148966 +/* Fault-handling in arch/powerpc/mm/mem.c gives USDPAA an opportunity to detect
148967 + * faults within its ranges via this hook. */
148968 +int usdpaa_test_fault(unsigned long pfn, u64 *phys_addr, u64 *size);
148969 +
148970 +#endif /* __KERNEL__ */
148971 +
148972 +#endif /* CONFIG_FSL_USDPAA */
148973 +
148974 +#ifdef __KERNEL__
148975 +/* This interface is needed in a few places and though it's not specific to
148976 + * USDPAA as such, creating a new header for it doesn't make any sense. The
148977 + * qbman kernel driver implements this interface and uses it as the backend for
148978 + * both the FQID and BPID allocators. The fsl_usdpaa driver also uses this
148979 + * interface for tracking per-process allocations handed out to user-space. */
148980 +struct dpa_alloc {
148981 + struct list_head free;
148982 + spinlock_t lock;
148983 + struct list_head used;
148984 +};
148985 +#define DECLARE_DPA_ALLOC(name) \
148986 + struct dpa_alloc name = { \
148987 + .free = { \
148988 + .prev = &name.free, \
148989 + .next = &name.free \
148990 + }, \
148991 + .lock = __SPIN_LOCK_UNLOCKED(name.lock), \
148992 + .used = { \
148993 + .prev = &name.used, \
148994 + .next = &name.used \
148995 + } \
148996 + }
148997 +static inline void dpa_alloc_init(struct dpa_alloc *alloc)
148998 +{
148999 + INIT_LIST_HEAD(&alloc->free);
149000 + INIT_LIST_HEAD(&alloc->used);
149001 + spin_lock_init(&alloc->lock);
149002 +}
149003 +int dpa_alloc_new(struct dpa_alloc *alloc, u32 *result, u32 count, u32 align,
149004 + int partial);
149005 +void dpa_alloc_free(struct dpa_alloc *alloc, u32 base_id, u32 count);
149006 +void dpa_alloc_seed(struct dpa_alloc *alloc, u32 fqid, u32 count);
149007 +
149008 +/* Like 'new' but specifies the desired range, returns -ENOMEM if the entire
149009 + * desired range is not available, or 0 for success. */
149010 +int dpa_alloc_reserve(struct dpa_alloc *alloc, u32 base_id, u32 count);
149011 +/* Pops and returns contiguous ranges from the allocator. Returns -ENOMEM when
149012 + * 'alloc' is empty. */
149013 +int dpa_alloc_pop(struct dpa_alloc *alloc, u32 *result, u32 *count);
149014 +/* Returns 1 if the specified id is alloced, 0 otherwise */
149015 +int dpa_alloc_check(struct dpa_alloc *list, u32 id);
149016 +#endif /* __KERNEL__ */
149017 +
149018 +#ifdef __cplusplus
149019 +}
149020 +#endif
149021 +
149022 +#endif /* FSL_USDPAA_H */
149023 --- /dev/null
149024 +++ b/include/uapi/linux/fmd/Kbuild
149025 @@ -0,0 +1,5 @@
149026 +header-y += integrations/
149027 +header-y += Peripherals/
149028 +
149029 +header-y += ioctls.h
149030 +header-y += net_ioctls.h
149031 --- /dev/null
149032 +++ b/include/uapi/linux/fmd/Peripherals/Kbuild
149033 @@ -0,0 +1,4 @@
149034 +header-y += fm_ioctls.h
149035 +header-y += fm_port_ioctls.h
149036 +header-y += fm_pcd_ioctls.h
149037 +header-y += fm_test_ioctls.h
149038 --- /dev/null
149039 +++ b/include/uapi/linux/fmd/Peripherals/fm_ioctls.h
149040 @@ -0,0 +1,628 @@
149041 +/* Copyright (c) 2008-2012 Freescale Semiconductor, Inc.
149042 + * All rights reserved.
149043 + *
149044 + * Redistribution and use in source and binary forms, with or without
149045 + * modification, are permitted provided that the following conditions are met:
149046 + * * Redistributions of source code must retain the above copyright
149047 + * notice, this list of conditions and the following disclaimer.
149048 + * * Redistributions in binary form must reproduce the above copyright
149049 + * notice, this list of conditions and the following disclaimer in the
149050 + * documentation and/or other materials provided with the distribution.
149051 + * * Neither the name of Freescale Semiconductor nor the
149052 + * names of its contributors may be used to endorse or promote products
149053 + * derived from this software without specific prior written permission.
149054 + *
149055 + *
149056 + * ALTERNATIVELY, this software may be distributed under the terms of the
149057 + * GNU General Public License ("GPL") as published by the Free Software
149058 + * Foundation, either version 2 of that License or (at your option) any
149059 + * later version.
149060 + *
149061 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
149062 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
149063 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
149064 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
149065 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
149066 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
149067 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
149068 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
149069 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
149070 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
149071 + */
149072 +
149073 +/**************************************************************************//**
149074 + @File fm_ioctls.h
149075 +
149076 + @Description FM Char device ioctls
149077 +*//***************************************************************************/
149078 +#ifndef __FM_IOCTLS_H
149079 +#define __FM_IOCTLS_H
149080 +
149081 +
149082 +/**************************************************************************//**
149083 + @Group lnx_ioctl_FM_grp Frame Manager Linux IOCTL API
149084 +
149085 + @Description FM Linux ioctls definitions and enums
149086 +
149087 + @{
149088 +*//***************************************************************************/
149089 +
149090 +/**************************************************************************//**
149091 + @Collection FM IOCTL device ('/dev') definitions
149092 +*//***************************************************************************/
149093 +#define DEV_FM_NAME "fm" /**< Name of the FM chardev */
149094 +
149095 +#define DEV_FM_MINOR_BASE 0
149096 +#define DEV_FM_PCD_MINOR_BASE (DEV_FM_MINOR_BASE + 1) /*/dev/fmx-pcd */
149097 +#define DEV_FM_OH_PORTS_MINOR_BASE (DEV_FM_PCD_MINOR_BASE + 1) /*/dev/fmx-port-ohy */
149098 +#define DEV_FM_RX_PORTS_MINOR_BASE (DEV_FM_OH_PORTS_MINOR_BASE + FM_MAX_NUM_OF_OH_PORTS) /*/dev/fmx-port-rxy */
149099 +#define DEV_FM_TX_PORTS_MINOR_BASE (DEV_FM_RX_PORTS_MINOR_BASE + FM_MAX_NUM_OF_RX_PORTS) /*/dev/fmx-port-txy */
149100 +#define DEV_FM_MAX_MINORS (DEV_FM_TX_PORTS_MINOR_BASE + FM_MAX_NUM_OF_TX_PORTS)
149101 +
149102 +#define FM_IOC_NUM(n) (n)
149103 +#define FM_PCD_IOC_NUM(n) (n+20)
149104 +#define FM_PORT_IOC_NUM(n) (n+70)
149105 +/* @} */
149106 +
149107 +#define IOC_FM_MAX_NUM_OF_PORTS 64
149108 +
149109 +
149110 +/**************************************************************************//**
149111 + @Description Enum for defining port types
149112 + (must match enum e_FmPortType defined in fm_ext.h)
149113 +*//***************************************************************************/
149114 +typedef enum ioc_fm_port_type {
149115 + e_IOC_FM_PORT_TYPE_OH_OFFLINE_PARSING = 0, /**< Offline parsing port */
149116 + e_IOC_FM_PORT_TYPE_RX, /**< 1G Rx port */
149117 + e_IOC_FM_PORT_TYPE_RX_10G, /**< 10G Rx port */
149118 + e_IOC_FM_PORT_TYPE_TX, /**< 1G Tx port */
149119 + e_IOC_FM_PORT_TYPE_TX_10G, /**< 10G Tx port */
149120 + e_IOC_FM_PORT_TYPE_DUMMY
149121 +} ioc_fm_port_type;
149122 +
149123 +
149124 +/**************************************************************************//**
149125 + @Group lnx_ioctl_FM_lib_grp FM library
149126 +
149127 + @Description FM API functions, definitions and enums
149128 + The FM module is the main driver module and is a mandatory module
149129 + for FM driver users. Before any further module initialization,
149130 + this module must be initialized.
149131 + The FM is a "single-tone" module. It is responsible of the common
149132 + HW modules: FPM, DMA, common QMI, common BMI initializations and
149133 + run-time control routines. This module must be initialized always
149134 + when working with any of the FM modules.
149135 + NOTE - We assumes that the FML will be initialize only by core No. 0!
149136 +
149137 + @{
149138 +*//***************************************************************************/
149139 +
149140 +/**************************************************************************//**
149141 + @Description FM Exceptions
149142 +*//***************************************************************************/
149143 +typedef enum ioc_fm_exceptions {
149144 + e_IOC_FM_EX_DMA_BUS_ERROR, /**< DMA bus error. */
149145 + e_IOC_EX_DMA_READ_ECC, /**< Read Buffer ECC error (Valid for FM rev < 6)*/
149146 + e_IOC_EX_DMA_SYSTEM_WRITE_ECC, /**< Write Buffer ECC error on system side (Valid for FM rev < 6)*/
149147 + e_IOC_EX_DMA_FM_WRITE_ECC, /**< Write Buffer ECC error on FM side (Valid for FM rev < 6)*/
149148 + e_IOC_EX_DMA_SINGLE_PORT_ECC, /**< Single Port ECC error on FM side (Valid for FM rev > 6)*/
149149 + e_IOC_EX_FPM_STALL_ON_TASKS, /**< Stall of tasks on FPM */
149150 + e_IOC_EX_FPM_SINGLE_ECC, /**< Single ECC on FPM. */
149151 + e_IOC_EX_FPM_DOUBLE_ECC, /**< Double ECC error on FPM ram access */
149152 + e_IOC_EX_QMI_SINGLE_ECC, /**< Single ECC on QMI. */
149153 + e_IOC_EX_QMI_DOUBLE_ECC, /**< Double bit ECC occurred on QMI */
149154 + e_IOC_EX_QMI_DEQ_FROM_UNKNOWN_PORTID,/**< Dequeue from unknown port id */
149155 + e_IOC_EX_BMI_LIST_RAM_ECC, /**< Linked List RAM ECC error */
149156 + e_IOC_EX_BMI_STORAGE_PROFILE_ECC, /**< Storage Profile ECC Error */
149157 + e_IOC_EX_BMI_STATISTICS_RAM_ECC, /**< Statistics Count RAM ECC Error Enable */
149158 + e_IOC_EX_BMI_DISPATCH_RAM_ECC, /**< Dispatch RAM ECC Error Enable */
149159 + e_IOC_EX_IRAM_ECC, /**< Double bit ECC occurred on IRAM*/
149160 + e_IOC_EX_MURAM_ECC /**< Double bit ECC occurred on MURAM*/
149161 +} ioc_fm_exceptions;
149162 +
149163 +/**************************************************************************//**
149164 + @Group lnx_ioctl_FM_runtime_control_grp FM Runtime Control Unit
149165 +
149166 + @Description FM Runtime control unit API functions, definitions and enums.
149167 + The FM driver provides a set of control routines for each module.
149168 + These routines may only be called after the module was fully
149169 + initialized (both configuration and initialization routines were
149170 + called). They are typically used to get information from hardware
149171 + (status, counters/statistics, revision etc.), to modify a current
149172 + state or to force/enable a required action. Run-time control may
149173 + be called whenever necessary and as many times as needed.
149174 + @{
149175 +*//***************************************************************************/
149176 +
149177 +/**************************************************************************//**
149178 + @Collection General FM defines.
149179 + *//***************************************************************************/
149180 +#define IOC_FM_MAX_NUM_OF_VALID_PORTS (FM_MAX_NUM_OF_OH_PORTS + \
149181 + FM_MAX_NUM_OF_1G_RX_PORTS + \
149182 + FM_MAX_NUM_OF_10G_RX_PORTS + \
149183 + FM_MAX_NUM_OF_1G_TX_PORTS + \
149184 + FM_MAX_NUM_OF_10G_TX_PORTS)
149185 +/* @} */
149186 +
149187 +/**************************************************************************//**
149188 + @Description Structure for Port bandwidth requirement. Port is identified
149189 + by type and relative id.
149190 + (must be identical to t_FmPortBandwidth defined in fm_ext.h)
149191 +*//***************************************************************************/
149192 +typedef struct ioc_fm_port_bandwidth_t {
149193 + ioc_fm_port_type type; /**< FM port type */
149194 + uint8_t relative_port_id; /**< Type relative port id */
149195 + uint8_t bandwidth; /**< bandwidth - (in term of percents) */
149196 +} ioc_fm_port_bandwidth_t;
149197 +
149198 +/**************************************************************************//**
149199 + @Description A Structure containing an array of Port bandwidth requirements.
149200 + The user should state the ports requiring bandwidth in terms of
149201 + percentage - i.e. all port's bandwidths in the array must add
149202 + up to 100.
149203 + (must be identical to t_FmPortsBandwidthParams defined in fm_ext.h)
149204 +*//***************************************************************************/
149205 +typedef struct ioc_fm_port_bandwidth_params {
149206 + uint8_t num_of_ports;
149207 + /**< num of ports listed in the array below */
149208 + ioc_fm_port_bandwidth_t ports_bandwidths[IOC_FM_MAX_NUM_OF_VALID_PORTS];
149209 + /**< for each port, it's bandwidth (all port's
149210 + bandwidths must add up to 100.*/
149211 +} ioc_fm_port_bandwidth_params;
149212 +
149213 +/**************************************************************************//**
149214 + @Description enum for defining FM counters
149215 +*//***************************************************************************/
149216 +typedef enum ioc_fm_counters {
149217 + e_IOC_FM_COUNTERS_ENQ_TOTAL_FRAME, /**< QMI total enqueued frames counter */
149218 + e_IOC_FM_COUNTERS_DEQ_TOTAL_FRAME, /**< QMI total dequeued frames counter */
149219 + e_IOC_FM_COUNTERS_DEQ_0, /**< QMI 0 frames from QMan counter */
149220 + e_IOC_FM_COUNTERS_DEQ_1, /**< QMI 1 frames from QMan counter */
149221 + e_IOC_FM_COUNTERS_DEQ_2, /**< QMI 2 frames from QMan counter */
149222 + e_IOC_FM_COUNTERS_DEQ_3, /**< QMI 3 frames from QMan counter */
149223 + e_IOC_FM_COUNTERS_DEQ_FROM_DEFAULT, /**< QMI dequeue from default queue counter */
149224 + e_IOC_FM_COUNTERS_DEQ_FROM_CONTEXT, /**< QMI dequeue from FQ context counter */
149225 + e_IOC_FM_COUNTERS_DEQ_FROM_FD, /**< QMI dequeue from FD command field counter */
149226 + e_IOC_FM_COUNTERS_DEQ_CONFIRM, /**< QMI dequeue confirm counter */
149227 +} ioc_fm_counters;
149228 +
149229 +typedef struct ioc_fm_obj_t {
149230 + void *obj;
149231 +} ioc_fm_obj_t;
149232 +
149233 +/**************************************************************************//**
149234 + @Description A structure for returning revision information
149235 + (must match struct t_FmRevisionInfo declared in fm_ext.h)
149236 +*//***************************************************************************/
149237 +typedef struct ioc_fm_revision_info_t {
149238 + uint8_t major; /**< Major revision */
149239 + uint8_t minor; /**< Minor revision */
149240 +} ioc_fm_revision_info_t;
149241 +
149242 +/**************************************************************************//**
149243 + @Description A structure for FM counters
149244 +*//***************************************************************************/
149245 +typedef struct ioc_fm_counters_params_t {
149246 + ioc_fm_counters cnt; /**< The requested counter */
149247 + uint32_t val; /**< The requested value to get/set from/into the counter */
149248 +} ioc_fm_counters_params_t;
149249 +
149250 +typedef union ioc_fm_api_version_t {
149251 + struct {
149252 + uint8_t major;
149253 + uint8_t minor;
149254 + uint8_t respin;
149255 + uint8_t reserved;
149256 + } version;
149257 + uint32_t ver;
149258 +} ioc_fm_api_version_t;
149259 +
149260 +#if (DPAA_VERSION >= 11)
149261 +/**************************************************************************//**
149262 + @Description A structure of information about each of the external
149263 + buffer pools used by a port or storage-profile.
149264 + (must be identical to t_FmExtPoolParams defined in fm_ext.h)
149265 +*//***************************************************************************/
149266 +typedef struct ioc_fm_ext_pool_params {
149267 + uint8_t id; /**< External buffer pool id */
149268 + uint16_t size; /**< External buffer pool buffer size */
149269 +} ioc_fm_ext_pool_params;
149270 +
149271 +/**************************************************************************//**
149272 + @Description A structure for informing the driver about the external
149273 + buffer pools allocated in the BM and used by a port or a
149274 + storage-profile.
149275 + (must be identical to t_FmExtPools defined in fm_ext.h)
149276 +*//***************************************************************************/
149277 +typedef struct ioc_fm_ext_pools {
149278 + uint8_t num_of_pools_used; /**< Number of pools use by this port */
149279 + ioc_fm_ext_pool_params ext_buf_pool[FM_PORT_MAX_NUM_OF_EXT_POOLS];
149280 + /**< Parameters for each port */
149281 +} ioc_fm_ext_pools;
149282 +
149283 +typedef struct ioc_fm_vsp_params_t {
149284 + void *p_fm; /**< A handle to the FM object this VSP related to */
149285 + ioc_fm_ext_pools ext_buf_pools; /**< Which external buffer pools are used
149286 + (up to FM_PORT_MAX_NUM_OF_EXT_POOLS), and their sizes.
149287 + parameter associated with Rx / OP port */
149288 + uint16_t liodn_offset; /**< VSP's LIODN offset */
149289 + struct {
149290 + ioc_fm_port_type port_type; /**< Port type */
149291 + uint8_t port_id; /**< Port Id - relative to type */
149292 + } port_params;
149293 + uint8_t relative_profile_id; /**< VSP Id - relative to VSP's range
149294 + defined in relevant FM object */
149295 + void *id; /**< return value */
149296 +} ioc_fm_vsp_params_t;
149297 +#endif /* (DPAA_VERSION >= 11) */
149298 +
149299 +/**************************************************************************//**
149300 + @Description A structure for defining BM pool depletion criteria
149301 +*//***************************************************************************/
149302 +typedef struct ioc_fm_buf_pool_depletion_t {
149303 + bool pools_grp_mode_enable; /**< select mode in which pause frames will be sent after
149304 + a number of pools (all together!) are depleted */
149305 + uint8_t num_of_pools; /**< the number of depleted pools that will invoke
149306 + pause frames transmission. */
149307 + bool pools_to_consider[BM_MAX_NUM_OF_POOLS];
149308 + /**< For each pool, TRUE if it should be considered for
149309 + depletion (Note - this pool must be used by this port!). */
149310 + bool single_pool_mode_enable; /**< select mode in which pause frames will be sent after
149311 + a single-pool is depleted; */
149312 + bool pools_to_consider_for_single_mode[BM_MAX_NUM_OF_POOLS];
149313 + /**< For each pool, TRUE if it should be considered for
149314 + depletion (Note - this pool must be used by this port!) */
149315 +#if (DPAA_VERSION >= 11)
149316 + bool pfc_priorities_en[FM_MAX_NUM_OF_PFC_PRIORITIES];
149317 + /**< This field is used by the MAC as the Priority Enable Vector in the PFC frame
149318 + which is transmitted */
149319 +#endif /* (DPAA_VERSION >= 11) */
149320 +} ioc_fm_buf_pool_depletion_t;
149321 +
149322 +#if (DPAA_VERSION >= 11)
149323 +typedef struct ioc_fm_buf_pool_depletion_params_t {
149324 + void *p_fm_vsp;
149325 + ioc_fm_buf_pool_depletion_t fm_buf_pool_depletion;
149326 +} ioc_fm_buf_pool_depletion_params_t;
149327 +#endif /* (DPAA_VERSION >= 11) */
149328 +
149329 +typedef struct ioc_fm_buffer_prefix_content_t {
149330 + uint16_t priv_data_size; /**< Number of bytes to be left at the beginning
149331 + of the external buffer; Note that the private-area will
149332 + start from the base of the buffer address. */
149333 + bool pass_prs_result; /**< TRUE to pass the parse result to/from the FM;
149334 + User may use FM_PORT_GetBufferPrsResult() in order to
149335 + get the parser-result from a buffer. */
149336 + bool pass_time_stamp; /**< TRUE to pass the timeStamp to/from the FM
149337 + User may use FM_PORT_GetBufferTimeStamp() in order to
149338 + get the parser-result from a buffer. */
149339 + bool pass_hash_result; /**< TRUE to pass the KG hash result to/from the FM
149340 + User may use FM_PORT_GetBufferHashResult() in order to
149341 + get the parser-result from a buffer. */
149342 + bool pass_all_other_pcd_info; /**< Add all other Internal-Context information:
149343 + AD, hash-result, key, etc. */
149344 + uint16_t data_align; /**< 0 to use driver's default alignment [64],
149345 + other value for selecting a data alignment (must be a power of 2);
149346 + if write optimization is used, must be >= 16. */
149347 + uint8_t manip_extra_space; /**< Maximum extra size needed (insertion-size minus removal-size);
149348 + Note that this field impacts the size of the buffer-prefix
149349 + (i.e. it pushes the data offset);
149350 + This field is irrelevant if DPAA_VERSION==10 */
149351 +} ioc_fm_buffer_prefix_content_t;
149352 +
149353 +typedef struct ioc_fm_buffer_prefix_content_params_t {
149354 + void *p_fm_vsp;
149355 + ioc_fm_buffer_prefix_content_t fm_buffer_prefix_content;
149356 +} ioc_fm_buffer_prefix_content_params_t;
149357 +
149358 +#if (DPAA_VERSION >= 11)
149359 +typedef struct ioc_fm_vsp_config_no_sg_params_t {
149360 + void *p_fm_vsp;
149361 + bool no_sg;
149362 +} ioc_fm_vsp_config_no_sg_params_t;
149363 +
149364 +typedef struct ioc_fm_vsp_prs_result_params_t {
149365 + void *p_fm_vsp;
149366 + void *p_data;
149367 +} ioc_fm_vsp_prs_result_params_t;
149368 +#endif
149369 +
149370 +typedef struct fm_ctrl_mon_t {
149371 + uint8_t percent_cnt[2];
149372 +} fm_ctrl_mon_t;
149373 +
149374 +typedef struct ioc_fm_ctrl_mon_counters_params_t {
149375 + uint8_t fm_ctrl_index;
149376 + fm_ctrl_mon_t *p_mon;
149377 +} ioc_fm_ctrl_mon_counters_params_t;
149378 +
149379 +/**************************************************************************//**
149380 + @Function FM_IOC_SET_PORTS_BANDWIDTH
149381 +
149382 + @Description Sets relative weights between ports when accessing common resources.
149383 +
149384 + @Param[in] ioc_fm_port_bandwidth_params Port bandwidth percentages,
149385 + their sum must equal 100.
149386 +
149387 + @Return E_OK on success; Error code otherwise.
149388 +
149389 + @Cautions Allowed only following FM_Init().
149390 +*//***************************************************************************/
149391 +#define FM_IOC_SET_PORTS_BANDWIDTH _IOW(FM_IOC_TYPE_BASE, FM_IOC_NUM(2), ioc_fm_port_bandwidth_params)
149392 +
149393 +/**************************************************************************//**
149394 + @Function FM_IOC_GET_REVISION
149395 +
149396 + @Description Returns the FM revision
149397 +
149398 + @Param[out] ioc_fm_revision_info_t A structure of revision information parameters.
149399 +
149400 + @Return None.
149401 +
149402 + @Cautions Allowed only following FM_Init().
149403 +*//***************************************************************************/
149404 +#define FM_IOC_GET_REVISION _IOR(FM_IOC_TYPE_BASE, FM_IOC_NUM(3), ioc_fm_revision_info_t)
149405 +
149406 +/**************************************************************************//**
149407 + @Function FM_IOC_GET_COUNTER
149408 +
149409 + @Description Reads one of the FM counters.
149410 +
149411 + @Param[in,out] ioc_fm_counters_params_t The requested counter parameters.
149412 +
149413 + @Return Counter's current value.
149414 +
149415 + @Cautions Allowed only following FM_Init().
149416 + Note that it is user's responsibilty to call this routine only
149417 + for enabled counters, and there will be no indication if a
149418 + disabled counter is accessed.
149419 +*//***************************************************************************/
149420 +#define FM_IOC_GET_COUNTER _IOWR(FM_IOC_TYPE_BASE, FM_IOC_NUM(4), ioc_fm_counters_params_t)
149421 +
149422 +/**************************************************************************//**
149423 + @Function FM_IOC_SET_COUNTER
149424 +
149425 + @Description Sets a value to an enabled counter. Use "0" to reset the counter.
149426 +
149427 + @Param[in] ioc_fm_counters_params_t The requested counter parameters.
149428 +
149429 + @Return E_OK on success; Error code otherwise.
149430 +
149431 + @Cautions Allowed only following FM_Init().
149432 +*//***************************************************************************/
149433 +#define FM_IOC_SET_COUNTER _IOW(FM_IOC_TYPE_BASE, FM_IOC_NUM(5), ioc_fm_counters_params_t)
149434 +
149435 +/**************************************************************************//**
149436 + @Function FM_IOC_FORCE_INTR
149437 +
149438 + @Description Causes an interrupt event on the requested source.
149439 +
149440 + @Param[in] ioc_fm_exceptions An exception to be forced.
149441 +
149442 + @Return E_OK on success; Error code if the exception is not enabled,
149443 + or is not able to create interrupt.
149444 +
149445 + @Cautions Allowed only following FM_Init().
149446 +*//***************************************************************************/
149447 +#define FM_IOC_FORCE_INTR _IOW(FM_IOC_TYPE_BASE, FM_IOC_NUM(6), ioc_fm_exceptions)
149448 +
149449 +/**************************************************************************//**
149450 + @Function FM_IOC_GET_API_VERSION
149451 +
149452 + @Description Reads the FMD IOCTL API version.
149453 +
149454 + @Param[in,out] ioc_fm_api_version_t The requested counter parameters.
149455 +
149456 + @Return Version's value.
149457 +*//***************************************************************************/
149458 +#define FM_IOC_GET_API_VERSION _IOR(FM_IOC_TYPE_BASE, FM_IOC_NUM(7), ioc_fm_api_version_t)
149459 +
149460 +#if (DPAA_VERSION >= 11)
149461 +/**************************************************************************//**
149462 + @Function FM_VSP_Config
149463 +
149464 + @Description Creates descriptor for the FM VSP module.
149465 +
149466 + The routine returns a handle (descriptor) to the FM VSP object.
149467 + This descriptor must be passed as first parameter to all other
149468 + FM VSP function calls.
149469 +
149470 + No actual initialization or configuration of FM hardware is
149471 + done by this routine.
149472 +
149473 +@Param[in] p_FmVspParams Pointer to data structure of parameters
149474 +
149475 + @Retval Handle to FM VSP object, or NULL for Failure.
149476 +*//***************************************************************************/
149477 +#if defined(CONFIG_COMPAT)
149478 +#define FM_IOC_VSP_CONFIG_COMPAT _IOWR(FM_IOC_TYPE_BASE, FM_IOC_NUM(8), ioc_compat_fm_vsp_params_t)
149479 +#endif
149480 +#define FM_IOC_VSP_CONFIG _IOWR(FM_IOC_TYPE_BASE, FM_IOC_NUM(8), ioc_fm_vsp_params_t)
149481 +
149482 +/**************************************************************************//**
149483 + @Function FM_VSP_Init
149484 +
149485 + @Description Initializes the FM VSP module
149486 +
149487 + @Param[in] h_FmVsp - FM VSP module descriptor
149488 +
149489 + @Return E_OK on success; Error code otherwise.
149490 +*//***************************************************************************/
149491 +#if defined(CONFIG_COMPAT)
149492 +#define FM_IOC_VSP_INIT_COMPAT _IOW(FM_IOC_TYPE_BASE, FM_IOC_NUM(9), ioc_compat_fm_obj_t)
149493 +#endif
149494 +#define FM_IOC_VSP_INIT _IOW(FM_IOC_TYPE_BASE, FM_IOC_NUM(9), ioc_fm_obj_t)
149495 +
149496 +/**************************************************************************//**
149497 + @Function FM_VSP_Free
149498 +
149499 + @Description Frees all resources that were assigned to FM VSP module.
149500 +
149501 + Calling this routine invalidates the descriptor.
149502 +
149503 + @Param[in] h_FmVsp - FM VSP module descriptor
149504 +
149505 + @Return E_OK on success; Error code otherwise.
149506 +*//***************************************************************************/
149507 +#if defined(CONFIG_COMPAT)
149508 +#define FM_IOC_VSP_FREE_COMPAT _IOW(FM_IOC_TYPE_BASE, FM_IOC_NUM(10), ioc_compat_fm_obj_t)
149509 +#endif
149510 +#define FM_IOC_VSP_FREE _IOW(FM_IOC_TYPE_BASE, FM_IOC_NUM(10), ioc_fm_obj_t)
149511 +
149512 +/**************************************************************************//**
149513 + @Function FM_VSP_ConfigPoolDepletion
149514 +
149515 + @Description Calling this routine enables pause frame generation depending on the
149516 + depletion status of BM pools. It also defines the conditions to activate
149517 + this functionality. By default, this functionality is disabled.
149518 +
149519 + @Param[in] ioc_fm_buf_pool_depletion_params_t A structure holding the required parameters.
149520 +
149521 + @Return E_OK on success; Error code otherwise.
149522 +
149523 + @Cautions Allowed only following FM_VSP_Config() and before FM_VSP_Init().
149524 +*//***************************************************************************/
149525 +#if defined(CONFIG_COMPAT)
149526 +#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)
149527 +#endif
149528 +#define FM_IOC_VSP_CONFIG_POOL_DEPLETION _IOW(FM_IOC_TYPE_BASE, FM_IOC_NUM(11), ioc_fm_buf_pool_depletion_params_t)
149529 +
149530 +/**************************************************************************//**
149531 + @Function FM_VSP_ConfigBufferPrefixContent
149532 +
149533 + @Description Defines the structure, size and content of the application buffer.
149534 +
149535 + The prefix will
149536 + In VSPs defined for Tx ports, if 'passPrsResult', the application
149537 + should set a value to their offsets in the prefix of
149538 + the FM will save the first 'privDataSize', than,
149539 + depending on 'passPrsResult' and 'passTimeStamp', copy parse result
149540 + and timeStamp, and the packet itself (in this order), to the
149541 + application buffer, and to offset.
149542 +
149543 + Calling this routine changes the buffer margins definitions
149544 + in the internal driver data base from its default
149545 + configuration: Data size: [DEFAULT_FM_SP_bufferPrefixContent_privDataSize]
149546 + Pass Parser result: [DEFAULT_FM_SP_bufferPrefixContent_passPrsResult].
149547 + Pass timestamp: [DEFAULT_FM_SP_bufferPrefixContent_passTimeStamp].
149548 +
149549 + @Param[in] ioc_fm_buffer_prefix_content_params_t A structure holding the required parameters.
149550 +
149551 + @Return E_OK on success; Error code otherwise.
149552 +
149553 + @Cautions Allowed only following FM_VSP_Config() and before FM_VSP_Init().
149554 +*//***************************************************************************/
149555 +#if defined(CONFIG_COMPAT)
149556 +#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)
149557 +#endif
149558 +#define FM_IOC_VSP_CONFIG_BUFFER_PREFIX_CONTENT _IOW(FM_IOC_TYPE_BASE, FM_IOC_NUM(12), ioc_fm_buffer_prefix_content_params_t)
149559 +
149560 +/**************************************************************************//**
149561 + @Function FM_VSP_ConfigNoScatherGather
149562 +
149563 + @Description Calling this routine changes the possibility to receive S/G frame
149564 + in the internal driver data base
149565 + from its default configuration: optimize = [DEFAULT_FM_SP_noScatherGather]
149566 +
149567 + @Param[in] ioc_fm_vsp_config_no_sg_params_t A structure holding the required parameters.
149568 +
149569 + @Return E_OK on success; Error code otherwise.
149570 +
149571 + @Cautions Allowed only following FM_VSP_Config() and before FM_VSP_Init().
149572 +*//***************************************************************************/
149573 +#if defined(CONFIG_COMPAT)
149574 +#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)
149575 +#endif
149576 +#define FM_IOC_VSP_CONFIG_NO_SG _IOW(FM_IOC_TYPE_BASE, FM_IOC_NUM(13), ioc_fm_vsp_config_no_sg_params_t)
149577 +
149578 +/**************************************************************************//**
149579 + @Function FM_VSP_GetBufferPrsResult
149580 +
149581 + @Description Returns the pointer to the parse result in the data buffer.
149582 + In Rx ports this is relevant after reception, if parse
149583 + result is configured to be part of the data passed to the
149584 + application. For non Rx ports it may be used to get the pointer
149585 + of the area in the buffer where parse result should be
149586 + initialized - if so configured.
149587 + See FM_VSP_ConfigBufferPrefixContent for data buffer prefix
149588 + configuration.
149589 +
149590 + @Param[in] ioc_fm_vsp_prs_result_params_t A structure holding the required parameters.
149591 +
149592 + @Return Parse result pointer on success, NULL if parse result was not
149593 + configured for this port.
149594 +
149595 + @Cautions Allowed only following FM_VSP_Init().
149596 +*//***************************************************************************/
149597 +#if defined(CONFIG_COMPAT)
149598 +#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)
149599 +#endif
149600 +#define FM_IOC_VSP_GET_BUFFER_PRS_RESULT _IOWR(FM_IOC_TYPE_BASE, FM_IOC_NUM(14), ioc_fm_vsp_prs_result_params_t)
149601 +#endif /* (DPAA_VERSION >= 11) */
149602 +
149603 +/**************************************************************************//**
149604 + @Function FM_CtrlMonStart
149605 +
149606 + @Description Start monitoring utilization of all available FM controllers.
149607 +
149608 + In order to obtain FM controllers utilization the following sequence
149609 + should be used:
149610 + -# FM_CtrlMonStart()
149611 + -# FM_CtrlMonStop()
149612 + -# FM_CtrlMonGetCounters() - issued for each FM controller
149613 +
149614 + @Return E_OK on success; Error code otherwise.
149615 +
149616 + @Cautions Allowed only following FM_Init().
149617 +*//***************************************************************************/
149618 +#define FM_IOC_CTRL_MON_START _IO(FM_IOC_TYPE_BASE, FM_IOC_NUM(15))
149619 +
149620 +
149621 +/**************************************************************************//**
149622 + @Function FM_CtrlMonStop
149623 +
149624 + @Description Stop monitoring utilization of all available FM controllers.
149625 +
149626 + In order to obtain FM controllers utilization the following sequence
149627 + should be used:
149628 + -# FM_CtrlMonStart()
149629 + -# FM_CtrlMonStop()
149630 + -# FM_CtrlMonGetCounters() - issued for each FM controller
149631 +
149632 + @Return E_OK on success; Error code otherwise.
149633 +
149634 + @Cautions Allowed only following FM_Init().
149635 +*//***************************************************************************/
149636 +#define FM_IOC_CTRL_MON_STOP _IO(FM_IOC_TYPE_BASE, FM_IOC_NUM(16))
149637 +
149638 +/**************************************************************************//**
149639 + @Function FM_CtrlMonGetCounters
149640 +
149641 + @Description Obtain FM controller utilization parameters.
149642 +
149643 + In order to obtain FM controllers utilization the following sequence
149644 + should be used:
149645 + -# FM_CtrlMonStart()
149646 + -# FM_CtrlMonStop()
149647 + -# FM_CtrlMonGetCounters() - issued for each FM controller
149648 +
149649 + @Param[in] ioc_fm_ctrl_mon_counters_params_t A structure holding the required parameters.
149650 +
149651 + @Return E_OK on success; Error code otherwise.
149652 +
149653 + @Cautions Allowed only following FM_Init().
149654 +*//***************************************************************************/
149655 +#if defined(CONFIG_COMPAT)
149656 +#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)
149657 +#endif
149658 +#define FM_IOC_CTRL_MON_GET_COUNTERS _IOW(FM_IOC_TYPE_BASE, FM_IOC_NUM(17), ioc_fm_ctrl_mon_counters_params_t)
149659 +
149660 +/** @} */ /* end of lnx_ioctl_FM_runtime_control_grp group */
149661 +/** @} */ /* end of lnx_ioctl_FM_lib_grp group */
149662 +/** @} */ /* end of lnx_ioctl_FM_grp */
149663 +
149664 +#define FMD_API_VERSION_MAJOR 21
149665 +#define FMD_API_VERSION_MINOR 1
149666 +#define FMD_API_VERSION_RESPIN 0
149667 +
149668 +#endif /* __FM_IOCTLS_H */
149669 --- /dev/null
149670 +++ b/include/uapi/linux/fmd/Peripherals/fm_pcd_ioctls.h
149671 @@ -0,0 +1,3084 @@
149672 +/* Copyright (c) 2008-2012 Freescale Semiconductor, Inc.
149673 + * All rights reserved.
149674 + *
149675 + * Redistribution and use in source and binary forms, with or without
149676 + * modification, are permitted provided that the following conditions are met:
149677 + * * Redistributions of source code must retain the above copyright
149678 + * notice, this list of conditions and the following disclaimer.
149679 + * * Redistributions in binary form must reproduce the above copyright
149680 + * notice, this list of conditions and the following disclaimer in the
149681 + * documentation and/or other materials provided with the distribution.
149682 + * * Neither the name of Freescale Semiconductor nor the
149683 + * names of its contributors may be used to endorse or promote products
149684 + * derived from this software without specific prior written permission.
149685 + *
149686 + *
149687 + * ALTERNATIVELY, this software may be distributed under the terms of the
149688 + * GNU General Public License ("GPL") as published by the Free Software
149689 + * Foundation, either version 2 of that License or (at your option) any
149690 + * later version.
149691 + *
149692 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
149693 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
149694 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
149695 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
149696 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
149697 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
149698 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
149699 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
149700 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
149701 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
149702 + */
149703 +
149704 +
149705 +/******************************************************************************
149706 + @File fm_pcd_ioctls.h
149707 +
149708 + @Description FM PCD ...
149709 +*//***************************************************************************/
149710 +#ifndef __FM_PCD_IOCTLS_H
149711 +#define __FM_PCD_IOCTLS_H
149712 +
149713 +#include "net_ioctls.h"
149714 +#include "fm_ioctls.h"
149715 +
149716 +
149717 +/**************************************************************************//**
149718 +
149719 + @Group lnx_ioctl_FM_grp Frame Manager Linux IOCTL API
149720 +
149721 + @Description Frame Manager Linux ioctls definitions and enums
149722 +
149723 + @{
149724 +*//***************************************************************************/
149725 +
149726 +/**************************************************************************//**
149727 + @Group lnx_ioctl_FM_PCD_grp FM PCD
149728 +
149729 + @Description Frame Manager PCD API functions, definitions and enums
149730 +
149731 + The FM PCD module is responsible for the initialization of all
149732 + global classifying FM modules. This includes the parser general and
149733 + common registers, the key generator global and common registers,
149734 + and the policer global and common registers.
149735 + In addition, the FM PCD SW module will initialize all required
149736 + key generator schemes, coarse classification flows, and policer
149737 + profiles. When an FM module is configured to work with one of these
149738 + entities, it will register to it using the FM PORT API. The PCD
149739 + module will manage the PCD resources - i.e. resource management of
149740 + KeyGen schemes, etc.
149741 +
149742 + @{
149743 +*//***************************************************************************/
149744 +
149745 +/**************************************************************************//**
149746 + @Collection General PCD defines
149747 +*//***************************************************************************/
149748 +#define IOC_FM_PCD_MAX_NUM_OF_PRIVATE_HDRS 2 /**< Number of units/headers saved for user */
149749 +
149750 +#define IOC_FM_PCD_PRS_NUM_OF_HDRS 16 /**< Number of headers supported by HW parser */
149751 +#define IOC_FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS (32 - IOC_FM_PCD_MAX_NUM_OF_PRIVATE_HDRS)
149752 + /**< Number of distinction units is limited by
149753 + register size (32 bits) minus reserved bits
149754 + for private headers. */
149755 +#define IOC_FM_PCD_MAX_NUM_OF_INTERCHANGEABLE_HDRS 4 /**< Maximum number of interchangeable headers
149756 + in a distinction unit */
149757 +#define IOC_FM_PCD_KG_NUM_OF_GENERIC_REGS 8 /**< Total number of generic KeyGen registers */
149758 +#define IOC_FM_PCD_KG_MAX_NUM_OF_EXTRACTS_PER_KEY 35 /**< Max number allowed on any configuration;
149759 + For HW implementation reasons, in most
149760 + cases less than this will be allowed; The
149761 + driver will return an initialization error
149762 + if resource is unavailable. */
149763 +#define IOC_FM_PCD_KG_NUM_OF_EXTRACT_MASKS 4 /**< Total number of masks allowed on KeyGen extractions. */
149764 +#define IOC_FM_PCD_KG_NUM_OF_DEFAULT_GROUPS 16 /**< Number of default value logical groups */
149765 +
149766 +#define IOC_FM_PCD_PRS_NUM_OF_LABELS 32 /**< Maximum number of SW parser labels */
149767 +#define IOC_FM_PCD_SW_PRS_SIZE 0x00000800 /**< Total size of SW parser area */
149768 +
149769 +#define IOC_FM_PCD_MAX_MANIP_INSRT_TEMPLATE_SIZE 128 /**< Maximum size of insertion template for
149770 + insert manipulation */
149771 +
149772 +#if DPAA_VERSION >= 11
149773 +#define IOC_FM_PCD_FRM_REPLIC_MAX_NUM_OF_ENTRIES 64 /**< Maximum possible entries for frame replicator group */
149774 +#endif /* DPAA_VERSION >= 11 */
149775 +/* @} */
149776 +
149777 +#ifdef FM_CAPWAP_SUPPORT
149778 +#error "FM_CAPWAP_SUPPORT not implemented!"
149779 +#endif
149780 +
149781 +
149782 +/**************************************************************************//**
149783 + @Group lnx_ioctl_FM_PCD_init_grp FM PCD Initialization Unit
149784 +
149785 + @Description Frame Manager PCD Initialization Unit API
149786 +
149787 + @{
149788 +*//***************************************************************************/
149789 +
149790 +/**************************************************************************//**
149791 + @Description PCD counters
149792 + (must match enum e_FmPcdCounters defined in fm_pcd_ext.h)
149793 +*//***************************************************************************/
149794 +typedef enum ioc_fm_pcd_counters {
149795 + e_IOC_FM_PCD_KG_COUNTERS_TOTAL, /**< KeyGen counter */
149796 + e_IOC_FM_PCD_PLCR_COUNTERS_RED, /**< Policer counter - counts the total number of RED packets that exit the Policer. */
149797 + e_IOC_FM_PCD_PLCR_COUNTERS_YELLOW, /**< Policer counter - counts the total number of YELLOW packets that exit the Policer. */
149798 + e_IOC_FM_PCD_PLCR_COUNTERS_RECOLORED_TO_RED, /**< Policer counter - counts the number of packets that changed color to RED by the Policer;
149799 + This is a subset of e_IOC_FM_PCD_PLCR_COUNTERS_RED packet count, indicating active color changes. */
149800 + e_IOC_FM_PCD_PLCR_COUNTERS_RECOLORED_TO_YELLOW, /**< Policer counter - counts the number of packets that changed color to YELLOW by the Policer;
149801 + This is a subset of e_IOC_FM_PCD_PLCR_COUNTERS_YELLOW packet count, indicating active color changes. */
149802 + e_IOC_FM_PCD_PLCR_COUNTERS_TOTAL, /**< Policer counter - counts the total number of packets passed in the Policer. */
149803 + e_IOC_FM_PCD_PLCR_COUNTERS_LENGTH_MISMATCH, /**< Policer counter - counts the number of packets with length mismatch. */
149804 + e_IOC_FM_PCD_PRS_COUNTERS_PARSE_DISPATCH, /**< Parser counter - counts the number of times the parser block is dispatched. */
149805 + e_IOC_FM_PCD_PRS_COUNTERS_L2_PARSE_RESULT_RETURNED, /**< Parser counter - counts the number of times L2 parse result is returned (including errors). */
149806 + e_IOC_FM_PCD_PRS_COUNTERS_L3_PARSE_RESULT_RETURNED, /**< Parser counter - counts the number of times L3 parse result is returned (including errors). */
149807 + e_IOC_FM_PCD_PRS_COUNTERS_L4_PARSE_RESULT_RETURNED, /**< Parser counter - counts the number of times L4 parse result is returned (including errors). */
149808 + e_IOC_FM_PCD_PRS_COUNTERS_SHIM_PARSE_RESULT_RETURNED, /**< Parser counter - counts the number of times SHIM parse result is returned (including errors). */
149809 + 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. */
149810 + 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. */
149811 + 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. */
149812 + 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. */
149813 + e_IOC_FM_PCD_PRS_COUNTERS_SOFT_PRS_CYCLES, /**< Parser counter - counts the number of cycles spent executing soft parser instruction (including stall cycles). */
149814 + 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. */
149815 + 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). */
149816 + e_IOC_FM_PCD_PRS_COUNTERS_MURAM_READ_CYCLES, /**< MURAM counter - counts the number of cycles while performing FMan Memory read. */
149817 + e_IOC_FM_PCD_PRS_COUNTERS_MURAM_READ_STALL_CYCLES, /**< MURAM counter - counts the number of cycles stalled while performing FMan Memory read. */
149818 + e_IOC_FM_PCD_PRS_COUNTERS_MURAM_WRITE_CYCLES, /**< MURAM counter - counts the number of cycles while performing FMan Memory write. */
149819 + e_IOC_FM_PCD_PRS_COUNTERS_MURAM_WRITE_STALL_CYCLES, /**< MURAM counter - counts the number of cycles stalled while performing FMan Memory write. */
149820 + e_IOC_FM_PCD_PRS_COUNTERS_FPM_COMMAND_STALL_CYCLES /**< FPM counter - counts the number of cycles stalled while performing a FPM Command. */
149821 +} ioc_fm_pcd_counters;
149822 +
149823 +/**************************************************************************//**
149824 + @Description PCD interrupts
149825 + (must match enum e_FmPcdExceptions defined in fm_pcd_ext.h)
149826 +*//***************************************************************************/
149827 +typedef enum ioc_fm_pcd_exceptions {
149828 + e_IOC_FM_PCD_KG_EXCEPTION_DOUBLE_ECC, /**< KeyGen double-bit ECC error is detected on internal memory read access. */
149829 + e_IOC_FM_PCD_KG_EXCEPTION_KEYSIZE_OVERFLOW, /**< KeyGen scheme configuration error indicating a key size larger than 56 bytes. */
149830 + e_IOC_FM_PCD_PLCR_EXCEPTION_DOUBLE_ECC, /**< Policer double-bit ECC error has been detected on PRAM read access. */
149831 + e_IOC_FM_PCD_PLCR_EXCEPTION_INIT_ENTRY_ERROR, /**< Policer access to a non-initialized profile has been detected. */
149832 + e_IOC_FM_PCD_PLCR_EXCEPTION_PRAM_SELF_INIT_COMPLETE, /**< Policer RAM self-initialization complete */
149833 + e_IOC_FM_PCD_PLCR_EXCEPTION_ATOMIC_ACTION_COMPLETE, /**< Policer atomic action complete */
149834 + e_IOC_FM_PCD_PRS_EXCEPTION_DOUBLE_ECC, /**< Parser double-bit ECC error */
149835 + e_IOC_FM_PCD_PRS_EXCEPTION_SINGLE_ECC /**< Parser single-bit ECC error */
149836 +} ioc_fm_pcd_exceptions;
149837 +
149838 +/** @} */ /* end of lnx_ioctl_FM_PCD_init_grp group */
149839 +
149840 +
149841 +/**************************************************************************//**
149842 + @Group lnx_ioctl_FM_PCD_Runtime_grp FM PCD Runtime Unit
149843 +
149844 + @Description Frame Manager PCD Runtime Unit
149845 +
149846 + The runtime control allows creation of PCD infrastructure modules
149847 + such as Network Environment Characteristics, Classification Plan
149848 + Groups and Coarse Classification Trees.
149849 + It also allows on-the-fly initialization, modification and removal
149850 + of PCD modules such as KeyGen schemes, coarse classification nodes
149851 + and Policer profiles.
149852 +
149853 + In order to explain the programming model of the PCD driver interface
149854 + a few terms should be explained, and will be used below.
149855 + - Distinction Header - One of the 16 protocols supported by the FM parser,
149856 + or one of the SHIM headers (1 or 2). May be a header with a special
149857 + option (see below).
149858 + - Interchangeable Headers Group - This is a group of Headers recognized
149859 + by either one of them. For example, if in a specific context the user
149860 + chooses to treat IPv4 and IPV6 in the same way, they may create an
149861 + interchangeable Headers Unit consisting of these 2 headers.
149862 + - A Distinction Unit - a Distinction Header or an Interchangeable Headers
149863 + Group.
149864 + - Header with special option - applies to Ethernet, MPLS, VLAN, IPv4 and
149865 + IPv6, includes multicast, broadcast and other protocol specific options.
149866 + In terms of hardware it relates to the options available in the classification
149867 + plan.
149868 + - Network Environment Characteristics - a set of Distinction Units that define
149869 + the total recognizable header selection for a certain environment. This is
149870 + NOT the list of all headers that will ever appear in a flow, but rather
149871 + everything that needs distinction in a flow, where distinction is made by KeyGen
149872 + schemes and coarse classification action descriptors.
149873 +
149874 + The PCD runtime modules initialization is done in stages. The first stage after
149875 + initializing the PCD module itself is to establish a Network Flows Environment
149876 + Definition. The application may choose to establish one or more such environments.
149877 + Later, when needed, the application will have to state, for some of its modules,
149878 + to which single environment it belongs.
149879 +
149880 + @{
149881 +*//***************************************************************************/
149882 +
149883 +
149884 +/**************************************************************************//**
149885 + @Description structure for FM counters
149886 +*//***************************************************************************/
149887 +typedef struct ioc_fm_pcd_counters_params_t {
149888 + ioc_fm_pcd_counters cnt; /**< The requested counter */
149889 + uint32_t val; /**< The requested value to get/set from/into the counter */
149890 +} ioc_fm_pcd_counters_params_t;
149891 +
149892 +/**************************************************************************//**
149893 + @Description structure for FM exception definitios
149894 +*//***************************************************************************/
149895 +typedef struct ioc_fm_pcd_exception_params_t {
149896 + ioc_fm_pcd_exceptions exception; /**< The requested exception */
149897 + bool enable; /**< TRUE to enable interrupt, FALSE to mask it. */
149898 +} ioc_fm_pcd_exception_params_t;
149899 +
149900 +/**************************************************************************//**
149901 + @Description A structure for SW parser labels
149902 + (must be identical to struct t_FmPcdPrsLabelParams defined in fm_pcd_ext.h)
149903 + *//***************************************************************************/
149904 +typedef struct ioc_fm_pcd_prs_label_params_t {
149905 + uint32_t instruction_offset; /**< SW parser label instruction offset (2 bytes
149906 + resolution), relative to Parser RAM. */
149907 + ioc_net_header_type hdr; /**< The existence of this header will invoke
149908 + the SW parser code. */
149909 + uint8_t index_per_hdr; /**< Normally 0, if more than one SW parser
149910 + attachments for the same header, use this
149911 + index to distinguish between them. */
149912 +} ioc_fm_pcd_prs_label_params_t;
149913 +
149914 +/**************************************************************************//**
149915 + @Description A structure for SW parser
149916 + (Must match struct t_FmPcdPrsSwParams defined in fm_pcd_ext.h)
149917 + *//***************************************************************************/
149918 +typedef struct ioc_fm_pcd_prs_sw_params_t {
149919 + bool override; /**< FALSE to invoke a check that nothing else
149920 + was loaded to this address, including
149921 + internal patches.
149922 + TRUE to override any existing code.*/
149923 + uint32_t size; /**< SW parser code size */
149924 + uint16_t base; /**< SW parser base (in instruction counts!
149925 + must be larger than 0x20)*/
149926 + uint8_t *p_code; /**< SW parser code */
149927 + uint32_t sw_prs_data_params[IOC_FM_PCD_PRS_NUM_OF_HDRS];
149928 + /**< SW parser data (parameters) */
149929 + uint8_t num_of_labels; /**< Number of labels for SW parser. */
149930 + ioc_fm_pcd_prs_label_params_t labels_table[IOC_FM_PCD_PRS_NUM_OF_LABELS];
149931 + /**< SW parser labels table,
149932 + containing num_of_labels entries */
149933 +} ioc_fm_pcd_prs_sw_params_t;
149934 +
149935 +/**************************************************************************//**
149936 + @Description A structure to set the a KeyGen default value
149937 + *//***************************************************************************/
149938 +typedef struct ioc_fm_pcd_kg_dflt_value_params_t {
149939 + uint8_t valueId; /**< 0,1 - one of 2 global default values */
149940 + uint32_t value; /**< The requested default value */
149941 +} ioc_fm_pcd_kg_dflt_value_params_t;
149942 +
149943 +
149944 +/**************************************************************************//**
149945 + @Function FM_PCD_Enable
149946 +
149947 + @Description This routine should be called after PCD is initialized for enabling all
149948 + PCD engines according to their existing configuration.
149949 +
149950 + @Return 0 on success; Error code otherwise.
149951 +
149952 + @Cautions Allowed only when PCD is disabled.
149953 +*//***************************************************************************/
149954 +#define FM_PCD_IOC_ENABLE _IO(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(1))
149955 +
149956 +/**************************************************************************//**
149957 + @Function FM_PCD_Disable
149958 +
149959 + @Description This routine may be called when PCD is enabled in order to
149960 + disable all PCD engines. It may be called
149961 + only when none of the ports in the system are using the PCD.
149962 +
149963 + @Return 0 on success; Error code otherwise.
149964 +
149965 + @Cautions Allowed only when PCD is enabled.
149966 +*//***************************************************************************/
149967 +#define FM_PCD_IOC_DISABLE _IO(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(2))
149968 +
149969 + /**************************************************************************//**
149970 + @Function FM_PCD_PrsLoadSw
149971 +
149972 + @Description This routine may be called only when all ports in the
149973 + system are actively using the classification plan scheme.
149974 + In such cases it is recommended in order to save resources.
149975 + The driver automatically saves 8 classification plans for
149976 + ports that do NOT use the classification plan mechanism, to
149977 + avoid this (in order to save those entries) this routine may
149978 + be called.
149979 +
149980 + @Param[in] ioc_fm_pcd_prs_sw_params_t A pointer to the image of the software parser code.
149981 +
149982 + @Return 0 on success; Error code otherwise.
149983 +
149984 + @Cautions Allowed only when PCD is disabled.
149985 +*//***************************************************************************/
149986 +#if defined(CONFIG_COMPAT)
149987 +#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)
149988 +#endif
149989 +#define FM_PCD_IOC_PRS_LOAD_SW _IOW(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(3), ioc_fm_pcd_prs_sw_params_t)
149990 +
149991 +/**************************************************************************//**
149992 + @Function FM_PCD_KgSetDfltValue
149993 +
149994 + @Description Calling this routine sets a global default value to be used
149995 + by the KeyGen when parser does not recognize a required
149996 + field/header.
149997 + By default default values are 0.
149998 +
149999 + @Param[in] ioc_fm_pcd_kg_dflt_value_params_t A pointer to a structure with the relevant parameters
150000 +
150001 + @Return 0 on success; Error code otherwise.
150002 +
150003 + @Cautions Allowed only when PCD is disabled.
150004 +*//***************************************************************************/
150005 +#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)
150006 +
150007 +/**************************************************************************//**
150008 + @Function FM_PCD_KgSetAdditionalDataAfterParsing
150009 +
150010 + @Description Calling this routine allows the keygen to access data past
150011 + the parser finishing point.
150012 +
150013 + @Param[in] uint8_t payload-offset; the number of bytes beyond the parser location.
150014 +
150015 + @Return 0 on success; Error code otherwise.
150016 +
150017 + @Cautions Allowed only when PCD is disabled.
150018 +*//***************************************************************************/
150019 +#define FM_PCD_IOC_KG_SET_ADDITIONAL_DATA_AFTER_PARSING _IOW(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(7), uint8_t)
150020 +
150021 +/**************************************************************************//**
150022 + @Function FM_PCD_SetException
150023 +
150024 + @Description Calling this routine enables/disables PCD interrupts.
150025 +
150026 + @Param[in] ioc_fm_pcd_exception_params_t Arguments struct with exception to be enabled/disabled.
150027 +
150028 + @Return 0 on success; Error code otherwise.
150029 +*//***************************************************************************/
150030 +#define FM_PCD_IOC_SET_EXCEPTION _IOW(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(8), ioc_fm_pcd_exception_params_t)
150031 +
150032 +/**************************************************************************//**
150033 + @Function FM_PCD_GetCounter
150034 +
150035 + @Description Reads one of the FM PCD counters.
150036 +
150037 + @Param[in,out] ioc_fm_pcd_counters_params_t The requested counter parameters.
150038 +
150039 + @Return 0 on success; Error code otherwise.
150040 +
150041 + @Cautions Note that it is user's responsibilty to call this routine only
150042 + for enabled counters, and there will be no indication if a
150043 + disabled counter is accessed.
150044 +*//***************************************************************************/
150045 +#define FM_PCD_IOC_GET_COUNTER _IOWR(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(9), ioc_fm_pcd_counters_params_t)
150046 +
150047 +/**************************************************************************//**
150048 +
150049 + @Function FM_PCD_KgSchemeGetCounter
150050 +
150051 + @Description Reads scheme packet counter.
150052 +
150053 + @Param[in] h_Scheme scheme handle as returned by FM_PCD_KgSchemeSet().
150054 +
150055 + @Return Counter's current value.
150056 +
150057 + @Cautions Allowed only following FM_PCD_Init() & FM_PCD_KgSchemeSet().
150058 +*//***************************************************************************/
150059 +#if defined(CONFIG_COMPAT)
150060 +#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)
150061 +#endif
150062 +#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)
150063 +
150064 +#if 0
150065 +TODO: unused IOCTL
150066 +/**************************************************************************//**
150067 + @Function FM_PCD_ModifyCounter
150068 +
150069 + @Description Writes a value to an enabled counter. Use "0" to reset the counter.
150070 +
150071 + @Param[in] ioc_fm_pcd_counters_params_t - The requested counter parameters.
150072 +
150073 + @Return 0 on success; Error code otherwise.
150074 +*//***************************************************************************/
150075 +#define FM_PCD_IOC_MODIFY_COUNTER _IOW(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(10), ioc_fm_pcd_counters_params_t)
150076 +#define FM_PCD_IOC_SET_COUNTER FM_PCD_IOC_MODIFY_COUNTER
150077 +#endif
150078 +
150079 +/**************************************************************************//**
150080 + @Function FM_PCD_ForceIntr
150081 +
150082 + @Description Causes an interrupt event on the requested source.
150083 +
150084 + @Param[in] ioc_fm_pcd_exceptions - An exception to be forced.
150085 +
150086 + @Return 0 on success; error code if the exception is not enabled,
150087 + or is not able to create interrupt.
150088 +*//***************************************************************************/
150089 +#define FM_PCD_IOC_FORCE_INTR _IOW(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(11), ioc_fm_pcd_exceptions)
150090 +
150091 +/**************************************************************************//**
150092 + @Collection Definitions of coarse classification parameters as required by KeyGen
150093 + (when coarse classification is the next engine after this scheme).
150094 +*//***************************************************************************/
150095 +#define IOC_FM_PCD_MAX_NUM_OF_CC_TREES 8
150096 +#define IOC_FM_PCD_MAX_NUM_OF_CC_GROUPS 16
150097 +#define IOC_FM_PCD_MAX_NUM_OF_CC_UNITS 4
150098 +#define IOC_FM_PCD_MAX_NUM_OF_KEYS 256
150099 +#define IOC_FM_PCD_MAX_NUM_OF_FLOWS (4*KILOBYTE)
150100 +#define IOC_FM_PCD_MAX_SIZE_OF_KEY 56
150101 +#define IOC_FM_PCD_MAX_NUM_OF_CC_ENTRIES_IN_GRP 16
150102 +#define IOC_FM_PCD_LAST_KEY_INDEX 0xffff
150103 +#define IOC_FM_PCD_MANIP_DSCP_VALUES 64
150104 +/* @} */
150105 +
150106 +/**************************************************************************//**
150107 + @Collection A set of definitions to allow protocol
150108 + special option description.
150109 +*//***************************************************************************/
150110 +typedef uint32_t ioc_protocol_opt_t; /**< A general type to define a protocol option. */
150111 +
150112 +typedef ioc_protocol_opt_t ioc_eth_protocol_opt_t; /**< Ethernet protocol options. */
150113 +#define IOC_ETH_BROADCAST 0x80000000 /**< Ethernet Broadcast. */
150114 +#define IOC_ETH_MULTICAST 0x40000000 /**< Ethernet Multicast. */
150115 +
150116 +typedef ioc_protocol_opt_t ioc_vlan_protocol_opt_t; /**< Vlan protocol options. */
150117 +#define IOC_VLAN_STACKED 0x20000000 /**< Stacked VLAN. */
150118 +
150119 +typedef ioc_protocol_opt_t ioc_mpls_protocol_opt_t; /**< MPLS protocol options. */
150120 +#define IOC_MPLS_STACKED 0x10000000 /**< Stacked MPLS. */
150121 +
150122 +typedef ioc_protocol_opt_t ioc_ipv4_protocol_opt_t; /**< IPv4 protocol options. */
150123 +#define IOC_IPV4_BROADCAST_1 0x08000000 /**< IPv4 Broadcast. */
150124 +#define IOC_IPV4_MULTICAST_1 0x04000000 /**< IPv4 Multicast. */
150125 +#define IOC_IPV4_UNICAST_2 0x02000000 /**< Tunneled IPv4 - Unicast. */
150126 +#define IOC_IPV4_MULTICAST_BROADCAST_2 0x01000000 /**< Tunneled IPv4 - Broadcast/Multicast. */
150127 +
150128 +#define IOC_IPV4_FRAG_1 0x00000008 /**< IPV4 reassembly option.
150129 + IPV4 Reassembly manipulation requires network
150130 + environment with IPV4 header and IPV4_FRAG_1 option */
150131 +
150132 +typedef ioc_protocol_opt_t ioc_ipv6_protocol_opt_t; /**< IPv6 protocol options. */
150133 +#define IOC_IPV6_MULTICAST_1 0x00800000 /**< IPv6 Multicast. */
150134 +#define IOC_IPV6_UNICAST_2 0x00400000 /**< Tunneled IPv6 - Unicast. */
150135 +#define IOC_IPV6_MULTICAST_2 0x00200000 /**< Tunneled IPv6 - Multicast. */
150136 +
150137 +#define IOC_IPV6_FRAG_1 0x00000004 /**< IPV6 reassembly option.
150138 + IPV6 Reassembly manipulation requires network
150139 + environment with IPV6 header and IPV6_FRAG_1 option */
150140 +#if (DPAA_VERSION >= 11)
150141 +typedef ioc_protocol_opt_t ioc_capwap_protocol_opt_t; /**< CAPWAP protocol options. */
150142 +#define CAPWAP_FRAG_1 0x00000008 /**< CAPWAP reassembly option.
150143 + CAPWAP Reassembly manipulation requires network
150144 + environment with CAPWAP header and CAPWAP_FRAG_1 option;
150145 + in case where fragment found, the fragment-extension offset
150146 + may be found at 'shim2' (in parser-result). */
150147 +#endif /* (DPAA_VERSION >= 11) */
150148 +
150149 +/* @} */
150150 +
150151 +#define IOC_FM_PCD_MANIP_MAX_HDR_SIZE 256
150152 +#define IOC_FM_PCD_MANIP_DSCP_TO_VLAN_TRANS 64
150153 +/**************************************************************************//**
150154 + @Collection A set of definitions to support Header Manipulation selection.
150155 +*//***************************************************************************/
150156 +typedef uint32_t ioc_hdr_manip_flags_t; /**< A general type to define a HMan update command flags. */
150157 +
150158 +typedef ioc_hdr_manip_flags_t ioc_ipv4_hdr_manip_update_flags_t; /**< IPv4 protocol HMan update command flags. */
150159 +
150160 +#define IOC_HDR_MANIP_IPV4_TOS 0x80000000 /**< update TOS with the given value ('tos' field
150161 + of ioc_fm_pcd_manip_hdr_field_update_ipv4_t) */
150162 +#define IOC_HDR_MANIP_IPV4_ID 0x40000000 /**< update IP ID with the given value ('id' field
150163 + of ioc_fm_pcd_manip_hdr_field_update_ipv4_t) */
150164 +#define IOC_HDR_MANIP_IPV4_TTL 0x20000000 /**< Decrement TTL by 1 */
150165 +#define IOC_HDR_MANIP_IPV4_SRC 0x10000000 /**< update IP source address with the given value
150166 + ('src' field of ioc_fm_pcd_manip_hdr_field_update_ipv4_t) */
150167 +#define IOC_HDR_MANIP_IPV4_DST 0x08000000 /**< update IP destination address with the given value
150168 + ('dst' field of ioc_fm_pcd_manip_hdr_field_update_ipv4_t) */
150169 +
150170 +typedef ioc_hdr_manip_flags_t ioc_ipv6_hdr_manip_update_flags_t; /**< IPv6 protocol HMan update command flags. */
150171 +
150172 +#define IOC_HDR_MANIP_IPV6_TC 0x80000000 /**< update Traffic Class address with the given value
150173 + ('traffic_class' field of ioc_fm_pcd_manip_hdr_field_update_ipv6_t) */
150174 +#define IOC_HDR_MANIP_IPV6_HL 0x40000000 /**< Decrement Hop Limit by 1 */
150175 +#define IOC_HDR_MANIP_IPV6_SRC 0x20000000 /**< update IP source address with the given value
150176 + ('src' field of ioc_fm_pcd_manip_hdr_field_update_ipv6_t) */
150177 +#define IOC_HDR_MANIP_IPV6_DST 0x10000000 /**< update IP destination address with the given value
150178 + ('dst' field of ioc_fm_pcd_manip_hdr_field_update_ipv6_t) */
150179 +
150180 +typedef ioc_hdr_manip_flags_t ioc_tcp_udp_hdr_manip_update_flags_t;/**< TCP/UDP protocol HMan update command flags. */
150181 +
150182 +#define IOC_HDR_MANIP_TCP_UDP_SRC 0x80000000 /**< update TCP/UDP source address with the given value
150183 + ('src' field of ioc_fm_pcd_manip_hdr_field_update_tcp_udp_t) */
150184 +#define IOC_HDR_MANIP_TCP_UDP_DST 0x40000000 /**< update TCP/UDP destination address with the given value
150185 + ('dst' field of ioc_fm_pcd_manip_hdr_field_update_tcp_udp_t) */
150186 +#define IOC_HDR_MANIP_TCP_UDP_CHECKSUM 0x20000000 /**< update TCP/UDP checksum */
150187 +
150188 +/* @} */
150189 +
150190 +/**************************************************************************//**
150191 + @Description A type used for returning the order of the key extraction.
150192 + each value in this array represents the index of the extraction
150193 + command as defined by the user in the initialization extraction array.
150194 + The valid size of this array is the user define number of extractions
150195 + required (also marked by the second '0' in this array).
150196 +*//***************************************************************************/
150197 +typedef uint8_t ioc_fm_pcd_kg_key_order_t [IOC_FM_PCD_KG_MAX_NUM_OF_EXTRACTS_PER_KEY];
150198 +
150199 +/**************************************************************************//**
150200 + @Description All PCD engines
150201 + (must match enum e_FmPcdEngine defined in fm_pcd_ext.h)
150202 +*//***************************************************************************/
150203 +typedef enum ioc_fm_pcd_engine {
150204 + e_IOC_FM_PCD_INVALID = 0, /**< Invalid PCD engine */
150205 + e_IOC_FM_PCD_DONE, /**< No PCD Engine indicated */
150206 + e_IOC_FM_PCD_KG, /**< KeyGen */
150207 + e_IOC_FM_PCD_CC, /**< Coarse Classifier */
150208 + e_IOC_FM_PCD_PLCR, /**< Policer */
150209 + e_IOC_FM_PCD_PRS, /**< Parser */
150210 +#if DPAA_VERSION >= 11
150211 + e_IOC_FM_PCD_FR, /**< Frame Replicator */
150212 +#endif /* DPAA_VERSION >= 11 */
150213 + e_IOC_FM_PCD_HASH /**< Hash Table */
150214 +} ioc_fm_pcd_engine;
150215 +
150216 +/**************************************************************************//**
150217 + @Description An enum for selecting extraction by header types
150218 + (Must match enum e_FmPcdExtractByHdrType defined in fm_pcd_ext.h)
150219 +*//***************************************************************************/
150220 +typedef enum ioc_fm_pcd_extract_by_hdr_type {
150221 + e_IOC_FM_PCD_EXTRACT_FROM_HDR, /**< Extract bytes from header */
150222 + e_IOC_FM_PCD_EXTRACT_FROM_FIELD, /**< Extract bytes from header field */
150223 + e_IOC_FM_PCD_EXTRACT_FULL_FIELD /**< Extract a full field */
150224 +} ioc_fm_pcd_extract_by_hdr_type;
150225 +
150226 +/**************************************************************************//**
150227 + @Description An enum for selecting extraction source (when it is not the header)
150228 + (Must match enum e_FmPcdExtractFrom defined in fm_pcd_ext.h)
150229 +*//***************************************************************************/
150230 +typedef enum ioc_fm_pcd_extract_from {
150231 + e_IOC_FM_PCD_EXTRACT_FROM_FRAME_START, /**< KG & CC: Extract from beginning of frame */
150232 + e_IOC_FM_PCD_EXTRACT_FROM_DFLT_VALUE, /**< KG only: Extract from a default value */
150233 + e_IOC_FM_PCD_EXTRACT_FROM_CURR_END_OF_PARSE, /**< KG only: Extract from the point where parsing had finished */
150234 + e_IOC_FM_PCD_EXTRACT_FROM_KEY, /**< CC only: Field where saved KEY */
150235 + e_IOC_FM_PCD_EXTRACT_FROM_HASH, /**< CC only: Field where saved HASH */
150236 + e_IOC_FM_PCD_EXTRACT_FROM_PARSE_RESULT, /**< KG & CC: Extract from the parser result */
150237 + e_IOC_FM_PCD_EXTRACT_FROM_ENQ_FQID, /**< KG & CC: Extract from enqueue FQID */
150238 + e_IOC_FM_PCD_EXTRACT_FROM_FLOW_ID /**< CC only: Field where saved Dequeue FQID */
150239 +} ioc_fm_pcd_extract_from;
150240 +
150241 +/**************************************************************************//**
150242 + @Description An enum for selecting extraction type
150243 +*//***************************************************************************/
150244 +typedef enum ioc_fm_pcd_extract_type {
150245 + e_IOC_FM_PCD_EXTRACT_BY_HDR, /**< Extract according to header */
150246 + e_IOC_FM_PCD_EXTRACT_NON_HDR, /**< Extract from data that is not the header */
150247 + e_IOC_FM_PCD_KG_EXTRACT_PORT_PRIVATE_INFO /**< Extract private info as specified by user */
150248 +} ioc_fm_pcd_extract_type;
150249 +
150250 +/**************************************************************************//**
150251 + @Description An enum for selecting a default
150252 +*//***************************************************************************/
150253 +typedef enum ioc_fm_pcd_kg_extract_dflt_select {
150254 + e_IOC_FM_PCD_KG_DFLT_GBL_0, /**< Default selection is KG register 0 */
150255 + e_IOC_FM_PCD_KG_DFLT_GBL_1, /**< Default selection is KG register 1 */
150256 + e_IOC_FM_PCD_KG_DFLT_PRIVATE_0, /**< Default selection is a per scheme register 0 */
150257 + e_IOC_FM_PCD_KG_DFLT_PRIVATE_1, /**< Default selection is a per scheme register 1 */
150258 + e_IOC_FM_PCD_KG_DFLT_ILLEGAL /**< Illegal selection */
150259 +} ioc_fm_pcd_kg_extract_dflt_select;
150260 +
150261 +/**************************************************************************//**
150262 + @Description Enumeration type defining all default groups - each group shares
150263 + a default value, one of four user-initialized values.
150264 +*//***************************************************************************/
150265 +typedef enum ioc_fm_pcd_kg_known_fields_dflt_types {
150266 + e_IOC_FM_PCD_KG_MAC_ADDR, /**< MAC Address */
150267 + e_IOC_FM_PCD_KG_TCI, /**< TCI field */
150268 + e_IOC_FM_PCD_KG_ENET_TYPE, /**< ENET Type */
150269 + e_IOC_FM_PCD_KG_PPP_SESSION_ID, /**< PPP Session id */
150270 + e_IOC_FM_PCD_KG_PPP_PROTOCOL_ID, /**< PPP Protocol id */
150271 + e_IOC_FM_PCD_KG_MPLS_LABEL, /**< MPLS label */
150272 + e_IOC_FM_PCD_KG_IP_ADDR, /**< IP addr */
150273 + e_IOC_FM_PCD_KG_PROTOCOL_TYPE, /**< Protocol type */
150274 + e_IOC_FM_PCD_KG_IP_TOS_TC, /**< TOS or TC */
150275 + e_IOC_FM_PCD_KG_IPV6_FLOW_LABEL, /**< IPV6 flow label */
150276 + e_IOC_FM_PCD_KG_IPSEC_SPI, /**< IPSEC SPI */
150277 + e_IOC_FM_PCD_KG_L4_PORT, /**< L4 Port */
150278 + e_IOC_FM_PCD_KG_TCP_FLAG, /**< TCP Flag */
150279 + e_IOC_FM_PCD_KG_GENERIC_FROM_DATA, /**< grouping implemented by SW,
150280 + any data extraction that is not the full
150281 + field described above */
150282 + e_IOC_FM_PCD_KG_GENERIC_FROM_DATA_NO_V, /**< grouping implemented by SW,
150283 + any data extraction without validation */
150284 + e_IOC_FM_PCD_KG_GENERIC_NOT_FROM_DATA /**< grouping implemented by SW,
150285 + extraction from parser result or
150286 + direct use of default value */
150287 +} ioc_fm_pcd_kg_known_fields_dflt_types;
150288 +
150289 +/**************************************************************************//**
150290 + @Description Enumeration type for defining header index for scenarios with
150291 + multiple (tunneled) headers
150292 +*//***************************************************************************/
150293 +typedef enum ioc_fm_pcd_hdr_index {
150294 + e_IOC_FM_PCD_HDR_INDEX_NONE = 0, /**< used when multiple headers not used, also
150295 + to specify regular IP (not tunneled). */
150296 + e_IOC_FM_PCD_HDR_INDEX_1, /**< may be used for VLAN, MPLS, tunneled IP */
150297 + e_IOC_FM_PCD_HDR_INDEX_2, /**< may be used for MPLS, tunneled IP */
150298 + e_IOC_FM_PCD_HDR_INDEX_3, /**< may be used for MPLS */
150299 + e_IOC_FM_PCD_HDR_INDEX_LAST = 0xFF /**< may be used for VLAN, MPLS */
150300 +} ioc_fm_pcd_hdr_index;
150301 +
150302 +/**************************************************************************//**
150303 + @Description Enumeration type for selecting the policer profile functional type
150304 +*//***************************************************************************/
150305 +typedef enum ioc_fm_pcd_profile_type_selection {
150306 + e_IOC_FM_PCD_PLCR_PORT_PRIVATE, /**< Port dedicated profile */
150307 + e_IOC_FM_PCD_PLCR_SHARED /**< Shared profile (shared within partition) */
150308 +} ioc_fm_pcd_profile_type_selection;
150309 +
150310 +/**************************************************************************//**
150311 + @Description Enumeration type for selecting the policer profile algorithm
150312 +*//***************************************************************************/
150313 +typedef enum ioc_fm_pcd_plcr_algorithm_selection {
150314 + e_IOC_FM_PCD_PLCR_PASS_THROUGH, /**< Policer pass through */
150315 + e_IOC_FM_PCD_PLCR_RFC_2698, /**< Policer algorithm RFC 2698 */
150316 + e_IOC_FM_PCD_PLCR_RFC_4115 /**< Policer algorithm RFC 4115 */
150317 +} ioc_fm_pcd_plcr_algorithm_selection;
150318 +
150319 +/**************************************************************************//**
150320 + @Description Enumeration type for selecting a policer profile color mode
150321 +*//***************************************************************************/
150322 +typedef enum ioc_fm_pcd_plcr_color_mode {
150323 + e_IOC_FM_PCD_PLCR_COLOR_BLIND, /**< Color blind */
150324 + e_IOC_FM_PCD_PLCR_COLOR_AWARE /**< Color aware */
150325 +} ioc_fm_pcd_plcr_color_mode;
150326 +
150327 +/**************************************************************************//**
150328 + @Description Enumeration type for selecting a policer profile color
150329 +*//***************************************************************************/
150330 +typedef enum ioc_fm_pcd_plcr_color {
150331 + e_IOC_FM_PCD_PLCR_GREEN, /**< Green */
150332 + e_IOC_FM_PCD_PLCR_YELLOW, /**< Yellow */
150333 + e_IOC_FM_PCD_PLCR_RED, /**< Red */
150334 + e_IOC_FM_PCD_PLCR_OVERRIDE /**< Color override */
150335 +} ioc_fm_pcd_plcr_color;
150336 +
150337 +/**************************************************************************//**
150338 + @Description Enumeration type for selecting the policer profile packet frame length selector
150339 +*//***************************************************************************/
150340 +typedef enum ioc_fm_pcd_plcr_frame_length_select {
150341 + e_IOC_FM_PCD_PLCR_L2_FRM_LEN, /**< L2 frame length */
150342 + e_IOC_FM_PCD_PLCR_L3_FRM_LEN, /**< L3 frame length */
150343 + e_IOC_FM_PCD_PLCR_L4_FRM_LEN, /**< L4 frame length */
150344 + e_IOC_FM_PCD_PLCR_FULL_FRM_LEN /**< Full frame length */
150345 +} ioc_fm_pcd_plcr_frame_length_select;
150346 +
150347 +/**************************************************************************//**
150348 + @Description Enumeration type for selecting roll-back frame
150349 +*//***************************************************************************/
150350 +typedef enum ioc_fm_pcd_plcr_roll_back_frame_select {
150351 + e_IOC_FM_PCD_PLCR_ROLLBACK_L2_FRM_LEN, /**< Rollback L2 frame length */
150352 + e_IOC_FM_PCD_PLCR_ROLLBACK_FULL_FRM_LEN /**< Rollback Full frame length */
150353 +} ioc_fm_pcd_plcr_roll_back_frame_select;
150354 +
150355 +/**************************************************************************//**
150356 + @Description Enumeration type for selecting the policer profile packet or byte mode
150357 +*//***************************************************************************/
150358 +typedef enum ioc_fm_pcd_plcr_rate_mode {
150359 + e_IOC_FM_PCD_PLCR_BYTE_MODE, /**< Byte mode */
150360 + e_IOC_FM_PCD_PLCR_PACKET_MODE /**< Packet mode */
150361 +} ioc_fm_pcd_plcr_rate_mode;
150362 +
150363 +/**************************************************************************//**
150364 + @Description Enumeration type for defining action of frame
150365 +*//***************************************************************************/
150366 +typedef enum ioc_fm_pcd_done_action {
150367 + e_IOC_FM_PCD_ENQ_FRAME = 0, /**< Enqueue frame */
150368 + e_IOC_FM_PCD_DROP_FRAME /**< Drop frame */
150369 +} ioc_fm_pcd_done_action;
150370 +
150371 +/**************************************************************************//**
150372 + @Description Enumeration type for selecting the policer counter
150373 +*//***************************************************************************/
150374 +typedef enum ioc_fm_pcd_plcr_profile_counters {
150375 + e_IOC_FM_PCD_PLCR_PROFILE_GREEN_PACKET_TOTAL_COUNTER, /**< Green packets counter */
150376 + e_IOC_FM_PCD_PLCR_PROFILE_YELLOW_PACKET_TOTAL_COUNTER, /**< Yellow packets counter */
150377 + e_IOC_FM_PCD_PLCR_PROFILE_RED_PACKET_TOTAL_COUNTER, /**< Red packets counter */
150378 + e_IOC_FM_PCD_PLCR_PROFILE_RECOLOURED_YELLOW_PACKET_TOTAL_COUNTER, /**< Recolored yellow packets counter */
150379 + e_IOC_FM_PCD_PLCR_PROFILE_RECOLOURED_RED_PACKET_TOTAL_COUNTER /**< Recolored red packets counter */
150380 +} ioc_fm_pcd_plcr_profile_counters;
150381 +
150382 +/**************************************************************************//**
150383 + @Description Enumeration type for selecting the PCD action after extraction
150384 +*//***************************************************************************/
150385 +typedef enum ioc_fm_pcd_action {
150386 + e_IOC_FM_PCD_ACTION_NONE, /**< NONE */
150387 + e_IOC_FM_PCD_ACTION_EXACT_MATCH, /**< Exact match on the selected extraction*/
150388 + e_IOC_FM_PCD_ACTION_INDEXED_LOOKUP /**< Indexed lookup on the selected extraction*/
150389 +} ioc_fm_pcd_action;
150390 +
150391 +/**************************************************************************//**
150392 + @Description Enumeration type for selecting type of insert manipulation
150393 +*//***************************************************************************/
150394 +typedef enum ioc_fm_pcd_manip_hdr_insrt_type {
150395 + e_IOC_FM_PCD_MANIP_INSRT_GENERIC, /**< Insert according to offset & size */
150396 + e_IOC_FM_PCD_MANIP_INSRT_BY_HDR, /**< Insert according to protocol */
150397 +#if (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10))
150398 + e_IOC_FM_PCD_MANIP_INSRT_BY_TEMPLATE /**< Insert template to start of frame */
150399 +#endif /* FM_CAPWAP_SUPPORT */
150400 +} ioc_fm_pcd_manip_hdr_insrt_type;
150401 +
150402 +/**************************************************************************//**
150403 + @Description Enumeration type for selecting type of remove manipulation
150404 +*//***************************************************************************/
150405 +typedef enum ioc_fm_pcd_manip_hdr_rmv_type {
150406 + e_IOC_FM_PCD_MANIP_RMV_GENERIC, /**< Remove according to offset & size */
150407 + e_IOC_FM_PCD_MANIP_RMV_BY_HDR /**< Remove according to offset & size */
150408 +} ioc_fm_pcd_manip_hdr_rmv_type;
150409 +
150410 +/**************************************************************************//**
150411 + @Description An enum for selecting specific L2 fields removal
150412 +*//***************************************************************************/
150413 +typedef enum ioc_fm_pcd_manip_hdr_rmv_specific_l2 {
150414 + e_IOC_FM_PCD_MANIP_HDR_RMV_ETHERNET, /**< Ethernet/802.3 MAC */
150415 + e_IOC_FM_PCD_MANIP_HDR_RMV_STACKED_QTAGS, /**< stacked QTags */
150416 + e_IOC_FM_PCD_MANIP_HDR_RMV_ETHERNET_AND_MPLS, /**< MPLS and Ethernet/802.3 MAC header until
150417 + the header which follows the MPLS header */
150418 + e_IOC_FM_PCD_MANIP_HDR_RMV_MPLS /**< Remove MPLS header (Unlimited MPLS labels) */
150419 +} ioc_fm_pcd_manip_hdr_rmv_specific_l2;
150420 +
150421 +/**************************************************************************//**
150422 + @Description Enumeration type for selecting specific fields updates
150423 +*//***************************************************************************/
150424 +typedef enum ioc_fm_pcd_manip_hdr_field_update_type {
150425 + e_IOC_FM_PCD_MANIP_HDR_FIELD_UPDATE_VLAN, /**< VLAN updates */
150426 + e_IOC_FM_PCD_MANIP_HDR_FIELD_UPDATE_IPV4, /**< IPV4 updates */
150427 + e_IOC_FM_PCD_MANIP_HDR_FIELD_UPDATE_IPV6, /**< IPV6 updates */
150428 + e_IOC_FM_PCD_MANIP_HDR_FIELD_UPDATE_TCP_UDP, /**< TCP_UDP updates */
150429 +} ioc_fm_pcd_manip_hdr_field_update_type;
150430 +
150431 +/**************************************************************************//**
150432 + @Description Enumeration type for selecting VLAN updates
150433 +*//***************************************************************************/
150434 +typedef enum ioc_fm_pcd_manip_hdr_field_update_vlan {
150435 + e_IOC_FM_PCD_MANIP_HDR_FIELD_UPDATE_VLAN_VPRI, /**< Replace VPri of outer most VLAN tag. */
150436 + e_IOC_FM_PCD_MANIP_HDR_FIELD_UPDATE_DSCP_TO_VLAN /**< DSCP to VLAN priority bits translation */
150437 +} ioc_fm_pcd_manip_hdr_field_update_vlan;
150438 +
150439 +/**************************************************************************//**
150440 + @Description Enumeration type for selecting specific L2 fields removal
150441 +*//***************************************************************************/
150442 +typedef enum ioc_fm_pcd_manip_hdr_insrt_specific_l2 {
150443 + e_IOC_FM_PCD_MANIP_HDR_INSRT_MPLS /**< Insert MPLS header (Unlimited MPLS labels) */
150444 +} ioc_fm_pcd_manip_hdr_insrt_specific_l2;
150445 +
150446 +#if (DPAA_VERSION >= 11)
150447 +/**************************************************************************//**
150448 + @Description Enumeration type for selecting QoS mapping mode
150449 +
150450 + Note: In all cases except 'e_FM_PCD_MANIP_HDR_QOS_MAPPING_NONE'
150451 + User should instruct the port to read the parser-result
150452 +*//***************************************************************************/
150453 +typedef enum ioc_fm_pcd_manip_hdr_qos_mapping_mode {
150454 + e_IOC_FM_PCD_MANIP_HDR_QOS_MAPPING_NONE = 0, /**< No mapping, QoS field will not be changed */
150455 + e_IOC_FM_PCD_MANIP_HDR_QOS_MAPPING_AS_IS, /**< QoS field will be overwritten by the last byte in the parser-result. */
150456 +} ioc_fm_pcd_manip_hdr_qos_mapping_mode;
150457 +
150458 +/**************************************************************************//**
150459 + @Description Enumeration type for selecting QoS source
150460 +
150461 + Note: In all cases except 'e_FM_PCD_MANIP_HDR_QOS_SRC_NONE'
150462 + User should left room for the parser-result on input/output buffer
150463 + and instruct the port to read/write the parser-result to the buffer (RPD should be set)
150464 +*//***************************************************************************/
150465 +typedef enum ioc_fm_pcd_manip_hdr_qos_src {
150466 + e_IOC_FM_PCD_MANIP_HDR_QOS_SRC_NONE = 0, /**< TODO */
150467 + e_IOC_FM_PCD_MANIP_HDR_QOS_SRC_USER_DEFINED, /**< QoS will be taken from the last byte in the parser-result. */
150468 +} ioc_fm_pcd_manip_hdr_qos_src;
150469 +#endif /* (DPAA_VERSION >= 11) */
150470 +
150471 +/**************************************************************************//**
150472 + @Description Enumeration type for selecting type of header insertion
150473 +*//***************************************************************************/
150474 +typedef enum ioc_fm_pcd_manip_hdr_insrt_by_hdr_type {
150475 + e_IOC_FM_PCD_MANIP_INSRT_BY_HDR_SPECIFIC_L2, /**< Specific L2 fields insertion */
150476 +#if (DPAA_VERSION >= 11)
150477 + e_IOC_FM_PCD_MANIP_INSRT_BY_HDR_IP, /**< IP insertion */
150478 + e_IOC_FM_PCD_MANIP_INSRT_BY_HDR_UDP, /**< UDP insertion */
150479 + e_IOC_FM_PCD_MANIP_INSRT_BY_HDR_UDP_LITE, /**< UDP lite insertion */
150480 + e_IOC_FM_PCD_MANIP_INSRT_BY_HDR_CAPWAP /**< CAPWAP insertion */
150481 +#endif /* (DPAA_VERSION >= 11) */
150482 +} ioc_fm_pcd_manip_hdr_insrt_by_hdr_type;
150483 +
150484 +/**************************************************************************//**
150485 + @Description Enumeration type for selecting specific custom command
150486 +*//***************************************************************************/
150487 +typedef enum ioc_fm_pcd_manip_hdr_custom_type {
150488 + e_IOC_FM_PCD_MANIP_HDR_CUSTOM_IP_REPLACE, /**< Replace IPv4/IPv6 */
150489 +} ioc_fm_pcd_manip_hdr_custom_type;
150490 +
150491 +/**************************************************************************//**
150492 + @Description Enumeration type for selecting specific custom command
150493 +*//***************************************************************************/
150494 +typedef enum ioc_fm_pcd_manip_hdr_custom_ip_replace {
150495 + e_IOC_FM_PCD_MANIP_HDR_CUSTOM_REPLACE_IPV4_BY_IPV6, /**< Replace IPv4 by IPv6 */
150496 + e_IOC_FM_PCD_MANIP_HDR_CUSTOM_REPLACE_IPV6_BY_IPV4 /**< Replace IPv6 by IPv4 */
150497 +} ioc_fm_pcd_manip_hdr_custom_ip_replace;
150498 +
150499 +/**************************************************************************//**
150500 + @Description Enumeration type for selecting type of header removal
150501 +*//***************************************************************************/
150502 +typedef enum ioc_fm_pcd_manip_hdr_rmv_by_hdr_type {
150503 + e_IOC_FM_PCD_MANIP_RMV_BY_HDR_SPECIFIC_L2 = 0, /**< Specific L2 fields removal */
150504 +#if (DPAA_VERSION >= 11)
150505 + e_IOC_FM_PCD_MANIP_RMV_BY_HDR_CAPWAP, /**< CAPWAP removal */
150506 +#endif /* (DPAA_VERSION >= 11) */
150507 +#if (DPAA_VERSION >= 11) || ((DPAA_VERSION == 10) && defined(FM_CAPWAP_SUPPORT))
150508 + e_IOC_FM_PCD_MANIP_RMV_BY_HDR_FROM_START, /**< Locate from data that is not the header */
150509 +#endif /* (DPAA_VERSION >= 11) || ((DPAA_VERSION == 10) && defined(FM_CAPWAP_SUPPORT)) */
150510 +} ioc_fm_pcd_manip_hdr_rmv_by_hdr_type;
150511 +
150512 +/**************************************************************************//**
150513 + @Description Enumeration type for selecting type of timeout mode
150514 +*//***************************************************************************/
150515 +typedef enum ioc_fm_pcd_manip_reassem_time_out_mode {
150516 + e_IOC_FM_PCD_MANIP_TIME_OUT_BETWEEN_FRAMES, /**< Limits the time of the reassembly process
150517 + from the first fragment to the last */
150518 + e_IOC_FM_PCD_MANIP_TIME_OUT_BETWEEN_FRAG /**< Limits the time of receiving the fragment */
150519 +} ioc_fm_pcd_manip_reassem_time_out_mode;
150520 +
150521 +/**************************************************************************//**
150522 + @Description Enumeration type for selecting type of WaysNumber mode
150523 +*//***************************************************************************/
150524 +typedef enum ioc_fm_pcd_manip_reassem_ways_number {
150525 + e_IOC_FM_PCD_MANIP_ONE_WAY_HASH = 1, /**< One way hash */
150526 + e_IOC_FM_PCD_MANIP_TWO_WAYS_HASH, /**< Two ways hash */
150527 + e_IOC_FM_PCD_MANIP_THREE_WAYS_HASH, /**< Three ways hash */
150528 + e_IOC_FM_PCD_MANIP_FOUR_WAYS_HASH, /**< Four ways hash */
150529 + e_IOC_FM_PCD_MANIP_FIVE_WAYS_HASH, /**< Five ways hash */
150530 + e_IOC_FM_PCD_MANIP_SIX_WAYS_HASH, /**< Six ways hash */
150531 + e_IOC_FM_PCD_MANIP_SEVEN_WAYS_HASH, /**< Seven ways hash */
150532 + e_IOC_FM_PCD_MANIP_EIGHT_WAYS_HASH /**< Eight ways hash */
150533 +} ioc_fm_pcd_manip_reassem_ways_number;
150534 +
150535 +#if (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10))
150536 +/**************************************************************************//**
150537 + @Description Enumeration type for selecting type of statistics mode
150538 +*//***************************************************************************/
150539 +typedef enum ioc_fm_pcd_stats {
150540 + e_IOC_FM_PCD_STATS_PER_FLOWID = 0 /**< Flow ID is used as index for getting statistics */
150541 +} ioc_fm_pcd_stats;
150542 +#endif
150543 +
150544 +/**************************************************************************//**
150545 + @Description Enumeration type for selecting manipulation type
150546 +*//***************************************************************************/
150547 +typedef enum ioc_fm_pcd_manip_type {
150548 + e_IOC_FM_PCD_MANIP_HDR = 0, /**< Header manipulation */
150549 + e_IOC_FM_PCD_MANIP_REASSEM, /**< Reassembly */
150550 + e_IOC_FM_PCD_MANIP_FRAG, /**< Fragmentation */
150551 + e_IOC_FM_PCD_MANIP_SPECIAL_OFFLOAD /**< Special Offloading */
150552 +} ioc_fm_pcd_manip_type;
150553 +
150554 +/**************************************************************************//**
150555 + @Description Enumeration type for selecting type of statistics mode
150556 +*//***************************************************************************/
150557 +typedef enum ioc_fm_pcd_cc_stats_mode {
150558 + e_IOC_FM_PCD_CC_STATS_MODE_NONE = 0, /**< No statistics support */
150559 + e_IOC_FM_PCD_CC_STATS_MODE_FRAME, /**< Frame count statistics */
150560 + e_IOC_FM_PCD_CC_STATS_MODE_BYTE_AND_FRAME, /**< Byte and frame count statistics */
150561 +#if (DPAA_VERSION >= 11)
150562 + e_IOC_FM_PCD_CC_STATS_MODE_RMON, /**< Byte and frame length range count statistics */
150563 +#endif /* (DPAA_VERSION >= 11) */
150564 +} ioc_fm_pcd_cc_stats_mode;
150565 +
150566 +/**************************************************************************//**
150567 + @Description Enumeration type for determining the action in case an IP packet
150568 + is larger than MTU but its DF (Don't Fragment) bit is set.
150569 +*//***************************************************************************/
150570 +typedef enum ioc_fm_pcd_manip_dont_frag_action {
150571 + e_IOC_FM_PCD_MANIP_DISCARD_PACKET = 0, /**< Discard packet */
150572 + e_IOC_FM_PCD_MANIP_ENQ_TO_ERR_Q_OR_DISCARD_PACKET = e_IOC_FM_PCD_MANIP_DISCARD_PACKET,
150573 + /**< Obsolete, cannot enqueue to error queue;
150574 + In practice, selects to discard packets;
150575 + Will be removed in the future */
150576 + e_IOC_FM_PCD_MANIP_FRAGMENT_PACKECT, /**< Fragment packet and continue normal processing */
150577 + e_IOC_FM_PCD_MANIP_CONTINUE_WITHOUT_FRAG /**< Continue normal processing without fragmenting the packet */
150578 +} ioc_fm_pcd_manip_dont_frag_action;
150579 +
150580 +/**************************************************************************//**
150581 + @Description Enumeration type for selecting type of special offload manipulation
150582 +*//***************************************************************************/
150583 +typedef enum ioc_fm_pcd_manip_special_offload_type {
150584 + e_IOC_FM_PCD_MANIP_SPECIAL_OFFLOAD_IPSEC, /**< IPSec offload manipulation */
150585 +#if (DPAA_VERSION >= 11)
150586 + e_IOC_FM_PCD_MANIP_SPECIAL_OFFLOAD_CAPWAP /**< CAPWAP offload manipulation */
150587 +#endif /* (DPAA_VERSION >= 11) */
150588 +} ioc_fm_pcd_manip_special_offload_type;
150589 +
150590 +/**************************************************************************//**
150591 + @Description A union of protocol dependent special options
150592 + (Must match union u_FmPcdHdrProtocolOpt defined in fm_pcd_ext.h)
150593 +*//***************************************************************************/
150594 +typedef union ioc_fm_pcd_hdr_protocol_opt_u {
150595 + ioc_eth_protocol_opt_t eth_opt; /**< Ethernet options */
150596 + ioc_vlan_protocol_opt_t vlan_opt; /**< Vlan options */
150597 + ioc_mpls_protocol_opt_t mpls_opt; /**< MPLS options */
150598 + ioc_ipv4_protocol_opt_t ipv4_opt; /**< IPv4 options */
150599 + ioc_ipv6_protocol_opt_t ipv6_opt; /**< IPv6 options */
150600 +#if (DPAA_VERSION >= 11)
150601 + ioc_capwap_protocol_opt_t capwap_opt; /**< CAPWAP options */
150602 +#endif /* (DPAA_VERSION >= 11) */
150603 +} ioc_fm_pcd_hdr_protocol_opt_u;
150604 +
150605 +/**************************************************************************//**
150606 + @Description A union holding all known protocol fields
150607 +*//***************************************************************************/
150608 +typedef union ioc_fm_pcd_fields_u {
150609 + ioc_header_field_eth_t eth; /**< Ethernet */
150610 + ioc_header_field_vlan_t vlan; /**< VLAN */
150611 + ioc_header_field_llc_snap_t llc_snap; /**< LLC SNAP */
150612 + ioc_header_field_pppoe_t pppoe; /**< PPPoE */
150613 + ioc_header_field_mpls_t mpls; /**< MPLS */
150614 + ioc_header_field_ip_t ip; /**< IP */
150615 + ioc_header_field_ipv4_t ipv4; /**< IPv4 */
150616 + ioc_header_field_ipv6_t ipv6; /**< IPv6 */
150617 + ioc_header_field_udp_t udp; /**< UDP */
150618 + ioc_header_field_udp_lite_t udp_lite; /**< UDP_Lite */
150619 + ioc_header_field_tcp_t tcp; /**< TCP */
150620 + ioc_header_field_sctp_t sctp; /**< SCTP */
150621 + ioc_header_field_dccp_t dccp; /**< DCCP */
150622 + ioc_header_field_gre_t gre; /**< GRE */
150623 + ioc_header_field_minencap_t minencap; /**< Minimal Encapsulation */
150624 + ioc_header_field_ipsec_ah_t ipsec_ah; /**< IPSec AH */
150625 + ioc_header_field_ipsec_esp_t ipsec_esp; /**< IPSec ESP */
150626 + ioc_header_field_udp_encap_esp_t udp_encap_esp; /**< UDP Encapsulation ESP */
150627 +} ioc_fm_pcd_fields_u;
150628 +
150629 +/**************************************************************************//**
150630 + @Description Parameters for defining header extraction for key generation
150631 +*//***************************************************************************/
150632 +typedef struct ioc_fm_pcd_from_hdr_t {
150633 + uint8_t size; /**< Size in byte */
150634 + uint8_t offset; /**< Byte offset */
150635 +} ioc_fm_pcd_from_hdr_t;
150636 +
150637 +/**************************************************************************//**
150638 + @Description Parameters for defining field extraction for key generation
150639 +*//***************************************************************************/
150640 +typedef struct ioc_fm_pcd_from_field_t {
150641 + ioc_fm_pcd_fields_u field; /**< Field selection */
150642 + uint8_t size; /**< Size in byte */
150643 + uint8_t offset; /**< Byte offset */
150644 +} ioc_fm_pcd_from_field_t;
150645 +
150646 +/**************************************************************************//**
150647 + @Description Parameters for defining a single network environment unit
150648 + A distinction unit should be defined if it will later be used
150649 + by one or more PCD engines to distinguish between flows.
150650 + (Must match struct t_FmPcdDistinctionUnit defined in fm_pcd_ext.h)
150651 +*//***************************************************************************/
150652 +typedef struct ioc_fm_pcd_distinction_unit_t {
150653 + struct {
150654 + ioc_net_header_type hdr; /**< One of the headers supported by the FM */
150655 + ioc_fm_pcd_hdr_protocol_opt_u opt; /**< Select only one option! */
150656 + } hdrs[IOC_FM_PCD_MAX_NUM_OF_INTERCHANGEABLE_HDRS];
150657 +} ioc_fm_pcd_distinction_unit_t;
150658 +
150659 +/**************************************************************************//**
150660 + @Description Parameters for defining all different distinction units supported
150661 + by a specific PCD Network Environment Characteristics module.
150662 +
150663 + Each unit represent a protocol or a group of protocols that may
150664 + be used later by the different PCD engines to distinguish between flows.
150665 + (Must match struct t_FmPcdNetEnvParams defined in fm_pcd_ext.h)
150666 +*//***************************************************************************/
150667 +typedef struct ioc_fm_pcd_net_env_params_t {
150668 + uint8_t num_of_distinction_units;/**< Number of different units to be identified */
150669 + ioc_fm_pcd_distinction_unit_t units[IOC_FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS];
150670 + /**< An array of num_of_distinction_units of the
150671 + different units to be identified */
150672 + void *id; /**< Output parameter; Returns the net-env Id to be used */
150673 +} ioc_fm_pcd_net_env_params_t;
150674 +
150675 +/**************************************************************************//**
150676 + @Description Parameters for defining a single extraction action when
150677 + creating a key
150678 +*//***************************************************************************/
150679 +typedef struct ioc_fm_pcd_extract_entry_t {
150680 + ioc_fm_pcd_extract_type type; /**< Extraction type select */
150681 + union {
150682 + struct {
150683 + ioc_net_header_type hdr; /**< Header selection */
150684 + bool ignore_protocol_validation;
150685 + /**< Ignore protocol validation */
150686 + ioc_fm_pcd_hdr_index hdr_index; /**< Relevant only for MPLS, VLAN and tunneled
150687 + IP. Otherwise should be cleared.*/
150688 + ioc_fm_pcd_extract_by_hdr_type type; /**< Header extraction type select */
150689 + union {
150690 + ioc_fm_pcd_from_hdr_t from_hdr; /**< Extract bytes from header parameters */
150691 + ioc_fm_pcd_from_field_t from_field; /**< Extract bytes from field parameters */
150692 + ioc_fm_pcd_fields_u full_field; /**< Extract full field parameters */
150693 + } extract_by_hdr_type;
150694 + } extract_by_hdr; /**< Used when type = e_IOC_FM_PCD_KG_EXTRACT_BY_HDR */
150695 + struct {
150696 + ioc_fm_pcd_extract_from src; /**< Non-header extraction source */
150697 + ioc_fm_pcd_action action; /**< Relevant for CC Only */
150698 + uint16_t ic_indx_mask; /**< Relevant only for CC when
150699 + action = e_IOC_FM_PCD_ACTION_INDEXED_LOOKUP;
150700 + Note that the number of bits that are set within
150701 + this mask must be log2 of the CC-node 'num_of_keys'.
150702 + Note that the mask cannot be set on the lower bits. */
150703 + uint8_t offset; /**< Byte offset */
150704 + uint8_t size; /**< Size in bytes */
150705 + } extract_non_hdr; /**< Used when type = e_IOC_FM_PCD_KG_EXTRACT_NON_HDR */
150706 + } extract_params;
150707 +} ioc_fm_pcd_extract_entry_t;
150708 +
150709 +/**************************************************************************//**
150710 + @Description A structure for defining masks for each extracted
150711 + field in the key.
150712 +*//***************************************************************************/
150713 +typedef struct ioc_fm_pcd_kg_extract_mask_t {
150714 + uint8_t extract_array_index; /**< Index in the extraction array, as initialized by user */
150715 + uint8_t offset; /**< Byte offset */
150716 + uint8_t mask; /**< A byte mask (selected bits will be ignored) */
150717 +} ioc_fm_pcd_kg_extract_mask_t;
150718 +
150719 +/**************************************************************************//**
150720 + @Description A structure for defining default selection per groups
150721 + of fields
150722 +*//***************************************************************************/
150723 +typedef struct ioc_fm_pcd_kg_extract_dflt_t {
150724 + ioc_fm_pcd_kg_known_fields_dflt_types type; /**< Default type select*/
150725 + ioc_fm_pcd_kg_extract_dflt_select dflt_select; /**< Default register select */
150726 +} ioc_fm_pcd_kg_extract_dflt_t;
150727 +
150728 +
150729 +/**************************************************************************//**
150730 + @Description A structure for defining all parameters needed for
150731 + generation a key and using a hash function
150732 +*//***************************************************************************/
150733 +typedef struct ioc_fm_pcd_kg_key_extract_and_hash_params_t {
150734 + uint32_t private_dflt0; /**< Scheme default register 0 */
150735 + uint32_t private_dflt1; /**< Scheme default register 1 */
150736 + uint8_t num_of_used_extracts; /**< defines the valid size of the following array */
150737 + ioc_fm_pcd_extract_entry_t extract_array [IOC_FM_PCD_KG_MAX_NUM_OF_EXTRACTS_PER_KEY];
150738 + /**< An array of extraction definitions. */
150739 + uint8_t num_of_used_dflts; /**< defines the valid size of the following array */
150740 + ioc_fm_pcd_kg_extract_dflt_t dflts[IOC_FM_PCD_KG_NUM_OF_DEFAULT_GROUPS];
150741 + /**< For each extraction used in this scheme, specify the required
150742 + default register to be used when header is not found.
150743 + types not specified in this array will get undefined value. */
150744 + uint8_t num_of_used_masks; /**< Defines the valid size of the following array */
150745 + ioc_fm_pcd_kg_extract_mask_t masks[IOC_FM_PCD_KG_NUM_OF_EXTRACT_MASKS];
150746 + uint8_t hash_shift; /**< Hash result right shift.
150747 + Selects the 24 bits out of the 64 hash result.
150748 + 0 means using the 24 LSB's, otherwise use the
150749 + 24 LSB's after shifting right.*/
150750 + uint32_t hash_distribution_num_of_fqids; /**< must be > 1 and a power of 2. Represents the range
150751 + of queues for the key and hash functionality */
150752 + uint8_t hash_distribution_fqids_shift; /**< selects the FQID bits that will be effected by the hash */
150753 + bool symmetric_hash; /**< TRUE to generate the same hash for frames with swapped source and
150754 + destination fields on all layers; If TRUE, driver will check that for
150755 + all layers, if SRC extraction is selected, DST extraction must also be
150756 + selected, and vice versa. */
150757 +} ioc_fm_pcd_kg_key_extract_and_hash_params_t;
150758 +
150759 +/**************************************************************************//**
150760 + @Description A structure of parameters for defining a single
150761 + Qid mask (extracted OR).
150762 +*//***************************************************************************/
150763 +typedef struct ioc_fm_pcd_kg_extracted_or_params_t {
150764 + ioc_fm_pcd_extract_type type; /**< Extraction type select */
150765 + union {
150766 + struct { /**< used when type = e_IOC_FM_PCD_KG_EXTRACT_BY_HDR */
150767 + ioc_net_header_type hdr;
150768 + ioc_fm_pcd_hdr_index hdr_index; /**< Relevant only for MPLS, VLAN and tunneled
150769 + IP. Otherwise should be cleared.*/
150770 + bool ignore_protocol_validation;
150771 +
150772 + } extract_by_hdr;
150773 + ioc_fm_pcd_extract_from src; /**< used when type = e_IOC_FM_PCD_KG_EXTRACT_NON_HDR */
150774 + } extract_params;
150775 + uint8_t extraction_offset; /**< Offset for extraction */
150776 + ioc_fm_pcd_kg_extract_dflt_select dflt_value; /**< Select register from which extraction is taken if
150777 + field not found */
150778 + uint8_t mask; /**< Mask LSB byte of extraction (specified bits are ignored) */
150779 + uint8_t bit_offset_in_fqid; /**< 0-31, Selects which bits of the 24 FQID bits to effect using
150780 + the extracted byte; Assume byte is placed as the 8 MSB's in
150781 + a 32 bit word where the lower bits
150782 + are the FQID; i.e if bitOffsetInFqid=1 than its LSB
150783 + will effect the FQID MSB, if bitOffsetInFqid=24 than the
150784 + extracted byte will effect the 8 LSB's of the FQID,
150785 + if bitOffsetInFqid=31 than the byte's MSB will effect
150786 + the FQID's LSB; 0 means - no effect on FQID;
150787 + Note that one, and only one of
150788 + bitOffsetInFqid or bitOffsetInPlcrProfile must be set (i.e,
150789 + extracted byte must effect either FQID or Policer profile).*/
150790 + uint8_t bit_offset_in_plcr_profile;
150791 + /**< 0-15, Selects which bits of the 8 policer profile id bits to
150792 + effect using the extracted byte; Assume byte is placed
150793 + as the 8 MSB's in a 16 bit word where the lower bits
150794 + are the policer profile id; i.e if bitOffsetInPlcrProfile=1
150795 + than its LSB will effect the profile MSB, if bitOffsetInFqid=8
150796 + than the extracted byte will effect the whole policer profile id,
150797 + if bitOffsetInFqid=15 than the byte's MSB will effect
150798 + the Policer Profile id's LSB;
150799 + 0 means - no effect on policer profile; Note that one, and only one of
150800 + bitOffsetInFqid or bitOffsetInPlcrProfile must be set (i.e,
150801 + extracted byte must effect either FQID or Policer profile).*/
150802 +} ioc_fm_pcd_kg_extracted_or_params_t;
150803 +
150804 +/**************************************************************************//**
150805 + @Description A structure for configuring scheme counter
150806 +*//***************************************************************************/
150807 +typedef struct ioc_fm_pcd_kg_scheme_counter_t {
150808 + bool update; /**< FALSE to keep the current counter state
150809 + and continue from that point, TRUE to update/reset
150810 + the counter when the scheme is written. */
150811 + uint32_t value; /**< If update=TRUE, this value will be written into the
150812 + counter; clear this field to reset the counter. */
150813 +} ioc_fm_pcd_kg_scheme_counter_t;
150814 +
150815 +
150816 +/**************************************************************************//**
150817 + @Description A structure for retrieving FMKG_SE_SPC
150818 +*//***************************************************************************/
150819 +typedef struct ioc_fm_pcd_kg_scheme_spc_t {
150820 + uint32_t val; /**< return value */
150821 + void *id; /**< scheme handle */
150822 +} ioc_fm_pcd_kg_scheme_spc_t;
150823 +
150824 +/**************************************************************************//**
150825 + @Description A structure for defining policer profile parameters as required by keygen
150826 + (when policer is the next engine after this scheme).
150827 + (Must match struct t_FmPcdKgPlcrProfile defined in fm_pcd_ext.h)
150828 +*//***************************************************************************/
150829 +typedef struct ioc_fm_pcd_kg_plcr_profile_t {
150830 + bool shared_profile; /**< TRUE if this profile is shared between ports
150831 + (i.e. managed by master partition) May not be TRUE
150832 + if profile is after Coarse Classification*/
150833 + bool direct; /**< If TRUE, direct_relative_profile_id only selects the profile
150834 + id, if FALSE fqid_offset_relative_profile_id_base is used
150835 + together with fqid_offset_shift and num_of_profiles
150836 + parameters, to define a range of profiles from
150837 + which the KeyGen result will determine the
150838 + destination policer profile. */
150839 + union {
150840 + uint16_t direct_relative_profile_id; /**< Used if 'direct' is TRUE, to select policer profile.
150841 + This parameter should indicate the policer profile offset within the port's
150842 + policer profiles or SHARED window. */
150843 + struct {
150844 + uint8_t fqid_offset_shift; /**< Shift of KG results without the qid base */
150845 + uint8_t fqid_offset_relative_profile_id_base;
150846 + /**< OR of KG results without the qid base
150847 + This parameter should indicate the policer profile
150848 + offset within the port's policer profiles window
150849 + or SHARED window depends on shared_profile */
150850 + uint8_t num_of_profiles; /**< Range of profiles starting at base */
150851 + } indirect_profile; /**< Indirect profile parameters */
150852 + } profile_select; /**< Direct/indirect profile selection and parameters */
150853 +} ioc_fm_pcd_kg_plcr_profile_t;
150854 +
150855 +#if DPAA_VERSION >= 11
150856 +/**************************************************************************//**
150857 + @Description Parameters for configuring a storage profile for a KeyGen scheme.
150858 +*//***************************************************************************/
150859 +typedef struct ioc_fm_pcd_kg_storage_profile_t {
150860 + bool direct; /**< If TRUE, directRelativeProfileId only selects the
150861 + profile id;
150862 + If FALSE, fqidOffsetRelativeProfileIdBase is used
150863 + together with fqidOffsetShift and numOfProfiles
150864 + parameters to define a range of profiles from which
150865 + the KeyGen result will determine the destination
150866 + storage profile. */
150867 + union {
150868 + uint16_t direct_relative_profileId; /**< Used when 'direct' is TRUE, to select a storage profile;
150869 + should indicate the storage profile offset within the
150870 + port's storage profiles window. */
150871 + struct {
150872 + uint8_t fqid_offset_shift; /**< Shift of KeyGen results without the FQID base */
150873 + uint8_t fqid_offset_relative_profile_id_base;
150874 + /**< OR of KeyGen results without the FQID base;
150875 + should indicate the policer profile offset within the
150876 + port's storage profiles window. */
150877 + uint8_t num_of_profiles; /**< Range of profiles starting at base. */
150878 + } indirect_profile; /**< Indirect profile parameters. */
150879 + } profile_select; /**< Direct/indirect profile selection and parameters. */
150880 +} ioc_fm_pcd_kg_storage_profile_t;
150881 +#endif /* DPAA_VERSION >= 11 */
150882 +
150883 +/**************************************************************************//**
150884 + @Description Parameters for defining CC as the next engine after KeyGen
150885 + (Must match struct t_FmPcdKgCc defined in fm_pcd_ext.h)
150886 +*//***************************************************************************/
150887 +typedef struct ioc_fm_pcd_kg_cc_t {
150888 + void *tree_id; /**< CC Tree id */
150889 + uint8_t grp_id; /**< CC group id within the CC tree */
150890 + bool plcr_next; /**< TRUE if after CC, in case of data frame,
150891 + policing is required. */
150892 + bool bypass_plcr_profile_generation;
150893 + /**< TRUE to bypass KeyGen policer profile generation;
150894 + selected profile is the one set at port initialization. */
150895 + ioc_fm_pcd_kg_plcr_profile_t plcr_profile; /**< Valid only if plcr_next = TRUE and
150896 + bypass_plcr_profile_generation = FALSE */
150897 +} ioc_fm_pcd_kg_cc_t;
150898 +
150899 +/**************************************************************************//**
150900 + @Description Parameters for defining initializing a KeyGen scheme
150901 + (Must match struct t_FmPcdKgSchemeParams defined in fm_pcd_ext.h)
150902 +*//***************************************************************************/
150903 +typedef struct ioc_fm_pcd_kg_scheme_params_t {
150904 + bool modify; /**< TRUE to change an existing scheme */
150905 + union {
150906 + uint8_t relative_scheme_id;
150907 + /**< if modify=FALSE: partition-relative scheme id */
150908 + void *scheme_id; /**< if modify=TRUE: the id of an existing scheme */
150909 + } scm_id;
150910 + bool always_direct; /**< This scheme is reached only directly, i.e. no need
150911 + for match vector; KeyGen will ignore it when matching */
150912 + struct { /**< HL relevant only if always_direct=FALSE */
150913 + void *net_env_id; /**< The id of the Network Environment as returned
150914 + by FM_PCD_NetEnvCharacteristicsSet() */
150915 + uint8_t num_of_distinction_units;
150916 + /**< Number of NetEnv units listed in unit_ids array */
150917 + uint8_t unit_ids[IOC_FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS];
150918 + /**< Indexes as passed to SetNetEnvCharacteristics (?) array */
150919 + } net_env_params;
150920 + bool use_hash; /**< use the KG Hash functionality */
150921 + ioc_fm_pcd_kg_key_extract_and_hash_params_t key_extract_and_hash_params;
150922 + /**< used only if useHash = TRUE */
150923 + bool bypass_fqid_generation;
150924 + /**< Normally - FALSE, TRUE to avoid FQID update in the IC;
150925 + In such a case FQID after KG will be the default FQID
150926 + defined for the relevant port, or the FQID defined by CC
150927 + in cases where CC was the previous engine. */
150928 + uint32_t base_fqid; /**< Base FQID; Relevant only if bypass_fqid_generation = FALSE;
150929 + If hash is used and an even distribution is expected
150930 + according to hash_distribution_num_of_fqids, base_fqid must be aligned to
150931 + hash_distribution_num_of_fqids. */
150932 + uint8_t num_of_used_extracted_ors;
150933 + /**< Number of FQID masks listed in extracted_ors array*/
150934 + ioc_fm_pcd_kg_extracted_or_params_t extracted_ors[IOC_FM_PCD_KG_NUM_OF_GENERIC_REGS];
150935 + /**< IOC_FM_PCD_KG_NUM_OF_GENERIC_REGS
150936 + registers are shared between qid_masks
150937 + functionality and some of the extraction
150938 + actions; Normally only some will be used
150939 + for qid_mask. Driver will return error if
150940 + resource is full at initialization time. */
150941 +#if DPAA_VERSION >= 11
150942 + bool override_storage_profile;
150943 + /**< TRUE if KeyGen override previously decided storage profile */
150944 + ioc_fm_pcd_kg_storage_profile_t storage_profile;/**< Used when override_storage_profile=TRUE */
150945 +#endif /* DPAA_VERSION >= 11 */
150946 + ioc_fm_pcd_engine next_engine; /**< may be BMI, PLCR or CC */
150947 + union { /**< depends on nextEngine */
150948 + ioc_fm_pcd_done_action done_action; /**< Used when next engine is BMI (done) */
150949 + ioc_fm_pcd_kg_plcr_profile_t plcr_profile; /**< Used when next engine is PLCR */
150950 + ioc_fm_pcd_kg_cc_t cc; /**< Used when next engine is CC */
150951 + } kg_next_engine_params;
150952 + ioc_fm_pcd_kg_scheme_counter_t scheme_counter; /**< A structure of parameters for updating
150953 + the scheme counter */
150954 + void *id; /**< Returns the scheme Id to be used */
150955 +} ioc_fm_pcd_kg_scheme_params_t;
150956 +
150957 +/**************************************************************************//**
150958 + @Collection
150959 +*//***************************************************************************/
150960 +#if DPAA_VERSION >= 11
150961 +#define IOC_FM_PCD_CC_STATS_MAX_NUM_OF_FLR 10 /* Maximal supported number of frame length ranges */
150962 +#define IOC_FM_PCD_CC_STATS_FLR_SIZE 2 /* Size in bytes of a frame length range limit */
150963 +#endif /* DPAA_VERSION >= 11 */
150964 +#define IOC_FM_PCD_CC_STATS_FLR_COUNT_SIZE 4 /* Size in bytes of a frame length range counter */
150965 +/* @} */
150966 +
150967 +/**************************************************************************//**
150968 + @Description Parameters for defining CC as the next engine after a CC node.
150969 + (Must match struct t_FmPcdCcNextCcParams defined in fm_pcd_ext.h)
150970 +*//***************************************************************************/
150971 +typedef struct ioc_fm_pcd_cc_next_cc_params_t {
150972 + void *cc_node_id; /**< Id of the next CC node */
150973 +} ioc_fm_pcd_cc_next_cc_params_t;
150974 +
150975 +#if DPAA_VERSION >= 11
150976 +/**************************************************************************//**
150977 + @Description A structure for defining Frame Replicator as the next engine after a CC node.
150978 + (Must match struct t_FmPcdCcNextFrParams defined in fm_pcd_ext.h)
150979 +*//***************************************************************************/
150980 +typedef struct ioc_fm_pcd_cc_next_fr_params_t {
150981 + void* frm_replic_id; /**< The id of the next frame replicator group */
150982 +} ioc_fm_pcd_cc_next_fr_params_t;
150983 +#endif /* DPAA_VERSION >= 11 */
150984 +
150985 +/**************************************************************************//**
150986 + @Description A structure for defining PLCR params when PLCR is the
150987 + next engine after a CC node
150988 + (Must match struct t_FmPcdCcNextPlcrParams defined in fm_pcd_ext.h)
150989 +*//***************************************************************************/
150990 +typedef struct ioc_fm_pcd_cc_next_plcr_params_t {
150991 + bool override_params; /**< TRUE if CC override previously decided parameters*/
150992 + bool shared_profile; /**< Relevant only if overrideParams=TRUE:
150993 + TRUE if this profile is shared between ports */
150994 + uint16_t new_relative_profile_id; /**< Relevant only if overrideParams=TRUE:
150995 + (otherwise profile id is taken from keygen);
150996 + This parameter should indicate the policer
150997 + profile offset within the port's
150998 + policer profiles or from SHARED window.*/
150999 + uint32_t new_fqid; /**< Relevant only if overrideParams=TRUE:
151000 + FQID for enquing the frame;
151001 + In earlier chips if policer next engine is KEYGEN,
151002 + this parameter can be 0, because the KEYGEN always decides
151003 + the enqueue FQID.*/
151004 +#if DPAA_VERSION >= 11
151005 + uint8_t new_relative_storage_profile_id;
151006 + /**< Indicates the relative storage profile offset within
151007 + the port's storage profiles window;
151008 + Relevant only if the port was configured with VSP. */
151009 +#endif /* DPAA_VERSION >= 11 */
151010 +} ioc_fm_pcd_cc_next_plcr_params_t;
151011 +
151012 +/**************************************************************************//**
151013 + @Description A structure for defining enqueue params when BMI is the
151014 + next engine after a CC node
151015 + (Must match struct t_FmPcdCcNextEnqueueParams defined in fm_pcd_ext.h)
151016 +*//***************************************************************************/
151017 +typedef struct ioc_fm_pcd_cc_next_enqueue_params_t {
151018 + ioc_fm_pcd_done_action action; /**< Action - when next engine is BMI (done) */
151019 + bool override_fqid; /**< TRUE if CC override previously decided fqid and vspid,
151020 + relevant if action = e_IOC_FM_PCD_ENQ_FRAME */
151021 + uint32_t new_fqid; /**< Valid if overrideFqid=TRUE, FQID for enqueuing the frame
151022 + (otherwise FQID is taken from KeyGen),
151023 + relevant if action = e_IOC_FM_PCD_ENQ_FRAME*/
151024 +#if DPAA_VERSION >= 11
151025 + uint8_t new_relative_storage_profile_id;
151026 + /**< Valid if override_fqid=TRUE, Indicates the relative virtual
151027 + storage profile offset within the port's storage profiles
151028 + window; Relevant only if the port was configured with VSP. */
151029 +#endif /* DPAA_VERSION >= 11 */
151030 +
151031 +} ioc_fm_pcd_cc_next_enqueue_params_t;
151032 +
151033 +/**************************************************************************//**
151034 + @Description A structure for defining KG params when KG is the next engine after a CC node
151035 + (Must match struct t_FmPcdCcNextKgParams defined in fm_pcd_ext.h)
151036 +*//***************************************************************************/
151037 +typedef struct ioc_fm_pcd_cc_next_kg_params_t {
151038 + bool override_fqid; /**< TRUE if CC override previously decided fqid and vspid,
151039 + Note - this parameters are irrelevant for earlier chips */
151040 + uint32_t new_fqid; /**< Valid if overrideFqid=TRUE, FQID for enqueuing the frame
151041 + (otherwise FQID is taken from KeyGen),
151042 + Note - this parameters are irrelevant for earlier chips */
151043 +#if DPAA_VERSION >= 11
151044 + uint8_t new_relative_storage_profile_id;
151045 + /**< Valid if override_fqid=TRUE, Indicates the relative virtual
151046 + storage profile offset within the port's storage profiles
151047 + window; Relevant only if the port was configured with VSP. */
151048 +#endif /* DPAA_VERSION >= 11 */
151049 + void *p_direct_scheme; /**< Direct scheme id to go to. */
151050 +} ioc_fm_pcd_cc_next_kg_params_t;
151051 +
151052 +/**************************************************************************//**
151053 + @Description Parameters for defining the next engine after a CC node.
151054 + (Must match struct t_FmPcdCcNextEngineParams defined in fm_pcd_ext.h)
151055 +*//***************************************************************************/
151056 +typedef struct ioc_fm_pcd_cc_next_engine_params_t {
151057 + ioc_fm_pcd_engine next_engine; /**< User has to initialize parameters
151058 + according to nextEngine definition */
151059 + union {
151060 + ioc_fm_pcd_cc_next_cc_params_t cc_params; /**< Parameters in case next engine is CC */
151061 + ioc_fm_pcd_cc_next_plcr_params_t plcr_params; /**< Parameters in case next engine is PLCR */
151062 + ioc_fm_pcd_cc_next_enqueue_params_t enqueue_params; /**< Parameters in case next engine is BMI */
151063 + ioc_fm_pcd_cc_next_kg_params_t kg_params; /**< Parameters in case next engine is KG */
151064 +#if DPAA_VERSION >= 11
151065 + ioc_fm_pcd_cc_next_fr_params_t fr_params; /**< Parameters in case next engine is FR */
151066 +#endif /* DPAA_VERSION >= 11 */
151067 + } params; /**< Union used for all the next-engine parameters options */
151068 + void *manip_id; /**< Handle to Manipulation object.
151069 + Relevant if next engine is of type result
151070 + (e_IOC_FM_PCD_PLCR, e_IOC_FM_PCD_KG, e_IOC_FM_PCD_DONE) */
151071 + bool statistics_en; /**< If TRUE, statistics counters are incremented
151072 + for each frame passing through this
151073 + Coarse Classification entry. */
151074 +} ioc_fm_pcd_cc_next_engine_params_t;
151075 +
151076 +/**************************************************************************//**
151077 + @Description Parameters for defining a single CC key
151078 +*//***************************************************************************/
151079 +typedef struct ioc_fm_pcd_cc_key_params_t {
151080 + uint8_t *p_key; /**< pointer to the key of the size defined in key_size */
151081 + uint8_t *p_mask; /**< pointer to the Mask per key of the size defined
151082 + in keySize. p_key and p_mask (if defined) has to be
151083 + of the same size defined in the key_size */
151084 + ioc_fm_pcd_cc_next_engine_params_t cc_next_engine_params;
151085 + /**< parameters for the next for the defined Key in p_key */
151086 +
151087 +} ioc_fm_pcd_cc_key_params_t;
151088 +
151089 +/**************************************************************************//**
151090 + @Description Parameters for defining CC keys parameters
151091 + The driver supports two methods for CC node allocation: dynamic and static.
151092 + Static mode was created in order to prevent runtime alloc/free
151093 + of FMan memory (MURAM), which may cause fragmentation; in this mode,
151094 + the driver automatically allocates the memory according to
151095 + 'max_num_of_keys' parameter. The driver calculates the maximal memory
151096 + size that may be used for this CC-Node taking into consideration
151097 + 'mask_support' and 'statistics_mode' parameters.
151098 + When 'action' = e_IOC_FM_PCD_ACTION_INDEXED_LOOKUP in the extraction
151099 + parameters of this node, 'max_num_of_keys' must be equal to 'num_of_keys'.
151100 + In dynamic mode, 'max_num_of_keys' must be zero. At initialization,
151101 + all required structures are allocated according to 'num_of_keys'
151102 + parameter. During runtime modification, these structures are
151103 + re-allocated according to the updated number of keys.
151104 +
151105 + Please note that 'action' and 'ic_indx_mask' mentioned in the
151106 + specific parameter explanations are passed in the extraction
151107 + parameters of the node (fields of extractccparams.extractnonhdr).
151108 +*//***************************************************************************/
151109 +typedef struct ioc_keys_params_t {
151110 + uint16_t max_num_of_keys;/**< Maximum number of keys that will (ever) be used in this CC-Node;
151111 + A value of zero may be used for dynamic memory allocation. */
151112 + bool mask_support; /**< This parameter is relevant only if a node is initialized with
151113 + action = e_IOC_FM_PCD_ACTION_EXACT_MATCH and max_num_of_keys > 0;
151114 + Should be TRUE to reserve table memory for key masks, even if
151115 + initial keys do not contain masks, or if the node was initialized
151116 + as 'empty' (without keys); this will allow user to add keys with
151117 + masks at runtime. */
151118 + ioc_fm_pcd_cc_stats_mode statistics_mode;/**< Determines the supported statistics mode for all node's keys.
151119 + To enable statistics gathering, statistics should be enabled per
151120 + every key, using 'statistics_en' in next engine parameters structure
151121 + of that key;
151122 + If 'max_num_of_keys' is set, all required structures will be
151123 + preallocated for all keys. */
151124 +#if (DPAA_VERSION >= 11)
151125 + uint16_t frame_length_ranges[IOC_FM_PCD_CC_STATS_MAX_NUM_OF_FLR];
151126 + /**< Relevant only for 'RMON' statistics mode
151127 + (this feature is supported only on B4860 device);
151128 + Holds a list of programmable thresholds. For each received frame,
151129 + its length in bytes is examined against these range thresholds and
151130 + the appropriate counter is incremented by 1. For example, to belong
151131 + to range i, the following should hold:
151132 + range i-1 threshold < frame length <= range i threshold
151133 + Each range threshold must be larger then its preceding range
151134 + threshold. Last range threshold must be 0xFFFF. */
151135 +#endif /* (DPAA_VERSION >= 11) */
151136 + uint16_t num_of_keys; /**< Number of initial keys;
151137 + Note that in case of 'action' = e_IOC_FM_PCD_ACTION_INDEXED_LOOKUP,
151138 + this field should be power-of-2 of the number of bits that are
151139 + set in 'ic_indx_mask'. */
151140 + uint8_t key_size; /**< Size of key - for extraction of type FULL_FIELD, 'key_size' has
151141 + to be the standard size of the selected key; For other extraction
151142 + types, 'key_size' has to be as size of extraction; When 'action' =
151143 + e_IOC_FM_PCD_ACTION_INDEXED_LOOKUP, 'keySize' must be 2. */
151144 + ioc_fm_pcd_cc_key_params_t key_params[IOC_FM_PCD_MAX_NUM_OF_KEYS];
151145 + /**< An array with 'num_of_keys' entries, each entry specifies the
151146 + corresponding key parameters;
151147 + When 'action' = e_IOC_FM_PCD_ACTION_EXACT_MATCH, this value must not
151148 + exceed 255 (IOC_FM_PCD_MAX_NUM_OF_KEYS-1) as the last entry is saved
151149 + for the 'miss' entry. */
151150 + ioc_fm_pcd_cc_next_engine_params_t cc_next_engine_params_for_miss;
151151 + /**< Parameters for defining the next engine when a key is not matched;
151152 + Not relevant if action = e_IOC_FM_PCD_ACTION_INDEXED_LOOKUP. */
151153 +} ioc_keys_params_t;
151154 +
151155 +/**************************************************************************//**
151156 + @Description Parameters for defining a CC node
151157 +*//***************************************************************************/
151158 +typedef struct ioc_fm_pcd_cc_node_params_t {
151159 + ioc_fm_pcd_extract_entry_t extract_cc_params; /**< Extraction parameters */
151160 + ioc_keys_params_t keys_params; /**< Keys definition matching the selected extraction */
151161 + void *id; /**< Output parameter; returns the CC node Id to be used */
151162 +} ioc_fm_pcd_cc_node_params_t;
151163 +
151164 +/**************************************************************************//**
151165 + @Description Parameters for defining a hash table
151166 + (Must match struct t_FmPcdHashTableParams defined in fm_pcd_ext.h)
151167 +*//***************************************************************************/
151168 +typedef struct ioc_fm_pcd_hash_table_params_t {
151169 + uint16_t max_num_of_keys; /**< Maximum Number Of Keys that will (ever) be used in this Hash-table */
151170 + ioc_fm_pcd_cc_stats_mode statistics_mode; /**< If not e_IOC_FM_PCD_CC_STATS_MODE_NONE, the required structures for the
151171 + requested statistics mode will be allocated according to max_num_of_keys. */
151172 + uint8_t kg_hash_shift; /**< KG-Hash-shift as it was configured in the KG-scheme
151173 + that leads to this hash-table. */
151174 + uint16_t hash_res_mask; /**< Mask that will be used on the hash-result;
151175 + The number-of-sets for this hash will be calculated
151176 + as (2^(number of bits set in 'hash_res_mask'));
151177 + The 4 lower bits must be cleared. */
151178 + uint8_t hash_shift; /**< Byte offset from the beginning of the KeyGen hash result to the
151179 + 2-bytes to be used as hash index. */
151180 + uint8_t match_key_size; /**< Size of the exact match keys held by the hash buckets */
151181 +
151182 + ioc_fm_pcd_cc_next_engine_params_t cc_next_engine_params_for_miss;
151183 + /**< Parameters for defining the next engine when a key is not matched */
151184 + void *id;
151185 +} ioc_fm_pcd_hash_table_params_t;
151186 +
151187 +/**************************************************************************//**
151188 + @Description A structure with the arguments for the FM_PCD_HashTableAddKey ioctl() call
151189 +*//***************************************************************************/
151190 +typedef struct ioc_fm_pcd_hash_table_add_key_params_t {
151191 + void *p_hash_tbl;
151192 + uint8_t key_size;
151193 + ioc_fm_pcd_cc_key_params_t key_params;
151194 +} ioc_fm_pcd_hash_table_add_key_params_t;
151195 +
151196 +/**************************************************************************//**
151197 + @Description Parameters for defining a CC tree group.
151198 +
151199 + This structure defines a CC group in terms of NetEnv units
151200 + and the action to be taken in each case. The unit_ids list must
151201 + be given in order from low to high indices.
151202 +
151203 + ioc_fm_pcd_cc_next_engine_params_t is a list of 2^num_of_distinction_units
151204 + structures where each defines the next action to be taken for
151205 + each units combination. for example:
151206 + num_of_distinction_units = 2
151207 + unit_ids = {1,3}
151208 + next_engine_per_entries_in_grp[0] = ioc_fm_pcd_cc_next_engine_params_t for the case that
151209 + unit 1 - not found; unit 3 - not found;
151210 + next_engine_per_entries_in_grp[1] = ioc_fm_pcd_cc_next_engine_params_t for the case that
151211 + unit 1 - not found; unit 3 - found;
151212 + next_engine_per_entries_in_grp[2] = ioc_fm_pcd_cc_next_engine_params_t for the case that
151213 + unit 1 - found; unit 3 - not found;
151214 + next_engine_per_entries_in_grp[3] = ioc_fm_pcd_cc_next_engine_params_t for the case that
151215 + unit 1 - found; unit 3 - found;
151216 +*//***************************************************************************/
151217 +typedef struct ioc_fm_pcd_cc_grp_params_t {
151218 + uint8_t num_of_distinction_units; /**< Up to 4 */
151219 + uint8_t unit_ids [IOC_FM_PCD_MAX_NUM_OF_CC_UNITS];
151220 + /**< Indexes of the units as defined in
151221 + FM_PCD_NetEnvCharacteristicsSet() */
151222 + ioc_fm_pcd_cc_next_engine_params_t next_engine_per_entries_in_grp[IOC_FM_PCD_MAX_NUM_OF_CC_ENTRIES_IN_GRP];
151223 + /**< Maximum entries per group is 16 */
151224 +} ioc_fm_pcd_cc_grp_params_t;
151225 +
151226 +/**************************************************************************//**
151227 + @Description Parameters for defining the CC tree groups
151228 + (Must match struct t_FmPcdCcTreeParams defined in fm_pcd_ext.h)
151229 +*//***************************************************************************/
151230 +typedef struct ioc_fm_pcd_cc_tree_params_t {
151231 + void *net_env_id; /**< Id of the Network Environment as returned
151232 + by FM_PCD_NetEnvCharacteristicsSet() */
151233 + uint8_t num_of_groups; /**< Number of CC groups within the CC tree */
151234 + ioc_fm_pcd_cc_grp_params_t fm_pcd_cc_group_params [IOC_FM_PCD_MAX_NUM_OF_CC_GROUPS];
151235 + /**< Parameters for each group. */
151236 + void *id; /**< Output parameter; Returns the tree Id to be used */
151237 +} ioc_fm_pcd_cc_tree_params_t;
151238 +
151239 +/**************************************************************************//**
151240 + @Description Parameters for defining policer byte rate
151241 +*//***************************************************************************/
151242 +typedef struct ioc_fm_pcd_plcr_byte_rate_mode_param_t {
151243 + ioc_fm_pcd_plcr_frame_length_select frame_length_selection; /**< Frame length selection */
151244 + ioc_fm_pcd_plcr_roll_back_frame_select roll_back_frame_selection; /**< relevant option only e_IOC_FM_PCD_PLCR_L2_FRM_LEN,
151245 + e_IOC_FM_PCD_PLCR_FULL_FRM_LEN */
151246 +} ioc_fm_pcd_plcr_byte_rate_mode_param_t;
151247 +
151248 +/**************************************************************************//**
151249 + @Description Parameters for defining the policer profile (based on
151250 + RFC-2698 or RFC-4115 attributes).
151251 +*//***************************************************************************/
151252 +typedef struct ioc_fm_pcd_plcr_non_passthrough_alg_param_t {
151253 + ioc_fm_pcd_plcr_rate_mode rate_mode; /**< Byte / Packet */
151254 + ioc_fm_pcd_plcr_byte_rate_mode_param_t byte_mode_param; /**< Valid for Byte NULL for Packet */
151255 + uint32_t committed_info_rate; /**< KBits/Sec or Packets/Sec */
151256 + uint32_t committed_burst_size; /**< KBits or Packets */
151257 + uint32_t peak_or_excess_info_rate; /**< KBits/Sec or Packets/Sec */
151258 + uint32_t peak_or_excess_burst_size; /**< KBits or Packets */
151259 +} ioc_fm_pcd_plcr_non_passthrough_alg_param_t;
151260 +
151261 +/**************************************************************************//**
151262 + @Description Parameters for defining the next engine after policer
151263 +*//***************************************************************************/
151264 +typedef union ioc_fm_pcd_plcr_next_engine_params_u {
151265 + ioc_fm_pcd_done_action action; /**< Action - when next engine is BMI (done) */
151266 + void *p_profile; /**< Policer profile handle - used when next engine
151267 + is PLCR, must be a SHARED profile */
151268 + void *p_direct_scheme; /**< Direct scheme select - when next engine is Keygen */
151269 +} ioc_fm_pcd_plcr_next_engine_params_u;
151270 +
151271 +typedef struct ioc_fm_pcd_port_params_t {
151272 + ioc_fm_port_type port_type; /**< Type of port for this profile */
151273 + uint8_t port_id; /**< FM-Port id of port for this profile */
151274 +} ioc_fm_pcd_port_params_t;
151275 +
151276 +/**************************************************************************//**
151277 + @Description Parameters for defining the policer profile entry
151278 + (Must match struct t_FmPcdPlcrProfileParams defined in fm_pcd_ext.h)
151279 +*//***************************************************************************/
151280 +typedef struct ioc_fm_pcd_plcr_profile_params_t {
151281 + bool modify; /**< TRUE to change an existing profile */
151282 + union {
151283 + struct {
151284 + ioc_fm_pcd_profile_type_selection profile_type; /**< Type of policer profile */
151285 + ioc_fm_pcd_port_params_t *p_fm_port; /**< Relevant for per-port profiles only */
151286 + uint16_t relative_profile_id; /**< Profile id - relative to shared group or to port */
151287 + } new_params; /**< Use it when modify = FALSE */
151288 + void *p_profile; /**< A handle to a profile - use it when modify=TRUE */
151289 + } profile_select;
151290 + ioc_fm_pcd_plcr_algorithm_selection alg_selection; /**< Profile Algorithm PASS_THROUGH, RFC_2698, RFC_4115 */
151291 + ioc_fm_pcd_plcr_color_mode color_mode; /**< COLOR_BLIND, COLOR_AWARE */
151292 +
151293 + union {
151294 + ioc_fm_pcd_plcr_color dflt_color; /**< For Color-Blind Pass-Through mode; the policer will re-color
151295 + any incoming packet with the default value. */
151296 + ioc_fm_pcd_plcr_color override; /**< For Color-Aware modes; the profile response to a
151297 + pre-color value of 2'b11. */
151298 + } color;
151299 +
151300 + ioc_fm_pcd_plcr_non_passthrough_alg_param_t non_passthrough_alg_param; /**< RFC2698 or RFC4115 parameters */
151301 +
151302 + ioc_fm_pcd_engine next_engine_on_green; /**< Next engine for green-colored frames */
151303 + ioc_fm_pcd_plcr_next_engine_params_u params_on_green; /**< Next engine parameters for green-colored frames */
151304 +
151305 + ioc_fm_pcd_engine next_engine_on_yellow; /**< Next engine for yellow-colored frames */
151306 + ioc_fm_pcd_plcr_next_engine_params_u params_on_yellow; /**< Next engine parameters for yellow-colored frames */
151307 +
151308 + ioc_fm_pcd_engine next_engine_on_red; /**< Next engine for red-colored frames */
151309 + ioc_fm_pcd_plcr_next_engine_params_u params_on_red; /**< Next engine parameters for red-colored frames */
151310 +
151311 + bool trap_profile_on_flow_A; /**< Obsolete - do not use */
151312 + bool trap_profile_on_flow_B; /**< Obsolete - do not use */
151313 + bool trap_profile_on_flow_C; /**< Obsolete - do not use */
151314 +
151315 + void *id; /**< output parameter; Returns the profile Id to be used */
151316 +} ioc_fm_pcd_plcr_profile_params_t;
151317 +
151318 +/**************************************************************************//**
151319 + @Description A structure for modifying CC tree next engine
151320 +*//***************************************************************************/
151321 +typedef struct ioc_fm_pcd_cc_tree_modify_next_engine_params_t {
151322 + void *id; /**< CC tree Id to be used */
151323 + uint8_t grp_indx; /**< A Group index in the tree */
151324 + uint8_t indx; /**< Entry index in the group defined by grp_index */
151325 + ioc_fm_pcd_cc_next_engine_params_t cc_next_engine_params;
151326 + /**< Parameters for the next for the defined Key in the p_Key */
151327 +} ioc_fm_pcd_cc_tree_modify_next_engine_params_t;
151328 +
151329 +/**************************************************************************//**
151330 + @Description A structure for modifying CC node next engine
151331 +*//***************************************************************************/
151332 +typedef struct ioc_fm_pcd_cc_node_modify_next_engine_params_t {
151333 + void *id; /**< CC node Id to be used */
151334 + uint16_t key_indx; /**< Key index for Next Engine Params modifications;
151335 + NOTE: This parameter is IGNORED for miss-key! */
151336 + uint8_t key_size; /**< Key size of added key */
151337 + ioc_fm_pcd_cc_next_engine_params_t cc_next_engine_params;
151338 + /**< parameters for the next for the defined Key in the p_Key */
151339 +} ioc_fm_pcd_cc_node_modify_next_engine_params_t;
151340 +
151341 +/**************************************************************************//**
151342 + @Description A structure for remove CC node key
151343 +*//***************************************************************************/
151344 +typedef struct ioc_fm_pcd_cc_node_remove_key_params_t {
151345 + void *id; /**< CC node Id to be used */
151346 + uint16_t key_indx; /**< Key index for Next Engine Params modifications;
151347 + NOTE: This parameter is IGNORED for miss-key! */
151348 +} ioc_fm_pcd_cc_node_remove_key_params_t;
151349 +
151350 +/**************************************************************************//**
151351 + @Description A structure for modifying CC node key and next engine
151352 +*//***************************************************************************/
151353 +typedef struct ioc_fm_pcd_cc_node_modify_key_and_next_engine_params_t {
151354 + void *id; /**< CC node Id to be used */
151355 + uint16_t key_indx; /**< Key index for Next Engine Params modifications;
151356 + NOTE: This parameter is IGNORED for miss-key! */
151357 + uint8_t key_size; /**< Key size of added key */
151358 + ioc_fm_pcd_cc_key_params_t key_params; /**< it's array with numOfKeys entries each entry in
151359 + the array of the type ioc_fm_pcd_cc_key_params_t */
151360 +} ioc_fm_pcd_cc_node_modify_key_and_next_engine_params_t;
151361 +
151362 +/**************************************************************************//**
151363 + @Description A structure for modifying CC node key
151364 +*//***************************************************************************/
151365 +typedef struct ioc_fm_pcd_cc_node_modify_key_params_t {
151366 + void *id; /**< CC node Id to be used */
151367 + uint16_t key_indx; /**< Key index for Next Engine Params modifications;
151368 + NOTE: This parameter is IGNORED for miss-key! */
151369 + uint8_t key_size; /**< Key size of added key */
151370 + uint8_t *p_key; /**< Pointer to the key of the size defined in key_size */
151371 + uint8_t *p_mask; /**< Pointer to the Mask per key of the size defined
151372 + in keySize. p_Key and p_Mask (if defined) have to be
151373 + of the same size as defined in the key_size */
151374 +} ioc_fm_pcd_cc_node_modify_key_params_t;
151375 +
151376 +/**************************************************************************//**
151377 + @Description A structure with the arguments for the FM_PCD_HashTableRemoveKey ioctl() call
151378 +*//***************************************************************************/
151379 +typedef struct ioc_fm_pcd_hash_table_remove_key_params_t {
151380 + void *p_hash_tbl; /**< The id of the hash table */
151381 + uint8_t key_size; /**< The size of the key to remove */
151382 + uint8_t *p_key; /**< Pointer to the key to remove */
151383 +} ioc_fm_pcd_hash_table_remove_key_params_t;
151384 +
151385 +/**************************************************************************//**
151386 + @Description Parameters for selecting a location for requested manipulation
151387 +*//***************************************************************************/
151388 +typedef struct ioc_fm_manip_hdr_info_t {
151389 + ioc_net_header_type hdr; /**< Header selection */
151390 + ioc_fm_pcd_hdr_index hdr_index; /**< Relevant only for MPLS, VLAN and tunneled IP. Otherwise should be cleared. */
151391 + bool by_field; /**< TRUE if the location of manipulation is according to some field in the specific header*/
151392 + ioc_fm_pcd_fields_u full_field; /**< Relevant only when by_field = TRUE: Extract field */
151393 +} ioc_fm_manip_hdr_info_t;
151394 +
151395 +/**************************************************************************//**
151396 + @Description Parameters for defining header removal by header type
151397 +*//***************************************************************************/
151398 +typedef struct ioc_fm_pcd_manip_hdr_rmv_by_hdr_params_t {
151399 + ioc_fm_pcd_manip_hdr_rmv_by_hdr_type type; /**< Selection of header removal location */
151400 + union {
151401 +#if ((DPAA_VERSION == 10) && defined(FM_CAPWAP_SUPPORT))
151402 + struct {
151403 + bool include;/**< If FALSE, remove until the specified header (not including the header);
151404 + If TRUE, remove also the specified header. */
151405 + ioc_fm_manip_hdr_info_t hdr_info;
151406 + } from_start_by_hdr; /**< Relevant when type = e_IOC_FM_PCD_MANIP_RMV_BY_HDR_FROM_START */
151407 +#endif /* FM_CAPWAP_SUPPORT */
151408 +#if (DPAA_VERSION >= 11)
151409 + ioc_fm_manip_hdr_info_t hdr_info; /**< Relevant when type = e_FM_PCD_MANIP_RMV_BY_HDR_FROM_START */
151410 +#endif /* (DPAA_VERSION >= 11) */
151411 + ioc_fm_pcd_manip_hdr_rmv_specific_l2 specific_l2;/**< Relevant when type = e_IOC_FM_PCD_MANIP_BY_HDR_SPECIFIC_L2;
151412 + Defines which L2 headers to remove. */
151413 + } u;
151414 +} ioc_fm_pcd_manip_hdr_rmv_by_hdr_params_t;
151415 +
151416 +/**************************************************************************//**
151417 + @Description Parameters for configuring IP fragmentation manipulation
151418 +*//***************************************************************************/
151419 +typedef struct ioc_fm_pcd_manip_frag_ip_params_t {
151420 + uint16_t size_for_fragmentation; /**< If length of the frame is greater than this value,
151421 + IP fragmentation will be executed.*/
151422 +#if DPAA_VERSION == 10
151423 + uint8_t scratch_bpid; /**< Absolute buffer pool id according to BM configuration.*/
151424 +#endif /* DPAA_VERSION == 10 */
151425 + bool sg_bpid_en; /**< Enable a dedicated buffer pool id for the Scatter/Gather buffer allocation;
151426 + If disabled, the Scatter/Gather buffer will be allocated from the same pool as the
151427 + received frame's buffer. */
151428 + uint8_t sg_bpid; /**< Scatter/Gather buffer pool id;
151429 + This parameter is relevant when 'sg_bpid_en=TRUE';
151430 + Same LIODN number is used for these buffers as for the received frames buffers, so buffers
151431 + of this pool need to be allocated in the same memory area as the received buffers.
151432 + If the received buffers arrive from different sources, the Scatter/Gather BP id should be
151433 + mutual to all these sources. */
151434 + ioc_fm_pcd_manip_dont_frag_action dont_frag_action; /**< Dont Fragment Action - If an IP packet is larger
151435 + than MTU and its DF bit is set, then this field will
151436 + determine the action to be taken.*/
151437 +} ioc_fm_pcd_manip_frag_ip_params_t;
151438 +
151439 +/**************************************************************************//**
151440 + @Description Parameters for configuring IP reassembly manipulation.
151441 +
151442 + This is a common structure for both IPv4 and IPv6 reassembly
151443 + manipulation. For reassembly of both IPv4 and IPv6, make sure to
151444 + set the 'hdr' field in ioc_fm_pcd_manip_reassem_params_t to IOC_HEADER_TYPE_IPv6.
151445 +*//***************************************************************************/
151446 +typedef struct ioc_fm_pcd_manip_reassem_ip_params_t {
151447 + uint8_t relative_scheme_id[2]; /**< Partition relative scheme id:
151448 + relativeSchemeId[0] - Relative scheme ID for IPV4 Reassembly manipulation;
151449 + relativeSchemeId[1] - Relative scheme ID for IPV6 Reassembly manipulation;
151450 + NOTE: The following comment is relevant only for FMAN v2 devices:
151451 + Relative scheme ID for IPv4/IPv6 Reassembly manipulation must be smaller than
151452 + the user schemes id to ensure that the reassembly's schemes will be first match.
151453 + The remaining schemes, if defined, should have higher relative scheme ID. */
151454 +#if DPAA_VERSION >= 11
151455 + uint32_t non_consistent_sp_fqid; /**< In case that other fragments of the frame corresponds to different storage
151456 + profile than the opening fragment (Non-Consistent-SP state)
151457 + then one of two possible scenarios occurs:
151458 + if 'nonConsistentSpFqid != 0', the reassembled frame will be enqueued to
151459 + this fqid, otherwise a 'Non Consistent SP' bit will be set in the FD[status].*/
151460 +#else
151461 + uint8_t sg_bpid; /**< Buffer pool id for the S/G frame created by the reassembly process */
151462 +#endif /* DPAA_VERSION >= 11 */
151463 + uint8_t data_mem_id; /**< Memory partition ID for the IPR's external tables structure */
151464 + uint16_t data_liodn_offset; /**< LIODN offset for access the IPR's external tables structure. */
151465 + uint16_t min_frag_size[2]; /**< Minimum fragment size:
151466 + minFragSize[0] - for ipv4, minFragSize[1] - for ipv6 */
151467 + ioc_fm_pcd_manip_reassem_ways_number num_of_frames_per_hash_entry[2];
151468 + /**< Number of frames per hash entry needed for reassembly process:
151469 + numOfFramesPerHashEntry[0] - for ipv4 (max value is e_IOC_FM_PCD_MANIP_EIGHT_WAYS_HASH);
151470 + numOfFramesPerHashEntry[1] - for ipv6 (max value is e_IOC_FM_PCD_MANIP_SIX_WAYS_HASH). */
151471 + uint16_t max_num_frames_in_process;/**< Number of frames which can be processed by Reassembly in the same time;
151472 + Must be power of 2;
151473 + In the case numOfFramesPerHashEntry == e_IOC_FM_PCD_MANIP_FOUR_WAYS_HASH,
151474 + maxNumFramesInProcess has to be in the range of 4 - 512;
151475 + In the case numOfFramesPerHashEntry == e_IOC_FM_PCD_MANIP_EIGHT_WAYS_HASH,
151476 + maxNumFramesInProcess has to be in the range of 8 - 2048. */
151477 + ioc_fm_pcd_manip_reassem_time_out_mode time_out_mode; /**< Expiration delay initialized by Reassembly process */
151478 + uint32_t fqid_for_time_out_frames;/**< FQID in which time out frames will enqueue during Time Out Process */
151479 + uint32_t timeout_threshold_for_reassm_process;
151480 + /**< Represents the time interval in microseconds which defines
151481 + if opened frame (at least one fragment was processed but not all the fragments)is found as too old*/
151482 +} ioc_fm_pcd_manip_reassem_ip_params_t;
151483 +
151484 +/**************************************************************************//**
151485 + @Description Parameters for defining IPSEC manipulation
151486 +*//***************************************************************************/
151487 +typedef struct ioc_fm_pcd_manip_special_offload_ipsec_params_t {
151488 + bool decryption; /**< TRUE if being used in decryption direction;
151489 + FALSE if being used in encryption direction. */
151490 + bool ecn_copy; /**< TRUE to copy the ECN bits from inner/outer to outer/inner
151491 + (direction depends on the 'decryption' field). */
151492 + bool dscp_copy; /**< TRUE to copy the DSCP bits from inner/outer to outer/inner
151493 + (direction depends on the 'decryption' field). */
151494 + bool variable_ip_hdr_len; /**< TRUE for supporting variable IP header length in decryption. */
151495 + bool variable_ip_version; /**< TRUE for supporting both IP version on the same SA in encryption */
151496 + uint8_t outer_ip_hdr_len; /**< If 'variable_ip_version == TRUE' than this field must be set to non-zero value;
151497 + It is specifies the length of the outer IP header that was configured in the
151498 + corresponding SA. */
151499 + uint16_t arw_size; /**< if <> '0' then will perform ARW check for this SA;
151500 + The value must be a multiplication of 16 */
151501 + void *arw_addr; /**< if arwSize <> '0' then this field must be set to non-zero value;
151502 + MUST be allocated from FMAN's MURAM that the post-sec op-port belong
151503 + Must be 4B aligned. Required MURAM size is '(NEXT_POWER_OF_2(arwSize+32))/8+4' Bytes */
151504 +} ioc_fm_pcd_manip_special_offload_ipsec_params_t;
151505 +
151506 +#if (DPAA_VERSION >= 11)
151507 +/**************************************************************************//**
151508 + @Description Parameters for configuring CAPWAP fragmentation manipulation
151509 +
151510 + Restrictions:
151511 + - Maximum number of fragments per frame is 16.
151512 + - Transmit confirmation is not supported.
151513 + - Fragmentation nodes must be set as the last PCD action (i.e. the
151514 + corresponding CC node key must have next engine set to e_FM_PCD_DONE).
151515 + - Only BMan buffers shall be used for frames to be fragmented.
151516 + - NOTE: The following comment is relevant only for FMAN v3 devices: IPF
151517 + does not support VSP. Therefore, on the same port where we have IPF we
151518 + cannot support VSP.
151519 +*//***************************************************************************/
151520 +typedef struct ioc_fm_pcd_manip_frag_capwap_params_t {
151521 + uint16_t size_for_fragmentation; /**< If length of the frame is greater than this value,
151522 + CAPWAP fragmentation will be executed.*/
151523 + bool sg_bpid_en; /**< Enable a dedicated buffer pool id for the Scatter/Gather buffer allocation;
151524 + If disabled, the Scatter/Gather buffer will be allocated from the same pool as the
151525 + received frame's buffer. */
151526 + uint8_t sg_bpid; /**< Scatter/Gather buffer pool id;
151527 + This parameters is relevant when 'sgBpidEn=TRUE';
151528 + Same LIODN number is used for these buffers as for the received frames buffers, so buffers
151529 + of this pool need to be allocated in the same memory area as the received buffers.
151530 + If the received buffers arrive from different sources, the Scatter/Gather BP id should be
151531 + mutual to all these sources. */
151532 + bool compress_mode_en; /**< CAPWAP Header Options Compress Enable mode;
151533 + When this mode is enabled then only the first fragment include the CAPWAP header options
151534 + field (if user provides it in the input frame) and all other fragments exclude the CAPWAP
151535 + options field (CAPWAP header is updated accordingly).*/
151536 +} ioc_fm_pcd_manip_frag_capwap_params_t;
151537 +
151538 +/**************************************************************************//**
151539 + @Description Parameters for configuring CAPWAP reassembly manipulation.
151540 +
151541 + Restrictions:
151542 + - Application must define one scheme to catch the reassembled frames.
151543 + - Maximum number of fragments per frame is 16.
151544 +
151545 +*//***************************************************************************/
151546 +typedef struct ioc_fm_pcd_manip_reassem_capwap_params_t {
151547 + uint8_t relative_scheme_id; /**< Partition relative scheme id;
151548 + NOTE: this id must be smaller than the user schemes id to ensure that the reassembly scheme will be first match;
151549 + Rest schemes, if defined, should have higher relative scheme ID. */
151550 + uint8_t data_mem_id; /**< Memory partition ID for the IPR's external tables structure */
151551 + uint16_t data_liodn_offset; /**< LIODN offset for access the IPR's external tables structure. */
151552 + uint16_t max_reassembled_frame_length;/**< The maximum CAPWAP reassembled frame length in bytes;
151553 + If maxReassembledFrameLength == 0, any successful reassembled frame length is
151554 + considered as a valid length;
151555 + if maxReassembledFrameLength > 0, a successful reassembled frame which its length
151556 + exceeds this value is considered as an error frame (FD status[CRE] bit is set). */
151557 + ioc_fm_pcd_manip_reassem_ways_number num_of_frames_per_hash_entry;
151558 + /**< Number of frames per hash entry needed for reassembly process */
151559 + uint16_t max_num_frames_in_process; /**< Number of frames which can be processed by reassembly in the same time;
151560 + Must be power of 2;
151561 + In the case numOfFramesPerHashEntry == e_FM_PCD_MANIP_FOUR_WAYS_HASH,
151562 + maxNumFramesInProcess has to be in the range of 4 - 512;
151563 + In the case numOfFramesPerHashEntry == e_FM_PCD_MANIP_EIGHT_WAYS_HASH,
151564 + maxNumFramesInProcess has to be in the range of 8 - 2048. */
151565 + ioc_fm_pcd_manip_reassem_time_out_mode time_out_mode; /**< Expiration delay initialized by Reassembly process */
151566 + uint32_t fqid_for_time_out_frames; /**< FQID in which time out frames will enqueue during Time Out Process;
151567 + Recommended value for this field is 0; in this way timed-out frames will be discarded */
151568 + uint32_t timeout_threshold_for_reassm_process;
151569 + /**< Represents the time interval in microseconds which defines
151570 + if opened frame (at least one fragment was processed but not all the fragments)is found as too old*/
151571 +} ioc_fm_pcd_manip_reassem_capwap_params_t;
151572 +
151573 +/**************************************************************************//**
151574 + @Description structure for defining CAPWAP manipulation
151575 +*//***************************************************************************/
151576 +typedef struct ioc_fm_pcd_manip_special_offload_capwap_params_t {
151577 + bool dtls; /**< TRUE if continue to SEC DTLS encryption */
151578 + ioc_fm_pcd_manip_hdr_qos_src qos_src; /**< TODO */
151579 +} ioc_fm_pcd_manip_special_offload_capwap_params_t;
151580 +
151581 +#endif /* (DPAA_VERSION >= 11) */
151582 +
151583 +/**************************************************************************//**
151584 + @Description Parameters for defining special offload manipulation
151585 +*//***************************************************************************/
151586 +typedef struct ioc_fm_pcd_manip_special_offload_params_t {
151587 + ioc_fm_pcd_manip_special_offload_type type; /**< Type of special offload manipulation */
151588 + union
151589 + {
151590 + ioc_fm_pcd_manip_special_offload_ipsec_params_t ipsec; /**< Parameters for IPSec; Relevant when
151591 + type = e_IOC_FM_PCD_MANIP_SPECIAL_OFFLOAD_IPSEC */
151592 +
151593 +#if (DPAA_VERSION >= 11)
151594 + ioc_fm_pcd_manip_special_offload_capwap_params_t capwap; /**< Parameters for CAPWAP; Relevant when
151595 + type = e_FM_PCD_MANIP_SPECIAL_OFFLOAD_CAPWAP */
151596 +#endif /* (DPAA_VERSION >= 11) */
151597 + } u;
151598 +} ioc_fm_pcd_manip_special_offload_params_t;
151599 +
151600 +/**************************************************************************//**
151601 + @Description Parameters for defining generic removal manipulation
151602 +*//***************************************************************************/
151603 +typedef struct ioc_fm_pcd_manip_hdr_rmv_generic_params_t {
151604 + uint8_t offset; /**< Offset from beginning of header to the start
151605 + location of the removal */
151606 + uint8_t size; /**< Size of removed section */
151607 +} ioc_fm_pcd_manip_hdr_rmv_generic_params_t;
151608 +
151609 +/**************************************************************************//**
151610 + @Description Parameters for defining insertion manipulation
151611 +*//***************************************************************************/
151612 +typedef struct ioc_fm_pcd_manip_hdr_insrt_t {
151613 + uint8_t size; /**< size of inserted section */
151614 + uint8_t *p_data; /**< data to be inserted */
151615 +} ioc_fm_pcd_manip_hdr_insrt_t;
151616 +
151617 +/**************************************************************************//**
151618 + @Description Parameters for defining generic insertion manipulation
151619 +*//***************************************************************************/
151620 +typedef struct ioc_fm_pcd_manip_hdr_insrt_generic_params_t {
151621 + uint8_t offset; /**< Offset from beginning of header to the start
151622 + location of the insertion */
151623 + uint8_t size; /**< Size of inserted section */
151624 + bool replace; /**< TRUE to override (replace) existing data at
151625 + 'offset', FALSE to insert */
151626 + uint8_t *p_data; /**< Pointer to data to be inserted */
151627 +} ioc_fm_pcd_manip_hdr_insrt_generic_params_t;
151628 +
151629 +/**************************************************************************//**
151630 + @Description Parameters for defining header manipulation VLAN DSCP To Vpri translation
151631 +*//***************************************************************************/
151632 +typedef struct ioc_fm_pcd_manip_hdr_field_update_vlan_dscp_to_vpri_t {
151633 + uint8_t dscp_to_vpri_table[IOC_FM_PCD_MANIP_DSCP_TO_VLAN_TRANS];
151634 + /**< A table of VPri values for each DSCP value;
151635 + The index is the D_SCP value (0-0x3F) and the
151636 + value is the corresponding VPRI (0-15). */
151637 + uint8_t vpri_def_val; /**< 0-7, Relevant only if if update_type =
151638 + e_IOC_FM_PCD_MANIP_HDR_FIELD_UPDATE_DSCP_TO_VLAN,
151639 + this field is the Q Tag default value if the
151640 + IP header is not found. */
151641 +} ioc_fm_pcd_manip_hdr_field_update_vlan_dscp_to_vpri_t;
151642 +
151643 +/**************************************************************************//**
151644 + @Description Parameters for defining header manipulation VLAN fields updates
151645 +*//***************************************************************************/
151646 +typedef struct ioc_fm_pcd_manip_hdr_field_update_vlan_t {
151647 + ioc_fm_pcd_manip_hdr_field_update_vlan update_type; /**< Selects VLAN update type */
151648 + union {
151649 + uint8_t vpri; /**< 0-7, Relevant only if If update_type =
151650 + e_IOC_FM_PCD_MANIP_HDR_FIELD_UPDATE_VLAN_PRI, this
151651 + is the new VLAN pri. */
151652 + ioc_fm_pcd_manip_hdr_field_update_vlan_dscp_to_vpri_t dscp_to_vpri;
151653 + /**< Parameters structure, Relevant only if update_type =
151654 + e_IOC_FM_PCD_MANIP_HDR_FIELD_UPDATE_DSCP_TO_VLAN. */
151655 + } u;
151656 +} ioc_fm_pcd_manip_hdr_field_update_vlan_t;
151657 +
151658 +/**************************************************************************//**
151659 + @Description Parameters for defining header manipulation IPV4 fields updates
151660 +*//***************************************************************************/
151661 +typedef struct ioc_fm_pcd_manip_hdr_field_update_ipv4_t {
151662 + ioc_ipv4_hdr_manip_update_flags_t valid_updates; /**< ORed flag, selecting the required updates */
151663 + uint8_t tos; /**< 8 bit New TOS; Relevant if valid_updates contains
151664 + IOC_HDR_MANIP_IPV4_TOS */
151665 + uint16_t id; /**< 16 bit New IP ID; Relevant only if valid_updates
151666 + contains IOC_HDR_MANIP_IPV4_ID */
151667 + uint32_t src; /**< 32 bit New IP SRC; Relevant only if valid_updates
151668 + contains IOC_HDR_MANIP_IPV4_SRC */
151669 + uint32_t dst; /**< 32 bit New IP DST; Relevant only if valid_updates
151670 + contains IOC_HDR_MANIP_IPV4_DST */
151671 +} ioc_fm_pcd_manip_hdr_field_update_ipv4_t;
151672 +
151673 +/**************************************************************************//**
151674 + @Description Parameters for defining header manipulation IPV6 fields updates
151675 +*//***************************************************************************/
151676 +typedef struct ioc_fm_pcd_manip_hdr_field_update_ipv6_t {
151677 + ioc_ipv6_hdr_manip_update_flags_t valid_updates; /**< ORed flag, selecting the required updates */
151678 + uint8_t traffic_class; /**< 8 bit New Traffic Class; Relevant if valid_updates contains
151679 + IOC_HDR_MANIP_IPV6_TC */
151680 + uint8_t src[IOC_NET_HEADER_FIELD_IPv6_ADDR_SIZE];
151681 + /**< 16 byte new IP SRC; Relevant only if valid_updates
151682 + contains IOC_HDR_MANIP_IPV6_SRC */
151683 + uint8_t dst[IOC_NET_HEADER_FIELD_IPv6_ADDR_SIZE];
151684 + /**< 16 byte new IP DST; Relevant only if valid_updates
151685 + contains IOC_HDR_MANIP_IPV6_DST */
151686 +} ioc_fm_pcd_manip_hdr_field_update_ipv6_t;
151687 +
151688 +/**************************************************************************//**
151689 + @Description Parameters for defining header manipulation TCP/UDP fields updates
151690 +*//***************************************************************************/
151691 +typedef struct ioc_fm_pcd_manip_hdr_field_update_tcp_udp_t {
151692 + ioc_tcp_udp_hdr_manip_update_flags_t valid_updates; /**< ORed flag, selecting the required updates */
151693 + uint16_t src; /**< 16 bit New TCP/UDP SRC; Relevant only if valid_updates
151694 + contains IOC_HDR_MANIP_TCP_UDP_SRC */
151695 + uint16_t dst; /**< 16 bit New TCP/UDP DST; Relevant only if valid_updates
151696 + contains IOC_HDR_MANIP_TCP_UDP_DST */
151697 +} ioc_fm_pcd_manip_hdr_field_update_tcp_udp_t;
151698 +
151699 +/**************************************************************************//**
151700 + @Description Parameters for defining header manipulation fields updates
151701 +*//***************************************************************************/
151702 +typedef struct ioc_fm_pcd_manip_hdr_field_update_params_t {
151703 + ioc_fm_pcd_manip_hdr_field_update_type type; /**< Type of header field update manipulation */
151704 + union {
151705 + ioc_fm_pcd_manip_hdr_field_update_vlan_t vlan; /**< Parameters for VLAN update. Relevant when
151706 + type = e_IOC_FM_PCD_MANIP_HDR_FIELD_UPDATE_VLAN */
151707 + ioc_fm_pcd_manip_hdr_field_update_ipv4_t ipv4; /**< Parameters for IPv4 update. Relevant when
151708 + type = e_IOC_FM_PCD_MANIP_HDR_FIELD_UPDATE_IPV4 */
151709 + ioc_fm_pcd_manip_hdr_field_update_ipv6_t ipv6; /**< Parameters for IPv6 update. Relevant when
151710 + type = e_IOC_FM_PCD_MANIP_HDR_FIELD_UPDATE_IPV6 */
151711 + ioc_fm_pcd_manip_hdr_field_update_tcp_udp_t tcp_udp;/**< Parameters for TCP/UDP update. Relevant when
151712 + type = e_IOC_FM_PCD_MANIP_HDR_FIELD_UPDATE_TCP_UDP */
151713 + } u;
151714 +} ioc_fm_pcd_manip_hdr_field_update_params_t;
151715 +
151716 +/**************************************************************************//**
151717 + @Description Parameters for defining custom header manipulation for IP replacement
151718 +*//***************************************************************************/
151719 +typedef struct ioc_fm_pcd_manip_hdr_custom_ip_hdr_replace_t {
151720 + ioc_fm_pcd_manip_hdr_custom_ip_replace replace_type; /**< Selects replace update type */
151721 + bool dec_ttl_hl; /**< Decrement TTL (IPV4) or Hop limit (IPV6) by 1 */
151722 + bool update_ipv4_id; /**< Relevant when replace_type =
151723 + e_IOC_FM_PCD_MANIP_HDR_CUSTOM_REPLACE_IPV6_BY_IPV4 */
151724 + uint16_t id; /**< 16 bit New IP ID; Relevant only if
151725 + update_ipv4_id = TRUE */
151726 + uint8_t hdr_size; /**< The size of the new IP header */
151727 + uint8_t hdr[IOC_FM_PCD_MANIP_MAX_HDR_SIZE];
151728 + /**< The new IP header */
151729 +} ioc_fm_pcd_manip_hdr_custom_ip_hdr_replace_t;
151730 +
151731 +/**************************************************************************//**
151732 + @Description Parameters for defining custom header manipulation
151733 +*//***************************************************************************/
151734 +typedef struct ioc_fm_pcd_manip_hdr_custom_params_t {
151735 + ioc_fm_pcd_manip_hdr_custom_type type; /**< Type of header field update manipulation */
151736 + union {
151737 + ioc_fm_pcd_manip_hdr_custom_ip_hdr_replace_t ip_hdr_replace;
151738 + /**< Parameters IP header replacement */
151739 + } u;
151740 +} ioc_fm_pcd_manip_hdr_custom_params_t;
151741 +
151742 +/**************************************************************************//**
151743 + @Description Parameters for defining specific L2 insertion manipulation
151744 +*//***************************************************************************/
151745 +typedef struct ioc_fm_pcd_manip_hdr_insrt_specific_l2_params_t {
151746 + ioc_fm_pcd_manip_hdr_insrt_specific_l2 specific_l2; /**< Selects which L2 headers to insert */
151747 + bool update; /**< TRUE to update MPLS header */
151748 + uint8_t size; /**< size of inserted section */
151749 + uint8_t *p_data; /**< data to be inserted */
151750 +} ioc_fm_pcd_manip_hdr_insrt_specific_l2_params_t;
151751 +
151752 +#if (DPAA_VERSION >= 11)
151753 +/**************************************************************************//**
151754 + @Description Parameters for defining IP insertion manipulation
151755 +*//***************************************************************************/
151756 +typedef struct ioc_fm_pcd_manip_hdr_insrt_ip_params_t {
151757 + bool calc_l4_checksum; /**< Calculate L4 checksum. */
151758 + ioc_fm_pcd_manip_hdr_qos_mapping_mode mapping_mode; /**< TODO */
151759 + uint8_t last_pid_offset; /**< the offset of the last Protocol within
151760 + the inserted header */
151761 + uint16_t id; /**< 16 bit New IP ID */
151762 + bool dont_frag_overwrite;
151763 + /**< IPv4 only. DF is overwritten with the hash-result next-to-last byte.
151764 + * This byte is configured to be overwritten when RPD is set. */
151765 + uint8_t last_dst_offset;
151766 + /**< IPv6 only. if routing extension exist, user should set the offset of the destination address
151767 + * in order to calculate UDP checksum pseudo header;
151768 + * Otherwise set it to '0'. */
151769 + ioc_fm_pcd_manip_hdr_insrt_t insrt; /**< size and data to be inserted. */
151770 +} ioc_fm_pcd_manip_hdr_insrt_ip_params_t;
151771 +#endif /* (DPAA_VERSION >= 11) */
151772 +
151773 +/**************************************************************************//**
151774 + @Description Parameters for defining header insertion manipulation by header type
151775 +*//***************************************************************************/
151776 +typedef struct ioc_fm_pcd_manip_hdr_insrt_by_hdr_params_t {
151777 + ioc_fm_pcd_manip_hdr_insrt_by_hdr_type type; /**< Selects manipulation type */
151778 + union {
151779 + ioc_fm_pcd_manip_hdr_insrt_specific_l2_params_t specific_l2_params;
151780 + /**< Used when type = e_IOC_FM_PCD_MANIP_INSRT_BY_HDR_SPECIFIC_L2:
151781 + Selects which L2 headers to remove */
151782 +#if (DPAA_VERSION >= 11)
151783 + ioc_fm_pcd_manip_hdr_insrt_ip_params_t ip_params; /**< Used when type = e_FM_PCD_MANIP_INSRT_BY_HDR_IP */
151784 + ioc_fm_pcd_manip_hdr_insrt_t insrt; /**< Used when type is one of e_FM_PCD_MANIP_INSRT_BY_HDR_UDP,
151785 + e_FM_PCD_MANIP_INSRT_BY_HDR_UDP_LITE, or
151786 + e_FM_PCD_MANIP_INSRT_BY_HDR_CAPWAP */
151787 +#endif /* (DPAA_VERSION >= 11) */
151788 + } u;
151789 +} ioc_fm_pcd_manip_hdr_insrt_by_hdr_params_t;
151790 +
151791 +/**************************************************************************//**
151792 + @Description Parameters for defining header insertion manipulation
151793 +*//***************************************************************************/
151794 +typedef struct ioc_fm_pcd_manip_hdr_insrt_params_t {
151795 + ioc_fm_pcd_manip_hdr_insrt_type type; /**< Type of insertion manipulation */
151796 + union {
151797 + ioc_fm_pcd_manip_hdr_insrt_by_hdr_params_t by_hdr; /**< Parameters for defining header insertion manipulation by header type,
151798 + relevant if 'type' = e_IOC_FM_PCD_MANIP_INSRT_BY_HDR */
151799 + ioc_fm_pcd_manip_hdr_insrt_generic_params_t generic;/**< Parameters for defining generic header insertion manipulation,
151800 + relevant if type = e_IOC_FM_PCD_MANIP_INSRT_GENERIC */
151801 +#if (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10))
151802 + ioc_fm_pcd_manip_hdr_insrt_by_template_params_t by_template;
151803 + /**< Parameters for defining header insertion manipulation by template,
151804 + relevant if 'type' = e_IOC_FM_PCD_MANIP_INSRT_BY_TEMPLATE */
151805 +#endif /* FM_CAPWAP_SUPPORT */
151806 + } u;
151807 +} ioc_fm_pcd_manip_hdr_insrt_params_t;
151808 +
151809 +/**************************************************************************//**
151810 + @Description Parameters for defining header removal manipulation
151811 +*//***************************************************************************/
151812 +typedef struct ioc_fm_pcd_manip_hdr_rmv_params_t {
151813 + ioc_fm_pcd_manip_hdr_rmv_type type; /**< Type of header removal manipulation */
151814 + union {
151815 + ioc_fm_pcd_manip_hdr_rmv_by_hdr_params_t by_hdr; /**< Parameters for defining header removal manipulation by header type,
151816 + relevant if type = e_IOC_FM_PCD_MANIP_RMV_BY_HDR */
151817 + ioc_fm_pcd_manip_hdr_rmv_generic_params_t generic; /**< Parameters for defining generic header removal manipulation,
151818 + relevant if type = e_IOC_FM_PCD_MANIP_RMV_GENERIC */
151819 + } u;
151820 +} ioc_fm_pcd_manip_hdr_rmv_params_t;
151821 +
151822 +/**************************************************************************//**
151823 + @Description Parameters for defining header manipulation node
151824 +*//***************************************************************************/
151825 +typedef struct ioc_fm_pcd_manip_hdr_params_t {
151826 + bool rmv; /**< TRUE, to define removal manipulation */
151827 + ioc_fm_pcd_manip_hdr_rmv_params_t rmv_params; /**< Parameters for removal manipulation, relevant if 'rmv' = TRUE */
151828 +
151829 + bool insrt; /**< TRUE, to define insertion manipulation */
151830 + ioc_fm_pcd_manip_hdr_insrt_params_t insrt_params; /**< Parameters for insertion manipulation, relevant if 'insrt' = TRUE */
151831 +
151832 + bool field_update; /**< TRUE, to define field update manipulation */
151833 + ioc_fm_pcd_manip_hdr_field_update_params_t field_update_params; /**< Parameters for field update manipulation, relevant if 'fieldUpdate' = TRUE */
151834 +
151835 + bool custom; /**< TRUE, to define custom manipulation */
151836 + ioc_fm_pcd_manip_hdr_custom_params_t custom_params; /**< Parameters for custom manipulation, relevant if 'custom' = TRUE */
151837 +
151838 + bool dont_parse_after_manip;/**< FALSE to activate the parser a second time after
151839 + completing the manipulation on the frame */
151840 +} ioc_fm_pcd_manip_hdr_params_t;
151841 +
151842 +
151843 +/**************************************************************************//**
151844 + @Description structure for defining fragmentation manipulation
151845 +*//***************************************************************************/
151846 +typedef struct ioc_fm_pcd_manip_frag_params_t {
151847 + ioc_net_header_type hdr; /**< Header selection */
151848 + union {
151849 +#if (DPAA_VERSION >= 11)
151850 + ioc_fm_pcd_manip_frag_capwap_params_t capwap_frag; /**< Parameters for defining CAPWAP fragmentation,
151851 + relevant if 'hdr' = HEADER_TYPE_CAPWAP */
151852 +#endif /* (DPAA_VERSION >= 11) */
151853 + ioc_fm_pcd_manip_frag_ip_params_t ip_frag; /**< Parameters for defining IP fragmentation,
151854 + relevant if 'hdr' = HEADER_TYPE_Ipv4 or HEADER_TYPE_Ipv6 */
151855 + } u;
151856 +} ioc_fm_pcd_manip_frag_params_t;
151857 +
151858 +/**************************************************************************//**
151859 + @Description structure for defining reassemble manipulation
151860 +*//***************************************************************************/
151861 +typedef struct ioc_fm_pcd_manip_reassem_params_t {
151862 + ioc_net_header_type hdr; /**< Header selection */
151863 + union {
151864 +#if (DPAA_VERSION >= 11)
151865 + ioc_fm_pcd_manip_reassem_capwap_params_t capwap_reassem; /**< Parameters for defining CAPWAP reassembly,
151866 + relevant if 'hdr' = HEADER_TYPE_CAPWAP */
151867 +#endif /* (DPAA_VERSION >= 11) */
151868 + ioc_fm_pcd_manip_reassem_ip_params_t ip_reassem; /**< Parameters for defining IP reassembly,
151869 + relevant if 'hdr' = HEADER_TYPE_Ipv4 or HEADER_TYPE_Ipv6 */
151870 + } u;
151871 +} ioc_fm_pcd_manip_reassem_params_t;
151872 +
151873 +/**************************************************************************//**
151874 + @Description Parameters for defining a manipulation node
151875 +*//***************************************************************************/
151876 +typedef struct ioc_fm_pcd_manip_params_t {
151877 + ioc_fm_pcd_manip_type type; /**< Selects type of manipulation node */
151878 + union {
151879 + ioc_fm_pcd_manip_hdr_params_t hdr; /**< Parameters for defining header manipulation node */
151880 + ioc_fm_pcd_manip_reassem_params_t reassem;/**< Parameters for defining reassembly manipulation node */
151881 + ioc_fm_pcd_manip_frag_params_t frag; /**< Parameters for defining fragmentation manipulation node */
151882 + ioc_fm_pcd_manip_special_offload_params_t special_offload;/**< Parameters for defining special offload manipulation node */
151883 + } u;
151884 + void *p_next_manip;/**< Handle to another (previously defined) manipulation node;
151885 + Allows concatenation of manipulation actions
151886 + This parameter is optional and may be NULL. */
151887 +#if (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10))
151888 + bool frag_or_reasm;/**< TRUE, if defined fragmentation/reassembly manipulation */
151889 + ioc_fm_pcd_manip_frag_or_reasm_params_t frag_or_reasm_params;/**< Parameters for fragmentation/reassembly manipulation,
151890 + relevant if frag_or_reasm = TRUE */
151891 +#endif /* FM_CAPWAP_SUPPORT */
151892 + void *id;
151893 +} ioc_fm_pcd_manip_params_t;
151894 +
151895 +/**************************************************************************//**
151896 + @Description Structure for retrieving IP reassembly statistics
151897 +*//***************************************************************************/
151898 +typedef struct ioc_fm_pcd_manip_reassem_ip_stats_t {
151899 + /* common counters for both IPv4 and IPv6 */
151900 + uint32_t timeout; /**< Counts the number of TimeOut occurrences */
151901 + uint32_t rfd_pool_busy; /**< Counts the number of failed attempts to allocate
151902 + a Reassembly Frame Descriptor */
151903 + uint32_t internal_buffer_busy; /**< Counts the number of times an internal buffer busy occurred */
151904 + uint32_t external_buffer_busy; /**< Counts the number of times external buffer busy occurred */
151905 + uint32_t sg_fragments; /**< Counts the number of Scatter/Gather fragments */
151906 + uint32_t dma_semaphore_depletion; /**< Counts the number of failed attempts to allocate a DMA semaphore */
151907 +#if (DPAA_VERSION >= 11)
151908 + uint32_t non_consistent_sp; /**< Counts the number of Non Consistent Storage Profile events for
151909 + successfully reassembled frames */
151910 +#endif /* (DPAA_VERSION >= 11) */
151911 +struct {
151912 + uint32_t successfully_reassembled; /**< Counts the number of successfully reassembled frames */
151913 + uint32_t valid_fragments; /**< Counts the total number of valid fragments that
151914 + have been processed for all frames */
151915 + uint32_t processed_fragments; /**< Counts the number of processed fragments
151916 + (valid and error fragments) for all frames */
151917 + uint32_t malformed_fragments; /**< Counts the number of malformed fragments processed for all frames */
151918 + uint32_t discarded_fragments; /**< Counts the number of fragments discarded by the reassembly process */
151919 + uint32_t auto_learn_busy; /**< Counts the number of times a busy condition occurs when attempting
151920 + to access an IP-Reassembly Automatic Learning Hash set */
151921 + uint32_t more_than16fragments; /**< Counts the fragment occurrences in which the number of fragments-per-frame
151922 + exceeds 16 */
151923 + } specific_hdr_statistics[2]; /**< slot '0' is for IPv4, slot '1' is for IPv6 */
151924 +} ioc_fm_pcd_manip_reassem_ip_stats_t;
151925 +
151926 +/**************************************************************************//**
151927 + @Description Structure for retrieving IP fragmentation statistics
151928 +*//***************************************************************************/
151929 +typedef struct ioc_fm_pcd_manip_frag_ip_stats_t {
151930 + uint32_t total_frames; /**< Number of frames that passed through the manipulation node */
151931 + uint32_t fragmented_frames; /**< Number of frames that were fragmented */
151932 + uint32_t generated_fragments; /**< Number of fragments that were generated */
151933 +} ioc_fm_pcd_manip_frag_ip_stats_t;
151934 +
151935 +#if (DPAA_VERSION >= 11)
151936 +/**************************************************************************//**
151937 + @Description Structure for retrieving CAPWAP reassembly statistics
151938 +*//***************************************************************************/
151939 +typedef struct ioc_fm_pcd_manip_reassem_capwap_stats_t {
151940 + uint32_t timeout; /**< Counts the number of timeout occurrences */
151941 + uint32_t rfd_pool_busy; /**< Counts the number of failed attempts to allocate
151942 + a Reassembly Frame Descriptor */
151943 + uint32_t internal_buffer_busy; /**< Counts the number of times an internal buffer busy occurred */
151944 + uint32_t external_buffer_busy; /**< Counts the number of times external buffer busy occurred */
151945 + uint32_t sg_fragments; /**< Counts the number of Scatter/Gather fragments */
151946 + uint32_t dma_semaphore_depletion; /**< Counts the number of failed attempts to allocate a DMA semaphore */
151947 + uint32_t successfully_reassembled; /**< Counts the number of successfully reassembled frames */
151948 + uint32_t valid_fragments; /**< Counts the total number of valid fragments that
151949 + have been processed for all frames */
151950 + uint32_t processed_fragments; /**< Counts the number of processed fragments
151951 + (valid and error fragments) for all frames */
151952 + uint32_t malformed_fragments; /**< Counts the number of malformed fragments processed for all frames */
151953 + uint32_t autoLearn_busy; /**< Counts the number of times a busy condition occurs when attempting
151954 + to access an Reassembly Automatic Learning Hash set */
151955 + uint32_t discarded_fragments; /**< Counts the number of fragments discarded by the reassembly process */
151956 + uint32_t more_than16fragments; /**< Counts the fragment occurrences in which the number of fragments-per-frame
151957 + exceeds 16 */
151958 + uint32_t exceed_max_reassembly_frame_len;/**< ounts the number of times that a successful reassembled frame
151959 + length exceeds MaxReassembledFrameLength value */
151960 +} ioc_fm_pcd_manip_reassem_capwap_stats_t;
151961 +
151962 +/**************************************************************************//**
151963 + @Description Structure for retrieving CAPWAP fragmentation statistics
151964 +*//***************************************************************************/
151965 +typedef struct ioc_fm_pcd_manip_frag_capwap_stats_t {
151966 + uint32_t total_frames; /**< Number of frames that passed through the manipulation node */
151967 + uint32_t fragmented_frames; /**< Number of frames that were fragmented */
151968 + uint32_t generated_fragments; /**< Number of fragments that were generated */
151969 +#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
151970 + uint8_t sg_allocation_failure; /**< Number of allocation failure of s/g buffers */
151971 +#endif /* (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0)) */
151972 +} ioc_fm_pcd_manip_frag_capwap_stats_t;
151973 +#endif /* (DPAA_VERSION >= 11) */
151974 +
151975 +/**************************************************************************//**
151976 + @Description Structure for retrieving reassembly statistics
151977 +*//***************************************************************************/
151978 +typedef struct ioc_fm_pcd_manip_reassem_stats_t {
151979 + union {
151980 + ioc_fm_pcd_manip_reassem_ip_stats_t ip_reassem; /**< Structure for IP reassembly statistics */
151981 +#if (DPAA_VERSION >= 11)
151982 + ioc_fm_pcd_manip_reassem_capwap_stats_t capwap_reassem; /**< Structure for CAPWAP reassembly statistics */
151983 +#endif /* (DPAA_VERSION >= 11) */
151984 + } u;
151985 +} ioc_fm_pcd_manip_reassem_stats_t;
151986 +
151987 +/**************************************************************************//**
151988 + @Description structure for retrieving fragmentation statistics
151989 +*//***************************************************************************/
151990 +typedef struct ioc_fm_pcd_manip_frag_stats_t {
151991 + union {
151992 + ioc_fm_pcd_manip_frag_ip_stats_t ip_frag; /**< Structure for IP fragmentation statistics */
151993 +#if (DPAA_VERSION >= 11)
151994 + ioc_fm_pcd_manip_frag_capwap_stats_t capwap_frag; /**< Structure for CAPWAP fragmentation statistics */
151995 +#endif /* (DPAA_VERSION >= 11) */
151996 + } u;
151997 +} ioc_fm_pcd_manip_frag_stats_t;
151998 +
151999 +/**************************************************************************//**
152000 + @Description structure for defining manipulation statistics
152001 +*//***************************************************************************/
152002 +typedef struct ioc_fm_pcd_manip_stats_t {
152003 + union {
152004 + ioc_fm_pcd_manip_reassem_stats_t reassem; /**< Structure for reassembly statistics */
152005 + ioc_fm_pcd_manip_frag_stats_t frag; /**< Structure for fragmentation statistics */
152006 + } u;
152007 +} ioc_fm_pcd_manip_stats_t;
152008 +
152009 +/**************************************************************************//**
152010 + @Description Parameters for acquiring manipulation statistics
152011 +*//***************************************************************************/
152012 +typedef struct ioc_fm_pcd_manip_get_stats_t {
152013 + void *id;
152014 + ioc_fm_pcd_manip_stats_t stats;
152015 +} ioc_fm_pcd_manip_get_stats_t;
152016 +
152017 +#if DPAA_VERSION >= 11
152018 +/**************************************************************************//**
152019 + @Description Parameters for defining frame replicator group and its members
152020 +*//***************************************************************************/
152021 +typedef struct ioc_fm_pcd_frm_replic_group_params_t {
152022 + uint8_t max_num_of_entries; /**< Maximal number of members in the group - must be at least two */
152023 + uint8_t num_of_entries; /**< Number of members in the group - must be at least 1 */
152024 + ioc_fm_pcd_cc_next_engine_params_t next_engine_params[IOC_FM_PCD_FRM_REPLIC_MAX_NUM_OF_ENTRIES];
152025 + /**< Array of members' parameters */
152026 + void *id;
152027 +} ioc_fm_pcd_frm_replic_group_params_t;
152028 +
152029 +typedef struct ioc_fm_pcd_frm_replic_member_t {
152030 + void *h_replic_group;
152031 + uint16_t member_index;
152032 +} ioc_fm_pcd_frm_replic_member_t;
152033 +
152034 +typedef struct ioc_fm_pcd_frm_replic_member_params_t {
152035 + ioc_fm_pcd_frm_replic_member_t member;
152036 + ioc_fm_pcd_cc_next_engine_params_t next_engine_params;
152037 +} ioc_fm_pcd_frm_replic_member_params_t;
152038 +#endif /* DPAA_VERSION >= 11 */
152039 +
152040 +
152041 +typedef struct ioc_fm_pcd_cc_key_statistics_t {
152042 + uint32_t byte_count; /**< This counter reflects byte count of frames that
152043 + were matched by this key. */
152044 + uint32_t frame_count; /**< This counter reflects count of frames that
152045 + were matched by this key. */
152046 +#if (DPAA_VERSION >= 11)
152047 + uint32_t frame_length_range_count[IOC_FM_PCD_CC_STATS_MAX_NUM_OF_FLR];
152048 + /**< These counters reflect how many frames matched
152049 + this key in 'RMON' statistics mode:
152050 + Each counter holds the number of frames of a
152051 + specific frames length range, according to the
152052 + ranges provided at initialization. */
152053 +#endif /* (DPAA_VERSION >= 11) */
152054 +} ioc_fm_pcd_cc_key_statistics_t;
152055 +
152056 +
152057 +typedef struct ioc_fm_pcd_cc_tbl_get_stats_t {
152058 + void *id;
152059 + uint16_t key_index;
152060 + ioc_fm_pcd_cc_key_statistics_t statistics;
152061 +} ioc_fm_pcd_cc_tbl_get_stats_t;
152062 +
152063 +/**************************************************************************//**
152064 + @Function FM_PCD_MatchTableGetKeyStatistics
152065 +
152066 + @Description This routine may be used to get statistics counters of specific key
152067 + in a CC Node.
152068 +
152069 + If 'e_FM_PCD_CC_STATS_MODE_FRAME' and
152070 + 'e_FM_PCD_CC_STATS_MODE_BYTE_AND_FRAME' were set for this node,
152071 + these counters reflect how many frames passed that were matched
152072 + this key; The total frames count will be returned in the counter
152073 + of the first range (as only one frame length range was defined).
152074 + If 'e_FM_PCD_CC_STATS_MODE_RMON' was set for this node, the total
152075 + frame count will be separated to frame length counters, based on
152076 + provided frame length ranges.
152077 +
152078 + @Param[in] h_CcNode A handle to the node
152079 + @Param[in] keyIndex Key index for adding
152080 + @Param[out] p_KeyStatistics Key statistics counters
152081 +
152082 + @Return The specific key statistics.
152083 +
152084 + @Cautions Allowed only following FM_PCD_MatchTableSet().
152085 +*//***************************************************************************/
152086 +
152087 +#if defined(CONFIG_COMPAT)
152088 +#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)
152089 +#endif
152090 +#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)
152091 +
152092 +/**************************************************************************//**
152093 + @Function FM_PCD_MatchTableGetMissStatistics
152094 +
152095 + @Description This routine may be used to get statistics counters of miss entry
152096 + in a CC Node.
152097 +
152098 + If 'e_FM_PCD_CC_STATS_MODE_FRAME' and
152099 + 'e_FM_PCD_CC_STATS_MODE_BYTE_AND_FRAME' were set for this node,
152100 + these counters reflect how many frames were not matched to any
152101 + existing key and therefore passed through the miss entry; The
152102 + total frames count will be returned in the counter of the
152103 + first range (as only one frame length range was defined).
152104 +
152105 + @Param[in] h_CcNode A handle to the node
152106 + @Param[out] p_MissStatistics Statistics counters for 'miss'
152107 +
152108 + @Return E_OK on success; Error code otherwise.
152109 +
152110 + @Cautions Allowed only following FM_PCD_MatchTableSet().
152111 +*//***************************************************************************/
152112 +
152113 +#if defined(CONFIG_COMPAT)
152114 +#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)
152115 +#endif
152116 +#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)
152117 +
152118 +/**************************************************************************//**
152119 + @Function FM_PCD_HashTableGetMissStatistics
152120 +
152121 + @Description This routine may be used to get statistics counters of 'miss'
152122 + entry of the a hash table.
152123 +
152124 + If 'e_FM_PCD_CC_STATS_MODE_FRAME' and
152125 + 'e_FM_PCD_CC_STATS_MODE_BYTE_AND_FRAME' were set for this node,
152126 + these counters reflect how many frames were not matched to any
152127 + existing key and therefore passed through the miss entry;
152128 +
152129 + @Param[in] h_HashTbl A handle to a hash table
152130 + @Param[out] p_MissStatistics Statistics counters for 'miss'
152131 +
152132 + @Return E_OK on success; Error code otherwise.
152133 +
152134 + @Cautions Allowed only following FM_PCD_HashTableSet().
152135 +*//***************************************************************************/
152136 +
152137 +#if defined(CONFIG_COMPAT)
152138 +#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)
152139 +#endif
152140 +#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)
152141 +
152142 +
152143 +/**************************************************************************//**
152144 + @Function FM_PCD_NetEnvCharacteristicsSet
152145 +
152146 + @Description Define a set of Network Environment Characteristics.
152147 +
152148 + When setting an environment it is important to understand its
152149 + application. It is not meant to describe the flows that will run
152150 + on the ports using this environment, but what the user means TO DO
152151 + with the PCD mechanisms in order to parse-classify-distribute those
152152 + frames.
152153 + By specifying a distinction unit, the user means it would use that option
152154 + for distinction between frames at either a KeyGen scheme or a coarse
152155 + classification action descriptor. Using interchangeable headers to define a
152156 + unit means that the user is indifferent to which of the interchangeable
152157 + headers is present in the frame, and wants the distinction to be based
152158 + on the presence of either one of them.
152159 +
152160 + Depending on context, there are limitations to the use of environments. A
152161 + port using the PCD functionality is bound to an environment. Some or even
152162 + all ports may share an environment but also an environment per port is
152163 + possible. When initializing a scheme, a classification plan group (see below),
152164 + or a coarse classification tree, one of the initialized environments must be
152165 + stated and related to. When a port is bound to a scheme, a classification
152166 + plan group, or a coarse classification tree, it MUST be bound to the same
152167 + environment.
152168 +
152169 + The different PCD modules, may relate (for flows definition) ONLY on
152170 + distinction units as defined by their environment. When initializing a
152171 + scheme for example, it may not choose to select IPV4 as a match for
152172 + recognizing flows unless it was defined in the relating environment. In
152173 + fact, to guide the user through the configuration of the PCD, each module's
152174 + characterization in terms of flows is not done using protocol names, but using
152175 + environment indexes.
152176 +
152177 + In terms of HW implementation, the list of distinction units sets the LCV vectors
152178 + and later used for match vector, classification plan vectors and coarse classification
152179 + indexing.
152180 +
152181 + @Param[in,out] ioc_fm_pcd_net_env_params_t A structure defining the distiction units for this configuration.
152182 +
152183 + @Return 0 on success; Error code otherwise.
152184 +*//***************************************************************************/
152185 +#if defined(CONFIG_COMPAT)
152186 +#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)
152187 +#endif
152188 +#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)
152189 +
152190 +/**************************************************************************//**
152191 + @Function FM_PCD_NetEnvCharacteristicsDelete
152192 +
152193 + @Description Deletes a set of Network Environment Charecteristics.
152194 +
152195 + @Param[in] ioc_fm_obj_t - The id of a Network Environment object.
152196 +
152197 + @Return 0 on success; Error code otherwise.
152198 +*//***************************************************************************/
152199 +#if defined(CONFIG_COMPAT)
152200 +#define FM_PCD_IOC_NET_ENV_CHARACTERISTICS_DELETE_COMPAT _IOW(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(21), ioc_compat_fm_obj_t)
152201 +#endif
152202 +#define FM_PCD_IOC_NET_ENV_CHARACTERISTICS_DELETE _IOW(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(21), ioc_fm_obj_t)
152203 +
152204 +/**************************************************************************//**
152205 + @Function FM_PCD_KgSchemeSet
152206 +
152207 + @Description Initializing or modifying and enabling a scheme for the KeyGen.
152208 + This routine should be called for adding or modifying a scheme.
152209 + When a scheme needs modifying, the API requires that it will be
152210 + rewritten. In such a case 'modify' should be TRUE. If the
152211 + routine is called for a valid scheme and 'modify' is FALSE,
152212 + it will return error.
152213 +
152214 + @Param[in,out] ioc_fm_pcd_kg_scheme_params_t A structure of parameters for defining the scheme
152215 +
152216 + @Return 0 on success; Error code otherwise.
152217 +*//***************************************************************************/
152218 +#if defined(CONFIG_COMPAT)
152219 +#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)
152220 +#endif
152221 +#define FM_PCD_IOC_KG_SCHEME_SET _IOWR(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(24), ioc_fm_pcd_kg_scheme_params_t)
152222 +
152223 +/**************************************************************************//**
152224 + @Function FM_PCD_KgSchemeDelete
152225 +
152226 + @Description Deleting an initialized scheme.
152227 +
152228 + @Param[in] ioc_fm_obj_t scheme id as initalized by application at FM_PCD_IOC_KG_SET_SCHEME
152229 +
152230 + @Return 0 on success; Error code otherwise.
152231 +*//***************************************************************************/
152232 +#if defined(CONFIG_COMPAT)
152233 +#define FM_PCD_IOC_KG_SCHEME_DELETE_COMPAT _IOW(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(25), ioc_compat_fm_obj_t)
152234 +#endif
152235 +#define FM_PCD_IOC_KG_SCHEME_DELETE _IOW(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(25), ioc_fm_obj_t)
152236 +
152237 +/**************************************************************************//**
152238 + @Function FM_PCD_CcRootBuild
152239 +
152240 + @Description This routine must be called to define a complete coarse
152241 + classification tree. This is the way to define coarse
152242 + classification to a certain flow - the KeyGen schemes
152243 + may point only to trees defined in this way.
152244 +
152245 + @Param[in,out] ioc_fm_pcd_cc_tree_params_t A structure of parameters to define the tree.
152246 +
152247 + @Return 0 on success; Error code otherwise.
152248 +*//***************************************************************************/
152249 +#if defined(CONFIG_COMPAT)
152250 +#define FM_PCD_IOC_CC_ROOT_BUILD_COMPAT _IOWR(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(26), compat_uptr_t)
152251 +#endif
152252 +#define FM_PCD_IOC_CC_ROOT_BUILD _IOWR(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(26), void *) /* workaround ...*/
152253 +
152254 +/**************************************************************************//**
152255 + @Function FM_PCD_CcRootDelete
152256 +
152257 + @Description Deleting a built tree.
152258 +
152259 + @Param[in] ioc_fm_obj_t - The id of a CC tree.
152260 +*//***************************************************************************/
152261 +#if defined(CONFIG_COMPAT)
152262 +#define FM_PCD_IOC_CC_ROOT_DELETE_COMPAT _IOW(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(27), ioc_compat_fm_obj_t)
152263 +#endif
152264 +#define FM_PCD_IOC_CC_ROOT_DELETE _IOW(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(27), ioc_fm_obj_t)
152265 +
152266 +/**************************************************************************//**
152267 + @Function FM_PCD_MatchTableSet
152268 +
152269 + @Description This routine should be called for each CC (coarse classification)
152270 + node. The whole CC tree should be built bottom up so that each
152271 + node points to already defined nodes. p_NodeId returns the node
152272 + Id to be used by other nodes.
152273 +
152274 + @Param[in,out] ioc_fm_pcd_cc_node_params_t A structure for defining the CC node params
152275 +
152276 + @Return 0 on success; Error code otherwise.
152277 +*//***************************************************************************/
152278 +#if defined(CONFIG_COMPAT)
152279 +#define FM_PCD_IOC_MATCH_TABLE_SET_COMPAT _IOWR(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(28), compat_uptr_t)
152280 +#endif
152281 +#define FM_PCD_IOC_MATCH_TABLE_SET _IOWR(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(28), void *) /* workaround ...*/
152282 +
152283 +/**************************************************************************//**
152284 + @Function FM_PCD_MatchTableDelete
152285 +
152286 + @Description Deleting a built node.
152287 +
152288 + @Param[in] ioc_fm_obj_t - The id of a CC node.
152289 +
152290 + @Return 0 on success; Error code otherwise.
152291 +*//***************************************************************************/
152292 +#if defined(CONFIG_COMPAT)
152293 +#define FM_PCD_IOC_MATCH_TABLE_DELETE_COMPAT _IOW(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(29), ioc_compat_fm_obj_t)
152294 +#endif
152295 +#define FM_PCD_IOC_MATCH_TABLE_DELETE _IOW(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(29), ioc_fm_obj_t)
152296 +
152297 +/**************************************************************************//**
152298 + @Function FM_PCD_CcRootModifyNextEngine
152299 +
152300 + @Description Modify the Next Engine Parameters in the entry of the tree.
152301 +
152302 + @Param[in] ioc_fm_pcd_cc_tree_modify_next_engine_params_t - Pointer to a structure with the relevant parameters
152303 +
152304 + @Return 0 on success; Error code otherwise.
152305 +
152306 + @Cautions Allowed only following FM_PCD_CcRootBuild().
152307 +*//***************************************************************************/
152308 +#if defined(CONFIG_COMPAT)
152309 +#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)
152310 +#endif
152311 +#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)
152312 +
152313 +/**************************************************************************//**
152314 + @Function FM_PCD_MatchTableModifyNextEngine
152315 +
152316 + @Description Modify the Next Engine Parameters in the relevant key entry of the node.
152317 +
152318 + @Param[in] ioc_fm_pcd_cc_node_modify_next_engine_params_t A pointer to a structure with the relevant parameters
152319 +
152320 + @Return 0 on success; Error code otherwise.
152321 +
152322 + @Cautions Allowed only following FM_PCD_MatchTableSet().
152323 +*//***************************************************************************/
152324 +#if defined(CONFIG_COMPAT)
152325 +#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)
152326 +#endif
152327 +#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)
152328 +
152329 +/**************************************************************************//**
152330 + @Function FM_PCD_MatchTableModifyMissNextEngine
152331 +
152332 + @Description Modify the Next Engine Parameters of the Miss key case of the node.
152333 +
152334 + @Param[in] ioc_fm_pcd_cc_node_modify_next_engine_params_t - Pointer to a structure with the relevant parameters
152335 +
152336 + @Return 0 on success; Error code otherwise.
152337 +
152338 + @Cautions Allowed only following FM_PCD_MatchTableSet().
152339 +*//***************************************************************************/
152340 +#if defined(CONFIG_COMPAT)
152341 +#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)
152342 +#endif
152343 +#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)
152344 +
152345 +/**************************************************************************//**
152346 + @Function FM_PCD_MatchTableRemoveKey
152347 +
152348 + @Description Remove the key (including next engine parameters of this key)
152349 + defined by the index of the relevant node.
152350 +
152351 + @Param[in] ioc_fm_pcd_cc_node_remove_key_params_t A pointer to a structure with the relevant parameters
152352 +
152353 + @Return 0 on success; Error code otherwise.
152354 +
152355 + @Cautions Allowed only after FM_PCD_MatchTableSet() has been called for this
152356 + node and for all of the nodes that lead to it.
152357 +*//***************************************************************************/
152358 +#if defined(CONFIG_COMPAT)
152359 +#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)
152360 +#endif
152361 +#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)
152362 +
152363 +/**************************************************************************//**
152364 + @Function FM_PCD_MatchTableAddKey
152365 +
152366 + @Description Add the key (including next engine parameters of this key in the
152367 + index defined by the keyIndex. Note that 'FM_PCD_LAST_KEY_INDEX'
152368 + may be used when the user doesn't care about the position of the
152369 + key in the table - in that case, the key will be automatically
152370 + added by the driver in the last available entry.
152371 +
152372 + @Param[in] ioc_fm_pcd_cc_node_modify_key_and_next_engine_params_t A pointer to a structure with the relevant parameters
152373 +
152374 + @Return 0 on success; Error code otherwise.
152375 +
152376 + @Cautions Allowed only after FM_PCD_MatchTableSet() has been called for this
152377 + node and for all of the nodes that lead to it.
152378 +*//***************************************************************************/
152379 +#if defined(CONFIG_COMPAT)
152380 +#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)
152381 +#endif
152382 +#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)
152383 +
152384 +/**************************************************************************//**
152385 + @Function FM_PCD_MatchTableModifyKeyAndNextEngine
152386 +
152387 + @Description Modify the key and Next Engine Parameters of this key in the index defined by key_index.
152388 +
152389 + @Param[in] ioc_fm_pcd_cc_node_modify_key_and_next_engine_params_t A pointer to a structure with the relevant parameters
152390 +
152391 + @Return 0 on success; Error code otherwise.
152392 +
152393 + @Cautions Allowed only following FM_PCD_MatchTableSet() not only of the relevnt node but also
152394 + the node that points to this node
152395 +*//***************************************************************************/
152396 +#if defined(CONFIG_COMPAT)
152397 +#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)
152398 +#endif
152399 +#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)
152400 +
152401 +/**************************************************************************//**
152402 + @Function FM_PCD_MatchTableModifyKey
152403 +
152404 + @Description Modify the key at the index defined by key_index.
152405 +
152406 + @Param[in] ioc_fm_pcd_cc_node_modify_key_params_t - Pointer to a structure with the relevant parameters
152407 +
152408 + @Return 0 on success; Error code otherwise.
152409 +
152410 + @Cautions Allowed only after FM_PCD_MatchTableSet() has been called for this
152411 + node and for all of the nodes that lead to it.
152412 +*//***************************************************************************/
152413 +#if defined(CONFIG_COMPAT)
152414 +#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)
152415 +#endif
152416 +#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)
152417 +
152418 +/**************************************************************************//**
152419 + @Function FM_PCD_HashTableSet
152420 +
152421 + @Description This routine initializes a hash table structure.
152422 + KeyGen hash result determines the hash bucket.
152423 + Next, KeyGen key is compared against all keys of this
152424 + bucket (exact match).
152425 + Number of sets (number of buckets) of the hash equals to the
152426 + number of 1-s in 'hash_res_mask' in the provided parameters.
152427 + Number of hash table ways is then calculated by dividing
152428 + 'max_num_of_keys' equally between the hash sets. This is the maximal
152429 + number of keys that a hash bucket may hold.
152430 + The hash table is initialized empty and keys may be
152431 + added to it following the initialization. Keys masks are not
152432 + supported in current hash table implementation.
152433 + The initialized hash table can be integrated as a node in a
152434 + CC tree.
152435 +
152436 + @Param[in,out] ioc_fm_pcd_hash_table_params_t - Pointer to a structure with the relevant parameters
152437 +
152438 + @Return 0 on success; Error code otherwise.
152439 +*//***************************************************************************/
152440 +#if defined(CONFIG_COMPAT)
152441 +#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)
152442 +#endif
152443 +#define FM_PCD_IOC_HASH_TABLE_SET _IOWR(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(37), ioc_fm_pcd_hash_table_params_t)
152444 +
152445 +
152446 +/**************************************************************************//**
152447 + @Function FM_PCD_HashTableDelete
152448 +
152449 + @Description This routine deletes the provided hash table and released all
152450 + its allocated resources.
152451 +
152452 + @Param[in] ioc_fm_obj_t - The ID of a hash table.
152453 +
152454 + @Return 0 on success; Error code otherwise.
152455 +
152456 + @Cautions Allowed only following FM_PCD_HashTableSet().
152457 +*//***************************************************************************/
152458 +#if defined(CONFIG_COMPAT)
152459 +#define FM_PCD_IOC_HASH_TABLE_DELETE_COMPAT _IOW(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(37), ioc_compat_fm_obj_t)
152460 +#endif
152461 +#define FM_PCD_IOC_HASH_TABLE_DELETE _IOW(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(37), ioc_fm_obj_t)
152462 +
152463 +/**************************************************************************//**
152464 + @Function FM_PCD_HashTableAddKey
152465 +
152466 + @Description This routine adds the provided key (including next engine
152467 + parameters of this key) to the hash table.
152468 + The key is added as the last key of the bucket that it is
152469 + mapped to.
152470 +
152471 + @Param[in] ioc_fm_pcd_hash_table_add_key_params_t - Pointer to a structure with the relevant parameters
152472 +
152473 + @Return 0 on success; error code otherwise.
152474 +
152475 + @Cautions Allowed only following FM_PCD_HashTableSet().
152476 +*//***************************************************************************/
152477 +#if defined(CONFIG_COMPAT)
152478 +#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)
152479 +#endif
152480 +#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)
152481 +
152482 +/**************************************************************************//**
152483 + @Function FM_PCD_HashTableRemoveKey
152484 +
152485 + @Description This routine removes the requested key (including next engine
152486 + parameters of this key) from the hash table.
152487 +
152488 + @Param[in] ioc_fm_pcd_hash_table_remove_key_params_t - Pointer to a structure with the relevant parameters
152489 +
152490 + @Return 0 on success; Error code otherwise.
152491 +
152492 + @Cautions Allowed only following FM_PCD_HashTableSet().
152493 +*//***************************************************************************/
152494 +#if defined(CONFIG_COMPAT)
152495 +#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)
152496 +#endif
152497 +#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)
152498 +
152499 +/**************************************************************************//**
152500 + @Function FM_PCD_PlcrProfileSet
152501 +
152502 + @Description Sets a profile entry in the policer profile table.
152503 + The routine overrides any existing value.
152504 +
152505 + @Param[in,out] ioc_fm_pcd_plcr_profile_params_t A structure of parameters for defining a
152506 + policer profile entry.
152507 +
152508 + @Return 0 on success; Error code otherwise.
152509 +*//***************************************************************************/
152510 +#if defined(CONFIG_COMPAT)
152511 +#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)
152512 +#endif
152513 +#define FM_PCD_IOC_PLCR_PROFILE_SET _IOWR(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(41), ioc_fm_pcd_plcr_profile_params_t)
152514 +
152515 +/**************************************************************************//**
152516 + @Function FM_PCD_PlcrProfileDelete
152517 +
152518 + @Description Delete a profile entry in the policer profile table.
152519 + The routine set entry to invalid.
152520 +
152521 + @Param[in] ioc_fm_obj_t The id of a policer profile.
152522 +
152523 + @Return 0 on success; Error code otherwise.
152524 +*//***************************************************************************/
152525 +#if defined(CONFIG_COMPAT)
152526 +#define FM_PCD_IOC_PLCR_PROFILE_DELETE_COMPAT _IOW(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(41), ioc_compat_fm_obj_t)
152527 +#endif
152528 +#define FM_PCD_IOC_PLCR_PROFILE_DELETE _IOW(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(41), ioc_fm_obj_t)
152529 +
152530 +/**************************************************************************//**
152531 + @Function FM_PCD_ManipNodeSet
152532 +
152533 + @Description This routine should be called for defining a manipulation
152534 + node. A manipulation node must be defined before the CC node
152535 + that precedes it.
152536 +
152537 + @Param[in] ioc_fm_pcd_manip_params_t - A structure of parameters defining the manipulation
152538 +
152539 + @Return A handle to the initialized object on success; NULL code otherwise.
152540 +*//***************************************************************************/
152541 +#if defined(CONFIG_COMPAT)
152542 +#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)
152543 +#endif
152544 +#define FM_PCD_IOC_MANIP_NODE_SET _IOWR(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(43), ioc_fm_pcd_manip_params_t)
152545 +
152546 +/**************************************************************************//**
152547 + @Function FM_PCD_ManipNodeReplace
152548 +
152549 + @Description Change existing manipulation node to be according to new requirement.
152550 + (Here, it's implemented as a variant of the same IOCTL as for
152551 + FM_PCD_ManipNodeSet(), and one that when called, the 'id' member
152552 + in its 'ioc_fm_pcd_manip_params_t' argument is set to contain
152553 + the manip node's handle)
152554 +
152555 + @Param[in] ioc_fm_pcd_manip_params_t - A structure of parameters defining the manipulation
152556 +
152557 + @Return 0 on success; error code otherwise.
152558 +
152559 + @Cautions Allowed only following FM_PCD_ManipNodeSet().
152560 +*//***************************************************************************/
152561 +#if defined(CONFIG_COMPAT)
152562 +#define FM_PCD_IOC_MANIP_NODE_REPLACE_COMPAT FM_PCD_IOC_MANIP_NODE_SET_COMPAT
152563 +#endif
152564 +#define FM_PCD_IOC_MANIP_NODE_REPLACE FM_PCD_IOC_MANIP_NODE_SET
152565 +
152566 +/**************************************************************************//**
152567 + @Function FM_PCD_ManipNodeDelete
152568 +
152569 + @Description Delete an existing manipulation node.
152570 +
152571 + @Param[in] ioc_fm_obj_t The id of the manipulation node to delete.
152572 +
152573 + @Return 0 on success; error code otherwise.
152574 +
152575 + @Cautions Allowed only following FM_PCD_ManipNodeSet().
152576 +*//***************************************************************************/
152577 +#if defined(CONFIG_COMPAT)
152578 +#define FM_PCD_IOC_MANIP_NODE_DELETE_COMPAT _IOW(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(44), ioc_compat_fm_obj_t)
152579 +#endif
152580 +#define FM_PCD_IOC_MANIP_NODE_DELETE _IOW(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(44), ioc_fm_obj_t)
152581 +
152582 +/**************************************************************************//**
152583 + @Function FM_PCD_ManipGetStatistics
152584 +
152585 + @Description Retrieve the manipulation statistics.
152586 +
152587 + @Param[in] h_ManipNode A handle to a manipulation node.
152588 + @Param[out] p_FmPcdManipStats A structure for retrieving the manipulation statistics
152589 +
152590 + @Return E_OK on success; Error code otherwise.
152591 +
152592 + @Cautions Allowed only following FM_PCD_ManipNodeSet().
152593 +*//***************************************************************************/
152594 +#if defined(CONFIG_COMPAT)
152595 +#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)
152596 +#endif
152597 +#define FM_PCD_IOC_MANIP_GET_STATS _IOWR(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(50), ioc_fm_pcd_manip_get_stats_t)
152598 +
152599 +/**************************************************************************//**
152600 +@Function FM_PCD_SetAdvancedOffloadSupport
152601 +
152602 +@Description This routine must be called in order to support the following features:
152603 + IP-fragmentation, IP-reassembly, IPsec, Header-manipulation, frame-replicator.
152604 +
152605 +@Param[in] h_FmPcd FM PCD module descriptor.
152606 +
152607 +@Return 0 on success; error code otherwise.
152608 +
152609 +@Cautions Allowed only when PCD is disabled.
152610 +*//***************************************************************************/
152611 +#define FM_PCD_IOC_SET_ADVANCED_OFFLOAD_SUPPORT _IO(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(45))
152612 +
152613 +#if (DPAA_VERSION >= 11)
152614 +/**************************************************************************//**
152615 + @Function FM_PCD_FrmReplicSetGroup
152616 +
152617 + @Description Initialize a Frame Replicator group.
152618 +
152619 + @Param[in] h_FmPcd FM PCD module descriptor.
152620 + @Param[in] p_FrmReplicGroupParam A structure of parameters for the initialization of
152621 + the frame replicator group.
152622 +
152623 + @Return A handle to the initialized object on success; NULL code otherwise.
152624 +
152625 + @Cautions Allowed only following FM_PCD_Init().
152626 +*//***************************************************************************/
152627 +#if defined(CONFIG_COMPAT)
152628 +#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)
152629 +#endif
152630 +#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)
152631 +
152632 +/**************************************************************************//**
152633 + @Function FM_PCD_FrmReplicDeleteGroup
152634 +
152635 + @Description Delete a Frame Replicator group.
152636 +
152637 + @Param[in] h_FrmReplicGroup A handle to the frame replicator group.
152638 +
152639 + @Return E_OK on success; Error code otherwise.
152640 +
152641 + @Cautions Allowed only following FM_PCD_FrmReplicSetGroup().
152642 +*//***************************************************************************/
152643 +#if defined(CONFIG_COMPAT)
152644 +#define FM_PCD_IOC_FRM_REPLIC_GROUP_DELETE_COMPAT _IOWR(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(47), ioc_compat_fm_obj_t)
152645 +#endif
152646 +#define FM_PCD_IOC_FRM_REPLIC_GROUP_DELETE _IOWR(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(47), ioc_fm_obj_t)
152647 +
152648 +/**************************************************************************//**
152649 + @Function FM_PCD_FrmReplicAddMember
152650 +
152651 + @Description Add the member in the index defined by the memberIndex.
152652 +
152653 + @Param[in] h_FrmReplicGroup A handle to the frame replicator group.
152654 + @Param[in] memberIndex member index for adding.
152655 + @Param[in] p_MemberParams A pointer to the new member parameters.
152656 +
152657 + @Return E_OK on success; Error code otherwise.
152658 +
152659 + @Cautions Allowed only following FM_PCD_FrmReplicSetGroup() of this group.
152660 +*//***************************************************************************/
152661 +#if defined(CONFIG_COMPAT)
152662 +#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)
152663 +#endif
152664 +#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)
152665 +
152666 +/**************************************************************************//**
152667 + @Function FM_PCD_FrmReplicRemoveMember
152668 +
152669 + @Description Remove the member defined by the index from the relevant group.
152670 +
152671 + @Param[in] h_FrmReplicGroup A handle to the frame replicator group.
152672 + @Param[in] memberIndex member index for removing.
152673 +
152674 + @Return E_OK on success; Error code otherwise.
152675 +
152676 + @Cautions Allowed only following FM_PCD_FrmReplicSetGroup() of this group.
152677 +*//***************************************************************************/
152678 +#if defined(CONFIG_COMPAT)
152679 +#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)
152680 +#endif
152681 +#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)
152682 +
152683 +#endif
152684 +
152685 +#if (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10))
152686 +/**************************************************************************//**
152687 + @Function FM_PCD_StatisticsSetNode
152688 +
152689 + @Description This routine should be called for defining a statistics node.
152690 +
152691 + @Param[in,out] ioc_fm_pcd_stats_params_t A structure of parameters defining the statistics
152692 +
152693 + @Return 0 on success; Error code otherwise.
152694 +*//***************************************************************************/
152695 +#if defined(CONFIG_COMPAT)
152696 +#define FM_PCD_IOC_STATISTICS_SET_NODE_COMPAT _IOWR(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(45), void *)
152697 +#endif
152698 +#define FM_PCD_IOC_STATISTICS_SET_NODE _IOWR(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(45), void *)
152699 +
152700 +#endif /* FM_CAPWAP_SUPPORT */
152701 +
152702 +#ifdef NCSW_BACKWARD_COMPATIBLE_API
152703 +#if defined(CONFIG_COMPAT)
152704 +#define FM_PCD_IOC_SET_NET_ENV_CHARACTERISTICS_COMPAT \
152705 + FM_PCD_IOC_NET_ENV_CHARACTERISTICS_SET_COMPAT
152706 +#define FM_PCD_IOC_DELETE_NET_ENV_CHARACTERISTICS_COMPAT \
152707 + FM_PCD_IOC_NET_ENV_CHARACTERISTICS_DELETE_COMPAT
152708 +#define FM_PCD_IOC_KG_SET_SCHEME_COMPAT FM_PCD_IOC_KG_SCHEME_SET_COMPAT
152709 +#define FM_PCD_IOC_KG_DEL_SCHEME_COMPAT FM_PCD_IOC_KG_SCHEME_DELETE_COMPAT
152710 +#define FM_PCD_IOC_CC_BUILD_TREE_COMPAT FM_PCD_IOC_CC_ROOT_BUILD_COMPAT
152711 +#define FM_PCD_IOC_CC_DELETE_TREE_COMPAT FM_PCD_IOC_CC_ROOT_DELETE_COMPAT
152712 +#define FM_PCD_IOC_CC_DELETE_NODE_COMPAT FM_PCD_IOC_MATCH_TABLE_DELETE_COMPAT
152713 +#define FM_PCD_IOC_CC_TREE_MODIFY_NEXT_ENGINE_COMPAT \
152714 + FM_PCD_IOC_CC_ROOT_MODIFY_NEXT_ENGINE_COMPAT
152715 +#define FM_PCD_IOC_CC_NODE_MODIFY_NEXT_ENGINE_COMPAT \
152716 + FM_PCD_IOC_MATCH_TABLE_MODIFY_NEXT_ENGINE_COMPAT
152717 +#define FM_PCD_IOC_CC_NODE_MODIFY_MISS_NEXT_ENGINE_COMPAT \
152718 + FM_PCD_IOC_MATCH_TABLE_MODIFY_MISS_NEXT_ENGINE_COMPAT
152719 +#define FM_PCD_IOC_CC_NODE_REMOVE_KEY_COMPAT FM_PCD_IOC_MATCH_TABLE_REMOVE_KEY_COMPAT
152720 +#define FM_PCD_IOC_CC_NODE_ADD_KEY_COMPAT FM_PCD_IOC_MATCH_TABLE_ADD_KEY_COMPAT
152721 +#define FM_PCD_IOC_CC_NODE_MODIFY_KEY_AND_NEXT_ENGINE_COMPAT \
152722 + FM_PCD_IOC_MATCH_TABLE_MODIFY_KEY_AND_NEXT_ENGINE_COMPAT
152723 +#define FM_PCD_IOC_CC_NODE_MODIFY_KEY_COMPAT FM_PCD_IOC_MATCH_TABLE_MODIFY_KEY_COMPAT
152724 +#define FM_PCD_IOC_PLCR_SET_PROFILE_COMPAT FM_PCD_IOC_PLCR_PROFILE_SET_COMPAT
152725 +#define FM_PCD_IOC_PLCR_DEL_PROFILE_COMPAT FM_PCD_IOC_PLCR_PROFILE_DELETE_COMPAT
152726 +#define FM_PCD_IOC_MANIP_SET_NODE_COMPAT FM_PCD_IOC_MANIP_NODE_SET_COMPAT
152727 +#define FM_PCD_IOC_MANIP_DELETE_NODE_COMPAT FM_PCD_IOC_MANIP_NODE_DELETE_COMPAT
152728 +#endif
152729 +#define FM_PCD_IOC_SET_NET_ENV_CHARACTERISTICS FM_PCD_IOC_NET_ENV_CHARACTERISTICS_SET
152730 +#define FM_PCD_IOC_DELETE_NET_ENV_CHARACTERISTICS \
152731 + FM_PCD_IOC_NET_ENV_CHARACTERISTICS_DELETE
152732 +#define FM_PCD_IOC_KG_SET_SCHEME FM_PCD_IOC_KG_SCHEME_SET
152733 +#define FM_PCD_IOC_KG_DEL_SCHEME FM_PCD_IOC_KG_SCHEME_DELETE
152734 +#define FM_PCD_IOC_CC_BUILD_TREE FM_PCD_IOC_CC_ROOT_BUILD
152735 +#define FM_PCD_IOC_CC_DELETE_TREE FM_PCD_IOC_CC_ROOT_DELETE
152736 +#define FM_PCD_IOC_CC_DELETE_NODE FM_PCD_IOC_MATCH_TABLE_DELETE
152737 +#define FM_PCD_IOC_CC_TREE_MODIFY_NEXT_ENGINE FM_PCD_IOC_CC_ROOT_MODIFY_NEXT_ENGINE
152738 +#define FM_PCD_IOC_CC_NODE_MODIFY_NEXT_ENGINE FM_PCD_IOC_MATCH_TABLE_MODIFY_NEXT_ENGINE
152739 +#define FM_PCD_IOC_CC_NODE_MODIFY_MISS_NEXT_ENGINE \
152740 + FM_PCD_IOC_MATCH_TABLE_MODIFY_MISS_NEXT_ENGINE
152741 +#define FM_PCD_IOC_CC_NODE_REMOVE_KEY FM_PCD_IOC_MATCH_TABLE_REMOVE_KEY
152742 +#define FM_PCD_IOC_CC_NODE_ADD_KEY FM_PCD_IOC_MATCH_TABLE_ADD_KEY
152743 +#define FM_PCD_IOC_CC_NODE_MODIFY_KEY_AND_NEXT_ENGINE \
152744 + FM_PCD_IOC_MATCH_TABLE_MODIFY_KEY_AND_NEXT_ENGINE
152745 +#define FM_PCD_IOC_CC_NODE_MODIFY_KEY FM_PCD_IOC_MATCH_TABLE_MODIFY_KEY
152746 +#define FM_PCD_IOC_PLCR_SET_PROFILE FM_PCD_IOC_PLCR_PROFILE_SET
152747 +#define FM_PCD_IOC_PLCR_DEL_PROFILE FM_PCD_IOC_PLCR_PROFILE_DELETE
152748 +#define FM_PCD_IOC_MANIP_SET_NODE FM_PCD_IOC_MANIP_NODE_SET
152749 +#define FM_PCD_IOC_MANIP_DELETE_NODE FM_PCD_IOC_MANIP_NODE_DELETE
152750 +#endif /* NCSW_BACKWARD_COMPATIBLE_API */
152751 +
152752 +#endif /* __FM_PCD_IOCTLS_H */
152753 +/** @} */ /* end of lnx_ioctl_FM_PCD_Runtime_grp group */
152754 +/** @} */ /* end of lnx_ioctl_FM_PCD_grp group */
152755 +/** @} */ /* end of lnx_ioctl_FM_grp group */
152756 --- /dev/null
152757 +++ b/include/uapi/linux/fmd/Peripherals/fm_port_ioctls.h
152758 @@ -0,0 +1,973 @@
152759 +/* Copyright (c) 2008-2012 Freescale Semiconductor, Inc.
152760 + * All rights reserved.
152761 + *
152762 + * Redistribution and use in source and binary forms, with or without
152763 + * modification, are permitted provided that the following conditions are met:
152764 + * * Redistributions of source code must retain the above copyright
152765 + * notice, this list of conditions and the following disclaimer.
152766 + * * Redistributions in binary form must reproduce the above copyright
152767 + * notice, this list of conditions and the following disclaimer in the
152768 + * documentation and/or other materials provided with the distribution.
152769 + * * Neither the name of Freescale Semiconductor nor the
152770 + * names of its contributors may be used to endorse or promote products
152771 + * derived from this software without specific prior written permission.
152772 + *
152773 + *
152774 + * ALTERNATIVELY, this software may be distributed under the terms of the
152775 + * GNU General Public License ("GPL") as published by the Free Software
152776 + * Foundation, either version 2 of that License or (at your option) any
152777 + * later version.
152778 + *
152779 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
152780 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
152781 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
152782 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
152783 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
152784 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
152785 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
152786 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
152787 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
152788 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
152789 + */
152790 +
152791 +/******************************************************************************
152792 + @File fm_port_ioctls.h
152793 +
152794 + @Description FM Port routines
152795 +*//***************************************************************************/
152796 +#ifndef __FM_PORT_IOCTLS_H
152797 +#define __FM_PORT_IOCTLS_H
152798 +
152799 +#include "enet_ext.h"
152800 +#include "net_ioctls.h"
152801 +#include "fm_ioctls.h"
152802 +#include "fm_pcd_ioctls.h"
152803 +
152804 +
152805 +/**************************************************************************//**
152806 +
152807 + @Group lnx_ioctl_FM_grp Frame Manager Linux IOCTL API
152808 +
152809 + @Description FM Linux ioctls definitions and enums
152810 +
152811 + @{
152812 +*//***************************************************************************/
152813 +
152814 +/**************************************************************************//**
152815 + @Group lnx_ioctl_FM_PORT_grp FM Port
152816 +
152817 + @Description FM Port API
152818 +
152819 + The FM uses a general module called "port" to represent a Tx port
152820 + (MAC), an Rx port (MAC), offline parsing flow or host command
152821 + flow. There may be up to 17 (may change) ports in an FM - 5 Tx
152822 + ports (4 for the 1G MACs, 1 for the 10G MAC), 5 Rx Ports, and 7
152823 + Host command/Offline parsing ports. The SW driver manages these
152824 + ports as sub-modules of the FM, i.e. after an FM is initialized,
152825 + its ports may be initialized and operated upon.
152826 +
152827 + The port is initialized aware of its type, but other functions on
152828 + a port may be indifferent to its type. When necessary, the driver
152829 + verifies coherency and returns error if applicable.
152830 +
152831 + On initialization, user specifies the port type and it's index
152832 + (relative to the port's type). Host command and Offline parsing
152833 + ports share the same id range, I.e user may not initialized host
152834 + command port 0 and offline parsing port 0.
152835 +
152836 + @{
152837 +*//***************************************************************************/
152838 +
152839 +/**************************************************************************//**
152840 + @Description An enum for defining port PCD modes.
152841 + (Must match enum e_FmPortPcdSupport defined in fm_port_ext.h)
152842 +
152843 + This enum defines the superset of PCD engines support - i.e. not
152844 + all engines have to be used, but all have to be enabled. The real
152845 + flow of a specific frame depends on the PCD configuration and the
152846 + frame headers and payload.
152847 + Note: the first engine and the first engine after the parser (if
152848 + exists) should be in order, the order is important as it will
152849 + define the flow of the port. However, as for the rest engines
152850 + (the ones that follows), the order is not important anymore as
152851 + it is defined by the PCD graph itself.
152852 +*//***************************************************************************/
152853 +typedef enum ioc_fm_port_pcd_support {
152854 + e_IOC_FM_PORT_PCD_SUPPORT_NONE = 0 /**< BMI to BMI, PCD is not used */
152855 + , e_IOC_FM_PORT_PCD_SUPPORT_PRS_ONLY /**< Use only Parser */
152856 + , e_IOC_FM_PORT_PCD_SUPPORT_PLCR_ONLY /**< Use only Policer */
152857 + , e_IOC_FM_PORT_PCD_SUPPORT_PRS_AND_PLCR /**< Use Parser and Policer */
152858 + , e_IOC_FM_PORT_PCD_SUPPORT_PRS_AND_KG /**< Use Parser and Keygen */
152859 + , e_IOC_FM_PORT_PCD_SUPPORT_PRS_AND_KG_AND_CC /**< Use Parser, Keygen and Coarse Classification */
152860 + , e_IOC_FM_PORT_PCD_SUPPORT_PRS_AND_KG_AND_CC_AND_PLCR
152861 + /**< Use all PCD engines */
152862 + , e_IOC_FM_PORT_PCD_SUPPORT_PRS_AND_KG_AND_PLCR /**< Use Parser, Keygen and Policer */
152863 + , e_IOC_FM_PORT_PCD_SUPPORT_PRS_AND_CC /**< Use Parser and Coarse Classification */
152864 + , e_IOC_FM_PORT_PCD_SUPPORT_PRS_AND_CC_AND_PLCR /**< Use Parser and Coarse Classification and Policer */
152865 + , e_IOC_FM_PORT_PCD_SUPPORT_CC_ONLY /**< Use only Coarse Classification */
152866 +#if (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10))
152867 + , e_IOC_FM_PORT_PCD_SUPPORT_CC_AND_KG /**< Use Coarse Classification,and Keygen */
152868 + , e_IOC_FM_PORT_PCD_SUPPORT_CC_AND_KG_AND_PLCR /**< Use Coarse Classification, Keygen and Policer */
152869 +#endif /* FM_CAPWAP_SUPPORT */
152870 +} ioc_fm_port_pcd_support;
152871 +
152872 +
152873 +/**************************************************************************//**
152874 + @Collection FM Frame error
152875 +*//***************************************************************************/
152876 +typedef uint32_t ioc_fm_port_frame_err_select_t; /**< typedef for defining Frame Descriptor errors */
152877 +
152878 +/* @} */
152879 +
152880 +
152881 +/**************************************************************************//**
152882 + @Description An enum for defining Dual Tx rate limiting scale.
152883 + (Must match e_FmPortDualRateLimiterScaleDown defined in fm_port_ext.h)
152884 +*//***************************************************************************/
152885 +typedef enum ioc_fm_port_dual_rate_limiter_scale_down {
152886 + e_IOC_FM_PORT_DUAL_RATE_LIMITER_NONE = 0, /**< Use only single rate limiter */
152887 + e_IOC_FM_PORT_DUAL_RATE_LIMITER_SCALE_DOWN_BY_2, /**< Divide high rate limiter by 2 */
152888 + e_IOC_FM_PORT_DUAL_RATE_LIMITER_SCALE_DOWN_BY_4, /**< Divide high rate limiter by 4 */
152889 + e_IOC_FM_PORT_DUAL_RATE_LIMITER_SCALE_DOWN_BY_8 /**< Divide high rate limiter by 8 */
152890 +} ioc_fm_port_dual_rate_limiter_scale_down;
152891 +
152892 +/**************************************************************************//**
152893 + @Description A structure for defining Tx rate limiting
152894 + (Must match struct t_FmPortRateLimit defined in fm_port_ext.h)
152895 +*//***************************************************************************/
152896 +typedef struct ioc_fm_port_rate_limit_t {
152897 + uint16_t max_burst_size; /**< in KBytes for Tx ports, in frames
152898 + for offline parsing ports. (note that
152899 + for early chips burst size is
152900 + rounded up to a multiply of 1000 frames).*/
152901 + uint32_t rate_limit; /**< in Kb/sec for Tx ports, in frame/sec for
152902 + offline parsing ports. Rate limit refers to
152903 + data rate (rather than line rate). */
152904 + ioc_fm_port_dual_rate_limiter_scale_down rate_limit_divider; /**< For offline parsing ports only. Not-valid
152905 + for some earlier chip revisions */
152906 +} ioc_fm_port_rate_limit_t;
152907 +
152908 +
152909 +
152910 +/**************************************************************************//**
152911 + @Group lnx_ioctl_FM_PORT_runtime_control_grp FM Port Runtime Control Unit
152912 +
152913 + @Description FM Port Runtime control unit API functions, definitions and enums.
152914 +
152915 + @{
152916 +*//***************************************************************************/
152917 +
152918 +/**************************************************************************//**
152919 + @Description An enum for defining FM Port counters.
152920 + (Must match enum e_FmPortCounters defined in fm_port_ext.h)
152921 +*//***************************************************************************/
152922 +typedef enum ioc_fm_port_counters {
152923 + e_IOC_FM_PORT_COUNTERS_CYCLE, /**< BMI performance counter */
152924 + e_IOC_FM_PORT_COUNTERS_TASK_UTIL, /**< BMI performance counter */
152925 + e_IOC_FM_PORT_COUNTERS_QUEUE_UTIL, /**< BMI performance counter */
152926 + e_IOC_FM_PORT_COUNTERS_DMA_UTIL, /**< BMI performance counter */
152927 + e_IOC_FM_PORT_COUNTERS_FIFO_UTIL, /**< BMI performance counter */
152928 + e_IOC_FM_PORT_COUNTERS_RX_PAUSE_ACTIVATION, /**< BMI Rx only performance counter */
152929 + e_IOC_FM_PORT_COUNTERS_FRAME, /**< BMI statistics counter */
152930 + e_IOC_FM_PORT_COUNTERS_DISCARD_FRAME, /**< BMI statistics counter */
152931 + e_IOC_FM_PORT_COUNTERS_DEALLOC_BUF, /**< BMI deallocate buffer statistics counter */
152932 + e_IOC_FM_PORT_COUNTERS_RX_BAD_FRAME, /**< BMI Rx only statistics counter */
152933 + e_IOC_FM_PORT_COUNTERS_RX_LARGE_FRAME, /**< BMI Rx only statistics counter */
152934 + e_IOC_FM_PORT_COUNTERS_RX_FILTER_FRAME, /**< BMI Rx & OP only statistics counter */
152935 + e_IOC_FM_PORT_COUNTERS_RX_LIST_DMA_ERR, /**< BMI Rx, OP & HC only statistics counter */
152936 + e_IOC_FM_PORT_COUNTERS_RX_OUT_OF_BUFFERS_DISCARD, /**< BMI Rx, OP & HC statistics counter */
152937 + e_IOC_FM_PORT_COUNTERS_PREPARE_TO_ENQUEUE_COUNTER, /**< BMI Rx, OP & HC only statistics counter */
152938 + e_IOC_FM_PORT_COUNTERS_WRED_DISCARD, /**< BMI OP & HC only statistics counter */
152939 + e_IOC_FM_PORT_COUNTERS_LENGTH_ERR, /**< BMI non-Rx statistics counter */
152940 + e_IOC_FM_PORT_COUNTERS_UNSUPPRTED_FORMAT, /**< BMI non-Rx statistics counter */
152941 + e_IOC_FM_PORT_COUNTERS_DEQ_TOTAL, /**< QMI total QM dequeues counter */
152942 + e_IOC_FM_PORT_COUNTERS_ENQ_TOTAL, /**< QMI total QM enqueues counter */
152943 + e_IOC_FM_PORT_COUNTERS_DEQ_FROM_DEFAULT, /**< QMI counter */
152944 + e_IOC_FM_PORT_COUNTERS_DEQ_CONFIRM /**< QMI counter */
152945 +} ioc_fm_port_counters;
152946 +
152947 +typedef struct ioc_fm_port_bmi_stats_t {
152948 + uint32_t cnt_cycle;
152949 + uint32_t cnt_task_util;
152950 + uint32_t cnt_queue_util;
152951 + uint32_t cnt_dma_util;
152952 + uint32_t cnt_fifo_util;
152953 + uint32_t cnt_rx_pause_activation;
152954 + uint32_t cnt_frame;
152955 + uint32_t cnt_discard_frame;
152956 + uint32_t cnt_dealloc_buf;
152957 + uint32_t cnt_rx_bad_frame;
152958 + uint32_t cnt_rx_large_frame;
152959 + uint32_t cnt_rx_filter_frame;
152960 + uint32_t cnt_rx_list_dma_err;
152961 + uint32_t cnt_rx_out_of_buffers_discard;
152962 + uint32_t cnt_wred_discard;
152963 + uint32_t cnt_length_err;
152964 + uint32_t cnt_unsupported_format;
152965 +} ioc_fm_port_bmi_stats_t;
152966 +
152967 +/**************************************************************************//**
152968 + @Description Structure for Port id parameters.
152969 + (Description may be inaccurate;
152970 + must match struct t_FmPortCongestionGrps defined in fm_port_ext.h)
152971 +
152972 + Fields commented 'IN' are passed by the port module to be used
152973 + by the FM module.
152974 + Fields commented 'OUT' will be filled by FM before returning to port.
152975 +*//***************************************************************************/
152976 +typedef struct ioc_fm_port_congestion_groups_t {
152977 + uint16_t num_of_congestion_grps_to_consider; /**< The number of required congestion groups
152978 + to define the size of the following array */
152979 + uint8_t congestion_grps_to_consider [FM_PORT_NUM_OF_CONGESTION_GRPS];
152980 + /**< An array of CG indexes;
152981 + Note that the size of the array should be
152982 + 'num_of_congestion_grps_to_consider'. */
152983 +#if DPAA_VERSION >= 11
152984 + bool pfc_priorities_enable[FM_PORT_NUM_OF_CONGESTION_GRPS][FM_MAX_NUM_OF_PFC_PRIORITIES];
152985 + /**< A matrix that represents the map between the CG ids
152986 + defined in 'congestion_grps_to_consider' to the priorities
152987 + mapping array. */
152988 +#endif /* DPAA_VERSION >= 11 */
152989 +} ioc_fm_port_congestion_groups_t;
152990 +
152991 +
152992 +
152993 +/**************************************************************************//**
152994 + @Function FM_PORT_Disable
152995 +
152996 + @Description Gracefully disable an FM port. The port will not start new tasks after all
152997 + tasks associated with the port are terminated.
152998 +
152999 + @Return 0 on success; error code otherwise.
153000 +
153001 + @Cautions This is a blocking routine, it returns after port is
153002 + gracefully stopped, i.e. the port will not except new frames,
153003 + but it will finish all frames or tasks which were already began
153004 +*//***************************************************************************/
153005 +#define FM_PORT_IOC_DISABLE _IO(FM_IOC_TYPE_BASE, FM_PORT_IOC_NUM(1))
153006 +
153007 +/**************************************************************************//**
153008 + @Function FM_PORT_Enable
153009 +
153010 + @Description A runtime routine provided to allow disable/enable of port.
153011 +
153012 + @Return 0 on success; error code otherwise.
153013 +*//***************************************************************************/
153014 +#define FM_PORT_IOC_ENABLE _IO(FM_IOC_TYPE_BASE, FM_PORT_IOC_NUM(2))
153015 +
153016 +/**************************************************************************//**
153017 + @Function FM_PORT_SetRateLimit
153018 +
153019 + @Description Calling this routine enables rate limit algorithm.
153020 + By default, this functionality is disabled.
153021 + Note that rate-limit mechanism uses the FM time stamp.
153022 + The selected rate limit specified here would be
153023 + rounded DOWN to the nearest 16M.
153024 +
153025 + May be used for Tx and offline parsing ports only
153026 +
153027 + @Param[in] ioc_fm_port_rate_limit A structure of rate limit parameters
153028 +
153029 + @Return 0 on success; error code otherwise.
153030 +*//***************************************************************************/
153031 +#define FM_PORT_IOC_SET_RATE_LIMIT _IOW(FM_IOC_TYPE_BASE, FM_PORT_IOC_NUM(3), ioc_fm_port_rate_limit_t)
153032 +
153033 +/**************************************************************************//**
153034 + @Function FM_PORT_DeleteRateLimit
153035 +
153036 + @Description Calling this routine disables the previously enabled rate limit.
153037 +
153038 + May be used for Tx and offline parsing ports only
153039 +
153040 + @Return 0 on success; error code otherwise.
153041 +*//***************************************************************************/
153042 +#define FM_PORT_IOC_DELETE_RATE_LIMIT _IO(FM_IOC_TYPE_BASE, FM_PORT_IOC_NUM(5))
153043 +#define FM_PORT_IOC_REMOVE_RATE_LIMIT FM_PORT_IOC_DELETE_RATE_LIMIT
153044 +
153045 +
153046 +/**************************************************************************//**
153047 + @Function FM_PORT_AddCongestionGrps
153048 +
153049 + @Description This routine effects the corresponding Tx port.
153050 + It should be called in order to enable pause
153051 + frame transmission in case of congestion in one or more
153052 + of the congestion groups relevant to this port.
153053 + Each call to this routine may add one or more congestion
153054 + groups to be considered relevant to this port.
153055 +
153056 + May be used for Rx, or RX+OP ports only (depending on chip)
153057 +
153058 + @Param[in] ioc_fm_port_congestion_groups_t - A pointer to an array of
153059 + congestion group ids to consider.
153060 +
153061 + @Return 0 on success; error code otherwise.
153062 +*//***************************************************************************/
153063 +#define FM_PORT_IOC_ADD_CONGESTION_GRPS _IOW(FM_IOC_TYPE_BASE, FM_PORT_IOC_NUM(34), ioc_fm_port_congestion_groups_t)
153064 +
153065 +/**************************************************************************//**
153066 + @Function FM_PORT_RemoveCongestionGrps
153067 +
153068 + @Description This routine effects the corresponding Tx port. It should be
153069 + called when congestion groups were
153070 + defined for this port and are no longer relevant, or pause
153071 + frames transmitting is not required on their behalf.
153072 + Each call to this routine may remove one or more congestion
153073 + groups to be considered relevant to this port.
153074 +
153075 + May be used for Rx, or RX+OP ports only (depending on chip)
153076 +
153077 + @Param[in] ioc_fm_port_congestion_groups_t - A pointer to an array of
153078 + congestion group ids to consider.
153079 +
153080 + @Return 0 on success; error code otherwise.
153081 +*//***************************************************************************/
153082 +#define FM_PORT_IOC_REMOVE_CONGESTION_GRPS _IOW(FM_IOC_TYPE_BASE, FM_PORT_IOC_NUM(35), ioc_fm_port_congestion_groups_t)
153083 +
153084 +/**************************************************************************//**
153085 + @Function FM_PORT_SetErrorsRoute
153086 +
153087 + @Description Errors selected for this routine will cause a frame with that error
153088 + to be enqueued to error queue.
153089 + Errors not selected for this routine will cause a frame with that error
153090 + to be enqueued to the one of the other port queues.
153091 + By default all errors are defined to be enqueued to error queue.
153092 + Errors that were configured to be discarded (at initialization)
153093 + may not be selected here.
153094 +
153095 + May be used for Rx and offline parsing ports only
153096 +
153097 + @Param[in] ioc_fm_port_frame_err_select_t A list of errors to enqueue to error queue
153098 +
153099 + @Return 0 on success; error code otherwise.
153100 +
153101 + @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init().
153102 + (szbs001: How is it possible to have one function that needs to be
153103 + called BEFORE FM_PORT_Init() implemented as an ioctl,
153104 + which will ALWAYS be called AFTER the FM_PORT_Init()
153105 + for that port!?!?!?!???!?!??!?!?)
153106 +*//***************************************************************************/
153107 +#define FM_PORT_IOC_SET_ERRORS_ROUTE _IOW(FM_IOC_TYPE_BASE, FM_PORT_IOC_NUM(4), ioc_fm_port_frame_err_select_t)
153108 +
153109 +
153110 +/**************************************************************************//**
153111 + @Group lnx_ioctl_FM_PORT_pcd_runtime_control_grp FM Port PCD Runtime Control Unit
153112 +
153113 + @Description FM Port PCD Runtime control unit API functions, definitions and enums.
153114 +
153115 + @{
153116 +*//***************************************************************************/
153117 +
153118 +/**************************************************************************//**
153119 + @Description A structure defining the KG scheme after the parser.
153120 + (Must match struct t_FmPcdKgSchemeSelect defined in fm_port_ext.h)
153121 +
153122 + This is relevant only to change scheme selection mode - from
153123 + direct to indirect and vice versa, or when the scheme is selected directly,
153124 + to select the scheme id.
153125 +
153126 +*//***************************************************************************/
153127 +typedef struct ioc_fm_pcd_kg_scheme_select_t {
153128 + bool direct; /**< TRUE to use 'scheme_id' directly, FALSE to use LCV.*/
153129 + void *scheme_id; /**< Relevant for 'direct'=TRUE only.
153130 + 'scheme_id' selects the scheme after parser. */
153131 +} ioc_fm_pcd_kg_scheme_select_t;
153132 +
153133 +/**************************************************************************//**
153134 + @Description Scheme IDs structure
153135 + (Must match struct t_FmPcdPortSchemesParams defined in fm_port_ext.h)
153136 +*//***************************************************************************/
153137 +typedef struct ioc_fm_pcd_port_schemes_params_t {
153138 + uint8_t num_of_schemes; /**< Number of schemes for port to be bound to. */
153139 + void *scheme_ids[FM_PCD_KG_NUM_OF_SCHEMES]; /**< Array of 'num_of_schemes' schemes for the
153140 + port to be bound to */
153141 +} ioc_fm_pcd_port_schemes_params_t;
153142 +
153143 +/**************************************************************************//**
153144 + @Description A union for defining port protocol parameters for parser
153145 + (Must match union u_FmPcdHdrPrsOpts defined in fm_port_ext.h)
153146 +*//***************************************************************************/
153147 +typedef union ioc_fm_pcd_hdr_prs_opts_u {
153148 + /* MPLS */
153149 + struct {
153150 + bool label_interpretation_enable;/**< When this bit is set, the last MPLS label will be
153151 + interpreted as described in HW spec table. When the bit
153152 + is cleared, the parser will advance to MPLS next parse */
153153 + ioc_net_header_type next_parse; /**< must be equal or higher than IPv4 */
153154 + } mpls_prs_options;
153155 +
153156 + /* VLAN */
153157 + struct {
153158 + uint16_t tag_protocol_id1; /**< User defined Tag Protocol Identifier, to be recognized
153159 + on VLAN TAG on top of 0x8100 and 0x88A8 */
153160 + uint16_t tag_protocol_id2; /**< User defined Tag Protocol Identifier, to be recognized
153161 + on VLAN TAG on top of 0x8100 and 0x88A8 */
153162 + } vlan_prs_options;
153163 +
153164 + /* PPP */
153165 + struct{
153166 + bool enable_mtu_check; /**< Check validity of MTU according to RFC2516 */
153167 + } pppoe_prs_options;
153168 +
153169 + /* IPV6 */
153170 + struct {
153171 + bool routing_hdr_disable; /**< Disable routing header */
153172 + } ipv6_prs_options;
153173 +
153174 + /* UDP */
153175 + struct {
153176 + bool pad_ignore_checksum; /**< TRUE to ignore pad in checksum */
153177 + } udp_prs_options;
153178 +
153179 + /* TCP */
153180 + struct {
153181 + bool pad_ignore_checksum; /**< TRUE to ignore pad in checksum */
153182 + } tcp_prs_options;
153183 +} ioc_fm_pcd_hdr_prs_opts_u;
153184 +
153185 +/**************************************************************************//**
153186 + @Description A structure for defining each header for the parser
153187 + (must match struct t_FmPcdPrsAdditionalHdrParams defined in fm_port_ext.h)
153188 +*//***************************************************************************/
153189 +typedef struct ioc_fm_pcd_prs_additional_hdr_params_t {
153190 + ioc_net_header_type hdr; /**< Selected header */
153191 + bool err_disable; /**< TRUE to disable error indication */
153192 + bool soft_prs_enable; /**< Enable jump to SW parser when this
153193 + header is recognized by the HW parser. */
153194 + uint8_t index_per_hdr; /**< Normally 0, if more than one sw parser
153195 + attachments exists for the same header,
153196 + (in the main sw parser code) use this
153197 + index to distinguish between them. */
153198 + bool use_prs_opts; /**< TRUE to use parser options. */
153199 + ioc_fm_pcd_hdr_prs_opts_u prs_opts; /**< A unuion according to header type,
153200 + defining the parser options selected.*/
153201 +} ioc_fm_pcd_prs_additional_hdr_params_t;
153202 +
153203 +/**************************************************************************//**
153204 + @Description A structure for defining port PCD parameters
153205 + (Must match t_FmPortPcdPrsParams defined in fm_port_ext.h)
153206 +*//***************************************************************************/
153207 +typedef struct ioc_fm_port_pcd_prs_params_t {
153208 + uint8_t prs_res_priv_info; /**< The private info provides a method of inserting
153209 + port information into the parser result. This information
153210 + may be extracted by KeyGen and be used for frames
153211 + distribution when a per-port distinction is required,
153212 + it may also be used as a port logical id for analyzing
153213 + incoming frames. */
153214 + uint8_t parsing_offset; /**< Number of bytes from begining of packet to start parsing */
153215 + ioc_net_header_type first_prs_hdr; /**< The type of the first header axpected at 'parsing_offset' */
153216 + bool include_in_prs_statistics; /**< TRUE to include this port in the parser statistics */
153217 + uint8_t num_of_hdrs_with_additional_params;
153218 + /**< Normally 0, some headers may get special parameters */
153219 + ioc_fm_pcd_prs_additional_hdr_params_t additional_params[IOC_FM_PCD_PRS_NUM_OF_HDRS];
153220 + /**< 'num_of_hdrs_with_additional_params' structures
153221 + additional parameters for each header that requires them */
153222 + bool set_vlan_tpid1; /**< TRUE to configure user selection of Ethertype to
153223 + indicate a VLAN tag (in addition to the TPID values
153224 + 0x8100 and 0x88A8). */
153225 + uint16_t vlan_tpid1; /**< extra tag to use if set_vlan_tpid1=TRUE. */
153226 + bool set_vlan_tpid2; /**< TRUE to configure user selection of Ethertype to
153227 + indicate a VLAN tag (in addition to the TPID values
153228 + 0x8100 and 0x88A8). */
153229 + uint16_t vlan_tpid2; /**< extra tag to use if set_vlan_tpid1=TRUE. */
153230 +} ioc_fm_port_pcd_prs_params_t;
153231 +
153232 +/**************************************************************************//**
153233 + @Description A structure for defining coarse alassification parameters
153234 + (Must match t_FmPortPcdCcParams defined in fm_port_ext.h)
153235 +*//***************************************************************************/
153236 +typedef struct ioc_fm_port_pcd_cc_params_t {
153237 + void *cc_tree_id; /**< CC tree id */
153238 +} ioc_fm_port_pcd_cc_params_t;
153239 +
153240 +/**************************************************************************//**
153241 + @Description A structure for defining keygen parameters
153242 + (Must match t_FmPortPcdKgParams defined in fm_port_ext.h)
153243 +*//***************************************************************************/
153244 +typedef struct ioc_fm_port_pcd_kg_params_t {
153245 + uint8_t num_of_schemes; /**< Number of schemes for port to be bound to. */
153246 + void *scheme_ids[FM_PCD_KG_NUM_OF_SCHEMES];
153247 + /**< Array of 'num_of_schemes' schemes for the
153248 + port to be bound to */
153249 + bool direct_scheme; /**< TRUE for going from parser to a specific scheme,
153250 + regardless of parser result */
153251 + void *direct_scheme_id; /**< Scheme id, as returned by FM_PCD_KgSetScheme;
153252 + relevant only if direct=TRUE. */
153253 +} ioc_fm_port_pcd_kg_params_t;
153254 +
153255 +/**************************************************************************//**
153256 + @Description A structure for defining policer parameters
153257 + (Must match t_FmPortPcdPlcrParams defined in fm_port_ext.h)
153258 +*//***************************************************************************/
153259 +typedef struct ioc_fm_port_pcd_plcr_params_t {
153260 + void *plcr_profile_id; /**< Selected profile handle;
153261 + relevant in one of the following cases:
153262 + e_IOC_FM_PORT_PCD_SUPPORT_PLCR_ONLY or
153263 + e_IOC_FM_PORT_PCD_SUPPORT_PRS_AND_PLCR were selected,
153264 + or if any flow uses a KG scheme where policer
153265 + profile is not generated (bypass_plcr_profile_generation selected) */
153266 +} ioc_fm_port_pcd_plcr_params_t;
153267 +
153268 +/**************************************************************************//**
153269 + @Description A structure for defining port PCD parameters
153270 + (Must match struct t_FmPortPcdParams defined in fm_port_ext.h)
153271 +*//***************************************************************************/
153272 +typedef struct ioc_fm_port_pcd_params_t {
153273 + ioc_fm_port_pcd_support pcd_support; /**< Relevant for Rx and offline ports only.
153274 + Describes the active PCD engines for this port. */
153275 + void *net_env_id; /**< HL Unused in PLCR only mode */
153276 + ioc_fm_port_pcd_prs_params_t *p_prs_params; /**< Parser parameters for this port */
153277 + ioc_fm_port_pcd_cc_params_t *p_cc_params; /**< Coarse classification parameters for this port */
153278 + ioc_fm_port_pcd_kg_params_t *p_kg_params; /**< Keygen parameters for this port */
153279 + ioc_fm_port_pcd_plcr_params_t *p_plcr_params; /**< Policer parameters for this port */
153280 + void *p_ip_reassembly_manip;/**< IP Reassembly manipulation */
153281 +#if (DPAA_VERSION >= 11)
153282 + void *p_capwap_reassembly_manip;/**< CAPWAP Reassembly manipulation */
153283 +#endif /* (DPAA_VERSION >= 11) */
153284 +} ioc_fm_port_pcd_params_t;
153285 +
153286 +/**************************************************************************//**
153287 + @Description A structure for defining the Parser starting point
153288 + (Must match struct t_FmPcdPrsStart defined in fm_port_ext.h)
153289 +*//***************************************************************************/
153290 +typedef struct ioc_fm_pcd_prs_start_t {
153291 + uint8_t parsing_offset; /**< Number of bytes from begining of packet to
153292 + start parsing */
153293 + ioc_net_header_type first_prs_hdr; /**< The type of the first header axpected at
153294 + 'parsing_offset' */
153295 +} ioc_fm_pcd_prs_start_t;
153296 +
153297 +
153298 +/**************************************************************************//**
153299 + @Description FQID parameters structure
153300 +*//***************************************************************************/
153301 +typedef struct ioc_fm_port_pcd_fqids_params_t {
153302 + uint32_t num_fqids; /**< Number of fqids to be allocated for the port */
153303 + uint8_t alignment; /**< Alignment required for this port */
153304 + uint32_t base_fqid; /**< output parameter - the base fqid */
153305 +} ioc_fm_port_pcd_fqids_params_t;
153306 +
153307 +
153308 +/**************************************************************************//**
153309 + @Function FM_PORT_IOC_ALLOC_PCD_FQIDS
153310 +
153311 + @Description Allocates FQID's
153312 +
153313 + May be used for Rx and offline parsing ports only
153314 +
153315 + @Param[in,out] ioc_fm_port_pcd_fqids_params_t Parameters for allocating FQID's
153316 +
153317 + @Return 0 on success; error code otherwise.
153318 +*//***************************************************************************/
153319 +#define FM_PORT_IOC_ALLOC_PCD_FQIDS _IOWR(FM_IOC_TYPE_BASE, FM_PORT_IOC_NUM(19), ioc_fm_port_pcd_fqids_params_t)
153320 +
153321 +/**************************************************************************//**
153322 + @Function FM_PORT_IOC_FREE_PCD_FQIDS
153323 +
153324 + @Description Frees previously-allocated FQIDs
153325 +
153326 + May be used for Rx and offline parsing ports only
153327 +
153328 + @Param[in] uint32_t Base FQID of previously allocated range.
153329 +
153330 + @Return 0 on success; error code otherwise.
153331 +*//***************************************************************************/
153332 +#define FM_PORT_IOC_FREE_PCD_FQIDS _IOW(FM_IOC_TYPE_BASE, FM_PORT_IOC_NUM(19), uint32_t)
153333 +
153334 +
153335 +/**************************************************************************//**
153336 + @Function FM_PORT_SetPCD
153337 +
153338 + @Description Calling this routine defines the port's PCD configuration.
153339 + It changes it from its default configuration which is PCD
153340 + disabled (BMI to BMI) and configures it according to the passed
153341 + parameters.
153342 +
153343 + May be used for Rx and offline parsing ports only
153344 +
153345 + @Param[in] ioc_fm_port_pcd_params_t A Structure of parameters defining the port's PCD
153346 + configuration.
153347 +
153348 + @Return 0 on success; error code otherwise.
153349 +*//***************************************************************************/
153350 +#if defined(CONFIG_COMPAT)
153351 +#define FM_PORT_IOC_SET_PCD_COMPAT _IOW(FM_IOC_TYPE_BASE, FM_PORT_IOC_NUM(20), ioc_compat_fm_port_pcd_params_t)
153352 +#endif
153353 +#define FM_PORT_IOC_SET_PCD _IOW(FM_IOC_TYPE_BASE, FM_PORT_IOC_NUM(20), ioc_fm_port_pcd_params_t)
153354 +
153355 +/**************************************************************************//**
153356 + @Function FM_PORT_DeletePCD
153357 +
153358 + @Description Calling this routine releases the port's PCD configuration.
153359 + The port returns to its default configuration which is PCD
153360 + disabled (BMI to BMI) and all PCD configuration is removed.
153361 +
153362 + May be used for Rx and offline parsing ports which are
153363 + in PCD mode only
153364 +
153365 + @Return 0 on success; error code otherwise.
153366 +*//***************************************************************************/
153367 +#define FM_PORT_IOC_DELETE_PCD _IO(FM_IOC_TYPE_BASE, FM_PORT_IOC_NUM(21))
153368 +
153369 +/**************************************************************************//**
153370 + @Function FM_PORT_AttachPCD
153371 +
153372 + @Description This routine may be called after FM_PORT_DetachPCD was called,
153373 + to return to the originally configured PCD support flow.
153374 + The couple of routines are used to allow PCD configuration changes
153375 + that demand that PCD will not be used while changes take place.
153376 +
153377 + May be used for Rx and offline parsing ports which are
153378 + in PCD mode only
153379 +
153380 + @Return 0 on success; error code otherwise.
153381 +*//***************************************************************************/
153382 +#define FM_PORT_IOC_ATTACH_PCD _IO(FM_IOC_TYPE_BASE, FM_PORT_IOC_NUM(23))
153383 +
153384 +/**************************************************************************//**
153385 + @Function FM_PORT_DetachPCD
153386 +
153387 + @Description Calling this routine detaches the port from its PCD functionality.
153388 + The port returns to its default flow which is BMI to BMI.
153389 +
153390 + May be used for Rx and offline parsing ports which are
153391 + in PCD mode only
153392 +
153393 + @Return 0 on success; error code otherwise.
153394 +*//***************************************************************************/
153395 +#define FM_PORT_IOC_DETACH_PCD _IO(FM_IOC_TYPE_BASE, FM_PORT_IOC_NUM(22))
153396 +
153397 +/**************************************************************************//**
153398 + @Function FM_PORT_PcdPlcrAllocProfiles
153399 +
153400 + @Description This routine may be called only for ports that use the Policer in
153401 + order to allocate private policer profiles.
153402 +
153403 + @Param[in] uint16_t The number of required policer profiles
153404 +
153405 + @Return 0 on success; error code otherwise.
153406 +
153407 + @Cautions Allowed before FM_PORT_SetPCD() only.
153408 +*//***************************************************************************/
153409 +#define FM_PORT_IOC_PCD_PLCR_ALLOC_PROFILES _IOW(FM_IOC_TYPE_BASE, FM_PORT_IOC_NUM(24), uint16_t)
153410 +
153411 +/**************************************************************************//**
153412 + @Function FM_PORT_PcdPlcrFreeProfiles
153413 +
153414 + @Description This routine should be called for freeing private policer profiles.
153415 +
153416 + @Return 0 on success; error code otherwise.
153417 +
153418 + @Cautions Allowed before FM_PORT_SetPCD() only.
153419 +*//***************************************************************************/
153420 +#define FM_PORT_IOC_PCD_PLCR_FREE_PROFILES _IO(FM_IOC_TYPE_BASE, FM_PORT_IOC_NUM(25))
153421 +
153422 +/**************************************************************************//**
153423 + @Function FM_PORT_PcdKgModifyInitialScheme
153424 +
153425 + @Description This routine may be called only for ports that use the keygen in
153426 + order to change the initial scheme frame should be routed to.
153427 + The change may be of a scheme id (in case of direct mode),
153428 + from direct to indirect, or from indirect to direct - specifying the scheme id.
153429 +
153430 + @Param[in] ioc_fm_pcd_kg_scheme_select_t A structure of parameters for defining whether
153431 + a scheme is direct/indirect, and if direct - scheme id.
153432 +
153433 + @Return 0 on success; error code otherwise.
153434 +*//***************************************************************************/
153435 +#if defined(CONFIG_COMPAT)
153436 +#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)
153437 +#endif
153438 +#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)
153439 +
153440 +/**************************************************************************//**
153441 + @Function FM_PORT_PcdPlcrModifyInitialProfile
153442 +
153443 + @Description This routine may be called for ports with flows
153444 + e_IOC_FM_PCD_SUPPORT_PLCR_ONLY or e_IOC_FM_PCD_SUPPORT_PRS_AND_PLCR only,
153445 + to change the initial Policer profile frame should be routed to.
153446 + The change may be of a profile and/or absolute/direct mode selection.
153447 +
153448 + @Param[in] ioc_fm_obj_t Policer profile Id as returned from FM_PCD_PlcrSetProfile.
153449 +
153450 + @Return 0 on success; error code otherwise.
153451 +*//***************************************************************************/
153452 +#if defined(CONFIG_COMPAT)
153453 +#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)
153454 +#endif
153455 +#define FM_PORT_IOC_PCD_PLCR_MODIFY_INITIAL_PROFILE _IOW(FM_IOC_TYPE_BASE, FM_PORT_IOC_NUM(27), ioc_fm_obj_t)
153456 +
153457 +/**************************************************************************//**
153458 + @Function FM_PORT_PcdCcModifyTree
153459 +
153460 + @Description This routine may be called to change this port connection to
153461 + a pre-initializes coarse classification Tree.
153462 +
153463 + @Param[in] ioc_fm_obj_t Id of new coarse classification tree selected for this port.
153464 +
153465 + @Return 0 on success; error code otherwise.
153466 +
153467 + @Cautions Allowed only following FM_PORT_SetPCD() and FM_PORT_DetachPCD()
153468 +*//***************************************************************************/
153469 +#if defined(CONFIG_COMPAT)
153470 +#define FM_PORT_IOC_PCD_CC_MODIFY_TREE_COMPAT _IOW(FM_IOC_TYPE_BASE, FM_PORT_IOC_NUM(28), ioc_compat_fm_obj_t)
153471 +#endif
153472 +#define FM_PORT_IOC_PCD_CC_MODIFY_TREE _IOW(FM_IOC_TYPE_BASE, FM_PORT_IOC_NUM(28), ioc_fm_obj_t)
153473 +
153474 +/**************************************************************************//**
153475 + @Function FM_PORT_PcdKgBindSchemes
153476 +
153477 + @Description These routines may be called for modifying the binding of ports
153478 + to schemes. The scheme itself is not added,
153479 + just this specific port starts using it.
153480 +
153481 + @Param[in] ioc_fm_pcd_port_schemes_params_t Schemes parameters structre
153482 +
153483 + @Return 0 on success; error code otherwise.
153484 +
153485 + @Cautions Allowed only following FM_PORT_SetPCD().
153486 +*//***************************************************************************/
153487 +#if defined(CONFIG_COMPAT)
153488 +#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)
153489 +#endif
153490 +#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)
153491 +
153492 +/**************************************************************************//**
153493 + @Function FM_PORT_PcdKgUnbindSchemes
153494 +
153495 + @Description These routines may be called for modifying the binding of ports
153496 + to schemes. The scheme itself is not removed or invalidated,
153497 + just this specific port stops using it.
153498 +
153499 + @Param[in] ioc_fm_pcd_port_schemes_params_t Schemes parameters structre
153500 +
153501 + @Return 0 on success; error code otherwise.
153502 +
153503 + @Cautions Allowed only following FM_PORT_SetPCD().
153504 +*//***************************************************************************/
153505 +#if defined(CONFIG_COMPAT)
153506 +#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)
153507 +#endif
153508 +#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)
153509 +
153510 +typedef struct ioc_fm_port_mac_addr_params_t {
153511 + uint8_t addr[ENET_NUM_OCTETS_PER_ADDRESS];
153512 +} ioc_fm_port_mac_addr_params_t;
153513 +
153514 +/**************************************************************************//**
153515 + @Function FM_MAC_AddHashMacAddr
153516 +
153517 + @Description Add an Address to the hash table. This is for filter purpose only.
153518 +
153519 + @Param[in] ioc_fm_port_mac_addr_params_t - Ethernet Mac address
153520 +
153521 + @Return E_OK on success; Error code otherwise.
153522 +
153523 + @Cautions Allowed only following FM_MAC_Init(). It is a filter only address.
153524 + @Cautions Some address need to be filtered out in upper FM blocks.
153525 +*//***************************************************************************/
153526 +#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)
153527 +
153528 +/**************************************************************************//**
153529 + @Function FM_MAC_RemoveHashMacAddr
153530 +
153531 + @Description Delete an Address to the hash table. This is for filter purpose only.
153532 +
153533 + @Param[in] ioc_fm_port_mac_addr_params_t - Ethernet Mac address
153534 +
153535 + @Return E_OK on success; Error code otherwise.
153536 +
153537 + @Cautions Allowed only following FM_MAC_Init().
153538 +*//***************************************************************************/
153539 +#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)
153540 +
153541 +typedef struct ioc_fm_port_tx_pause_frames_params_t {
153542 + uint8_t priority;
153543 + uint16_t pause_time;
153544 + uint16_t thresh_time;
153545 +} ioc_fm_port_tx_pause_frames_params_t;
153546 +
153547 +/**************************************************************************//**
153548 + @Function FM_MAC_SetTxPauseFrames
153549 +
153550 + @Description Enable/Disable transmission of Pause-Frames.
153551 + The routine changes the default configuration:
153552 + pause-time - [0xf000]
153553 + threshold-time - [0]
153554 +
153555 + @Param[in] ioc_fm_port_tx_pause_frames_params_t A structure holding the required parameters.
153556 +
153557 + @Return E_OK on success; Error code otherwise.
153558 +
153559 + @Cautions Allowed only following FM_MAC_Init().
153560 + PFC is supported only on new mEMAC; i.e. in MACs that don't have
153561 + PFC support (10G-MAC and dTSEC), user should use 'FM_MAC_NO_PFC'
153562 + in the 'priority' field.
153563 +*//***************************************************************************/
153564 +#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)
153565 +
153566 +typedef struct ioc_fm_port_mac_statistics_t {
153567 + /* RMON */
153568 + uint64_t e_stat_pkts_64; /**< r-10G tr-DT 64 byte frame counter */
153569 + uint64_t e_stat_pkts_65_to_127; /**< r-10G 65 to 127 byte frame counter */
153570 + uint64_t e_stat_pkts_128_to_255; /**< r-10G 128 to 255 byte frame counter */
153571 + uint64_t e_stat_pkts_256_to_511; /**< r-10G 256 to 511 byte frame counter */
153572 + uint64_t e_stat_pkts_512_to_1023; /**< r-10G 512 to 1023 byte frame counter */
153573 + uint64_t e_stat_pkts_1024_to_1518; /**< r-10G 1024 to 1518 byte frame counter */
153574 + uint64_t e_stat_pkts_1519_to_1522; /**< r-10G 1519 to 1522 byte good frame count */
153575 + /* */
153576 + uint64_t e_stat_fragments; /**< Total number of packets that were less than 64 octets long with a wrong CRC.*/
153577 + uint64_t e_stat_jabbers; /**< Total number of packets longer than valid maximum length octets */
153578 + uint64_t e_stat_drop_events; /**< number of dropped packets due to internal errors of the MAC Client (during recieve). */
153579 + uint64_t e_stat_CRC_align_errors; /**< Incremented when frames of correct length but with CRC error are received.*/
153580 + uint64_t e_stat_undersize_pkts; /**< Incremented for frames under 64 bytes with a valid FCS and otherwise well formed;
153581 + This count does not include range length errors */
153582 + uint64_t e_stat_oversize_pkts; /**< Incremented for frames which exceed 1518 (non VLAN) or 1522 (VLAN) and contains
153583 + a valid FCS and otherwise well formed */
153584 + /* Pause */
153585 + uint64_t te_stat_pause; /**< Pause MAC Control received */
153586 + uint64_t re_stat_pause; /**< Pause MAC Control sent */
153587 + /* MIB II */
153588 + uint64_t if_in_octets; /**< Total number of byte received. */
153589 + uint64_t if_in_pkts; /**< Total number of packets received.*/
153590 + uint64_t if_in_ucast_pkts; /**< Total number of unicast frame received;
153591 + NOTE: this counter is not supported on dTSEC MAC */
153592 + uint64_t if_in_mcast_pkts; /**< Total number of multicast frame received*/
153593 + uint64_t if_in_bcast_pkts; /**< Total number of broadcast frame received */
153594 + uint64_t if_in_discards; /**< Frames received, but discarded due to problems within the MAC RX. */
153595 + uint64_t if_in_errors; /**< Number of frames received with error:
153596 + - FIFO Overflow Error
153597 + - CRC Error
153598 + - Frame Too Long Error
153599 + - Alignment Error
153600 + - The dedicated Error Code (0xfe, not a code error) was received */
153601 + uint64_t if_out_octets; /**< Total number of byte sent. */
153602 + uint64_t if_out_pkts; /**< Total number of packets sent .*/
153603 + uint64_t if_out_ucast_pkts; /**< Total number of unicast frame sent;
153604 + NOTE: this counter is not supported on dTSEC MAC */
153605 + uint64_t if_out_mcast_pkts; /**< Total number of multicast frame sent */
153606 + uint64_t if_out_bcast_pkts; /**< Total number of multicast frame sent */
153607 + uint64_t if_out_discards; /**< Frames received, but discarded due to problems within the MAC TX N/A!.*/
153608 + uint64_t if_out_errors; /**< Number of frames transmitted with error:
153609 + - FIFO Overflow Error
153610 + - FIFO Underflow Error
153611 + - Other */
153612 +} ioc_fm_port_mac_statistics_t;
153613 +
153614 +/**************************************************************************//**
153615 + @Function FM_MAC_GetStatistics
153616 +
153617 + @Description get all MAC statistics counters
153618 +
153619 + @Param[out] ioc_fm_port_mac_statistics_t A structure holding the statistics
153620 +
153621 + @Return E_OK on success; Error code otherwise.
153622 +
153623 + @Cautions Allowed only following FM_Init().
153624 +*//***************************************************************************/
153625 +#define FM_PORT_IOC_GET_MAC_STATISTICS _IOR(FM_IOC_TYPE_BASE, FM_PORT_IOC_NUM(41), ioc_fm_port_mac_statistics_t)
153626 +
153627 +/**************************************************************************//**
153628 + @Function FM_PORT_ConfigBufferPrefixContent
153629 +
153630 + @Description Defines the structure, size and content of the application buffer.
153631 + The prefix will
153632 + In Tx ports, if 'passPrsResult', the application
153633 + should set a value to their offsets in the prefix of
153634 + the FM will save the first 'privDataSize', than,
153635 + depending on 'passPrsResult' and 'passTimeStamp', copy parse result
153636 + and timeStamp, and the packet itself (in this order), to the
153637 + application buffer, and to offset.
153638 + Calling this routine changes the buffer margins definitions
153639 + in the internal driver data base from its default
153640 + configuration: Data size: [DEFAULT_FM_SP_bufferPrefixContent_privDataSize]
153641 + Pass Parser result: [DEFAULT_FM_SP_bufferPrefixContent_passPrsResult].
153642 + Pass timestamp: [DEFAULT_FM_SP_bufferPrefixContent_passTimeStamp].
153643 +
153644 + May be used for all ports
153645 +
153646 + @Param[in] ioc_fm_buffer_prefix_content_t A structure holding the required parameters.
153647 +
153648 + @Return E_OK on success; Error code otherwise.
153649 +
153650 + @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init().
153651 +*//***************************************************************************/
153652 +#define FM_PORT_IOC_CONFIG_BUFFER_PREFIX_CONTENT _IOW(FM_IOC_TYPE_BASE, FM_PORT_IOC_NUM(39), ioc_fm_buffer_prefix_content_t)
153653 +
153654 +#if (DPAA_VERSION >= 11)
153655 +typedef struct ioc_fm_port_vsp_alloc_params_t {
153656 + uint8_t num_of_profiles; /**< Number of Virtual Storage Profiles */
153657 + uint8_t dflt_relative_id; /**< The default Virtual-Storage-Profile-id dedicated to Rx/OP port
153658 + The same default Virtual-Storage-Profile-id will be for coupled Tx port
153659 + if relevant function called for Rx port */
153660 + void *p_fm_tx_port; /**< Handle to coupled Tx Port; not relevant for OP port. */
153661 +}ioc_fm_port_vsp_alloc_params_t;
153662 +
153663 +/**************************************************************************//**
153664 + @Function FM_PORT_VSPAlloc
153665 +
153666 + @Description This routine allocated VSPs per port and forces the port to work
153667 + in VSP mode. Note that the port is initialized by default with the
153668 + physical-storage-profile only.
153669 +
153670 + @Param[in] h_FmPort A handle to a FM Port module.
153671 + @Param[in] p_Params A structure of parameters for allocation VSP's per port
153672 +
153673 + @Return E_OK on success; Error code otherwise.
153674 +
153675 + @Cautions Allowed only following FM_PORT_Init(), and before FM_PORT_SetPCD()
153676 + and also before FM_PORT_Enable() (i.e. the port should be disabled).
153677 +*//***************************************************************************/
153678 +#if defined(CONFIG_COMPAT)
153679 +#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)
153680 +#endif
153681 +#define FM_PORT_IOC_VSP_ALLOC _IOW(FM_IOC_TYPE_BASE, FM_PORT_IOC_NUM(38), ioc_fm_port_vsp_alloc_params_t)
153682 +#endif /* (DPAA_VERSION >= 11) */
153683 +
153684 +/**************************************************************************//**
153685 + @Function FM_PORT_GetBmiCounters
153686 +
153687 + @Description Read port's BMI stat counters and place them into
153688 + a designated structure of counters.
153689 +
153690 + @Param[in] h_FmPort A handle to a FM Port module.
153691 + @Param[out] p_BmiStats counters structure
153692 +
153693 + @Return E_OK on success; Error code otherwise.
153694 +
153695 + @Cautions Allowed only following FM_PORT_Init().
153696 +*//***************************************************************************/
153697 +
153698 +#define FM_PORT_IOC_GET_BMI_COUNTERS _IOR(FM_IOC_TYPE_BASE, FM_PORT_IOC_NUM(42), ioc_fm_port_bmi_stats_t)
153699 +
153700 +typedef struct ioc_fm_port_mac_frame_size_counters_t {
153701 +
153702 + e_CommMode type;
153703 + uint64_t count_pkts_64; /**< 64 byte frame counter */
153704 + uint64_t count_pkts_65_to_127; /**< 65 to 127 byte frame counter */
153705 + uint64_t count_pkts_128_to_255; /**< 128 to 255 byte frame counter */
153706 + uint64_t count_pkts_256_to_511; /**< 256 to 511 byte frame counter */
153707 + uint64_t count_pkts_512_to_1023; /**< 512 to 1023 byte frame counter */
153708 + uint64_t count_pkts_1024_to_1518; /**< 1024 to 1518 byte frame counter */
153709 + uint64_t count_pkts_1519_to_1522; /**< 1519 to 1522 byte good frame count */
153710 +} ioc_fm_port_mac_frame_size_counters_t;
153711 +
153712 +/**************************************************************************//**
153713 + @Function FM_MAC_GetFrameSizeCounters
153714 +
153715 + @Description get MAC statistics counters for different frame size
153716 +
153717 + @Param[out] ioc_fm_port_mac_frame_size_counters_t A structure holding the counters
153718 +
153719 + @Return E_OK on success; Error code otherwise.
153720 +
153721 + @Cautions Allowed only following FM_Init().
153722 +*//***************************************************************************/
153723 +#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)
153724 +
153725 +
153726 +/** @} */ /* end of lnx_ioctl_FM_PORT_pcd_runtime_control_grp group */
153727 +/** @} */ /* end of lnx_ioctl_FM_PORT_runtime_control_grp group */
153728 +
153729 +/** @} */ /* end of lnx_ioctl_FM_PORT_grp group */
153730 +/** @} */ /* end of lnx_ioctl_FM_grp group */
153731 +#endif /* __FM_PORT_IOCTLS_H */
153732 --- /dev/null
153733 +++ b/include/uapi/linux/fmd/Peripherals/fm_test_ioctls.h
153734 @@ -0,0 +1,208 @@
153735 +/* Copyright (c) 2008-2012 Freescale Semiconductor, Inc.
153736 + * All rights reserved.
153737 + *
153738 + * Redistribution and use in source and binary forms, with or without
153739 + * modification, are permitted provided that the following conditions are met:
153740 + * * Redistributions of source code must retain the above copyright
153741 + * notice, this list of conditions and the following disclaimer.
153742 + * * Redistributions in binary form must reproduce the above copyright
153743 + * notice, this list of conditions and the following disclaimer in the
153744 + * documentation and/or other materials provided with the distribution.
153745 + * * Neither the name of Freescale Semiconductor nor the
153746 + * names of its contributors may be used to endorse or promote products
153747 + * derived from this software without specific prior written permission.
153748 + *
153749 + *
153750 + * ALTERNATIVELY, this software may be distributed under the terms of the
153751 + * GNU General Public License ("GPL") as published by the Free Software
153752 + * Foundation, either version 2 of that License or (at your option) any
153753 + * later version.
153754 + *
153755 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
153756 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
153757 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
153758 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
153759 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
153760 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
153761 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
153762 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
153763 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
153764 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
153765 + */
153766 +
153767 +/**************************************************************************//**
153768 + @File fm_test_ioctls.h
153769 +
153770 + @Description FM Char device ioctls
153771 +*//***************************************************************************/
153772 +#ifndef __FM_TEST_IOCTLS_H
153773 +#define __FM_TEST_IOCTLS_H
153774 +
153775 +#include "ioctls.h"
153776 +
153777 +
153778 +/**************************************************************************//**
153779 + @Group lnx_ioctl_FMT_grp Frame Manager Test Linux IOCTL API
153780 +
153781 + @Description FM-Test Linux ioctls definitions and enums
153782 +
153783 + @{
153784 +*//***************************************************************************/
153785 +
153786 +#define IOC_FMT_MAX_NUM_OF_PORTS 26
153787 +
153788 +/**************************************************************************//**
153789 + @Collection TEST Parameters
153790 +*//***************************************************************************/
153791 +/**************************************************************************//**
153792 + @Description: Name of the FM-Test chardev
153793 +*//***************************************************************************/
153794 +#define DEV_FM_TEST_NAME "fm-test-port"
153795 +
153796 +#define DEV_FM_TEST_PORTS_MINOR_BASE 0
153797 +#define DEV_FM_TEST_MAX_MINORS (DEV_FM_TEST_PORTS_MINOR_BASE + IOC_FMT_MAX_NUM_OF_PORTS)
153798 +
153799 +#define FMT_PORT_IOC_NUM(n) n
153800 +/* @} */
153801 +
153802 +/**************************************************************************//**
153803 + @Group lnx_ioctl_FMT_lib_grp FM-Test library
153804 +
153805 + @Description TODO
153806 +
153807 + @{
153808 +*//***************************************************************************/
153809 +
153810 +/**************************************************************************//**
153811 + @Description TODO
153812 +*//***************************************************************************/
153813 +typedef uint8_t ioc_fmt_xxx_t;
153814 +
153815 +#define FM_PRS_MAX 32
153816 +#define FM_TIME_STAMP_MAX 8
153817 +
153818 +/**************************************************************************//**
153819 + @Description FM Port buffer content description
153820 +*//***************************************************************************/
153821 +typedef struct ioc_fmt_buff_context_t {
153822 + void *p_user_priv;
153823 + uint8_t fm_prs_res[FM_PRS_MAX];
153824 + uint8_t fm_time_stamp[FM_TIME_STAMP_MAX];
153825 +} ioc_fmt_buff_context_t;
153826 +
153827 +#if defined(__KERNEL__) && defined(CONFIG_COMPAT)
153828 +typedef struct ioc_fmt_compat_buff_context_t {
153829 + compat_uptr_t p_user_priv;
153830 + uint8_t fm_prs_res[FM_PRS_MAX];
153831 + uint8_t fm_time_stamp[FM_TIME_STAMP_MAX];
153832 +} ioc_fmt_compat_buff_context_t;
153833 +#endif
153834 +
153835 +/**************************************************************************//**
153836 + @Description Buffer descriptor
153837 +*//***************************************************************************/
153838 +typedef struct ioc_fmt_buff_desc_t {
153839 + uint32_t qid;
153840 + void *p_data;
153841 + uint32_t size;
153842 + uint32_t status;
153843 + ioc_fmt_buff_context_t buff_context;
153844 +} ioc_fmt_buff_desc_t;
153845 +
153846 +#if defined(__KERNEL__) && defined(CONFIG_COMPAT)
153847 +typedef struct ioc_fmt_compat_buff_desc_t {
153848 + uint32_t qid;
153849 + compat_uptr_t p_data;
153850 + uint32_t size;
153851 + uint32_t status;
153852 + ioc_fmt_compat_buff_context_t buff_context;
153853 +} ioc_fmt_compat_buff_desc_t;
153854 +#endif
153855 +
153856 +/**************************************************************************//**
153857 + @Group lnx_ioctl_FMT_runtime_control_grp FM-Test Runtime Control Unit
153858 +
153859 + @Description TODO
153860 + @{
153861 +*//***************************************************************************/
153862 +
153863 +/** @} */ /* end of lnx_ioctl_FMT_runtime_control_grp group */
153864 +
153865 +
153866 +/**************************************************************************//**
153867 + @Group lnx_ioctl_FMTP_lib_grp FM-Port-Test library
153868 +
153869 + @Description TODO
153870 +
153871 + @{
153872 +*//***************************************************************************/
153873 +
153874 +/**************************************************************************//**
153875 + @Description FM-Test FM port type
153876 +*//***************************************************************************/
153877 +typedef enum ioc_fmt_port_type {
153878 + e_IOC_FMT_PORT_T_RXTX, /**< Standard port */
153879 + e_IOC_FMT_PORT_T_OP, /**< Offline-parsing port */
153880 +} ioc_fmt_port_type;
153881 +
153882 +/**************************************************************************//**
153883 + @Description TODO
153884 +*//***************************************************************************/
153885 +typedef struct ioc_fmt_port_param_t {
153886 + uint8_t fm_id;
153887 + ioc_fmt_port_type fm_port_type;
153888 + uint8_t fm_port_id;
153889 + uint32_t num_tx_queues;
153890 +} ioc_fmt_port_param_t;
153891 +
153892 +
153893 +/**************************************************************************//**
153894 + @Function FMT_PORT_IOC_INIT
153895 +
153896 + @Description TODO
153897 +
153898 + @Param[in] ioc_fmt_port_param_t TODO
153899 +
153900 + @Cautions Allowed only after the FM equivalent port is already initialized.
153901 +*//***************************************************************************/
153902 +#define FMT_PORT_IOC_INIT _IOW(FMT_IOC_TYPE_BASE, FMT_PORT_IOC_NUM(0), ioc_fmt_port_param_t)
153903 +
153904 +/**************************************************************************//**
153905 + @Function FMT_PORT_IOC_SET_DIAG_MODE
153906 +
153907 + @Description TODO
153908 +
153909 + @Param[in] ioc_diag_mode TODO
153910 +
153911 + @Cautions Allowed only following FMT_PORT_IOC_INIT().
153912 +*//***************************************************************************/
153913 +#define FMT_PORT_IOC_SET_DIAG_MODE _IOW(FMT_IOC_TYPE_BASE, FMT_PORT_IOC_NUM(1), ioc_diag_mode)
153914 +
153915 +/**************************************************************************//**
153916 + @Function FMT_PORT_IOC_SET_IP_HEADER_MANIP
153917 +
153918 + @Description Set IP header manipulations for this port.
153919 +
153920 + @Param[in] int 1 to enable; 0 to disable
153921 +
153922 + @Cautions Allowed only following FMT_PORT_IOC_INIT().
153923 +*//***************************************************************************/
153924 +#define FMT_PORT_IOC_SET_IP_HEADER_MANIP _IOW(FMT_IOC_TYPE_BASE, FMT_PORT_IOC_NUM(2), int)
153925 +
153926 +/**************************************************************************//**
153927 + @Function FMT_PORT_IOC_SET_DPAECHO_MODE
153928 +
153929 + @Description Set DPA in echo mode - all frame are sent back.
153930 +
153931 + @Param[in] int 1 to enable; 0 to disable
153932 +
153933 + @Cautions Allowed only following FMT_PORT_IOC_INIT().
153934 +*//***************************************************************************/
153935 +#define FMT_PORT_IOC_SET_DPAECHO_MODE _IOW(FMT_IOC_TYPE_BASE, FMT_PORT_IOC_NUM(3), int)
153936 +
153937 +/** @} */ /* end of lnx_ioctl_FMTP_lib_grp group */
153938 +/** @} */ /* end of lnx_ioctl_FMT_lib_grp group */
153939 +/** @} */ /* end of lnx_ioctl_FMT_grp */
153940 +
153941 +
153942 +#endif /* __FM_TEST_IOCTLS_H */
153943 --- /dev/null
153944 +++ b/include/uapi/linux/fmd/integrations/Kbuild
153945 @@ -0,0 +1 @@
153946 +header-y += integration_ioctls.h
153947 --- /dev/null
153948 +++ b/include/uapi/linux/fmd/integrations/integration_ioctls.h
153949 @@ -0,0 +1,56 @@
153950 +/* Copyright (c) 2008-2012 Freescale Semiconductor, Inc.
153951 + * All rights reserved.
153952 + *
153953 + * Redistribution and use in source and binary forms, with or without
153954 + * modification, are permitted provided that the following conditions are met:
153955 + * * Redistributions of source code must retain the above copyright
153956 + * notice, this list of conditions and the following disclaimer.
153957 + * * Redistributions in binary form must reproduce the above copyright
153958 + * notice, this list of conditions and the following disclaimer in the
153959 + * documentation and/or other materials provided with the distribution.
153960 + * * Neither the name of Freescale Semiconductor nor the
153961 + * names of its contributors may be used to endorse or promote products
153962 + * derived from this software without specific prior written permission.
153963 + *
153964 + *
153965 + * ALTERNATIVELY, this software may be distributed under the terms of the
153966 + * GNU General Public License ("GPL") as published by the Free Software
153967 + * Foundation, either version 2 of that License or (at your option) any
153968 + * later version.
153969 + *
153970 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
153971 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
153972 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
153973 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
153974 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
153975 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
153976 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
153977 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
153978 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
153979 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
153980 + */
153981 +
153982 +/**************************************************************************//**
153983 + @File integration_ioctls.h
153984 +
153985 + @Description External header file for Integration unit routines.
153986 +*//***************************************************************************/
153987 +
153988 +#ifndef __INTG_IOCTLS_H
153989 +#define __INTG_IOCTLS_H
153990 +
153991 +
153992 +#define FM_IOC_TYPE_BASE (NCSW_IOC_TYPE_BASE+1)
153993 +#define FMT_IOC_TYPE_BASE (NCSW_IOC_TYPE_BASE+3)
153994 +
153995 +/*#define FM_IOCTL_DBG*/
153996 +
153997 +#if defined(FM_IOCTL_DBG)
153998 + #define _fm_ioctl_dbg(format, arg...) \
153999 + printk("fm ioctl [%s:%u](cpu:%u) - " format, \
154000 + __func__, __LINE__, smp_processor_id(), ##arg)
154001 +#else
154002 +# define _fm_ioctl_dbg(arg...)
154003 +#endif
154004 +
154005 +#endif /* __INTG_IOCTLS_H */
154006 --- /dev/null
154007 +++ b/include/uapi/linux/fmd/ioctls.h
154008 @@ -0,0 +1,96 @@
154009 +/* Copyright (c) 2008-2012 Freescale Semiconductor, Inc.
154010 + * All rights reserved.
154011 + *
154012 + * Redistribution and use in source and binary forms, with or without
154013 + * modification, are permitted provided that the following conditions are met:
154014 + * * Redistributions of source code must retain the above copyright
154015 + * notice, this list of conditions and the following disclaimer.
154016 + * * Redistributions in binary form must reproduce the above copyright
154017 + * notice, this list of conditions and the following disclaimer in the
154018 + * documentation and/or other materials provided with the distribution.
154019 + * * Neither the name of Freescale Semiconductor nor the
154020 + * names of its contributors may be used to endorse or promote products
154021 + * derived from this software without specific prior written permission.
154022 + *
154023 + *
154024 + * ALTERNATIVELY, this software may be distributed under the terms of the
154025 + * GNU General Public License ("GPL") as published by the Free Software
154026 + * Foundation, either version 2 of that License or (at your option) any
154027 + * later version.
154028 + *
154029 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
154030 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
154031 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
154032 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
154033 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
154034 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
154035 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
154036 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
154037 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
154038 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
154039 + */
154040 +
154041 +/**************************************************************************//**
154042 + @File ioctls.h
154043 +
154044 + @Description Structures and definitions for Command Relay Ioctls
154045 +*//***************************************************************************/
154046 +
154047 +#ifndef __IOCTLS_H__
154048 +#define __IOCTLS_H__
154049 +
154050 +#include <asm/ioctl.h>
154051 +
154052 +#include "integration_ioctls.h"
154053 +
154054 +
154055 +/**************************************************************************//**
154056 + @Group lnx_ioctl_ncsw_grp NetCommSw Linux User-Space (IOCTL) API
154057 + @{
154058 +*//***************************************************************************/
154059 +
154060 +#define NCSW_IOC_TYPE_BASE 0xe0 /**< defines the IOCTL type for all
154061 + the NCSW Linux module commands */
154062 +
154063 +
154064 +/**************************************************************************//**
154065 + @Description IOCTL Memory allocation types.
154066 +*//***************************************************************************/
154067 +typedef enum ioc_mem_type {
154068 + e_IOC_MEM_INVALID = 0x00000000, /**< Invalid memory type (error) */
154069 + e_IOC_MEM_CACHABLE_SYS = 0x00000001, /**< Primary DDR, cacheable segment */
154070 + e_IOC_MEM_NOCACHE_SYS = 0x00000004, /**< Primary DDR, non-cacheable segment */
154071 + e_IOC_MEM_SECONDARY = 0x00000002, /**< Either secondary DDR or SDRAM */
154072 + e_IOC_MEM_PRAM = 0x00000008 /**< Multi-user RAM identifier */
154073 +} ioc_mem_type;
154074 +
154075 +/**************************************************************************//**
154076 + @Description Enumeration (bit flags) of communication modes (Transmit,
154077 + receive or both).
154078 +*//***************************************************************************/
154079 +typedef enum ioc_comm_mode {
154080 + e_IOC_COMM_MODE_NONE = 0 /**< No transmit/receive communication */
154081 + , e_IOC_COMM_MODE_RX = 1 /**< Only receive communication */
154082 + , e_IOC_COMM_MODE_TX = 2 /**< Only transmit communication */
154083 + , e_IOC_COMM_MODE_RX_AND_TX = 3 /**< Both transmit and receive communication */
154084 +} ioc_comm_mode;
154085 +
154086 +/**************************************************************************//**
154087 + @Description General Diagnostic Mode
154088 +*//***************************************************************************/
154089 +typedef enum ioc_diag_mode
154090 +{
154091 + e_IOC_DIAG_MODE_NONE = 0,
154092 + e_IOC_DIAG_MODE_CTRL_LOOPBACK, /**< loopback in the controller; E.g. MAC, TDM, etc. */
154093 + e_IOC_DIAG_MODE_CHIP_LOOPBACK, /**< loopback in the chip but not in controller;
154094 + E.g. IO-pins, SerDes, etc. */
154095 + e_IOC_DIAG_MODE_PHY_LOOPBACK, /**< loopback in the external PHY */
154096 + e_IOC_DIAG_MODE_LINE_LOOPBACK, /**< loopback in the external line */
154097 + e_IOC_DIAG_MODE_CTRL_ECHO, /**< */
154098 + e_IOC_DIAG_MODE_PHY_ECHO /**< */
154099 +} ioc_diag_mode;
154100 +
154101 +/** @} */ /* end of lnx_ioctl_ncsw_grp */
154102 +
154103 +
154104 +#endif /* __IOCTLS_H__ */
154105 --- /dev/null
154106 +++ b/include/uapi/linux/fmd/net_ioctls.h
154107 @@ -0,0 +1,430 @@
154108 +/* Copyright (c) 2008-2012 Freescale Semiconductor, Inc.
154109 + * All rights reserved.
154110 + *
154111 + * Redistribution and use in source and binary forms, with or without
154112 + * modification, are permitted provided that the following conditions are met:
154113 + * * Redistributions of source code must retain the above copyright
154114 + * notice, this list of conditions and the following disclaimer.
154115 + * * Redistributions in binary form must reproduce the above copyright
154116 + * notice, this list of conditions and the following disclaimer in the
154117 + * documentation and/or other materials provided with the distribution.
154118 + * * Neither the name of Freescale Semiconductor nor the
154119 + * names of its contributors may be used to endorse or promote products
154120 + * derived from this software without specific prior written permission.
154121 + *
154122 + *
154123 + * ALTERNATIVELY, this software may be distributed under the terms of the
154124 + * GNU General Public License ("GPL") as published by the Free Software
154125 + * Foundation, either version 2 of that License or (at your option) any
154126 + * later version.
154127 + *
154128 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
154129 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
154130 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
154131 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
154132 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
154133 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
154134 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
154135 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
154136 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
154137 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
154138 + */
154139 +
154140 +
154141 +/**************************************************************************//**
154142 + @File net_ioctls.h
154143 +
154144 + @Description This file contains common and general netcomm headers definitions.
154145 +*//***************************************************************************/
154146 +#ifndef __NET_IOCTLS_H
154147 +#define __NET_IOCTLS_H
154148 +
154149 +#include "ioctls.h"
154150 +
154151 +
154152 +typedef uint8_t ioc_header_field_ppp_t;
154153 +
154154 +#define IOC_NET_HEADER_FIELD_PPP_PID (1)
154155 +#define IOC_NET_HEADER_FIELD_PPP_COMPRESSED (IOC_NET_HEADER_FIELD_PPP_PID << 1)
154156 +#define IOC_NET_HEADER_FIELD_PPP_ALL_FIELDS ((IOC_NET_HEADER_FIELD_PPP_PID << 2) - 1)
154157 +
154158 +
154159 +typedef uint8_t ioc_header_field_pppoe_t;
154160 +
154161 +#define IOC_NET_HEADER_FIELD_PPPoE_VER (1)
154162 +#define IOC_NET_HEADER_FIELD_PPPoE_TYPE (IOC_NET_HEADER_FIELD_PPPoE_VER << 1)
154163 +#define IOC_NET_HEADER_FIELD_PPPoE_CODE (IOC_NET_HEADER_FIELD_PPPoE_VER << 2)
154164 +#define IOC_NET_HEADER_FIELD_PPPoE_SID (IOC_NET_HEADER_FIELD_PPPoE_VER << 3)
154165 +#define IOC_NET_HEADER_FIELD_PPPoE_LEN (IOC_NET_HEADER_FIELD_PPPoE_VER << 4)
154166 +#define IOC_NET_HEADER_FIELD_PPPoE_SESSION (IOC_NET_HEADER_FIELD_PPPoE_VER << 5)
154167 +#define IOC_NET_HEADER_FIELD_PPPoE_PID (IOC_NET_HEADER_FIELD_PPPoE_VER << 6)
154168 +#define IOC_NET_HEADER_FIELD_PPPoE_ALL_FIELDS ((IOC_NET_HEADER_FIELD_PPPoE_VER << 7) - 1)
154169 +
154170 +#define IOC_NET_HEADER_FIELD_PPPMUX_PID (1)
154171 +#define IOC_NET_HEADER_FIELD_PPPMUX_CKSUM (IOC_NET_HEADER_FIELD_PPPMUX_PID << 1)
154172 +#define IOC_NET_HEADER_FIELD_PPPMUX_COMPRESSED (IOC_NET_HEADER_FIELD_PPPMUX_PID << 2)
154173 +#define IOC_NET_HEADER_FIELD_PPPMUX_ALL_FIELDS ((IOC_NET_HEADER_FIELD_PPPMUX_PID << 3) - 1)
154174 +
154175 +#define IOC_NET_HEADER_FIELD_PPPMUX_SUBFRAME_PFF (1)
154176 +#define IOC_NET_HEADER_FIELD_PPPMUX_SUBFRAME_LXT (IOC_NET_HEADER_FIELD_PPPMUX_SUBFRAME_PFF << 1)
154177 +#define IOC_NET_HEADER_FIELD_PPPMUX_SUBFRAME_LEN (IOC_NET_HEADER_FIELD_PPPMUX_SUBFRAME_PFF << 2)
154178 +#define IOC_NET_HEADER_FIELD_PPPMUX_SUBFRAME_PID (IOC_NET_HEADER_FIELD_PPPMUX_SUBFRAME_PFF << 3)
154179 +#define IOC_NET_HEADER_FIELD_PPPMUX_SUBFRAME_USE_PID (IOC_NET_HEADER_FIELD_PPPMUX_SUBFRAME_PFF << 4)
154180 +#define IOC_NET_HEADER_FIELD_PPPMUX_SUBFRAME_ALL_FIELDS ((IOC_NET_HEADER_FIELD_PPPMUX_SUBFRAME_PFF << 5) - 1)
154181 +
154182 +
154183 +typedef uint8_t ioc_header_field_eth_t;
154184 +
154185 +#define IOC_NET_HEADER_FIELD_ETH_DA (1)
154186 +#define IOC_NET_HEADER_FIELD_ETH_SA (IOC_NET_HEADER_FIELD_ETH_DA << 1)
154187 +#define IOC_NET_HEADER_FIELD_ETH_LENGTH (IOC_NET_HEADER_FIELD_ETH_DA << 2)
154188 +#define IOC_NET_HEADER_FIELD_ETH_TYPE (IOC_NET_HEADER_FIELD_ETH_DA << 3)
154189 +#define IOC_NET_HEADER_FIELD_ETH_FINAL_CKSUM (IOC_NET_HEADER_FIELD_ETH_DA << 4)
154190 +#define IOC_NET_HEADER_FIELD_ETH_PADDING (IOC_NET_HEADER_FIELD_ETH_DA << 5)
154191 +#define IOC_NET_HEADER_FIELD_ETH_ALL_FIELDS ((IOC_NET_HEADER_FIELD_ETH_DA << 6) - 1)
154192 +
154193 +#define IOC_NET_HEADER_FIELD_ETH_ADDR_SIZE 6
154194 +
154195 +typedef uint16_t ioc_header_field_ip_t;
154196 +
154197 +#define IOC_NET_HEADER_FIELD_IP_VER (1)
154198 +#define IOC_NET_HEADER_FIELD_IP_DSCP (IOC_NET_HEADER_FIELD_IP_VER << 2)
154199 +#define IOC_NET_HEADER_FIELD_IP_ECN (IOC_NET_HEADER_FIELD_IP_VER << 3)
154200 +#define IOC_NET_HEADER_FIELD_IP_PROTO (IOC_NET_HEADER_FIELD_IP_VER << 4)
154201 +
154202 +#define IOC_NET_HEADER_FIELD_IP_PROTO_SIZE 1
154203 +
154204 +typedef uint16_t ioc_header_field_ipv4_t;
154205 +
154206 +#define IOC_NET_HEADER_FIELD_IPv4_VER (1)
154207 +#define IOC_NET_HEADER_FIELD_IPv4_HDR_LEN (IOC_NET_HEADER_FIELD_IPv4_VER << 1)
154208 +#define IOC_NET_HEADER_FIELD_IPv4_TOS (IOC_NET_HEADER_FIELD_IPv4_VER << 2)
154209 +#define IOC_NET_HEADER_FIELD_IPv4_TOTAL_LEN (IOC_NET_HEADER_FIELD_IPv4_VER << 3)
154210 +#define IOC_NET_HEADER_FIELD_IPv4_ID (IOC_NET_HEADER_FIELD_IPv4_VER << 4)
154211 +#define IOC_NET_HEADER_FIELD_IPv4_FLAG_D (IOC_NET_HEADER_FIELD_IPv4_VER << 5)
154212 +#define IOC_NET_HEADER_FIELD_IPv4_FLAG_M (IOC_NET_HEADER_FIELD_IPv4_VER << 6)
154213 +#define IOC_NET_HEADER_FIELD_IPv4_OFFSET (IOC_NET_HEADER_FIELD_IPv4_VER << 7)
154214 +#define IOC_NET_HEADER_FIELD_IPv4_TTL (IOC_NET_HEADER_FIELD_IPv4_VER << 8)
154215 +#define IOC_NET_HEADER_FIELD_IPv4_PROTO (IOC_NET_HEADER_FIELD_IPv4_VER << 9)
154216 +#define IOC_NET_HEADER_FIELD_IPv4_CKSUM (IOC_NET_HEADER_FIELD_IPv4_VER << 10)
154217 +#define IOC_NET_HEADER_FIELD_IPv4_SRC_IP (IOC_NET_HEADER_FIELD_IPv4_VER << 11)
154218 +#define IOC_NET_HEADER_FIELD_IPv4_DST_IP (IOC_NET_HEADER_FIELD_IPv4_VER << 12)
154219 +#define IOC_NET_HEADER_FIELD_IPv4_OPTS (IOC_NET_HEADER_FIELD_IPv4_VER << 13)
154220 +#define IOC_NET_HEADER_FIELD_IPv4_OPTS_COUNT (IOC_NET_HEADER_FIELD_IPv4_VER << 14)
154221 +#define IOC_NET_HEADER_FIELD_IPv4_ALL_FIELDS ((IOC_NET_HEADER_FIELD_IPv4_VER << 15) - 1)
154222 +
154223 +#define IOC_NET_HEADER_FIELD_IPv4_ADDR_SIZE 4
154224 +#define IOC_NET_HEADER_FIELD_IPv4_PROTO_SIZE 1
154225 +
154226 +
154227 +typedef uint8_t ioc_header_field_ipv6_t;
154228 +
154229 +#define IOC_NET_HEADER_FIELD_IPv6_VER (1)
154230 +#define IOC_NET_HEADER_FIELD_IPv6_TC (IOC_NET_HEADER_FIELD_IPv6_VER << 1)
154231 +#define IOC_NET_HEADER_FIELD_IPv6_SRC_IP (IOC_NET_HEADER_FIELD_IPv6_VER << 2)
154232 +#define IOC_NET_HEADER_FIELD_IPv6_DST_IP (IOC_NET_HEADER_FIELD_IPv6_VER << 3)
154233 +#define IOC_NET_HEADER_FIELD_IPv6_NEXT_HDR (IOC_NET_HEADER_FIELD_IPv6_VER << 4)
154234 +#define IOC_NET_HEADER_FIELD_IPv6_FL (IOC_NET_HEADER_FIELD_IPv6_VER << 5)
154235 +#define IOC_NET_HEADER_FIELD_IPv6_HOP_LIMIT (IOC_NET_HEADER_FIELD_IPv6_VER << 6)
154236 +#define IOC_NET_HEADER_FIELD_IPv6_ALL_FIELDS ((IOC_NET_HEADER_FIELD_IPv6_VER << 7) - 1)
154237 +
154238 +#define IOC_NET_HEADER_FIELD_IPv6_ADDR_SIZE 16
154239 +#define IOC_NET_HEADER_FIELD_IPv6_NEXT_HDR_SIZE 1
154240 +
154241 +#define IOC_NET_HEADER_FIELD_ICMP_TYPE (1)
154242 +#define IOC_NET_HEADER_FIELD_ICMP_CODE (IOC_NET_HEADER_FIELD_ICMP_TYPE << 1)
154243 +#define IOC_NET_HEADER_FIELD_ICMP_CKSUM (IOC_NET_HEADER_FIELD_ICMP_TYPE << 2)
154244 +#define IOC_NET_HEADER_FIELD_ICMP_ID (IOC_NET_HEADER_FIELD_ICMP_TYPE << 3)
154245 +#define IOC_NET_HEADER_FIELD_ICMP_SQ_NUM (IOC_NET_HEADER_FIELD_ICMP_TYPE << 4)
154246 +#define IOC_NET_HEADER_FIELD_ICMP_ALL_FIELDS ((IOC_NET_HEADER_FIELD_ICMP_TYPE << 5) - 1)
154247 +
154248 +#define IOC_NET_HEADER_FIELD_ICMP_CODE_SIZE 1
154249 +#define IOC_NET_HEADER_FIELD_ICMP_TYPE_SIZE 1
154250 +
154251 +#define IOC_NET_HEADER_FIELD_IGMP_VERSION (1)
154252 +#define IOC_NET_HEADER_FIELD_IGMP_TYPE (IOC_NET_HEADER_FIELD_IGMP_VERSION << 1)
154253 +#define IOC_NET_HEADER_FIELD_IGMP_CKSUM (IOC_NET_HEADER_FIELD_IGMP_VERSION << 2)
154254 +#define IOC_NET_HEADER_FIELD_IGMP_DATA (IOC_NET_HEADER_FIELD_IGMP_VERSION << 3)
154255 +#define IOC_NET_HEADER_FIELD_IGMP_ALL_FIELDS ((IOC_NET_HEADER_FIELD_IGMP_VERSION << 4) - 1)
154256 +
154257 +
154258 +typedef uint16_t ioc_header_field_tcp_t;
154259 +
154260 +#define IOC_NET_HEADER_FIELD_TCP_PORT_SRC (1)
154261 +#define IOC_NET_HEADER_FIELD_TCP_PORT_DST (IOC_NET_HEADER_FIELD_TCP_PORT_SRC << 1)
154262 +#define IOC_NET_HEADER_FIELD_TCP_SEQ (IOC_NET_HEADER_FIELD_TCP_PORT_SRC << 2)
154263 +#define IOC_NET_HEADER_FIELD_TCP_ACK (IOC_NET_HEADER_FIELD_TCP_PORT_SRC << 3)
154264 +#define IOC_NET_HEADER_FIELD_TCP_OFFSET (IOC_NET_HEADER_FIELD_TCP_PORT_SRC << 4)
154265 +#define IOC_NET_HEADER_FIELD_TCP_FLAGS (IOC_NET_HEADER_FIELD_TCP_PORT_SRC << 5)
154266 +#define IOC_NET_HEADER_FIELD_TCP_WINDOW (IOC_NET_HEADER_FIELD_TCP_PORT_SRC << 6)
154267 +#define IOC_NET_HEADER_FIELD_TCP_CKSUM (IOC_NET_HEADER_FIELD_TCP_PORT_SRC << 7)
154268 +#define IOC_NET_HEADER_FIELD_TCP_URGPTR (IOC_NET_HEADER_FIELD_TCP_PORT_SRC << 8)
154269 +#define IOC_NET_HEADER_FIELD_TCP_OPTS (IOC_NET_HEADER_FIELD_TCP_PORT_SRC << 9)
154270 +#define IOC_NET_HEADER_FIELD_TCP_OPTS_COUNT (IOC_NET_HEADER_FIELD_TCP_PORT_SRC << 10)
154271 +#define IOC_NET_HEADER_FIELD_TCP_ALL_FIELDS ((IOC_NET_HEADER_FIELD_TCP_PORT_SRC << 11) - 1)
154272 +
154273 +#define IOC_NET_HEADER_FIELD_TCP_PORT_SIZE 2
154274 +
154275 +
154276 +typedef uint8_t ioc_header_field_sctp_t;
154277 +
154278 +#define IOC_NET_HEADER_FIELD_SCTP_PORT_SRC (1)
154279 +#define IOC_NET_HEADER_FIELD_SCTP_PORT_DST (IOC_NET_HEADER_FIELD_SCTP_PORT_SRC << 1)
154280 +#define IOC_NET_HEADER_FIELD_SCTP_VER_TAG (IOC_NET_HEADER_FIELD_SCTP_PORT_SRC << 2)
154281 +#define IOC_NET_HEADER_FIELD_SCTP_CKSUM (IOC_NET_HEADER_FIELD_SCTP_PORT_SRC << 3)
154282 +#define IOC_NET_HEADER_FIELD_SCTP_ALL_FIELDS ((IOC_NET_HEADER_FIELD_SCTP_PORT_SRC << 4) - 1)
154283 +
154284 +#define IOC_NET_HEADER_FIELD_SCTP_PORT_SIZE 2
154285 +
154286 +typedef uint8_t ioc_header_field_dccp_t;
154287 +
154288 +#define IOC_NET_HEADER_FIELD_DCCP_PORT_SRC (1)
154289 +#define IOC_NET_HEADER_FIELD_DCCP_PORT_DST (IOC_NET_HEADER_FIELD_DCCP_PORT_SRC << 1)
154290 +#define IOC_NET_HEADER_FIELD_DCCP_ALL_FIELDS ((IOC_NET_HEADER_FIELD_DCCP_PORT_SRC << 2) - 1)
154291 +
154292 +#define IOC_NET_HEADER_FIELD_DCCP_PORT_SIZE 2
154293 +
154294 +
154295 +typedef uint8_t ioc_header_field_udp_t;
154296 +
154297 +#define IOC_NET_HEADER_FIELD_UDP_PORT_SRC (1)
154298 +#define IOC_NET_HEADER_FIELD_UDP_PORT_DST (IOC_NET_HEADER_FIELD_UDP_PORT_SRC << 1)
154299 +#define IOC_NET_HEADER_FIELD_UDP_LEN (IOC_NET_HEADER_FIELD_UDP_PORT_SRC << 2)
154300 +#define IOC_NET_HEADER_FIELD_UDP_CKSUM (IOC_NET_HEADER_FIELD_UDP_PORT_SRC << 3)
154301 +#define IOC_NET_HEADER_FIELD_UDP_ALL_FIELDS ((IOC_NET_HEADER_FIELD_UDP_PORT_SRC << 4) - 1)
154302 +
154303 +#define IOC_NET_HEADER_FIELD_UDP_PORT_SIZE 2
154304 +
154305 +typedef uint8_t ioc_header_field_udp_lite_t;
154306 +
154307 +#define IOC_NET_HEADER_FIELD_UDP_LITE_PORT_SRC (1)
154308 +#define IOC_NET_HEADER_FIELD_UDP_LITE_PORT_DST (IOC_NET_HEADER_FIELD_UDP_LITE_PORT_SRC << 1)
154309 +#define IOC_NET_HEADER_FIELD_UDP_LITE_ALL_FIELDS ((IOC_NET_HEADER_FIELD_UDP_LITE_PORT_SRC << 2) - 1)
154310 +
154311 +#define IOC_NET_HEADER_FIELD_UDP_LITE_PORT_SIZE 2
154312 +
154313 +typedef uint8_t ioc_header_field_udp_encap_esp_t;
154314 +
154315 +#define IOC_NET_HEADER_FIELD_UDP_ENCAP_ESP_PORT_SRC (1)
154316 +#define IOC_NET_HEADER_FIELD_UDP_ENCAP_ESP_PORT_DST (IOC_NET_HEADER_FIELD_UDP_ENCAP_ESP_PORT_SRC << 1)
154317 +#define IOC_NET_HEADER_FIELD_UDP_ENCAP_ESP_LEN (IOC_NET_HEADER_FIELD_UDP_ENCAP_ESP_PORT_SRC << 2)
154318 +#define IOC_NET_HEADER_FIELD_UDP_ENCAP_ESP_CKSUM (IOC_NET_HEADER_FIELD_UDP_ENCAP_ESP_PORT_SRC << 3)
154319 +#define IOC_NET_HEADER_FIELD_UDP_ENCAP_ESP_SPI (IOC_NET_HEADER_FIELD_UDP_ENCAP_ESP_PORT_SRC << 4)
154320 +#define IOC_NET_HEADER_FIELD_UDP_ENCAP_ESP_SEQUENCE_NUM (IOC_NET_HEADER_FIELD_UDP_ENCAP_ESP_PORT_SRC << 5)
154321 +#define IOC_NET_HEADER_FIELD_UDP_ENCAP_ESP_ALL_FIELDS ((IOC_NET_HEADER_FIELD_UDP_ENCAP_ESP_PORT_SRC << 6) - 1)
154322 +
154323 +#define IOC_NET_HEADER_FIELD_UDP_ENCAP_ESP_PORT_SIZE 2
154324 +#define IOC_NET_HEADER_FIELD_UDP_ENCAP_ESP_SPI_SIZE 4
154325 +
154326 +#define IOC_NET_HEADER_FIELD_IPHC_CID (1)
154327 +#define IOC_NET_HEADER_FIELD_IPHC_CID_TYPE (IOC_NET_HEADER_FIELD_IPHC_CID << 1)
154328 +#define IOC_NET_HEADER_FIELD_IPHC_HCINDEX (IOC_NET_HEADER_FIELD_IPHC_CID << 2)
154329 +#define IOC_NET_HEADER_FIELD_IPHC_GEN (IOC_NET_HEADER_FIELD_IPHC_CID << 3)
154330 +#define IOC_NET_HEADER_FIELD_IPHC_D_BIT (IOC_NET_HEADER_FIELD_IPHC_CID << 4)
154331 +#define IOC_NET_HEADER_FIELD_IPHC_ALL_FIELDS ((IOC_NET_HEADER_FIELD_IPHC_CID << 5) - 1)
154332 +
154333 +#define IOC_NET_HEADER_FIELD_SCTP_CHUNK_DATA_TYPE (1)
154334 +#define IOC_NET_HEADER_FIELD_SCTP_CHUNK_DATA_FLAGS (IOC_NET_HEADER_FIELD_SCTP_CHUNK_DATA_TYPE << 1)
154335 +#define IOC_NET_HEADER_FIELD_SCTP_CHUNK_DATA_LENGTH (IOC_NET_HEADER_FIELD_SCTP_CHUNK_DATA_TYPE << 2)
154336 +#define IOC_NET_HEADER_FIELD_SCTP_CHUNK_DATA_TSN (IOC_NET_HEADER_FIELD_SCTP_CHUNK_DATA_TYPE << 3)
154337 +#define IOC_NET_HEADER_FIELD_SCTP_CHUNK_DATA_STREAM_ID (IOC_NET_HEADER_FIELD_SCTP_CHUNK_DATA_TYPE << 4)
154338 +#define IOC_NET_HEADER_FIELD_SCTP_CHUNK_DATA_STREAM_SQN (IOC_NET_HEADER_FIELD_SCTP_CHUNK_DATA_TYPE << 5)
154339 +#define IOC_NET_HEADER_FIELD_SCTP_CHUNK_DATA_PAYLOAD_PID (IOC_NET_HEADER_FIELD_SCTP_CHUNK_DATA_TYPE << 6)
154340 +#define IOC_NET_HEADER_FIELD_SCTP_CHUNK_DATA_UNORDERED (IOC_NET_HEADER_FIELD_SCTP_CHUNK_DATA_TYPE << 7)
154341 +#define IOC_NET_HEADER_FIELD_SCTP_CHUNK_DATA_BEGGINING (IOC_NET_HEADER_FIELD_SCTP_CHUNK_DATA_TYPE << 8)
154342 +#define IOC_NET_HEADER_FIELD_SCTP_CHUNK_DATA_END (IOC_NET_HEADER_FIELD_SCTP_CHUNK_DATA_TYPE << 9)
154343 +#define IOC_NET_HEADER_FIELD_SCTP_CHUNK_DATA_ALL_FIELDS ((IOC_NET_HEADER_FIELD_SCTP_CHUNK_DATA_TYPE << 10) - 1)
154344 +
154345 +#define IOC_NET_HEADER_FIELD_L2TPv2_TYPE_BIT (1)
154346 +#define IOC_NET_HEADER_FIELD_L2TPv2_LENGTH_BIT (IOC_NET_HEADER_FIELD_L2TPv2_TYPE_BIT << 1)
154347 +#define IOC_NET_HEADER_FIELD_L2TPv2_SEQUENCE_BIT (IOC_NET_HEADER_FIELD_L2TPv2_TYPE_BIT << 2)
154348 +#define IOC_NET_HEADER_FIELD_L2TPv2_OFFSET_BIT (IOC_NET_HEADER_FIELD_L2TPv2_TYPE_BIT << 3)
154349 +#define IOC_NET_HEADER_FIELD_L2TPv2_PRIORITY_BIT (IOC_NET_HEADER_FIELD_L2TPv2_TYPE_BIT << 4)
154350 +#define IOC_NET_HEADER_FIELD_L2TPv2_VERSION (IOC_NET_HEADER_FIELD_L2TPv2_TYPE_BIT << 5)
154351 +#define IOC_NET_HEADER_FIELD_L2TPv2_LEN (IOC_NET_HEADER_FIELD_L2TPv2_TYPE_BIT << 6)
154352 +#define IOC_NET_HEADER_FIELD_L2TPv2_TUNNEL_ID (IOC_NET_HEADER_FIELD_L2TPv2_TYPE_BIT << 7)
154353 +#define IOC_NET_HEADER_FIELD_L2TPv2_SESSION_ID (IOC_NET_HEADER_FIELD_L2TPv2_TYPE_BIT << 8)
154354 +#define IOC_NET_HEADER_FIELD_L2TPv2_NS (IOC_NET_HEADER_FIELD_L2TPv2_TYPE_BIT << 9)
154355 +#define IOC_NET_HEADER_FIELD_L2TPv2_NR (IOC_NET_HEADER_FIELD_L2TPv2_TYPE_BIT << 10)
154356 +#define IOC_NET_HEADER_FIELD_L2TPv2_OFFSET_SIZE (IOC_NET_HEADER_FIELD_L2TPv2_TYPE_BIT << 11)
154357 +#define IOC_NET_HEADER_FIELD_L2TPv2_FIRST_BYTE (IOC_NET_HEADER_FIELD_L2TPv2_TYPE_BIT << 12)
154358 +#define IOC_NET_HEADER_FIELD_L2TPv2_ALL_FIELDS ((IOC_NET_HEADER_FIELD_L2TPv2_TYPE_BIT << 13) - 1)
154359 +
154360 +#define IOC_NET_HEADER_FIELD_L2TPv3_CTRL_TYPE_BIT (1)
154361 +#define IOC_NET_HEADER_FIELD_L2TPv3_CTRL_LENGTH_BIT (IOC_NET_HEADER_FIELD_L2TPv3_CTRL_TYPE_BIT << 1)
154362 +#define IOC_NET_HEADER_FIELD_L2TPv3_CTRL_SEQUENCE_BIT (IOC_NET_HEADER_FIELD_L2TPv3_CTRL_TYPE_BIT << 2)
154363 +#define IOC_NET_HEADER_FIELD_L2TPv3_CTRL_VERSION (IOC_NET_HEADER_FIELD_L2TPv3_CTRL_TYPE_BIT << 3)
154364 +#define IOC_NET_HEADER_FIELD_L2TPv3_CTRL_LENGTH (IOC_NET_HEADER_FIELD_L2TPv3_CTRL_TYPE_BIT << 4)
154365 +#define IOC_NET_HEADER_FIELD_L2TPv3_CTRL_CONTROL (IOC_NET_HEADER_FIELD_L2TPv3_CTRL_TYPE_BIT << 5)
154366 +#define IOC_NET_HEADER_FIELD_L2TPv3_CTRL_SENT (IOC_NET_HEADER_FIELD_L2TPv3_CTRL_TYPE_BIT << 6)
154367 +#define IOC_NET_HEADER_FIELD_L2TPv3_CTRL_RECV (IOC_NET_HEADER_FIELD_L2TPv3_CTRL_TYPE_BIT << 7)
154368 +#define IOC_NET_HEADER_FIELD_L2TPv3_CTRL_FIRST_BYTE (IOC_NET_HEADER_FIELD_L2TPv3_CTRL_TYPE_BIT << 8)
154369 +#define IOC_NET_HEADER_FIELD_L2TPv3_CTRL_ALL_FIELDS ((IOC_NET_HEADER_FIELD_L2TPv3_CTRL_TYPE_BIT << 9) - 1)
154370 +
154371 +#define IOC_NET_HEADER_FIELD_L2TPv3_SESS_TYPE_BIT (1)
154372 +#define IOC_NET_HEADER_FIELD_L2TPv3_SESS_VERSION (IOC_NET_HEADER_FIELD_L2TPv3_SESS_TYPE_BIT << 1)
154373 +#define IOC_NET_HEADER_FIELD_L2TPv3_SESS_ID (IOC_NET_HEADER_FIELD_L2TPv3_SESS_TYPE_BIT << 2)
154374 +#define IOC_NET_HEADER_FIELD_L2TPv3_SESS_COOKIE (IOC_NET_HEADER_FIELD_L2TPv3_SESS_TYPE_BIT << 3)
154375 +#define IOC_NET_HEADER_FIELD_L2TPv3_SESS_ALL_FIELDS ((IOC_NET_HEADER_FIELD_L2TPv3_SESS_TYPE_BIT << 4) - 1)
154376 +
154377 +
154378 +typedef uint8_t ioc_header_field_vlan_t;
154379 +
154380 +#define IOC_NET_HEADER_FIELD_VLAN_VPRI (1)
154381 +#define IOC_NET_HEADER_FIELD_VLAN_CFI (IOC_NET_HEADER_FIELD_VLAN_VPRI << 1)
154382 +#define IOC_NET_HEADER_FIELD_VLAN_VID (IOC_NET_HEADER_FIELD_VLAN_VPRI << 2)
154383 +#define IOC_NET_HEADER_FIELD_VLAN_LENGTH (IOC_NET_HEADER_FIELD_VLAN_VPRI << 3)
154384 +#define IOC_NET_HEADER_FIELD_VLAN_TYPE (IOC_NET_HEADER_FIELD_VLAN_VPRI << 4)
154385 +#define IOC_NET_HEADER_FIELD_VLAN_ALL_FIELDS ((IOC_NET_HEADER_FIELD_VLAN_VPRI << 5) - 1)
154386 +
154387 +#define IOC_NET_HEADER_FIELD_VLAN_TCI (IOC_NET_HEADER_FIELD_VLAN_VPRI | \
154388 + IOC_NET_HEADER_FIELD_VLAN_CFI | \
154389 + IOC_NET_HEADER_FIELD_VLAN_VID)
154390 +
154391 +
154392 +typedef uint8_t ioc_header_field_llc_t;
154393 +
154394 +#define IOC_NET_HEADER_FIELD_LLC_DSAP (1)
154395 +#define IOC_NET_HEADER_FIELD_LLC_SSAP (IOC_NET_HEADER_FIELD_LLC_DSAP << 1)
154396 +#define IOC_NET_HEADER_FIELD_LLC_CTRL (IOC_NET_HEADER_FIELD_LLC_DSAP << 2)
154397 +#define IOC_NET_HEADER_FIELD_LLC_ALL_FIELDS ((IOC_NET_HEADER_FIELD_LLC_DSAP << 3) - 1)
154398 +
154399 +#define IOC_NET_HEADER_FIELD_NLPID_NLPID (1)
154400 +#define IOC_NET_HEADER_FIELD_NLPID_ALL_FIELDS ((IOC_NET_HEADER_FIELD_NLPID_NLPID << 1) - 1)
154401 +
154402 +
154403 +typedef uint8_t ioc_header_field_snap_t;
154404 +
154405 +#define IOC_NET_HEADER_FIELD_SNAP_OUI (1)
154406 +#define IOC_NET_HEADER_FIELD_SNAP_PID (IOC_NET_HEADER_FIELD_SNAP_OUI << 1)
154407 +#define IOC_NET_HEADER_FIELD_SNAP_ALL_FIELDS ((IOC_NET_HEADER_FIELD_SNAP_OUI << 2) - 1)
154408 +
154409 +
154410 +typedef uint8_t ioc_header_field_llc_snap_t;
154411 +
154412 +#define IOC_NET_HEADER_FIELD_LLC_SNAP_TYPE (1)
154413 +#define IOC_NET_HEADER_FIELD_LLC_SNAP_ALL_FIELDS ((IOC_NET_HEADER_FIELD_LLC_SNAP_TYPE << 1) - 1)
154414 +
154415 +#define IOC_NET_HEADER_FIELD_ARP_HTYPE (1)
154416 +#define IOC_NET_HEADER_FIELD_ARP_PTYPE (IOC_NET_HEADER_FIELD_ARP_HTYPE << 1)
154417 +#define IOC_NET_HEADER_FIELD_ARP_HLEN (IOC_NET_HEADER_FIELD_ARP_HTYPE << 2)
154418 +#define IOC_NET_HEADER_FIELD_ARP_PLEN (IOC_NET_HEADER_FIELD_ARP_HTYPE << 3)
154419 +#define IOC_NET_HEADER_FIELD_ARP_OPER (IOC_NET_HEADER_FIELD_ARP_HTYPE << 4)
154420 +#define IOC_NET_HEADER_FIELD_ARP_SHA (IOC_NET_HEADER_FIELD_ARP_HTYPE << 5)
154421 +#define IOC_NET_HEADER_FIELD_ARP_SPA (IOC_NET_HEADER_FIELD_ARP_HTYPE << 6)
154422 +#define IOC_NET_HEADER_FIELD_ARP_THA (IOC_NET_HEADER_FIELD_ARP_HTYPE << 7)
154423 +#define IOC_NET_HEADER_FIELD_ARP_TPA (IOC_NET_HEADER_FIELD_ARP_HTYPE << 8)
154424 +#define IOC_NET_HEADER_FIELD_ARP_ALL_FIELDS ((IOC_NET_HEADER_FIELD_ARP_HTYPE << 9) - 1)
154425 +
154426 +#define IOC_NET_HEADER_FIELD_RFC2684_LLC (1)
154427 +#define IOC_NET_HEADER_FIELD_RFC2684_NLPID (IOC_NET_HEADER_FIELD_RFC2684_LLC << 1)
154428 +#define IOC_NET_HEADER_FIELD_RFC2684_OUI (IOC_NET_HEADER_FIELD_RFC2684_LLC << 2)
154429 +#define IOC_NET_HEADER_FIELD_RFC2684_PID (IOC_NET_HEADER_FIELD_RFC2684_LLC << 3)
154430 +#define IOC_NET_HEADER_FIELD_RFC2684_VPN_OUI (IOC_NET_HEADER_FIELD_RFC2684_LLC << 4)
154431 +#define IOC_NET_HEADER_FIELD_RFC2684_VPN_IDX (IOC_NET_HEADER_FIELD_RFC2684_LLC << 5)
154432 +#define IOC_NET_HEADER_FIELD_RFC2684_ALL_FIELDS ((IOC_NET_HEADER_FIELD_RFC2684_LLC << 6) - 1)
154433 +
154434 +#define IOC_NET_HEADER_FIELD_USER_DEFINED_SRCPORT (1)
154435 +#define IOC_NET_HEADER_FIELD_USER_DEFINED_PCDID (IOC_NET_HEADER_FIELD_USER_DEFINED_SRCPORT << 1)
154436 +#define IOC_NET_HEADER_FIELD_USER_DEFINED_ALL_FIELDS ((IOC_NET_HEADER_FIELD_USER_DEFINED_SRCPORT << 2) - 1)
154437 +
154438 +#define IOC_NET_HEADER_FIELD_PAYLOAD_BUFFER (1)
154439 +#define IOC_NET_HEADER_FIELD_PAYLOAD_SIZE (IOC_NET_HEADER_FIELD_PAYLOAD_BUFFER << 1)
154440 +#define IOC_NET_HEADER_FIELD_MAX_FRM_SIZE (IOC_NET_HEADER_FIELD_PAYLOAD_BUFFER << 2)
154441 +#define IOC_NET_HEADER_FIELD_MIN_FRM_SIZE (IOC_NET_HEADER_FIELD_PAYLOAD_BUFFER << 3)
154442 +#define IOC_NET_HEADER_FIELD_PAYLOAD_TYPE (IOC_NET_HEADER_FIELD_PAYLOAD_BUFFER << 4)
154443 +#define IOC_NET_HEADER_FIELD_FRAME_SIZE (IOC_NET_HEADER_FIELD_PAYLOAD_BUFFER << 5)
154444 +#define IOC_NET_HEADER_FIELD_PAYLOAD_ALL_FIELDS ((IOC_NET_HEADER_FIELD_PAYLOAD_BUFFER << 6) - 1)
154445 +
154446 +
154447 +typedef uint8_t ioc_header_field_gre_t;
154448 +
154449 +#define IOC_NET_HEADER_FIELD_GRE_TYPE (1)
154450 +#define IOC_NET_HEADER_FIELD_GRE_ALL_FIELDS ((IOC_NET_HEADER_FIELD_GRE_TYPE << 1) - 1)
154451 +
154452 +
154453 +typedef uint8_t ioc_header_field_minencap_t;
154454 +
154455 +#define IOC_NET_HEADER_FIELD_MINENCAP_SRC_IP (1)
154456 +#define IOC_NET_HEADER_FIELD_MINENCAP_DST_IP (IOC_NET_HEADER_FIELD_MINENCAP_SRC_IP << 1)
154457 +#define IOC_NET_HEADER_FIELD_MINENCAP_TYPE (IOC_NET_HEADER_FIELD_MINENCAP_SRC_IP << 2)
154458 +#define IOC_NET_HEADER_FIELD_MINENCAP_ALL_FIELDS ((IOC_NET_HEADER_FIELD_MINENCAP_SRC_IP << 3) - 1)
154459 +
154460 +
154461 +typedef uint8_t ioc_header_field_ipsec_ah_t;
154462 +
154463 +#define IOC_NET_HEADER_FIELD_IPSEC_AH_SPI (1)
154464 +#define IOC_NET_HEADER_FIELD_IPSEC_AH_NH (IOC_NET_HEADER_FIELD_IPSEC_AH_SPI << 1)
154465 +#define IOC_NET_HEADER_FIELD_IPSEC_AH_ALL_FIELDS ((IOC_NET_HEADER_FIELD_IPSEC_AH_SPI << 2) - 1)
154466 +
154467 +
154468 +typedef uint8_t ioc_header_field_ipsec_esp_t;
154469 +
154470 +#define IOC_NET_HEADER_FIELD_IPSEC_ESP_SPI (1)
154471 +#define IOC_NET_HEADER_FIELD_IPSEC_ESP_SEQUENCE_NUM (IOC_NET_HEADER_FIELD_IPSEC_ESP_SPI << 1)
154472 +#define IOC_NET_HEADER_FIELD_IPSEC_ESP_ALL_FIELDS ((IOC_NET_HEADER_FIELD_IPSEC_ESP_SPI << 2) - 1)
154473 +
154474 +#define IOC_NET_HEADER_FIELD_IPSEC_ESP_SPI_SIZE 4
154475 +
154476 +
154477 +typedef uint8_t ioc_header_field_mpls_t;
154478 +
154479 +#define IOC_NET_HEADER_FIELD_MPLS_LABEL_STACK (1)
154480 +#define IOC_NET_HEADER_FIELD_MPLS_LABEL_STACK_ALL_FIELDS ((IOC_NET_HEADER_FIELD_MPLS_LABEL_STACK << 1) - 1)
154481 +
154482 +
154483 +typedef uint8_t ioc_header_field_macsec_t;
154484 +
154485 +#define IOC_NET_HEADER_FIELD_MACSEC_SECTAG (1)
154486 +#define IOC_NET_HEADER_FIELD_MACSEC_ALL_FIELDS ((IOC_NET_HEADER_FIELD_MACSEC_SECTAG << 1) - 1)
154487 +
154488 +
154489 +typedef enum {
154490 + e_IOC_NET_HEADER_TYPE_NONE = 0,
154491 + e_IOC_NET_HEADER_TYPE_PAYLOAD,
154492 + e_IOC_NET_HEADER_TYPE_ETH,
154493 + e_IOC_NET_HEADER_TYPE_VLAN,
154494 + e_IOC_NET_HEADER_TYPE_IPv4,
154495 + e_IOC_NET_HEADER_TYPE_IPv6,
154496 + e_IOC_NET_HEADER_TYPE_IP,
154497 + e_IOC_NET_HEADER_TYPE_TCP,
154498 + e_IOC_NET_HEADER_TYPE_UDP,
154499 + e_IOC_NET_HEADER_TYPE_UDP_LITE,
154500 + e_IOC_NET_HEADER_TYPE_IPHC,
154501 + e_IOC_NET_HEADER_TYPE_SCTP,
154502 + e_IOC_NET_HEADER_TYPE_SCTP_CHUNK_DATA,
154503 + e_IOC_NET_HEADER_TYPE_PPPoE,
154504 + e_IOC_NET_HEADER_TYPE_PPP,
154505 + e_IOC_NET_HEADER_TYPE_PPPMUX,
154506 + e_IOC_NET_HEADER_TYPE_PPPMUX_SUBFRAME,
154507 + e_IOC_NET_HEADER_TYPE_L2TPv2,
154508 + e_IOC_NET_HEADER_TYPE_L2TPv3_CTRL,
154509 + e_IOC_NET_HEADER_TYPE_L2TPv3_SESS,
154510 + e_IOC_NET_HEADER_TYPE_LLC,
154511 + e_IOC_NET_HEADER_TYPE_LLC_SNAP,
154512 + e_IOC_NET_HEADER_TYPE_NLPID,
154513 + e_IOC_NET_HEADER_TYPE_SNAP,
154514 + e_IOC_NET_HEADER_TYPE_MPLS,
154515 + e_IOC_NET_HEADER_TYPE_IPSEC_AH,
154516 + e_IOC_NET_HEADER_TYPE_IPSEC_ESP,
154517 + e_IOC_NET_HEADER_TYPE_UDP_ENCAP_ESP, /* RFC 3948 */
154518 + e_IOC_NET_HEADER_TYPE_MACSEC,
154519 + e_IOC_NET_HEADER_TYPE_GRE,
154520 + e_IOC_NET_HEADER_TYPE_MINENCAP,
154521 + e_IOC_NET_HEADER_TYPE_DCCP,
154522 + e_IOC_NET_HEADER_TYPE_ICMP,
154523 + e_IOC_NET_HEADER_TYPE_IGMP,
154524 + e_IOC_NET_HEADER_TYPE_ARP,
154525 + e_IOC_NET_HEADER_TYPE_CAPWAP,
154526 + e_IOC_NET_HEADER_TYPE_CAPWAP_DTLS,
154527 + e_IOC_NET_HEADER_TYPE_RFC2684,
154528 + e_IOC_NET_HEADER_TYPE_USER_DEFINED_L2,
154529 + e_IOC_NET_HEADER_TYPE_USER_DEFINED_L3,
154530 + e_IOC_NET_HEADER_TYPE_USER_DEFINED_L4,
154531 + e_IOC_NET_HEADER_TYPE_USER_DEFINED_SHIM1,
154532 + e_IOC_NET_HEADER_TYPE_USER_DEFINED_SHIM2,
154533 + e_IOC_NET_MAX_HEADER_TYPE_COUNT
154534 +} ioc_net_header_type;
154535 +
154536 +
154537 +#endif /* __NET_IOCTLS_H */